diff --git a/doc/src/sgml/ref/alter_property_graph.sgml b/doc/src/sgml/ref/alter_property_graph.sgml index 604c518011..0a20b482b8 100644 --- a/doc/src/sgml/ref/alter_property_graph.sgml +++ b/doc/src/sgml/ref/alter_property_graph.sgml @@ -33,7 +33,7 @@ ALTER PROPERTY GRAPH name DROP ALTER PROPERTY GRAPH name ALTER {VERTEX|NODE|EDGE|RELATIONSHIP} TABLE element_table_alias - { ADD LABEL label_name [ NO PROPERTIES | PROPERTIES ALL COLUMNS | PROPERTIES ( { expression [ AS property_name ] } [, ...] ) ] } [ ... ] + { ADD LABEL label_name [ NO PROPERTIES | PROPERTIES ALL COLUMNS | PROPERTIES ALL COLUMNS EXCEPT | PROPERTIES ( { expression [ AS property_name ] } [, ...] ) ] } [ ... ] ALTER PROPERTY GRAPH name ALTER {VERTEX|NODE|EDGE|RELATIONSHIP} TABLE element_table_alias diff --git a/doc/src/sgml/ref/create_property_graph.sgml b/doc/src/sgml/ref/create_property_graph.sgml index f88d1194cb..36b710cf7b 100644 --- a/doc/src/sgml/ref/create_property_graph.sgml +++ b/doc/src/sgml/ref/create_property_graph.sgml @@ -38,11 +38,11 @@ CREATE [ TEMP | TEMPORARY ] PROPERTY GRAPH nameand element_table_label_and_properties is either: - NO PROPERTIES | PROPERTIES ALL COLUMNS | PROPERTIES ( { expression [ AS property_name ] } [, ...] ) + NO PROPERTIES | PROPERTIES ALL COLUMNS | PROPERTIES ( { expression [ AS property_name ] } [, ...] ) | PROPERTIES ALL COLUMNS EXCEPT( { expression [ AS property_name ] } [, ...] ) or: - { { LABEL label_name | DEFAULT LABEL } [ NO PROPERTIES | PROPERTIES ALL COLUMNS | PROPERTIES ( { expression [ AS property_name ] } [, ...] ) ] } [...] + { { LABEL label_name | DEFAULT LABEL } [ NO PROPERTIES | PROPERTIES ALL COLUMNS | PROPERTIES ( { expression [ AS property_name ] } [, ...] ) ] } [...] | PROPERTIES ALL COLUMNS EXCEPT( { expression [ AS property_name ] } [, ...] ) @@ -185,6 +185,9 @@ CREATE [ TEMP | TEMPORARY ] PROPERTY GRAPH namePROPERTIES ALL COLUMNS EXCEPT( { expression [ AS property_name ] } [, ...] ) diff --git a/src/backend/commands/propgraphcmds.c b/src/backend/commands/propgraphcmds.c index f204fc3125..7d46080702 100644 --- a/src/backend/commands/propgraphcmds.c +++ b/src/backend/commands/propgraphcmds.c @@ -700,6 +700,8 @@ insert_property_records(Oid graphid, Oid ellabeloid, Oid pgerelid, const PropGra Relation rel; ListCell *lc; + pstate = make_parsestate(NULL); + if (properties->all) { Relation attRelation; @@ -719,10 +721,40 @@ insert_property_records(Oid graphid, Oid ellabeloid, Oid pgerelid, const PropGra Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attributeTuple); ColumnRef *cr; ResTarget *rt; + bool exceptional = false; if (att->attnum <= 0 || att->attisdropped) continue; + /* Skip the attribute if exists in except column list */ + if (properties->except) + { + char *cname = NULL; + + foreach(lc, properties->except) + { + rt = lfirst_node(ResTarget, lc); + cr = (ColumnRef *) rt->val; + cname = strVal(linitial(cr->fields)); + + if (!get_attnum(pgerelid, cname)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + cname, get_rel_name(pgerelid)), + parser_errposition(pstate, rt->location))); + + if (strcmp(cname, NameStr(att->attname)) == 0) + { + exceptional = true; + break; + } + } + } + + if (exceptional) + continue; + cr = makeNode(ColumnRef); rt = makeNode(ResTarget); @@ -756,7 +788,6 @@ insert_property_records(Oid graphid, Oid ellabeloid, Oid pgerelid, const PropGra rel = table_open(pgerelid, AccessShareLock); - pstate = make_parsestate(NULL); nsitem = addRangeTableEntryForRelation(pstate, rel, AccessShareLock, diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 03016742cb..8bd5fd16af 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -9383,6 +9383,16 @@ element_table_properties: pr->all = true; pr->location = @1; + $$ = (Node *) pr; + } + | PROPERTIES ALL COLUMNS EXCEPT '(' xml_attribute_list ')' + { + PropGraphProperties *pr = makeNode(PropGraphProperties); + + pr->all = true; + pr->except = $6; + pr->location = @1; + $$ = (Node *) pr; } | PROPERTIES '(' xml_attribute_list ')' diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index c4223fda57..64d9e79b83 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -4119,6 +4119,7 @@ typedef struct PropGraphProperties { NodeTag type; List *properties; + List *except; bool all; ParseLoc location; } PropGraphProperties; diff --git a/src/test/regress/expected/create_property_graph.out b/src/test/regress/expected/create_property_graph.out index 43316fbc02..c4a28674a0 100644 --- a/src/test/regress/expected/create_property_graph.out +++ b/src/test/regress/expected/create_property_graph.out @@ -491,6 +491,52 @@ DROP PROPERTY GRAPH g1; -- error: does not exist ERROR: property graph "g1" does not exist DROP PROPERTY GRAPH IF EXISTS g1; NOTICE: property graph "g1" does not exist, skipping +-- test except column name list +CREATE PROPERTY GRAPH except_list_test + VERTEX TABLES (t1 KEY (a), t2 KEY (i) LABEL l1 PROPERTIES ALL COLUMNS EXCEPT (k)) + EDGE TABLES ( + e1 + SOURCE KEY (a) REFERENCES t1 (a) + DESTINATION KEY (i) REFERENCES t2 (i) + ); +ALTER PROPERTY GRAPH except_list_test ALTER VERTEX TABLE t2 ADD LABEL l2 PROPERTIES ALL COLUMNS EXCEPT (invalid_cname, j); -- error: invalid col name +ERROR: column "invalid_cname" of relation "t2" does not exist +ALTER PROPERTY GRAPH except_list_test ALTER VERTEX TABLE t2 ADD LABEL l2 PROPERTIES ALL COLUMNS EXCEPT (k, j); +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l1) COLUMNS(p.i)); + i +--- +(0 rows) + +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l1) COLUMNS(p.j)); + j +--- +(0 rows) + +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l1) COLUMNS(p.k)); -- error: does not exist +ERROR: property "k" does not exist +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l2) COLUMNS(p.i)); + i +--- +(0 rows) + +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l2) COLUMNS(p.j)); -- error: does not exist +ERROR: property "j" of element variable "p" not found +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l2) COLUMNS(p.k)); -- error: does not exist +ERROR: property "k" does not exist +SELECT * FROM information_schema.pg_label_properties WHERE property_graph_name = 'except_list_test'; + property_graph_catalog | property_graph_schema | property_graph_name | label_name | property_name +------------------------+-----------------------------+---------------------+------------+--------------- + regression | create_property_graph_tests | except_list_test | e1 | a + regression | create_property_graph_tests | except_list_test | e1 | i + regression | create_property_graph_tests | except_list_test | e1 | t + regression | create_property_graph_tests | except_list_test | l1 | i + regression | create_property_graph_tests | except_list_test | l1 | j + regression | create_property_graph_tests | except_list_test | l2 | i + regression | create_property_graph_tests | except_list_test | t1 | a + regression | create_property_graph_tests | except_list_test | t1 | b +(8 rows) + +DROP PROPERTY GRAPH except_list_test; -- leave for pg_upgrade/pg_dump tests --DROP SCHEMA create_property_graph_tests CASCADE; DROP ROLE regress_graph_user1, regress_graph_user2; diff --git a/src/test/regress/sql/create_property_graph.sql b/src/test/regress/sql/create_property_graph.sql index 4f9b5c0349..bd85fd0278 100644 --- a/src/test/regress/sql/create_property_graph.sql +++ b/src/test/regress/sql/create_property_graph.sql @@ -184,6 +184,29 @@ DROP PROPERTY GRAPH g1; -- error: does not exist DROP PROPERTY GRAPH IF EXISTS g1; +-- test except column name list + +CREATE PROPERTY GRAPH except_list_test + VERTEX TABLES (t1 KEY (a), t2 KEY (i) LABEL l1 PROPERTIES ALL COLUMNS EXCEPT (k)) + EDGE TABLES ( + e1 + SOURCE KEY (a) REFERENCES t1 (a) + DESTINATION KEY (i) REFERENCES t2 (i) + ); + +ALTER PROPERTY GRAPH except_list_test ALTER VERTEX TABLE t2 ADD LABEL l2 PROPERTIES ALL COLUMNS EXCEPT (invalid_cname, j); -- error: invalid col name +ALTER PROPERTY GRAPH except_list_test ALTER VERTEX TABLE t2 ADD LABEL l2 PROPERTIES ALL COLUMNS EXCEPT (k, j); + +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l1) COLUMNS(p.i)); +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l1) COLUMNS(p.j)); +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l1) COLUMNS(p.k)); -- error: does not exist +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l2) COLUMNS(p.i)); +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l2) COLUMNS(p.j)); -- error: does not exist +SELECT * FROM GRAPH_TABLE(except_list_test MATCH (p:l2) COLUMNS(p.k)); -- error: does not exist + +SELECT * FROM information_schema.pg_label_properties WHERE property_graph_name = 'except_list_test'; + +DROP PROPERTY GRAPH except_list_test; -- leave for pg_upgrade/pg_dump tests --DROP SCHEMA create_property_graph_tests CASCADE;