should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,42 @@
# name: test/sql/catalog/case_insensitive_alter.test
# description: Test case insensitive alter
# group: [catalog]
statement ok
CREATE TABLE "MyTable"(i integer, "BigColumn" integer);
statement ok
ALTER TABLE MyTable ALTER BIGCOLUMN SET DATA TYPE VARCHAR
statement ok
ALTER TABLE MyTable DROP COLUMN BIGCOLUMN;
statement error
SELECT BIGCOLUMN FROM MyTable
----
statement ok
ALTER TABLE MyTable ADD COLUMN "BIGCOLUMN" VARCHAR;
statement ok
ALTER TABLE MyTable ALTER COLUMN BIGCOLUMN SET DEFAULT 3
statement ok
INSERT INTO MyTable(BIGCOLUMN) VALUES (DEFAULT)
query I
SELECT BIGCOLUMN FROM MyTable
----
3
statement ok
ALTER TABLE MyTable ALTER COLUMN BIGCOLUMN DROP DEFAULT
statement ok
SELECT BIGCOLUMN FROM MyTable
statement ok
ALTER TABLE MyTable RENAME BIGCOLUMN TO "SmallColumn"
statement ok
SELECT SmallColumn FROM MyTable

View File

@@ -0,0 +1,47 @@
# name: test/sql/catalog/case_insensitive_binder.test
# description: Test case insensitive binder
# group: [catalog]
statement ok
CREATE TABLE "MyTable"(i integer);
statement ok
SELECT * FROM mytable;
statement ok
SELECT * FROM MyTable;
statement ok
SELECT * FROM "MyTable";
statement ok
ALTER TABLE MyTable ADD COLUMN j INTEGER;
statement ok
ALTER TABLE MyTable RENAME TO "MyOtherTable"
statement ok
DROP TABLE MyOtherTable;
statement ok
CREATE TABLE "ABC"(i integer);
statement error
CREATE TABLE "AbC"(i integer);
----
statement ok
SELECT * FROM "ABC";
statement ok
SELECT * FROM abc; -- error: which table did I mean?
statement ok
ALTER TABLE abc ADD COLUMN j INTEGER;
statement error
ALTER TABLE "ABC" ADD COLUMN "J" INTEGER;
----
statement ok
DROP TABLE abc

View File

@@ -0,0 +1,24 @@
# name: test/sql/catalog/case_insensitive_caps.test
# description: Test case insensitivity with quoted values
# group: [catalog]
# we create a table in lowercase names
statement ok
CREATE TABLE mytable(mycolumn INTEGER, myothercolumn INTEGER);
# we can query the column using quoted text
statement ok
SELECT "MYCOLUMN" FROM "MYTABLE";
# we can also alter in this manner
statement ok
ALTER TABLE "MYTABLE" DROP COLUMN "MYCOLUMN";
statement ok
ALTER TABLE "MYTABLE" ADD COLUMN mycolumn INTEGER;
statement ok
ALTER TABLE "MYTABLE" ALTER COLUMN "MYCOLUMN" SET DEFAULT 3
statement ok
DROP TABLE "MYTABLE"

View File

@@ -0,0 +1,18 @@
# name: test/sql/catalog/case_insensitive_cte.test
# description: Test case insensitive CTE
# group: [catalog]
statement ok
PRAGMA enable_verification
query I
with cte AS (SELECT 42 "A")
select a from cte
----
42
query I
with "CTE" AS (SELECT 42)
select * from cte
----
42

View File

@@ -0,0 +1,150 @@
# name: test/sql/catalog/case_insensitive_operations.test
# description: Test case insensitive operations
# group: [catalog]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
loop i 0 2
statement ok
CREATE TABLE INTEGERS(I INTEGER);
statement ok
INSERT INTO integers (i) VALUES (1), (2), (3), (NULL);
query I
SELECT integers.i FROM integers ORDER BY i;
----
NULL
1
2
3
query I
SELECT integers.i AS i FROM integers GROUP BY I ORDER BY "integers"."I";
----
NULL
1
2
3
query I
SELECT integers.i AS "ZZZ" FROM integers GROUP BY "zzz" ORDER BY "INTEGERS"."i";
----
NULL
1
2
3
query I
WITH "CTE"("ZZZ") AS (
SELECT integers.i AS "ZZZ" FROM integers GROUP BY "zzz"
)
SELECT * FROM cte ORDER BY zZz;
----
NULL
1
2
3
statement error
WITH "CTE"("ZZZ") AS (
SELECT integers.i AS "ZZZ" FROM integers GROUP BY "zzz"
),
"cte" AS (SELECT 42)
----
query I
UPDATE integers SET i=integers.i+1
----
4
query I
SELECT i FROM integers ORDER BY integers.i;
----
NULL
2
3
4
query I
DELETE FROM integers WHERE i IS NULL;
----
1
query I
SELECT i FROM integers ORDER BY integers.i;
----
2
3
4
statement ok
ALTER TABLE integers ADD COLUMN J INTEGER;
query II
SELECT i, j FROM integers ORDER BY integers.i;
----
2 NULL
3 NULL
4 NULL
query I
UPDATE integers SET j=integers.i;
----
3
statement ok
ALTER TABLE integers DROP COLUMN i;
query I
SELECT j FROM integers ORDER BY integers.j;
----
2
3
4
query I
SELECT tbl.k FROM (SELECT j FROM integers) TBL(K) ORDER BY K;
----
2
3
4
statement ok
DROP TABLE integers;
# structs
statement ok
CREATE TABLE STRUCTS(S ROW(I ROW(K INTEGER)));
statement ok
INSERT INTO structs VALUES ({'i': {'k': 42}});
query III
SELECT structs.S.i.K, "STRUCTS"."S"."I"."K", "structs"."s"."i"."k" FROM structs
----
42 42 42
query I
SELECT "STRUCTS"."S"."I"."K" FROM structs GROUP BY "STRUCTS"."S"."I"."K"
----
42
query I
SELECT structs.S.i.K FROM structs GROUP BY structs.S.i.K
----
42
statement ok
DROP TABLE structs;
statement ok
PRAGMA preserve_identifier_case=false;
endloop

View File

@@ -0,0 +1,205 @@
# name: test/sql/catalog/case_insensitive_using.test
# description: Test case insensitivity in USING clauses and NATURAL joins
# group: [catalog]
statement ok
create table A as select 1 as "X", 2 as "Y";
statement ok
create table B as select 1 as "X", 3 as "Z";
query III
select * from A join B using(X);
----
1 2 3
query III
select * from A join B using("X");
----
1 2 3
# case mismatch in using clause
statement ok
DROP TABLE "A"
statement ok
DROP TABLE "B"
statement ok
create table A as select 1 as "X", 2 as "Y";
statement ok
create table B as select 1 as X, 3 as "Z";
query III
select * from A join B using(X);
----
1 2 3
query III
select * from A join B using(X);
----
1 2 3
# using clause with many different case variations on the same name
statement ok
DROP TABLE "A"
statement ok
DROP TABLE "B"
statement ok
create table A as select 1 as "hello", 2 as x;
statement ok
create table B as select 1 as "HELLO", 3 as x2;
statement ok
create table C as select 1 as "hEllO", 4 as x3;
statement ok
create table D as select 1 as "HElLo", 5 as x4;
statement ok
create table E as select 1 as "heLLo", 6 as x5;
query III
SELECT * FROM a JOIN b USING (hello)
----
1 2 3
query III
SELECT * FROM a JOIN b USING (hello, "HELLO");
----
1 2 3
query IIII
SELECT * FROM a JOIN b USING (hello) JOIN c USING (hello)
----
1 2 3 4
query IIII
SELECT * FROM a JOIN b USING (hello) JOIN c USING ("HELLO")
----
1 2 3 4
query IIIII
SELECT * FROM a JOIN b USING (hello) JOIN c USING (hello) JOIN d USING (hello)
----
1 2 3 4 5
query IIIII
SELECT * FROM a JOIN b USING ("HELLO") JOIN c USING ("HeLLo") JOIN d USING (hello)
----
1 2 3 4 5
# full outer join
query IIIIII
SELECT * FROM a JOIN b USING (hello) JOIN c USING (hello) JOIN d USING (hello) JOIN e USING (hello)
----
1 2 3 4 5 6
query III
SELECT * FROM a FULL OUTER JOIN b USING (hello)
----
1 2 3
query IIII
SELECT * FROM a FULL OUTER JOIN b USING (hello) FULL OUTER JOIN c USING (hello)
----
1 2 3 4
query IIIII
SELECT * FROM a FULL OUTER JOIN b USING (hello) FULL OUTER JOIN c USING (hello) FULL OUTER JOIN d USING (hello)
----
1 2 3 4 5
query IIIIII
SELECT * FROM a FULL OUTER JOIN b USING (hello) FULL OUTER JOIN c USING (hello) FULL OUTER JOIN d USING (hello) FULL OUTER JOIN e USING (hello)
----
1 2 3 4 5 6
# natural join
query III
SELECT * FROM a NATURAL JOIN b
----
1 2 3
query IIII
SELECT * FROM a NATURAL JOIN b NATURAL JOIN c
----
1 2 3 4
query IIIII
SELECT * FROM a NATURAL JOIN b NATURAL JOIN c NATURAL JOIN d
----
1 2 3 4 5
query IIIIII
SELECT * FROM a NATURAL JOIN b NATURAL JOIN c NATURAL JOIN d NATURAL JOIN e
----
1 2 3 4 5 6
query IIIIII
SELECT * FROM (a NATURAL JOIN b NATURAL JOIN c) NATURAL JOIN (d NATURAL JOIN e)
----
1 2 3 4 5 6
# natural full outer join
query III
SELECT * FROM a NATURAL FULL OUTER JOIN b
----
1 2 3
query IIII
SELECT * FROM a NATURAL FULL OUTER JOIN b NATURAL FULL OUTER JOIN c
----
1 2 3 4
query IIIII
SELECT * FROM a NATURAL FULL OUTER JOIN b NATURAL FULL OUTER JOIN c NATURAL FULL OUTER JOIN d
----
1 2 3 4 5
query IIIIII
SELECT * FROM a NATURAL FULL OUTER JOIN b NATURAL FULL OUTER JOIN c NATURAL FULL OUTER JOIN d NATURAL FULL OUTER JOIN e
----
1 2 3 4 5 6
query IIIIII
SELECT * FROM (a NATURAL FULL OUTER JOIN b NATURAL FULL OUTER JOIN c) NATURAL FULL OUTER JOIN (d NATURAL FULL OUTER JOIN e)
----
1 2 3 4 5 6
# natural join with ambiguity
query II
SELECT * FROM (SELECT 1 "hello", 2 "hello") NATURAL JOIN (SELECT 1 "hello", 2 "hello")
----
1 2
query II
SELECT * FROM (SELECT 1 "hello", 2 "HeLlO") NATURAL JOIN (SELECT 1 "hello", 2 "HeLlO")
----
1 2
query IIII
SELECT * FROM (SELECT 1 "hello", 2 "hello") t1, (SELECT 1 "hello", 2 "hello") t2
----
1 2 1 2
# using join with ambiguity
query III
SELECT * FROM (SELECT 1 "hello", 2 "hello") t1 JOIN (SELECT 1 "hello", 2 "hello") t2 USING (hello);
----
1 2 2
query III
SELECT * FROM (SELECT 1 "hello", 2 "HeLlO") t1 JOIN (SELECT 1 "hello", 2 "HeLlO") t2 USING (hello);
----
1 2 2
# ambiguous using column reference
statement error
SELECT hello FROM (a JOIN b USING (hello)), (d JOIN e USING (hello))
----
<REGEX>:.*Binder Error: Ambiguous column reference.*

View File

