From 73b44ad6f3cb2e2b563c61da699c716d6e32b48c Mon Sep 17 00:00:00 2001 From: Ben King <9087625+benfdking@users.noreply.github.com> Date: Thu, 28 Nov 2024 13:08:37 +0000 Subject: [PATCH] feat: implementing start of create macro in duckdb --- crates/lib-dialects/src/duckdb.rs | 30 ++- .../test/fixtures/dialects/duckdb/macro.sql | 48 ++++ .../test/fixtures/dialects/duckdb/macro.yml | 221 ++++++++++++++++++ 3 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 crates/lib-dialects/test/fixtures/dialects/duckdb/macro.sql create mode 100644 crates/lib-dialects/test/fixtures/dialects/duckdb/macro.yml diff --git a/crates/lib-dialects/src/duckdb.rs b/crates/lib-dialects/src/duckdb.rs index b843a9f03..235eeb9b8 100644 --- a/crates/lib-dialects/src/duckdb.rs +++ b/crates/lib-dialects/src/duckdb.rs @@ -25,6 +25,7 @@ pub fn raw_dialect() -> Dialect { duckdb_dialect.name = DialectKind::Duckdb; duckdb_dialect.add_keyword_to_set("reserved_keywords", "Summarize"); + duckdb_dialect.add_keyword_to_set("reserved_keywords", "Macro"); duckdb_dialect.add([ ( @@ -97,6 +98,32 @@ pub fn raw_dialect() -> Dialect { .to_matchable() .into(), ), + ( + "CreateMacroStatementSegment".into(), + Sequence::new(vec_of_erased![ + Ref::keyword("CREATE"), + one_of(vec_of_erased![ + Ref::keyword("TEMP"), + Ref::keyword("TEMPORARY") + ]) + .config(|config| config.optional()), + one_of(vec_of_erased![ + Ref::keyword("MACRO"), + Ref::keyword("FUNCTION") + ]), + Ref::new("SingleIdentifierGrammar"), + Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new( + "BaseExpressionElementGrammar" + )])]), + Ref::keyword("AS"), + one_of(vec_of_erased![ + Ref::new("SelectStatementSegment"), + Ref::new("BaseExpressionElementGrammar") + ]) + ]) + .to_matchable() + .into(), + ), ]); duckdb_dialect.insert_lexer_matchers( @@ -220,7 +247,8 @@ pub fn raw_dialect() -> Dialect { Some(vec_of_erased![ Ref::new("LoadStatementSegment"), Ref::new("SummarizeStatementSegment"), - Ref::new("DescribeStatementSegment") + Ref::new("DescribeStatementSegment"), + Ref::new("CreateMacroStatementSegment") ]), None, None, diff --git a/crates/lib-dialects/test/fixtures/dialects/duckdb/macro.sql b/crates/lib-dialects/test/fixtures/dialects/duckdb/macro.sql new file mode 100644 index 000000000..1959160f1 --- /dev/null +++ b/crates/lib-dialects/test/fixtures/dialects/duckdb/macro.sql @@ -0,0 +1,48 @@ +CREATE MACRO one() AS (SELECT 1); + +CREATE MACRO add(a, b) AS a + b; + +CREATE FUNCTION add(a, b) AS a + b; + +CREATE MACRO ifelse(a, b, c) AS CASE WHEN a THEN b ELSE c END; + +CREATE MACRO plus_one(a) AS (WITH cte AS (SELECT 1 AS a) SELECT cte.a + a FROM cte); + +CREATE MACRO arr_append(l, e) AS list_concat(l, list_value(e)); + +CREATE TEMP MACRO add(a, b) AS a + b; + +CREATE TEMPORARY MACRO add(a, b) AS a + b; + +-- CREATE OR REPLACE MACRO add(a, b) AS a + b; +-- CREATE MACRO add_default(a, b := 5) AS a + b; +-- +-- CREATE MACRO static_table() AS TABLE +-- SELECT 'Hello' AS column1, 'World' AS column2; +-- +-- CREATE MACRO dynamic_table(col1_value, col2_value) AS TABLE +-- SELECT col1_value AS column1, col2_value AS column2; +-- +-- CREATE OR REPLACE TEMP MACRO dynamic_table(col1_value, col2_value) AS TABLE +-- SELECT col1_value AS column1, col2_value AS column2 +-- UNION ALL +-- SELECT 'Hello' AS col1_value, 456 AS col2_value; +-- +-- CREATE MACRO get_users(i) AS TABLE +-- SELECT * FROM users WHERE uid IN (SELECT unnest(i)); +-- +-- CREATE TABLE users AS +-- SELECT * +-- FROM (VALUES (1, 'Ada'), (2, 'Bob'), (3, 'Carl'), (4, 'Dan'), (5, 'Eve')) t(uid, name); +-- SELECT * FROM get_users([1, 5]); +-- +-- CREATE MACRO checksum(table_name) AS TABLE +-- SELECT bit_xor(md5_number(COLUMNS(*)::VARCHAR)) +-- FROM query_table(table_name); +-- +-- CREATE TABLE tbl AS SELECT unnest([42, 43]) AS x, 100 AS y; +-- SELECT * FROM checksum('tbl'); +-- +-- CREATE MACRO add_x +-- (a, b) AS a + b, +-- (a, b, c) AS a + b + c; \ No newline at end of file diff --git a/crates/lib-dialects/test/fixtures/dialects/duckdb/macro.yml b/crates/lib-dialects/test/fixtures/dialects/duckdb/macro.yml new file mode 100644 index 000000000..13be26a5b --- /dev/null +++ b/crates/lib-dialects/test/fixtures/dialects/duckdb/macro.yml @@ -0,0 +1,221 @@ +file: +- statement: + - keyword: CREATE + - keyword: MACRO + - naked_identifier: one + - bracketed: + - start_bracket: ( + - end_bracket: ) + - keyword: AS + - expression: + - bracketed: + - start_bracket: ( + - expression: + - select_statement: + - select_clause: + - keyword: SELECT + - select_clause_element: + - numeric_literal: '1' + - end_bracket: ) +- statement_terminator: ; +- statement: + - keyword: CREATE + - keyword: MACRO + - naked_identifier: add + - bracketed: + - start_bracket: ( + - column_reference: + - naked_identifier: a + - comma: ',' + - column_reference: + - naked_identifier: b + - end_bracket: ) + - keyword: AS + - expression: + - column_reference: + - naked_identifier: a + - binary_operator: + + - column_reference: + - naked_identifier: b +- statement_terminator: ; +- statement: + - keyword: CREATE + - keyword: FUNCTION + - naked_identifier: add + - bracketed: + - start_bracket: ( + - column_reference: + - naked_identifier: a + - comma: ',' + - column_reference: + - naked_identifier: b + - end_bracket: ) + - keyword: AS + - expression: + - column_reference: + - naked_identifier: a + - binary_operator: + + - column_reference: + - naked_identifier: b +- statement_terminator: ; +- statement: + - keyword: CREATE + - keyword: MACRO + - naked_identifier: ifelse + - bracketed: + - start_bracket: ( + - column_reference: + - naked_identifier: a + - comma: ',' + - column_reference: + - naked_identifier: b + - comma: ',' + - column_reference: + - naked_identifier: c + - end_bracket: ) + - keyword: AS + - expression: + - case_expression: + - keyword: CASE + - when_clause: + - keyword: WHEN + - expression: + - column_reference: + - naked_identifier: a + - keyword: THEN + - expression: + - column_reference: + - naked_identifier: b + - else_clause: + - keyword: ELSE + - expression: + - column_reference: + - naked_identifier: c + - keyword: END +- statement_terminator: ; +- statement: + - keyword: CREATE + - keyword: MACRO + - naked_identifier: plus_one + - bracketed: + - start_bracket: ( + - column_reference: + - naked_identifier: a + - end_bracket: ) + - keyword: AS + - expression: + - bracketed: + - start_bracket: ( + - with_compound_statement: + - keyword: WITH + - common_table_expression: + - naked_identifier: cte + - keyword: AS + - bracketed: + - start_bracket: ( + - select_statement: + - select_clause: + - keyword: SELECT + - select_clause_element: + - numeric_literal: '1' + - alias_expression: + - keyword: AS + - naked_identifier: a + - end_bracket: ) + - select_statement: + - select_clause: + - keyword: SELECT + - select_clause_element: + - expression: + - column_reference: + - naked_identifier: cte + - dot: . + - naked_identifier: a + - binary_operator: + + - column_reference: + - naked_identifier: a + - from_clause: + - keyword: FROM + - from_expression: + - from_expression_element: + - table_expression: + - table_reference: + - naked_identifier: cte + - end_bracket: ) +- statement_terminator: ; +- statement: + - keyword: CREATE + - keyword: MACRO + - naked_identifier: arr_append + - bracketed: + - start_bracket: ( + - column_reference: + - naked_identifier: l + - comma: ',' + - column_reference: + - naked_identifier: e + - end_bracket: ) + - keyword: AS + - function: + - function_name: + - function_name_identifier: list_concat + - bracketed: + - start_bracket: ( + - expression: + - column_reference: + - naked_identifier: l + - comma: ',' + - expression: + - function: + - function_name: + - function_name_identifier: list_value + - bracketed: + - start_bracket: ( + - expression: + - column_reference: + - naked_identifier: e + - end_bracket: ) + - end_bracket: ) +- statement_terminator: ; +- statement: + - keyword: CREATE + - keyword: TEMP + - keyword: MACRO + - naked_identifier: add + - bracketed: + - start_bracket: ( + - column_reference: + - naked_identifier: a + - comma: ',' + - column_reference: + - naked_identifier: b + - end_bracket: ) + - keyword: AS + - expression: + - column_reference: + - naked_identifier: a + - binary_operator: + + - column_reference: + - naked_identifier: b +- statement_terminator: ; +- statement: + - keyword: CREATE + - keyword: TEMPORARY + - keyword: MACRO + - naked_identifier: add + - bracketed: + - start_bracket: ( + - column_reference: + - naked_identifier: a + - comma: ',' + - column_reference: + - naked_identifier: b + - end_bracket: ) + - keyword: AS + - expression: + - column_reference: + - naked_identifier: a + - binary_operator: + + - column_reference: + - naked_identifier: b +- statement_terminator: ;