should be it
This commit is contained in:
47
external/duckdb/test/sql/catalog/function/attached_macro.test
vendored
Normal file
47
external/duckdb/test/sql/catalog/function/attached_macro.test
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# name: test/sql/catalog/function/attached_macro.test
|
||||
# description: Call a table function living in a different catalog.
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
ATTACH ':memory:' AS checksum_macro;
|
||||
|
||||
statement ok
|
||||
CREATE MACRO checksum_macro.checksum(table_name) AS TABLE
|
||||
SELECT bit_xor(md5_number(COLUMNS(*)::VARCHAR))
|
||||
FROM query_table(table_name);
|
||||
|
||||
# Use 'query_table' with a schema-qualified table name.
|
||||
|
||||
statement ok
|
||||
BEGIN
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl AS SELECT UNNEST([42, 43]) AS x;
|
||||
|
||||
statement ok
|
||||
USE checksum_macro;
|
||||
|
||||
query I
|
||||
SELECT * FROM checksum('memory.tbl');
|
||||
----
|
||||
60609334165039584609948387465088153270
|
||||
|
||||
statement ok
|
||||
ABORT
|
||||
|
||||
# Call a table function that lives in a different catalog
|
||||
|
||||
statement ok
|
||||
BEGIN
|
||||
|
||||
statement ok
|
||||
USE memory;
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl AS SELECT UNNEST([42, 43]) AS x;
|
||||
|
||||
statement ok
|
||||
SELECT * FROM checksum_macro.checksum('tbl');
|
||||
|
||||
statement ok
|
||||
ABORT
|
||||
12
external/duckdb/test/sql/catalog/function/information_schema_macro.test
vendored
Normal file
12
external/duckdb/test/sql/catalog/function/information_schema_macro.test
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# name: test/sql/catalog/function/information_schema_macro.test
|
||||
# description: Issue #3690: Creating a MACRO in pg_catalog or information_schema causes duckdb to crash
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# not allowed
|
||||
statement error
|
||||
create macro information_schema.foo(a) as a;
|
||||
----
|
||||
<REGEX>:.*Binder Error: Cannot create entry.*
|
||||
35
external/duckdb/test/sql/catalog/function/macro_query_table.test
vendored
Normal file
35
external/duckdb/test/sql/catalog/function/macro_query_table.test
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# name: test/sql/catalog/function/macro_query_table.test
|
||||
# description: Test using a scalar macro with the query_table function
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
create macro min_from_tbl(tbl, col) as (select min(col) from query_table(tbl::VARCHAR));
|
||||
|
||||
statement ok
|
||||
create table integers as from range(100) t(i)
|
||||
|
||||
query I
|
||||
SELECT min_from_tbl(integers, i)
|
||||
----
|
||||
0
|
||||
|
||||
# column does not exist
|
||||
statement error
|
||||
SELECT min_from_tbl(integers, k)
|
||||
----
|
||||
not found in FROM clause
|
||||
|
||||
# table does not exist
|
||||
statement error
|
||||
SELECT min_from_tbl(integers2, i)
|
||||
----
|
||||
Table with name integers2 does not exist
|
||||
|
||||
# using a non-scalar parameter is not supported
|
||||
statement error
|
||||
SELECT min_from_tbl(tbl_name, i) from (values ('integers')) t(tbl_name);
|
||||
----
|
||||
tbl_name
|
||||
159
external/duckdb/test/sql/catalog/function/python_style_macro_parameters.test
vendored
Normal file
159
external/duckdb/test/sql/catalog/function/python_style_macro_parameters.test
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
# name: test/sql/catalog/function/python_style_macro_parameters.test
|
||||
# description: Test Python-style macro parameters
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
create or replace macro m(a := 'a', b := 'b') as a || b
|
||||
|
||||
query I
|
||||
select m()
|
||||
----
|
||||
ab
|
||||
|
||||
# we can supply arguments in any order as long as they are named
|
||||
query I
|
||||
select m(b := 'a', a := 'b')
|
||||
----
|
||||
ba
|
||||
|
||||
query I
|
||||
select m(a := 'b', b := 'a')
|
||||
----
|
||||
ba
|
||||
|
||||
query I
|
||||
select m('c')
|
||||
----
|
||||
cb
|
||||
|
||||
query I
|
||||
select m('c', 'd')
|
||||
----
|
||||
cd
|
||||
|
||||
query I
|
||||
select m('c', b := 'd')
|
||||
----
|
||||
cd
|
||||
|
||||
# 'a' is already supplied as positional, so cannot be used as named
|
||||
statement error
|
||||
select m('c', a:= 'd')
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
select m('c', 'd', b := 'e')
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
# now without default arguments
|
||||
statement ok
|
||||
create or replace macro m(a, b) as a || b
|
||||
|
||||
statement error
|
||||
select m()
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
query I
|
||||
select m(b := 'a', a := 'b')
|
||||
----
|
||||
ba
|
||||
|
||||
query I
|
||||
select m(a := 'b', b := 'a')
|
||||
----
|
||||
ba
|
||||
|
||||
statement error
|
||||
select m('c')
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
query I
|
||||
select m('c', 'd')
|
||||
----
|
||||
cd
|
||||
|
||||
query I
|
||||
select m('c', b := 'd')
|
||||
----
|
||||
cd
|
||||
|
||||
# replicate tests above but with a table macro
|
||||
statement ok
|
||||
create or replace macro m(a := 'a', b := 'b') as table (select a || b)
|
||||
|
||||
query I
|
||||
select * from m()
|
||||
----
|
||||
ab
|
||||
|
||||
query I
|
||||
select * from m(b := 'a', a := 'b')
|
||||
----
|
||||
ba
|
||||
|
||||
query I
|
||||
select * from m(a := 'b', b := 'a')
|
||||
----
|
||||
ba
|
||||
|
||||
query I
|
||||
select * from m('c')
|
||||
----
|
||||
cb
|
||||
|
||||
query I
|
||||
select * from m('c', 'd')
|
||||
----
|
||||
cd
|
||||
|
||||
query I
|
||||
select * from m('c', b := 'd')
|
||||
----
|
||||
cd
|
||||
|
||||
statement error
|
||||
select * from m('c', a:= 'd')
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
select * from m('c', 'd', b := 'e')
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement ok
|
||||
create or replace macro m(a, b) as table (select a || b)
|
||||
|
||||
statement error
|
||||
select * from m()
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
query I
|
||||
select * from m(b := 'a', a := 'b')
|
||||
----
|
||||
ba
|
||||
|
||||
query I
|
||||
select * from m(a := 'b', b := 'a')
|
||||
----
|
||||
ba
|
||||
|
||||
statement error
|
||||
select * from m('c')
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
query I
|
||||
select * from m('c', 'd')
|
||||
----
|
||||
cd
|
||||
|
||||
query I
|
||||
select * from m('c', b := 'd')
|
||||
----
|
||||
cd
|
||||
304
external/duckdb/test/sql/catalog/function/query_function.test
vendored
Normal file
304
external/duckdb/test/sql/catalog/function/query_function.test
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
# name: test/sql/catalog/function/query_function.test
|
||||
# description: test query() function
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I
|
||||
SELECT * FROM query('SELECT 42');
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
FROM query('SELECT 42 AS a');
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
FROM query('SELECT 10 + 32;');
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
FROM query('SELECT abs(-42)');
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
SELECT * FROM query('SELECT * FROM (SELECT 1 + 2)');
|
||||
----
|
||||
3
|
||||
|
||||
query III
|
||||
FROM query('SELECT 1, 2, 3');
|
||||
----
|
||||
1 2 3
|
||||
|
||||
query I
|
||||
FROM query('SELECT 42;;;--- hello;');
|
||||
----
|
||||
42
|
||||
|
||||
# query text
|
||||
query I
|
||||
SELECT * FROM query('SELECT ''hello''');
|
||||
----
|
||||
hello
|
||||
|
||||
# query a table
|
||||
statement ok
|
||||
CREATE TABLE tbl (a INT, b INT, c INT);
|
||||
|
||||
statement ok
|
||||
FROM query('SELECT *, 1 + 2 FROM tbl');
|
||||
|
||||
statement ok
|
||||
INSERT INTO tbl VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9);
|
||||
|
||||
query III
|
||||
SELECT * FROM query('FROM tbl');
|
||||
----
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
query I
|
||||
SELECT * FROM query('SELECT a + b + c FROM tbl');
|
||||
----
|
||||
6
|
||||
15
|
||||
24
|
||||
|
||||
# query multiple nested type tags
|
||||
query II
|
||||
SELECT * FROM query('WITH a(i) AS (SELECT 1) SELECT a1.i AS i1, a2.i AS i2 FROM a AS a1, a AS a2');
|
||||
----
|
||||
1 1
|
||||
|
||||
# test incorrect usage
|
||||
statement error
|
||||
SELECT * FROM query(NULL);
|
||||
----
|
||||
<REGEX>:Parser Error.*NULL.*
|
||||
|
||||
statement error
|
||||
SELECT * FROM query(' ');
|
||||
----
|
||||
Parser Error: Expected a single SELECT statement
|
||||
|
||||
statement error
|
||||
SELECT * FROM query('');
|
||||
----
|
||||
Parser Error: Expected a single SELECT statement
|
||||
|
||||
statement error
|
||||
SELECT * FROM query('FROM query(FROM)');
|
||||
----
|
||||
Parser Error: syntax error at or near "FROM"
|
||||
|
||||
# multiple statements are not supported
|
||||
statement error
|
||||
SELECT * FROM query('SELECT 1; SELECT 2');
|
||||
----
|
||||
Parser Error: Expected a single SELECT statement
|
||||
|
||||
# invalid input
|
||||
statement error
|
||||
SELECT query(SELECT 1);
|
||||
----
|
||||
Parser Error: syntax error at or near "SELECT"
|
||||
|
||||
statement error
|
||||
SELECT * FROM query('CREATE TABLE tbl (a INT)');
|
||||
----
|
||||
Parser Error: Expected a single SELECT statement
|
||||
|
||||
# test PIVOT statements in query() function
|
||||
query I
|
||||
SELECT * FROM query('SELECT * FROM (PIVOT (SELECT 1 AS col) ON col IN (1) using first(col))');
|
||||
----
|
||||
1
|
||||
|
||||
# PIVOT without explicit IN clause should give helpful error message
|
||||
statement error
|
||||
SELECT * FROM query('SELECT * FROM (PIVOT (SELECT 1 AS col) ON col using first(col))');
|
||||
----
|
||||
Parser Error: PIVOT statements without explicit IN clauses are not supported in query() function. Please specify the pivot values explicitly, e.g.: PIVOT ... ON col IN (val1, val2, ...)
|
||||
|
||||
# test query_table()
|
||||
statement ok
|
||||
CREATE TABLE tbl_int AS SELECT 42;
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl_varchar AS SELECT 'duckdb';
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl2_varchar AS SELECT '1?ch@racter$';
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl_empty AS SELECT '';
|
||||
|
||||
query I
|
||||
FROM query_table('tbl_int');
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
FROM query_table(['tbl_int']);
|
||||
----
|
||||
42
|
||||
|
||||
query III
|
||||
FROM query_table(tbl);
|
||||
----
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl2 (a INT, b INT, c INT);
|
||||
|
||||
statement ok
|
||||
INSERT INTO tbl2 VALUES (9, 8, 7), (6, 5, 4), (3, 2, 1);
|
||||
|
||||
query III
|
||||
FROM query_table([tbl, tbl2]);
|
||||
----
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
9 8 7
|
||||
6 5 4
|
||||
3 2 1
|
||||
|
||||
# test incorrect usage
|
||||
statement error
|
||||
FROM query_table();
|
||||
----
|
||||
No function matches the given name and argument types 'query_table()'.
|
||||
|
||||
statement error
|
||||
FROM query_table(NULL);
|
||||
----
|
||||
<REGEX>:.*Cannot use NULL.*
|
||||
|
||||
statement error
|
||||
FROM query_table([]);
|
||||
----
|
||||
Binder Error: No function matches the given name and argument types 'query_table(INTEGER[])'.
|
||||
|
||||
statement error
|
||||
FROM query_table(['']);
|
||||
----
|
||||
Parser Error: syntax error at end of input
|
||||
|
||||
statement error
|
||||
FROM query_table('tbl_int', 'tbl_varchar', tbl2_varchar);
|
||||
----
|
||||
Binder Error: No function matches the given name and argument types 'query_table(VARCHAR, VARCHAR, VARCHAR)'.
|
||||
|
||||
statement error
|
||||
FROM query_table([tbl_int, tbl2]);
|
||||
----
|
||||
Binder Error: Set operations can only apply to expressions with the same number of result columns
|
||||
|
||||
statement error
|
||||
FROM query_table(not_defined_tbl);
|
||||
----
|
||||
Catalog Error: Table with name not_defined_tbl does not exist!
|
||||
|
||||
statement error
|
||||
FROM query_table('FROM query(''select 1 + 2;'')');
|
||||
----
|
||||
Catalog Error: Table with name FROM query('select 1 + 2;') does not exist!
|
||||
|
||||
statement error
|
||||
FROM query_table('FROM query("select 1 + 2;")');
|
||||
----
|
||||
Catalog Error: Table with name FROM query(select 1 + 2;) does not exist!
|
||||
|
||||
statement error
|
||||
FROM query_table('(SELECT 17 + 25)');
|
||||
----
|
||||
Catalog Error: Table with name (SELECT 17 + 25) does not exist!
|
||||
|
||||
# tables with special table names
|
||||
statement ok
|
||||
CREATE TABLE "(SELECT 17 + 25)"(i int);
|
||||
|
||||
statement ok
|
||||
insert into "(SELECT 17 + 25)" values (100);
|
||||
|
||||
query I
|
||||
SELECT * FROM "(SELECT 17 + 25)";
|
||||
----
|
||||
100
|
||||
|
||||
query I
|
||||
FROM query_table("(SELECT 17 + 25)");
|
||||
----
|
||||
100
|
||||
|
||||
query I
|
||||
FROM query_table('(SELECT 17 + 25)');
|
||||
----
|
||||
100
|
||||
|
||||
statement error
|
||||
FROM query_table(SELECT 17 + 25);
|
||||
----
|
||||
Parser Error: syntax error at or near "SELECT"
|
||||
|
||||
statement error
|
||||
FROM query_table("SELECT 4 + 2");
|
||||
----
|
||||
Catalog Error: Table with name SELECT 4 + 2 does not exist!
|
||||
|
||||
statement error
|
||||
FROM query_table('SELECT 4 + 2');
|
||||
----
|
||||
Catalog Error: Table with name SELECT 4 + 2 does not exist!
|
||||
|
||||
query I
|
||||
SELECT f.* FROM query_table('tbl_int') as f;
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
SELECT f.x FROM query_table('tbl_int') as f(x);
|
||||
----
|
||||
42
|
||||
|
||||
# test by_name argument
|
||||
query I
|
||||
FROM query_table(['tbl_int', 'tbl_varchar', 'tbl_empty', 'tbl2_varchar'], false);
|
||||
----
|
||||
42
|
||||
duckdb
|
||||
(empty)
|
||||
1?ch@racter$
|
||||
|
||||
query IIII
|
||||
from query_table([tbl_int, tbl_varchar, tbl_empty, tbl2_varchar], true);
|
||||
----
|
||||
42 NULL NULL NULL
|
||||
NULL duckdb NULL NULL
|
||||
NULL NULL (empty) NULL
|
||||
NULL NULL NULL 1?ch@racter$
|
||||
|
||||
# test incorrect usage
|
||||
statement error
|
||||
FROM query_table(true);
|
||||
----
|
||||
Binder Error: No function matches the given name and argument types 'query_table(BOOLEAN)'.
|
||||
|
||||
statement error
|
||||
FROM query_table(tbl2, true);
|
||||
----
|
||||
Binder Error: No function matches the given name and argument types 'query_table(VARCHAR, BOOLEAN)'.
|
||||
|
||||
statement error
|
||||
FROM query_table(['tbl_int', 'tbl_varchar', 'tbl_empty', '(select ''I am a subquery'')'], false);
|
||||
----
|
||||
Catalog Error: Table with name (select 'I am a subquery') does not exist!
|
||||
28
external/duckdb/test/sql/catalog/function/struct_extract_macro.test
vendored
Normal file
28
external/duckdb/test/sql/catalog/function/struct_extract_macro.test
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# name: test/sql/catalog/function/struct_extract_macro.test
|
||||
# description: Test struct extract on a macro
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE MACRO my_extract(x) AS x.a.b
|
||||
|
||||
query I
|
||||
SELECT my_extract({'a': {'b': 42}})
|
||||
----
|
||||
42
|
||||
|
||||
mode skip
|
||||
# FIXME: this does not work yet due to the way in which macro functions are bound
|
||||
# as it is not trivial to fix, for now we leave it as is
|
||||
|
||||
statement ok
|
||||
CREATE MACRO my_subquery_extract(x) AS (SELECT x.a.b);
|
||||
|
||||
query I
|
||||
SELECT my_subquery_extract({'a': {'b': 42}})
|
||||
----
|
||||
42
|
||||
|
||||
mode unskip
|
||||
330
external/duckdb/test/sql/catalog/function/test_complex_macro.test
vendored
Normal file
330
external/duckdb/test/sql/catalog/function/test_complex_macro.test
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
# name: test/sql/catalog/function/test_complex_macro.test
|
||||
# description: Test Complex Macro
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers (a INT)
|
||||
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (1)
|
||||
|
||||
# cte and subquery
|
||||
statement ok
|
||||
CREATE MACRO cte_sq(a,b) AS (WITH cte AS (SELECT a * 2 AS c) SELECT cte.c + sq.d FROM cte, (SELECT b * 3 AS d) AS sq)
|
||||
|
||||
query T
|
||||
SELECT cte_sq(3,4)
|
||||
----
|
||||
18
|
||||
|
||||
statement ok
|
||||
CREATE MACRO nested_cte(needle, haystack) AS needle IN (
|
||||
SELECT i FROM (
|
||||
WITH ints AS (
|
||||
SELECT CAST(UNNEST(string_split(haystack,',')) AS INT) AS i
|
||||
)
|
||||
SELECT i FROM ints
|
||||
) AS sq
|
||||
)
|
||||
|
||||
query T
|
||||
SELECT nested_cte(2, '2,2,2,2')
|
||||
----
|
||||
1
|
||||
|
||||
statement ok
|
||||
CREATE MACRO IFELSE(a,b,c) AS CASE WHEN a THEN b ELSE c END
|
||||
|
||||
query T
|
||||
SELECT IFELSE(1, IFELSE(1,'a','b'), 'c')
|
||||
----
|
||||
a
|
||||
|
||||
query T
|
||||
SELECT IFELSE(1, IFELSE(0,'a','b'), 'c')
|
||||
----
|
||||
b
|
||||
|
||||
query T
|
||||
SELECT IFELSE(0, IFELSE(1,'a','b'), 'c')
|
||||
----
|
||||
c
|
||||
|
||||
query T
|
||||
SELECT IFELSE(1, IFELSE(1,a,'b'), 'c') FROM integers
|
||||
----
|
||||
1
|
||||
|
||||
statement error
|
||||
SELECT IFELSE(1,IFELSE(1,b,1),a) FROM integers
|
||||
----
|
||||
|
||||
statement ok
|
||||
CREATE MACRO f1(x) AS (SELECT MIN(a) + x FROM integers)
|
||||
|
||||
query I
|
||||
select f1(42) from integers;
|
||||
----
|
||||
43
|
||||
|
||||
# macro in GROUP BY
|
||||
statement ok
|
||||
CREATE MACRO mod_two(k) AS k%2
|
||||
|
||||
query II
|
||||
SELECT mod_two(a), SUM(a) FROM integers GROUP BY mod_two(a)
|
||||
----
|
||||
1 1
|
||||
|
||||
# more nested stuff
|
||||
statement ok
|
||||
CREATE MACRO add_mac(a, b) AS a + b
|
||||
|
||||
statement ok
|
||||
CREATE MACRO double_add(a, b, c) AS add_mac(add_mac(a, b), c)
|
||||
|
||||
query T
|
||||
SELECT double_add(1, 2, 3)
|
||||
----
|
||||
6
|
||||
|
||||
statement ok
|
||||
CREATE MACRO triple_add1(a, b, c, d) AS add_mac(add_mac(a, b), add_mac(c, d))
|
||||
|
||||
query T
|
||||
SELECT triple_add1(1, 2, 3, 4)
|
||||
----
|
||||
10
|
||||
|
||||
statement ok
|
||||
CREATE MACRO triple_add2(a, b, c, d) as add_mac(add_mac(add_mac(a, b), c), d)
|
||||
|
||||
query T
|
||||
SELECT triple_add2(1, 2, 3, 4)
|
||||
----
|
||||
10
|
||||
|
||||
# subquery within macro parameters
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (41)
|
||||
|
||||
query T
|
||||
SELECT add((SELECT MIN(a) FROM integers), (SELECT MAX(a) FROM integers))
|
||||
----
|
||||
42
|
||||
|
||||
# macros within a correlated subquery
|
||||
query T
|
||||
SELECT (SELECT MAX(add(i1.a, a)) FROM integers) FROM integers i1
|
||||
----
|
||||
42
|
||||
82
|
||||
|
||||
# parameter expression
|
||||
statement error
|
||||
CREATE MACRO prep(x) AS ?+1
|
||||
----
|
||||
|
||||
# prepared statements
|
||||
statement ok
|
||||
CREATE MACRO add_one(a) AS a + 1
|
||||
|
||||
statement ok
|
||||
PREPARE v1 AS SELECT add_one(?::INTEGER)
|
||||
|
||||
query T
|
||||
EXECUTE v1(1)
|
||||
----
|
||||
2
|
||||
|
||||
statement ok
|
||||
CREATE MACRO my_square(a) AS a * a
|
||||
|
||||
statement ok
|
||||
PREPARE v2 AS SELECT my_square(?::INTEGER)
|
||||
|
||||
query T
|
||||
EXECUTE v2(3)
|
||||
----
|
||||
9
|
||||
|
||||
# test FTS extension use case
|
||||
statement ok
|
||||
CREATE TABLE documents(id VARCHAR, body VARCHAR)
|
||||
|
||||
statement ok
|
||||
INSERT INTO documents VALUES ('doc1', ' QUÁCK+QUÁCK+QUÁCK'), ('doc2', ' BÁRK+BÁRK+BÁRK+BÁRK'), ('doc3', ' MÉOW+MÉOW+MÉOW+MÉOW+MÉOW')
|
||||
|
||||
statement ok
|
||||
CREATE SCHEMA fts_main_documents
|
||||
|
||||
statement ok
|
||||
CREATE TABLE fts_main_documents.docs AS (
|
||||
SELECT
|
||||
row_number() OVER () AS docid,
|
||||
id AS name
|
||||
FROM
|
||||
main.documents
|
||||
)
|
||||
|
||||
statement ok
|
||||
CREATE TABLE fts_main_documents.terms AS (
|
||||
SELECT
|
||||
term,
|
||||
docid,
|
||||
row_number() OVER (PARTITION BY docid) AS pos
|
||||
FROM (
|
||||
SELECT
|
||||
unnest(string_split_regex(regexp_replace(lower(strip_accents(body)), '[^a-z]', ' ', 'g'), '\s+')) AS term,
|
||||
row_number() OVER () AS docid
|
||||
FROM main.documents
|
||||
) AS sq
|
||||
WHERE
|
||||
term != ''
|
||||
)
|
||||
|
||||
statement ok
|
||||
ALTER TABLE fts_main_documents.docs ADD len INT
|
||||
|
||||
statement ok
|
||||
UPDATE fts_main_documents.docs d
|
||||
SET len = (
|
||||
SELECT count(term)
|
||||
FROM fts_main_documents.terms t
|
||||
WHERE t.docid = d.docid
|
||||
)
|
||||
|
||||
statement ok
|
||||
CREATE TABLE fts_main_documents.dict AS
|
||||
WITH distinct_terms AS (
|
||||
SELECT DISTINCT term, docid
|
||||
FROM fts_main_documents.terms
|
||||
ORDER BY docid
|
||||
)
|
||||
SELECT
|
||||
row_number() OVER () AS termid,
|
||||
term
|
||||
FROM
|
||||
distinct_terms
|
||||
|
||||
statement ok
|
||||
ALTER TABLE fts_main_documents.terms ADD termid INT
|
||||
|
||||
statement ok
|
||||
UPDATE fts_main_documents.terms t
|
||||
SET termid = (
|
||||
SELECT termid
|
||||
FROM fts_main_documents.dict d
|
||||
WHERE t.term = d.term
|
||||
)
|
||||
|
||||
statement ok
|
||||
ALTER TABLE fts_main_documents.terms DROP term
|
||||
|
||||
statement ok
|
||||
ALTER TABLE fts_main_documents.dict ADD df INT
|
||||
|
||||
statement ok
|
||||
UPDATE fts_main_documents.dict d
|
||||
SET df = (
|
||||
SELECT count(distinct docid)
|
||||
FROM fts_main_documents.terms t
|
||||
WHERE d.termid = t.termid
|
||||
GROUP BY termid
|
||||
)
|
||||
|
||||
query II
|
||||
WITH ppterms AS (
|
||||
SELECT unnest(string_split_regex(regexp_replace(lower(strip_accents('QUÁCK BÁRK')), '[^a-z]', ' ', 'g'), '\s+')) AS term
|
||||
), qtermids AS (
|
||||
SELECT termid
|
||||
FROM fts_main_documents.dict AS dict
|
||||
JOIN ppterms
|
||||
USING (term)
|
||||
), qterms AS (
|
||||
SELECT termid,
|
||||
docid
|
||||
FROM fts_main_documents.terms AS terms
|
||||
WHERE termid IN (
|
||||
SELECT qtermids.termid FROM qtermids
|
||||
)
|
||||
), subscores AS (
|
||||
SELECT docs.docid,
|
||||
len,
|
||||
term_tf.termid,
|
||||
tf,
|
||||
df,
|
||||
(log((3 - df + 0.5) / (df + 0.5))* ((tf * (1.2 + 1)/(tf + 1.2 * (1 - 0.75 + 0.75 * (len / 4)))))) AS subscore
|
||||
FROM (
|
||||
SELECT termid,
|
||||
docid,
|
||||
COUNT(*) AS tf
|
||||
FROM qterms
|
||||
GROUP BY docid,
|
||||
termid
|
||||
) AS term_tf
|
||||
JOIN (
|
||||
SELECT DISTINCT docid
|
||||
FROM qterms
|
||||
) AS cdocs
|
||||
ON term_tf.docid = cdocs.docid
|
||||
JOIN fts_main_documents.docs AS docs
|
||||
ON term_tf.docid = docs.docid
|
||||
JOIN fts_main_documents.dict AS dict
|
||||
ON term_tf.termid = dict.termid
|
||||
)
|
||||
SELECT name,
|
||||
score
|
||||
FROM (
|
||||
SELECT docid,
|
||||
sum(subscore) AS score
|
||||
FROM subscores
|
||||
GROUP BY docid
|
||||
) AS scores
|
||||
JOIN fts_main_documents.docs AS docs
|
||||
ON scores.docid = docs.docid
|
||||
ORDER BY score DESC
|
||||
LIMIT 1000
|
||||
----
|
||||
doc2 0.37543634550460314
|
||||
doc1 0.3683526408724408
|
||||
|
||||
statement ok
|
||||
CREATE MACRO fts_match(docname, query_string) AS docname IN (
|
||||
WITH ppterms AS (SELECT unnest(string_split_regex(regexp_replace(lower(strip_accents(query_string)), '[^a-z]', ' ', 'g'), '\s+')) AS term),
|
||||
qtermids AS (SELECT termid FROM fts_main_documents.dict AS dict, ppterms WHERE dict.term = ppterms.term),
|
||||
qterms AS (SELECT termid, docid FROM fts_main_documents.terms AS terms WHERE termid IN (SELECT qtermids.termid FROM qtermids)),
|
||||
subscores AS (
|
||||
SELECT docs.docid, len, term_tf.termid,
|
||||
tf, df, (log((3 - df + 0.5) / (df + 0.5))* ((tf * (1.2 + 1)/(tf + 1.2 * (1 - 0.75 + 0.75 * (len / 4)))))) AS subscore
|
||||
FROM (SELECT termid, docid, COUNT(*) AS tf FROM qterms
|
||||
GROUP BY docid, termid) AS term_tf
|
||||
JOIN (SELECT docid FROM qterms
|
||||
GROUP BY docid) -- HAVING COUNT(DISTINCT termid) = 3)
|
||||
AS cdocs ON term_tf.docid = cdocs.docid
|
||||
JOIN fts_main_documents.docs AS docs ON term_tf.docid = docs.docid
|
||||
JOIN fts_main_documents.dict AS dict ON term_tf.termid = dict.termid)
|
||||
SELECT name FROM (SELECT docid, sum(subscore) AS score
|
||||
FROM subscores GROUP BY docid) AS scores JOIN fts_main_documents.docs AS docs ON
|
||||
scores.docid = docs.docid ORDER BY score DESC LIMIT 1000)
|
||||
|
||||
query II
|
||||
SELECT * FROM documents WHERE fts_match(id, 'QUÁCK BÁRK')
|
||||
----
|
||||
doc1 QUÁCK+QUÁCK+QUÁCK
|
||||
doc2 BÁRK+BÁRK+BÁRK+BÁRK
|
||||
|
||||
# macro with window function
|
||||
statement ok
|
||||
CREATE MACRO mywindow(k,v) AS SUM(v) OVER (PARTITION BY k)
|
||||
|
||||
query II rowsort
|
||||
WITH grouped AS (SELECT mod(range, 3) AS grp, range AS val FROM RANGE(500))
|
||||
SELECT DISTINCT grp, mywindow(grp, val) FROM grouped ORDER BY grp
|
||||
----
|
||||
0 41583
|
||||
1 41750
|
||||
2 41417
|
||||
14
external/duckdb/test/sql/catalog/function/test_cross_catalog_macros.test
vendored
Normal file
14
external/duckdb/test/sql/catalog/function/test_cross_catalog_macros.test
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# name: test/sql/catalog/function/test_cross_catalog_macros.test
|
||||
# description: Test cross-catalog dependencies in macros
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
CREATE MACRO my_first_macro() AS (84)
|
||||
|
||||
statement ok
|
||||
CREATE TEMPORARY MACRO my_second_macro() AS my_first_macro() + 42;
|
||||
|
||||
query I
|
||||
SELECT my_second_macro()
|
||||
----
|
||||
126
|
||||
92
external/duckdb/test/sql/catalog/function/test_cte_macro.test
vendored
Normal file
92
external/duckdb/test/sql/catalog/function/test_cte_macro.test
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
# name: test/sql/catalog/function/test_cte_macro.test
|
||||
# description: Test Macro with CTE
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers (a INT)
|
||||
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (1)
|
||||
|
||||
statement ok
|
||||
CREATE MACRO parameterized_cte(a) AS (WITH cte AS (SELECT a AS answer) SELECT answer FROM cte)
|
||||
|
||||
query T
|
||||
SELECT parameterized_cte(42)
|
||||
----
|
||||
42
|
||||
|
||||
statement ok
|
||||
CREATE MACRO in_with_cte(i) AS i IN (WITH cte AS (SELECT a AS answer FROM integers) SELECT answer FROM cte)
|
||||
|
||||
query T
|
||||
SELECT in_with_cte(1)
|
||||
----
|
||||
1
|
||||
|
||||
query T
|
||||
SELECT in_with_cte(2)
|
||||
----
|
||||
0
|
||||
|
||||
statement ok
|
||||
CREATE MACRO plus42(a) AS (WITH cte AS (SELECT 42 AS answer) SELECT answer + a FROM cte)
|
||||
|
||||
query T
|
||||
SELECT plus42(42)
|
||||
----
|
||||
84
|
||||
|
||||
query T
|
||||
SELECT plus42(a) FROM integers
|
||||
----
|
||||
43
|
||||
|
||||
# macro parameters should be contained within the function call (so 42 + 3 + 1)
|
||||
query T
|
||||
SELECT plus42(3) + a FROM integers
|
||||
----
|
||||
46
|
||||
|
||||
# we should not be able to query the CTE from outside the function call
|
||||
statement error
|
||||
SELECT plus42(42) + answer FROM cte;
|
||||
----
|
||||
|
||||
statement ok
|
||||
CREATE MACRO plus1(a) AS (WITH tbl AS (SELECT 1 AS one) SELECT one + a FROM tbl)
|
||||
|
||||
query T
|
||||
SELECT plus1(3)
|
||||
----
|
||||
4
|
||||
|
||||
query T
|
||||
SELECT plus42(a) + plus1(a) FROM integers;
|
||||
----
|
||||
45
|
||||
|
||||
statement ok
|
||||
CREATE MACRO deep_cte(param) AS (
|
||||
WITH cte1 AS (
|
||||
WITH cte2 AS (
|
||||
WITH cte3 AS (
|
||||
WITH cte4 AS (
|
||||
SELECT param AS d
|
||||
)
|
||||
SELECT d AS c FROM cte4
|
||||
)
|
||||
SELECT c AS b FROM cte3
|
||||
)
|
||||
SELECT b AS a FROM cte2
|
||||
)
|
||||
SELECT a FROM cte1
|
||||
)
|
||||
|
||||
query T
|
||||
SELECT deep_cte(42)
|
||||
----
|
||||
42
|
||||
36
external/duckdb/test/sql/catalog/function/test_drop_macro.test
vendored
Normal file
36
external/duckdb/test/sql/catalog/function/test_drop_macro.test
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# name: test/sql/catalog/function/test_drop_macro.test
|
||||
# description: Test dropping scalar/table macros
|
||||
# group: [function]
|
||||
|
||||
# create scalar and table macro with same name
|
||||
statement ok
|
||||
create macro m() as 42;
|
||||
|
||||
statement ok
|
||||
create macro m() as table (select 42 i);
|
||||
|
||||
# table macros are explicitly dropped with "drop macro table"
|
||||
# however, we also want to support dropping them with drop macro
|
||||
# we disambiguate by first trying to drop the scalar macro, then the table macro
|
||||
statement ok
|
||||
drop macro m;
|
||||
|
||||
# scalar macros are dropped first so this fails
|
||||
statement error
|
||||
select m();
|
||||
----
|
||||
is a table function but it was used as a scalar function
|
||||
|
||||
# table macro is still available
|
||||
query I
|
||||
from m();
|
||||
----
|
||||
42
|
||||
|
||||
statement ok
|
||||
drop macro m;
|
||||
|
||||
statement error
|
||||
from m();
|
||||
----
|
||||
with name m does not exist
|
||||
88
external/duckdb/test/sql/catalog/function/test_macro_default_arg.test
vendored
Normal file
88
external/duckdb/test/sql/catalog/function/test_macro_default_arg.test
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
# name: test/sql/catalog/function/test_macro_default_arg.test
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
set storage_compatibility_version='v0.10.2'
|
||||
|
||||
statement ok
|
||||
pragma enable_verification;
|
||||
|
||||
statement ok
|
||||
CREATE MACRO f(x := NULL) AS x+1;
|
||||
|
||||
query I
|
||||
SELECT f();
|
||||
----
|
||||
NULL
|
||||
|
||||
query I
|
||||
SELECT f(x := 41)
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
SELECT f(x := (SELECT 41));
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
select f(x:=(select 1 a));
|
||||
----
|
||||
2
|
||||
|
||||
query I
|
||||
select f(x:=a) from (select 41) t(a);
|
||||
----
|
||||
42
|
||||
|
||||
statement ok
|
||||
create table t as select 41 a;
|
||||
|
||||
query I
|
||||
select f(x:=a) from t;
|
||||
----
|
||||
42
|
||||
|
||||
statement error
|
||||
create macro my_macro1(a, b := a) as a + b;
|
||||
----
|
||||
Invalid default value
|
||||
|
||||
statement ok
|
||||
create table integers (a integer);
|
||||
|
||||
# this used to be allowed but is no longer (and for good reason)
|
||||
statement error
|
||||
create macro my_macro2(a := i) as (
|
||||
select min(a) from integers
|
||||
)
|
||||
----
|
||||
Invalid default value
|
||||
|
||||
statement ok
|
||||
drop table integers;
|
||||
|
||||
statement ok
|
||||
Create table t1 (a int, b int);
|
||||
|
||||
statement ok
|
||||
Create table t2 (c int, d int);
|
||||
|
||||
statement ok
|
||||
CREATE OR REPLACE MACRO eq(x := NULL, y := NULL) AS x = y
|
||||
|
||||
statement ok
|
||||
INSERT INTO t1 VALUES (1, 1), (1, 2), (2, 2), (3, 4);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t2 VALUES (4, 1), (2, 10), (6, 2), (2, 6);
|
||||
|
||||
statement ok
|
||||
SELECT * FROM t1 as t1_alias inner join (select * from t2) as t2_alias ON (eq(x := t1_alias.a, y := t2_alias.c))
|
||||
|
||||
# no default parameters with incorrect names
|
||||
statement error
|
||||
SELECT * FROM t1 as t1_alias inner join (select * from t2) as t2_alias ON (eq(a := t1_alias.a, c := t2_alias.c))
|
||||
----
|
||||
Binder Error
|
||||
|
||||
60
external/duckdb/test/sql/catalog/function/test_macro_default_arg.test_slow
vendored
Normal file
60
external/duckdb/test/sql/catalog/function/test_macro_default_arg.test_slow
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
# name: test/sql/catalog/function/test_macro_default_arg.test_slow
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
pragma enable_verification;
|
||||
|
||||
# The following tests do not test any behavior related to default arguments,
|
||||
# other than what expressions can be passed to a parameter with a default argument
|
||||
|
||||
statement ok
|
||||
CREATE MACRO f(x := NULL) AS (
|
||||
x
|
||||
)
|
||||
|
||||
# Empty
|
||||
statement ok
|
||||
select f(
|
||||
)
|
||||
|
||||
# constant
|
||||
statement ok
|
||||
select f(
|
||||
x := 42
|
||||
)
|
||||
|
||||
# column reference
|
||||
|
||||
statement ok
|
||||
create table tbl as select 42 i;
|
||||
|
||||
# existing column reference
|
||||
statement ok
|
||||
select f(
|
||||
x := i
|
||||
) from tbl;
|
||||
|
||||
# non-existing column reference
|
||||
statement error
|
||||
select f(
|
||||
x := j
|
||||
) from tbl;
|
||||
----
|
||||
|
||||
# cast
|
||||
statement ok
|
||||
select f(
|
||||
x := cast('42' as INT)
|
||||
);
|
||||
|
||||
# is null
|
||||
statement ok
|
||||
select f(
|
||||
x := 42 IS NULL
|
||||
)
|
||||
|
||||
# is not null
|
||||
statement ok
|
||||
select f(
|
||||
x := 42 IS NOT NULL
|
||||
)
|
||||
119
external/duckdb/test/sql/catalog/function/test_macro_default_arg_with_dependencies.test
vendored
Normal file
119
external/duckdb/test/sql/catalog/function/test_macro_default_arg_with_dependencies.test
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
# name: test/sql/catalog/function/test_macro_default_arg_with_dependencies.test
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
ATTACH '__TEST_DIR__/macro_default_arg.db' (STORAGE_VERSION 'v1.0.0');
|
||||
|
||||
statement ok
|
||||
USE macro_default_arg
|
||||
|
||||
statement ok
|
||||
set enable_macro_dependencies=true
|
||||
|
||||
statement ok
|
||||
pragma enable_verification;
|
||||
|
||||
statement ok
|
||||
CREATE MACRO f(x := NULL) AS x+1;
|
||||
|
||||
query I
|
||||
SELECT f();
|
||||
----
|
||||
NULL
|
||||
|
||||
query I
|
||||
SELECT f(x := 41)
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
SELECT f(x := (SELECT 41));
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
select f(x:=(select 1 a));
|
||||
----
|
||||
2
|
||||
|
||||
query I
|
||||
select f(x:=a) from (select 41) t(a);
|
||||
----
|
||||
42
|
||||
|
||||
statement ok
|
||||
create table t as select 41 a;
|
||||
|
||||
query I
|
||||
select f(x:=a) from t;
|
||||
----
|
||||
42
|
||||
|
||||
statement error
|
||||
create macro my_macro1(a, b := a) as a + b;
|
||||
----
|
||||
Invalid default value
|
||||
|
||||
statement ok
|
||||
create table integers (a integer);
|
||||
|
||||
# this used to be allowed but is no longer (and for good reason)
|
||||
statement error
|
||||
create macro my_macro2(a := i) as (
|
||||
select min(a) from integers
|
||||
);
|
||||
----
|
||||
Invalid default value
|
||||
|
||||
# to test the dependencies we create this macro instead
|
||||
statement ok
|
||||
create macro my_macro2(i := 42) as (
|
||||
select min(a) + i from integers
|
||||
);
|
||||
|
||||
statement ok
|
||||
insert into integers values (5), (10), (13)
|
||||
|
||||
query I
|
||||
select my_macro2(84)
|
||||
----
|
||||
89
|
||||
|
||||
statement error
|
||||
drop table integers;
|
||||
----
|
||||
macro function "my_macro2" depends on table "integers".
|
||||
|
||||
statement ok
|
||||
drop table integers cascade;
|
||||
|
||||
# The macro was dropped by the CASCADE
|
||||
statement error
|
||||
select my_macro2(5);
|
||||
----
|
||||
Catalog Error: Scalar Function with name my_macro2 does not exist!
|
||||
|
||||
statement ok
|
||||
Create table t1 (a int, b int);
|
||||
|
||||
statement ok
|
||||
Create table t2 (c int, d int);
|
||||
|
||||
statement ok
|
||||
CREATE OR REPLACE MACRO eq(x := NULL, y := NULL) AS x = y
|
||||
|
||||
statement ok
|
||||
INSERT INTO t1 VALUES (1, 1), (1, 2), (2, 2), (3, 4);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t2 VALUES (4, 1), (2, 10), (6, 2), (2, 6);
|
||||
|
||||
statement ok
|
||||
SELECT * FROM t1 as t1_alias inner join (select * from t2) as t2_alias ON (eq(x := t1_alias.a, y := t2_alias.c))
|
||||
|
||||
# no default parameters with incorrect names
|
||||
statement error
|
||||
SELECT * FROM t1 as t1_alias inner join (select * from t2) as t2_alias ON (eq(a := t1_alias.a, c := t2_alias.c))
|
||||
----
|
||||
Binder Error
|
||||
|
||||
36
external/duckdb/test/sql/catalog/function/test_macro_issue_13104.test
vendored
Normal file
36
external/duckdb/test/sql/catalog/function/test_macro_issue_13104.test
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# name: test/sql/catalog/function/test_macro_issue_13104.test
|
||||
# description: Test Issue 13104 - Macro default variable that is a boolean type fails
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
create or replace macro my_macro(a:=true) as a;
|
||||
|
||||
query I
|
||||
select my_macro()
|
||||
----
|
||||
true
|
||||
|
||||
statement ok
|
||||
create or replace macro my_macro(a:=false) as a;
|
||||
|
||||
query I
|
||||
select my_macro()
|
||||
----
|
||||
false
|
||||
|
||||
# bonus: we can also use struct/list as default parameters now
|
||||
statement ok
|
||||
create or replace macro my_macro(a:={duck:42}) as a;
|
||||
|
||||
query I
|
||||
select my_macro()
|
||||
----
|
||||
{'duck': 42}
|
||||
|
||||
statement ok
|
||||
create or replace macro my_macro(a:=[42]) as a;
|
||||
|
||||
query I
|
||||
select my_macro()
|
||||
----
|
||||
[42]
|
||||
11
external/duckdb/test/sql/catalog/function/test_macro_issue_18927.test
vendored
Normal file
11
external/duckdb/test/sql/catalog/function/test_macro_issue_18927.test
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# name: test/sql/catalog/function/test_macro_issue_18927.test
|
||||
# description: Test Issue 18927 - Dot operator (function chaining) fails with macros
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
CREATE OR REPLACE MACRO my(s) AS s.lower().split('').aggregate('count');
|
||||
|
||||
query I
|
||||
SELECT my('AA');
|
||||
----
|
||||
2
|
||||
12
external/duckdb/test/sql/catalog/function/test_macro_issue_19119.test
vendored
Normal file
12
external/duckdb/test/sql/catalog/function/test_macro_issue_19119.test
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# name: test/sql/catalog/function/test_macro_issue_19119.test
|
||||
# description: Test Issue 19119 - Regression: combination of window functions and RAISE_EVEN raises "Not implemented Error: Unimplemented expression class"
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t (x INT);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t (x) VALUES (1), (2);
|
||||
|
||||
statement ok
|
||||
SELECT ROUND_EVEN(SUM(x) OVER (), 0) AS y FROM t;
|
||||
97
external/duckdb/test/sql/catalog/function/test_macro_overloads.test
vendored
Normal file
97
external/duckdb/test/sql/catalog/function/test_macro_overloads.test
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
# name: test/sql/catalog/function/test_macro_overloads.test
|
||||
# description: Test macro overloads
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# simple overloaded macro
|
||||
statement ok
|
||||
CREATE MACRO multi_add
|
||||
() AS 0,
|
||||
(a) AS a,
|
||||
(a, b) AS a + b,
|
||||
(a, b, c) AS a + b + c,
|
||||
(a, b, c, d) AS a + b + c + d,
|
||||
(a, b, c, d, e) AS a + b + c + d + e
|
||||
|
||||
query IIIIII
|
||||
SELECT multi_add(),
|
||||
multi_add(42),
|
||||
multi_add(42, 1),
|
||||
multi_add(42, 1, 1),
|
||||
multi_add(42, 1, 1, 1),
|
||||
multi_add(42, 1, 1, 1, 1)
|
||||
----
|
||||
0 42 43 44 45 46
|
||||
|
||||
# overload not found
|
||||
statement error
|
||||
SELECT multi_add(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
# named parameters
|
||||
statement ok
|
||||
CREATE MACRO arithmetic
|
||||
(a, b, mult := 1) AS (a + b) * mult,
|
||||
(a, b, c, division := 1) AS (a + b + c) / division
|
||||
|
||||
statement error
|
||||
select arithmetic(100, 200, 300)
|
||||
----
|
||||
multiple overloads that match the supplied arguments
|
||||
|
||||
# disambiguate arithmetic(100, 200, 300) using c := 300
|
||||
query IIII
|
||||
SELECT arithmetic(42, 84), arithmetic(42, 84, mult := 10), arithmetic(100, 200, c := 300), arithmetic(100, 200, 300, division := 10)
|
||||
----
|
||||
126 1260 600 60
|
||||
|
||||
# table macro overloads
|
||||
statement ok
|
||||
CREATE MACRO generate_numbers
|
||||
(a, b) AS TABLE (SELECT * FROM range(a + b) t(i)),
|
||||
(a, b, c, mult := 1) AS TABLE (SELECT * FROM range((a + b + c) * mult) t(i))
|
||||
|
||||
query I
|
||||
SELECT COUNT(*) FROM generate_numbers(20, 10);
|
||||
----
|
||||
30
|
||||
|
||||
query I
|
||||
SELECT COUNT(*) FROM generate_numbers(1, 2, 2, mult := 5);
|
||||
----
|
||||
25
|
||||
|
||||
|
||||
# view overloads in duckdb_functions
|
||||
query II
|
||||
SELECT function_name, parameters FROM duckdb_functions() WHERE function_name IN ('arithmetic', 'multi_add', 'generate_numbers') ORDER BY function_name, len(parameters)
|
||||
----
|
||||
arithmetic [a, b, mult]
|
||||
arithmetic [a, b, c, division]
|
||||
generate_numbers [a, b]
|
||||
generate_numbers [a, b, c, mult]
|
||||
multi_add []
|
||||
multi_add [a]
|
||||
multi_add [a, b]
|
||||
multi_add [a, b, c]
|
||||
multi_add [a, b, c, d]
|
||||
multi_add [a, b, c, d, e]
|
||||
|
||||
# ambiguity conflict between macros
|
||||
statement error
|
||||
CREATE MACRO ambiguous_macro
|
||||
(a) AS a,
|
||||
(a) AS a + 1
|
||||
----
|
||||
Ambiguity in macro overloads
|
||||
|
||||
# error in macro overload definition
|
||||
statement error
|
||||
CREATE MACRO error_in_definition
|
||||
(a) AS a,
|
||||
(a, b) AS a + y
|
||||
----
|
||||
Referenced column "y" not found in FROM clause
|
||||
73
external/duckdb/test/sql/catalog/function/test_macro_relpersistence_conflict.test
vendored
Normal file
73
external/duckdb/test/sql/catalog/function/test_macro_relpersistence_conflict.test
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
# name: test/sql/catalog/function/test_macro_relpersistence_conflict.test
|
||||
# description: Test Macro temporary/if exists/or replace
|
||||
# group: [function]
|
||||
|
||||
load __TEST_DIR__/my_macro_database.db
|
||||
|
||||
statement ok
|
||||
PRAGMA disable_checkpoint_on_shutdown
|
||||
|
||||
statement ok
|
||||
PRAGMA wal_autocheckpoint='1TB';
|
||||
|
||||
statement ok
|
||||
create macro test(a, b) as a + b
|
||||
|
||||
query T
|
||||
select test(4, 2)
|
||||
----
|
||||
6
|
||||
|
||||
statement ok
|
||||
create or replace macro test(a, b) as a + a
|
||||
|
||||
# should be different now
|
||||
query T
|
||||
select test(4, 2)
|
||||
----
|
||||
8
|
||||
|
||||
# should be ignored
|
||||
statement ok
|
||||
create macro if not exists test(a, b) as a + b
|
||||
|
||||
query T
|
||||
select test(4, 2)
|
||||
----
|
||||
8
|
||||
|
||||
statement ok
|
||||
drop macro test
|
||||
|
||||
# now let's do the same stuff with a temporary macro
|
||||
statement ok
|
||||
create temporary macro test(a, b) as a + b
|
||||
|
||||
query T
|
||||
select test(4, 2)
|
||||
----
|
||||
6
|
||||
|
||||
statement ok
|
||||
create or replace temporary macro test(a, b) as a + a
|
||||
|
||||
query T
|
||||
select test(4, 2)
|
||||
----
|
||||
8
|
||||
|
||||
statement ok
|
||||
create temporary macro if not exists test(a, b) as a + b
|
||||
|
||||
query T
|
||||
select test(4, 2)
|
||||
----
|
||||
8
|
||||
|
||||
restart
|
||||
|
||||
# macro should be gone
|
||||
statement error
|
||||
select test(4, 2)
|
||||
----
|
||||
<REGEX>:.*Catalog Error.*does not exist.*
|
||||
352
external/duckdb/test/sql/catalog/function/test_macro_type_overloads.test
vendored
Normal file
352
external/duckdb/test/sql/catalog/function/test_macro_type_overloads.test
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
# name: test/sql/catalog/function/test_macro_type_overloads.test
|
||||
# description: Test macro TYPE overloads
|
||||
# group: [function]
|
||||
|
||||
# always works for in-memory dbs
|
||||
statement ok
|
||||
attach ':memory:' AS inmemorydb
|
||||
|
||||
statement ok
|
||||
use inmemorydb
|
||||
|
||||
statement ok
|
||||
create or replace macro m(s varchar) as s || 'c'
|
||||
|
||||
statement ok
|
||||
drop macro m;
|
||||
|
||||
statement ok
|
||||
attach '__TEST_DIR__/test_macro_type_overloads_olderdb.db' AS olderdb (storage_version 'v1.3.0')
|
||||
|
||||
statement ok
|
||||
use olderdb
|
||||
|
||||
# does not work for older versions
|
||||
statement error
|
||||
create or replace macro m(s varchar) as s || 'c'
|
||||
----
|
||||
Typed macro parameters are only supported for
|
||||
|
||||
# we can also always create temporary typed macros
|
||||
statement ok
|
||||
create or replace temporary macro m(s varchar) as s || 'c'
|
||||
|
||||
statement ok
|
||||
drop macro m;
|
||||
|
||||
# rest of the tests proceed with a db version that works
|
||||
statement ok
|
||||
attach '__TEST_DIR__/test_macro_type_overloads_newerdb.db' AS newerdb (storage_version 'v1.4.0')
|
||||
|
||||
statement ok
|
||||
use newerdb
|
||||
|
||||
statement ok
|
||||
create view v as select 42
|
||||
|
||||
# create macro with type varchar
|
||||
statement ok
|
||||
create or replace macro m(s varchar) as s || 'c'
|
||||
|
||||
# this works
|
||||
query I
|
||||
select m('ab')
|
||||
----
|
||||
abc
|
||||
|
||||
query I
|
||||
select m(s := 'ab')
|
||||
----
|
||||
abc
|
||||
|
||||
# list cannot be implicitly cast to varchar, so this fails
|
||||
statement error
|
||||
select m([42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
select m(s := [42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
# test the same behavior with an arg with a default
|
||||
statement ok
|
||||
create or replace macro m(s varchar := 'cc') as s || 'c'
|
||||
|
||||
query I
|
||||
select m('ab')
|
||||
----
|
||||
abc
|
||||
|
||||
query I
|
||||
select m(s := 'ab')
|
||||
----
|
||||
abc
|
||||
|
||||
statement error
|
||||
select m([42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
select m(s := [42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement ok
|
||||
create or replace macro m
|
||||
(a tinyint) as a + 1,
|
||||
(a smallint) as a + 2,
|
||||
(a integer) as a + 3,
|
||||
(a bigint) as a + 4,
|
||||
(a hugeint) as a + 5,
|
||||
(a) as a + 10
|
||||
|
||||
# to support the sliding window of forwards compatibility, we don't yet serialize parameter types to storage
|
||||
# therefore, this test has is skipped in the force_storage_restart.json test config
|
||||
query I
|
||||
select parameter_types[1]
|
||||
from duckdb_functions()
|
||||
where function_name = 'm'
|
||||
and function_type = 'macro'
|
||||
order by all
|
||||
----
|
||||
BIGINT
|
||||
HUGEINT
|
||||
INTEGER
|
||||
SMALLINT
|
||||
TINYINT
|
||||
NULL
|
||||
|
||||
query IIIIII
|
||||
select
|
||||
m(0::tinyint),
|
||||
m(0::smallint),
|
||||
m(0::integer),
|
||||
m(0::bigint),
|
||||
m(0::hugeint),
|
||||
m(0::double)
|
||||
----
|
||||
1 2 3 4 5 10
|
||||
|
||||
# not sure if I agree with this but this is how our implicit cast cost rules select the lowest cost function
|
||||
# i also doubt that people will create this many integer type overloads with different behaviors
|
||||
query IIIIII
|
||||
select
|
||||
m(0::utinyint),
|
||||
m(0::usmallint),
|
||||
m(0::uinteger),
|
||||
m(0::ubigint),
|
||||
m(0::uhugeint),
|
||||
m(0::float)
|
||||
----
|
||||
4 4 4 5 10 10
|
||||
|
||||
statement ok
|
||||
create or replace macro m
|
||||
(i int, j) as i + j,
|
||||
(i, j int) as i - j;
|
||||
|
||||
# exact same cost, can't disambiguate with these arguments
|
||||
statement error
|
||||
select m(0, 42)
|
||||
----
|
||||
has multiple overloads
|
||||
|
||||
# this resolves to the first one because the first arg is int
|
||||
query I
|
||||
select m(0, 42::float)
|
||||
----
|
||||
42
|
||||
|
||||
# this resolves to the second one because the second arg is int
|
||||
query I
|
||||
select m(0::float, 42)
|
||||
----
|
||||
-42
|
||||
|
||||
# user types should at least bind properly (instead of defaulting to LogicalTypeId::USER)
|
||||
statement ok
|
||||
create or replace type cool_string as varchar;
|
||||
|
||||
statement ok
|
||||
create or replace macro m(s cool_string) as s;
|
||||
|
||||
statement ok
|
||||
select m('duck')
|
||||
|
||||
# this fails on creation because we won't implicitly cast
|
||||
statement error
|
||||
create or replace macro m(s varchar := 42) as s
|
||||
----
|
||||
cannot be implicitly cast
|
||||
|
||||
# can fix with an explicit type cast
|
||||
statement ok
|
||||
create or replace macro m(s varchar := 42::varchar) as s
|
||||
|
||||
# this can be implicitly cast so it succeeds
|
||||
statement ok
|
||||
create or replace macro m(i bigint := 42::integer) as i
|
||||
|
||||
# test that the supplied arg is cast to a bigint
|
||||
query I
|
||||
select typeof(m(42::integer))
|
||||
----
|
||||
BIGINT
|
||||
|
||||
# replicate tests above with table macro
|
||||
statement ok
|
||||
create or replace macro m(s varchar) as table (select s || 'c')
|
||||
|
||||
query I
|
||||
from m('ab')
|
||||
----
|
||||
abc
|
||||
|
||||
query I
|
||||
from m(s := 'ab')
|
||||
----
|
||||
abc
|
||||
|
||||
statement error
|
||||
from m([42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
from m(s := [42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement ok
|
||||
create or replace macro m(s varchar := 'cc') as table (select s || 'c')
|
||||
|
||||
query I
|
||||
from m('ab')
|
||||
----
|
||||
abc
|
||||
|
||||
query I
|
||||
from m(s := 'ab')
|
||||
----
|
||||
abc
|
||||
|
||||
statement error
|
||||
from m([42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
from m(s := [42])
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement ok
|
||||
create or replace macro m
|
||||
(a tinyint) as table (select a + 1),
|
||||
(a smallint) as table (select a + 2),
|
||||
(a integer) as table (select a + 3),
|
||||
(a bigint) as table (select a + 4),
|
||||
(a hugeint) as table (select a + 5),
|
||||
(a) as table (select a + 10)
|
||||
|
||||
query I
|
||||
select parameter_types[1]
|
||||
from duckdb_functions()
|
||||
where function_name = 'm'
|
||||
and function_type = 'table_macro'
|
||||
order by all
|
||||
----
|
||||
BIGINT
|
||||
HUGEINT
|
||||
INTEGER
|
||||
SMALLINT
|
||||
TINYINT
|
||||
NULL
|
||||
|
||||
query I
|
||||
from m(0::tinyint)
|
||||
union all
|
||||
from m(0::smallint)
|
||||
union all
|
||||
from m(0::integer)
|
||||
union all
|
||||
from m(0::bigint)
|
||||
union all
|
||||
from m(0::hugeint)
|
||||
union all
|
||||
from m(0::double)
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
10
|
||||
|
||||
query I
|
||||
from m(0::utinyint)
|
||||
union all
|
||||
from m(0::usmallint)
|
||||
union all
|
||||
from m(0::uinteger)
|
||||
union all
|
||||
from m(0::ubigint)
|
||||
union all
|
||||
from m(0::uhugeint)
|
||||
union all
|
||||
from m(0::float)
|
||||
----
|
||||
4
|
||||
4
|
||||
4
|
||||
5
|
||||
10
|
||||
10
|
||||
|
||||
statement ok
|
||||
create or replace macro m
|
||||
(i int, j) as table (select i + j),
|
||||
(i, j int) as table (select i - j);
|
||||
|
||||
statement error
|
||||
from m(0, 42)
|
||||
----
|
||||
has multiple overloads
|
||||
|
||||
query I
|
||||
from m(0, 42::float)
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
from m(0::float, 42)
|
||||
----
|
||||
-42
|
||||
|
||||
statement ok
|
||||
create or replace type cool_string as varchar;
|
||||
|
||||
statement ok
|
||||
create or replace macro m(s cool_string) as table (select s);
|
||||
|
||||
statement ok
|
||||
from m('duck')
|
||||
|
||||
statement error
|
||||
create or replace macro m(s varchar := 42) as table (select s)
|
||||
----
|
||||
cannot be implicitly cast
|
||||
|
||||
statement ok
|
||||
create or replace macro m(s varchar := 42::varchar) as table (select s)
|
||||
|
||||
statement ok
|
||||
create or replace macro m(i bigint := 42::integer) as table (select i as i)
|
||||
|
||||
query I
|
||||
select typeof(i) from m(42::integer)
|
||||
----
|
||||
BIGINT
|
||||
16
external/duckdb/test/sql/catalog/function/test_macro_with_unknown_types.test
vendored
Normal file
16
external/duckdb/test/sql/catalog/function/test_macro_with_unknown_types.test
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# name: test/sql/catalog/function/test_macro_with_unknown_types.test
|
||||
# description: Test MACRO binding with unknown parameter types.
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification;
|
||||
|
||||
statement ok
|
||||
CREATE TEMP MACRO m1(x, y) AS (
|
||||
SELECT list_has_all(x, y) AND list_has_all(y, x)
|
||||
);
|
||||
|
||||
query I
|
||||
SELECT m1([1, 2], [1, 2]);
|
||||
----
|
||||
true
|
||||
60
external/duckdb/test/sql/catalog/function/test_recursive_macro.test
vendored
Normal file
60
external/duckdb/test/sql/catalog/function/test_recursive_macro.test
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
# name: test/sql/catalog/function/test_recursive_macro.test
|
||||
# description: Test recursive macros
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
set enable_macro_dependencies=true
|
||||
|
||||
statement ok
|
||||
CREATE MACRO "sum"(x) AS (CASE WHEN sum(x) IS NULL THEN 0 ELSE sum(x) END);
|
||||
|
||||
statement error
|
||||
SELECT sum(1);
|
||||
----
|
||||
Max expression depth limit
|
||||
|
||||
statement error
|
||||
SELECT sum(1) WHERE 42=0
|
||||
----
|
||||
Max expression depth limit
|
||||
|
||||
statement ok
|
||||
DROP MACRO sum
|
||||
|
||||
# recursive macro with explicit qualification
|
||||
statement ok
|
||||
CREATE MACRO "sum"(x) AS (CASE WHEN system.main.sum(x) IS NULL THEN 0 ELSE system.main.sum(x) END);
|
||||
|
||||
query I
|
||||
SELECT sum(1);
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
SELECT sum(1) WHERE 42=0
|
||||
----
|
||||
0
|
||||
|
||||
# evil test case by Mark
|
||||
statement ok
|
||||
create macro m1(a) as a+1;
|
||||
|
||||
statement ok
|
||||
create macro m2(a) as m1(a)+1;
|
||||
|
||||
statement error
|
||||
create or replace macro m1(a) as m2(a)+1;
|
||||
----
|
||||
Catalog Error: CREATE OR REPLACE is not allowed to depend on itself
|
||||
|
||||
# also table macros
|
||||
statement ok
|
||||
create macro m3(a) as a+1;
|
||||
|
||||
statement ok
|
||||
create macro m4(a) as table select m3(a);
|
||||
|
||||
statement error
|
||||
create or replace macro m3(a) as (from m4(42));
|
||||
----
|
||||
Catalog Error: CREATE OR REPLACE is not allowed to depend on itself
|
||||
53
external/duckdb/test/sql/catalog/function/test_recursive_macro_no_dependency.test
vendored
Normal file
53
external/duckdb/test/sql/catalog/function/test_recursive_macro_no_dependency.test
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# name: test/sql/catalog/function/test_recursive_macro_no_dependency.test
|
||||
# description: Test recursive macros
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
CREATE MACRO "sum"(x) AS (CASE WHEN sum(x) IS NULL THEN 0 ELSE sum(x) END);
|
||||
|
||||
statement error
|
||||
SELECT sum(1);
|
||||
----
|
||||
Max expression depth limit
|
||||
|
||||
statement error
|
||||
SELECT sum(1) WHERE 42=0
|
||||
----
|
||||
Max expression depth limit
|
||||
|
||||
statement ok
|
||||
DROP MACRO sum
|
||||
|
||||
# recursive macro with explicit qualification
|
||||
statement ok
|
||||
CREATE MACRO "sum"(x) AS (CASE WHEN system.main.sum(x) IS NULL THEN 0 ELSE system.main.sum(x) END);
|
||||
|
||||
query I
|
||||
SELECT sum(1);
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
SELECT sum(1) WHERE 42=0
|
||||
----
|
||||
0
|
||||
|
||||
# evil test case by Mark
|
||||
statement ok
|
||||
create macro m1(a) as a+1;
|
||||
|
||||
statement ok
|
||||
create macro m2(a) as m1(a)+1;
|
||||
|
||||
statement ok
|
||||
create or replace macro m1(a) as m2(a)+1;
|
||||
|
||||
# also table macros
|
||||
statement ok
|
||||
create macro m3(a) as a+1;
|
||||
|
||||
statement ok
|
||||
create macro m4(a) as table select m3(a);
|
||||
|
||||
statement ok
|
||||
create or replace macro m3(a) as (from m4(42));
|
||||
98
external/duckdb/test/sql/catalog/function/test_sequence_macro.test
vendored
Normal file
98
external/duckdb/test/sql/catalog/function/test_sequence_macro.test
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
# name: test/sql/catalog/function/test_sequence_macro.test
|
||||
# description: Test Sequence Macro
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers (i INT)
|
||||
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (42), (42)
|
||||
|
||||
statement ok
|
||||
CREATE SEQUENCE seq
|
||||
|
||||
# recursive CTE with sequences
|
||||
statement ok
|
||||
CREATE MACRO in_next_n(x, s, n) AS x IN (
|
||||
WITH RECURSIVE cte AS (
|
||||
SELECT nextval(s) AS nxt, 1 AS iter
|
||||
UNION ALL
|
||||
SELECT nextval(s), iter + 1
|
||||
FROM cte
|
||||
WHERE iter < n
|
||||
)
|
||||
SELECT nxt
|
||||
FROM cte
|
||||
)
|
||||
|
||||
query T
|
||||
SELECT in_next_n(3, 'seq', 5);
|
||||
----
|
||||
1
|
||||
|
||||
query T
|
||||
SELECT in_next_n(3, 'seq', 5);
|
||||
----
|
||||
0
|
||||
|
||||
query T
|
||||
SELECT in_next_n(12, 'seq', 5);
|
||||
----
|
||||
1
|
||||
|
||||
# overlapping param/column names can be disambiguated
|
||||
statement ok
|
||||
CREATE MACRO in_next_n2(x, s, n) AS x IN (
|
||||
WITH RECURSIVE cte AS (
|
||||
SELECT nextval(s) AS nxt, n AS n
|
||||
UNION ALL
|
||||
SELECT nextval(s), cte.n - 1
|
||||
FROM cte
|
||||
WHERE cte.n > 1
|
||||
)
|
||||
SELECT nxt
|
||||
FROM cte
|
||||
)
|
||||
|
||||
query T
|
||||
SELECT in_next_n2(17, 'seq', 5);
|
||||
----
|
||||
1
|
||||
|
||||
statement ok
|
||||
DROP SEQUENCE seq
|
||||
|
||||
statement ok
|
||||
CREATE SEQUENCE seq1
|
||||
|
||||
statement ok
|
||||
CREATE SEQUENCE seq2 INCREMENT BY 2 START WITH 2
|
||||
|
||||
statement ok
|
||||
CREATE MACRO test(s1, s2, x) AS nextval(s1) + nextval(s2) + x
|
||||
|
||||
query T
|
||||
SELECT test('seq1', 'seq2', i) FROM integers
|
||||
----
|
||||
45
|
||||
48
|
||||
|
||||
statement ok
|
||||
DROP SEQUENCE seq1
|
||||
|
||||
statement ok
|
||||
DROP SEQUENCE seq2
|
||||
|
||||
# argument with side-effects not allowed
|
||||
statement ok
|
||||
CREATE MACRO add_macro(a, b) AS a + b
|
||||
|
||||
statement ok
|
||||
CREATE SEQUENCE seqq
|
||||
|
||||
# TODO: uncomment when macro parameters are pushed as a projection
|
||||
#query T
|
||||
#SELECT add_macro(i + nextval('seqq'), 5) FROM integers
|
||||
#----
|
||||
#48
|
||||
#48
|
||||
379
external/duckdb/test/sql/catalog/function/test_simple_macro.test
vendored
Normal file
379
external/duckdb/test/sql/catalog/function/test_simple_macro.test
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
# name: test/sql/catalog/function/test_simple_macro.test
|
||||
# description: Test Simple Macro
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers (a INT)
|
||||
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (1)
|
||||
|
||||
statement ok
|
||||
CREATE MACRO one() AS (SELECT 1);
|
||||
|
||||
query T
|
||||
SELECT one()
|
||||
----
|
||||
1
|
||||
|
||||
statement error
|
||||
SELECT one(1)
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
SELECT one(NULL)
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement ok
|
||||
DROP MACRO one;
|
||||
|
||||
# HAVING in a macro
|
||||
statement ok
|
||||
CREATE MACRO having_macro(x) AS (SELECT * FROM integers GROUP BY a HAVING a = x)
|
||||
|
||||
query T
|
||||
SELECT having_macro(1)
|
||||
----
|
||||
1
|
||||
|
||||
query T
|
||||
SELECT having_macro(6)
|
||||
----
|
||||
NULL
|
||||
|
||||
# UNION in a macro
|
||||
statement ok
|
||||
CREATE MACRO union_macro(x, y, z) AS (SELECT x IN (SELECT y UNION ALL SELECT z))
|
||||
|
||||
query T
|
||||
SELECT union_macro(1, 2, 3)
|
||||
----
|
||||
false
|
||||
|
||||
query T
|
||||
SELECT union_macro(1, 2, 1)
|
||||
----
|
||||
true
|
||||
|
||||
query T
|
||||
SELECT union_macro(1, 1, 2)
|
||||
----
|
||||
true
|
||||
|
||||
# expression list
|
||||
statement ok
|
||||
CREATE MACRO in_expression_list(x, y, z) AS (SELECT x IN (VALUES (y), (z)))
|
||||
|
||||
query T
|
||||
SELECT in_expression_list(1, 2, 3)
|
||||
----
|
||||
false
|
||||
|
||||
query T
|
||||
SELECT in_expression_list(1, 2, 1)
|
||||
----
|
||||
true
|
||||
|
||||
query T
|
||||
SELECT in_expression_list(1, 1, 2)
|
||||
----
|
||||
true
|
||||
|
||||
# FUNCTION alias
|
||||
statement ok
|
||||
CREATE FUNCTION two() AS (SELECT 2);
|
||||
|
||||
query T
|
||||
SELECT two()
|
||||
----
|
||||
2
|
||||
|
||||
statement ok
|
||||
DROP FUNCTION two;
|
||||
|
||||
# b cannot be found
|
||||
statement error
|
||||
CREATE MACRO add_macro(a) AS a + b
|
||||
----
|
||||
column "b" not found
|
||||
|
||||
statement ok
|
||||
CREATE MACRO add_macro(a, b) AS a + b
|
||||
|
||||
query T
|
||||
SELECT add_macro(a,a) FROM integers
|
||||
----
|
||||
2
|
||||
|
||||
statement ok
|
||||
CREATE TABLE floats (b FLOAT)
|
||||
|
||||
statement ok
|
||||
INSERT INTO floats VALUES (0.5)
|
||||
|
||||
query T
|
||||
SELECT add_macro(a,2) + add_macro(3,b) FROM integers, floats
|
||||
----
|
||||
6.5
|
||||
|
||||
# can create function with same name as a ScalarFunction
|
||||
statement ok
|
||||
CREATE MACRO string_split(a,b) AS a + b
|
||||
|
||||
query I
|
||||
SELECT string_split(1, 2)
|
||||
----
|
||||
3
|
||||
|
||||
statement ok
|
||||
CREATE MACRO IFELSE(a,b,c) AS CASE WHEN a THEN b ELSE c END
|
||||
|
||||
query T
|
||||
SELECT IFELSE(1,'true','false')
|
||||
----
|
||||
true
|
||||
|
||||
query T
|
||||
SELECT ifelse(1,'true','false')
|
||||
----
|
||||
true
|
||||
|
||||
query T
|
||||
SELECT IFELSE(0,'true','false')
|
||||
----
|
||||
false
|
||||
|
||||
query T
|
||||
SELECT IFELSE(a = 1, 'true', 'false') FROM integers
|
||||
----
|
||||
true
|
||||
|
||||
query T
|
||||
SELECT IFELSE(a = 0, 'true', 'false') FROM integers
|
||||
----
|
||||
false
|
||||
|
||||
# incorrect number of arguments
|
||||
statement error
|
||||
SELECT IFELSE();
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
SELECT IFELSE(1);
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
SELECT IFELSE(1, 2);
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
SELECT IFELSE(1, 2, 3, 4);
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
# no duplicate macro function names
|
||||
statement error
|
||||
CREATE MACRO IFELSE(a,b) AS a+b
|
||||
----
|
||||
already exists
|
||||
|
||||
statement error
|
||||
CREATE MACRO ifelse(a,b) AS a+b
|
||||
----
|
||||
already exists
|
||||
|
||||
query T
|
||||
SELECT IFELSE('1', 'random', RANDOM()::VARCHAR)
|
||||
----
|
||||
random
|
||||
|
||||
# macro in a different schema
|
||||
statement ok
|
||||
CREATE SCHEMA macros
|
||||
|
||||
statement ok
|
||||
CREATE MACRO macros.add_macro(a, b) AS a + b
|
||||
|
||||
query T
|
||||
SELECT macros.add_macro(40,2)
|
||||
----
|
||||
42
|
||||
|
||||
# conflicting parameter names in macro definition
|
||||
statement error
|
||||
CREATE MACRO conflict(i, i) AS i + 1
|
||||
----
|
||||
|
||||
# aggregation macro's
|
||||
statement ok
|
||||
CREATE MACRO myavg(x) AS SUM(x) / COUNT(x)
|
||||
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (21), (41);
|
||||
|
||||
query T
|
||||
SELECT myavg(a) FROM integers
|
||||
----
|
||||
21
|
||||
|
||||
statement ok
|
||||
CREATE MACRO weird_avg(x) AS (MIN(x) + MAX(x)) / COUNT(x)
|
||||
|
||||
query T
|
||||
SELECT weird_avg(a) FROM integers
|
||||
----
|
||||
14
|
||||
|
||||
statement error
|
||||
CREATE MACRO star() AS *
|
||||
----
|
||||
|
||||
# macro's with default arguments
|
||||
statement error
|
||||
CREATE MACRO conflict(a, a := 1) AS a + a
|
||||
----
|
||||
|
||||
statement ok
|
||||
CREATE MACRO add_default5(a, b := 5) AS a + b
|
||||
|
||||
query I
|
||||
SELECT add_default5(3, 6)
|
||||
----
|
||||
9
|
||||
|
||||
query T
|
||||
SELECT add_default5(3)
|
||||
----
|
||||
8
|
||||
|
||||
query T
|
||||
SELECT add_default5(3, b := 6)
|
||||
----
|
||||
9
|
||||
|
||||
statement error
|
||||
SELECT add_default5(b := 6, 3)
|
||||
----
|
||||
positional argument following named argument
|
||||
|
||||
statement error
|
||||
CREATE MACRO wrong_order(a, b := 3, c) AS a + b + c
|
||||
----
|
||||
Parameter without a default follows parameter with a default
|
||||
|
||||
statement error
|
||||
CREATE MACRO wrong_order(a := 3, b) AS a + b
|
||||
----
|
||||
Parameter without a default follows parameter with a default
|
||||
|
||||
# only constant default values are allowed
|
||||
statement error
|
||||
CREATE MACRO select_plus_floats(a, f := b) AS (SELECT a + f FROM floats)
|
||||
----
|
||||
Invalid default value
|
||||
|
||||
# +(FLOAT, VARCHAR) does not work - but types are only checked once the macro is called
|
||||
statement ok
|
||||
CREATE MACRO wrong_type(s := 'not a float') AS (SELECT b + s FROM floats)
|
||||
|
||||
# this should fail
|
||||
statement error
|
||||
select wrong_type()
|
||||
----
|
||||
Could not convert
|
||||
|
||||
# but succeed if we pass the correct type
|
||||
query I
|
||||
select wrong_type(42)
|
||||
----
|
||||
42.5
|
||||
|
||||
statement error
|
||||
CREATE MACRO two_default_params(a := 4, a := 2) AS a + a
|
||||
----
|
||||
Duplicate parameter
|
||||
|
||||
statement ok
|
||||
CREATE MACRO two_default_params(a := 4, b := 2) AS a + b
|
||||
|
||||
query T
|
||||
SELECT two_default_params()
|
||||
----
|
||||
6
|
||||
|
||||
query T
|
||||
SELECT two_default_params(a := 5)
|
||||
----
|
||||
7
|
||||
|
||||
query T
|
||||
SELECT two_default_params(b := 3)
|
||||
----
|
||||
7
|
||||
|
||||
statement error
|
||||
SELECT two_default_params(a := 5, a := 3)
|
||||
----
|
||||
has named argument repeated
|
||||
|
||||
statement error
|
||||
SELECT two_default_params(b := 5, b := 3)
|
||||
----
|
||||
has named argument repeated
|
||||
|
||||
statement error
|
||||
CREATE MACRO macros.add_macro(a, b) AS a + b
|
||||
----
|
||||
already exists
|
||||
|
||||
statement error
|
||||
CREATE MACRO my_macro(a.b) AS 42;
|
||||
----
|
||||
syntax error
|
||||
|
||||
statement error
|
||||
CREATE MACRO my_macro(a.b.c) AS 42;
|
||||
----
|
||||
syntax error
|
||||
|
||||
statement ok
|
||||
CREATE MACRO my_macro(a) AS 42;
|
||||
|
||||
statement error
|
||||
SELECT my_macro(x := 42);
|
||||
----
|
||||
does not support the supplied arguments
|
||||
|
||||
statement error
|
||||
SELECT my_macro(a := 42, a := 42);
|
||||
----
|
||||
has named argument repeated
|
||||
|
||||
# internal issue 1044
|
||||
statement ok
|
||||
create macro zz1(x) as (select 10+x);
|
||||
|
||||
statement ok
|
||||
create macro zz2(x) as 20+x;
|
||||
|
||||
query II
|
||||
select zz1(1),zz2(2);
|
||||
----
|
||||
11 22
|
||||
|
||||
# should not return any results (because we shouldn't display "macro_parameters"
|
||||
query III
|
||||
select function_name, parameters, macro_definition
|
||||
from duckdb_functions()
|
||||
where function_name like 'zz%'
|
||||
and macro_definition like '%macro_parameters%';
|
||||
----
|
||||
|
||||
66
external/duckdb/test/sql/catalog/function/test_subquery_macro.test
vendored
Normal file
66
external/duckdb/test/sql/catalog/function/test_subquery_macro.test
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# name: test/sql/catalog/function/test_subquery_macro.test
|
||||
# description: Test Macro with subquery
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers (a INT)
|
||||
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (1)
|
||||
|
||||
statement ok
|
||||
CREATE MACRO subquery(a) AS (SELECT a)
|
||||
|
||||
query T
|
||||
SELECT subquery(1)
|
||||
----
|
||||
1
|
||||
|
||||
query T
|
||||
SELECT subquery(NULL)
|
||||
----
|
||||
NULL
|
||||
|
||||
query T
|
||||
SELECT subquery(3) + a FROM integers
|
||||
----
|
||||
4
|
||||
|
||||
query T
|
||||
SELECT subquery(a) FROM integers
|
||||
----
|
||||
1
|
||||
|
||||
# macro parameters and column names should not conflict
|
||||
statement error
|
||||
CREATE MACRO a1(a) AS (SELECT a + a FROM integers)
|
||||
----
|
||||
|
||||
statement ok
|
||||
CREATE MACRO a1(b) AS (SELECT a + a FROM integers)
|
||||
|
||||
query T
|
||||
SELECT a1(3)
|
||||
----
|
||||
2
|
||||
|
||||
query T
|
||||
SELECT a1(3) + a FROM integers
|
||||
----
|
||||
3
|
||||
|
||||
# never allow columns with the same name as parameters
|
||||
statement error
|
||||
CREATE MACRO a2(a) AS (SELECT i.a + a FROM integers i)
|
||||
----
|
||||
|
||||
statement ok
|
||||
CREATE MACRO a2(b) AS (SELECT i.a + b FROM integers i)
|
||||
|
||||
query T
|
||||
SELECT a2(3)
|
||||
----
|
||||
4
|
||||
128
external/duckdb/test/sql/catalog/function/test_table_macro.test
vendored
Normal file
128
external/duckdb/test/sql/catalog/function/test_table_macro.test
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
# name: test/sql/catalog/function/test_table_macro.test
|
||||
# description: Test SELECTMacro
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
|
||||
statement ok
|
||||
CREATE TABLE test_tbl (id INT, name string);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE test2_tbl (id INT, name string);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE greek_tbl (id INT, name string);
|
||||
|
||||
statement ok
|
||||
INSERT INTO test_tbl VALUES (1,'tom'), (2,'dick'),(3,'harry'), (4,'mary'), (5,'mungo'), (6,'midge');
|
||||
|
||||
statement ok
|
||||
INSERT INTO test_tbl VALUES (20,'andrew'), (21,'boris'),(22,'Caleb'), (23,'david'), (24,'evan');
|
||||
|
||||
statement ok
|
||||
INSERT INTO greek_tbl VALUES (1, 'alpha'), (2, 'beta'), (3, 'gamma'), (4, 'delta'), (5, 'epsilon'),(6, 'zeta'), (7, 'eta') , (8, 'theta'), (9, 'iota') , (10, 'kappa');
|
||||
|
||||
statement ok
|
||||
CREATE MACRO xt(a,_name) as TABLE SELECT * FROM test_tbl WHERE(id>=a or name=_name);
|
||||
|
||||
statement ok
|
||||
CREATE MACRO xt2(a,_name) as TABLE SELECT * FROM test_tbl WHERE(id>=a or name like _name);
|
||||
|
||||
statement ok
|
||||
CREATE MACRO sgreek(a,b,c) as TABLE SELECT a,b FROM greek_tbl WHERE(id >= c);
|
||||
|
||||
query II
|
||||
( SELECT* FROM xt(1, 'tom') UNION SELECT* FROM xt2(1, '%%%') ) INTERSECT SELECT* FROM xt(100,'midge');
|
||||
----
|
||||
6 midge
|
||||
|
||||
query II
|
||||
(SELECT* FROM xt(1, 'tom') EXCEPT SELECT* FROM xt(20,'tom' )) INTERSECT SELECT* FROM xt(100,'harry');
|
||||
----
|
||||
3 harry
|
||||
|
||||
query II
|
||||
SELECT * FROM xt(200,'andrew');
|
||||
----
|
||||
20 andrew
|
||||
|
||||
query II
|
||||
SELECT * FROM xt2(100,'m%');
|
||||
----
|
||||
4 mary
|
||||
5 mungo
|
||||
6 midge
|
||||
|
||||
|
||||
# check similar to
|
||||
statement ok
|
||||
CREATE MACRO xtm(cmp_str) as TABLE SELECT id, name FROM test_tbl WHERE( name similar to cmp_str);
|
||||
|
||||
statement ok
|
||||
SELECT * FROM xtm('m.*');
|
||||
|
||||
# check regexp_matches
|
||||
statement ok
|
||||
CREATE MACRO xt_reg(cmp) as TABLE SELECT * FROM test_tbl WHERE regexp_matches(name ,cmp );
|
||||
|
||||
statement ok
|
||||
SELECT * FROM xt_reg('^m');
|
||||
|
||||
# use regular macro for comparison
|
||||
statement ok
|
||||
CREATE MACRO cmp(a,m) as regexp_matches(a,m) or a similar to m;
|
||||
|
||||
statement ok
|
||||
CREATE MACRO gm(m) as TABLE SELECT * FROM greek_tbl WHERE cmp(name,m);
|
||||
|
||||
statement ok
|
||||
SELECT * FROM gm('^m');
|
||||
|
||||
# create a scalar macro with same name as table macro
|
||||
statement ok
|
||||
CREATE MACRO xt(a,b) as a+b;
|
||||
|
||||
# drop table macro
|
||||
statement ok
|
||||
DROP MACRO TABLE xt;
|
||||
|
||||
# use column identifer as a macro parameter
|
||||
statement ok
|
||||
CREATE MACRO xt(id, imax) as TABLE SELECT id,name FROM test_tbl WHERE id<=imax;
|
||||
|
||||
query II
|
||||
SELECT * FROM xt(id,1);
|
||||
----
|
||||
1 tom
|
||||
|
||||
# try to create table macro with pre-existing table name "range"
|
||||
statement ok
|
||||
CREATE MACRO range(a,b) as TABLE select a,b from test_tbl;
|
||||
|
||||
# use table macro as a scalar macro
|
||||
query II
|
||||
SELECT * FROM test_tbl where id>=(SELECT max(id) FROM xt(id,30));
|
||||
----
|
||||
24 evan
|
||||
|
||||
# use table macro as a scalar macro
|
||||
query II
|
||||
SELECT * FROM greek_tbl where id<=(SELECT min(id) FROM xt(id,30));
|
||||
----
|
||||
1 alpha
|
||||
|
||||
|
||||
# check that table macros are present in duckdb_functions() -
|
||||
# nb they have the function_type 'table_macro'
|
||||
query IIIIIIIII
|
||||
SELECT schema_name, function_name, function_type, description, return_type, parameters, parameter_types, varargs, macro_definition FROM duckdb_functions() WHERE function_type = 'table_macro' AND
|
||||
( function_name = 'sgreek' or function_name = 'xt') order by function_name;
|
||||
----
|
||||
main sgreek table_macro NULL NULL [a, b, c] [NULL, NULL, NULL] NULL SELECT a, b FROM greek_tbl WHERE (id >= c)
|
||||
main xt table_macro NULL NULL [id, imax] [NULL, NULL] NULL SELECT id, "name" FROM test_tbl WHERE (id <= imax)
|
||||
|
||||
|
||||
|
||||
|
||||
157
external/duckdb/test/sql/catalog/function/test_table_macro_args.test
vendored
Normal file
157
external/duckdb/test/sql/catalog/function/test_table_macro_args.test
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
# name: test/sql/catalog/function/test_table_macro_args.test
|
||||
# description: Test table macros with default args
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE cards_tbl (val int, name string, suit string);
|
||||
|
||||
statement ok
|
||||
INSERT INTO cards_tbl values (1, 'ace', 'clubs'), (11,'jack', 'clubs' ),
|
||||
(12, 'queen', 'clubs' ), (13, 'king', 'clubs');
|
||||
|
||||
statement ok
|
||||
INSERT INTO cards_tbl values (1, 'ace', 'diamonds'), (11,'jack', 'diamonds' ),
|
||||
(12, 'queen', 'diamonds' ), (13, 'king', 'diamonds');
|
||||
|
||||
statement ok
|
||||
INSERT INTO cards_tbl values (1, 'ace', 'hearts'), (11,'jack', 'hearts' ),
|
||||
(12, 'queen', 'hearts' ), (13, 'king', 'hearts');
|
||||
|
||||
statement ok
|
||||
INSERT INTO cards_tbl values (1, 'ace', 'spades'), (11,'jack', 'spades' ),
|
||||
(12, 'queen', 'spades' ), (13, 'king', 'spades');
|
||||
|
||||
|
||||
|
||||
statement ok
|
||||
CREATE MACRO card_select(_val_min:=1, _val_max:=1, _name:='%', _suit:='%')
|
||||
as TABLE SELECT * FROM cards_tbl WHERE val>=_val_min AND val<=_val_max AND name like _name AND suit like _suit;
|
||||
|
||||
|
||||
# try out macro with default args
|
||||
query I
|
||||
SELECT DISTINCT val from card_select();
|
||||
----
|
||||
1
|
||||
|
||||
# a single args
|
||||
query III
|
||||
SELECT * FROM card_select(_suit:='clubs');
|
||||
----
|
||||
1 ace clubs
|
||||
|
||||
# args in wrong order
|
||||
query III
|
||||
SELECT * FROM card_select(_name:='king', _val_max:=13) ORDER BY suit;
|
||||
----
|
||||
13 king clubs
|
||||
13 king diamonds
|
||||
13 king hearts
|
||||
13 king spades
|
||||
|
||||
query I
|
||||
SELECT count(suit) FROM card_select() GROUP BY ALL;
|
||||
----
|
||||
4
|
||||
|
||||
# use every arg
|
||||
query III
|
||||
SELECT * FROM card_select(_name:='king', _val_max:=13, _suit:='hearts', _val_min:=10);
|
||||
----
|
||||
13 king hearts
|
||||
|
||||
|
||||
# try a macro again with regular args and default args
|
||||
statement ok
|
||||
CREATE MACRO card_select_args(_val_min, _val_max, _name:='%', _suit:='%')
|
||||
as TABLE SELECT * FROM cards_tbl WHERE val>=_val_min AND val<=_val_max AND name like _name AND suit like _suit;
|
||||
|
||||
# default args before positional args
|
||||
statement error
|
||||
SELECT * FROM card_select_args(_name:='king',1, 13);
|
||||
----
|
||||
|
||||
|
||||
# correct arg order
|
||||
query I
|
||||
SELECT suit FROM card_select_args(1, 13, _name:='king' ) ORDER BY suit;
|
||||
----
|
||||
clubs
|
||||
diamonds
|
||||
hearts
|
||||
spades
|
||||
|
||||
|
||||
|
||||
# create macro without any args
|
||||
statement ok
|
||||
CREATE MACRO card_dfl() as TABLE SELECT DISTINCT suit FROM cards_tbl where suit='hearts';
|
||||
|
||||
query I
|
||||
SELECT * FROM card_dfl();
|
||||
----
|
||||
hearts
|
||||
|
||||
|
||||
|
||||
# check order by , limit with expressions
|
||||
statement ok
|
||||
CREATE MACRO sc(aorder, border, nlimit) AS TABLE SELECT * FROM cards_tbl ORDER BY aorder,border LIMIT nlimit;
|
||||
|
||||
query III
|
||||
SELECT * FROM sc(name, suit, 4);
|
||||
----
|
||||
1 ace clubs
|
||||
1 ace diamonds
|
||||
1 ace hearts
|
||||
1 ace spades
|
||||
|
||||
# check limit PERCENT and offset
|
||||
statement ok
|
||||
CREATE MACRO sc2(dlimit, noffset) AS TABLE SELECT DISTINCT suit from cards_tbl order by all limit dlimit% offset noffset;
|
||||
|
||||
query I
|
||||
SELECT * FROM sc2(50.0, 2);
|
||||
----
|
||||
hearts
|
||||
spades
|
||||
|
||||
|
||||
statement ok
|
||||
CREATE MACRO sc3(col) AS TABLE SELECT DISTINCT ON (col) col FROM cards_tbl ORDER BY col;
|
||||
|
||||
query I
|
||||
SELECT * FROM sc3(name);
|
||||
----
|
||||
ace
|
||||
jack
|
||||
king
|
||||
queen
|
||||
|
||||
query I
|
||||
SELECT * FROM sc3(suit);
|
||||
----
|
||||
clubs
|
||||
diamonds
|
||||
hearts
|
||||
spades
|
||||
|
||||
|
||||
# create macro with non existing table
|
||||
statement error
|
||||
CREATE MACRO card_no_tbl() as TABLE SELECT * FROM suit_tbl;
|
||||
----
|
||||
Catalog Error
|
||||
|
||||
# wrong arg order
|
||||
statement error
|
||||
CREATE MACRO card_select_args(_val_min, _name:='%', _suit:='%', _val_max)
|
||||
as TABLE SELECT * FROM cards_tbl WHERE val>=_val_min AND val<=_val_max AND name like _name AND suit like _suit;
|
||||
----
|
||||
|
||||
|
||||
# positional parameter repeated
|
||||
statement error
|
||||
CREATE MACRO card_select_val(_val_min, _val_min) as TABLE SELECT * FROM cards_tbl WHERE val>=_val_min AND val<=_val_max;
|
||||
----
|
||||
Parser Error: Duplicate parameter
|
||||
68
external/duckdb/test/sql/catalog/function/test_table_macro_complex.test
vendored
Normal file
68
external/duckdb/test/sql/catalog/function/test_table_macro_complex.test
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# name: test/sql/catalog/function/test_table_macro_complex.test
|
||||
# description: Test SELECT Macro
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
CREATE MACRO my_values(m,s) as TABLE select * from (values (1.0*m+s,'adam'), (2.0*m+s,'ben'),
|
||||
(3.0*m+s,'cris'), (4.0*m+s,'desmond'),(5.0*m+s, 'eric'));
|
||||
|
||||
query I
|
||||
SELECT sum(col0) from my_values(10.0,5.0);
|
||||
----
|
||||
175.00
|
||||
|
||||
# recursive union select macro
|
||||
statement ok
|
||||
CREATE MACRO my_values_union(m1,s1,m2,s2) as TABLE select * from my_values(m1,s1) UNION select * from my_values(m2,s2);
|
||||
|
||||
query I
|
||||
select max(col0) from my_values_union(1.0,2.0,3.0,20.0);
|
||||
----
|
||||
35.00
|
||||
|
||||
# ranges
|
||||
statement ok
|
||||
CREATE MACRO dates_between(date_min, date_max, ilimit:=100) AS TABLE WITH dates(date) AS
|
||||
(SELECT * FROM range(date '0000-01-01', date '3000-01-01', interval '1' month))
|
||||
SELECT * FROM dates WHERE date between date_min AND date_max;
|
||||
|
||||
|
||||
query T
|
||||
select * from dates_between('2021-01-01', '2021-02-04');
|
||||
----
|
||||
2021-01-01 00:00:00
|
||||
2021-02-01 00:00:00
|
||||
|
||||
|
||||
# alternative verify turns this CTE into a materialized CTE,
|
||||
# which then does not terminate anymore.
|
||||
require no_alternative_verify
|
||||
|
||||
statement ok
|
||||
CREATE MACRO fibonacci(n0, n1, nlimit, noffset) AS TABLE
|
||||
WITH RECURSIVE fib AS (
|
||||
SELECT 1 AS n,
|
||||
n0::bigint AS "fibₙ",
|
||||
n1::bigint AS "fibₙ₊₁"
|
||||
UNION ALL
|
||||
SELECT n+1,
|
||||
"fibₙ₊₁",
|
||||
"fibₙ" + "fibₙ₊₁"
|
||||
FROM fib
|
||||
)
|
||||
SELECT n, "fibₙ" FROM fib
|
||||
LIMIT nlimit OFFSET noffset;
|
||||
|
||||
|
||||
|
||||
query II
|
||||
SELECT * FROM fibonacci(1, 2, 5, 10);
|
||||
----
|
||||
11 144
|
||||
12 233
|
||||
13 377
|
||||
14 610
|
||||
15 987
|
||||
|
||||
|
||||
|
||||
143
external/duckdb/test/sql/catalog/function/test_table_macro_copy.test
vendored
Normal file
143
external/duckdb/test/sql/catalog/function/test_table_macro_copy.test
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
# name: test/sql/catalog/function/test_table_macro_copy.test
|
||||
# description: Test SELECTMacro
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
load __TEST_DIR__/table_macro.db
|
||||
|
||||
statement ok
|
||||
CREATE TABLE test_tbl (id INT, name string);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE test2_tbl (id INT, name string);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE greek_tbl (id INT, name string);
|
||||
|
||||
statement ok
|
||||
INSERT INTO test_tbl VALUES (1,'tom'), (2,'dick'),(3,'harry'), (4,'mary'), (5,'mungo'), (6,'midge');
|
||||
|
||||
statement ok
|
||||
INSERT INTO test_tbl VALUES (20,'andrew'), (21,'boris'),(22,'Caleb'), (23,'david'), (24,'evan');
|
||||
|
||||
statement ok
|
||||
INSERT INTO greek_tbl VALUES (1, 'alpha'), (2, 'beta'), (3, 'gamma'), (4, 'delta'), (5, 'epsilon'),(6, 'zeta'), (7, 'eta') , (8, 'theta'), (9, 'iota') , (10, 'kappa');
|
||||
|
||||
statement ok
|
||||
CREATE MACRO xt(a,_name) as TABLE SELECT * FROM test_tbl WHERE(id>=a or name=_name);
|
||||
|
||||
statement ok
|
||||
CREATE MACRO xt2(a,_name) as TABLE SELECT * FROM test_tbl WHERE(id>=a or name like _name);
|
||||
|
||||
statement ok
|
||||
CREATE MACRO sgreek(a,b,c) as TABLE SELECT a,b FROM greek_tbl WHERE(id >= c);
|
||||
|
||||
query II
|
||||
( SELECT* FROM xt(1, 'tom') UNION SELECT* FROM xt2(1, '%%%') ) INTERSECT SELECT* FROM xt(100,'midge');
|
||||
----
|
||||
6 midge
|
||||
|
||||
query II
|
||||
(SELECT* FROM xt(1, 'tom') EXCEPT SELECT* FROM xt(20,'tom' )) INTERSECT SELECT* FROM xt(100,'harry');
|
||||
----
|
||||
3 harry
|
||||
|
||||
query II
|
||||
SELECT * FROM xt(200,'andrew');
|
||||
----
|
||||
20 andrew
|
||||
|
||||
query II
|
||||
SELECT * FROM xt2(100,'m%');
|
||||
----
|
||||
4 mary
|
||||
5 mungo
|
||||
6 midge
|
||||
|
||||
|
||||
# check similar to
|
||||
statement ok
|
||||
CREATE MACRO xtm(cmp_str) as TABLE SELECT id, name FROM test_tbl WHERE( name similar to cmp_str);
|
||||
|
||||
statement ok
|
||||
SELECT * FROM xtm('m.*');
|
||||
|
||||
# check regexp_matches
|
||||
statement ok
|
||||
CREATE MACRO xt_reg(cmp) as TABLE SELECT * FROM test_tbl WHERE regexp_matches(name ,cmp );
|
||||
|
||||
statement ok
|
||||
SELECT * FROM xt_reg('^m');
|
||||
|
||||
# use regular macro for comparison
|
||||
statement ok
|
||||
CREATE MACRO cmp(a,m) as regexp_matches(a,m) or a similar to m;
|
||||
|
||||
statement ok
|
||||
CREATE MACRO gm(m) as TABLE SELECT * FROM greek_tbl WHERE cmp(name,m);
|
||||
|
||||
statement ok
|
||||
SELECT * FROM gm('^m');
|
||||
|
||||
# create a scalar macro with same name as table macro
|
||||
statement ok
|
||||
CREATE MACRO xt(a,b) as a+b;
|
||||
|
||||
# drop table macro
|
||||
statement ok
|
||||
DROP MACRO TABLE xt;
|
||||
|
||||
# use column identifer as a macro parameter
|
||||
statement ok
|
||||
CREATE MACRO xt(id, imax) as TABLE SELECT id,name FROM test_tbl WHERE id<=imax;
|
||||
|
||||
query II
|
||||
SELECT * FROM xt(id,1);
|
||||
----
|
||||
1 tom
|
||||
|
||||
# try to create table macro with pre-existing table name "range"
|
||||
statement ok
|
||||
CREATE MACRO range(a,b) as TABLE select a,b from test_tbl;
|
||||
|
||||
# use table macro as a scalar macro
|
||||
query II
|
||||
SELECT * FROM test_tbl where id>=(SELECT max(id) FROM xt(id,30));
|
||||
----
|
||||
24 evan
|
||||
|
||||
# use table macro as a scalar macro
|
||||
query II
|
||||
SELECT * FROM greek_tbl where id<=(SELECT min(id) FROM xt(id,30));
|
||||
----
|
||||
1 alpha
|
||||
|
||||
|
||||
# check that table macros are present in duckdb_functions() -
|
||||
# nb they have the function_type 'table_macro'
|
||||
query IIIIIIIII
|
||||
SELECT schema_name, function_name, function_type, description, return_type, parameters, parameter_types, varargs, macro_definition FROM duckdb_functions() WHERE function_type = 'table_macro' AND
|
||||
( function_name = 'sgreek' or function_name = 'xt') order by function_name;
|
||||
----
|
||||
main sgreek table_macro NULL NULL [a, b, c] [NULL, NULL, NULL] NULL SELECT a, b FROM greek_tbl WHERE (id >= c)
|
||||
main xt table_macro NULL NULL [id, imax] [NULL, NULL] NULL SELECT id, "name" FROM test_tbl WHERE (id <= imax)
|
||||
|
||||
statement ok
|
||||
ATTACH '__TEST_DIR__/table_macro2.db'
|
||||
|
||||
statement ok
|
||||
COPY FROM DATABASE table_macro TO table_macro2
|
||||
|
||||
# check that table macros are present in duckdb_functions() -
|
||||
# nb they have the function_type 'table_macro'
|
||||
query IIIIIIIIII
|
||||
SELECT database_name, schema_name, function_name, function_type, description, return_type, parameters, parameter_types, varargs, macro_definition FROM duckdb_functions() WHERE function_type = 'table_macro' AND
|
||||
( function_name = 'sgreek' or function_name = 'xt') order by database_name, function_name;
|
||||
----
|
||||
table_macro main sgreek table_macro NULL NULL [a, b, c] [NULL, NULL, NULL] NULL SELECT a, b FROM greek_tbl WHERE (id >= c)
|
||||
table_macro main xt table_macro NULL NULL [id, imax] [NULL, NULL] NULL SELECT id, "name" FROM test_tbl WHERE (id <= imax)
|
||||
table_macro2 main sgreek table_macro NULL NULL [a, b, c] [NULL, NULL, NULL] NULL SELECT a, b FROM greek_tbl WHERE (id >= c)
|
||||
table_macro2 main xt table_macro NULL NULL [id, imax] [NULL, NULL] NULL SELECT id, "name" FROM test_tbl WHERE (id <= imax)
|
||||
|
||||
105
external/duckdb/test/sql/catalog/function/test_table_macro_groups.test
vendored
Normal file
105
external/duckdb/test/sql/catalog/function/test_table_macro_groups.test
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
# name: test/sql/catalog/function/test_table_macro_groups.test
|
||||
# description: Test table macros with GROUP BY, HAVING
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
SET default_null_order='nulls_first';
|
||||
|
||||
statement ok
|
||||
CREATE TABLE car_pool (
|
||||
-- define columns (name / type / default value / nullable)
|
||||
id DECIMAL ,
|
||||
producer VARCHAR(50) ,
|
||||
model VARCHAR(50) ,
|
||||
yyyy DECIMAL CHECK (yyyy BETWEEN 1970 AND 2020),
|
||||
counter DECIMAL CHECK (counter >= 0),
|
||||
CONSTRAINT car_pool_pk PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
statement ok
|
||||
INSERT INTO car_pool VALUES
|
||||
( 1, 'VW', 'Golf', 2005, 5),
|
||||
( 2, 'VW', 'Golf', 2006, 2),
|
||||
( 3, 'VW', 'Golf', 2007, 3),
|
||||
( 4, 'VW', 'Golf', 2008, 3),
|
||||
( 5, 'VW', 'Passat', 2005, 5),
|
||||
( 6, 'VW', 'Passat', 2006, 1),
|
||||
( 7, 'VW', 'Beetle', 2005, 1),
|
||||
( 8, 'VW', 'Beetle', 2006, 2),
|
||||
( 9, 'VW', 'Beetle', 2008, 4),
|
||||
(10, 'Toyota', 'Corolla', 2005, 4),
|
||||
(11, 'Toyota', 'Corolla', 2006, 3),
|
||||
(12, 'Toyota', 'Corolla', 2007, 2),
|
||||
(13, 'Toyota', 'Corolla', 2008, 4),
|
||||
(14, 'Toyota', 'Prius', 2005, 1),
|
||||
(15, 'Toyota', 'Prius', 2006, 1),
|
||||
(16, 'Toyota', 'Hilux', 2005, 1),
|
||||
(17, 'Toyota', 'Hilux', 2006, 1),
|
||||
(18, 'Toyota', 'Hilux', 2008, 1);
|
||||
|
||||
|
||||
statement ok
|
||||
CREATE MACRO car_pool_cube(g1, g2, hcnt:=1) AS
|
||||
TABLE SELECT g1, g2, sum(counter) AS cnt FROM car_pool
|
||||
GROUP BY CUBE(g1, g2) HAVING cnt >= hcnt order by g1 NULLS LAST, g2 NULLS LAST;
|
||||
|
||||
query III
|
||||
SELECT * FROM car_pool_cube(producer, model, hcnt:=4.0);
|
||||
----
|
||||
Toyota Corolla 13.000
|
||||
Toyota NULL 18.000
|
||||
VW Beetle 7.000
|
||||
VW Golf 13.000
|
||||
VW Passat 6.000
|
||||
VW NULL 26.000
|
||||
NULL Beetle 7.000
|
||||
NULL Corolla 13.000
|
||||
NULL Golf 13.000
|
||||
NULL Passat 6.000
|
||||
NULL NULL 44.000
|
||||
|
||||
|
||||
statement ok
|
||||
CREATE MACRO car_pool_rollup(g1, g2, hcnt:=1) AS
|
||||
TABLE SELECT g1, g2, sum(counter) AS cnt FROM car_pool
|
||||
GROUP BY ROLLUP(g1, g2) HAVING cnt >= hcnt order by g1, g2;
|
||||
|
||||
|
||||
query III
|
||||
SELECT * FROM car_pool_rollup(model, yyyy, hcnt:=4);
|
||||
----
|
||||
NULL NULL 44.000
|
||||
Beetle NULL 7.000
|
||||
Beetle 2008.000 4.000
|
||||
Corolla NULL 13.000
|
||||
Corolla 2005.000 4.000
|
||||
Corolla 2008.000 4.000
|
||||
Golf NULL 13.000
|
||||
Golf 2005.000 5.000
|
||||
Passat NULL 6.000
|
||||
Passat 2005.000 5.000
|
||||
|
||||
|
||||
statement ok
|
||||
CREATE MACRO car_pool_groups(g1, g2, hcnt:=1) AS
|
||||
TABLE SELECT g1, g2, sum(counter) AS cnt FROM car_pool
|
||||
GROUP BY (g1, g2) HAVING cnt >= hcnt order by g1, g2;
|
||||
|
||||
query III
|
||||
SELECT * FROM car_pool_groups(model, yyyy, hcnt:=2);
|
||||
----
|
||||
Beetle 2006.000 2.000
|
||||
Beetle 2008.000 4.000
|
||||
Corolla 2005.000 4.000
|
||||
Corolla 2006.000 3.000
|
||||
Corolla 2007.000 2.000
|
||||
Corolla 2008.000 4.000
|
||||
Golf 2005.000 5.000
|
||||
Golf 2006.000 2.000
|
||||
Golf 2007.000 3.000
|
||||
Golf 2008.000 3.000
|
||||
Passat 2005.000 5.000
|
||||
|
||||
|
||||
|
||||
|
||||
46
external/duckdb/test/sql/catalog/function/test_window_macro.test
vendored
Normal file
46
external/duckdb/test/sql/catalog/function/test_window_macro.test
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# name: test/sql/catalog/function/test_window_macro.test
|
||||
# description: Test macro expansion for window functions
|
||||
# group: [function]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# Windowed aggregate macro
|
||||
statement ok
|
||||
CREATE OR REPLACE MACRO my_agg(x) AS SUM(CASE WHEN x THEN 1 END);
|
||||
|
||||
statement ok
|
||||
select my_agg(range)
|
||||
from range(2);
|
||||
|
||||
statement ok
|
||||
select my_agg(range) OVER ()
|
||||
from range(2);
|
||||
|
||||
# Windowed non-aggregate function macro
|
||||
statement ok
|
||||
CREATE OR REPLACE MACRO my_func(x) AS mod(x, 2);
|
||||
|
||||
statement ok
|
||||
select my_func(range)
|
||||
from range(2);
|
||||
|
||||
statement error
|
||||
select my_func(range) OVER ()
|
||||
from range(2);
|
||||
----
|
||||
mod is not an aggregate function
|
||||
|
||||
# Windowed non-aggregate expression macro
|
||||
statement ok
|
||||
CREATE OR REPLACE MACRO my_case(x) AS (CASE WHEN x THEN 1 END);
|
||||
|
||||
statement ok
|
||||
select my_case(range)
|
||||
from range(2);
|
||||
|
||||
statement error
|
||||
select my_case(range) OVER ()
|
||||
from range(2);
|
||||
----
|
||||
Window function macros must be functions
|
||||
Reference in New Issue
Block a user