@@ -0,0 +1,391 @@
# name: test/sql/catalog/comment_on.test
# description: Test COMMENT ON to add comments to various catalog entries
# group: [catalog]
load __TEST_DIR__/comment_on.db
### Generic tests
# String literal or NULL only
statement error
COMMENT ON TABLE test IS 1337
----
Parser Error: syntax error
# Catalog entry not found is error
statement error
COMMENT ON TABLE hahahoehoe IS 'blablabloebloe'
----
Catalog Error: Table with name hahahoehoe does not exist!
statement error
COMMENT ON FUNCTION add IS 'foobar'
----
Can not comment on System Catalog entries
### Comment on Tables
statement ok
CREATE TABLE test_table as SELECT 1 as test_table_column
query I
select comment from duckdb_tables() where table_name='test_table';
----
NULL
statement ok
COMMENT ON TABLE test_table IS 'very gezellige table'
query I
select comment from duckdb_tables() where table_name='test_table';
----
very gezellige table
# Apply a set of alters to the table to ensure it is not corrupted
statement ok
ALTER TABLE test_table ADD COLUMN new_col INTEGER
statement ok
ALTER TABLE test_table ALTER new_col SET DATA TYPE TINYINT
statement ok
ALTER TABLE test_table ALTER new_col SET DATA TYPE TINYINT
statement ok
ALTER TABLE test_table ALTER COLUMN new_col SET DEFAULT 1
statement ok
ALTER TABLE test_table ALTER COLUMN new_col DROP DEFAULT
statement ok
ALTER TABLE test_table ALTER new_col SET DATA TYPE TINYINT
statement ok
ALTER TABLE test_table RENAME COLUMN new_col TO new_col_2
statement ok
ALTER TABLE test_table DROP COLUMN new_col_2
statement ok
ALTER TABLE test_table RENAME TO test_table_2
statement ok
ALTER TABLE test_table_2 RENAME TO test_table
restart
query I
select comment from duckdb_tables() where table_name='test_table';
----
very gezellige table
# Reverting to null goes like dis
statement ok
COMMENT ON TABLE test_table IS NULL
query I
select comment from duckdb_tables() where table_name='test_table';
----
NULL
# Check table is still functioning
query I
SELECT * FROM test_table
----
1
### Comment on view
statement ok
CREATE VIEW test_view as SELECT 1 as test_view_column
query I
select comment from duckdb_views() where view_name='test_view';
----
NULL
statement ok
COMMENT ON VIEW test_view IS 'very gezellige view'
query I
select comment from duckdb_views() where view_name='test_view';
----
very gezellige view
statement ok
ALTER VIEW test_view RENAME TO test_view_2
statement ok
ALTER VIEW test_view_2 RENAME TO test_view
restart
query I
select comment from duckdb_views() where view_name='test_view';
----
very gezellige view
# Check view is still functioning
query I
SELECT * FROM test_view
----
1
### Comment on view column
query I
select comment from duckdb_columns() where column_name='test_view_column';
----
NULL
statement ok
COMMENT ON COLUMN test_view.test_view_column IS 'very gezellige viewcolumn'
query I
select comment from duckdb_columns() where column_name='test_view_column';
----
very gezellige viewcolumn
restart
query I
select comment from duckdb_columns() where column_name='test_view_column';
----
very gezellige viewcolumn
statement ok
DROP VIEW test_view
### Comment on indices
statement ok
CREATE INDEX test_index ON test_table using art(test_table_column)
query I
select comment from duckdb_indexes() where index_name='test_index';
----
NULL
statement ok
COMMENT ON INDEX test_index IS 'very gezellige index'
query I
select comment from duckdb_indexes() where index_name='test_index';
----
very gezellige index
restart
query I
select comment from duckdb_indexes() where index_name='test_index';
----
very gezellige index
# Check index is still functioning
query I
SELECT * FROM test_table WHERE test_table_column=1
----
1
statement ok
DROP INDEX test_index;
### Comment on sequences
statement ok
CREATE SEQUENCE test_sequence;
query I
select comment from duckdb_sequences() where sequence_name='test_sequence';
----
NULL
statement ok
COMMENT ON SEQUENCE test_sequence IS 'very gezellige sequence'
query I
select comment from duckdb_sequences() where sequence_name='test_sequence';
----
very gezellige sequence
restart
query I
select comment from duckdb_sequences() where sequence_name='test_sequence';
----
very gezellige sequence
# Check sequence is still functioning
query I
SELECT nextval('test_sequence')
----
1
statement ok
DROP SEQUENCE test_sequence
### Comment on types
statement ok
CREATE TYPE test_type AS int32;
query I
select comment from duckdb_types() where type_name='test_type';
----
NULL
statement ok
COMMENT ON TYPE test_type IS 'very gezellige type'
query I
select comment from duckdb_types() where type_name='test_type';
----
very gezellige type
restart
query I
select comment from duckdb_types() where type_name='test_type';
----
very gezellige type
# Check type is still functioning
query I
SELECT 1::test_type as val;
----
1
statement ok
DROP TYPE test_type
### Comment on table column
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
NULL
statement ok
COMMENT ON COLUMN test_table.test_table_column IS 'very gezellige column'
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
very gezellige column
restart
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
very gezellige column
# Comment persists rename
statement ok
ALTER TABLE test_table RENAME COLUMN test_table_column TO test_table_column_renamed
query I
select comment from duckdb_columns() where column_name='test_table_column_renamed';
----
very gezellige column
### Comment on Macro
statement ok
CREATE MACRO test_macro(a, b) AS a + b
query I
select comment from duckdb_functions() where function_name='test_macro';
----
NULL
statement ok
COMMENT ON MACRO test_macro IS 'very gezellige macro'
query I
select comment from duckdb_functions() where function_name='test_macro';
----
very gezellige macro
restart
query I
select comment from duckdb_functions() where function_name='test_macro';
----
very gezellige macro
# Check macro is still functioning
query I
SELECT test_macro(1,2);
----
3
statement ok
DROP MACRO test_macro
### Comment on function (alias for scalar macro)
statement ok
CREATE FUNCTION test_function(a, b) AS a + b
query I
select comment from duckdb_functions() where function_name='test_function';
----
NULL
statement ok
COMMENT ON FUNCTION test_function IS 'very gezellige function'
query I
select comment from duckdb_functions() where function_name='test_function';
----
very gezellige function
restart
query I
select comment from duckdb_functions() where function_name='test_function';
----
very gezellige function
### Comment on TABLE MACRO
statement ok
CREATE MACRO test_table_macro(a,b) as TABLE select a,b;
query I
select comment from duckdb_functions() where function_name='test_table_macro';
----
NULL
statement ok
COMMENT ON MACRO TABLE test_table_macro IS 'very gezellige table macro'
query I
select comment from duckdb_functions() where function_name='test_table_macro';
----
very gezellige table macro
restart
query I
select comment from duckdb_functions() where function_name='test_table_macro';
----
very gezellige table macro
# Check table macro is still functioning
query II
from test_table_macro(1,2);
----
1 2
statement ok
DROP MACRO TABLE test_table_macro
### Comment on DATABASE
statement error
COMMENT ON DATABASE blabla IS 'bloebloe'
----
Not implemented Error: Adding comments to databases is not implemented
### Comment on schemas
statement error
COMMENT ON SCHEMA blabla IS 'bloebloe'
----
Not implemented Error: Adding comments to schemas is not implemented
statement ok
DROP TABLE test_table

View File

@@ -0,0 +1,80 @@
# name: test/sql/catalog/comment_on_column.test
# description: Test COMMENT ON COLUMN
# group: [catalog]
load __TEST_DIR__/comment_on_column.db
statement ok
CREATE TABLE test_table as SELECT 1 as test_table_column
### Comment on column from table
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
NULL
statement ok
COMMENT ON COLUMN test_table.test_table_column IS 'very gezellige column'
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
very gezellige column
restart
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
very gezellige column
statement ok
CREATE VIEW test_view AS SELECT test_table_column as test_view_column FROM test_table;
### Comment on column from table
query I
select comment from duckdb_columns() where column_name='test_view_column';
----
NULL
statement ok
COMMENT ON COLUMN test_view.test_view_column IS 'very gezellige view column'
query I
select comment from duckdb_columns() where column_name='test_view_column';
----
very gezellige view column
restart
query I
select comment from duckdb_columns() where column_name='test_view_column';
----
very gezellige view column
query IIII
SELECT database_name, table_name, column_name, comment FROM duckdb_columns() where internal is false
----
comment_on_column test_table test_table_column very gezellige column
comment_on_column test_view test_view_column very gezellige view column
# check some erroneous inputs
statement error
COMMENT ON COLUMN bla.bloe.blie.blo IS NULL
----
Catalog "bla" does not exist!
statement error
COMMENT ON COLUMN blie.blo IS NULL
----
Table with name blie does not exist!
statement error
COMMENT ON COLUMN test_view.test_table_column IS NULL
----
View "test_view" does not have a column with name "test_table_column"
statement error
COMMENT ON COLUMN test_table.test_view_column IS NULL
----
Table "test_table" does not have a column with name "test_view_column"

View File

@@ -0,0 +1,57 @@
# name: test/sql/catalog/comment_on_dependencies.test
# description: Test COMMENT ON a catalog entry with dependencies
# group: [catalog]
### Create some test data
statement ok
CREATE TABLE t1 AS SELECT 1 as c1
statement ok
CREATE INDEX test_index ON t1 using art(c1)
statement ok
COMMENT ON TABLE t1 IS 'very niceee'
# Create a table
statement ok
CREATE TABLE a (i INTEGER)
# Create a view that depends on the table
statement ok
CREATE VIEW b AS SELECT i::STRING AS j FROM a
# Comment on the table
statement ok
COMMENT ON TABLE a IS 'a table'
# Comment on the table's column
statement ok
COMMENT ON COLUMN a.i IS 'a column'
# Comment on the view
statement ok
COMMENT ON VIEW b IS 'a view'
# Comment on the view's column
statement ok
COMMENT ON COLUMN b.j IS 'a column'
query I
select comment from duckdb_columns() where column_name='i';
----
a column
query I
select comment from duckdb_tables() where table_name='a';
----
a table
query I
select comment from duckdb_views() where view_name='b';
----
a view
query I
select comment from duckdb_columns() where column_name='j';
----
a column

View File

@@ -0,0 +1,156 @@
# name: test/sql/catalog/comment_on_extended.test
# description: Test COMMENT ON to add comment on database
# group: [catalog]
### Create some test data
statement ok
ATTACH '__TEST_DIR__/comment_on_extended_1.db' AS db1
statement ok
ATTACH '__TEST_DIR__/comment_on_extended_2.db' AS db2
statement ok
CREATE SCHEMA db1.s1;
statement ok
CREATE SCHEMA db2.s2;
statement ok
CREATE TABLE db1.s1.t1 AS SELECT 1 as c1
statement ok
CREATE TABLE db2.s2.t2 AS SELECT 2 as c2
# some extra tables to index on (since we can not comment on tables with dependencies)
statement ok
CREATE TABLE db1.s1.t3 AS SELECT 3 as c3
statement ok
CREATE TABLE db2.s2.t4 AS SELECT 4 as c4
statement ok
CREATE INDEX test_index ON db1.s1.t3 using art(c3)
statement ok
CREATE INDEX test_index ON db2.s2.t4 using art(c4)
### Confirm we have no comments yet
query I
SELECT count(*) from duckdb_tables() where comment IS NOT NULL;
----
0
query I
SELECT count(*) from duckdb_columns() where comment IS NOT NULL;
----
0
### Tables with fully qualified names
statement ok
COMMENT ON TABLE db1.s1.t1 IS 'very gezellige table 1'
query I
select comment from duckdb_tables() where table_name='t1';
----
very gezellige table 1
# just table
statement ok
USE db2.s2
statement ok
COMMENT ON TABLE t2 IS 'very gezellige table 2'
query I
select comment from duckdb_tables() where table_name='t2';
----
very gezellige table 2
# db.table
statement ok
COMMENT ON TABLE db2.t2 IS 'another very gezellige table 2'
query I
select comment from duckdb_tables() where table_name='t2';
----
another very gezellige table 2
# schema.table
statement ok
COMMENT ON TABLE s2.t2 IS 'yet another very gezellige table 2'
query I
select comment from duckdb_tables() where table_name='t2';
----
yet another very gezellige table 2
### Index with fully qualified name
statement ok
COMMENT ON INDEX db1.s1.test_index IS 'very gezellige index 1'
query I
select comment from duckdb_indexes() where index_name='test_index' and database_name='db1';
----
very gezellige index 1
# db.index
statement ok
COMMENT ON INDEX db2.test_index IS 'very gezellige index 2'
query III
select database_name, schema_name, comment from duckdb_indexes() where index_name='test_index' order by comment;
----
db1 s1 very gezellige index 1
db2 s2 very gezellige index 2
### Fully qualified column
statement error
COMMENT ON COLUMN col1 IS 'no bueno'
----
Parser Error: Invalid column reference: 'col1'
statement error
COMMENT ON COLUMN galaxy.db.schema.table.col1 IS 'no bueno'
----
Parser Error: Invalid column reference: 'galaxy.db."schema"."table".col1', too many dots
statement error
COMMENT ON COLUMN table_blablabla.col1 IS 'bla'
----
Catalog Error: Table with name table_blablabla does not exist!
statement ok
COMMENT ON COLUMN db1.s1.t1.c1 IS 'very gezellige column 1'
query IIII
select database_name, schema_name, table_name, comment from duckdb_columns() where column_name='c1' order by comment;
----
db1 s1 t1 very gezellige column 1
# Using db.tbl.col
statement ok
COMMENT ON COLUMN db2.t2.c2 IS 'very gezellige column 2'
query IIII
select database_name, schema_name, table_name, comment from duckdb_columns() where column_name='c2' order by comment;
----
db2 s2 t2 very gezellige column 2
# Using schema.tbl.col
statement ok
COMMENT ON COLUMN s2.t2.c2 IS 'another very gezellige column 2'
query IIII
select database_name, schema_name, table_name, comment from duckdb_columns() where column_name='c2' order by comment;
----
db2 s2 t2 another very gezellige column 2
# Using tbl.col
statement ok
COMMENT ON COLUMN t2.c2 IS 'yet another very gezellige column 2'
query IIII
select database_name, schema_name, table_name, comment from duckdb_columns() where column_name='c2' order by comment;
----
db2 s2 t2 yet another very gezellige column 2

View File

@@ -0,0 +1,133 @@
# name: test/sql/catalog/comment_on_pg_description.test
# description: Test the pg_description function for comment on
# group: [catalog]
statement ok
CREATE TABLE test AS SELECT 1 as a;
statement ok
COMMENT ON TABLE test IS 'comment-1'
statement ok
COMMENT ON COLUMN test.a IS 'comment-2'
statement ok
CREATE VIEW test_view AS FROM test;
statement ok
COMMENT ON COLUMN test_view.a IS 'comment-2.5'
statement ok
CREATE INDEX test_index ON test(a)
statement ok
COMMENT ON VIEW test_view IS 'comment-3'
statement ok
COMMENT ON INDEX test_index IS 'comment-4'
statement ok
CREATE SEQUENCE seq
statement ok
COMMENT ON SEQUENCE seq IS 'comment-5'
statement ok
CREATE TYPE test_type AS int32;
statement ok
COMMENT ON TYPE test_type IS 'comment-6'
statement ok
CREATE MACRO test_table_macro(a,b) as TABLE select a,b;
statement ok
CREATE FUNCTION test_function(a, b) AS a + b
statement ok
COMMENT ON MACRO TABLE test_table_macro IS 'comment-7'
statement ok
COMMENT ON MACRO test_function IS 'comment-8'
# Confirm that pg_description matches
query II
SELECT ddb.comment, pg.description
FROM duckdb_tables AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.table_oid
WHERE pg.objsubid=0 AND ddb.table_name='test'
----
comment-1 comment-1
query II
SELECT ddb.comment, pg.description
FROM duckdb_columns AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.table_oid
WHERE pg.objsubid=1 AND ddb.table_name='test'
----
comment-2 comment-2
query II
SELECT ddb.comment, pg.description
FROM duckdb_columns AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.table_oid
WHERE pg.objsubid=1 AND ddb.table_name='test_view'
----
comment-2.5 comment-2.5
query II
SELECT ddb.comment, pg.description
FROM duckdb_views AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.view_oid
WHERE pg.objsubid=0 AND ddb.view_name='test_view'
----
comment-3 comment-3
query II
SELECT ddb.comment, pg.description
FROM duckdb_indexes AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.index_oid
WHERE ddb.index_name='test_index'
----
comment-4 comment-4
query II
SELECT ddb.comment, pg.description
FROM duckdb_sequences() AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.sequence_oid
WHERE ddb.sequence_name='seq'
----
comment-5 comment-5
query II
SELECT ddb.comment, pg.description
FROM duckdb_types() AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.type_oid
WHERE ddb.type_name='test_type'
----
comment-6 comment-6
query II
SELECT ddb.comment, pg.description
FROM duckdb_functions() AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.function_oid
WHERE ddb.function_name='test_table_macro'
----
comment-7 comment-7
query II
SELECT ddb.comment, pg.description
FROM duckdb_functions() AS ddb
LEFT JOIN pg_description AS pg
ON pg.classoid=ddb.database_oid AND pg.objoid=ddb.function_oid
WHERE ddb.function_name='test_function'
----
comment-8 comment-8

View File

