Skip to content

Commit 3f6b842

Browse files
authored
[PECO-1671] removed hard-coded precision, scale in ResultSetMetadata (#313)
* removed hard-coded precision, scale in ResultSetMetadata * Default value for timestamp, float, double changed * added method for scale and precision * code cov
1 parent 03cf782 commit 3f6b842

File tree

5 files changed

+142
-18
lines changed

5 files changed

+142
-18
lines changed

src/main/java/com/databricks/jdbc/core/DatabricksResultSetMetaData.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.databricks.jdbc.client.impl.thrift.generated.TColumnDesc;
88
import com.databricks.jdbc.client.impl.thrift.generated.TGetResultSetMetadataResp;
9+
import com.databricks.jdbc.client.impl.thrift.generated.TTypeEntry;
10+
import com.databricks.jdbc.client.impl.thrift.generated.TTypeQualifierValue;
911
import com.databricks.jdbc.client.sqlexec.ResultManifest;
1012
import com.databricks.jdbc.commons.LogLevel;
1113
import com.databricks.jdbc.commons.util.LoggingUtil;
@@ -55,14 +57,17 @@ public DatabricksResultSetMetaData(String statementId, ResultManifest resultMani
5557
if (resultManifest.getSchema().getColumnCount() > 0) {
5658
for (ColumnInfo columnInfo : resultManifest.getSchema().getColumns()) {
5759
ColumnInfoTypeName columnTypeName = columnInfo.getTypeName();
58-
int precision = DatabricksTypeUtil.getPrecision(columnTypeName);
60+
int[] scaleAndPrecision = getScaleAndPrecision(columnInfo, columnTypeName);
61+
int precision = scaleAndPrecision[0];
62+
int scale = scaleAndPrecision[1];
5963
ImmutableDatabricksColumn.Builder columnBuilder = getColumnBuilder();
6064
columnBuilder
6165
.columnName(columnInfo.getName())
6266
.columnTypeClassName(DatabricksTypeUtil.getColumnTypeClassName(columnTypeName))
6367
.columnType(DatabricksTypeUtil.getColumnType(columnTypeName))
6468
.columnTypeText(columnInfo.getTypeText())
6569
.typePrecision(precision)
70+
.typeScale(scale)
6671
.displaySize(DatabricksTypeUtil.getDisplaySize(columnTypeName, precision))
6772
.isSigned(DatabricksTypeUtil.isSigned(columnTypeName));
6873

@@ -92,14 +97,18 @@ public DatabricksResultSetMetaData(
9297
if (resultManifest.getSchema() != null && resultManifest.getSchema().getColumnsSize() > 0) {
9398
for (TColumnDesc columnInfo : resultManifest.getSchema().getColumns()) {
9499
ColumnInfoTypeName columnTypeName = getTypeFromTypeDesc(columnInfo.getTypeDesc());
95-
int precision = DatabricksTypeUtil.getPrecision(columnTypeName);
100+
int[] scaleAndPrecision = getScaleAndPrecision(columnInfo, columnTypeName);
101+
int precision = scaleAndPrecision[0];
102+
int scale = scaleAndPrecision[1];
103+
96104
ImmutableDatabricksColumn.Builder columnBuilder = getColumnBuilder();
97105
columnBuilder
98106
.columnName(columnInfo.getColumnName())
99107
.columnTypeClassName(DatabricksTypeUtil.getColumnTypeClassName(columnTypeName))
100108
.columnType(DatabricksTypeUtil.getColumnType(columnTypeName))
101109
.columnTypeText(columnTypeName.name())
102110
.typePrecision(precision)
111+
.typeScale(scale)
103112
.displaySize(DatabricksTypeUtil.getDisplaySize(columnTypeName, precision))
104113
.isSigned(DatabricksTypeUtil.isSigned(columnTypeName));
105114
columnsBuilder.add(columnBuilder.build());
@@ -289,6 +298,33 @@ public Long getChunkCount() {
289298
return chunkCount;
290299
}
291300

301+
public int[] getScaleAndPrecision(ColumnInfo columnInfo, ColumnInfoTypeName columnTypeName) {
302+
int precision = DatabricksTypeUtil.getPrecision(columnTypeName);
303+
int scale = DatabricksTypeUtil.getScale(columnTypeName);
304+
if (columnInfo.getTypePrecision() != null) {
305+
precision = Math.toIntExact(columnInfo.getTypePrecision());
306+
scale = Math.toIntExact(columnInfo.getTypeScale());
307+
}
308+
return new int[] {precision, scale};
309+
}
310+
311+
public int[] getScaleAndPrecision(TColumnDesc columnInfo, ColumnInfoTypeName columnTypeName) {
312+
int precision = DatabricksTypeUtil.getPrecision(columnTypeName);
313+
int scale = DatabricksTypeUtil.getScale(columnTypeName);
314+
if (columnInfo.getTypeDesc() != null && columnInfo.getTypeDesc().getTypesSize() > 0) {
315+
TTypeEntry tTypeEntry = columnInfo.getTypeDesc().getTypes().get(0);
316+
if (tTypeEntry.isSetPrimitiveEntry()
317+
&& tTypeEntry.getPrimitiveEntry().isSetTypeQualifiers()
318+
&& tTypeEntry.getPrimitiveEntry().getTypeQualifiers().isSetQualifiers()) {
319+
Map<String, TTypeQualifierValue> qualifiers =
320+
tTypeEntry.getPrimitiveEntry().getTypeQualifiers().getQualifiers();
321+
scale = qualifiers.get("scale").getI32Value();
322+
precision = qualifiers.get("precision").getI32Value();
323+
}
324+
}
325+
return new int[] {precision, scale};
326+
}
327+
292328
private ImmutableDatabricksColumn.Builder getColumnBuilder() {
293329
return ImmutableDatabricksColumn.builder()
294330
.isAutoIncrement(false)

src/main/java/com/databricks/jdbc/core/DatabricksTypeUtil.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -265,18 +265,7 @@ public static int getScale(ColumnInfoTypeName typeName) {
265265
if (typeName == null) {
266266
return 0;
267267
}
268-
switch (typeName) {
269-
case FLOAT:
270-
return 7;
271-
case DOUBLE:
272-
return 15;
273-
case DECIMAL:
274-
return 10;
275-
case TIMESTAMP:
276-
return 6;
277-
default:
278-
return 0; // Default to 0 if unknown
279-
}
268+
return typeName == ColumnInfoTypeName.TIMESTAMP ? 9 : 0;
280269
}
281270

282271
public static boolean isSigned(ColumnInfoTypeName typeName) {

src/test/java/com/databricks/jdbc/core/DatabricksResultSetMetaDataTest.java

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
package com.databricks.jdbc.core;
22

3-
import com.databricks.jdbc.client.impl.thrift.generated.TColumnDesc;
4-
import com.databricks.jdbc.client.impl.thrift.generated.TGetResultSetMetadataResp;
5-
import com.databricks.jdbc.client.impl.thrift.generated.TTableSchema;
3+
import static com.databricks.jdbc.client.impl.thrift.commons.DatabricksThriftHelper.getTypeFromTypeDesc;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
6+
import com.databricks.jdbc.client.impl.thrift.generated.*;
67
import com.databricks.jdbc.client.sqlexec.ResultManifest;
78
import com.databricks.jdbc.driver.DatabricksJdbcConstants;
89
import com.databricks.sdk.service.sql.ColumnInfo;
910
import com.databricks.sdk.service.sql.ColumnInfoTypeName;
1011
import com.databricks.sdk.service.sql.ResultSchema;
1112
import java.sql.SQLException;
1213
import java.util.Collections;
14+
import java.util.HashMap;
1315
import java.util.List;
16+
import java.util.Map;
1417
import org.junit.jupiter.api.Assertions;
1518
import org.junit.jupiter.api.Test;
1619

@@ -25,6 +28,21 @@ public ColumnInfo getColumn(String name, ColumnInfoTypeName typeName, String typ
2528
return columnInfo;
2629
}
2730

31+
public TColumnDesc getThriftColumn(String name, TTypeDesc typeDesc) {
32+
TColumnDesc columnDesc = new TColumnDesc();
33+
columnDesc.setColumnName(name);
34+
columnDesc.setTypeDesc(typeDesc);
35+
return columnDesc;
36+
// TTypeDesc typeDesc = new TTypeDesc();
37+
// TTypeEntry typeEntry = new TTypeEntry();
38+
// TPrimitiveTypeEntry primitiveEntry = new TPrimitiveTypeEntry();
39+
// primitiveEntry.setTypeName(typeName);
40+
// typeEntry.setPrimitiveEntry(primitiveEntry);
41+
// typeDesc.setTypes(Collections.singletonList(typeEntry));
42+
// columnDesc.setTypeDesc(typeDesc);
43+
// return columnDesc;
44+
}
45+
2846
public ResultManifest getResultManifest() {
2947
ResultManifest manifest = new ResultManifest();
3048
manifest.setTotalRowCount(10L);
@@ -109,4 +127,66 @@ public void testEmptyAndNullThriftColumns() throws SQLException {
109127
resultSetMetadataResp.setSchema(new TTableSchema());
110128
Assertions.assertEquals(0, metaData.getColumnCount());
111129
}
130+
131+
@Test
132+
public void testGetScaleAndPrecisionWithColumnInfo() throws SQLException {
133+
DatabricksResultSetMetaData metaData =
134+
new DatabricksResultSetMetaData(STATEMENT_ID, getResultManifest());
135+
ColumnInfo decimalColumnInfo = getColumn("col1", ColumnInfoTypeName.DECIMAL, "decimal");
136+
decimalColumnInfo.setTypePrecision(10L);
137+
decimalColumnInfo.setTypeScale(2L);
138+
139+
int[] scaleAndPrecision =
140+
metaData.getScaleAndPrecision(decimalColumnInfo, decimalColumnInfo.getTypeName());
141+
assertEquals(10, scaleAndPrecision[0]);
142+
assertEquals(2, scaleAndPrecision[1]);
143+
144+
ColumnInfo stringColumnInfo = getColumn("col2", ColumnInfoTypeName.STRING, "string");
145+
scaleAndPrecision =
146+
metaData.getScaleAndPrecision(stringColumnInfo, stringColumnInfo.getTypeName());
147+
assertEquals(255, scaleAndPrecision[0]);
148+
assertEquals(0, scaleAndPrecision[1]);
149+
}
150+
151+
@Test
152+
public void testGetScaleAndPrecisionWithTColumnDesc() {
153+
DatabricksResultSetMetaData metaData =
154+
new DatabricksResultSetMetaData(STATEMENT_ID, getResultManifest());
155+
156+
TColumnDesc columnInfo = new TColumnDesc();
157+
TTypeDesc typeDesc = new TTypeDesc();
158+
TTypeEntry typeEntry = new TTypeEntry();
159+
TPrimitiveTypeEntry primitiveEntry = new TPrimitiveTypeEntry(TTypeId.DECIMAL_TYPE);
160+
Map<String, TTypeQualifierValue> qualifiers = new HashMap<>();
161+
TTypeQualifierValue scaleValue = new TTypeQualifierValue();
162+
scaleValue.setI32Value(2);
163+
TTypeQualifierValue precisionValue = new TTypeQualifierValue();
164+
precisionValue.setI32Value(10);
165+
qualifiers.put("scale", scaleValue);
166+
qualifiers.put("precision", precisionValue);
167+
TTypeQualifiers typeQualifiers = new TTypeQualifiers().setQualifiers(qualifiers);
168+
primitiveEntry.setTypeQualifiers(typeQualifiers);
169+
typeEntry.setPrimitiveEntry(primitiveEntry);
170+
typeDesc.setTypes(Collections.singletonList(typeEntry));
171+
columnInfo.setTypeDesc(typeDesc);
172+
173+
int[] scaleAndPrecision =
174+
metaData.getScaleAndPrecision(columnInfo, getTypeFromTypeDesc(columnInfo.getTypeDesc()));
175+
assertEquals(10, scaleAndPrecision[0]);
176+
assertEquals(2, scaleAndPrecision[1]);
177+
178+
// Test with string type
179+
columnInfo = new TColumnDesc();
180+
typeDesc = new TTypeDesc();
181+
typeEntry = new TTypeEntry();
182+
primitiveEntry = new TPrimitiveTypeEntry(TTypeId.STRING_TYPE);
183+
typeEntry.setPrimitiveEntry(primitiveEntry);
184+
typeDesc.setTypes(Collections.singletonList(typeEntry));
185+
columnInfo.setTypeDesc(typeDesc);
186+
187+
scaleAndPrecision =
188+
metaData.getScaleAndPrecision(columnInfo, getTypeFromTypeDesc(columnInfo.getTypeDesc()));
189+
assertEquals(255, scaleAndPrecision[0]);
190+
assertEquals(0, scaleAndPrecision[1]);
191+
}
112192
}

src/test/java/com/databricks/jdbc/core/DatabricksTypeUtilTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ public void testGetColumnInfoType(String inputTypeName, String expectedTypeName)
226226
}
227227

228228
@ParameterizedTest
229-
@CsvSource({"FLOAT, 7", "DOUBLE, 15", "DECIMAL, 10", "TIMESTAMP, 6", "STRING, 0", "NULL, 0"})
229+
@CsvSource({"FLOAT, 0", "DOUBLE, 0", "DECIMAL, 0", "TIMESTAMP, 9", "STRING, 0", "NULL, 0"})
230230
void testGetScale(ColumnInfoTypeName typeName, int expectedScale) {
231231
assertEquals(
232232
expectedScale,

src/test/java/com/databricks/jdbc/local/DriverTester.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,25 @@ void testGetTablesOSS_StatementExecution() throws Exception {
6060
con.close();
6161
}
6262

63+
@Test
64+
void testResultSetMetaData() throws Exception {
65+
DriverManager.registerDriver(new Driver());
66+
String jdbcUrl =
67+
"jdbc:databricks://e2-dogfood.staging.cloud.databricks.com:443/default;transportMode=http;ssl=1;AuthMech=3;httpPath=/sql/1.0/warehouses/58aa1b363649e722";
68+
69+
Connection con = DriverManager.getConnection(jdbcUrl, "user", "x");
70+
System.out.println("Connection established with jdbc driver......");
71+
Statement statement = con.createStatement();
72+
statement.setMaxRows(10000);
73+
ResultSet rs =
74+
statement.executeQuery(
75+
"select * from ml.feature_store_ol_dynamodb_.test_ft_data_types LIMIT 10");
76+
printResultSet(rs);
77+
rs.close();
78+
statement.close();
79+
con.close();
80+
}
81+
6382
@Test
6483
void testGetTablesOSS_Metadata() throws Exception {
6584
DriverManager.registerDriver(new Driver());

0 commit comments

Comments
 (0)