Skip to content

Commit

Permalink
Support dates<1583 for SQL Server connector
Browse files Browse the repository at this point in the history
  • Loading branch information
hovaesco authored and findepi committed Apr 21, 2021
1 parent c8e99e3 commit 62b7756
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.trino.plugin.jdbc.JdbcSplit;
import io.trino.plugin.jdbc.JdbcTableHandle;
import io.trino.plugin.jdbc.JdbcTypeHandle;
import io.trino.plugin.jdbc.LongReadFunction;
import io.trino.plugin.jdbc.LongWriteFunction;
import io.trino.plugin.jdbc.RemoteTableName;
import io.trino.plugin.jdbc.SliceWriteFunction;
Expand Down Expand Up @@ -68,7 +69,9 @@
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -86,8 +89,6 @@
import static io.trino.plugin.jdbc.StandardColumnMappings.booleanColumnMapping;
import static io.trino.plugin.jdbc.StandardColumnMappings.booleanWriteFunction;
import static io.trino.plugin.jdbc.StandardColumnMappings.charWriteFunction;
import static io.trino.plugin.jdbc.StandardColumnMappings.dateColumnMapping;
import static io.trino.plugin.jdbc.StandardColumnMappings.dateWriteFunction;
import static io.trino.plugin.jdbc.StandardColumnMappings.decimalColumnMapping;
import static io.trino.plugin.jdbc.StandardColumnMappings.defaultCharColumnMapping;
import static io.trino.plugin.jdbc.StandardColumnMappings.defaultVarcharColumnMapping;
Expand Down Expand Up @@ -139,6 +140,8 @@ public class SqlServerClient
// SqlServer supports 2100 parameters in prepared statement, let's create a space for about 4 big IN predicates
public static final int SQL_SERVER_MAX_LIST_EXPRESSIONS = 500;

private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

private static final Joiner DOT_JOINER = Joiner.on(".");

private final boolean snapshotIsolationDisabled;
Expand Down Expand Up @@ -279,7 +282,10 @@ public Optional<ColumnMapping> toColumnMapping(ConnectorSession session, Connect
return Optional.of(varbinaryColumnMapping());

case Types.DATE:
return Optional.of(dateColumnMapping());
return Optional.of(ColumnMapping.longMapping(
DATE,
sqlServerDateReadFunction(),
sqlServerDateWriteFunction()));

case Types.TIME:
TimeType timeType = createTimeType(typeHandle.getRequiredDecimalDigits());
Expand Down Expand Up @@ -350,7 +356,7 @@ public WriteMapping toWriteMapping(ConnectorSession session, Type type)
}

if (type == DATE) {
return WriteMapping.longMapping("date", dateWriteFunction());
return WriteMapping.longMapping("date", sqlServerDateWriteFunction());
}

if (type instanceof TimeType) {
Expand Down Expand Up @@ -399,6 +405,16 @@ public void set(PreparedStatement statement, int index, long picosOfDay)
};
}

private static LongWriteFunction sqlServerDateWriteFunction()
{
return (statement, index, day) -> statement.setString(index, DATE_FORMATTER.format(LocalDate.ofEpochDay(day)));
}

private static LongReadFunction sqlServerDateReadFunction()
{
return (resultSet, index) -> LocalDate.parse(resultSet.getString(index), DATE_FORMATTER).toEpochDay();
}

@Override
public Optional<JdbcExpression> implementAggregation(ConnectorSession session, AggregateFunction aggregate, Map<String, ColumnHandle> assignments)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,14 @@ public void testDate()
LocalDate dateOfLocalTimeChangeBackwardAtMidnightInSomeZone = LocalDate.of(1983, 10, 1);
checkIsDoubled(someZone, dateOfLocalTimeChangeBackwardAtMidnightInSomeZone.atStartOfDay().minusMinutes(1));

// BC dates not supported by SQL Server
SqlDataTypeTest testsSqlServer = SqlDataTypeTest.create()
.addRoundTrip("date", "NULL", DATE, "CAST(NULL AS DATE)")
// first day of AD
.addRoundTrip("date", "'0001-01-01'", DATE, "DATE '0001-01-01'")
.addRoundTrip("date", "'0012-12-12'", DATE, "DATE '0012-12-12'")
// before julian->gregorian switch
.addRoundTrip("date", "'1500-01-01'", DATE, "DATE '1500-01-01'")
// before epoch
.addRoundTrip("date", "'1952-04-03'", DATE, "DATE '1952-04-03'")
.addRoundTrip("date", "'1970-01-01'", DATE, "DATE '1970-01-01'")
Expand All @@ -316,6 +322,11 @@ public void testDate()

SqlDataTypeTest testsTrino = SqlDataTypeTest.create()
.addRoundTrip("date", "NULL", DATE, "CAST(NULL AS DATE)")
// first day of AD
.addRoundTrip("date", "DATE '0001-01-01'", DATE, "DATE '0001-01-01'")
.addRoundTrip("date", "DATE '0012-12-12'", DATE, "DATE '0012-12-12'")
// before julian->gregorian switch
.addRoundTrip("date", "DATE '1500-01-01'", DATE, "DATE '1500-01-01'")
// before epoch
.addRoundTrip("date", "DATE '1952-04-03'", DATE, "DATE '1952-04-03'")
.addRoundTrip("date", "DATE '1970-01-01'", DATE, "DATE '1970-01-01'")
Expand Down

0 comments on commit 62b7756

Please sign in to comment.