diff --git a/modules/api/src/main/java/org/apache/ignite/lang/util/IgniteNameUtils.java b/modules/api/src/main/java/org/apache/ignite/lang/util/IgniteNameUtils.java index e77aa10bd1e4..b090f7f355e6 100644 --- a/modules/api/src/main/java/org/apache/ignite/lang/util/IgniteNameUtils.java +++ b/modules/api/src/main/java/org/apache/ignite/lang/util/IgniteNameUtils.java @@ -38,7 +38,11 @@ private IgniteNameUtils() { * @return Unquoted identifier or identifier is cast to upper case. "tbl0" -> "TBL0", "\"Tbl0\"" -> "Tbl0". */ public static String parseIdentifier(String identifier) { - ensureNotNullAndNotEmpty(identifier, "name"); + ensureNotNullAndNotEmpty(identifier, "identifier"); + + if (identifier.indexOf('"') < 0) { // Fast-path without StringBuilder for unquoted names. + return parseUnquotedIdentifier(identifier); + } var tokenizer = new Tokenizer(identifier); @@ -149,11 +153,11 @@ private static boolean identifierExtend(int codePoint) { /** Wraps the given name with double quotes. */ private static String quote(String name) { - if (name.chars().noneMatch(cp -> cp == '\"')) { + if (name.indexOf('\"') < 0) { return '\"' + name + '\"'; } - StringBuilder sb = new StringBuilder(name.length() + 2).append('\"'); + StringBuilder sb = new StringBuilder(name.length() + 4).append('\"'); for (int currentPosition = 0; currentPosition < name.length(); currentPosition++) { char ch = name.charAt(currentPosition); if (ch == '\"') { @@ -174,6 +178,25 @@ private static void ensureNotNullAndNotEmpty(@Nullable String argument, String a } } + private static String parseUnquotedIdentifier(String identifier) { + if (identifier.indexOf('.') >= 0 || identifier.indexOf(' ') >= 0) { + throw new IllegalArgumentException("Fully qualified name is not expected [name=" + identifier + "]"); + } + + if (!identifierStart(identifier.codePointAt(0))) { + throw new IllegalArgumentException("Malformed identifier [identifier=" + identifier + ", pos=0]"); + } + + for (int i = 1; i < identifier.length(); i++) { + int codePoint = identifier.codePointAt(i); + if (!identifierStart(codePoint) && !identifierExtend(codePoint)) { + throw new IllegalArgumentException("Malformed identifier [identifier=" + identifier + ", pos=" + i + ']'); + } + } + + return identifier.toUpperCase(); + } + /** * Identifier chain tokenizer. * diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java index 67e09fcdd15b..4d8adf3d72c8 100644 --- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java +++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/Row.java @@ -37,7 +37,18 @@ public interface Row extends SchemaAware, BinaryRowEx, InternalTupleEx, BinaryTu * @param binaryRow Binary row. */ static Row wrapBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { - return new RowImpl(false, schema, BinaryTupleSchema.createRowSchema(schema), binaryRow); + return wrapBinaryRow(schema, BinaryTupleSchema.createRowSchema(schema), binaryRow); + } + + /** + * Creates a row from a given {@code BinaryRow}. + * + * @param schema Schema. + * @param rowSchema Row schema. + * @param binaryRow Binary row. + */ + static Row wrapBinaryRow(SchemaDescriptor schema, BinaryTupleSchema rowSchema, BinaryRow binaryRow) { + return new RowImpl(false, schema, rowSchema, binaryRow); } /** @@ -47,7 +58,18 @@ static Row wrapBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { * @param binaryRow Binary row. */ static Row wrapKeyOnlyBinaryRow(SchemaDescriptor schema, BinaryRow binaryRow) { - return new RowImpl(true, schema, BinaryTupleSchema.createKeySchema(schema), binaryRow); + return wrapKeyOnlyBinaryRow(schema, BinaryTupleSchema.createKeySchema(schema), binaryRow); + } + + /** + * Creates a row from a given {@code BinaryRow} that only contains the key component. + * + * @param schema Schema. + * @param keySchema Key schema. + * @param binaryRow Binary row. + */ + static Row wrapKeyOnlyBinaryRow(SchemaDescriptor schema, BinaryTupleSchema keySchema, BinaryRow binaryRow) { + return new RowImpl(true, schema, keySchema, binaryRow); } /** Short-cut method that reads decimal value with a scale from the schema. */ diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java index c5f7dc591310..6afd685142a8 100644 --- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java +++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java @@ -36,7 +36,6 @@ import org.apache.ignite.internal.type.DecimalNativeType; import org.apache.ignite.internal.type.NativeType; import org.apache.ignite.internal.type.NativeTypeSpec; -import org.apache.ignite.internal.type.NativeTypes; import org.apache.ignite.internal.type.TemporalNativeType; import org.apache.ignite.internal.util.TemporalTypeUtils; import org.jetbrains.annotations.Nullable; @@ -208,7 +207,7 @@ public RowAssembler appendDefault() { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendBoolean(boolean val) throws SchemaMismatchException { - checkType(NativeTypes.BOOLEAN); + checkType(NativeTypeSpec.BOOLEAN); builder.appendBoolean(val); @@ -229,7 +228,7 @@ public RowAssembler appendBoolean(Boolean value) throws SchemaMismatchException * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendByte(byte val) throws SchemaMismatchException { - checkType(NativeTypes.INT8); + checkType(NativeTypeSpec.INT8); builder.appendByte(val); @@ -250,7 +249,7 @@ public RowAssembler appendByte(Byte value) throws SchemaMismatchException { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendShort(short val) throws SchemaMismatchException { - checkType(NativeTypes.INT16); + checkType(NativeTypeSpec.INT16); builder.appendShort(val); @@ -271,7 +270,7 @@ public RowAssembler appendShort(Short value) throws SchemaMismatchException { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendInt(int val) throws SchemaMismatchException { - checkType(NativeTypes.INT32); + checkType(NativeTypeSpec.INT32); builder.appendInt(val); @@ -292,7 +291,7 @@ public RowAssembler appendInt(@Nullable Integer value) { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendLong(long val) throws SchemaMismatchException { - checkType(NativeTypes.INT64); + checkType(NativeTypeSpec.INT64); builder.appendLong(val); @@ -313,7 +312,7 @@ public RowAssembler appendLong(Long value) { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendFloat(float val) throws SchemaMismatchException { - checkType(NativeTypes.FLOAT); + checkType(NativeTypeSpec.FLOAT); builder.appendFloat(val); @@ -334,7 +333,7 @@ public RowAssembler appendFloat(Float value) { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendDouble(double val) throws SchemaMismatchException { - checkType(NativeTypes.DOUBLE); + checkType(NativeTypeSpec.DOUBLE); builder.appendDouble(val); @@ -427,7 +426,7 @@ public RowAssembler appendBytes(byte[] value) { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendUuidNotNull(UUID uuid) throws SchemaMismatchException { - checkType(NativeTypes.UUID); + checkType(NativeTypeSpec.UUID); builder.appendUuidNotNull(uuid); @@ -448,7 +447,7 @@ public RowAssembler appendUuid(UUID value) { * @throws SchemaMismatchException If a value doesn't match the current column type. */ public RowAssembler appendDateNotNull(LocalDate val) throws SchemaMismatchException { - checkType(NativeTypes.DATE); + checkType(NativeTypeSpec.DATE); builder.appendDateNotNull(val); @@ -566,15 +565,6 @@ private void checkType(NativeTypeSpec type) { } } - /** - * Checks that the type being appended matches the column type. - * - * @param type Type that is attempted to be appended. - */ - private void checkType(NativeType type) { - checkType(type.spec()); - } - private void shiftColumn() { curCol++; } diff --git a/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java b/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java index 1055764cd479..072a1022f106 100644 --- a/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java +++ b/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java @@ -30,6 +30,7 @@ import org.apache.ignite.internal.binarytuple.BinaryTupleContainer; import org.apache.ignite.internal.binarytuple.BinaryTupleReader; import org.apache.ignite.internal.schema.BinaryRowImpl; +import org.apache.ignite.internal.schema.BinaryTupleSchema; import org.apache.ignite.internal.schema.Column; import org.apache.ignite.internal.schema.SchemaAware; import org.apache.ignite.internal.schema.SchemaDescriptor; @@ -54,6 +55,8 @@ public class TupleMarshallerImpl implements TupleMarshaller { private static final Object POISON_OBJECT = new Object(); private final SchemaDescriptor schema; + private final BinaryTupleSchema rowSchema; + private final BinaryTupleSchema keySchema; private final int keyOnlyFixedLengthColumnSize; private final int valueOnlyFixedLengthColumnSize; @@ -65,6 +68,8 @@ public class TupleMarshallerImpl implements TupleMarshaller { */ public TupleMarshallerImpl(SchemaDescriptor schema) { this.schema = schema; + rowSchema = BinaryTupleSchema.createRowSchema(schema); + keySchema = BinaryTupleSchema.createKeySchema(schema); keyOnlyFixedLengthColumnSize = schema.keyColumns().stream() .map(Column::type) @@ -102,7 +107,7 @@ public Row marshal(Tuple tuple) throws MarshallerException { // BinaryTuple from client has matching schema version, and all values are valid. Use buffer as is. var binaryRow = new BinaryRowImpl(schema.version(), tupleReader.byteBuffer()); - return Row.wrapBinaryRow(schema, binaryRow); + return Row.wrapBinaryRow(schema, rowSchema, binaryRow); } } } @@ -186,8 +191,8 @@ private Row buildRow( } return part == TuplePart.KEY - ? Row.wrapKeyOnlyBinaryRow(schema, rowBuilder.build()) - : Row.wrapBinaryRow(schema, rowBuilder.build()); + ? Row.wrapKeyOnlyBinaryRow(schema, keySchema, rowBuilder.build()) + : Row.wrapBinaryRow(schema, rowSchema, rowBuilder.build()); } void gatherStatistics(