Skip to content
Open
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 @@ -512,6 +512,7 @@ public static void appendToSpannerKey(
case DATE:
case STRING:
case TIMESTAMP:
case UUID:
keyBuilder.append(keysJsonObject.getString(name));
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,13 @@ private static TableFieldSchema tableRowColumnsToBigQueryIOField(String name, St
"PG_NUMERIC",
"PG_JSONB",
"STRING",
"TIMESTAMP"
"TIMESTAMP",
"UUID"
};
Set<String> supportedTypes = Set.of(supportedTypesArr);
if (type.startsWith("ARRAY")) {
String arrayItemType = type.substring(6, type.length() - 1);

if (supportedTypes.contains(arrayItemType)) {
if (arrayItemType.equals("PG_NUMERIC")) {
bigQueryField.setType("STRING");
Expand All @@ -114,6 +116,8 @@ private static TableFieldSchema tableRowColumnsToBigQueryIOField(String name, St
} else if (arrayItemType.equals("FLOAT32")) {
// BigQuery does not support the FLOAT32 type.
bigQueryField.setType("FLOAT64");
} else if (arrayItemType.equals("UUID")) {
Comment thread
googledrew marked this conversation as resolved.
bigQueryField.setType("STRING");
} else {
bigQueryField.setType(arrayItemType);
}
Expand All @@ -136,6 +140,8 @@ private static TableFieldSchema tableRowColumnsToBigQueryIOField(String name, St
} else if (type.equals("FLOAT32")) {
// BigQuery does not support the FLOAT32 type.
bigQueryField.setType("FLOAT64");
} else if (type.equals("UUID")) {
bigQueryField.setType("STRING");
Comment thread
googledrew marked this conversation as resolved.
} else {
bigQueryField.setType(type);
}
Expand Down Expand Up @@ -203,11 +209,16 @@ private static Object getColumnValueFromResultSet(
return removeNulls(resultSet.getPgJsonbList(columnName));
} else if (columnType.equals(Type.array(Type.string()))) {
return removeNulls(resultSet.getStringList(columnName));
} else if (columnType.equals(Type.array(Type.uuid()))) {
return removeNulls(resultSet.getStringList(columnName));
} else if (columnType.equals(Type.array(Type.timestamp()))) {
return removeNulls(resultSet.getTimestampList(columnName)).stream()
.map(e -> e.toString())
.collect(Collectors.toList());
} else {
if (columnType.equals(Type.uuid())) {
return resultSet.getString(columnName);
}
Type.Code columnTypeCode = columnType.getCode();
switch (columnTypeCode) {
case BOOL:
Expand Down Expand Up @@ -242,6 +253,7 @@ private static Object getColumnValueFromResultSet(
}

private static <T> List<T> removeNulls(List<T> list) {

return list.stream().filter(Objects::nonNull).collect(Collectors.toList());
}

Expand Down Expand Up @@ -310,7 +322,8 @@ public static void addSpannerNonPkColumnsToTableRow(
|| columnType.equals(Type.array(Type.pgNumeric()))
|| columnType.equals(Type.array(Type.pgJsonb()))
|| columnType.equals(Type.array(Type.string()))
|| columnType.equals(Type.array(Type.timestamp()))) {
|| columnType.equals(Type.array(Type.timestamp()))
|| columnType.equals(Type.array(Type.uuid()))) {
JSONArray jsonArray = newValuesJsonObject.getJSONArray(columnName);
List<Object> objects = new ArrayList<>(jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public static Type informationSchemaGoogleSQLTypeToSpannerType(String type) {
return Type.string();
case "TIMESTAMP":
return Type.timestamp();
case "UUID":
return Type.uuid();
default:
if (type.startsWith("ARRAY")) {
// Get array type, e.g. "ARRAY<STRING>" -> "STRING".
Expand Down Expand Up @@ -93,6 +95,8 @@ public static Type informationSchemaPostgreSQLTypeToSpannerType(String type) {
return Type.timestamp();
case "SPANNER.COMMIT_TIMESTAMP":
return Type.timestamp();
case "UUID":
Comment thread
googledrew marked this conversation as resolved.
return Type.uuid();
default:
throw new IllegalArgumentException(
String.format("Unsupported Spanner PostgreSQL type: %s", type));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1101,4 +1101,176 @@ public void testCleanSpannerType() {
assertThat(SpannerToBigQueryUtils.cleanSpannerType("ARRAY<NUMERIC<PG_NUMERIC>>"))
.isEqualTo("ARRAY<NUMERIC>");
}

@Test
public void testTableRowColumnsToBigQueryIOFields_UUID() {
TableRow tableRow = new TableRow();
// GoogleSQL UUID
tableRow.put("GsqlUuidCol", "");
tableRow.put("_type_GsqlUuidCol", "UUID");
// GoogleSQL ARRAY<UUID>
tableRow.put("GsqlUuidArrCol", "");
tableRow.put("_type_GsqlUuidArrCol", "ARRAY<UUID>");
// PostgreSQL UUID (treated as STRING)
tableRow.put("PgUuidCol", "");
tableRow.put("_type_PgUuidCol", "STRING");
// PostgreSQL UUID[] (treated as ARRAY<STRING>)
tableRow.put("PgUuidArrCol", "");
tableRow.put("_type_PgUuidArrCol", "ARRAY<STRING>");

List<TableFieldSchema> expectedFields =
ImmutableList.of(
new TableFieldSchema()
.setName("GsqlUuidCol")
.setMode(Field.Mode.NULLABLE.name())
.setType("STRING"),
new TableFieldSchema()
.setName("GsqlUuidArrCol")
.setMode(Field.Mode.REPEATED.name())
.setType("STRING"),
new TableFieldSchema()
.setName("PgUuidCol")
.setMode(Field.Mode.NULLABLE.name())
.setType("STRING"),
new TableFieldSchema()
.setName("PgUuidArrCol")
.setMode(Field.Mode.REPEATED.name())
.setType("STRING"));

List<TableFieldSchema> actualFields =
SpannerToBigQueryUtils.tableRowColumnsToBigQueryIOFields(tableRow, false);
assertThat(actualFields).containsExactlyElementsIn(expectedFields);
}

@Test
public void testSpannerSnapshotRowToBigQueryTableRow_GoogleSQL_UUID() {
String colName = "GsqlUuidCol";
String uuidVal = "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11";
TrackedSpannerColumn column = TrackedSpannerColumn.create(colName, Type.uuid(), 1, -1);
List<TrackedSpannerColumn> spannerColumns = ImmutableList.of(column);
TableRow tableRow = new TableRow();

ResultSet resultSet = Mockito.mock(ResultSet.class);
when(resultSet.next()).thenReturn(true).thenReturn(false);
when(resultSet.isNull(colName)).thenReturn(false);
when(resultSet.getString(colName)).thenReturn(uuidVal);
SpannerToBigQueryUtils.spannerSnapshotRowToBigQueryTableRow(
resultSet, spannerColumns, tableRow);

assertThat(tableRow.get(colName)).isEqualTo(uuidVal);
}

@Test
public void testSpannerSnapshotRowToBigQueryTableRow_GoogleSQL_ARRAY_UUID() {
String colName = "GsqlUuidArrCol";
List<String> uuidList =
ImmutableList.of(
"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", "b1eebc99-9c0b-4ef8-bb6d-6bb9bd380a12");
List<String> expectedList =
ImmutableList.of(
"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", "b1eebc99-9c0b-4ef8-bb6d-6bb9bd380a12");
TrackedSpannerColumn column =
TrackedSpannerColumn.create(colName, Type.array(Type.uuid()), 1, -1);
List<TrackedSpannerColumn> spannerColumns = ImmutableList.of(column);
TableRow tableRow = new TableRow();
ResultSet resultSet = Mockito.mock(ResultSet.class);
when(resultSet.next()).thenReturn(true).thenReturn(false);
when(resultSet.isNull(colName)).thenReturn(false);
when(resultSet.getStringList(colName)).thenReturn(uuidList);
SpannerToBigQueryUtils.spannerSnapshotRowToBigQueryTableRow(
resultSet, spannerColumns, tableRow);

assertThat(tableRow.get(colName)).isEqualTo(expectedList);
}

@Test
public void testSpannerSnapshotRowToBigQueryTableRow_PostgreSQL_UUID() {
String colName = "PgUuidCol";
String uuidVal = "c0eebc99-9c0b-4ef8-bb6d-6bb9bd380a13";
// PG UUID is treated as Type.string()
TrackedSpannerColumn column = TrackedSpannerColumn.create(colName, Type.string(), 1, -1);
List<TrackedSpannerColumn> spannerColumns = ImmutableList.of(column);
TableRow tableRow = new TableRow();
List<Type.StructField> structFields =
ImmutableList.of(Type.StructField.of(colName, Type.string()));

ResultSet resultSet =
ResultSets.forRows(
Type.struct(structFields),
Collections.singletonList(
Struct.newBuilder().set(colName).to(Value.string(uuidVal)).build()));
SpannerToBigQueryUtils.spannerSnapshotRowToBigQueryTableRow(
resultSet, spannerColumns, tableRow);
assertThat(tableRow.get(colName)).isEqualTo(uuidVal);
}

@Test
public void testSpannerSnapshotRowToBigQueryTableRow_GoogleSQL_UUID_PK() {
String pkColName = "Id";
String nonPkColName = "Value";
String uuidPkVal = "d0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14";
String stringVal = "TestData";

TrackedSpannerColumn pkColumn = TrackedSpannerColumn.create(pkColName, Type.uuid(), 1, 1);
TrackedSpannerColumn nonPkColumn =
TrackedSpannerColumn.create(nonPkColName, Type.string(), 2, -1);
List<TrackedSpannerColumn> spannerColumns = ImmutableList.of(pkColumn, nonPkColumn);
TableRow tableRow = new TableRow();

ResultSet resultSet = Mockito.mock(ResultSet.class);
when(resultSet.next()).thenReturn(true).thenReturn(false);
when(resultSet.isNull(pkColName)).thenReturn(false);
when(resultSet.getString(pkColName)).thenReturn(uuidPkVal);
when(resultSet.isNull(nonPkColName)).thenReturn(false);
when(resultSet.getString(nonPkColName)).thenReturn(stringVal);

SpannerToBigQueryUtils.spannerSnapshotRowToBigQueryTableRow(
resultSet, spannerColumns, tableRow);

assertThat(tableRow.get(pkColName)).isEqualTo(uuidPkVal);
assertThat(tableRow.get(nonPkColName)).isEqualTo(stringVal);
}

@Test
public void testAddSpannerNonPkColumnsToTableRow_GoogleSQL_ARRAY_UUID() throws Exception {
String colName = "GsqlUuidArrCol";
List<String> uuidList =
ImmutableList.of(
"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", "b1eebc99-9c0b-4ef8-bb6d-6bb9bd380a12");
String newValuesJson =
"{\""
+ colName
+ "\":[\"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11\", \"b1eebc99-9c0b-4ef8-bb6d-6bb9bd380a12\"]}";
TrackedSpannerColumn column =
TrackedSpannerColumn.create(colName, Type.array(Type.uuid()), 1, -1);
List<TrackedSpannerColumn> spannerColumns = ImmutableList.of(column);
TableRow tableRow = new TableRow();

SpannerToBigQueryUtils.addSpannerNonPkColumnsToTableRow(
newValuesJson, spannerColumns, tableRow, ModType.INSERT);

assertThat(tableRow.get(colName)).isInstanceOf(List.class);
assertThat((List<String>) tableRow.get(colName)).containsExactlyElementsIn(uuidList);
assertThat(tableRow.get("_type_" + colName)).isEqualTo("ARRAY<UUID>");
}

@Test
public void testAddSpannerNonPkColumnsToTableRow_GoogleSQL_ARRAY_UUID_WithNulls()
throws Exception {
String colName = "GsqlUuidArrCol";
List<String> expectedUuidList = ImmutableList.of("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11");
String newValuesJson = "{\"" + colName + "\":[\"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11\", null]}";
TrackedSpannerColumn column =
TrackedSpannerColumn.create(colName, Type.array(Type.uuid()), 1, -1);
List<TrackedSpannerColumn> spannerColumns = ImmutableList.of(column);
TableRow tableRow = new TableRow();

SpannerToBigQueryUtils.addSpannerNonPkColumnsToTableRow(
newValuesJson, spannerColumns, tableRow, ModType.INSERT);

assertThat(tableRow.get(colName)).isInstanceOf(List.class);
// Nulls should be filtered out
assertThat((List<String>) tableRow.get(colName)).containsExactlyElementsIn(expectedUuidList);
assertThat(tableRow.get("_type_" + colName)).isEqualTo("ARRAY<UUID>");
}
Comment thread
googledrew marked this conversation as resolved.
}
Loading
Loading