diff --git a/decode.ts b/decode.ts index 2a5ff1bc..5c5435dc 100644 --- a/decode.ts +++ b/decode.ts @@ -8,6 +8,7 @@ import { decodeBytea, decodeByteaArray, decodeDate, + decodeDateArray, decodeDatetime, decodeDatetimeArray, decodeInt, @@ -103,6 +104,8 @@ function decodeText(value: Uint8Array, typeOid: number): any { return decodeByteaArray(strValue); case Oid.date: return decodeDate(strValue); + case Oid.date_array: + return decodeDateArray(strValue); case Oid.int8: return decodeBigint(strValue); case Oid.int8_array: diff --git a/oid.ts b/oid.ts index 5cad4de5..a79ab8d5 100644 --- a/oid.ts +++ b/oid.ts @@ -147,7 +147,8 @@ export const Oid = { timestamp: 1114, // deno-lint-ignore camelcase timestamp_array: 1115, - _date: 1182, + // deno-lint-ignore camelcase + date_array: 1182, // deno-lint-ignore camelcase time_array: 1183, timestamptz: 1184, diff --git a/query/decoders.ts b/query/decoders.ts index 7e040bb7..316fa227 100644 --- a/query/decoders.ts +++ b/query/decoders.ts @@ -80,7 +80,15 @@ function decodeByteaHex(byteaStr: string): Uint8Array { return bytes; } -export function decodeDate(dateStr: string): Date { +export function decodeDate(dateStr: string): Date | number { + // there are special `infinity` and `-infinity` + // cases representing out-of-range dates + if (dateStr === "infinity") { + return Number(Infinity); + } else if (dateStr === "-infinity") { + return Number(-Infinity); + } + const matches = DATE_RE.exec(dateStr); if (!matches) { @@ -100,20 +108,16 @@ export function decodeDate(dateStr: string): Date { return date; } +export function decodeDateArray(value: string) { + return parseArray(value, decodeDate); +} + export function decodeDatetime(dateStr: string): number | Date { /** * Postgres uses ISO 8601 style date output by default: * 1997-12-17 07:37:16-08 */ - // there are special `infinity` and `-infinity` - // cases representing out-of-range dates - if (dateStr === "infinity") { - return Number(Infinity); - } else if (dateStr === "-infinity") { - return Number(-Infinity); - } - const matches = DATETIME_RE.exec(dateStr); if (!matches) { diff --git a/test_deps.ts b/test_deps.ts index 1fd1db81..8c75f43b 100644 --- a/test_deps.ts +++ b/test_deps.ts @@ -9,3 +9,7 @@ export { decode as decodeBase64, encode as encodeBase64, } from "https://deno.land/std@0.84.0/encoding/base64.ts"; +export { + format as formatDate, + parse as parseDate, +} from "https://deno.land/std@0.85.0/datetime/mod.ts"; diff --git a/tests/data_types.ts b/tests/data_types.ts index 019291af..f3e9c1b8 100644 --- a/tests/data_types.ts +++ b/tests/data_types.ts @@ -1,4 +1,10 @@ -import { assertEquals, decodeBase64, encodeBase64 } from "../test_deps.ts"; +import { + assertEquals, + decodeBase64, + encodeBase64, + formatDate, + parseDate, +} from "../test_deps.ts"; import { Client } from "../mod.ts"; import TEST_CONNECTION_PARAMS from "./config.ts"; import { getTestClient } from "./helpers.ts"; @@ -674,3 +680,28 @@ testClient(async function tidArray() { assertEquals(result.rows[0][0], [[4681n, 1869n], [0n, 17476n]]); }); + +testClient(async function date() { + const date = "2020-01-01"; + + const result = await CLIENT.queryArray<[Timestamp, Timestamp]>( + "SELECT $1::DATE, 'Infinity'::Date", + date, + ); + + assertEquals(result.rows[0], [parseDate(date, "yyyy-MM-dd"), Infinity]); +}); + +testClient(async function dateArray() { + const dates = ["2020-01-01", formatDate(new Date(), "yyyy-MM-dd")]; + + const result = await CLIENT.queryArray<[Timestamp, Timestamp]>( + "SELECT ARRAY[$1::DATE, $2]", + ...dates, + ); + + assertEquals( + result.rows[0][0], + dates.map((date) => parseDate(date, "yyyy-MM-dd")), + ); +});