@@ -0,0 +1,335 @@
# name: test/sql/catalog/comment_on_wal.test
# description: Test COMMENT ON to add comments to various catalog entries
# group: [catalog]
load __TEST_DIR__/comment_on_wal.db
statement ok
SET checkpoint_threshold = '10.0 GB';
statement ok
PRAGMA disable_checkpoint_on_shutdown
### Generic tests
# TODO: we need further testing of comments not being modified as catalog entries are altered
# String literal or NULL only
statement error
COMMENT ON TABLE test IS 1337
----
Parser Error: syntax error
# Catalog entry not found is error
statement error
COMMENT ON TABLE hahahoehoe IS 'blablabloebloe'
----
Catalog Error: Table with name hahahoehoe does not exist!
### Comment on Tables
statement ok
CREATE TABLE test_table as SELECT 1 as test_table_column
query I
select comment from duckdb_tables() where table_name='test_table';
----
NULL
statement ok
COMMENT ON TABLE test_table IS 'very gezellige table'
query I
select comment from duckdb_tables() where table_name='test_table';
----
very gezellige table
restart
query I
select comment from duckdb_tables() where table_name='test_table';
----
very gezellige table
# Reverting to null goes like dis
statement ok
COMMENT ON TABLE test_table IS NULL
query I
select comment from duckdb_tables() where table_name='test_table';
----
NULL
# Check table is still functioning
query I
SELECT * FROM test_table
----
1
### Comment on view
statement ok
CREATE VIEW test_view as SELECT 1 as test_view_column
query I
select comment from duckdb_views() where view_name='test_view';
----
NULL
statement ok
COMMENT ON VIEW test_view IS 'very gezellige view'
query I
select comment from duckdb_views() where view_name='test_view';
----
very gezellige view
restart
query I
select comment from duckdb_views() where view_name='test_view';
----
very gezellige view
# Check view is still functioning
query I
SELECT * FROM test_view
----
1
statement ok
DROP VIEW test_view
### Comment on indices
statement ok
CREATE INDEX test_index ON test_table using art(test_table_column)
query I
select comment from duckdb_indexes() where index_name='test_index';
----
NULL
statement ok
COMMENT ON INDEX test_index IS 'very gezellige index'
query I
select comment from duckdb_indexes() where index_name='test_index';
----
very gezellige index
restart
query I
select comment from duckdb_indexes() where index_name='test_index';
----
very gezellige index
# Check index is still functioning
query I
SELECT * FROM test_table WHERE test_table_column=1
----
1
statement ok
DROP INDEX test_index;
### Comment on sequences
statement ok
CREATE SEQUENCE test_sequence;
query I
select comment from duckdb_sequences() where sequence_name='test_sequence';
----
NULL
statement ok
COMMENT ON SEQUENCE test_sequence IS 'very gezellige sequence'
query I
select comment from duckdb_sequences() where sequence_name='test_sequence';
----
very gezellige sequence
restart
query I
select comment from duckdb_sequences() where sequence_name='test_sequence';
----
very gezellige sequence
# Check sequence is still functioning
query I
SELECT nextval('test_sequence')
----
1
statement ok
DROP SEQUENCE test_sequence
### Comment on types
statement ok
CREATE TYPE test_type AS int32;
query I
select comment from duckdb_types() where type_name='test_type';
----
NULL
statement ok
COMMENT ON TYPE test_type IS 'very gezellige type'
query I
select comment from duckdb_types() where type_name='test_type';
----
very gezellige type
restart
query I
select comment from duckdb_types() where type_name='test_type';
----
very gezellige type
# Check type is still functioning
query I
SELECT 1::test_type as val;
----
1
statement ok
DROP TYPE test_type
### Comment on column
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
NULL
statement ok
COMMENT ON COLUMN test_table.test_table_column IS 'very gezellige column'
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
very gezellige column
restart
query I
select comment from duckdb_columns() where column_name='test_table_column';
----
very gezellige column
# Comment persists rename
statement ok
ALTER TABLE test_table RENAME COLUMN test_table_column TO test_table_column_renamed
query I
select comment from duckdb_columns() where column_name='test_table_column_renamed';
----
very gezellige column
### Comment on Macro
statement ok
CREATE MACRO test_macro(a, b) AS a + b
query I
select comment from duckdb_functions() where function_name='test_macro';
----
NULL
statement ok
COMMENT ON MACRO test_macro IS 'very gezellige macro'
query I
select comment from duckdb_functions() where function_name='test_macro';
----
very gezellige macro
restart
query I
select comment from duckdb_functions() where function_name='test_macro';
----
very gezellige macro
# Check macro is still functioning
query I
SELECT test_macro(1,2);
----
3
statement ok
DROP MACRO test_macro
### Comment on function (alias for scalar macro)
statement ok
CREATE FUNCTION test_function(a, b) AS a + b
query I
select comment from duckdb_functions() where function_name='test_function';
----
NULL
statement ok
COMMENT ON FUNCTION test_function IS 'very gezellige function'
query I
select comment from duckdb_functions() where function_name='test_function';
----
very gezellige function
restart
query I
select comment from duckdb_functions() where function_name='test_function';
----
very gezellige function
### Comment on TABLE MACRO
statement ok
CREATE MACRO test_table_macro(a,b) as TABLE select a,b;
query I
select comment from duckdb_functions() where function_name='test_table_macro';
----
NULL
statement ok
COMMENT ON MACRO TABLE test_table_macro IS 'very gezellige table macro'
query I
select comment from duckdb_functions() where function_name='test_table_macro';
----
very gezellige table macro
restart
query I
select comment from duckdb_functions() where function_name='test_table_macro';
----
very gezellige table macro
# Check table macro is still functioning
query II
from test_table_macro(1,2);
----
1 2
statement ok
DROP MACRO TABLE test_table_macro
### Comment on DATABASE
statement error
COMMENT ON DATABASE blabla IS 'bloebloe'
----
Not implemented Error: Adding comments to databases is not implemented
### Comment on schemas
statement error
COMMENT ON SCHEMA blabla IS 'bloebloe'
----
Not implemented Error: Adding comments to schemas is not implemented
statement ok
DROP TABLE test_table

View File

@@ -0,0 +1,33 @@
# name: test/sql/catalog/dependencies/add_column_to_table_referenced_by_fk.test
# group: [dependencies]
statement ok
pragma enable_verification;
statement ok
create table tbl(a varchar primary key);
statement ok
create table tbl2(
a varchar,
foreign key (a) references tbl(a)
)
statement ok
insert into tbl values('abc');
statement ok
insert into tbl2 values ('abc');
statement ok
alter table tbl add column b integer default 5;
query II
select * from tbl;
----
abc 5
query I
select * from tbl2;
----
abc

View File

@@ -0,0 +1,27 @@
# name: test/sql/catalog/dependencies/add_column_to_table_referenced_by_macro.test
# group: [dependencies]
statement ok
pragma enable_verification;
statement ok
create table tbl(a varchar default 'abc');
statement ok
insert into tbl values(DEFAULT);
statement ok
create macro mcr() as table select * from tbl;
query I
select * from mcr();
----
abc
statement ok
alter table tbl add column b integer default 5;
query II
select * from mcr();
----
abc 5

View File

@@ -0,0 +1,27 @@
# name: test/sql/catalog/dependencies/add_column_to_table_referenced_by_view.test
# group: [dependencies]
statement ok
pragma enable_verification;
statement ok
create table tbl(a varchar default 'abc');
statement ok
insert into tbl values(DEFAULT);
statement ok
create view vw as select * from tbl;
query I
select * from vw;
----
abc
statement ok
alter table tbl add column b integer default 5;
statement error
select * from vw;
----
Contents of view were altered: types don't match! Expected [VARCHAR], but found [VARCHAR, INTEGER] instead

View File

@@ -0,0 +1,16 @@
# name: test/sql/catalog/dependencies/change_type_of_table_column_referenced_by_index.test
# group: [dependencies]
statement ok
pragma enable_verification;
statement ok
create table tbl(a varchar, b integer);
statement ok
create index idx on tbl(a);
statement error
alter table tbl alter a set type integer;
----
Catalog Error: Cannot change the type of this column: an index depends on it!

View File

@@ -0,0 +1,16 @@
# name: test/sql/catalog/dependencies/remove_table_column_referenced_by_index.test
# group: [dependencies]
statement ok
pragma enable_verification;
statement ok
create table tbl(a varchar, b integer);
statement ok
create index idx on tbl(a);
statement error
alter table tbl drop column a;
----
Catalog Error: Cannot drop this column: an index depends on it!

View File

@@ -0,0 +1,16 @@
# name: test/sql/catalog/dependencies/rename_table_column_referenced_by_index.test
# group: [dependencies]
statement ok
pragma enable_verification;
statement ok
create table tbl(a varchar);
statement ok
create index idx on tbl(a);
statement error
alter table tbl rename a to b;
----
Cannot alter entry "tbl" because there are entries that depend on it.

View File

@@ -0,0 +1,27 @@
# name: test/sql/catalog/dependencies/rename_view_referenced_by_table_macro.test
# group: [dependencies]
statement ok
pragma enable_verification;
# Create a table so our view has something to reference
statement ok
create table tbl (a varchar);
# Create the view
statement ok
create view vw as select * from tbl;
# Create a table macro that references the view
statement ok
create macro static_table() as table select * from vw;
# Rename the view (Postgres 16.0 does not block this ALTER)
statement ok
alter view vw rename to vw2;
# Our table macro now errors
statement error
select * from static_table();
----
Catalog Error: Table with name vw does not exist!

View File

@@ -0,0 +1,17 @@
# name: test/sql/catalog/dependencies/set_default_of_table_column_referenced_by_index.test
# group: [dependencies]
statement ok
pragma enable_verification;
statement ok
create table tbl(a varchar, b integer);
statement ok
create index idx on tbl(a);
statement error
alter table tbl alter a set default 'test';
----
Dependency Error: Cannot alter entry "tbl" because there are entries that depend on it.

View File

