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 @@ -44,7 +44,6 @@
import com.google.common.base.Suppliers;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Types;
Expand Down Expand Up @@ -78,10 +77,8 @@ class RelationalArrayFacade implements RelationalArray {
this.delegate = array;
}

@Nullable
private DataType.ArrayType computeType() {
return delegateMetadata.getType() == Type.UNKNOWN ? null :
DataType.ArrayType.from(RelationalStructFacade.RelationalStructFacadeMetaData.getDataType(delegateMetadata.getType(), delegateMetadata, delegateMetadata.getNullable()));
return DataType.ArrayType.from(TypeConversion.getDataType(delegateMetadata.getType(), delegateMetadata, delegateMetadata.getNullable()));
}

/**
Expand Down Expand Up @@ -153,12 +150,12 @@ public Object getArray(long oneBasedIndex, int askedForCount) throws SQLExceptio
int count = getCount(askedForCount, this.delegate.getElementCount(), index);
final var array = new Object[count];
int j = 0;
final var componentType = this.delegateMetadata.getJavaSqlTypesCode();
final var componentType = this.delegateMetadata.getType();
for (int i = index; i < count; i++) {
if (componentType == Types.STRUCT) {
if (componentType == Type.STRUCT) {
array[j++] = new RelationalStructFacade(delegateMetadata.getStructMetadata(), delegate.getElement(i).getStruct());
} else {
Assert.failUnchecked(ErrorCode.UNKNOWN_TYPE, "Type not supported: " + SqlTypeNamesSupport.getSqlTypeName(componentType));
Assert.failUnchecked(ErrorCode.UNKNOWN_TYPE, "Type not supported: " + componentType.name());
}
}
return array;
Expand All @@ -185,9 +182,9 @@ public RelationalResultSet getResultSet(long oneBasedIndex, int askedForCount) t
final var componentType = this.delegateMetadata.getType();
final var componentSqlType = this.delegateMetadata.getJavaSqlTypesCode();
final var componentColumnBuilder = ColumnMetadata.newBuilder().setName("VALUE").setType(componentType).setJavaSqlTypesCode(componentSqlType);
if (componentSqlType == Types.ARRAY) {
if (componentType == Type.ARRAY) {
componentColumnBuilder.setArrayMetadata(this.delegateMetadata.getArrayMetadata());
} else if (componentSqlType == Types.STRUCT) {
} else if (componentType == Type.STRUCT) {
componentColumnBuilder.setStructMetadata(this.delegateMetadata.getStructMetadata());
}
resultSetBuilder.setMetadata(ResultSetMetadata.newBuilder().setColumnMetadata(ListColumnMetadata.newBuilder()
Expand All @@ -197,12 +194,12 @@ public RelationalResultSet getResultSet(long oneBasedIndex, int askedForCount) t
final var listColumnBuilder = ListColumn.newBuilder();
listColumnBuilder.addColumn(Column.newBuilder().setInteger(i + 1).build());
final var valueColumnBuilder = Column.newBuilder();
if (componentSqlType == Types.STRUCT) {
if (componentType == Type.STRUCT) {
valueColumnBuilder.setStruct(delegate.getElement(i).getStruct());
} else if (componentSqlType == Types.INTEGER) {
} else if (componentType == Type.INTEGER) {
valueColumnBuilder.setInteger(delegate.getElement(i).getInteger());
} else {
Assert.failUnchecked(ErrorCode.UNKNOWN_TYPE, "Type not supported: " + SqlTypeNamesSupport.getSqlTypeName(componentSqlType));
Assert.failUnchecked(ErrorCode.UNKNOWN_TYPE, "Type not supported: " + componentType.name());
}
resultSetBuilder.addRow(Struct.newBuilder()
.setColumns(listColumnBuilder
Expand Down Expand Up @@ -281,7 +278,7 @@ private void initOrCheckMetadata(ListColumnMetadata innerMetadata) {
builder.setStructMetadata(innerMetadata);
metadata = builder.build();
} else {
Assert.thatUnchecked(metadata.getJavaSqlTypesCode() == Types.STRUCT, ErrorCode.DATATYPE_MISMATCH, "dataType mismatch!");
Assert.thatUnchecked(metadata.getType() == Type.ARRAY, ErrorCode.DATATYPE_MISMATCH, "dataType mismatch!");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package com.apple.foundationdb.relational.jdbc;

import com.apple.foundationdb.relational.api.ArrayMetaData;
import com.apple.foundationdb.relational.api.RelationalStructMetaData;
import com.apple.foundationdb.relational.api.StructMetaData;
import com.apple.foundationdb.relational.api.RelationalResultSetMetaData;
import com.apple.foundationdb.relational.api.exceptions.ErrorCode;
Expand Down Expand Up @@ -56,9 +57,10 @@ public DataType.StructType getRelationalDataType() throws SQLException {
}

@Override
public StructMetaData getStructMetaData(int oneBasedColumn) throws SQLException {
return new RelationalStructFacade.RelationalStructFacadeMetaData(
this.delegate.getColumnMetadata().getColumnMetadata(PositionalIndex.toProtobuf(oneBasedColumn)).getStructMetadata());
public StructMetaData getStructMetaData(int oneBasedColumn) {
return RelationalStructMetaData.of(TypeConversion.getStructDataType(
this.delegate.getColumnMetadata().getColumnMetadata(
PositionalIndex.toProtobuf(oneBasedColumn)).getStructMetadata().getColumnMetadataList(), false));
}

@Override
Expand All @@ -85,8 +87,8 @@ public String getColumnLabel(int column) throws SQLException {

@Override
public int getColumnType(int oneBasedColumn) throws SQLException {
return this.delegate.getColumnMetadata()
.getColumnMetadata(PositionalIndex.toProtobuf(oneBasedColumn)).getJavaSqlTypesCode();
return TypeConversion.toSqlType(this.delegate.getColumnMetadata()
.getColumnMetadata(PositionalIndex.toProtobuf(oneBasedColumn)).getType());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,15 @@

package com.apple.foundationdb.relational.jdbc;

import com.apple.foundationdb.relational.api.ArrayMetaData;
import com.apple.foundationdb.relational.api.RelationalArray;
import com.apple.foundationdb.relational.api.RelationalStruct;
import com.apple.foundationdb.relational.api.RelationalStructBuilder;
import com.apple.foundationdb.relational.api.RelationalStructMetaData;
import com.apple.foundationdb.relational.api.StructMetaData;
import com.apple.foundationdb.relational.api.exceptions.ErrorCode;
import com.apple.foundationdb.relational.api.exceptions.RelationalException;
import com.apple.foundationdb.relational.api.metadata.DataType;
import com.apple.foundationdb.relational.jdbc.grpc.v1.column.Column;
import com.apple.foundationdb.relational.jdbc.grpc.v1.column.ColumnMetadata;
import com.apple.foundationdb.relational.jdbc.grpc.v1.column.EnumMetadata;
import com.apple.foundationdb.relational.jdbc.grpc.v1.column.ListColumn;
import com.apple.foundationdb.relational.jdbc.grpc.v1.column.ListColumnMetadata;
import com.apple.foundationdb.relational.jdbc.grpc.v1.column.Struct;
Expand All @@ -54,6 +51,8 @@
import java.util.UUID;
import java.util.function.Supplier;

import static com.apple.foundationdb.relational.jdbc.TypeConversion.getStructDataType;

/**
* Facade over grpc protobuf objects that offers a {@link RelationalStruct} view.
* Used by jdbc client but also serializable (protobuf) so can be passed over
Expand All @@ -69,7 +68,6 @@ class RelationalStructFacade implements RelationalStruct {
/**
* A StructMetaData facade over {@link #delegateMetadata}.
*/
private final StructMetaData structMetaData;
private final Supplier<DataType.StructType> type;

