Skip to content

Commit

Permalink
Merge pull request #237 from antonycourtney/use-iso-string-reltab
Browse files Browse the repository at this point in the history
add all available timestamp types to the column type map
  • Loading branch information
hamilton authored Oct 16, 2023
2 parents aac06e5 + d027f38 commit 16f1740
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 12 deletions.
44 changes: 33 additions & 11 deletions packages/reltab-duckdb/test/basic.auto.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,35 +371,57 @@ test("DuckDb date type", async () => {
`);
});

test("DuckDb timestamp type", async () => {
test("DuckDb timestamp types", async () => {
const dbc = testCtx;
const dbds = dbc as DbDataSource;
const driver = dbds.db as reltabDuckDB.DuckDBDriver;

await driver.runSqlQuery("create table tstamp_ttest(t timestamp); ");
await driver.runSqlQuery(
"insert into tstamp_ttest values ('1991-07-21 11:30:00');"
);
const d1 = "1991-07-21T11:30:00.000Z";
const d2 = "2022-02-11T14:15:45.000Z";

// NOTE:
// fully uniform results with duckdb-node blocked on https://github.com/duckdb/duckdb-node/issues/13.
// Once this issue is fixed, we can comment out the timestamp_ns, timestamp_ms, and timestamp_s
// columns and add the results to the snapshot.
await driver.runSqlQuery(
"insert into tstamp_ttest values ('2022-02-11 14:15:45');"
`
create table timestamp_test as (
select '${d1}' as t,
cast('${d1}' as TIMESTAMP WITH TIME ZONE) as tz,
-- cast('${d1}' as timestamp_ns) as t_ns,
-- cast('${d1}' as timestamp_ms) as t_ms,
-- cast('${d1}' as timestamp_s) as t_s,
cast('${d1}' as datetime) as dt,
cast('${d1}' as date) as d
UNION ALL select
'${d2}' as t,
cast('${d2}' as TIMESTAMP WITH TIME ZONE) as tz,
-- cast('${d2}' as timestamp_ns) as t_ns,
-- cast('${d2}' as timestamp_ms) as t_ms,
-- cast('${d2}' as timestamp_s) as t_s,
cast('${d2}' as datetime) as dt,
cast('${d2}' as date) as d
);`
);

const q0 = tableQuery("tstamp_ttest");
const q0 = tableQuery("timestamp_test");
const q0res = await dbc.evalQuery(q0);
// console.log("q0res: ", q0res);
// const rowData = q0res.rowData;
// console.log("rowData: ", rowData);

const fmtRows = getFormattedRows(q0res);
// console.log("fmtRows: ", fmtRows);

expect(fmtRows).toMatchInlineSnapshot(`
Array [
Array [
"1991-07-21T11:30:00.000Z",
"1991-07-21T11:30:00.000Z",
"1991-07-21T11:30:00.000Z",
"1991-07-21",
],
Array [
"2022-02-11T14:15:45.000Z",
"2022-02-11T14:15:45.000Z",
"2022-02-11T14:15:45.000Z",
"2022-02-11",
],
]
`);
Expand Down
60 changes: 59 additions & 1 deletion packages/reltab/src/dialects/DuckDBDialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ const realCT = new ColumnType("DOUBLE", "real");
const textCT = new ColumnType("VARCHAR", "string");
const boolCT = new ColumnType("BOOL", "boolean");

const timestampCT = new ColumnType("TIMESTAMP", "timestamp", {
const createTimestampStringRenderer = (dateOnly = false) => ({
stringRender: (val: any) => {
if (val == null) {
return "";
}
let retStr: string;
try {
retStr = new Date(val).toISOString();
if (dateOnly) retStr = retStr.split("T")[0];
} catch (err) {
if (err instanceof RangeError) {
console.info(
Expand All @@ -35,6 +36,56 @@ const timestampCT = new ColumnType("TIMESTAMP", "timestamp", {
},
});

// see https://duckdb.org/docs/sql/data_types/timestamp
// for timestamp type coverage.
const timestampCT = new ColumnType(
"TIMESTAMP",
"timestamp",
createTimestampStringRenderer()
);

const timestampNSCT = new ColumnType(
"TIMESTAMP_NS",
"timestamp",
createTimestampStringRenderer()
);

const timestampSCT = new ColumnType(
"TIMESTAMP_S",
"timestamp",
createTimestampStringRenderer()
);

const timestampMSCT = new ColumnType(
"TIMESTAMP_MS",
"timestamp",
createTimestampStringRenderer()
);

const datetimeCT = new ColumnType(
"DATETIME",
"timestamp",
createTimestampStringRenderer()
);

const timestampWithTimeZoneCT = new ColumnType(
"TIMESTAMP WITH TIME ZONE",
"timestamp",
createTimestampStringRenderer()
);

const timestampTZCT = new ColumnType(
"TIMESTAMPTZ",
"timestamp",
createTimestampStringRenderer()
);

const dateCT = new ColumnType(
"DATE",
"timestamp",
createTimestampStringRenderer(true)
);

const blobCT = new ColumnType("BLOB", "blob", {
stringRender: (val: any) => {
if (val == null) {
Expand Down Expand Up @@ -72,6 +123,13 @@ export class DuckDBDialectClass extends BaseSQLDialect {
FLOAT: realCT,
TEXT: textCT,
TIMESTAMP: timestampCT,
TIMESTAMPTZ: timestampTZCT,
"TIMESTAMP WITH TIME ZONE": timestampWithTimeZoneCT,
TIMESTAMP_NS: timestampNSCT,
TIMESTAMP_S: timestampSCT,
TIMESTAMP_MS: timestampMSCT,
DATETIME: datetimeCT,
DATE: dateCT,
VARCHAR: textCT,
BOOL: boolCT,
BOOLEAN: boolCT,
Expand Down

0 comments on commit 16f1740

Please sign in to comment.