Skip to content

Commit

Permalink
Return null instead of default value for nullable types
Browse files Browse the repository at this point in the history
  • Loading branch information
zhicwu committed Jul 4, 2022
1 parent 2f2f2ea commit 70612d8
Show file tree
Hide file tree
Showing 16 changed files with 111 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ default boolean isNaN() {
return v != v;
}

/**
* Checks whether the value is nullable. This always returns {@code false} for
* nested value type.
*
* @return true if the value is nullable; false otherwise
*/
default boolean isNullable() {
return true;
}

/**
* Checks if the value is null, or empty for non-null types like Array, Tuple
* and Map.
Expand Down Expand Up @@ -485,7 +495,7 @@ default <K, V> Map<K, V> asMap(Class<K> keyClass, Class<V> valueClass) {
* @return a typed object representing the value, could be null
*/
default <T, E extends Enum<E>> T asObject(Class<T> clazz) {
if (clazz == null) {
if (clazz == null || (isNullable() && isNullOrEmpty())) {
return null;
} else if (clazz == boolean.class || clazz == Boolean.class) {
return clazz.cast(asBoolean());
Expand Down Expand Up @@ -531,6 +541,8 @@ default <T, E extends Enum<E>> T asObject(Class<T> clazz) {
return clazz.cast(asArray());
} else if (List.class.isAssignableFrom(clazz)) {
return clazz.cast(asTuple());
} else if (Map.class.isAssignableFrom(clazz)) {
return clazz.cast(asMap());
} else if (Enum.class.isAssignableFrom(clazz)) {
return clazz.cast(asEnum((Class<E>) clazz));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public ClickHouseArrayValue<T> copy(boolean deep) {
return new ClickHouseArrayValue<>(newValue);
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ public ClickHouseBitmapValue copy(boolean deep) {
return new ClickHouseBitmapValue(getValue());
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ public String asString(int length, Charset charset) {
return convert(getValue(), length);
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ public String asString(int length, Charset charset) {
return convert(getValue(), length);
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ public String asString(int length, Charset charset) {
return convert(getValue(), length);
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ public String asString(int length, Charset charset) {
return convert(getValue(), length);
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
double[][] value = getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ public String asString(int length, Charset charset) {
return str;
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
Object[][] value = getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ public List<Object> asTuple() {
return getValue();
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public ClickHouseByteArrayValue copy(boolean deep) {
return new ClickHouseByteArrayValue(Arrays.copyOf(value, value.length));
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public ClickHouseDoubleArrayValue copy(boolean deep) {
return new ClickHouseDoubleArrayValue(Arrays.copyOf(value, value.length));
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public ClickHouseFloatArrayValue copy(boolean deep) {
return new ClickHouseFloatArrayValue(Arrays.copyOf(value, value.length));
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public ClickHouseIntArrayValue copy(boolean deep) {
return new ClickHouseIntArrayValue(Arrays.copyOf(value, value.length));
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public ClickHouseLongArrayValue copy(boolean deep) {
return new ClickHouseLongArrayValue(Arrays.copyOf(value, value.length));
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public ClickHouseShortArrayValue copy(boolean deep) {
return new ClickHouseShortArrayValue(Arrays.copyOf(value, value.length));
}

@Override
public boolean isNullable() {
return false;
}

@Override
public boolean isNullOrEmpty() {
return getValue().length == 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.clickhouse.jdbc;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
Expand Down Expand Up @@ -90,28 +91,28 @@ public Object apply(ResultSet rs, Integer i) {
@DataProvider(name = "nullableColumns")
private Object[][] getNullableColumns() {
return new Object[][] {
new Object[] { "Bool", "false" },
new Object[] { "Date", "1970-01-01" },
new Object[] { "Date32", "1970-01-01" },
new Object[] { "DateTime32('UTC')", "1970-01-01 00:00:00" },
new Object[] { "DateTime64(3, 'UTC')", "1970-01-01 00:00:00" },
new Object[] { "Decimal(10,4)", "0" },
new Object[] { "Enum8('x'=0,'y'=1)", "x" },
new Object[] { "Enum16('xx'=1,'yy'=0)", "yy" },
new Object[] { "Float32", "0.0" },
new Object[] { "Float64", "0.0" },
new Object[] { "Int8", "0" },
new Object[] { "UInt8", "0" },
new Object[] { "Int16", "0" },
new Object[] { "UInt16", "0" },
new Object[] { "Int32", "0" },
new Object[] { "UInt32", "0" },
new Object[] { "Int64", "0" },
new Object[] { "UInt64", "0" },
new Object[] { "Int128", "0" },
new Object[] { "UInt128", "0" },
new Object[] { "Int256", "0" },
new Object[] { "UInt256", "0" },
new Object[] { "Bool", "false", Boolean.class },
new Object[] { "Date", "1970-01-01", LocalDate.class },
new Object[] { "Date32", "1970-01-01", LocalDate.class },
new Object[] { "DateTime32('UTC')", "1970-01-01 00:00:00", LocalDateTime.class },
new Object[] { "DateTime64(3, 'UTC')", "1970-01-01 00:00:00", OffsetDateTime.class },
new Object[] { "Decimal(10,4)", "0", BigDecimal.class },
new Object[] { "Enum8('x'=0,'y'=1)", "x", Integer.class },
new Object[] { "Enum16('xx'=1,'yy'=0)", "yy", String.class },
new Object[] { "Float32", "0.0", Float.class },
new Object[] { "Float64", "0.0", Double.class },
new Object[] { "Int8", "0", Byte.class },
new Object[] { "UInt8", "0", Short.class },
new Object[] { "Int16", "0", Short.class },
new Object[] { "UInt16", "0", Integer.class },
new Object[] { "Int32", "0", Integer.class },
new Object[] { "UInt32", "0", Long.class },
new Object[] { "Int64", "0", Long.class },
new Object[] { "UInt64", "0", BigInteger.class },
new Object[] { "Int128", "0", BigInteger.class },
new Object[] { "UInt128", "0", BigInteger.class },
new Object[] { "Int256", "0", BigInteger.class },
new Object[] { "UInt256", "0", BigInteger.class },
};
}

Expand Down Expand Up @@ -296,7 +297,7 @@ public void testNullableValues(ClickHouseDataType type, Object value, BiFunction
}

@Test(dataProvider = "nullableColumns", groups = "integration")
public void testNullValue(String columnType, String defaultValue) throws Exception {
public void testNullValue(String columnType, String defaultValue, Class<?> clazz) throws Exception {
Properties props = new Properties();
props.setProperty(JdbcConfig.PROP_NULL_AS_DEFAULT, "2");
String tableName = "test_query_null_value_" + columnType.split("\\(")[0].trim().toLowerCase();
Expand All @@ -312,6 +313,8 @@ public void testNullValue(String columnType, String defaultValue) throws Excepti
Assert.assertTrue(rs.next(), "Should have at least one row");
Assert.assertEquals(rs.getInt(1), 1);
Assert.assertEquals(rs.getString(2), defaultValue);
Assert.assertNotNull(rs.getObject(2));
Assert.assertNotNull(rs.getObject(2, clazz));
Assert.assertFalse(rs.wasNull(), "Should not be null");
Assert.assertFalse(rs.next(), "Should have only one row");
}
Expand All @@ -321,6 +324,7 @@ public void testNullValue(String columnType, String defaultValue) throws Excepti
Assert.assertTrue(rs.next(), "Should have at least one row");
Assert.assertEquals(rs.getInt(1), 1);
Assert.assertEquals(rs.getString(2), null);
Assert.assertEquals(rs.getObject(2, clazz), null);
Assert.assertTrue(rs.wasNull(), "Should be null");
Assert.assertFalse(rs.next(), "Should have only one row");
}
Expand All @@ -330,6 +334,7 @@ public void testNullValue(String columnType, String defaultValue) throws Excepti
Assert.assertTrue(rs.next(), "Should have at least one row");
Assert.assertEquals(rs.getInt(1), 1);
Assert.assertEquals(rs.getString(2), null);
Assert.assertEquals(rs.getObject(2, clazz), null);
Assert.assertTrue(rs.wasNull(), "Should be null");
Assert.assertFalse(rs.next(), "Should have only one row");
}
Expand Down

0 comments on commit 70612d8

Please sign in to comment.