-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DuckDB complains when it receives parameters that were not actually used in the query. From Postgres we get all supplied parameters though. So this changes the code to filter the unused ones out. To do this we lot DuckDB parse the query and tell us which parameters it expects, and then we remove the unexpected ones. Fixes #411 Fixes #234 Co-authored-by: Zhou Sun <[email protected]>
- Loading branch information
1 parent
44b292a
commit 04be407
Showing
6 changed files
with
444 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
CREATE TABLE ta(a integer); | ||
INSERT INTO ta VALUES(125); | ||
-- test procedure | ||
CREATE OR REPLACE PROCEDURE protest(b INT) | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
va integer; | ||
BEGIN | ||
SELECT * INTO va FROM ta WHERE a = b; | ||
RAISE NOTICE '%', va * 2; | ||
END; | ||
$$; | ||
CALL protest(1); -- null | ||
NOTICE: <NULL> | ||
CALL protest(125); -- 250 | ||
NOTICE: 250 | ||
-- test function | ||
CREATE OR REPLACE FUNCTION functest(b INT) | ||
RETURNS integer | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
va integer; | ||
BEGIN | ||
SELECT * INTO va FROM ta WHERE a = b; | ||
RETURN va * 2; | ||
END; | ||
$$; | ||
SELECT functest(124); -- null | ||
functest | ||
---------- | ||
|
||
(1 row) | ||
|
||
SELECT functest(125); -- 250 | ||
functest | ||
---------- | ||
250 | ||
(1 row) | ||
|
||
CREATE TABLE tb(a int DEFAULT 1, b text, c varchar DEFAULT 'pg_duckdb'); | ||
INSERT INTO tb(a, b) VALUES(1, 'test'); | ||
INSERT INTO tb VALUES(2, 'test2', 'pg_duckdb_test'); | ||
CREATE OR REPLACE FUNCTION functest2(va INT, vc varchar) | ||
RETURNS text | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
vb text; | ||
BEGIN | ||
SELECT b INTO vb FROM tb WHERE a = va and c = vc; | ||
RETURN vb; | ||
END; | ||
$$; | ||
SELECT functest2(1, 'pg_duckdb'); -- test | ||
functest2 | ||
----------- | ||
test | ||
(1 row) | ||
|
||
CREATE OR REPLACE PROCEDURE protest2(va INT, vb text) | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
vc varchar; | ||
BEGIN | ||
SELECT c INTO vc FROM tb WHERE a = va and b = vb; | ||
RAISE NOTICE '%', vc; | ||
END; | ||
$$; | ||
CALL protest2(2, 'test2'); -- pg_duckdb_test | ||
NOTICE: pg_duckdb_test | ||
DROP TABLE ta, tb; | ||
DROP FUNCTION functest, functest2; | ||
DROP PROCEDURE protest, protest2; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
-- the view should return the empty | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements; | ||
name | statement | parameter_types | ||
------+-----------+----------------- | ||
(0 rows) | ||
|
||
CREATE TABLE copy_database(datname text, datistemplate boolean, datallowconn boolean); | ||
INSERT INTO copy_database SELECT datname, datistemplate, datallowconn FROM pg_database; | ||
-- parameterized queries | ||
PREPARE q1(text) AS | ||
SELECT datname, datistemplate, datallowconn | ||
FROM copy_database WHERE datname = $1; | ||
EXECUTE q1('postgres'); | ||
datname | datistemplate | datallowconn | ||
----------+---------------+-------------- | ||
postgres | f | t | ||
(1 row) | ||
|
||
-- q1 | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+-----------------------------------------------------+----------------- | ||
q1 | PREPARE q1(text) AS +| {text} | ||
| SELECT datname, datistemplate, datallowconn+| | ||
| FROM copy_database WHERE datname = $1; | | ||
(1 row) | ||
|
||
CREATE TABLE ta(a int); | ||
INSERT INTO ta(a) SELECT * FROM generate_series(1, 1000); | ||
SELECT COUNT(*) FROM ta; | ||
count | ||
------- | ||
1000 | ||
(1 row) | ||
|
||
PREPARE q2 AS SELECT COUNT(*) FROM ta; | ||
EXECUTE q2; | ||
count | ||
------- | ||
1000 | ||
(1 row) | ||
|
||
-- q1 q2 | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+-----------------------------------------------------+----------------- | ||
q1 | PREPARE q1(text) AS +| {text} | ||
| SELECT datname, datistemplate, datallowconn+| | ||
| FROM copy_database WHERE datname = $1; | | ||
q2 | PREPARE q2 AS SELECT COUNT(*) FROM ta; | {} | ||
(2 rows) | ||
|
||
PREPARE q3(int) AS | ||
SELECT * FROM ta WHERE a = $1; | ||
CREATE TEMPORARY TABLE q3_prep_results AS EXECUTE q3(200); | ||
SELECT * FROM q3_prep_results; | ||
a | ||
----- | ||
200 | ||
(1 row) | ||
|
||
-- q1 q2 q3 | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+-----------------------------------------------------+----------------- | ||
q1 | PREPARE q1(text) AS +| {text} | ||
| SELECT datname, datistemplate, datallowconn+| | ||
| FROM copy_database WHERE datname = $1; | | ||
q2 | PREPARE q2 AS SELECT COUNT(*) FROM ta; | {} | ||
q3 | PREPARE q3(int) AS +| {integer} | ||
| SELECT * FROM ta WHERE a = $1; | | ||
(3 rows) | ||
|
||
CREATE TABLE tb (a int DEFAULT 1, b int, c varchar DEFAULT 'pg_duckdb'); | ||
INSERT INTO tb(b) VALUES(2); | ||
PREPARE q4(int, varchar) AS | ||
SELECT b FROM tb WHERE a = $1 AND c = $2; | ||
EXECUTE q4(1, 'pg_duckdb'); | ||
b | ||
--- | ||
2 | ||
(1 row) | ||
|
||
EXECUTE q4(1, 'pg_duckdb'); | ||
b | ||
--- | ||
2 | ||
(1 row) | ||
|
||
-- q1 q2 q3 q4 | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+-----------------------------------------------------+------------------------------- | ||
q1 | PREPARE q1(text) AS +| {text} | ||
| SELECT datname, datistemplate, datallowconn+| | ||
| FROM copy_database WHERE datname = $1; | | ||
q2 | PREPARE q2 AS SELECT COUNT(*) FROM ta; | {} | ||
q3 | PREPARE q3(int) AS +| {integer} | ||
| SELECT * FROM ta WHERE a = $1; | | ||
q4 | PREPARE q4(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1 AND c = $2; | | ||
(4 rows) | ||
|
||
TRUNCATE tb; | ||
INSERT INTO tb VALUES(10, 10, 'test'); | ||
INSERT INTO tb VALUES(100, 100, 'pg_duckdb'); | ||
PREPARE q5(int, varchar) AS | ||
SELECT b FROM tb WHERE a = $1 AND b = $1 AND c = $2; | ||
EXECUTE q5(10, 'test'); | ||
b | ||
---- | ||
10 | ||
(1 row) | ||
|
||
EXECUTE q5(100, 'pg_duckdb'); | ||
b | ||
----- | ||
100 | ||
(1 row) | ||
|
||
-- q1 q2 q3 q4 q5 | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+--------------------------------------------------------------+------------------------------- | ||
q1 | PREPARE q1(text) AS +| {text} | ||
| SELECT datname, datistemplate, datallowconn +| | ||
| FROM copy_database WHERE datname = $1; | | ||
q2 | PREPARE q2 AS SELECT COUNT(*) FROM ta; | {} | ||
q3 | PREPARE q3(int) AS +| {integer} | ||
| SELECT * FROM ta WHERE a = $1; | | ||
q4 | PREPARE q4(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1 AND c = $2; | | ||
q5 | PREPARE q5(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1 AND b = $1 AND c = $2; | | ||
(5 rows) | ||
|
||
PREPARE q6(int, varchar) AS | ||
SELECT b FROM tb WHERE c = $2; | ||
EXECUTE q6(10, 'test'); | ||
b | ||
---- | ||
10 | ||
(1 row) | ||
|
||
-- q1 q2 q3 q4 q5 q6 | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+--------------------------------------------------------------+------------------------------- | ||
q1 | PREPARE q1(text) AS +| {text} | ||
| SELECT datname, datistemplate, datallowconn +| | ||
| FROM copy_database WHERE datname = $1; | | ||
q2 | PREPARE q2 AS SELECT COUNT(*) FROM ta; | {} | ||
q3 | PREPARE q3(int) AS +| {integer} | ||
| SELECT * FROM ta WHERE a = $1; | | ||
q4 | PREPARE q4(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1 AND c = $2; | | ||
q5 | PREPARE q5(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1 AND b = $1 AND c = $2; | | ||
q6 | PREPARE q6(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE c = $2; | | ||
(6 rows) | ||
|
||
PREPARE q7(int, varchar) AS | ||
SELECT b FROM tb WHERE a = $1; | ||
EXECUTE q7(100, 'pg_duckdb'); | ||
b | ||
----- | ||
100 | ||
(1 row) | ||
|
||
-- q1 q2 q3 q4 q5 q6 q7 | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+--------------------------------------------------------------+------------------------------- | ||
q1 | PREPARE q1(text) AS +| {text} | ||
| SELECT datname, datistemplate, datallowconn +| | ||
| FROM copy_database WHERE datname = $1; | | ||
q2 | PREPARE q2 AS SELECT COUNT(*) FROM ta; | {} | ||
q3 | PREPARE q3(int) AS +| {integer} | ||
| SELECT * FROM ta WHERE a = $1; | | ||
q4 | PREPARE q4(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1 AND c = $2; | | ||
q5 | PREPARE q5(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1 AND b = $1 AND c = $2; | | ||
q6 | PREPARE q6(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE c = $2; | | ||
q7 | PREPARE q7(int, varchar) AS +| {integer,"character varying"} | ||
| SELECT b FROM tb WHERE a = $1; | | ||
(7 rows) | ||
|
||
-- test DEALLOCATE ALL; | ||
DEALLOCATE ALL; | ||
SELECT name, statement, parameter_types FROM pg_prepared_statements | ||
ORDER BY name; | ||
name | statement | parameter_types | ||
------+-----------+----------------- | ||
(0 rows) | ||
|
||
DROP TABLE copy_database, ta, tb; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,3 +24,5 @@ test: altered_tables | |
test: transactions | ||
test: transaction_errors | ||
test: secrets | ||
test: prepare | ||
test: function |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
CREATE TABLE ta(a integer); | ||
INSERT INTO ta VALUES(125); | ||
|
||
-- test procedure | ||
CREATE OR REPLACE PROCEDURE protest(b INT) | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
va integer; | ||
BEGIN | ||
SELECT * INTO va FROM ta WHERE a = b; | ||
RAISE NOTICE '%', va * 2; | ||
END; | ||
$$; | ||
|
||
CALL protest(1); -- null | ||
CALL protest(125); -- 250 | ||
|
||
-- test function | ||
CREATE OR REPLACE FUNCTION functest(b INT) | ||
RETURNS integer | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
va integer; | ||
BEGIN | ||
SELECT * INTO va FROM ta WHERE a = b; | ||
RETURN va * 2; | ||
END; | ||
$$; | ||
|
||
SELECT functest(124); -- null | ||
SELECT functest(125); -- 250 | ||
|
||
CREATE TABLE tb(a int DEFAULT 1, b text, c varchar DEFAULT 'pg_duckdb'); | ||
INSERT INTO tb(a, b) VALUES(1, 'test'); | ||
INSERT INTO tb VALUES(2, 'test2', 'pg_duckdb_test'); | ||
|
||
CREATE OR REPLACE FUNCTION functest2(va INT, vc varchar) | ||
RETURNS text | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
vb text; | ||
BEGIN | ||
SELECT b INTO vb FROM tb WHERE a = va and c = vc; | ||
RETURN vb; | ||
END; | ||
$$; | ||
|
||
SELECT functest2(1, 'pg_duckdb'); -- test | ||
|
||
CREATE OR REPLACE PROCEDURE protest2(va INT, vb text) | ||
LANGUAGE plpgsql | ||
AS $$ | ||
DECLARE | ||
vc varchar; | ||
BEGIN | ||
SELECT c INTO vc FROM tb WHERE a = va and b = vb; | ||
RAISE NOTICE '%', vc; | ||
END; | ||
$$; | ||
|
||
CALL protest2(2, 'test2'); -- pg_duckdb_test | ||
|
||
DROP TABLE ta, tb; | ||
DROP FUNCTION functest, functest2; | ||
DROP PROCEDURE protest, protest2; |
Oops, something went wrong.