From ea7c8790c54e266d7d60a31b086d1eba0489147b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 28 Feb 2024 12:21:36 +0200 Subject: [PATCH] Support ARRAY() constructor syntax in PostgreSQL Fixes #71 --- src/cst/Expr.ts | 8 ++++++++ src/parser.pegjs | 13 +++++++++++-- src/showNode/expr.ts | 1 + test/expr/array.test.ts | 4 ++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/cst/Expr.ts b/src/cst/Expr.ts index b06a0577..b1e3adda 100644 --- a/src/cst/Expr.ts +++ b/src/cst/Expr.ts @@ -52,6 +52,7 @@ export type Expr = | BetweenExpr | CaseExpr | RowConstructor + | ArrayConstructor | IntervalExpr | StringWithCharset | QuantifierExpr @@ -343,6 +344,13 @@ export interface RowConstructor extends BaseNode { row: ParenExpr>; } +// PostgreSQL +export interface ArrayConstructor extends BaseNode { + type: "array_constructor"; + arrayKw: Keyword<"ARRAY">; + expr: ParenExpr; +} + // MySQL, MariaDB, BigQuery export interface IntervalExpr extends BaseNode { type: "interval_expr"; diff --git a/src/parser.pegjs b/src/parser.pegjs index e53f76cd..3e43a239 100644 --- a/src/parser.pegjs +++ b/src/parser.pegjs @@ -1501,7 +1501,7 @@ values_row / &mysql list:(paren$list$expr_or_default / row_constructor) { return list; } row_constructor - = kw:(ROW __) row:paren$list$expr_or_default { + = kw:(ROW __) row:paren$compound_select_stmt { return loc({ type: "row_constructor", rowKw: read(kw), @@ -1509,6 +1509,15 @@ row_constructor }); } +array_constructor + = kw:(ARRAY __) expr:select_stmt { + return loc({ + type: "array_constructor", + arrayKw: read(kw), + expr: expr, + }); + } + expr_or_default = expr / default @@ -6295,7 +6304,7 @@ primary / &bigquery x:(typed_array_expr / array_expr / typed_struct_expr) { return x; } / &postgres x:typed_array_expr { return x; } / cast_expr - / &postgres x:row_constructor { return x; } + / &postgres x:(row_constructor / array_constructor) { return x; } / &sqlite e:raise_expr { return e; } / (&mysql / &bigquery / &postgres) e:extract_expr { return e; } / case_expr diff --git a/src/showNode/expr.ts b/src/showNode/expr.ts index cec71cd6..9b6a1fde 100644 --- a/src/showNode/expr.ts +++ b/src/showNode/expr.ts @@ -25,6 +25,7 @@ export const exprMap: FullTransformMap = { cast_format: (node) => show([node.formatKw, node.string, node.timezone]), cast_format_timezone: (node) => show([node.atTimeZoneKw, node.timezone]), row_constructor: (node) => show([node.rowKw, node.row]), + array_constructor: (node) => show([node.arrayKw, node.expr]), raise_expr: (node) => show([node.raiseKw, node.args]), raise_expr_type: (node) => show(node.typeKw), extract_expr: (node) => show([node.extractKw, node.args]), diff --git a/test/expr/array.test.ts b/test/expr/array.test.ts index c010aeb0..7cb81288 100644 --- a/test/expr/array.test.ts +++ b/test/expr/array.test.ts @@ -82,6 +82,10 @@ describe("array", () => { it("supports empty ARRAY[]", () => { testExprWc(`ARRAY[]`); }); + + it("supports ARRAY() constructor", () => { + testExprWc(`ARRAY(SELECT row from tbl)`); + }); }); dialect(["mysql", "mariadb"], () => {