@@ -0,0 +1,538 @@
# name: test/sql/catalog/dependencies/test_alter_dependency_ownership.test
# description: Tests alter of ownership of sequences
# group: [dependencies]
require skip_reload
##TEST: If the table is dropped, then the sequence is also droppped
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
DROP TABLE tablename;
statement error
SELECT nextval('sequence1');
----
Catalog Error: Sequence with name sequence1 does not exist!
##TEST: If the table is dropped, then the sequence is also droppped, using schemas
statement ok
CREATE SEQUENCE main.sequence1;
statement ok
CREATE TABLE main.tablename (
colname integer
);
statement ok
ALTER SEQUENCE main.sequence1 OWNED BY main.tablename;
statement ok
DROP TABLE main.tablename;
statement error
SELECT nextval('main.sequence1');
----
Catalog Error: Sequence with name sequence1 does not exist!
##TEST: If the owned sequence is dropped with CASCADE, then the table is also dropped
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
DROP SEQUENCE sequence1 CASCADE;
statement error
SELECT * FROM tablename;
----
Catalog Error: Table with name tablename does not exist!
##TEST: The owned sequence cannot be dropped without CASCADE
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
DROP TABLE tablename;
##TEST: If sequence is already owned by other table throw an error
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
CREATE TABLE tablename2 (
colname integer
);
# owned by specified more than once
statement error
ALTER SEQUENCE sequence1 OWNED BY tablename OWNED BY tablename2;
----
Parser Error: Owned by value should be passed as most once
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement error
ALTER SEQUENCE sequence1 OWNED BY tablename2;
----
Dependency Error: sequence1 is already owned by tablename
statement ok
DROP TABLE tablename;
statement ok
DROP TABLE tablename2;
##TEST: If owning the sequence twice shouldn't return any error
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
DROP TABLE tablename;
##TEST: A table can own many sequences, and when the table is dropped, all sequences are also dropped
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE SEQUENCE sequence2;
statement ok
CREATE SEQUENCE sequence3;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
ALTER SEQUENCE sequence2 OWNED BY tablename;
statement ok
ALTER SEQUENCE sequence3 OWNED BY tablename;
statement ok
DROP TABLE tablename;
statement error
SELECT nextval('sequence1');
----
Catalog Error: Sequence with name sequence1 does not exist!
statement error
SELECT nextval('sequence2');
----
Catalog Error: Sequence with name sequence2 does not exist!
statement error
SELECT nextval('sequence3');
----
Catalog Error: Sequence with name sequence3 does not exist!
##TEST: When owning a sequence, insertions work normally
statement ok
CREATE SEQUENCE sequence1;
# sequence 2 will not be owned by tablename
statement ok
CREATE SEQUENCE sequence2;
statement ok
CREATE TABLE tablename (
colname integer DEFAULT nextval('sequence1'),
colname2 integer DEFAULT nextval('sequence2'),
colname3 integer,
colname4 float,
colname5 string
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
INSERT INTO tablename VALUES(default, default, 10, 2.0, 'aaaa');
statement ok
INSERT INTO tablename VALUES(default, default, 20, 3.0, 'bbbb');
query IIIII
SELECT colname, colname2, colname3, colname4, colname5 FROM tablename;
----
1 1 10 2.0 aaaa
2 2 20 3.0 bbbb
statement ok
DROP TABLE tablename;
statement ok
DROP SEQUENCE sequence2;
##TEST: If we change the name of a table that has an owned sequence, the ownership moves to the new table name
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
ALTER TABLE tablename RENAME TO new_tablename;
# Create a new table, with the same name as the old table and try to own the sequence
statement ok
CREATE TABLE tablename (
colname integer
);
statement error
ALTER SEQUENCE sequence1 OWNED BY tablename;
----
sequence1 is already owned by new_tablename
statement error
DROP SEQUENCE sequence1;
----
table "new_tablename" depends on index "sequence1".
statement error
CREATE OR REPLACE SEQUENCE sequence1;
----
table "new_tablename" depends on index "sequence1".
# Owning the sequence with the same table shouldn't return any error
statement ok
ALTER SEQUENCE sequence1 OWNED BY new_tablename;
statement ok
DROP TABLE tablename;
statement ok
DROP TABLE new_tablename;
##TEST: If we add a column to a table that has an owned sequence, the ownership remains
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
ALTER TABLE tablename ADD COLUMN colname2 integer DEFAULT nextval('sequence1')
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
DROP TABLE tablename;
##TEST: If we remove a column to a table that has an owned sequence, the ownership remains
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer,
colname2 integer DEFAULT nextval('sequence1')
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
ALTER TABLE tablename DROP colname2;
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
DROP TABLE tablename;
##TEST: If we alter the type of a column that has the sequence as default value
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer DEFAULT nextval('sequence1')
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
ALTER TABLE tablename ALTER colname TYPE float;
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
DROP TABLE tablename;
###TEST: If we have many columns using the sequence as default and drop one by one, the ownership should remain intact
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer DEFAULT nextval('sequence1'),
colname2 integer DEFAULT nextval('sequence1'),
colname3 integer DEFAULT nextval('sequence1'),
colname4 integer DEFAULT nextval('sequence1')
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
ALTER TABLE tablename DROP colname4;
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
ALTER TABLE tablename DROP colname3;
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
ALTER TABLE tablename DROP colname2;
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
DROP TABLE tablename;
##TEST: If we drop a table which owns a sequence and then roll back, the ownership should remain
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE TABLE tablename (
colname integer DEFAULT nextval('sequence1')
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tablename;
statement ok
BEGIN TRANSACTION;
statement ok
DROP TABLE tablename;
statement error
select nextval('sequence1');
----
Catalog Error: Sequence with name sequence1 does not exist!
statement ok
ROLLBACK;
query I
select nextval('sequence1');
----
1
statement error
DROP SEQUENCE sequence1;
----
table "tablename" depends on index "sequence1".
statement ok
DROP TABLE tablename;
##TEST: View can own a sequence
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE VIEW v1_sequence1(a) AS SELECT 42;
statement ok
ALTER SEQUENCE sequence1 OWNED BY v1_sequence1;
statement error
DROP SEQUENCE sequence1;
----
view "v1_sequence1" depends on index "sequence1".
statement ok
DROP VIEW v1_sequence1;
statement error
SELECT nextval('sequence1');
----
Catalog Error: Sequence with name sequence1 does not exist!
##TEST: Sequence can own a sequence
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE SEQUENCE sequence2;
statement ok
ALTER SEQUENCE sequence1 OWNED BY sequence2;
statement error
DROP SEQUENCE sequence1;
----
index "sequence2" depends on index "sequence1".
statement ok
DROP SEQUENCE sequence2;
statement error
SELECT nextval('sequence1');
----
Catalog Error: Sequence with name sequence1 does not exist!
##TEST: Sequence cant own its owner
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE SEQUENCE sequence2;
statement ok
ALTER SEQUENCE sequence1 OWNED BY sequence2;
statement error
ALTER SEQUENCE sequence2 OWNED BY sequence1;
----
Dependency Error: sequence1 can not become the owner, it is already owned by sequence2
statement ok
DROP SEQUENCE sequence2;
##TEST: Dependency cycle should throw error
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE SEQUENCE sequence2;
statement ok
CREATE SEQUENCE sequence3;
statement ok
CREATE SEQUENCE sequence4;
statement ok
ALTER SEQUENCE sequence2 OWNED BY sequence1;
statement error
ALTER SEQUENCE sequence3 OWNED BY sequence2;
----
Dependency Error: sequence2 can not become the owner, it is already owned by sequence1
# FIXME: this error makes no sense, if there is no circular dependency
# this should be allowed
statement error
ALTER SEQUENCE sequence1 OWNED BY sequence3;
----
Dependency Error: sequence1 already owns sequence2. Cannot have circular dependencies
statement ok
ALTER SEQUENCE sequence3 OWNED BY sequence4;
statement ok
DROP SEQUENCE sequence1;
statement ok
DROP SEQUENCE sequence4;
statement error
SELECT nextval('sequence1');
----
Catalog Error: Sequence with name sequence1 does not exist!
statement error
SELECT nextval('sequence2');
----
Catalog Error: Sequence with name sequence2 does not exist!
statement error
SELECT nextval('sequence3');
----
Catalog Error: Sequence with name sequence3 does not exist!
statement error
SELECT nextval('sequence4');
----
Catalog Error: Sequence with name sequence4 does not exist!

View File

@@ -0,0 +1,55 @@
# name: test/sql/catalog/dependencies/test_alter_owned_by.test
# group: [dependencies]
require skip_reload
statement ok
PRAGMA verify_serializer
##TEST: If the table is dropped, then the sequence is also droppped
statement ok
CREATE SEQUENCE sequence1;
statement ok
CREATE SEQUENCE sequence2;
statement ok
CREATE TABLE tbl1 (
colname integer
);
statement ok
CREATE TABLE tbl2 (
colname integer
);
statement ok
ALTER SEQUENCE sequence1 OWNED BY tbl1;
# sequence1 can not be the owner of an entry, sequence1 is already owned
statement error
ALTER SEQUENCE sequence2 OWNED BY sequence1;
----
<REGEX>:.*Dependency Error.*is already owned.*
# sequence1 is already owned by another entry
statement error
ALTER SEQUENCE sequence1 OWNED BY tbl2;
----
<REGEX>:.*Dependency Error.*is already owned.*
statement ok
create sequence sequence3;
statement error
alter sequence sequence3 owned by sequence1
----
<REGEX>:.*Dependency Error.*is already owned.*
statement ok
DROP TABLE tbl1;
statement error
SELECT nextval('sequence1');
----
<REGEX>:.*Catalog Error.*does not exist.*

View File

@@ -0,0 +1,44 @@
# name: test/sql/catalog/dependencies/test_alter_owning_table.test
# description: Test ALTER of table that owns a sequence
# group: [dependencies]
# FIXME: we don't preserve OWNED BY on restarts
require skip_reload
statement ok
create sequence seq;
statement ok
create sequence other_seq;
statement ok
create table tbl (
a integer default nextval('other_seq')
);
statement ok
alter sequence seq owned by tbl;
statement ok
alter table tbl rename to tbl2;
statement error
drop sequence seq;
----
table "tbl2" depends on index "seq".
statement error
drop sequence other_seq;
----
table "tbl2" depends on index "other_seq".
statement ok
drop table tbl2;
statement error
drop sequence seq;
----
Sequence with name seq does not exist!
statement ok
drop sequence other_seq;

View File

@@ -0,0 +1,36 @@
# name: test/sql/catalog/dependencies/test_concurrent_alter.test
# group: [dependencies]
require skip_reload
# Create the table
statement ok
CREATE TABLE t2 AS (SELECT 42);
# Create a sequence
statement ok
create sequence seq;
# Let the table own the sequence
statement ok
alter sequence seq owned by t2;
concurrentloop i 1 100
loop j 1 10
statement maybe
alter table t2 rename to t3;
----
Error
statement maybe
alter table t3 rename to t2;
----
Error
# j
endloop
# i
endloop

View File

@@ -0,0 +1,38 @@
# name: test/sql/catalog/dependencies/test_concurrent_drop.test
# description: Test concurrent alter and rename of tables
# group: [dependencies]
require skip_reload
# Create a sequence object
statement ok
create sequence seq;
concurrentloop i 0 100
# Create dependencies on the sequence
statement ok
create table tbl${i} (
a integer default nextval('seq')
);
# Cant drop the sequence because we just added a dependency
statement error
drop sequence seq;
----
Cannot drop entry "seq" because there are entries that depend on it.
# Use the sequence
statement ok
insert into tbl${i} VALUES(DEFAULT);
# Drop the table - removing the dependency
statement ok
drop table tbl${i};
# i
endloop
# We can now drop the sequence, all its dependents are gone
statement ok
drop sequence seq;

View File

@@ -0,0 +1,34 @@
# name: test/sql/catalog/dependencies/test_concurrent_index_creation.test
# description: Test concurrent alter and rename of tables
# group: [dependencies]
mode skip
require skip_reload
statement ok
ATTACH '__TEST_DIR__/concurrent_index_creation.db' AS source;
concurrentloop i 0 10
statement maybe
CREATE TABLE IF NOT EXISTS source.tbl (i INT);
----
# Create an index on the table.
statement maybe
CREATE INDEX index${i} ON source.tbl (i);
----
# Drop the table and its indexes.
statement maybe
DROP TABLE source.tbl;
----
endloop
statement ok
DETACH source;
statement ok
ATTACH '__TEST_DIR__/concurrent_index_creation.db' AS source;

View File

@@ -0,0 +1,38 @@
# name: test/sql/catalog/dependencies/test_concurrent_rename.test_slow
# description: Tests concurrent rename of tables
# group: [dependencies]
require skip_reload
statement ok
CREATE TABLE t2 AS (SELECT 42);
concurrentloop i 1 100
loop j 1 10
# Rename to t3
statement maybe
alter table t2 rename to t3;
----
# Rename back to t2
statement maybe
alter table t3 rename to t2;
----
# Select from t3 - might succeed
statement maybe
select * from t3;
----
# Select from t2 - might succeed
statement maybe
select * from t2;
----
# j
endloop
# i
endloop

View File

@@ -0,0 +1,36 @@
# name: test/sql/catalog/dependencies/test_concurrent_schema_creation.test
# description: Test concurrent schema creation + table creation
# group: [dependencies]
require skip_reload
concurrentloop i 0 100
# Create a schema for every thread
statement ok
create schema schema${i};
# Create a table inside this schema
statement ok
create table schema${i}.tbl${i} (a integer);
# Drop the schema for the thread - should fail
statement error
drop schema schema${i};
----
because there are entries that depend on it
# Insert into the table
statement ok
insert into schema${i}.tbl${i} VALUES(1);
# Drop the table
statement ok
drop table schema${i}.tbl${i};
# Drop the schema again - now it succeeds
statement ok
drop schema schema${i};
# i
endloop

View File

@@ -0,0 +1,78 @@
# name: test/sql/catalog/dependencies/test_default_value_dependency.test
# description: Default values and dependencies
# group: [dependencies]
require skip_reload
# dependency on a sequence in a default value
statement ok con1
CREATE SEQUENCE seq
statement ok con1
CREATE TABLE integers(i INTEGER DEFAULT nextval('seq'), j INTEGER)
statement ok con1
INSERT INTO integers (j) VALUES (1), (1), (1), (1), (1)
query R con2
SELECT SUM(i) FROM integers
----
15.000000
# we can't drop the sequence: the table depends on it
statement error con1
DROP SEQUENCE seq
----
# cascade drop works
statement ok con1
DROP SEQUENCE seq CASCADE
# but it also drops the table
statement error con1
SELECT * FROM integers
----
# dependency on multiple sequences in default value
statement ok con1
CREATE SEQUENCE seq
statement ok con1
CREATE SEQUENCE seq1
statement ok con1
CREATE SEQUENCE seq2
statement error con1
CREATE TABLE integers(i INTEGER DEFAULT nextval('seq' || CAST(nextval('seq') AS VARCHAR)), j INTEGER)
----
non-constant sequences are no longer supported
statement ok con1
CREATE TABLE integers(i INTEGER DEFAULT nextval('seq1') + nextval('seq2'), j INTEGER)
# seq1 exists, so the result of the first default value is 1
statement ok con1
INSERT INTO integers (j) VALUES (1)
# we canot drop seq1 and seq2: the dependency is fixed
statement error con1
DROP SEQUENCE seq1
----
Cannot drop entry
statement error con1
DROP SEQUENCE seq2
----
Cannot drop entry
# need to do a cascading drop
statement ok con1
DROP SEQUENCE seq1 CASCADE
# now the table is gone
statement error con1
SELECT * FROM integers
----
does not exist

View File

@@ -0,0 +1,81 @@
# name: test/sql/catalog/dependencies/test_prepare_dependencies_transactions.test
# description: Prepare dependencies and transactions
# group: [dependencies]
require skip_reload
statement ok
SET immediate_transaction_mode=true
# case one: prepared statement is created outside of transaction and committed
statement ok con1
CREATE TABLE integers(i INTEGER)
statement ok con1
INSERT INTO integers VALUES (1), (2), (3), (4), (5)
statement ok con2
PREPARE v AS SELECT SUM(i) FROM integers
# begin a transaction in con2
statement ok con2
BEGIN TRANSACTION
# now drop the table in con, with a cascading drop
statement ok con1
DROP TABLE integers CASCADE
# we can still execute v in con2
statement ok con2
EXECUTE v
# if we try to drop integers we get a conflict though
statement error con2
DROP TABLE integers CASCADE
----
<REGEX>:.*TransactionContext Error: Catalog write-write conflict on alter.*
# now we rollback
statement ok con2
ROLLBACK
# now we can't use the prepared statement anymore
statement error con2
EXECUTE v
----
<REGEX>:.*Catalog Error.*does not exist.*
# case two: prepared statement is created inside transaction
statement ok con1
CREATE TABLE integers(i INTEGER)
statement ok con1
INSERT INTO integers VALUES (1), (2), (3), (4), (5)
# begin a transaction and create a prepared statement
statement ok con2
BEGIN TRANSACTION
statement ok con2
PREPARE v AS SELECT SUM(i) FROM integers
# use the prepared statement
statement ok con2
EXECUTE v
# integers has a prepared statement depending on it, but we can still drop it
statement ok con1
DROP TABLE integers
# using the prepared statement after the table is still works: we are inside a transaction that uses an old version
statement ok con2
EXECUTE v
statement ok con2
COMMIT
# after committing we can no longer use the prepared statement
statement error con2
EXECUTE v
----
<REGEX>:.*Catalog Error.*does not exist.*

View File

@@ -0,0 +1,46 @@
# name: test/sql/catalog/dependencies/test_prepared_dependency.test
# description: Prepared statement dependencies
# group: [dependencies]
require skip_reload
# prepared statements and dependencies
# dependency on a bound table
statement ok con1
CREATE TABLE integers(i INTEGER)
statement ok con2
PREPARE v AS SELECT * FROM integers
statement ok con2
EXECUTE v
statement ok con1
DROP TABLE integers CASCADE
# after the drop the prepared statement is invalidated
statement error con2
EXECUTE v
----
<REGEX>:.*Catalog Error.*does not exist.*
# dependency on a sequence for prepare
statement ok con1
CREATE SEQUENCE seq
statement ok con2
PREPARE v AS SELECT nextval('seq')
statement ok con2
EXECUTE v
# drop the sequence
statement ok con1
DROP SEQUENCE seq CASCADE
# after the drop the prepared statement is invalidated
statement error con2
EXECUTE v
----
<REGEX>:.*Catalog Error.*does not exist.*

View File

@@ -0,0 +1,103 @@
# name: test/sql/catalog/dependencies/test_schema_dependency.test
# description: Schema dependencies
# group: [dependencies]
# single schema and dependencies
statement ok con1
CREATE SCHEMA s1
statement ok con1
CREATE TABLE s1.integers(i INTEGER)
query I con1
SELECT * FROM s1.integers
----
# can't drop: dependency
statement error con1
DROP SCHEMA s1
----
table "integers" depends on schema "s1".
query I con1
SELECT * FROM s1.integers
----
# we can drop with cascade though
statement ok con1
DROP SCHEMA s1 CASCADE
# this also drops the table
statement error con1
SELECT * FROM s1.integers
----
Table with name integers does not exist
# schemas and dependencies
# create a schema and a table inside the schema
statement ok con1
CREATE SCHEMA s1
statement ok con1
CREATE TABLE s1.integers(i INTEGER)
statement ok con1
BEGIN TRANSACTION
statement ok con2
BEGIN TRANSACTION
# drop the table in con1
statement ok con1
DROP TABLE s1.integers
# we can't drop the schema from con2 because the table still exists for con2!
statement error con2
DROP SCHEMA s1
----
table "integers" depends on schema "s1".
# now rollback the table drop
statement ok con1
ROLLBACK
statement ok con2
ROLLBACK
# the table exists again
query I con1
SELECT * FROM s1.integers
----
# try again, but this time we commit
statement ok con1
BEGIN TRANSACTION
statement ok con2
BEGIN TRANSACTION
# drop the schema entirely now
statement ok con1
DROP SCHEMA s1 CASCADE
# we can still query the table from con2
query I con2
SELECT * FROM s1.integers
----
# even after we commit
statement ok con1
COMMIT
query I con2
SELECT * FROM s1.integers
----
# however if we end the transaction in con2 the schema is gone
statement ok con2
ROLLBACK
statement error con2
CREATE TABLE s1.dummy(i INTEGER)
----
Schema with name s1 does not exist

View File

@@ -0,0 +1,43 @@
# name: test/sql/catalog/dependencies/test_write_after_rename.test
# group: [dependencies]
load __TEST_DIR__/create_after_rename.db
# Create 'tbl'
statement ok
create table tbl (i integer);
statement ok
insert into tbl VALUES (5);
statement ok
begin transaction;
# Rename 'tbl' -> 'tbl2'
statement ok
alter table tbl rename to tbl2;
# Create a new table with the old name: 'tbl'
statement ok
create table tbl (b varchar);
statement ok
insert into tbl VALUES ('test')
statement ok
commit;
statement ok
checkpoint;
restart
query I
select * from tbl2;
----
5
query I
select * from tbl;
----
test

View File

@@ -0,0 +1,54 @@
# name: test/sql/catalog/did_you_mean.test
# description: The error messages suggest possible alternative
# group: [catalog]
statement ok
CREATE TABLE hello(i INTEGER);
statement ok
CREATE SCHEMA test;
statement ok
CREATE TABLE test.bye(i INTEGER);
statement error
SELECT * FROM helloo;
----
Did you mean "hello"
statement error
SELECT * FROM bye;
----
Did you mean "test.bye
statement ok
CREATE SCHEMA a;
CREATE TABLE a.foo(name text);
statement error
SELECT * FROM foo;
----
Did you mean "a.foo"?
statement ok
CREATE SCHEMA b;
CREATE TABLE b.foo(name text);
statement error
SELECT * FROM foo;
----
Did you mean "a.foo or b.foo"?
statement ok
CREATE SCHEMA c;
CREATE TABLE c.foo(name text);
statement error
SELECT * FROM foo;
----
Did you mean "a.foo, b.foo, or c.foo"?
statement error
SELECT * FROM a.fooo;
----
Did you mean "foo"?

View File

@@ -0,0 +1,29 @@
# name: test/sql/catalog/drop_create_rollback.test
# description: Issue #7274 - crash when recreating table with different case sensitivity but the same name
# group: [catalog]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE t1 (c1 CHAR(5));
statement ok
BEGIN TRANSACTION;
statement ok
DROP TABLE IF EXISTS t1;
statement ok
CREATE TABLE T1 (C2 CHAR(5));
statement ok
SELECT C2 FROM T1;
statement ok
ROLLBACK;
statement error
SELECT C2 FROM T1;
----
c1

View 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

View 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.*

View 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

View 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

View 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!

View 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

View 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

View 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

View 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

View 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

View 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

View 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
)

View 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

View 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]

