Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,8 @@ private static Type fromProtoType(@Nullable Descriptors.GenericDescriptor descri
final var elementField = messageDescriptor.findFieldByName(NullableArrayTypeUtils.getRepeatedFieldName());
final var elementTypeCode = TypeCode.fromProtobufType(elementField.getType());
return fromProtoTypeToArray(descriptor, protoType, elementTypeCode, true);
} else if (TupleFieldsProto.UUID.getDescriptor().equals(messageDescriptor)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may have discussed this before, but can you please remind me again why are handling the conversion of UUID PB message within a Struct but not within and Array?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are adding an extra check here for the case of RECORD, since the descriptor could be that representing a UUID. If so, we do not consider it a "Record" type, but a "UUID" type. This is only needed for this particular case, and not also in Arrays as that dispatches the element processing to this function only.

return Type.uuidType(isNullable);
} else {
return Record.fromFieldDescriptorsMap(isNullable, Record.toFieldDescriptorMap(messageDescriptor.getFields()));
}
Expand Down Expand Up @@ -2475,7 +2477,8 @@ public boolean equals(final Object o) {
}
final var field = (Field)o;
return getFieldType().equals(field.getFieldType()) &&
getFieldNameOptional().equals(field.getFieldNameOptional());
getFieldNameOptional().equals(field.getFieldNameOptional()) &&
getFieldIndexOptional().equals(field.getFieldIndexOptional());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,15 @@ public Stream<? extends Arguments> provideArguments(final ExtensionContext conte
.setStartDate(random.nextLong())
.setSchoolName("randomString" + random.nextInt()).build()
).build()
),
Arguments.of(
"TestRecordsUuidProto.UuidRecord", TestRecordsUuidProto.UuidRecord.newBuilder()
.setPkey(TupleFieldsProto.UUID.newBuilder()
.setMostSignificantBits(98452560)
.setLeastSignificantBits(30900234)
.build())
.build()
)
// This does not work currently owing to https://github.com/FoundationDB/fdb-record-layer/issues/3295
// Arguments.of(
// "TestRecordsUuidProto.UuidRecord", TestRecordsUuidProto.UuidRecord.newBuilder()
// .setPkey(TupleFieldsProto.UUID.newBuilder()
// .setMostSignificantBits(98452560)
// .setLeastSignificantBits(30900234)
// .build())
// .build()
// )
);
}
}
Expand Down Expand Up @@ -308,28 +307,4 @@ void testAnyRecordSerialization() {
Type.AnyRecord r1 = new Type.AnyRecord(false);
Assertions.assertEquals(r1, Type.AnyRecord.fromProto(serializationContext, r1.toProto(serializationContext)));
}

@Test
void testUUIDInterpretedAsRecordType() {
final TestRecordsUuidProto.UuidRecord uuidRecord = TestRecordsUuidProto.UuidRecord.newBuilder()
.setName("testUuidRecord")
.setPkey(TupleFieldsProto.UUID.newBuilder()
.setMostSignificantBits(1)
.setLeastSignificantBits(2))
.build();
final Type.Record recordType = Type.Record.fromDescriptor(uuidRecord.getDescriptorForType());
final Map<String, Type.Record.Field> fieldsMaps = recordType.getFieldNameFieldMap();
checkIsUuidRecordType(fieldsMaps, "pkey");
checkIsUuidRecordType(fieldsMaps, "secondary");
checkIsUuidRecordType(fieldsMaps, "unique");
}

