Skip to content

Commit

Permalink
WIP(FIR-38126): struct type
Browse files Browse the repository at this point in the history
  • Loading branch information
ptiurin committed Dec 6, 2024
1 parent e367f7d commit 98a40fa
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,40 @@ void shouldInsertAndSelectGeography() throws SQLException {
}
}

@Test
@Tag("v2")
void shouldInsertAndSelectStruct() throws SQLException {
Car car1 = Car.builder().make("Ford").sales(12345).ts(new Timestamp(2)).d(new Date(3)).build();

// TODO: use prepared statement ddl for more complex type
executeStatementFromFile("/statements/statement/ddl.sql");
try (Connection connection = createConnection()) {

try (PreparedStatement statement = connection
.prepareStatement("INSERT INTO statement_test (id) VALUES (?)")) {
statement.setLong(1, car1.getSales());
// statement.setString(2, car1.getMake());
// statement.setTimestamp(3, car1.getTs());
// statement.setDate(4, car1.getD());
statement.executeUpdate();
}
setParam(connection, "advanced_mode", "true");
setParam(connection, "enable_row_selection", "true");
try (Statement statement = connection.createStatement();
ResultSet rs = statement
.executeQuery("SELECT statement_test FROM statement_test")) {
rs.next();
assertEquals(FireboltDataType.STRUCT.name().toLowerCase() + "(id long null)",
rs.getMetaData().getColumnTypeName(1).toLowerCase());
String expectedJson = String.format("{\"id\":\"%d\"}",
car1.getSales());
assertEquals(expectedJson, rs.getString(1));
}
} finally {
executeStatementFromFile("/statements/statement/cleanup.sql");
}
}

private QueryResult createExpectedResult(List<List<?>> expectedRows) {
return QueryResult.builder().databaseName(ConnectionInfo.getInstance().getDatabase())
.tableName("prepared_statement_test")
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/firebolt/jdbc/resultset/column/ColumnType.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.stream.Collectors;

import static com.firebolt.jdbc.type.FireboltDataType.ARRAY;
import static com.firebolt.jdbc.type.FireboltDataType.STRUCT;
import static com.firebolt.jdbc.type.FireboltDataType.TUPLE;
import static com.firebolt.jdbc.type.FireboltDataType.ofType;

Expand Down Expand Up @@ -62,6 +63,8 @@ public static ColumnType of(String columnType) {
innerDataTypes = getCollectionSubType(FireboltDataType.ARRAY, typeWithoutNullKeyword);
} else if (isType(FireboltDataType.TUPLE, typeWithoutNullKeyword)) {
innerDataTypes = getCollectionSubType(FireboltDataType.TUPLE, typeWithoutNullKeyword);
} else if (isType(FireboltDataType.STRUCT, typeWithoutNullKeyword)) {
innerDataTypes = getCollectionSubType(FireboltDataType.STRUCT, typeWithoutNullKeyword);
}

int typeEndIndex = getTypeEndPosition(typeWithoutNullKeyword);
Expand Down Expand Up @@ -108,6 +111,8 @@ private static List<ColumnType> getCollectionSubType(FireboltDataType fireboltDa
if (fireboltDataType.equals(TUPLE)) {
types = typeWithoutNullKeyword.split(",(?![^()]*\\))"); // Regex to split on comma and ignoring comma that are between
// parenthesis
} else if (fireboltDataType.equals(STRUCT)) {
types = typeWithoutNullKeyword.split(",");
} else {
types = new String[] {typeWithoutNullKeyword};
}
Expand Down Expand Up @@ -177,6 +182,8 @@ public String getCompactTypeName() {
return getArrayCompactTypeName();
} else if (isTuple()) {
return getTupleCompactTypeName(innerTypes);
} else if (isStruct()) {
return name;
} else {
return dataType.getDisplayName();
}
Expand Down Expand Up @@ -209,6 +216,10 @@ private boolean isTuple() {
return dataType.equals(TUPLE);
}

private boolean isStruct() {
return dataType.equals(STRUCT);
}

public ColumnType getArrayBaseColumnType() {
if (innerTypes == null || innerTypes.isEmpty()) {
return null;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/firebolt/jdbc/type/FireboltDataType.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public enum FireboltDataType {
TUPLE(Types.OTHER, FireboltDataTypeDisplayNames.TUPLE, BaseType.OBJECT, false, true, 0, 0, 0, false,"Tuple"),
BYTEA(Types.BINARY, FireboltDataTypeDisplayNames.BYTEA, BaseType.BYTEA, false, true, 0, 0, 0, false, "ByteA"),
GEOGRAPHY(Types.VARCHAR, FireboltDataTypeDisplayNames.GEOGRAPHY, BaseType.TEXT, false, false, 0, 0, 0, false,
"Geography");
"Geography"),
STRUCT(Types.VARCHAR, FireboltDataTypeDisplayNames.STRUCT, BaseType.TEXT, false, false, 0, 0, 0, false, "Struct");

private static final Map<String, FireboltDataType> typeNameOrAliasToType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ public class FireboltDataTypeDisplayNames {
static final String TUPLE = "tuple";
static final String BYTEA = "bytea";
static final String GEOGRAPHY = "geography";
static final String STRUCT = "struct";
}
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,26 @@ void shouldReturnGeography() throws SQLException {
assertEquals(Types.VARCHAR, resultSet.getMetaData().getColumnType(9));
}

@Test
void shouldReturnStruct() throws SQLException {
inputStream = getInputStreamWithStruct();
resultSet = createResultSet(inputStream);
resultSet.next();
// TODO: is this correct null handling?
assertEquals("{\"a\": N}", resultSet.getObject(3));
assertEquals("{\"a\": N}", resultSet.getObject("an_empty_struct"));
assertEquals("{\"a\": 1}", resultSet.getObject(4));
assertEquals("{\"a\": 1}", resultSet.getObject("a_struct"));
// Returns native JDBC type
for (int i = 3; i <= 5; i++) {
assertEquals(Types.VARCHAR, resultSet.getMetaData().getColumnType(i));
}

assertEquals("STRUCT(A INT NULL)", resultSet.getMetaData().getColumnTypeName(3));
assertEquals("STRUCT(A INT)", resultSet.getMetaData().getColumnTypeName(4));
assertEquals("STRUCT(A INT)", resultSet.getMetaData().getColumnTypeName(5));
}

@Test
void shouldBeCaseInsensitive() throws SQLException {
inputStream = getInputStreamWithCommonResponseExample();
Expand Down Expand Up @@ -1552,6 +1572,10 @@ private InputStream getInputStreamWithArray() {
return FireboltResultSetTest.class.getResourceAsStream("/responses/firebolt-response-with-array");
}

private InputStream getInputStreamWithStruct() {
return FireboltResultSetTest.class.getResourceAsStream("/responses/firebolt-response-with-struct-nofalse");
}

private ResultSet createResultSet(InputStream is) throws SQLException {
return new FireboltResultSet(is, "a_table", "a_db", 65535, false, fireboltStatement, true);
}
Expand Down

0 comments on commit 98a40fa

Please sign in to comment.