Skip to content

Commit cbf5815

Browse files
committed
bring back relational support to get/set UUID
1 parent b69e51e commit cbf5815

File tree

27 files changed

+392
-32
lines changed

27 files changed

+392
-32
lines changed

fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalPreparedStatement.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import java.sql.Time;
4646
import java.sql.Timestamp;
4747
import java.util.Calendar;
48+
import java.util.UUID;
4849

4950
/**
5051
* Extension of {@link java.sql.PreparedStatement} to allow for Relational specific Prepared Statements.
@@ -160,6 +161,29 @@ public interface RelationalPreparedStatement extends java.sql.PreparedStatement
160161
*/
161162
void setObject(String parameterName, Object x) throws SQLException;
162163

164+
/**
165+
* Sets the designated parameter to the given Java <code>UUID</code> value.
166+
*
167+
* @param parameterIndex the first parameter is 1, the second is 2, ...
168+
* @param x the parameter value
169+
* @exception SQLException if parameterIndex does not correspond to a parameter
170+
* marker in the SQL statement;
171+
* if a database access error occurs or
172+
* this method is called on a closed <code>PreparedStatement</code>
173+
*/
174+
void setUUID(int parameterIndex, UUID x) throws SQLException;
175+
176+
/**
177+
* Sets the designated parameter to the given Java <code>UUID</code> value.
178+
*
179+
* @param parameterName the name of the parameter
180+
* @param x the parameter value
181+
* @exception SQLException if parameterName does not correspond to a parameter
182+
* marker in the SQL statement; if a database access error occurs or
183+
* this method is called on a closed <code>PreparedStatement</code>
184+
*/
185+
void setUUID(String parameterName, UUID x) throws SQLException;
186+
163187
/**
164188
* Sets the designated parameter to SQL <code>NULL</code>.
165189
*

fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/RelationalStruct.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.sql.Struct;
2929
import java.sql.Wrapper;
3030
import java.util.Map;
31+
import java.util.UUID;
3132

3233
/**
3334
* A {@link Struct} but with metadata describing the instance.
@@ -76,6 +77,10 @@ public interface RelationalStruct extends Struct, Wrapper {
7677

7778
RelationalArray getArray(String fieldName) throws SQLException;
7879

80+
UUID getUUID(int oneBasedPosition) throws SQLException;
81+
82+
UUID getUUID(String fieldName) throws SQLException;
83+
7984
/**
8085
* Reports whether the last column read had a value of SQL NULL. See {@link ResultSet#wasNull()}
8186
*/

fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/SqlTypeNamesSupport.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.sql.Array;
2626
import java.sql.Struct;
2727
import java.sql.Types;
28+
import java.util.UUID;
2829