private static void checkIsUuidRecordType(@Nonnull Map<String, Type.Record.Field> fieldsMap, @Nonnull String fieldName) {
Assertions.assertTrue(fieldsMap.containsKey(fieldName));
Assertions.assertInstanceOf(Type.Record.class, fieldsMap.get(fieldName).getFieldType());
final Type.Record uuidRecord = (Type.Record) fieldsMap.get(fieldName).getFieldType();
Assertions.assertEquals(2, uuidRecord.getFields().size());
Assertions.assertEquals(Type.TypeCode.LONG, uuidRecord.getFields().get(0).getFieldType().getTypeCode());
Assertions.assertEquals(Type.TypeCode.LONG, uuidRecord.getFields().get(1).getFieldType().getTypeCode());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import javax.annotation.Nonnull;
import java.sql.SQLException;
import java.util.UUID;

/**
* Builder for {@link RelationalArray}.
Expand All @@ -44,6 +45,8 @@ public interface RelationalArrayBuilder {

RelationalArrayBuilder addLong(long value) throws SQLException;

RelationalArrayBuilder addUuid(@Nonnull UUID value) throws SQLException;

RelationalArrayBuilder addObject(@Nonnull Object value) throws SQLException;

RelationalArrayBuilder addStruct(RelationalStruct struct) throws SQLException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.sql.SQLException;
import java.util.UUID;

/**
* For implementation by {@link RelationalStruct} <a href="https://refactoring.guru/design-patterns/builder">Builder</a>.
Expand Down Expand Up @@ -50,6 +51,8 @@ public interface RelationalStructBuilder {

RelationalStructBuilder addString(String fieldName, @Nullable String s) throws SQLException;

RelationalStructBuilder addUuid(String fieldName, @Nullable UUID uuid) throws SQLException;

RelationalStructBuilder addObject(String fieldName, @Nullable Object obj) throws SQLException;

RelationalStructBuilder addStruct(String fieldName, @Nonnull RelationalStruct struct) throws SQLException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -200,6 +201,8 @@ public static DataType getDataTypeFromObject(@Nullable Object obj) {
return Primitives.DOUBLE.type();
} else if (obj instanceof String) {
return Primitives.STRING.type();
} else if (obj instanceof UUID) {
return Primitives.UUID.type();
} else if (obj instanceof RelationalStruct) {
return ((RelationalStruct) obj).getMetaData().getRelationalDataType();
} else if (obj instanceof RelationalArray) {
Expand Down
4 changes: 2 additions & 2 deletions fdb-relational-core/src/main/antlr/RelationalParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ columnType
: primitiveType | customType=uid;

primitiveType
: BOOLEAN | INTEGER | BIGINT | FLOAT | DOUBLE | STRING | BYTES;
: BOOLEAN | INTEGER | BIGINT | FLOAT | DOUBLE | STRING | BYTES | UUID;

columnConstraint
: nullNotnull #nullColumnConstraint
Expand Down Expand Up @@ -1354,7 +1354,7 @@ functionNameBase
| TIMESTAMPADD | TIMESTAMPDIFF | TIME_FORMAT | TIME_TO_SEC
| TOUCHES | TO_BASE64 | TO_DAYS | TO_SECONDS | UCASE
| UNCOMPRESS | UNCOMPRESSED_LENGTH | UNHEX | UNIX_TIMESTAMP
| UPDATEXML | UPPER | UUID | UUID_SHORT
| UPDATEXML | UPPER
| VALIDATE_PASSWORD_STRENGTH | VERSION | VISIBLE
| WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS | WEEK | WEEKDAY
| WEEKOFYEAR | WEIGHT_STRING | WITHIN | YEAR | YEARWEEK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public interface EmbeddedRelationalArray extends RelationalArray {

Expand Down Expand Up @@ -94,6 +95,11 @@ public Builder addBytes(@Nonnull byte[] value) throws SQLException {
return addField(value, DataType.Primitives.BYTES.type());
}

@Override
public Builder addUuid(@Nonnull UUID uuid) throws SQLException {
return addField(uuid, DataType.Primitives.UUID.type());
}

@Override
public Builder addObject(@Nonnull Object obj) throws SQLException {
if (obj instanceof RelationalStruct) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public Builder addString(String fieldName, @Nullable String s) {
return addField(fieldName, DataType.Primitives.STRING.type(), s);
}

@Override
public Builder addUuid(String fieldName, @Nullable UUID uuid) {
return addField(fieldName, DataType.Primitives.UUID.type(), uuid);
}

@Override
public RelationalStructBuilder addObject(String fieldName, @Nullable Object obj) throws SQLException {
if (obj instanceof RelationalStruct) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
package com.apple.foundationdb.relational.recordlayer.metadata;

import com.apple.foundationdb.annotation.API;

import com.apple.foundationdb.record.RecordMetaData;
import com.apple.foundationdb.record.RecordMetaDataProto;
import com.apple.foundationdb.record.metadata.Key;
import com.apple.foundationdb.record.query.combinatorics.TopologicalSort;
import com.apple.foundationdb.record.query.plan.cascades.typing.TypeRepository;
import com.apple.foundationdb.relational.api.exceptions.ErrorCode;
import com.apple.foundationdb.relational.api.exceptions.RelationalException;
import com.apple.foundationdb.relational.api.metadata.DataType;
Expand All @@ -38,7 +38,6 @@
import com.apple.foundationdb.relational.recordlayer.metadata.serde.RecordMetadataDeserializer;
import com.apple.foundationdb.relational.recordlayer.metadata.serde.RecordMetadataSerializer;
import com.apple.foundationdb.relational.util.Assert;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
Expand All @@ -50,6 +49,7 @@
import com.google.protobuf.Descriptors;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Comparator;
Expand Down Expand Up @@ -189,10 +189,11 @@ private RecordMetaData buildRecordMetadata() {
final var fileDescriptorProtoSerializer = new FileDescriptorSerializer();
accept(fileDescriptorProtoSerializer);
final Descriptors.FileDescriptor fileDescriptor;
final var dependencies = new ArrayList<>(TypeRepository.DEPENDENCIES);
dependencies.add(RecordMetaDataProto.getDescriptor());
try {
fileDescriptor = Descriptors.FileDescriptor.buildFrom(
fileDescriptorProtoSerializer.getFileBuilder().build(),
new Descriptors.FileDescriptor[]{RecordMetaDataProto.getDescriptor()});
fileDescriptorProtoSerializer.getFileBuilder().build(), dependencies.toArray(new Descriptors.FileDescriptor[0]));
} catch (Descriptors.DescriptorValidationException e) {
throw new RelationalException(ErrorCode.SERIALIZATION_FAILURE, e).toUncheckedWrappedException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
package com.apple.foundationdb.relational.recordlayer.metadata.serde;

import com.apple.foundationdb.annotation.API;

import com.apple.foundationdb.record.RecordMetaDataOptionsProto;
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
import com.apple.foundationdb.record.query.plan.cascades.typing.TypeRepository;
Expand All @@ -31,14 +30,15 @@
import com.apple.foundationdb.relational.recordlayer.metadata.RecordLayerTable;
import com.apple.foundationdb.relational.recordlayer.metadata.SkeletonVisitor;
import com.apple.foundationdb.relational.util.Assert;

import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors;

import javax.annotation.Nonnull;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@API(API.Status.EXPERIMENTAL)
public class FileDescriptorSerializer extends SkeletonVisitor {
Expand Down Expand Up @@ -73,6 +73,7 @@ public FileDescriptorSerializer() {

public FileDescriptorSerializer(@Nonnull DescriptorProtos.FileDescriptorProto.Builder fileBuilder) {
this.fileBuilder = fileBuilder;
this.fileBuilder.addAllDependency(TypeRepository.DEPENDENCIES.stream().map(Descriptors.FileDescriptor::getFullName).collect(Collectors.toList()));
this.unionDescriptorBuilder = DescriptorProtos.DescriptorProto.newBuilder().setName("RecordTypeUnion");
final RecordMetaDataOptionsProto.RecordTypeOptions options = RecordMetaDataOptionsProto.RecordTypeOptions.newBuilder().setUsage(RecordMetaDataOptionsProto.RecordTypeOptions.Usage.UNION).build();
unionDescriptorBuilder.getOptionsBuilder().setExtension(RecordMetaDataOptionsProto.record, options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.apple.foundationdb.relational.recordlayer.query;

import com.apple.foundationdb.record.metadata.expressions.TupleFieldsHelper;
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
import com.apple.foundationdb.record.query.plan.cascades.typing.TypeRepository;
import com.apple.foundationdb.relational.api.exceptions.ErrorCode;
Expand All @@ -42,6 +43,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Stack;
import java.util.UUID;
import java.util.function.Supplier;

public class Literals {
Expand Down Expand Up @@ -260,7 +262,7 @@ public void finishStructLiteral(@Nonnull final Type.Record type,
for (final OrderedLiteral fieldOrderedLiteral : fields) {
final var fieldValue = fieldOrderedLiteral.getLiteralObject();
if (fieldValue != null) {
messageBuilder.setField(fieldDescriptors.get(i), fieldValue);
messageBuilder.setField(fieldDescriptors.get(i), transformFieldValue(fieldValue));
}
i++;
}
Expand All @@ -272,6 +274,13 @@ public void finishStructLiteral(@Nonnull final Type.Record type,
structLiteralScopeCount--;
}

private static Object transformFieldValue(@Nonnull Object fieldValue) {
if (fieldValue instanceof UUID) {
return TupleFieldsHelper.toProto((UUID) fieldValue);
}
return fieldValue;
}

public boolean isAddingComplexLiteral() {
return arrayLiteralScopeCount + structLiteralScopeCount != 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,9 @@ public DataType lookupType(@Nonnull Identifier typeIdentifier, boolean isNullabl
case "FLOAT":
type = isNullable ? DataType.Primitives.NULLABLE_FLOAT.type() : DataType.Primitives.FLOAT.type();
break;
case "UUID":
type = isNullable ? DataType.Primitives.NULLABLE_UUID.type() : DataType.Primitives.UUID.type();
break;
default:
Assert.notNullUnchecked(metadataCatalog);
// assume it is a custom type, will fail in upper layers if the type can not be resolved.
Expand Down
Loading