/**
Expand All @@ -87,10 +85,9 @@ class RelationalStructFacade implements RelationalStruct {
private boolean wasNull;

RelationalStructFacade(ListColumnMetadata delegateMetadata, Struct delegate) {
type = Suppliers.memoize(() -> TypeConversion.getStructDataType(delegateMetadata.getColumnMetadataList(), false));
type = Suppliers.memoize(() -> getStructDataType(delegateMetadata.getColumnMetadataList(), false));
this.delegate = delegate;
this.delegateMetadata = delegateMetadata;
this.structMetaData = new RelationalStructFacadeMetaData(delegateMetadata);
this.wasNull = false;
}

Expand All @@ -115,7 +112,7 @@ ListColumnMetadata getDelegateMetadata() {
*/
@Override
public StructMetaData getMetaData() {
return type.get() != null ? RelationalStructMetaData.of(type.get()) : structMetaData;
return RelationalStructMetaData.of(type.get());
}

@Override
Expand Down Expand Up @@ -430,7 +427,7 @@ int getZeroBasedOffsetOrThrow(String fieldName) throws SQLException {
}

@Override
public RelationalStructBuilder addBoolean(String fieldName, boolean b) throws SQLException {
public RelationalStructBuilder addBoolean(String fieldName, boolean b) {
// Add the metadata and get offset at where to insert data.
int offset = addMetadata(ColumnMetadata.newBuilder()
.setName(fieldName).setJavaSqlTypesCode(Types.BOOLEAN).setType(Type.BOOLEAN).build());
Expand All @@ -440,7 +437,7 @@ public RelationalStructBuilder addBoolean(String fieldName, boolean b) throws SQ
}

@Override
public RelationalStructBuilder addLong(String fieldName, long l) throws SQLException {
public RelationalStructBuilder addLong(String fieldName, long l) {
int offset = addMetadata(ColumnMetadata.newBuilder()
.setName(fieldName).setJavaSqlTypesCode(Types.BIGINT).setType(Type.LONG).build());
this.listColumnBuilder.addColumn(offset, Column.newBuilder().setLong(l).build());
Expand All @@ -453,15 +450,15 @@ public RelationalStructBuilder addFloat(String fieldName, float f) throws SQLExc
}

@Override
public RelationalStructBuilder addDouble(String fieldName, double d) throws SQLException {
public RelationalStructBuilder addDouble(String fieldName, double d) {
int offset = addMetadata(ColumnMetadata.newBuilder()
.setName(fieldName).setJavaSqlTypesCode(Types.DOUBLE).setType(Type.DOUBLE).build());
this.listColumnBuilder.addColumn(offset, Column.newBuilder().setDouble(d).build());
return this;
}

@Override
public RelationalStructBuilder addBytes(String fieldName, byte[] bytes) throws SQLException {
public RelationalStructBuilder addBytes(String fieldName, byte[] bytes) {
int offset = addMetadata(ColumnMetadata.newBuilder()
.setName(fieldName).setJavaSqlTypesCode(Types.BINARY).setType(Type.BYTES).build());
this.listColumnBuilder.addColumn(offset, Column.newBuilder().setBinary(ByteString.copyFrom(bytes)).build());
Expand All @@ -470,7 +467,7 @@ public RelationalStructBuilder addBytes(String fieldName, byte[] bytes) throws S

@Override
@SpotBugsSuppressWarnings("NP")
public RelationalStructBuilder addString(String fieldName, @Nullable String s) throws SQLException {
public RelationalStructBuilder addString(String fieldName, @Nullable String s) {
int offset = addMetadata(ColumnMetadata.newBuilder()
.setName(fieldName).setJavaSqlTypesCode(Types.VARCHAR).setType(Type.STRING).build());
// TODO: setString requires a non-null string, but this method takes a nullable string
Expand Down Expand Up @@ -503,7 +500,7 @@ public RelationalStructBuilder addStruct(String fieldName, @Nonnull RelationalSt
// Insert the data portion of RelationalStruct here.
RelationalStructFacade relationalStructFacade = struct.unwrap(RelationalStructFacade.class);
int offset = addMetadata(ColumnMetadata.newBuilder().setName(fieldName)
.setJavaSqlTypesCode(Types.STRUCT).setType(Type.STRUCT).setStructMetadata(relationalStructFacade.delegateMetadata).build());
.setJavaSqlTypesCode(Types.STRUCT).setType(Type.STRUCT).setStructMetadata(relationalStructFacade.getDelegateMetadata()).build());
this.listColumnBuilder
.addColumn(offset, Column.newBuilder().setStruct(relationalStructFacade.delegate).build());
return this;
Expand Down Expand Up @@ -540,152 +537,4 @@ public RelationalStruct build() {
return new RelationalStructFacade(columnListMetadataBuilder.build(), struct);
}
}

/**
* Facade over protobuf column metadata to present a StructMetaData view.
*/
static final class RelationalStructFacadeMetaData implements StructMetaData {
private final ListColumnMetadata metadata;
private final Supplier<DataType.StructType> type;

RelationalStructFacadeMetaData(ListColumnMetadata metadata) {
this.metadata = metadata;
this.type = Suppliers.memoize(this::computeType);
}

private DataType.StructType computeType() {
return getStructDataType(metadata.getColumnMetadataList(), false);
}

private static DataType.EnumType getEnumDataType(@Nonnull EnumMetadata enumMetadata, boolean nullable) {
final var enumValues = new ArrayList<DataType.EnumType.EnumValue>();
int i = 1;
for (var value: enumMetadata.getValuesList()) {
enumValues.add(DataType.EnumType.EnumValue.of(value, i++));
}
return DataType.EnumType.from(enumMetadata.getName(), enumValues, nullable);
}

private static DataType.StructType getStructDataType(@Nonnull List<ColumnMetadata> columnMetadataList, boolean nullable) {
final var fields = new ArrayList<DataType.StructType.Field>();
for (int i = 0; i < columnMetadataList.size(); i++) {
final var columnMetadata = columnMetadataList.get(i);
fields.add(DataType.StructType.Field.from(columnMetadata.getName(), getDataType(columnMetadata.getType(), columnMetadata, columnMetadata.getNullable()), i));
}
return DataType.StructType.from("ANONYMOUS_STRUCT", fields, nullable);
}

static DataType getDataType(@Nonnull Type type, @Nonnull ColumnMetadata columnMetadata, boolean nullable) {
switch (type) {
case LONG:
return nullable ? DataType.Primitives.NULLABLE_LONG.type() : DataType.Primitives.LONG.type();
case INTEGER:
return nullable ? DataType.Primitives.NULLABLE_INTEGER.type() : DataType.Primitives.INTEGER.type();
case DOUBLE:
return nullable ? DataType.Primitives.NULLABLE_DOUBLE.type() : DataType.Primitives.DOUBLE.type();
case FLOAT:
return nullable ? DataType.Primitives.NULLABLE_FLOAT.type() : DataType.Primitives.FLOAT.type();
case BOOLEAN:
return nullable ? DataType.Primitives.NULLABLE_BOOLEAN.type() : DataType.Primitives.BOOLEAN.type();
case BYTES:
return nullable ? DataType.Primitives.NULLABLE_BYTES.type() : DataType.Primitives.BYTES.type();
case UUID:
return nullable ? DataType.Primitives.NULLABLE_UUID.type() : DataType.Primitives.UUID.type();
case STRING:
return nullable ? DataType.Primitives.NULLABLE_STRING.type() : DataType.Primitives.STRING.type();
case VERSION:
return nullable ? DataType.Primitives.NULLABLE_VERSION.type() : DataType.Primitives.VERSION.type();
case STRUCT:
return getStructDataType(columnMetadata.getStructMetadata().getColumnMetadataList(), nullable);
case ENUM:
return getEnumDataType(columnMetadata.getEnumMetadata(), nullable);
case ARRAY:
final var arrayMetadata = columnMetadata.getArrayMetadata();
return DataType.ArrayType.from(getDataType(arrayMetadata.getType(), arrayMetadata, arrayMetadata.getNullable()), nullable);
default:
throw new RelationalException("Not implemeneted: " + type.name(), ErrorCode.INTERNAL_ERROR).toUncheckedWrappedException();
}
}

@Override
public int getColumnCount() throws SQLException {
return metadata.getColumnMetadataCount();
}

@Override
public int isNullable(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public String getTypeName() throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public String getColumnLabel(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public String getColumnName(int oneBasedColumn) throws SQLException {
return metadata.getColumnMetadata(PositionalIndex.toProtobuf(oneBasedColumn)).getName();
}

@Override
public String getSchemaName(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public String getTableName(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public String getCatalogName(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public int getColumnType(int oneBasedColumn) throws SQLException {
return metadata.getColumnMetadata(PositionalIndex.toProtobuf(oneBasedColumn)).getJavaSqlTypesCode();
}

@Override
public String getColumnTypeName(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public StructMetaData getStructMetaData(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public ArrayMetaData getArrayMetaData(int oneBasedColumn) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public int getLeadingPhantomColumnCount() {
return -1000;
}

@Nonnull
@Override
public DataType.StructType getRelationalDataType() {
return type.get();
}

@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}

@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
throw new SQLException("Not implemented", ErrorCode.UNSUPPORTED_OPERATION.getErrorCode());
}
}
}
Loading
Loading