View 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

View 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;

View 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

View 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.*

View 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

View 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

View 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

View 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));

View 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

View 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%';
----

View 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

View 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)

View 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

View 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

View 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)

View 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

View 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

View File

@@ -0,0 +1,20 @@
# name: test/sql/catalog/information_schema_read_only.test
# description: Test that information schema/pg_catalog are read only
# group: [catalog]
statement ok
PRAGMA enable_verification
statement error
CREATE TABLE system.information_schema.tbl(i INT)
----
Cannot create entry in system catalog
statement error
CREATE TABLE information_schema.tbl(i INT)
----
statement error
CREATE TABLE pg_catalog.tbl(i INT)
----
Cannot create entry in system catalog

View File

@@ -0,0 +1,12 @@
# name: test/sql/catalog/issue_9459.test
# description: Issue #9459 - Dropping schema with double quote in name fails
# group: [catalog]
statement ok
PRAGMA enable_verification
statement ok
create schema """cursed_schema";
statement ok
drop schema """cursed_schema";

View File

@@ -0,0 +1,31 @@
# name: test/sql/catalog/sequence/sequence_cycle.test
# description: Test Sequences with cycles
# group: [sequence]
statement ok
create sequence minseq INCREMENT BY -1 MINVALUE -5 MAXVALUE 5 CYCLE;
query I
SELECT nextval('minseq') from generate_series(0,20);
----
5
4
3
2
1
0
-1
-2
-3
-4
-5
5
4
3
2
1
0
-1
-2
-3
-4

View File

@@ -0,0 +1,16 @@
# name: test/sql/catalog/sequence/sequence_offset_increment.test
# description: Issue #9252: Sequences defined with offset and custom increment always start with 1 instead of using the offset
# group: [sequence]
statement ok
create sequence xx start 100 increment by 2;
query I
SELECT nextval('xx')
----
100
query I
SELECT nextval('xx')
----
102

View File

@@ -0,0 +1,119 @@
# name: test/sql/catalog/sequence/sequence_overflow.test
# description: Issue #2678: overflow in sequences
# group: [sequence]
statement ok
create sequence seq1 INCREMENT BY 1 MINVALUE 9223372036854775800 MAXVALUE 9223372036854775807 CYCLE;
query I
SELECT nextval('seq1') from generate_series(0,20);
----
9223372036854775800
9223372036854775801
9223372036854775802
9223372036854775803
9223372036854775804
9223372036854775805
9223372036854775806
9223372036854775807
9223372036854775800
9223372036854775801
9223372036854775802
9223372036854775803
9223372036854775804
9223372036854775805
9223372036854775806
9223372036854775807
9223372036854775800
9223372036854775801
9223372036854775802
9223372036854775803
9223372036854775804
statement ok
create sequence seq2 INCREMENT BY -1 MINVALUE -9223372036854775808 MAXVALUE -9223372036854775800 CYCLE;
query I
SELECT nextval('seq2') from generate_series(0,20);
----
-9223372036854775800
-9223372036854775801
-9223372036854775802
-9223372036854775803
-9223372036854775804
-9223372036854775805
-9223372036854775806
-9223372036854775807
-9223372036854775808
-9223372036854775800
-9223372036854775801
-9223372036854775802
-9223372036854775803
-9223372036854775804
-9223372036854775805
-9223372036854775806
-9223372036854775807
-9223372036854775808
-9223372036854775800
-9223372036854775801
-9223372036854775802
statement ok
create sequence seq3 INCREMENT BY 1 MINVALUE 9223372036854775800 MAXVALUE 9223372036854775807;
statement error
SELECT nextval('seq3') from generate_series(0,20);
----
<REGEX>:.*Sequence Error.*reached maximum value of sequence.*
statement ok
create sequence seq4 INCREMENT BY -1 MINVALUE -9223372036854775808 MAXVALUE -9223372036854775800;
statement error
SELECT nextval('seq4') from generate_series(0,20);
----
<REGEX>:.*Sequence Error.*reached minimum value of sequence.*
statement ok
create sequence seq5 INCREMENT BY 9223372036854775807 MINVALUE 9223372036854775800 MAXVALUE 9223372036854775807 CYCLE;
query I
SELECT nextval('seq5') from generate_series(0,20);
----
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
9223372036854775800
statement ok
create sequence seq6 INCREMENT BY 9223372036854775807 MINVALUE 9223372036854775800 MAXVALUE 9223372036854775807;
statement error
SELECT nextval('seq6') from generate_series(0,20);
----
<REGEX>:.*Sequence Error.*reached maximum value of sequence.*
statement ok
create sequence seq7 INCREMENT BY -9223372036854775808 MINVALUE -9223372036854775808 MAXVALUE -9223372036854775800;
statement error
SELECT nextval('seq7') from generate_series(0,20);
----
<REGEX>:.*Sequence Error.*reached minimum value of sequence.*

View File

@@ -0,0 +1,17 @@
# name: test/sql/catalog/sequence/test_duckdb_sequences.test
# group: [sequence]
require noforcestorage
statement ok
create sequence my_seq;
query I
select nextval('my_seq');
----
1
query I
select last_value from duckdb_sequences();
----
1

View File

@@ -0,0 +1,560 @@
# name: test/sql/catalog/sequence/test_sequence.test
# description: Test Sequences
# group: [sequence]
# note: query verification is disabled for these queries
# because running the same query multiple times with a sequence does not result in the same answer
# create a sequence
require skip_reload
statement ok
CREATE SEQUENCE seq;
# cannot create duplicate sequence
statement error
CREATE SEQUENCE seq;
----
<REGEX>:.*Catalog Error.*already exists.*
# ignore errors if sequence already exists
statement ok
CREATE SEQUENCE IF NOT EXISTS seq;
query I
SELECT nextval('seq')
----
1
# replace sequence
statement ok
CREATE OR REPLACE SEQUENCE seq
# generate values from the sequence
query I
SELECT nextval('seq')
----
1
query I
SELECT currval('seq')
----
1
query I
SELECT currval('seq')
----
1
query I
SELECT nextval('seq')
----
2
query I
SELECT currval('seq')
----
2
query I
SELECT currval('seq')
----
2
query II
SELECT nextval('seq'), nextval('seq');
----
3 4
# NULL in nextval/currval
query I
SELECT nextval(NULL)
----
NULL
query I
SELECT currval(NULL)
----
NULL
statement error
SELECT nextval(a) FROM (VALUES ('seq'), (NULL), ('seq')) tbl1(a)
----
<REGEX>:.*Not implemented Error.*non-constant sequences are no longer supported.*
statement error
SELECT currval(a) FROM (VALUES ('seq'), (NULL), ('seq')) tbl1(a)
----
<REGEX>:.*Not implemented Error.*non-constant sequences are no longer supported.*
# can't create a sequence that already exists
statement error
CREATE SEQUENCE seq;
----
<REGEX>:.*Catalog Error.*already exists.*
# drop the sequence
statement ok
DROP SEQUENCE seq;
# can't drop non-existing sequence
statement error
DROP SEQUENCE seq;
----
<REGEX>:.*Catalog Error: Sequence.*does not exist.*
# but doesn't fail with IF EXISTS
statement ok
DROP SEQUENCE IF EXISTS seq;
# INCREMENT BY
statement ok
CREATE SEQUENCE seq INCREMENT BY 2;
query I
SELECT nextval('seq')
----
1
query I
SELECT nextval('"seq"')
----
3
query I
SELECT currval('"seq"')
----
3
statement ok
DROP SEQUENCE seq;
# MINVALUE
statement ok
CREATE SEQUENCE seq MINVALUE 3;
query I
SELECT nextval('seq')
----
3
query I
SELECT nextval('seq')
----
4
statement ok
DROP SEQUENCE seq;
# MAXVALUE
statement ok
CREATE SEQUENCE seq MAXVALUE 2;
query I
SELECT nextval('seq')
----
1
query I
SELECT nextval('seq')
----
2
# max value exceeded
statement error
SELECT nextval('seq')
----
<REGEX>:.*Sequence Error.*reached maximum value of sequence.*
statement ok
DROP SEQUENCE seq;
# MAXVALUE and CYCLE
statement ok
CREATE SEQUENCE seq MAXVALUE 2 CYCLE;
query I
SELECT nextval('seq')
----
1
query I
SELECT nextval('seq')
----
2
query I
SELECT currval('seq')
----
2
# max value exceeded: cycle back
query I
SELECT nextval('seq')
----
1
query I
SELECT currval('seq')
----
1
statement ok
DROP SEQUENCE seq;
# START WITH, MINVALUE, MAXVALUE and CYCLE
statement ok
CREATE SEQUENCE seq MINVALUE 3 MAXVALUE 5 START WITH 4 CYCLE;
query I
SELECT nextval('seq')
----
4
query I
SELECT currval('seq')
----
4
query I
SELECT nextval('seq')
----
5
query I
SELECT currval('seq')
----
5
query I
SELECT nextval('seq')
----
3
query I
SELECT currval('seq')
----
3
statement ok
DROP SEQUENCE seq;
# START WITH defaults to MAXVALUE if increment is negative
statement ok
CREATE SEQUENCE seq INCREMENT BY -1 MINVALUE 0 MAXVALUE 2;
query I
SELECT nextval('seq')
----
2
query I
SELECT nextval('seq')
----
1
query I
SELECT nextval('seq')
----
0
query I
SELECT currval('seq')
----
0
statement error
SELECT nextval('seq')
----
<REGEX>:.*Sequence Error.*reached minimum value of sequence.*
query I
SELECT currval('seq')
----
0
statement ok
DROP SEQUENCE seq;
# START WITH defaults to MINVALUE if increment is positive
statement ok
CREATE SEQUENCE seq INCREMENT BY 1 MINVALUE 0 MAXVALUE 2;
query I
SELECT nextval('seq')
----
0
query I
SELECT nextval('seq')
----
1
query I
SELECT nextval('seq')
----
2
statement error
SELECT nextval('seq')
----
<REGEX>:.*Sequence Error.*reached maximum value of sequence.*
statement ok
DROP SEQUENCE seq;
# for positive increment min_value/start defaults to 1 and max_value defaults to 2^63
statement ok
CREATE SEQUENCE seq INCREMENT 1 MAXVALUE 3 START 2 CYCLE;
query I
SELECT nextval('seq')
----
2
query I
SELECT nextval('seq')
----
3
query I
SELECT nextval('seq')
----
1
statement ok
DROP SEQUENCE seq;
# for negative increment min_value defaults to -2^63 and max_value/start defaults to -1
statement ok
CREATE SEQUENCE seq INCREMENT -1 CYCLE;
query I
SELECT nextval('seq')
----
-1
query I
SELECT nextval('seq')
----
-2
query I
SELECT nextval('seq')
----
-3
statement ok
DROP SEQUENCE seq;
statement ok
CREATE SEQUENCE seq INCREMENT -1 MINVALUE -2 CYCLE;
query I
SELECT nextval('seq')
----
-1
query I
SELECT nextval('seq')
----
-2
query I
SELECT nextval('seq')
----
-1
statement ok
DROP SEQUENCE seq;
# min_value defaults to 1, setting start to -1 gives start < min_value
statement error
CREATE SEQUENCE seq INCREMENT 1 START -1 CYCLE;
----
<REGEX>:.*Parser Error.*cannot be less than MINVALUE.*
# max_value defaults to -1, setting start to 1 gives start > max_value
statement error
CREATE SEQUENCE seq INCREMENT -1 START 1 CYCLE;
----
<REGEX>:.*Parser Error.*cannot be greater than MAXVALUE.*
# sequences in schemas
statement ok
CREATE SCHEMA a;
statement ok
CREATE SCHEMA b;
statement ok
CREATE SEQUENCE a.seq;
statement ok
CREATE SEQUENCE b.seq;
query II
SELECT nextval('a.seq'), nextval('b.seq');
----
1 1
query II
SELECT currval('a.seq'), currval('b.seq');
----
1 1
# with quotes
query II
SELECT nextval('"a"."seq"'), nextval('"b".seq');
----
2 2
query II
SELECT currval('"a"."seq"'), currval('"b".seq');
----
2 2
# unterminated quotes
statement error
SELECT nextval('"a"."seq');
----
<REGEX>:.*Parser Error.*Unterminated quote.*
# too many separators
statement error
SELECT nextval('a.b.c.d');
----
<REGEX>:.*Parser Error.*too many entries found.*
# start exceeds max value
statement error
CREATE SEQUENCE seq MAXVALUE 5 START WITH 6;
----
<REGEX>:.*Parser Error.*cannot be greater than MAXVALUE.*
# start preceeds min value
statement error
CREATE SEQUENCE seq MINVALUE 5 START WITH 4;
----
<REGEX>:.*Parser Error.*cannot be less than MINVALUE.*
# min value bigger than max
statement error
CREATE SEQUENCE seq MINVALUE 7 MAXVALUE 5;
----
<REGEX>:.*Parser Error.*must be less than MAXVALUE.*
# increment must not be 0
statement error
CREATE SEQUENCE seq INCREMENT 0;
----
<REGEX>:.*Parser Error.*Increment must not be zero.*
statement ok
CREATE SEQUENCE seq;
statement ok
CREATE SEQUENCE seq2;
# we can use operations in nextval
query I
SELECT nextval('s'||'e'||'q')
----
1
statement ok
DROP SEQUENCE seq;
# sequences with tables
statement ok
CREATE SEQUENCE seq;
statement ok
CREATE TABLE strings(s VARCHAR);
statement ok
INSERT INTO strings VALUES ('seq'), ('seq2')
# nextval is run once per value
query TI
SELECT s, nextval('seq') FROM strings
----
seq 1
seq2 2
query TI
SELECT s, currval('seq') FROM strings
----
seq 2
seq2 2
# we cannot use the strings from the table as input to the sequence
statement error
SELECT s, nextval(s) FROM strings
----
<REGEX>:.*Not implemented Error.*non-constant sequences are no longer supported.*
statement error
SELECT s, currval(s) FROM strings
----
<REGEX>:.*Not implemented Error.*non-constant sequences are no longer supported.*
# this will also cause an error if the sequence does not exist
statement ok
INSERT INTO strings VALUES ('nonexistant_seq')
statement error
SELECT s, nextval(s) FROM strings
----
<REGEX>:.*Not implemented Error.*non-constant sequences are no longer supported.*
# currval causes error for new sequence
statement ok
CREATE SEQUENCE fresh;
statement error
select currval('fresh');
----
<REGEX>:.*Sequence Error.*sequence is not yet defined in this session.*
# convert inputs into varchar if that's not the case
statement error
select nextval(1 + 1);
----
<REGEX>:.*Binder Error: No function matches.*
statement error
select currval(true);
----
<REGEX>:.*Binder Error: No function matches.*
# max value specified more than once
statement error
CREATE SEQUENCE wrongseq NO MAXVALUE MAXVALUE 2;
----
<REGEX>:.*Parser Error: Maxvalue should be passed as most once.*
# min value specified more than once
statement error
CREATE SEQUENCE wrongseq MINVALUE 10 MINVALUE 2;
----
<REGEX>:.*Parser Error: Minvalue should be passed as most once.*
# start value specified more than once
statement error
CREATE SEQUENCE wrongseq START 13 START WITH 3;
----
<REGEX>:.*Parser Error: Start value should be passed as most once.*
# cycle value specified more than once
statement error
CREATE SEQUENCE wrongseq CYCLE MAXVALUE 2 MINVALUE 1 NO CYCLE;
----
<REGEX>:.*Parser Error: Cycle value should be passed as most once.*
# increment value specified more than once
statement error
CREATE SEQUENCE wrongseq INCREMENT 2 INCREMENT BY -1;
----
<REGEX>:.*Parser Error: Increment value should be passed as most once.*