2930
/**
3031
* Class to host method taken from SqlTypeSupport needed by
@@ -116,6 +117,8 @@ public static int getSqlTypeCodeFromObject(Object obj) {
116117
return Types.ARRAY;
117118
} else if (obj instanceof Struct) {
118119
return Types.STRUCT;
120+
} else if (obj instanceof UUID) {
121+
return Types.OTHER;
119122
} else {
120123
throw new IllegalStateException("Unexpected object type: " + obj.getClass().getName());
121124
}

fdb-relational-core/src/main/java/com/apple/foundationdb/relational/api/RowStruct.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020

2121
package com.apple.foundationdb.relational.api;
2222

23+
import com.apple.foundationdb.record.TupleFieldsProto;
24+
import com.apple.foundationdb.record.metadata.expressions.TupleFieldsHelper;
2325
import com.apple.foundationdb.relational.api.exceptions.ErrorCode;
2426
import com.apple.foundationdb.relational.api.exceptions.InvalidColumnReferenceException;
2527
import com.apple.foundationdb.relational.api.exceptions.RelationalException;
2628
import com.apple.foundationdb.relational.api.exceptions.UncheckedRelationalException;
2729
import com.apple.foundationdb.relational.recordlayer.MessageTuple;
30+
import com.apple.foundationdb.relational.util.Assert;
2831
import com.apple.foundationdb.relational.util.NullableArrayUtils;
2932
import com.google.protobuf.ByteString;
3033
import com.google.protobuf.Descriptors;
@@ -36,6 +39,7 @@
3639
import java.util.ArrayList;
3740
import java.util.Collection;
3841
import java.util.Locale;
42+
import java.util.UUID;
3943

4044
/**
4145
* Implementation of {@link RelationalStruct} that is backed by a {@link Row}.
@@ -186,6 +190,19 @@ public Object getObject(int oneBasedPosition) throws SQLException {
186190
return getArray(oneBasedPosition);
187191
case Types.BINARY:
188192
return getBytes(oneBasedPosition);
193+
case Types.OTHER:
194+
final var object = getObjectInternal(getZeroBasedPosition(oneBasedPosition));
195+
// This is a temporary workaround to support UUID as a primitive type. The fix essentially involves
196+
// delaying the conversion of a message field (of type UUID) in the messageTuple until now when we can
197+
// (little bit) predict that the field is actually a pre-defined UUID message. If the UUID message
198+
// field is of sql.Types.OTHER (rather than sql.Types.STRUCT), we can expect that the plan is baked with
199+
// the future-supported UUID type, and hence the result expects a JAVA UUID object. This can be
200+
// removed (and pushed to MessageTuple) once we have proper and complete support for UUID.
201+
if (object instanceof TupleFieldsProto.UUID) {
202+
return TupleFieldsHelper.fromProto((TupleFieldsProto.UUID) object);
203+
} else {
204+
return object;
205+
}
189206
default:
190207
return getObjectInternal(getZeroBasedPosition(oneBasedPosition));
191208
}
@@ -295,6 +312,24 @@ public RelationalStruct getStruct(int oneBasedColumn) throws SQLException {
295312
}
296313
}
297314

315+
@Override
316+
public UUID getUUID(String columnLabel) throws SQLException {
317+
return getUUID(getOneBasedPosition(columnLabel));
318+
}
319+
320+
@Override
321+
public UUID getUUID(int oneBasedColumn) throws SQLException {
322+
if (metaData.getColumnType(oneBasedColumn) != Types.OTHER) {
323+
throw new SQLException("Expected UUID should have type OTHER", ErrorCode.CANNOT_CONVERT_TYPE.getErrorCode());
324+
}
325+
Object obj = getObjectInternal(getZeroBasedPosition(oneBasedColumn));
326+
if (obj == null) {
327+
return null;
328+
}
329+
Assert.thatUnchecked(obj instanceof UUID, ErrorCode.CANNOT_CONVERT_TYPE, "Expected UUID, got {}", obj.getClass().getName());
330+
return (UUID) obj;
331+
}
332+
298333
@Override
299334
public RelationalStruct getStruct(String columnLabel) throws SQLException {
300335
return getStruct(getOneBasedPosition(columnLabel));

fdb-relational-core/src/main/java/com/apple/foundationdb/relational/api/SqlTypeSupport.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ public static int recordTypeToSqlType(Type.TypeCode typeCode) {
9898
case VERSION:
9999
return Types.BINARY;
100100
case ENUM:
101-
//TODO(bfines) should be string?
101+
case UUID:
102+
// There are no specific JDBC types for ENUM and UUID, hence, defaulting to Types.OTHER.
102103
return Types.OTHER;
103104
case RECORD:
104105
return Types.STRUCT;
@@ -185,7 +186,7 @@ private static Type.Record.Field descriptionToField(@Nonnull FieldDescription de
185186
@Nonnull
186187
private static FieldDescription fieldToDescription(@Nonnull Type.Record.Field field) throws RelationalException {
187188
final Type fieldType = field.getFieldType();
188-
if (fieldType.isPrimitive() || fieldType instanceof Type.Enum) {
189+
if (fieldType.isPrimitive() || fieldType instanceof Type.Enum || fieldType instanceof Type.Uuid) {
189190
return FieldDescription.primitive(field.getFieldName(),
190191
SqlTypeSupport.recordTypeToSqlType(fieldType.getTypeCode()),
191192
fieldType.isNullable() ? DatabaseMetaData.columnNullable : DatabaseMetaData.columnNoNulls,

fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/AbstractRecordLayerResultSet.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.apple.foundationdb.relational.api.exceptions.RelationalException;
3333

3434
import java.sql.SQLException;
35+
import java.util.UUID;
3536

3637
public abstract class AbstractRecordLayerResultSet implements RelationalResultSet {
3738

@@ -208,6 +209,22 @@ public RelationalArray getArray(String columnLabel) throws SQLException {
208209
return currentRow.getArray(columnLabel);
209210
}
210211

212+
@Override
213+
public UUID getUUID(int oneBasedPosition) throws SQLException {
214+
if (!currentRow.hasRow()) {
215+
throw new SQLException("ResultSet exhausted", ErrorCode.INVALID_CURSOR_STATE.getErrorCode());
216+
}
217+
return currentRow.getUUID(oneBasedPosition);
218+
}
219+
220+
@Override
221+
public UUID getUUID(String columnLabel) throws SQLException {
222+
if (!currentRow.hasRow()) {
223+
throw new SQLException("ResultSet exhausted", ErrorCode.INVALID_CURSOR_STATE.getErrorCode());
224+
}
225+
return currentRow.getUUID(columnLabel);
226+
}
227+
211228
@Override
212229
public RelationalStruct getStruct(int oneBasedColumn) throws SQLException {
213230
if (!currentRow.hasRow()) {

fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/EmbeddedRelationalPreparedStatement.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.Locale;
3939
import java.util.Map;
4040
import java.util.TreeMap;
41+
import java.util.UUID;
4142

4243
@API(API.Status.EXPERIMENTAL)
4344
public class EmbeddedRelationalPreparedStatement extends AbstractEmbeddedStatement implements RelationalPreparedStatement {
@@ -189,6 +190,18 @@ public void setObject(String parameterName, Object x) throws SQLException {
189190
namedParameters.put(parameterName, x);
190191
}
191192

193+
@Override
194+
public void setUUID(final int parameterIndex, final UUID x) throws SQLException {
195+
checkOpen();
196+
parameters.put(parameterIndex, x);
197+
}
198+
199+
@Override
200+
public void setUUID(final String parameterName, final UUID x) throws SQLException {
201+
checkOpen();
202+
namedParameters.put(parameterName, x);
203+
}
204+
192205
@Override
193206
public void setNull(int parameterIndex, int sqlType) throws SQLException {
194207
checkOpen();

fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/ErrorCapturingResultSet.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import javax.annotation.Nonnull;
3232
import java.sql.SQLException;
33+
import java.util.UUID;
3334

3435
@API(API.Status.EXPERIMENTAL)
3536
public class ErrorCapturingResultSet implements RelationalResultSet {
@@ -233,6 +234,24 @@ public RelationalArray getArray(String columnLabel) throws SQLException {
233234
}
234235
}
235236

237+
@Override
238+
public UUID getUUID(final int oneBasedPosition) throws SQLException {
239+
try {
240+
return delegate.getUUID(oneBasedPosition);
241+
} catch (RuntimeException re) {
242+
throw ExceptionUtil.toRelationalException(re).toSqlException();
243+
}
244+
}
245+
246+
@Override
247+
public UUID getUUID(final String fieldName) throws SQLException {
248+
try {
249+
return delegate.getUUID(fieldName);
250+
} catch (RuntimeException re) {
251+
throw ExceptionUtil.toRelationalException(re).toSqlException();
252+
}
253+
}
254+
236255
@Override
237256
public boolean isClosed() throws SQLException {
238257
return delegate.isClosed();

fdb-relational-core/src/test/java/com/apple/foundationdb/relational/compare/JDBCDatabaseMetaData.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,14 @@
2525

2626
import javax.annotation.Nonnull;
2727
import java.sql.Connection;
28-
import java.sql.DatabaseMetaData;
2928
import java.sql.ResultSet;
3029
import java.sql.RowIdLifetime;
3130
import java.sql.SQLException;
3231

3332
public class JDBCDatabaseMetaData implements RelationalDatabaseMetaData {
34-
private final DatabaseMetaData metaData;
33+
private final RelationalDatabaseMetaData metaData;
3534

36-
public JDBCDatabaseMetaData(DatabaseMetaData metaData) {
35+
public JDBCDatabaseMetaData(RelationalDatabaseMetaData metaData) {
3736
this.metaData = metaData;
3837
}
3938

fdb-relational-core/src/test/java/com/apple/foundationdb/relational/compare/JDBCRelationalResultSet.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import java.sql.Date;
3838
import java.sql.NClob;
3939
import java.sql.Ref;
40-
import java.sql.ResultSet;
4140
import java.sql.RowId;
4241
import java.sql.SQLException;
4342
import java.sql.SQLFeatureNotSupportedException;
@@ -49,11 +48,12 @@
4948
import java.sql.Timestamp;
5049
import java.util.Calendar;
5150
import java.util.Map;
51+
import java.util.UUID;
5252

5353
public class JDBCRelationalResultSet implements RelationalResultSet {
54-
private final ResultSet delegate;
54+
private final RelationalResultSet delegate;
5555

56-
public JDBCRelationalResultSet(ResultSet resultSet) {
56+
public JDBCRelationalResultSet(RelationalResultSet resultSet) {
5757
delegate = resultSet;
5858
}
5959

@@ -576,7 +576,7 @@ public Clob getClob(int columnIndex) throws SQLException {
576576
@Override
577577
public RelationalArray getArray(int columnIndex) throws SQLException {
578578
//TODO(bfines) this almost certainly won't work
579-
return (RelationalArray) delegate.getArray(columnIndex);
579+
return delegate.getArray(columnIndex);
580580
}
581581

582582
@Override
@@ -601,8 +601,17 @@ public Clob getClob(String columnLabel) throws SQLException {
601601

602602
@Override
603603
public RelationalArray getArray(String columnLabel) throws SQLException {
604-
//TODO(bfines) this almost certainly won't work
605-
return (RelationalArray) delegate.getArray(columnLabel);
604+
return delegate.getArray(columnLabel);
605+
}
606+
607+
@Override
608+
public UUID getUUID(final int oneBasedPosition) throws SQLException {
609+
return delegate.getUUID(oneBasedPosition);
610+
}
611+
612+
@Override
613+
public UUID getUUID(final String fieldName) throws SQLException {
614+
return delegate.getUUID(fieldName);
606615
}
607616

608617
@Override

0 commit comments

Comments
 (0)