Skip to content

Commit 629a5ef

Browse files
committed
[CALCITE-1466] Support for UNSIGNED types of TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT in type system
1 parent 0b2cba6 commit 629a5ef

File tree

7 files changed

+276
-53
lines changed

7 files changed

+276
-53
lines changed

core/src/main/java/org/apache/calcite/avatica/AvaticaResultSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ public ResultSetMetaData getMetaData() throws SQLException {
392392
public Object getObject(int columnIndex) throws SQLException {
393393
final Cursor.Accessor accessor = getAccessor(columnIndex);
394394
final ColumnMetaData metaData = columnMetaDataList.get(columnIndex - 1);
395-
return AvaticaSite.get(accessor, metaData.type.id, localCalendar);
395+
return AvaticaSite.get(accessor, metaData.type.id, metaData.signed, localCalendar);
396396
}
397397

398398
public Object getObject(String columnLabel) throws SQLException {

core/src/main/java/org/apache/calcite/avatica/AvaticaSite.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ public void setObject(Object x, int targetSqlType) {
291291

292292
/** Similar logic to {@link #setObject}. */
293293
public static Object get(Cursor.Accessor accessor, int targetSqlType,
294-
Calendar localCalendar) throws SQLException {
294+
boolean signed, Calendar localCalendar) throws SQLException {
295295
switch (targetSqlType) {
296296
case Types.CLOB:
297297
case Types.DATALINK:
@@ -304,6 +304,9 @@ public static Object get(Cursor.Accessor accessor, int targetSqlType,
304304
case Types.ARRAY:
305305
return accessor.getArray();
306306
case Types.BIGINT:
307+
if (!signed) {
308+
return accessor.wasNull() ? null : accessor.getBigDecimal().toBigInteger();
309+
}
307310
final long aLong = accessor.getLong();
308311
if (aLong == 0 && accessor.wasNull()) {
309312
return null;
@@ -337,6 +340,9 @@ public static Object get(Cursor.Accessor accessor, int targetSqlType,
337340
}
338341
return aDouble;
339342
case Types.INTEGER:
343+
if (!signed) {
344+
return accessor.wasNull() ? null : accessor.getLong();
345+
}
340346
final int anInt = accessor.getInt();
341347
if (anInt == 0 && accessor.wasNull()) {
342348
return null;
@@ -362,6 +368,9 @@ public static Object get(Cursor.Accessor accessor, int targetSqlType,
362368
case Types.ROWID:
363369
throw notImplemented();
364370
case Types.SMALLINT:
371+
if (!signed) {
372+
return accessor.wasNull() ? null : accessor.getInt();
373+
}
365374
final short aShort = accessor.getShort();
366375
if (aShort == 0 && accessor.wasNull()) {
367376
return null;
@@ -372,6 +381,9 @@ public static Object get(Cursor.Accessor accessor, int targetSqlType,
372381
case Types.TIMESTAMP:
373382
return accessor.getTimestamp(localCalendar);
374383
case Types.TINYINT:
384+
if (!signed) {
385+
return accessor.wasNull() ? null : accessor.getShort();
386+
}
375387
final byte aByte = accessor.getByte();
376388
if (aByte == 0 && accessor.wasNull()) {
377389
return null;

core/src/main/java/org/apache/calcite/avatica/MetaImpl.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,12 @@ public static ColumnMetaData columnMetaData(String name, int index,
221221

222222
public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
223223
boolean columnNullable) {
224-
return columnMetaData(name, index, type, intForColumnNullable(columnNullable));
224+
return columnMetaData(name, index, type, intForColumnNullable(columnNullable), true);
225+
}
226+
227+
public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
228+
boolean columnNullable, boolean signed) {
229+
return columnMetaData(name, index, type, intForColumnNullable(columnNullable), signed);
225230
}
226231

227232
public static ColumnMetaData columnMetaData(String name, int index,
@@ -231,15 +236,20 @@ public static ColumnMetaData columnMetaData(String name, int index,
231236
ColumnMetaData.Rep.VALUE_MAP.get(type);
232237
ColumnMetaData.AvaticaType scalarType =
233238
ColumnMetaData.scalar(pair.sqlType, pair.sqlTypeName, rep);
234-
return columnMetaData(name, index, scalarType, columnNullable);
239+
return columnMetaData(name, index, scalarType, columnNullable, true);
235240
}
236241

237242
public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
238243
int columnNullable) {
244+
return columnMetaData(name, index, type, columnNullable, true);
245+
}
246+
247+
public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
248+
int columnNullable, boolean signed) {
239249
return new ColumnMetaData(
240250
index, false, true, false, false,
241251
columnNullable,
242-
true, -1, name, name, null,
252+
signed, -1, name, name, null,
243253
0, 0, null, null, type, true, false, false,
244254
type.columnClassName());
245255
}

core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,15 @@ protected Accessor createAccessor(ColumnMetaData columnMetaData,
102102
}
103103
switch (columnMetaData.type.id) {
104104
case Types.TINYINT:
105-
return new ByteAccessor(getter);
105+
return columnMetaData.signed ? new ByteAccessor(getter) : new ShortAccessor(getter);
106106
case Types.SMALLINT:
107-
return new ShortAccessor(getter);
107+
return columnMetaData.signed ? new ShortAccessor(getter) : new IntAccessor(getter);
108108
case Types.INTEGER:
109-
return new IntAccessor(getter);
109+
return columnMetaData.signed ? new IntAccessor(getter) : new LongAccessor(getter);
110110
case Types.BIGINT:
111-
return new LongAccessor(getter);
111+
return columnMetaData.signed
112+
? new LongAccessor(getter)
113+
: new NumberAccessor(getter, columnMetaData.scale);
112114
case Types.BOOLEAN:
113115
case Types.BIT:
114116
return new BooleanAccessor(getter);

core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java

Lines changed: 115 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.io.InputStream;
3434
import java.io.Reader;
3535
import java.math.BigDecimal;
36+
import java.math.BigInteger;
3637
import java.net.URL;
3738
import java.sql.Array;
3839
import java.sql.Blob;
@@ -147,46 +148,70 @@ public TestMetaImpl(AvaticaConnection connection) {
147148
ColumnMetaData.scalar(Types.SMALLINT, "SMALLINT",
148149
ColumnMetaData.Rep.PRIMITIVE_SHORT),
149150
DatabaseMetaData.columnNoNulls),
150-
columnMetaData("int", 3,
151+
columnMetaData("medium", 3,
152+
ColumnMetaData.scalar(Types.INTEGER, "MEDIUMINT",
153+
ColumnMetaData.Rep.PRIMITIVE_INT),
154+
DatabaseMetaData.columnNoNulls),
155+
columnMetaData("int", 4,
151156
ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
152157
ColumnMetaData.Rep.PRIMITIVE_INT),
153158
DatabaseMetaData.columnNoNulls),
154-
columnMetaData("long", 4,
159+
columnMetaData("long", 5,
155160
ColumnMetaData.scalar(Types.BIGINT, "BIGINT",
156161
ColumnMetaData.Rep.PRIMITIVE_LONG),
157162
DatabaseMetaData.columnNoNulls),
158-
columnMetaData("float", 5,
163+
columnMetaData("byte_unsigned", 6,
164+
ColumnMetaData.scalar(Types.TINYINT, "TINYINT_UNSIGNED",
165+
ColumnMetaData.Rep.PRIMITIVE_SHORT),
166+
DatabaseMetaData.columnNoNulls, false),
167+
columnMetaData("short_unsigned", 7,
168+
ColumnMetaData.scalar(Types.SMALLINT, "SMALLINT_UNSIGNED",
169+
ColumnMetaData.Rep.PRIMITIVE_INT),
170+
DatabaseMetaData.columnNoNulls, false),
171+
columnMetaData("medium_unsigned", 8,
172+
ColumnMetaData.scalar(Types.INTEGER, "MEDIUMINT_UNSIGNED",
173+
ColumnMetaData.Rep.PRIMITIVE_INT),
174+
DatabaseMetaData.columnNoNulls, false),
175+
columnMetaData("int_unsigned", 9,
176+
ColumnMetaData.scalar(Types.INTEGER, "INTEGER_UNSIGNED",
177+
ColumnMetaData.Rep.PRIMITIVE_LONG),
178+
DatabaseMetaData.columnNoNulls, false),
179+
columnMetaData("long_unsigned", 10,
180+
ColumnMetaData.scalar(Types.BIGINT, "BIGINT_UNSIGNED",
181+
ColumnMetaData.Rep.NUMBER),
182+
DatabaseMetaData.columnNoNulls, false),
183+
columnMetaData("float", 11,
159184
ColumnMetaData.scalar(Types.REAL, "REAL",
160185
ColumnMetaData.Rep.FLOAT),
161186
DatabaseMetaData.columnNoNulls),
162-
columnMetaData("double", 6,
187+
columnMetaData("double", 12,
163188
ColumnMetaData.scalar(Types.FLOAT, "FLOAT",
164189
ColumnMetaData.Rep.DOUBLE),
165190
DatabaseMetaData.columnNoNulls),
166-
columnMetaData("string", 7,
191+
columnMetaData("string", 13,
167192
ColumnMetaData.scalar(Types.VARCHAR, "VARCHAR",
168193
ColumnMetaData.Rep.STRING),
169194
DatabaseMetaData.columnNoNulls),
170-
columnMetaData("date", 8,
195+
columnMetaData("date", 14,
171196
ColumnMetaData.scalar(Types.DATE, "DATE",
172197
ColumnMetaData.Rep.JAVA_SQL_DATE),
173198
DatabaseMetaData.columnNoNulls),
174-
columnMetaData("time", 9,
199+
columnMetaData("time", 15,
175200
ColumnMetaData.scalar(Types.TIME, "TIME",
176201
ColumnMetaData.Rep.JAVA_SQL_TIME),
177202
DatabaseMetaData.columnNoNulls),
178-
columnMetaData("timestamp", 10,
203+
columnMetaData("timestamp", 16,
179204
ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP",
180205
ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP),
181206
DatabaseMetaData.columnNoNulls),
182-
columnMetaData("array", 11,
207+
columnMetaData("array", 17,
183208
ColumnMetaData.array(
184209
ColumnMetaData.scalar(Types.INTEGER, "INTEGER",
185210
ColumnMetaData.Rep.PRIMITIVE_INT),
186211
"ARRAY",
187212
ColumnMetaData.Rep.ARRAY),
188213
DatabaseMetaData.columnNoNulls),
189-
columnMetaData("struct", 12,
214+
columnMetaData("struct", 18,
190215
ColumnMetaData.struct(
191216
Arrays.asList(
192217
columnMetaData("int", 0,
@@ -198,36 +223,36 @@ public TestMetaImpl(AvaticaConnection connection) {
198223
ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
199224
DatabaseMetaData.columnNoNulls))),
200225
DatabaseMetaData.columnNoNulls),
201-
columnMetaData("bit", 13,
226+
columnMetaData("bit", 19,
202227
ColumnMetaData.scalar(Types.BIT, "BIT",
203228
ColumnMetaData.Rep.PRIMITIVE_BOOLEAN),
204229
DatabaseMetaData.columnNoNulls),
205-
columnMetaData("null", 14,
230+
columnMetaData("null", 20,
206231
ColumnMetaData.scalar(Types.NULL, "NULL",
207232
ColumnMetaData.Rep.OBJECT),
208233
DatabaseMetaData.columnNullable),
209-
columnMetaData("date_array", 15,
234+
columnMetaData("date_array", 21,
210235
ColumnMetaData.array(
211236
ColumnMetaData.scalar(Types.DATE, "DATE",
212237
ColumnMetaData.Rep.PRIMITIVE_INT),
213238
"ARRAY",
214239
ColumnMetaData.Rep.ARRAY),
215240
DatabaseMetaData.columnNoNulls),
216-
columnMetaData("timestamp_array", 16,
241+
columnMetaData("timestamp_array", 22,
217242
ColumnMetaData.array(
218243
ColumnMetaData.scalar(Types.TIMESTAMP, "TIMESTAMP",
219244
ColumnMetaData.Rep.PRIMITIVE_LONG),
220245
"ARRAY",
221246
ColumnMetaData.Rep.ARRAY),
222247
DatabaseMetaData.columnNoNulls),
223-
columnMetaData("time_array", 17,
248+
columnMetaData("time_array", 23,
224249
ColumnMetaData.array(
225250
ColumnMetaData.scalar(Types.TIME, "TIME",
226251
ColumnMetaData.Rep.NUMBER),
227252
"ARRAY",
228253
ColumnMetaData.Rep.ARRAY),
229254
DatabaseMetaData.columnNoNulls),
230-
columnMetaData("decimal_array", 18,
255+
columnMetaData("decimal_array", 24,
231256
ColumnMetaData.array(
232257
ColumnMetaData.scalar(Types.DECIMAL, "DECIMAL",
233258
ColumnMetaData.Rep.PRIMITIVE_DOUBLE),
@@ -237,7 +262,8 @@ public TestMetaImpl(AvaticaConnection connection) {
237262

238263
List<Object> row = Collections.<Object>singletonList(
239264
new Object[] {
240-
true, (byte) 1, (short) 2, 3, 4L, 5.0f, 6.0d, "testvalue",
265+
true, (byte) 1, (short) 2, 3, 3, 4L, (short) 2, 3, 4L, 4L,
266+
new BigInteger("7"), 5.0f, 6.0d, "testvalue",
241267
new Date(DST_INSTANT), new Time(DST_INSTANT),
242268
new Timestamp(DST_INSTANT),
243269
Arrays.asList(1, 2, 3),
@@ -910,6 +936,51 @@ private LongAccessorTestHelper(Getter g) {
910936
}
911937
}
912938

939+
/**
940+
* Accessor test helper for the long unsigned column.
941+
*/
942+
private static final class LongUnsingedAccessorTestHelper extends AccessorTestHelper {
943+
private LongUnsingedAccessorTestHelper(Getter g) {
944+
super(g);
945+
}
946+
947+
@Override public void testGetString(ResultSet resultSet) throws SQLException {
948+
assertEquals("7", g.getString(resultSet));
949+
}
950+
951+
@Override public void testGetBoolean(ResultSet resultSet) throws SQLException {
952+
assertEquals(true, g.getBoolean(resultSet));
953+
}
954+
955+
@Override public void testGetByte(ResultSet resultSet) throws SQLException {
956+
assertEquals((byte) 7, g.getByte(resultSet));
957+
}
958+
959+
@Override public void testGetShort(ResultSet resultSet) throws SQLException {
960+
assertEquals((short) 7, g.getShort(resultSet));
961+
}
962+
963+
@Override public void testGetInt(ResultSet resultSet) throws SQLException {
964+
assertEquals(7, g.getInt(resultSet));
965+
}
966+
967+
@Override public void testGetLong(ResultSet resultSet) throws SQLException {
968+
assertEquals(7L, g.getLong(resultSet));
969+
}
970+
971+
@Override public void testGetDecimal(ResultSet resultSet) throws SQLException {
972+
assertEquals(new BigDecimal(7), g.getBigDecimal(resultSet));
973+
}
974+
975+
@Override public void testGetFloat(ResultSet resultSet) throws SQLException {
976+
assertEquals(7.0f, g.getFloat(resultSet), 0);
977+
}
978+
979+
@Override public void testGetDouble(ResultSet resultSet) throws SQLException {
980+
assertEquals(7.0d, g.getDouble(resultSet), 0);
981+
}
982+
}
983+
913984
/**
914985
* accessor test helper for the float column
915986
*/
@@ -1169,36 +1240,48 @@ public static Collection<AccessorTestHelper> data() {
11691240
new ShortAccessorTestHelper(new OrdinalGetter(3)),
11701241
new ShortAccessorTestHelper(new LabelGetter("short")),
11711242
new IntAccessorTestHelper(new OrdinalGetter(4)),
1243+
new IntAccessorTestHelper(new LabelGetter("medium")),
1244+
new IntAccessorTestHelper(new OrdinalGetter(5)),
11721245
new IntAccessorTestHelper(new LabelGetter("int")),
1173-
new LongAccessorTestHelper(new OrdinalGetter(5)),
1246+
new LongAccessorTestHelper(new OrdinalGetter(6)),
11741247
new LongAccessorTestHelper(new LabelGetter("long")),
1175-
new FloatAccessorTestHelper(new OrdinalGetter(6)),
1248+
new ShortAccessorTestHelper(new OrdinalGetter(7)),
1249+
new ShortAccessorTestHelper(new LabelGetter("byte_unsigned")),
1250+
new IntAccessorTestHelper(new OrdinalGetter(8)),
1251+
new IntAccessorTestHelper(new LabelGetter("short_unsigned")),
1252+
new LongAccessorTestHelper(new OrdinalGetter(9)),
1253+
new LongAccessorTestHelper(new LabelGetter("medium_unsigned")),
1254+
new LongAccessorTestHelper(new OrdinalGetter(10)),
1255+
new LongAccessorTestHelper(new LabelGetter("int_unsigned")),
1256+
new LongUnsingedAccessorTestHelper(new OrdinalGetter(11)),
1257+
new LongUnsingedAccessorTestHelper(new LabelGetter("long_unsigned")),
1258+
new FloatAccessorTestHelper(new OrdinalGetter(12)),
11761259
new FloatAccessorTestHelper(new LabelGetter("float")),
1177-
new DoubleAccessorTestHelper(new OrdinalGetter(7)),
1260+
new DoubleAccessorTestHelper(new OrdinalGetter(13)),
11781261
new DoubleAccessorTestHelper(new LabelGetter("double")),
1179-
new StringAccessorTestHelper(new OrdinalGetter(8)),
1262+
new StringAccessorTestHelper(new OrdinalGetter(14)),
11801263
new StringAccessorTestHelper(new LabelGetter("string")),
1181-
new DateAccessorTestHelper(new OrdinalGetter(9)),
1264+
new DateAccessorTestHelper(new OrdinalGetter(15)),
11821265
new DateAccessorTestHelper(new LabelGetter("date")),
1183-
new TimeAccessorTestHelper(new OrdinalGetter(10)),
1266+
new TimeAccessorTestHelper(new OrdinalGetter(16)),
11841267
new TimeAccessorTestHelper(new LabelGetter("time")),
1185-
new TimestampAccessorTestHelper(new OrdinalGetter(11)),
1268+
new TimestampAccessorTestHelper(new OrdinalGetter(17)),
11861269
new TimestampAccessorTestHelper(new LabelGetter("timestamp")),
1187-
new ArrayAccessorTestHelper(new OrdinalGetter(12)),
1270+
new ArrayAccessorTestHelper(new OrdinalGetter(18)),
11881271
new ArrayAccessorTestHelper(new LabelGetter("array")),
1189-
new StructAccessorTestHelper(new OrdinalGetter(13)),
1272+
new StructAccessorTestHelper(new OrdinalGetter(19)),
11901273
new StructAccessorTestHelper(new LabelGetter("struct")),
1191-
new BooleanAccessorTestHelper(new OrdinalGetter(14)),
1274+
new BooleanAccessorTestHelper(new OrdinalGetter(20)),
11921275
new BooleanAccessorTestHelper(new LabelGetter("bit")),
1193-
new NullObjectAccessorTestHelper(new OrdinalGetter(15)),
1276+
new NullObjectAccessorTestHelper(new OrdinalGetter(21)),
11941277
new NullObjectAccessorTestHelper(new LabelGetter("null")),
1195-
new DateArrayAccessorTestHelper(new OrdinalGetter(16)),
1278+
new DateArrayAccessorTestHelper(new OrdinalGetter(22)),
11961279
new DateArrayAccessorTestHelper(new LabelGetter("date_array")),
1197-
new TimestampArrayAccessorTestHelper(new OrdinalGetter(17)),
1280+
new TimestampArrayAccessorTestHelper(new OrdinalGetter(23)),
11981281
new TimestampArrayAccessorTestHelper(new LabelGetter("timestamp_array")),
1199-
new TimeArrayAccessorTestHelper(new OrdinalGetter(18)),
1282+
new TimeArrayAccessorTestHelper(new OrdinalGetter(24)),
12001283
new TimeArrayAccessorTestHelper(new LabelGetter("time_array")),
1201-
new DecimalArrayAccessorTestHelper(new OrdinalGetter(19)),
1284+
new DecimalArrayAccessorTestHelper(new OrdinalGetter(25)),
12021285
new DecimalArrayAccessorTestHelper(new LabelGetter("decimal_array")));
12031286
}
12041287

0 commit comments

Comments
 (0)