From e226023e610fa0a901d0114173cc037653258c3e Mon Sep 17 00:00:00 2001 From: sqyyeah <948885883@qq.com> Date: Thu, 27 Aug 2020 10:21:30 +0800 Subject: [PATCH] postgres_fdw supports column serial --- .../optimizer/commands/sequence.cpp | 3 +- src/test/regress/output/postgres_fdw.source | 303 +++++++----------- 2 files changed, 124 insertions(+), 182 deletions(-) diff --git a/src/gausskernel/optimizer/commands/sequence.cpp b/src/gausskernel/optimizer/commands/sequence.cpp index eeeb1ffb5..bf4950867 100755 --- a/src/gausskernel/optimizer/commands/sequence.cpp +++ b/src/gausskernel/optimizer/commands/sequence.cpp @@ -2090,7 +2090,8 @@ static void process_owned_by(const Relation seqrel, List* owned_by) /* Must be a regular table */ if (tablerel->rd_rel->relkind != RELKIND_RELATION && - !(tablerel->rd_rel->relkind == RELKIND_FOREIGN_TABLE && isMOTFromTblOid(RelationGetRelid(tablerel)))) + !(tablerel->rd_rel->relkind == RELKIND_FOREIGN_TABLE && (isMOTFromTblOid(RelationGetRelid(tablerel)) || + isPostgresFDWFromTblOid(RelationGetRelid(tablerel))))) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("referenced relation \"%s\" is not a table", RelationGetRelationName(tablerel)))); diff --git a/src/test/regress/output/postgres_fdw.source b/src/test/regress/output/postgres_fdw.source index 53d7154fe..8e6b8be7a 100644 --- a/src/test/regress/output/postgres_fdw.source +++ b/src/test/regress/output/postgres_fdw.source @@ -2868,33 +2868,34 @@ NOTICE: CREATE TABLE will create implicit sequence "loc1_f1_seq" for serial col create foreign table rem1 (f1 serial, f2 text) server loopback options(table_name 'loc1'); NOTICE: CREATE FOREIGN TABLE will create implicit sequence "rem1_f1_seq" for serial column "rem1.f1" -ERROR: referenced relation "rem1" is not a table select pg_catalog.setval('rem1_f1_seq', 10, false); -ERROR: relation "rem1_f1_seq" does not exist -LINE 1: select pg_catalog.setval('rem1_f1_seq', 10, false); - ^ -CONTEXT: referenced column: setval + setval +-------- + 10 +(1 row) + insert into loc1(f2) values('hi'); insert into rem1(f2) values('hi remote'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: insert into rem1(f2) values('hi remote'); - ^ insert into loc1(f2) values('bye'); insert into rem1(f2) values('bye remote'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: insert into rem1(f2) values('bye remote'); - ^ select * from loc1; - f1 | f2 -----+----- + f1 | f2 +----+------------ 1 | hi + 10 | hi remote 2 | bye -(2 rows) + 11 | bye remote +(4 rows) select * from rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: select * from rem1; - ^ + f1 | f2 +----+------------ + 1 | hi + 10 | hi remote + 2 | bye + 11 | bye remote +(4 rows) + -- =================================================================== -- test local triggers -- =================================================================== @@ -2907,10 +2908,10 @@ BEGIN END;$$; CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1 FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1 FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpgsql AS $$ @@ -2953,97 +2954,67 @@ $$; CREATE TRIGGER trig_row_before BEFORE INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view CREATE TRIGGER trig_row_after AFTER INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view delete from rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: delete from rem1; - ^ insert into rem1 values(1,'insert'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: insert into rem1 values(1,'insert'); - ^ update rem1 set f2 = 'update' where f1 = 1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: update rem1 set f2 = 'update' where f1 = 1; - ^ update rem1 set f2 = f2 || f2; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: update rem1 set f2 = f2 || f2; - ^ -- cleanup DROP TRIGGER trig_row_before ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_before" for table "rem1" does not exist DROP TRIGGER trig_row_after ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_after" for table "rem1" does not exist DROP TRIGGER trig_stmt_before ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_stmt_before" for table "rem1" does not exist DROP TRIGGER trig_stmt_after ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_stmt_after" for table "rem1" does not exist DELETE from rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: DELETE from rem1; - ^ -- Test WHEN conditions CREATE TRIGGER trig_row_before_insupd BEFORE INSERT OR UPDATE ON rem1 FOR EACH ROW WHEN (NEW.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view CREATE TRIGGER trig_row_after_insupd AFTER INSERT OR UPDATE ON rem1 FOR EACH ROW WHEN (NEW.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view -- Insert or update not matching: nothing happens INSERT INTO rem1 values(1, 'insert'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 values(1, 'insert'); - ^ UPDATE rem1 set f2 = 'test'; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 set f2 = 'test'; - ^ -- Insert or update matching: triggers are fired INSERT INTO rem1 values(2, 'update'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 values(2, 'update'); - ^ UPDATE rem1 set f2 = 'update update' where f1 = '2'; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 set f2 = 'update update' where f1 = '2'; - ^ CREATE TRIGGER trig_row_before_delete BEFORE DELETE ON rem1 FOR EACH ROW WHEN (OLD.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view CREATE TRIGGER trig_row_after_delete AFTER DELETE ON rem1 FOR EACH ROW WHEN (OLD.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view -- Trigger is fired for f1=2, not for f1=1 DELETE FROM rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: DELETE FROM rem1; - ^ -- cleanup DROP TRIGGER trig_row_before_insupd ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_before_insupd" for table "rem1" does not exist DROP TRIGGER trig_row_after_insupd ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_after_insupd" for table "rem1" does not exist DROP TRIGGER trig_row_before_delete ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_before_delete" for table "rem1" does not exist DROP TRIGGER trig_row_after_delete ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_after_delete" for table "rem1" does not exist -- Test various RETURN statements in BEFORE triggers. CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ BEGIN @@ -3054,134 +3025,123 @@ $$ language plpgsql; CREATE TRIGGER trig_row_before_insupd BEFORE INSERT OR UPDATE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view -- The new values should have 'triggered' appended INSERT INTO rem1 values(1, 'insert'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 values(1, 'insert'); - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye -(2 rows) + f1 | f2 +----+-------- + 1 | insert +(1 row) INSERT INTO rem1 values(2, 'insert') RETURNING f2; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 values(2, 'insert') RETURNING f2; - ^ + f2 +-------- + insert +(1 row) + SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+-------- + 1 | insert + 2 | insert (2 rows) UPDATE rem1 set f2 = ''; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 set f2 = ''; - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+---- + 1 | + 2 | (2 rows) UPDATE rem1 set f2 = 'skidoo' RETURNING f2; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 set f2 = 'skidoo' RETURNING f2; - ^ + f2 +-------- + skidoo + skidoo +(2 rows) + SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+-------- + 1 | skidoo + 2 | skidoo (2 rows) EXPLAIN (verbose, costs off) UPDATE rem1 set f1 = 10; -- all columns should be transmitted -ERROR: relation "rem1" does not exist on datanode1 -LINE 2: UPDATE rem1 set f1 = 10; - ^ + QUERY PLAN +----------------------------------------------------------------- + Update on public.rem1 + -> Foreign Scan on public.rem1 + Output: 10, f2, ctid + Remote SQL: SELECT f2, ctid FROM public.loc1 FOR UPDATE +(4 rows) + UPDATE rem1 set f1 = 10; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 set f1 = 10; - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+-------- + 10 | skidoo + 10 | skidoo (2 rows) DELETE FROM rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: DELETE FROM rem1; - ^ -- Add a second trigger, to check that the changes are propagated correctly -- from trigger to trigger CREATE TRIGGER trig_row_before_insupd2 BEFORE INSERT OR UPDATE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view INSERT INTO rem1 values(1, 'insert'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 values(1, 'insert'); - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye -(2 rows) + f1 | f2 +----+-------- + 1 | insert +(1 row) INSERT INTO rem1 values(2, 'insert') RETURNING f2; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 values(2, 'insert') RETURNING f2; - ^ + f2 +-------- + insert +(1 row) + SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+-------- + 1 | insert + 2 | insert (2 rows) UPDATE rem1 set f2 = ''; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 set f2 = ''; - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+---- + 1 | + 2 | (2 rows) UPDATE rem1 set f2 = 'skidoo' RETURNING f2; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 set f2 = 'skidoo' RETURNING f2; - ^ + f2 +-------- + skidoo + skidoo +(2 rows) + SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+-------- + 1 | skidoo + 2 | skidoo (2 rows) DROP TRIGGER trig_row_before_insupd ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_before_insupd" for table "rem1" does not exist DROP TRIGGER trig_row_before_insupd2 ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_row_before_insupd2" for table "rem1" does not exist DELETE from rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: DELETE from rem1; - ^ INSERT INTO rem1 VALUES (1, 'test'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 VALUES (1, 'test'); - ^ -- Test with a trigger returning NULL CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ BEGIN @@ -3191,68 +3151,49 @@ $$ language plpgsql; CREATE TRIGGER trig_null BEFORE INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trig_null(); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view -- Nothing should have changed. INSERT INTO rem1 VALUES (2, 'test2'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1 VALUES (2, 'test2'); - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+------- + 1 | test + 2 | test2 (2 rows) UPDATE rem1 SET f2 = 'test2'; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 SET f2 = 'test2'; - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye + f1 | f2 +----+------- + 1 | test2 + 2 | test2 (2 rows) DELETE from rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: DELETE from rem1; - ^ SELECT * from loc1; - f1 | f2 -----+----- - 1 | hi - 2 | bye -(2 rows) + f1 | f2 +----+---- +(0 rows) DROP TRIGGER trig_null ON rem1; -ERROR: relation "rem1" does not exist +ERROR: trigger "trig_null" for table "rem1" does not exist DELETE from rem1; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: DELETE from rem1; - ^ -- Test a combination of local and remote triggers CREATE TRIGGER trig_row_before BEFORE INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view CREATE TRIGGER trig_row_after AFTER INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); -ERROR: relation "rem1" does not exist +ERROR: "rem1" is not a table or view CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1 FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); INSERT INTO rem1(f2) VALUES ('test'); -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: INSERT INTO rem1(f2) VALUES ('test'); - ^ UPDATE rem1 SET f2 = 'testo'; -ERROR: relation "rem1" does not exist on datanode1 -LINE 1: UPDATE rem1 SET f2 = 'testo'; - ^ -- Test returning a system attribute INSERT INTO rem1(f2) VALUES ('test') RETURNING ctid; -ERROR: relation "rem1" does not exist on datanode1 +ERROR: column "ctid" does not exist LINE 1: INSERT INTO rem1(f2) VALUES ('test') RETURNING ctid; - ^ + ^ +CONTEXT: referenced column: ctid \ No newline at end of file