View File

@@ -0,0 +1,29 @@
# name: test/sql/catalog/sequence/test_sequence_dependency.test
# description: Test Sequence Dependencies
# group: [sequence]
require skip_reload
statement ok
create sequence seq;
statement ok
create table integers(i integer default nextval('seq'));
# can't drop the sequence
statement error
drop sequence seq;
----
statement ok
begin transaction;
statement ok
drop table integers;
statement ok
drop sequence seq;
statement ok
commit

View File

@@ -0,0 +1,16 @@
# name: test/sql/catalog/sequence/test_sequence_google_fuzz.test
# description: Test Sequence on results produce by the google fuzzer
# group: [sequence]
statement error
;creAte
sequence
uGeõó±õõõõ.õõõ.õ;creAte
sequence
uGeõõõõõ..õ;creAte
sequence
uGeõõõõõ..õ;creAte
sequence
uGeõõõõ
----
Catalog with name uGeõó±õõõõ does not exist!

View File

@@ -0,0 +1,14 @@
# name: test/sql/catalog/table/create_table_as_abort.test
# description: Test correct early abort of CREATE TABLE AS query when table already exists (#1891)
# group: [table]
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
CREATE TABLE IF NOT EXISTS integers AS SELECT i1.i FROM range(10000000000000000) i1(i);
statement error
CREATE TABLE integers AS SELECT i1.i FROM range(10000000000000000) i1(i);
----
<REGEX>:.*Catalog Error.*already exists.*

View File

@@ -0,0 +1,14 @@
# name: test/sql/catalog/table/create_table_parameters.test
# description: Issue #10008 - DuckDB SIGSEGV when creating table with DEFAULT ?
# group: [table]
statement error
CREATE TABLE t0 ( c1 INT DEFAULT ? );
----
<REGEX>:.*Binder Error.*cannot contain parameters.*
# error messages for `enable_verification`=(false|true)
statement error
CREATE TABLE t0 ( c1 INT CHECK (?) );
----
<REGEX>:(.*Invalid Input Error: Expected 2 parameters.*|.*Binder Error.*Unexpected prepared parameter.*)

View File

