Skip to content
Merged
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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ The Databend type is mapped to Java type as follows:
| Date | LocalDate |
| Timestamp | ZonedDateTime |
| Timestamp_TZ | OffsetDateTime |
| Interval | String |
| Interval | Duration |
| Geometry | byte[] |
| Bitmap | byte[] |
| Array | String |
Expand All @@ -126,6 +126,7 @@ void setObject(int parameterIndex, Object x)
- TIMESTAMP_TZ and TIMESTAMP map to `OffsetDateTime`, `ZonedDateTime`, `Instant` and `LocalDateTime` (TIMESTAMP_TZ can return `OffsetDateTime` but not `ZonedDateTime`).
- Date maps to `LocalDate`
- When parameters do not contain a timezone, Databend uses the session timezone (not the JVM zone) when storing/returning dates on databend-jdbc ≥ 0.4.3 AND databend-query ≥1.2.844.
- Interval map to `java.time.Duration`.

old Timestamp/Date are also supported, note that:

Expand All @@ -135,6 +136,8 @@ old Timestamp/Date are also supported, note that:
- `setDate`/`getDate` still use the JVM timezone, `getDate(1)` is equivalent to `Date.valueOf(getObject(1, LocalDate.class))`, `setDate(1, date)` is equivalent to `setObject(1, date.toLocalDate())`.




# Unwrapping to Databend-specific interfaces

## interface DatabendConnection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.databend.client.QueryRowField;
import com.databend.client.data.DatabendDataType;
import com.databend.client.data.DatabendRawType;
import com.databend.client.data.DatabendTypes;
import com.databend.client.errors.QueryErrors;
import com.databend.jdbc.annotation.NotImplemented;
import com.databend.jdbc.exception.DatabendUnsupportedOperationException;
Expand Down Expand Up @@ -44,11 +45,8 @@
import static java.util.Objects.requireNonNull;

abstract class AbstractDatabendResultSet implements ResultSet {
protected AtomicLong lastRequestTime = new AtomicLong();

static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE;

private static final long SECONDS_PER_DAY = 86_400L;
private static final long[] POWERS_OF_TEN = {
1L,
10L,
Expand Down Expand Up @@ -716,7 +714,18 @@ public ResultSetMetaData getMetaData()
@Override
public Object getObject(int columnIndex)
throws SQLException {
return column(columnIndex);
Object value = column(columnIndex);
if (value == null) {
return null;
}
DatabendRawType databendRawType = this.databendColumnInfoList.get(columnIndex - 1).getType();
if (DatabendRawType.startsWithIgnoreCase(databendRawType.getType(), DatabendTypes.INTERVAL)) {
if (!(value instanceof String)) {
throw new SQLDataException("Interval value is not textual: " + value.getClass().getName());
}
return Interval.decode((String) value);
}
return value;
}

@Override
Expand Down Expand Up @@ -1028,25 +1037,25 @@ public void updateNull(String columnLabel)
@Override
public void updateObject(int columnIndex, Object x, SQLType targetSqlType, int scaleOrLength)
throws SQLException {
this.updateObject(columnIndex, x, targetSqlType, scaleOrLength);
throw new SQLFeatureNotSupportedException("updateObject");
}

@Override
public void updateObject(String columnLabel, Object x, SQLType targetSqlType, int scaleOrLength)
throws SQLException {
this.updateObject(columnLabel, x, targetSqlType, scaleOrLength);
throw new SQLFeatureNotSupportedException("updateObject");
}

@Override
public void updateObject(int columnIndex, Object x, SQLType targetSqlType)
throws SQLException {
this.updateObject(columnIndex, x, targetSqlType);
throw new SQLFeatureNotSupportedException("updateObject");
}

@Override
public void updateObject(String columnLabel, Object x, SQLType targetSqlType)
throws SQLException {
this.updateObject(columnLabel, x, targetSqlType);
throw new SQLFeatureNotSupportedException("updateObject");
}

@Override
Expand Down Expand Up @@ -1700,7 +1709,7 @@ public <T> T getObject(int columnIndex, Class<T> type)
DatabendRawType databendRawType = this.databendColumnInfoList.get(columnIndex - 1).getType();

if (type == LocalDate.class) {
return type.cast( LocalDate.parse((String)value));
return type.cast(LocalDate.parse((String) value));
}

if (type == Instant.class) {
Expand All @@ -1715,6 +1724,17 @@ public <T> T getObject(int columnIndex, Class<T> type)
return type.cast(getZonedDateTimeNotNull((String) value, databendRawType));
}

if (type == Duration.class) {
Object intervalValue = getObject(columnIndex);
if (intervalValue == null) {
return null;
}
if (!(intervalValue instanceof Duration)) {
throw new SQLDataException(invalidColumnType(databendRawType, "Duration"));
}
return type.cast(intervalValue);
}

return (T) value;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,11 @@ public void setObject(int parameterIndex, Object x, int targetSqlType)
case Types.NVARCHAR:
case Types.LONGVARCHAR:
case Types.LONGNVARCHAR:
setString(parameterIndex, x.toString());
if (x instanceof Duration) {
setDurationLiteral(parameterIndex, (Duration) x);
} else {
setString(parameterIndex, x.toString());
}
return;
case Types.BINARY:
InputStream blobInputStream = new ByteArrayInputStream(x.toString().getBytes());
Expand All @@ -514,6 +518,13 @@ public void setObject(int parameterIndex, Object x, int targetSqlType)
case Types.TIMESTAMP_WITH_TIMEZONE:
setString(parameterIndex, toTimestampWithTimeZoneLiteral(x));
return;
case Types.OTHER:
case Types.JAVA_OBJECT:
if (x instanceof Duration) {
setDurationLiteral(parameterIndex, (Duration) x);
return;
}
break;
}
throw new SQLException("Unsupported target SQL type: " + targetSqlType);
}
Expand Down Expand Up @@ -562,6 +573,8 @@ public void setObject(int parameterIndex, Object x)
setString(parameterIndex, toTimestampLiteral(x));
} else if (x instanceof ZonedDateTime) {
setString(parameterIndex, toTimestampLiteral(x));
} else if (x instanceof Duration) {
setDurationLiteral(parameterIndex, (Duration) x);
} else if (x instanceof Map) {
setString(parameterIndex, convertToJsonString((Map<?, ?>) x));
} else if (x instanceof Array) {
Expand Down Expand Up @@ -599,6 +612,14 @@ public static String convertArrayListToString(ArrayList<?> arrayList) {
return builder.toString();
}

private void setDurationLiteral(int parameterIndex, Duration duration) throws SQLException {
try {
setString(parameterIndex, Interval.encode(duration));
} catch (IllegalArgumentException ex) {
throw new SQLException("Failed to encode Duration for interval parameter", ex);
}
}

@Override
public void addBatch()
throws SQLException {
Expand Down
Loading
Loading