Skip to content

Commit 749203f

Browse files
author
Yuwei Xiao
committed
more regress
1 parent 1b84967 commit 749203f

File tree

3 files changed

+119
-12
lines changed

3 files changed

+119
-12
lines changed

src/pgduckdb_planner.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,18 @@ extern "C" {
3737
#include "pgduckdb/pgduckdb_node.hpp"
3838
#include "pgduckdb/vendor/pg_list.hpp"
3939
#include "pgduckdb/utility/cpp_wrapper.hpp"
40+
#include "pgduckdb/pgduckdb_guc.h"
4041
#include "pgduckdb/pgduckdb_types.hpp"
4142

4243
bool
4344
IsAllowedPostgresInsert(Query *query, bool throw_error) {
45+
if (query->commandType == CMD_SELECT) {
46+
return false;
47+
}
48+
4449
int elevel = throw_error ? ERROR : DEBUG4;
4550
if (query->commandType != CMD_INSERT) {
46-
elog(elevel, "DuckDB only supports INSERT/SELECT on Postgres tables");
51+
elog(duckdb_log_pg_explain ? NOTICE : elevel, "DuckDB only supports INSERT/SELECT on Postgres tables");
4752
return false;
4853
}
4954

@@ -62,11 +67,10 @@ IsAllowedPostgresInsert(Query *query, bool throw_error) {
6267
}
6368

6469
if (!select_rte) {
65-
elog(elevel, "DuckDB does not support INSERT without a subquery");
70+
elog(duckdb_log_pg_explain ? NOTICE : elevel, "DuckDB does not support INSERT without a subquery");
6671
return false;
6772
}
68-
69-
/* TODO: Checking supported target column types */
73+
7074
Relation rel = RelationIdGetRelation(target_rel->relid);
7175
TupleDesc target_desc = RelationGetDescr(rel);
7276
bool ret = true;
@@ -76,9 +80,15 @@ IsAllowedPostgresInsert(Query *query, bool throw_error) {
7680
continue;
7781
}
7882

79-
if (attr->atttypid == BYTEAOID || attr->atttypid == XMLOID || pgduckdb::pg::IsDomainType(attr->atttypid) ||
80-
pgduckdb::pg::IsArrayType(attr->atttypid)) {
81-
elog(elevel, "DuckDB does not support INSERT/SELECT on BYTEA/ARRAY columns");
83+
/*
84+
* Check if the target column type is supported by pg_duckdb. The type is allowed as long as the type conversion
85+
* is implemented.
86+
*/
87+
auto duckdb_col_type = pgduckdb::ConvertPostgresToDuckColumnType(attr);
88+
if (duckdb_col_type.id() == duckdb::LogicalTypeId::USER) {
89+
elog(duckdb_log_pg_explain ? NOTICE : elevel,
90+
"DuckDB does not support INSERTs into tables with column `%s` of unsupported type (OID %u). ",
91+
NameStr(attr->attname), attr->atttypid);
8292
ret = false;
8393
break;
8494
}
@@ -232,7 +242,7 @@ CreatePlan(Query *query, bool throw_error) {
232242
}
233243

234244
if (IsAllowedPostgresInsert(query)) {
235-
RangeTblEntry *target_rel = (RangeTblEntry *)list_nth(query->rtable, query->resultRelation - 1);
245+
RangeTblEntry *target_rel = (RangeTblEntry *)list_nth(query->rtable, query->resultRelation - 1);
236246
Relation rel = RelationIdGetRelation(target_rel->relid);
237247
TupleDesc pg_tupdesc = RelationGetDescr(rel);
238248

@@ -317,7 +327,7 @@ CoerceTargetList(List *duckdb_targetlist, TupleDesc pg_tupdesc) {
317327
if (expr == NULL)
318328
elog(ERROR, "cannot coerce column %d from type %u to target type %u", attnum, sourceTypeId,
319329
targetTypeId);
320-
330+
321331
/* Create a new target entry with coerced expression */
322332
TargetEntry *new_te = makeTargetEntry(expr, attnum, source_te->resname, source_te->resjunk);
323333
ret = lappend(ret, new_te);

test/regression/expected/postgres_insert_select.out

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,17 @@ INSERT INTO tbl select r['a']::int, r['b'] from duckdb.query($$ SELECT 11 a, 'de
3939
INSERT INTO tbl select r['a']::int, r['b'] from duckdb.query($$ SELECT 21 a, 'ghi' b $$) r;
4040
ERROR: no partition of relation "tbl" found for row
4141
DETAIL: Partition key of the failing row contains (a) = (21).
42-
SELECT * FROM tbl ORDER BY a LIMIT 5;
42+
SELECT * FROM tbl_p1 ORDER BY a;
43+
a | b
44+
---+-----
45+
1 | abc
46+
(1 row)
47+
48+
SELECT * FROM tbl_p2 ORDER BY a;
4349
a | b
4450
----+-----
45-
1 | abc
4651
11 | def
47-
(2 rows)
52+
(1 row)
4853

4954
DROP TABLE tbl;
5055
-- case: INSERT INTO TABLE (col1, col3)
@@ -101,3 +106,67 @@ SELECT * FROM tbl;
101106
(4 rows)
102107

103108
DROP TABLE tbl;
109+
CREATE TABLE tbl (a INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, b text);
110+
INSERT INTO tbl (b) SELECT 'foo' FROM generate_series(1, 2);
111+
INSERT INTO tbl (b) SELECT 'qux' FROM generate_series(1, 4);;
112+
SELECT * FROM tbl;
113+
a | b
114+
---+-----
115+
1 | foo
116+
2 | foo
117+
3 | qux
118+
4 | qux
119+
5 | qux
120+
6 | qux
121+
(6 rows)
122+
123+
DROP TABLE tbl;
124+
CREATE TABLE tbl (a SERIAL PRIMARY KEY, b text);
125+
INSERT INTO tbl (b) SELECT 'foo' FROM generate_series(1, 2);
126+
INSERT INTO tbl (b) SELECT 'qux' FROM generate_series(1, 4);;
127+
SELECT * FROM tbl;
128+
a | b
129+
---+-----
130+
1 | foo
131+
2 | foo
132+
3 | qux
133+
4 | qux
134+
5 | qux
135+
6 | qux
136+
(6 rows)
137+
138+
DROP TABLE tbl;
139+
-- case: ARRAY / JSON type
140+
CREATE TABLE tbl (a int, b text[], c jsonb);
141+
CREATE TABLE tbl1 (a int, b text[], c jsonb);
142+
INSERT INTO tbl (a, b, c) VALUES (1, ARRAY ['foo', 'bar'], '{"a": 1, "b": 2}');
143+
INSERT INTO tbl1 SELECT * FROM tbl;
144+
SELECT * FROM tbl1;
145+
a | b | c
146+
---+-----------+------------------
147+
1 | {foo,bar} | {"a": 1, "b": 2}
148+
(1 row)
149+
150+
DROP TABLE tbl, tbl1;
151+
-- case: UPDATE/DELETE should be blocked
152+
SET duckdb.log_pg_explain to on;
153+
CREATE TABLE tbl (a int PRIMARY KEY, b text);
154+
INSERT INTO tbl (a, b) SELECT i, 'foo' FROM generate_series(1, 3) i;
155+
UPDATE tbl SET b = 'bar' WHERE a = 1;
156+
NOTICE: DuckDB only supports INSERT/SELECT on Postgres tables
157+
DELETE FROM tbl WHERE a = 1;
158+
NOTICE: DuckDB only supports INSERT/SELECT on Postgres tables
159+
-- INSERT without subquery should also be blocked
160+
INSERT INTO tbl (a, b) VALUES (1, 'foo');
161+
NOTICE: DuckDB does not support INSERT without a subquery
162+
DROP TABLE tbl;
163+
SET duckdb.log_pg_explain to off;
164+
-- case: UNSUPPORTED TYPE
165+
CREATE TABLE tbl (a int, b xml);
166+
CREATE TABLE tbl1 (a int, b xml);
167+
INSERT INTO tbl (a, b) VALUES (1, '<xml>foo</xml>');
168+
SET duckdb.log_pg_explain to on;
169+
INSERT INTO tbl1 SELECT * FROM tbl;
170+
NOTICE: DuckDB does not support INSERTs into tables with column `b` of unsupported type (OID 142).
171+
DROP TABLE tbl, tbl1;
172+
SET duckdb.log_pg_explain to off;

test/regression/sql/postgres_insert_select.sql

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,31 @@ INSERT INTO tbl (b) SELECT 'foo' FROM generate_series(1, 2);
6161
INSERT INTO tbl (b) SELECT 'qux' FROM generate_series(1, 4);;
6262
SELECT * FROM tbl;
6363
DROP TABLE tbl;
64+
65+
-- case: ARRAY / JSON type
66+
CREATE TABLE tbl (a int, b text[], c jsonb);
67+
CREATE TABLE tbl1 (a int, b text[], c jsonb);
68+
INSERT INTO tbl (a, b, c) VALUES (1, ARRAY ['foo', 'bar'], '{"a": 1, "b": 2}');
69+
INSERT INTO tbl1 SELECT * FROM tbl;
70+
SELECT * FROM tbl1;
71+
DROP TABLE tbl, tbl1;
72+
73+
-- case: UPDATE/DELETE should be blocked
74+
SET duckdb.log_pg_explain to on;
75+
CREATE TABLE tbl (a int PRIMARY KEY, b text);
76+
INSERT INTO tbl (a, b) SELECT i, 'foo' FROM generate_series(1, 3) i;
77+
UPDATE tbl SET b = 'bar' WHERE a = 1;
78+
DELETE FROM tbl WHERE a = 1;
79+
-- INSERT without subquery should also be blocked
80+
INSERT INTO tbl (a, b) VALUES (1, 'foo');
81+
DROP TABLE tbl;
82+
SET duckdb.log_pg_explain to off;
83+
84+
-- case: UNSUPPORTED TYPE
85+
CREATE TABLE tbl (a int, b xml);
86+
CREATE TABLE tbl1 (a int, b xml);
87+
INSERT INTO tbl (a, b) VALUES (1, '<xml>foo</xml>');
88+
SET duckdb.log_pg_explain to on;
89+
INSERT INTO tbl1 SELECT * FROM tbl;
90+
DROP TABLE tbl, tbl1;
91+
SET duckdb.log_pg_explain to off;

0 commit comments

Comments
 (0)