@@ -0,0 +1,22 @@
# name: test/sql/catalog/table/long_identifier.test
# description: Test long identifiers (>= 64 bytes)
# group: [table]
statement ok
create table integers("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" integer);
statement ok
select "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" from integers
statement ok
create table integers2("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" integer);
statement ok
select "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" from integers2
statement ok
create table integers3("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et laoreet lacus, sollicitudin cursus metus. Pellentesque quis magna magna. Ut viverra erat vulputate, euismod sapien id, mollis odio. Vestibulum accumsan orci ac diam accumsan efficitur. Sed vel maximus leo, vel tempus metus. Fusce urna dolor, lacinia ac scelerisque hendrerit, semper eu nisl. Vivamus pellentesque sapien id sapien finibus porttitor. Cras congue libero quis nunc pretium efficitur. Praesent vitae urna non elit luctus posuere mattis ac eros. Nunc tincidunt quam vel sem ullamcorper semper. Donec eget gravida justo. Duis vel mollis felis.
Duis scelerisque risus in sem molestie, nec egestas odio vestibulum. Nunc in dui eu dui fringilla dignissim vitae id felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus a tempus sapien. Cras vehicula maximus laoreet. In hac habitasse platea dictumst. In fermentum orci id libero congue dignissim. Aenean tristique porta arcu a varius. Cras vitae leo gravida, eleifend dolor et, porttitor arcu.
Pellentesque et fringilla tortor. Sed sodales nulla lacus, eget feugiat dolor mattis tincidunt. Morbi ut finibus odio. Mauris felis diam, ornare ac diam mattis, suscipit laoreet turpis. Duis vulputate mi in orci pretium, vitae varius turpis facilisis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas gravida libero at ligula pretium, quis gravida libero tempus. Aenean eu condimentum libero. Duis sagittis augue mi. Cras vel ante a ipsum consequat interdum. Aliquam venenatis metus sed ligula consequat congue. Fusce ut rutrum urna. Integer auctor purus nulla, eget lacinia dolor sollicitudin et. Vestibulum lacinia lectus nec mauris iaculis, eget cursus mauris semper. Donec ut lacinia felis. Quisque vitae risus sit amet erat semper suscipit.
Duis pulvinar ipsum purus, vitae placerat lectus commodo ut. Nullam viverra arcu vitae ipsum faucibus, at aliquet massa vehicula. Nunc eget felis sed quam sollicitudin tempus. Quisque lobortis id nisi id dictum. Phasellus id elementum purus. Duis diam purus, egestas ac quam et, porta fringilla velit. Nulla a turpis bibendum, eleifend eros eget, efficitur nibh. Pellentesque consectetur porttitor lacinia. Aliquam blandit eros eu metus ultrices, ut dignissim nunc lacinia. Mauris placerat volutpat odio, dictum dapibus dolor egestas sed. Nam consequat odio quis urna lobortis viverra. Phasellus facilisis elit nec neque rutrum laoreet. Etiam non maximus magna. Pellentesque pellentesque laoreet orci, vel sollicitudin urna sollicitudin a. Nunc id iaculis enim, quis pharetra mauris. Nullam sit amet diam eu massa dictum vehicula.
Vestibulum sed congue urna. Praesent iaculis massa viverra ex congue, nec euismod leo scelerisque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis aliquet ut augue non interdum. Quisque tempor blandit mi non dignissim. Integer hendrerit, elit id posuere facilisis, libero purus dignissim ipsum, nec tincidunt metus lectus elementum magna. Cras turpis dolor, gravida et ipsum non, vestibulum sagittis sapien. Maecenas varius lacus mi, at porta purus cursus eget. Nunc feugiat congue augue id mollis. Praesent sed erat non leo varius varius. Sed sodales justo sollicitudin ex faucibus euismod. Aenean gravida nec diam vel vestibulum. Donec feugiat risus velit, quis fringilla libero vulputate nec. Curabitur pulvinar, tellus in eleifend varius, orci ex hendrerit sem, at laoreet diam ante id nibh." integer);

View File

@@ -0,0 +1,15 @@
# name: test/sql/catalog/table/test_concurrent_constraints.test_slow
# group: [table]
statement ok
CREATE TABLE tbl_constraints(pk INT PRIMARY KEY, u INT UNIQUE, s INT CHECK (s > 42), d INT CHECK (d + 1 < 42));
concurrentloop threadid 0 100
statement ok
SELECT c.oid,c.*,t.relname as tabrelname, case when c.contype='c' then substring(pg_get_constraintdef(c.oid), 7) else null end consrc_copy
FROM pg_catalog.pg_constraint c
INNER JOIN pg_catalog.pg_class t ON t.oid=c.conrelid limit 5;
endloop

View File

@@ -0,0 +1,31 @@
# name: test/sql/catalog/table/test_create_table_parallelism.test
# description: Test parallel table creation
# group: [table]
statement ok
PRAGMA enable_verification
statement ok
PRAGMA threads=4
statement ok
PRAGMA verify_parallelism
statement ok
CREATE TABLE test AS (SELECT string_agg(range::VARCHAR, '🦆 ') AS s, mod(range, 10000) xx FROM range(50000) GROUP BY xx)
statement ok
CREATE TABLE test2 AS (SELECT unnest(string_split(s, ' ')) FROM test)
query T
SELECT count(*) FROM test2
----
50000
statement ok
CREATE TABLE test3 AS (SELECT * FROM test ORDER BY xx)
query T
SELECT count(*) FROM test3
----
10000

View File

@@ -0,0 +1,174 @@
# name: test/sql/catalog/table/test_default.test
# description: Test DEFAULT in tables
# group: [table]
require skip_reload
statement ok
PRAGMA enable_verification
# no default specified: write NULL value
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test (b) VALUES (3);
statement ok
INSERT INTO test VALUES (DEFAULT, DEFAULT);
query II
SELECT * FROM test
----
NULL 3
NULL NULL
statement ok
DROP TABLE test
# no default specified: default is NULL value
# but we set column to NOT NULL
# now insert should fail
statement ok
CREATE TABLE test (a INTEGER NOT NULL, b INTEGER);
statement error
INSERT INTO test (b) VALUES (3);
----
statement ok
DROP TABLE test
# simple default: constant value
statement ok
CREATE TABLE test (a INTEGER DEFAULT 1, b INTEGER);
statement ok
INSERT INTO test (b) VALUES (3);
query II
SELECT * FROM test
----
1 3
statement ok
DROP TABLE test
# default as expression
statement ok
CREATE TABLE test (a INTEGER DEFAULT 1+1, b INTEGER);
statement ok
INSERT INTO test (b) VALUES (3);
query II
SELECT * FROM test
----
2 3
statement ok
DROP TABLE test
# default with insert from query
statement ok
CREATE TABLE test (a INTEGER DEFAULT 1+1, b INTEGER);
statement ok
INSERT INTO test (b) SELECT 3
query II
SELECT * FROM test
----
2 3
statement ok
DROP TABLE test
# default from sequence
statement ok
CREATE SEQUENCE seq;
statement ok
CREATE TABLE test (a INTEGER DEFAULT nextval('seq'), b INTEGER);
statement ok
INSERT INTO test (b) VALUES (2), (4), (6), (2), (4);
query II
SELECT * FROM test ORDER BY 1
----
1 2
2 4
3 6
4 2
5 4
# cannot drop sequence now
statement error
DROP SEQUENCE seq
----
statement ok
DROP TABLE test
# after dropping table we can drop seq
statement ok
DROP SEQUENCE seq
# test default with update
statement ok
CREATE SEQUENCE seq;
statement ok
CREATE TABLE test (a INTEGER DEFAULT nextval('seq'), b INTEGER);
statement ok
INSERT INTO test (b) VALUES (1);
statement ok
UPDATE test SET a=DEFAULT
query II
SELECT * FROM test ORDER BY 1
----
2 1
# cannot use subquery in DEFAULT expression
statement error
CREATE TABLE test (a INTEGER DEFAULT (SELECT 42), b INTEGER);
----
# aggregate functions are not allowed in DEFAULT expressions
statement error
CREATE TABLE test (a INTEGER DEFAULT SUM(42), b INTEGER);
----
# window functions are not allowed in DEFAULT expressions
statement error
CREATE TABLE test (a INTEGER DEFAULT row_number() OVER (), b INTEGER);
----
# default value must be scalar expression
statement error
CREATE TABLE test (a INTEGER DEFAULT b+1, b INTEGER);
----
# test default with random
statement ok
DROP TABLE test
statement ok
CREATE TABLE test (a DOUBLE DEFAULT random(), b INTEGER);
statement ok
INSERT INTO test (b) VALUES (1);
statement ok
INSERT INTO test (b) VALUES (2);
query R
SELECT COUNT(DISTINCT a) FROM test;
----
2

View File

@@ -0,0 +1,51 @@
# name: test/sql/catalog/table/test_default_values.test
# description: Test DEFAULT VALUES insert
# group: [table]
statement ok
PRAGMA enable_verification
statement ok
create table x (i int default 1, j int default 2)
statement ok
insert into x default values;
query II
SELECT * FROM x
----
1 2
# returning
query I
insert into x default values returning (i);
----
1
query I
insert into x default values returning (j);
----
2
statement error
insert into x(i) default values;
----
Parser Error
# on conflict
statement ok
drop table x;
statement ok
create table x (i int primary key default 1, j int default 2)
statement ok
insert into x default values;
statement error
insert into x default values;
----
violates primary key constraint
statement ok
insert into x default values on conflict do nothing;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
# name: test/sql/catalog/table/test_table_drop_concurrent.test_slow
# group: [table]
require 64bit
# Create 4000 threads that all run the contents of this loop
concurrentloop threadid 0 300
# Create a table
statement ok
CREATE OR REPLACE TABLE df${threadid} as select i,i,i from range(100) tbl(i)
# Drop the table
statement ok
DROP TABLE df${threadid};
endloop

View File

@@ -0,0 +1,89 @@
# name: test/sql/catalog/test_catalog_errors.test
# description: Test various errors in catalog management
# group: [catalog]
statement ok
CREATE TABLE integers(i INTEGER);
statement ok
CREATE VIEW vintegers AS SELECT 42;
# cannot CREATE OR REPLACE a table with a view
statement error
CREATE OR REPLACE VIEW integers AS SELECT 42;
----
<REGEX>:.*Catalog Error: Existing object integers.*
# cannot use DROP VIEW to drop a table
statement error
DROP VIEW integers
----
<REGEX>:.*Catalog Error: Existing object integers.*
# cannot drop a table that does not exist
statement error
DROP TABLE blabla
----
<REGEX>:.*Catalog Error.*does not exist.*
# cannot alter a table that does not exist
statement error
ALTER TABLE blabla RENAME COLUMN i TO k
----
<REGEX>:.*Catalog Error.*does not exist.*
# cannot drop view with DROP TABLE
statement error
DROP TABLE IF EXISTS vintegers
----
<REGEX>:.*Catalog Error: Existing object vintegers.*
statement ok
CREATE INDEX i_index ON integers(i);
# cannot create an index that already exists
statement error
CREATE INDEX i_index ON integers(i);
----
<REGEX>:.*Catalog Error.*already exists.*
# with IF NOT EXISTS it does not fail!
statement ok
CREATE INDEX IF NOT EXISTS i_index ON integers(i);
# drop the index
statement ok
DROP INDEX i_index
# cannot drop the index again: it no longer exists
statement error
DROP INDEX i_index
----
<REGEX>:.*Catalog Error.*does not exist.*
# IF NOT EXISTS does not report the failure
statement ok
DROP INDEX IF EXISTS i_index
# create the index again, but as unique to exercise special handling due to indexes generated column constraints
statement ok
CREATE UNIQUE INDEX i_index ON integers(i);
# cannot create an index that already exists
statement error
CREATE UNIQUE INDEX i_index ON integers(i);
----
<REGEX>:.*Catalog Error.*already exists.*
# with IF NOT EXISTS it does not fail!
statement ok
CREATE UNIQUE INDEX IF NOT EXISTS i_index ON integers(i);
# dropping the table also drops the index
statement ok
DROP TABLE integers;
statement error
DROP INDEX i_index
----
<REGEX>:.*Catalog Error.*does not exist.*

View File

@@ -0,0 +1,63 @@
# name: test/sql/catalog/test_create_from_select.test
# description: Create table from SELECT statement
# group: [catalog]
statement ok
CREATE TABLE integers(i INTEGER);
statement ok
INSERT INTO integers VALUES (3), (4), (5)
query I
SELECT * FROM integers
----
3
4
5
statement ok
INSERT INTO integers SELECT i+3 FROM integers;
query I
SELECT * FROM integers
----
3
4
5
6
7
8
statement ok
CREATE TABLE integers2 AS SELECT i, i+2 AS j FROM integers;
query II
SELECT * FROM integers2 ORDER BY i
----
3 5
4 6
5 7
6 8
7 9
8 10
query I
SELECT i FROM integers2 ORDER BY i
----
3
4
5
6
7
8
query I
SELECT j FROM integers2 ORDER BY i
----
5
6
7
8
9
10

View File

@@ -0,0 +1,12 @@
# name: test/sql/catalog/test_extension_suggestion.test
# description: The error messages that suggests extension to be installed
# group: [catalog]
require skip_reload
require no_extension_autoloading "EXPECTED: This tests what happens when extension is not there"
statement error
SELECT from_json('data/json/array_of_empty_arrays.json');
----
Catalog Error: Scalar Function with name "from_json" is not in the catalog, but it exists in the json extension.

View File

@@ -0,0 +1,34 @@
# name: test/sql/catalog/test_if_not_exists.test
# description: Test IF NOT EXISTS
# group: [catalog]
statement ok
CREATE TABLE IF NOT EXISTS integers(i INTEGER, j INTEGER)
statement ok
CREATE TABLE IF NOT EXISTS integers(i INTEGER, j INTEGER)
statement ok
CREATE TABLE IF NOT EXISTS integers2 AS SELECT 42
statement ok
CREATE TABLE IF NOT EXISTS integers2 AS SELECT 42
# similar to Postgres, treat as NOOP if the entry exists but the type is different
statement ok
CREATE VIEW IF NOT EXISTS integers2 AS SELECT 42
statement error
DROP VIEW IF EXISTS integers
----
<REGEX>:Catalog Error.*trying to drop type View.*
statement ok
DROP TABLE IF EXISTS integers
statement ok
DROP TABLE IF EXISTS integers
statement ok
DROP TABLE IF EXISTS no_such_scheme.integers

View File

@@ -0,0 +1,25 @@
# name: test/sql/catalog/test_incorrect_table_creation.test
# description: Test failure cases in table creation/deletion
# group: [catalog]
# primary key constraint that references unknown column
statement error
CREATE TABLE integers(i INTEGER, PRIMARY KEY(j))
----
# primary key that references the same key twice
statement error
CREATE TABLE integers(i INTEGER, PRIMARY KEY(i, i))
----
# multiple primary keys
statement error
CREATE TABLE integers(i INTEGER, PRIMARY KEY(i), PRIMARY KEY(i))
----
Parser Error: table "integers" has more than one primary key
statement error
CREATE TABLE integers(i INTEGER PRIMARY KEY, PRIMARY KEY(i))
----
Parser Error: table "integers" has more than one primary key

View File

@@ -0,0 +1,70 @@
# name: test/sql/catalog/test_querying_from_detached_catalog.test
# description: Test switching from detached catalog to another catalog
# group: [catalog]
statement ok con1
ATTACH ':memory:' AS db1;
statement ok con1
ATTACH ':memory:' AS db2;
statement ok con1
CREATE TABLE db2.tbl (i INTEGER, j INTEGER);
statement ok con1
INSERT INTO db2.tbl VALUES (1, 2), (3,4);
statement ok con1
USE db1;
query I con1
SELECT CURRENT_SETTING('search_path');
----
db1.main
statement ok con2
USE db2;
# drop catalog db1, which con1 is using
statement ok con2
DETACH db1;
# querying to an attached catalog should work (with non-fully qualified name)
query II con1
FROM db2.tbl;
----
1 2
3 4
# querying to an attached catalog should work (with fully qualified name)
query II con1
FROM db2.main.tbl;
----
1 2
3 4
# creating a new table in db2 works
statement ok con1
CREATE TABLE db2.tbl2 AS SELECT 42;
# error message should say that the table does not exist
statement error con1
FROM db2.non_existent_table;
----
Catalog Error: Table with name non_existent_table does not exist!
# querying within the detached catalog fails
statement error con1
SHOW TABLES;
----
Binder Error: Catalog "db1" does not exist!
# swithcing to another catalog should work
statement ok con1
USE db2;
query I con1
SELECT CURRENT_SETTING('search_path');
----
db2.main

View File

@@ -0,0 +1,26 @@
# name: test/sql/catalog/test_quoted_column_name.test
# description: Test quoted column name
# group: [catalog]
statement ok
CREATE TABLE integers("42" INTEGER)
statement ok
INSERT INTO integers VALUES (33)
query I
SELECT "42" FROM integers;
----
33
# verify escaped quotes and dots
statement ok
CREATE TABLE "table ""." ( "col ""." TEXT)
statement ok
INSERT INTO "table ""." ("col "".") VALUES ('quote_escaped_quote_''')
query TT
SELECT "table ""."."col "".", "col ""." FROM "table "".";
----
quote_escaped_quote_' quote_escaped_quote_'

View File

@@ -0,0 +1,79 @@
# name: test/sql/catalog/test_schema.test
# description: Schema creation/deletion with transactions
# group: [catalog]
statement ok
SET immediate_transaction_mode=true
# create a schema with a table
statement ok con1
CREATE SCHEMA test;
statement ok con1
CREATE OR REPLACE SCHEMA test;
statement ok con1
CREATE TABLE test.hello(i INTEGER);
statement error con1
CREATE OR REPLACE SCHEMA test;
----
table "hello" depends on schema "test".
# in one transaction drop the table and then the schema (without cascade)
statement ok con1
BEGIN TRANSACTION;
statement ok con1
DROP TABLE test.hello;
statement ok con1
DROP SCHEMA test;
statement ok con1
COMMIT;
# now work with multiple connections
# create the same schema
statement ok con1
CREATE SCHEMA test;
statement ok con1
CREATE TABLE test.hello(i INTEGER);
statement ok con1
INSERT INTO test.hello VALUES (2), (3), (4)
# begin the transactions
statement ok con1
BEGIN TRANSACTION
statement ok con2
BEGIN TRANSACTION
# con1 drops the schema and commits it
statement ok con1
DROP TABLE test.hello;
statement ok con1
DROP SCHEMA test;
statement ok con1
COMMIT;
# con2 queries the schema (should still work)
query I con2
SELECT * FROM test.hello
----
2
3
4
# now con2 finishes the transaction and tries again
statement ok con2
ROLLBACK;
statement error con2
SELECT * FROM test.hello
----
Table with name hello does not exist

View File

@@ -0,0 +1,51 @@
# name: test/sql/catalog/test_schema_conflict.test
# description: Catalog conflicts with schemas
# group: [catalog]
statement ok con1
BEGIN TRANSACTION;
statement ok con2
BEGIN TRANSACTION;
# create the same schema in both connections
statement ok con1
CREATE SCHEMA test;
# this should cause a conflict
statement error con2
CREATE SCHEMA test;
----
statement ok con1
COMMIT
statement ok con2
ROLLBACK
# now try the same with DROP SCHEMA
statement ok con1
BEGIN TRANSACTION;
statement ok con2
BEGIN TRANSACTION;
statement ok con1
DROP SCHEMA test;
# this should cause a conflict
statement error con2
DROP SCHEMA test;
----
# rollback the drop
statement ok con1
ROLLBACK
statement ok con2
ROLLBACK
# now the schema should still exist, so we can drop it again
statement ok con1
DROP SCHEMA test;

View File

@@ -0,0 +1,434 @@
# name: test/sql/catalog/test_set_schema.test
# description: Default schema name changes
# group: [catalog]
# This test focuses on actual name lookup.
# See also test_set_search_path.test
statement ok
CREATE SCHEMA test;
statement ok
CREATE SCHEMA out_of_path;
statement ok
SET SESSION schema = 'test';
# Testing CREATE TABLE
statement ok
CREATE TABLE main.main_table(j INTEGER);
statement ok
CREATE TABLE test_table(i INTEGER);
statement ok
CREATE TABLE out_of_path.oop_table(k INTEGER);
statement ok
SELECT * FROM test.test_table;
statement ok
SELECT * FROM test_table;
statement ok
SELECT * FROM main_table;
statement ok
SELECT * FROM out_of_path.oop_table;
statement error
SELECT * FROM out_of_path.test_table;
----
statement error
SELECT * FROM main.test_table;
----
# Testing INSERT, UPDATE and DELETE
statement error
INSERT INTO main.test_table (i) VALUES (1);
----
statement ok
INSERT INTO test_table (i) VALUES (1);
statement ok
INSERT INTO test.test_table (i) VALUES (2), (3);
statement ok
INSERT INTO main_table (j) VALUES (4);
statement ok
INSERT INTO main.main_table (j) VALUES (5), (6);
statement error
INSERT INTO oop_table (k) VALUES (7);
----
statement ok
INSERT INTO out_of_path.oop_table (k) VALUES (8), (9);
statement error
DELETE FROM main.test_table WHERE i=3;
----
statement error
DELETE FROM test.main_table WHERE i=5;
----
statement error
DELETE FROM oop_table WHERE k=8;
----
statement ok
DELETE FROM test.test_table WHERE i=1;
statement ok
DELETE FROM test_table WHERE i=2;
statement ok
DELETE FROM main.main_table WHERE j=4;
statement ok
DELETE FROM main_table WHERE j=5;
statement ok
DELETE FROM out_of_path.oop_table WHERE k=8;
query I
SELECT i FROM test_table;
----
3
query I
SELECT j FROM main.main_table;
----
6
query I
SELECT k FROM out_of_path.oop_table;
----
9
statement error
UPDATE main.test_table SET i=10 WHERE i=1;
----
statement ok
UPDATE test_table SET i=30 WHERE i=3;
statement ok
UPDATE test.test_table SET i=300 WHERE i=30;
statement ok
UPDATE main_table SET j=60 WHERE j=6;
statement ok
UPDATE main.main_table SET j=600 WHERE j=60;
query I
SELECT i FROM test_table;
----
300
query I
SELECT j FROM main_table;
----
600
# Testing temp table.
# test_temp_table should *not* be created in the test schema, but in the temp schema
statement ok
CREATE TEMP TABLE test_temp_table(i INTEGER);
statement error
SELECT * FROM memory.main.test_temp_table;
----
statement error
SELECT * FROM test.test_temp_table;
----
statement ok
SELECT * FROM test_temp_table;
statement ok
SELECT * FROM temp.test_temp_table;
# Testing functions and aggregates
query I
SELECT abs(i) FROM test_table;
----
300
# aggregates should work as expected
query I
SELECT sum(i) FROM test_table;
----
300
# Testing Views
statement ok
CREATE VIEW test_view AS SELECT * FROM test_table;
statement ok
CREATE VIEW main.main_view AS SELECT * FROM main.main_table;
statement ok
CREATE VIEW out_of_path.oop_view AS SELECT * FROM out_of_path.oop_table;
statement error
SELECT * FROM main.test_view;
----
statement ok
SELECT * FROM test.test_view;
statement ok
SELECT * FROM test_view;
statement ok
SELECT * FROM main.main_view;
statement ok
SELECT * FROM main_view;
statement error
SELECT * FROM oop_view;
----
statement ok
SELECT * FROM out_of_path.oop_view;
statement ok
SET SESSION schema = 'main';
# Test view's schema being bound on definition.
statement error
CREATE VIEW bad_test_view AS SELECT * FROM test_table;
----
# TODO(omo):
# Currenly this fails because we bind the table name
# when the view is actually used vs. defined.
# This behavior is incompatible with PG.
# statement ok
# SELECT * FROM test.test_view;
statement ok
SET SESSION schema = 'test';
statement error
DROP VIEW main.test_view
----
statement ok
DROP VIEW test_view
statement ok
DROP VIEW main_view
statement error
DROP VIEW oop_view
----
statement ok
DROP VIEW out_of_path.oop_view
# Testing Macros
statement ok
CREATE MACRO test_macro(a, b) AS a + b;
statement ok
CREATE MACRO test_macro2(c, d) AS c * d;
statement ok
CREATE MACRO main.main_macro(a, b) AS a - b;
statement ok
CREATE MACRO out_of_path.oop_macro(a, b) AS a * b;
statement error
SELECT main.test_macro(1, 2);
----
statement error
SELECT oop_macro(1, 2);
----
statement ok
SELECT main_macro(1, 2);
statement ok
SELECT main.main_macro(1, 2);
statement ok
SELECT test.test_macro(1, 2);
statement ok
SELECT test_macro(1, 2);
statement ok
SELECT out_of_path.oop_macro(1, 2);
statement error
DROP MACRO main.test_macro;
----
statement ok
DROP MACRO test_macro;
statement ok
DROP MACRO test.test_macro2;
statement ok
DROP MACRO main_macro;
statement error
DROP MACRO oop_macro;
----
statement ok
DROP MACRO out_of_path.oop_macro;
# Testing sequences.
statement ok
CREATE SEQUENCE test_sequence;
statement ok
CREATE SEQUENCE test_sequence2;
statement ok
CREATE SEQUENCE main.main_sequence;
statement ok
CREATE SEQUENCE out_of_path.oop_sequence;
statement error
SELECT main.nextval('main.test_sequence');
----
statement ok
SELECT main.nextval('test.test_sequence');
statement ok
SELECT main.nextval('test_sequence');
statement ok
SELECT main.nextval('main.main_sequence');
statement ok
SELECT main.nextval('main_sequence');
statement error
SELECT main.nextval('oop_sequence');
----
statement ok
SELECT main.nextval('out_of_path.oop_sequence');
statement error
DROP SEQUENCE main.test_sequence;
----
statement ok
DROP SEQUENCE test_sequence;
statement ok
DROP SEQUENCE test.test_sequence2;
statement ok
DROP SEQUENCE main_sequence;
statement error
DROP SEQUENCE oop_sequence;
----
statement ok
DROP SEQUENCE out_of_path.oop_sequence;
# Testing ALTER TABLE
statement error
ALTER TABLE main.test_table ADD COLUMN k INTEGER;
----
statement ok
ALTER TABLE main.main_table ADD COLUMN k INTEGER;
statement ok
ALTER TABLE main_table ADD COLUMN l INTEGER;
statement ok
ALTER TABLE test_table ADD COLUMN m INTEGER;
statement ok
ALTER TABLE test.test_table ADD COLUMN n INTEGER;
statement error
ALTER TABLE oop_table ADD COLUMN o INTEGER;
----
statement ok
ALTER TABLE out_of_path.oop_table ADD COLUMN p INTEGER;
# Testing DROP TABLE
statement error
DROP TABLE main.test_table;
----
statement error
DROP TABLE test.main_table;
----
statement ok
DROP TABLE test_table;
statement ok
DROP TABLE main_table;
statement error
DROP TABLE oop_table;
----
statement ok
DROP TABLE out_of_path.oop_table;
statement ok
CREATE TABLE test_table2(i INTEGER);
statement ok
DROP TABLE test.test_table2;
statement ok
CREATE TABLE test_table3(i INTEGER);
statement ok
DROP TABLE IF EXISTS test_table3;
statement ok
DROP TABLE IF EXISTS test_table3;
statement ok
CREATE TABLE test_table4(i INTEGER);
statement ok
DROP TABLE IF EXISTS test.test_table4;
statement ok
DROP TABLE IF EXISTS test.test_table4;
statement ok
CREATE TABLE main.main_table2(i INTEGER);
statement ok
DROP TABLE IF EXISTS main.main_table2;
statement ok
DROP TABLE IF EXISTS main.main_table2;

View File

@@ -0,0 +1,269 @@
# name: test/sql/catalog/test_set_search_path.test
# description: SET schema and SET search_path
# group: [catalog]
require skip_reload
# create a couple of schemas with a table each
statement ok
CREATE TABLE main_table(i INTEGER);
statement ok
CREATE SCHEMA test;
statement ok
CREATE TABLE test.test_table(i INTEGER);
statement ok
CREATE SCHEMA test2;
statement ok
CREATE TABLE test2.bye(i INTEGER);
statement ok
CREATE TABLE test2.test2_table(i INTEGER);
statement ok
CREATE SCHEMA test3;
statement ok
CREATE SCHEMA test4;
statement ok
CREATE SCHEMA test5;
statement ok
CREATE TABLE test5.test5_table(i INTEGER);
# Reading the config - It should be empty for now.
statement ok
SELECT CURRENT_SETTING('search_path');
statement ok
SELECT CURRENT_SETTING('schema');
# Setting the default value.
statement ok
SET SEARCH_PATH = 'test';
statement ok
SET SEARCH_PATH = 'test,test2';
statement ok
SET SEARCH_PATH = '"test","test2"';
statement ok
SET SEARCH_PATH = '"test","test2"';
statement error
SET SEARCH_PATH = 'does_not_exist';
----
<REGEX>:Catalog Error.*No catalog.*schema named.*
# Setting the default value through 'schema'
statement ok
SET SCHEMA = 'test';
statement error
SET SCHEMA = 'test,test2';
----
expected a single entry
statement error
SET SCHEMA = 'does_not_exist';
----
<REGEX>:Catalog Error.*No catalog.*schema named.*
# Reading out to see how aliasing works.
statement ok
SET SEARCH_PATH = 'test,test2';
statement error
SET SEARCH_PATH = '"invalid quoted string list';
----
<REGEX>:Parser Error.*Unterminated quote in qualified name.*
query I
SELECT MAIN.CURRENT_SETTING('search_path');
----
test,test2
query I
SELECT MAIN.CURRENT_SCHEMAS(false);
----
[test, test2]
query I
SELECT pg_catalog.CURRENT_SCHEMAS(false);
----
[test, test2]
statement ok
SET SCHEMA = 'test';
query I
SELECT MAIN.CURRENT_SETTING('search_path');
----
test
query I
SELECT MAIN.CURRENT_SCHEMA();
----
test
query I
SELECT pg_catalog.CURRENT_SCHEMA();
----
test
query I
SELECT current_schema();
----
test
query I
SELECT current_schemas(true);
----
[main, test, main, main, pg_catalog]
query I
SELECT current_schemas(false);
----
[test]
# Case insensitivity
statement ok
SET schema = 'test2';
query I
SELECT CURRENT_SETTING('search_path');
----
test2
statement ok
SET search_path = 'test3';
query I
SELECT CURRENT_SETTING('search_path');
----
test3
# Looking up from multiple schemas
statement ok
SET SEARCH_PATH = 'test,test2';
statement ok
SELECT i FROM test_table;
statement ok
SELECT i FROM test2_table;
statement ok
SELECT i FROM main_table;
statement ok
CREATE TABLE main.table_with_same_name(in_main INTEGER);
statement ok
CREATE TABLE test.table_with_same_name(in_test INTEGER);
statement ok
CREATE TABLE test2.table_with_same_name(in_test2 INTEGER);
statement error
SELECT in_main FROM table_with_same_name;
----
<REGEX>:Binder Error.*not found in FROM clause.*
statement error
SELECT in_test2 FROM table_with_same_name;
----
<REGEX>:Binder Error.*not found in FROM clause.*
statement ok
SELECT in_test FROM table_with_same_name;
# Or even more schemas
statement ok
SET SEARCH_PATH = 'test,test2,test3,test4,test5';
statement ok
SELECT i FROM test5_table;
statement ok
SELECT i FROM test_table;
statement ok
SELECT i FROM test2_table;
statement ok
SELECT i FROM main_table;
# Duplicate entry in the path (is allowed)
statement ok
SET SEARCH_PATH = 'test,test,test2';
statement ok
SELECT i FROM test_table;
statement ok
SELECT i FROM test2_table;
statement ok
SELECT i FROM main_table;
# Multiple connections
statement ok con1
SET schema = 'test';
statement ok con2
SET schema = 'test2';
statement ok con1
SELECT i FROM test_table;
statement error con2
SELECT i FROM test_table;
----
<REGEX>:Catalog Error.*does not exist.*
statement error con1
SELECT i FROM test2_table;
----
<REGEX>:Catalog Error.*does not exist.*
statement ok con2
SELECT i FROM test2_table;
# Same system functions in pg and duckdb
statement ok
SET search_path = pg_catalog;
statement ok
SELECT current_database();
statement ok
SELECT current_catalog();
query I
SELECT current_schema();
----
pg_catalog
query I
SELECT current_schemas(true);
----
[main, pg_catalog, main, main, pg_catalog]
query I
SELECT current_query();
----
SELECT current_query();

View File

@@ -0,0 +1,79 @@
# name: test/sql/catalog/test_standard_schema.test
# description: Schema creation/deletion
# group: [catalog]
# cannot drop MAIN schema
statement error
DROP SCHEMA main CASCADE;
----
<REGEX>:.*Catalog Error: Cannot drop entry.*
# create and drop an empty schema
statement ok
CREATE SCHEMA test;
statement ok
DROP SCHEMA test;
# create the schema again
statement ok
CREATE SCHEMA test;
# duplicate schema
statement error
CREATE SCHEMA test;
----
<REGEX>:.*Catalog Error.*already exists.*
# if not exists ignores error
statement ok
CREATE SCHEMA IF NOT EXISTS test;
# create table inside schema that exists should succeed
statement ok
CREATE TABLE test.hello(i INTEGER);
# create table inside schema that does not exist should fail
statement error
CREATE TABLE test2.hello(i INTEGER);
----
<REGEX>:.*Catalog Error.*does not exist.*
# use the table in queries
# insert into table
statement ok
INSERT INTO test.hello VALUES (2), (3), (4)
# select from table without schema specified should fail
statement error
SELECT * FROM hello
----
<REGEX>:.*Catalog Error.*does not exist.*
# with schema specified should succeed
query I
SELECT * FROM test.hello
----
2
3
4
# drop schema with dependencies should fail
statement error
DROP SCHEMA test;
----
<REGEX>:.*Dependency Error: Cannot drop entry.*
# unless we use cascade to drop
statement ok
DROP SCHEMA test CASCADE;
# drop schema if exists should not fail if schema does not exist
statement ok
DROP SCHEMA IF EXISTS test;
# but drop schema without it should fail
statement error
DROP SCHEMA test;
----
<REGEX>:.*Catalog Error.*does not exist.*

View File

@@ -0,0 +1,163 @@
# name: test/sql/catalog/test_temporary.test
# description: Test temporary catalog entry creation
# group: [catalog]
# basic temp table creation works
statement ok
CREATE TEMPORARY TABLE integers(i INTEGER) ON COMMIT PRESERVE ROWS
# we can (but never are required to) prefix temp tables with "temp" schema
statement ok
CREATE TEMPORARY TABLE integersx(i INTEGER)
# we don't support temporary schemas (yet?)
#statement error
#CREATE TEMPORARY SCHEMA asdf
# we can prefix temp tables with a schema that is not "temp"
statement ok
CREATE TEMPORARY TABLE main.integersy(i INTEGER)
statement ok
CREATE TEMPORARY TABLE s1 AS SELECT 42
query I
SELECT * FROM temp.s1
----
42
query I
SELECT * FROM s1
----
42
statement error
CREATE TABLE temp.integersy(i INTEGER)
----
<REGEX>:.*Parser Error.*Only TEMPORARY.*
statement ok
CREATE SCHEMA temp
statement error
CREATE TABLE temp.integersy(i INTEGER)
----
<REGEX>:.*Binder Error.*Ambiguous reference.*
statement ok
CREATE TABLE memory.temp.integersy(i INTEGER)
statement ok
DROP SCHEMA temp CASCADE
statement error
DROP TABLE memory.main.integersx
----
<REGEX>:.*Catalog Error.*does not exist.*
statement ok
DROP TABLE integersx
statement ok
CREATE TEMPORARY TABLE temp.integersx(i INTEGER)
statement ok
DROP TABLE temp.integersx
# unsupported
statement error
CREATE TEMPORARY TABLE integers2(i INTEGER) ON COMMIT DELETE ROWS
----
<REGEX>:.*Not implemented Error: Only ON COMMIT.*
# temp table already exists
statement error
CREATE TEMPORARY TABLE integers(i INTEGER)
----
<REGEX>:.*Catalog Error.*already exists.*
statement ok
INSERT INTO integers VALUES (42)
query I
SELECT i from integers
----
42
# temp table survives commit
statement ok
BEGIN TRANSACTION
statement ok
CREATE TEMPORARY TABLE integers2(i INTEGER)
statement ok
CREATE TEMPORARY SEQUENCE seq
statement ok
CREATE TEMPORARY VIEW v1 AS SELECT 42
statement ok
INSERT INTO integers2 VALUES (42)
query I
SELECT i from integers2
----
42
query I
SELECT nextval('seq')
----
1
query I
SELECT * from v1
----
42
statement ok
COMMIT
query I
SELECT i from integers2
----
42
query I
SELECT nextval('seq')
----
2
query I
SELECT * from v1
----
42
# temp table does not survive rollback
statement ok
BEGIN TRANSACTION
statement ok
CREATE TEMPORARY TABLE integers3(i INTEGER)
statement ok
INSERT INTO integers3 VALUES (42)
query I
SELECT i from integers3
----
42
statement ok
ROLLBACK
statement error
SELECT i from integers3
----
<REGEX>:.*Catalog Error.*does not exist.*
# table is not visible to other cons
statement error con2
INSERT INTO integers VALUES (42)
----
<REGEX>:.*Catalog Error.*does not exist.*

View File

@@ -0,0 +1,46 @@
# name: test/sql/catalog/test_unicode_schema.test
# description: Unicode schema
# group: [catalog]
statement ok
CREATE TABLE 👤(🔑 INTEGER PRIMARY KEY, 🗣 varchar(64), 🗓 DATE);
statement ok
CREATE TABLE (🔑 INTEGER PRIMARY KEY, 🗣 varchar(64));
statement ok
CREATE TABLE 📕(🔑 INTEGER PRIMARY KEY, 💬 varchar(64), 🔖 varchar(64), INTEGER);
statement ok
CREATE TABLE 👤🏠📕(👤 INTEGER, 📕 INTEGER, TEXT);
statement ok
INSERT INTO 👤 VALUES (1, 'Jeff', '2019-01-01'), (2, 'Annie', '2019-01-01');
statement ok
INSERT INTO VALUES (1, 'Herman Melville'), (2, 'Lewis Carroll');
statement ok
INSERT INTO 📕 VALUES (1, 'Alice in Wonderland', '🔮', 2), (2, 'Moby Dick', '📖', 1), (3, 'Through the Looking-Glass', '🔮', 2);
statement ok
INSERT INTO 👤🏠📕 VALUES (1, 1, '😍'), (1, 2, '🤢'), (2, 2, '🙂');
query TT
SELECT 👤.🗣 AS 👤, 📕.💬 AS 📕 FROM 👤 JOIN 👤🏠📕 ON 👤.🔑 = 👤🏠📕.👤 JOIN 📕 ON 📕.🔑 = 👤🏠📕.📕 ORDER BY 👤, 📕;
----
Annie Moby Dick
Jeff Alice in Wonderland
Jeff Moby Dick
query TT
SELECT 👤.🗣, 👤🏠📕. FROM 👤🏠📕 JOIN 📕 ON 👤🏠📕.📕 = 📕.🔑 JOIN 👤 ON 👤🏠📕.👤=👤.🔑 WHERE 📕.💬 = 'Moby Dick' ORDER BY 👤.🗣;
----
Annie 🙂
Jeff 🤢
query TT
SELECT type, name FROM sqlite_master WHERE name='👤' ORDER BY name;
----
table 👤

View File

@@ -0,0 +1,39 @@
# name: test/sql/catalog/view/recursive_view.test
# description: Issue #3017: Querying View of a View Crashes
# group: [view]
statement ok
set storage_compatibility_version='v0.10.2'
statement ok
CREATE TABLE IF NOT EXISTS test (val INTEGER);
statement ok
INSERT INTO test(val) VALUES (1), (2), (3);
# recursive view definition
statement ok
CREATE OR REPLACE VIEW foo AS (SELECT * FROM test);
statement ok
CREATE OR REPLACE VIEW foo AS (SELECT * FROM foo);
statement error
SELECT * FROM foo;
----
<REGEX>:.*Binder Error.*infinite recursion detected.*
# more complex recursive view definition
statement ok
CREATE OR REPLACE VIEW foo AS (SELECT * FROM test);
statement ok
CREATE OR REPLACE VIEW foo2 AS (SELECT * FROM foo);
statement ok
CREATE OR REPLACE VIEW foo AS (SELECT (SELECT * FROM foo2));
statement error
SELECT * FROM foo;
----
<REGEX>:.*Binder Error.*infinite recursion detected.*

Some files were not shown because too many files have changed in this diff Show More