From b44fa53ed1d41d912f582773a96935482566eedf Mon Sep 17 00:00:00 2001 From: wuyujun <714166892@qq.com> Date: Thu, 22 Sep 2022 16:33:36 +0800 Subject: [PATCH] =?UTF-8?q?B=E6=A8=A1=E5=BC=8F=E4=B8=8B=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E6=94=AF=E6=8C=81delete=E5=A4=9A=E8=A1=A8=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E7=9A=84delete=20XXX=20from=20XXXX=E8=AF=AD=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/src/sgml/ref/delete.sgmlin | 8 +++- src/common/backend/parser/gram.y | 47 +++++++++++++--------- src/test/regress/expected/delete.out | 4 ++ src/test/regress/expected/multi_delete.out | 40 +++++++++++++++++- src/test/regress/sql/delete.sql | 4 +- src/test/regress/sql/multi_delete.sql | 20 +++++++++ 6 files changed, 102 insertions(+), 21 deletions(-) diff --git a/doc/src/sgml/ref/delete.sgmlin b/doc/src/sgml/ref/delete.sgmlin index a219f8676..c95ad0cb2 100644 --- a/doc/src/sgml/ref/delete.sgmlin +++ b/doc/src/sgml/ref/delete.sgmlin @@ -21,10 +21,16 @@ DELETE [/*+ plan_hint */] [FROM] [ ONLY ] table_name [ * ] [ [ [partition_clause DELETE Multiple-Relation Syntax: [ WITH [ RECURSIVE ] with_query [, ...] ] -DELETE [/*+ plan_hint */] [FROM] +DELETE [/*+ plan_hint */] [FROM] {[ ONLY ] table_name [ * ] [ [ [partition_clause] [ [ AS ] alias ] ] | [ [ [ AS ] alias ] [partitions_clause] ] ]} [, ...] [ USING using_list ] [ WHERE condition | WHERE CURRENT OF cursor_name ]; +or +[ WITH [ RECURSIVE ] with_query [, ...] ] +DELETE [/*+ plan_hint */] + {[ ONLY ] table_name [ * ] [ [ [partition_clause] [ [ AS ] alias ] ] | [ [ [ AS ] alias ] [partitions_clause] ] ]} [, ...] + [ FROM using_list ] + [ WHERE condition | WHERE CURRENT OF cursor_name ]; where with_query can be: with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index 0f472b798..15315d39d 100644 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -246,6 +246,7 @@ static Node *make_node_from_scanbuf(int start_pos, int end_pos, core_yyscan_t yy static int64 SequenceStrGetInt64(const char *str); static int GetLoadType(int load_type_f, int load_type_s); static Node *MakeSqlLoadNode(char *colname); +static void checkDeleteRelationError(); /* start with .. connect by related utilities */ static bool IsConnectByRootIdent(Node* node); @@ -20155,15 +20156,7 @@ DeleteStmt: opt_with_clause DELETE_P hint_string FROM relation_expr_opt_alias_li DeleteStmt *n = makeNode(DeleteStmt); n->relations = $5; if (list_length(n->relations) > 1) { -#ifdef ENABLE_MULTIPLE_NODES - ereport(errstate, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("multi-relation delete is not yet supported."))); -#endif - if (u_sess->attr.attr_sql.sql_compatibility != B_FORMAT) - ereport(errstate, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("multi-relation delete only support in B-format database"))); + checkDeleteRelationError(); } n->usingClause = $6; n->whereClause = $7; @@ -20180,15 +20173,7 @@ DeleteStmt: opt_with_clause DELETE_P hint_string FROM relation_expr_opt_alias_li DeleteStmt *n = makeNode(DeleteStmt); n->relations = $4; if (list_length(n->relations) > 1) { -#ifdef ENABLE_MULTIPLE_NODES - ereport(errstate, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("multi-relation delete is not yet supported."))); -#endif - if (u_sess->attr.attr_sql.sql_compatibility != B_FORMAT) - ereport(errstate, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("multi-relation delete only support in B-format database"))); + checkDeleteRelationError(); } n->usingClause = $5; n->whereClause = $6; @@ -20199,6 +20184,19 @@ DeleteStmt: opt_with_clause DELETE_P hint_string FROM relation_expr_opt_alias_li n->hintState = create_hintstate($3); $$ = (Node *)n; } + /* this is only used in multi-relation DELETE for compatibility B database. */ + | opt_with_clause DELETE_P hint_string relation_expr_opt_alias_list + FROM from_list where_or_current_clause + { + DeleteStmt *n = makeNode(DeleteStmt); + n->relations = $4; + checkDeleteRelationError(); + n->usingClause = $6; + n->whereClause = $7; + n->withClause = $1; + n->hintState = create_hintstate($3); + $$ = (Node *)n; + } ; using_clause: @@ -28543,6 +28541,19 @@ static FuncCall* MakePriorAsFunc() return n; } +static void checkDeleteRelationError() +{ +#ifdef ENABLE_MULTIPLE_NODES + ereport(errstate, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("multi-relation delete is not yet supported."))); +#endif + if (u_sess->attr.attr_sql.sql_compatibility != B_FORMAT) + ereport(errstate, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("multi-relation delete only support in B-format database"))); +} + /* * Must undefine this stuff before including scan.c, since it has different * definitions for these macros. diff --git a/src/test/regress/expected/delete.out b/src/test/regress/expected/delete.out index 6a9b50f5e..ec735ff07 100644 --- a/src/test/regress/expected/delete.out +++ b/src/test/regress/expected/delete.out @@ -40,3 +40,7 @@ create table t_t_mutil_t1(col1 int,col2 int); create table t_t_mutil_t2(col1 int,col2 int); delete from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1=b.col1; ERROR: multi-relation delete only support in B-format database +delete a from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1=b.col1; +ERROR: multi-relation delete only support in B-format database +delete a,b from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1=b.col1; +ERROR: multi-relation delete only support in B-format database diff --git a/src/test/regress/expected/multi_delete.out b/src/test/regress/expected/multi_delete.out index 65bceea8f..5539d0839 100644 --- a/src/test/regress/expected/multi_delete.out +++ b/src/test/regress/expected/multi_delete.out @@ -15,10 +15,16 @@ DELETE [/*+ plan_hint */] [FROM] [ ONLY ] table_name [ * ] [ [ [partition_clause DELETE Multiple-Relation Syntax: [ WITH [ RECURSIVE ] with_query [, ...] ] -DELETE [/*+ plan_hint */] [FROM] +DELETE [/*+ plan_hint */] [FROM] {[ ONLY ] table_name [ * ] [ [ [partition_clause] [ [ AS ] alias ] ] | [ [ [ AS ] alias ] [partitions_clause] ] ]} [, ...] [ USING using_list ] [ WHERE condition | WHERE CURRENT OF cursor_name ]; +or +[ WITH [ RECURSIVE ] with_query [, ...] ] +DELETE [/*+ plan_hint */] + {[ ONLY ] table_name [ * ] [ [ [partition_clause] [ [ AS ] alias ] ] | [ [ [ AS ] alias ] [partitions_clause] ] ]} [, ...] + [ FROM using_list ] + [ WHERE condition | WHERE CURRENT OF cursor_name ]; where with_query can be: with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] @@ -65,6 +71,38 @@ select * from t_t_mutil_t3; (1 row) rollback; +-- delete xx from xxx; +begin; +delete t_t_mutil_t1 a from t_t_mutil_t2 b,t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete a from t_t_mutil_t1 a,t_t_mutil_t2 b,t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete t_t_mutil_t1 a,t_t_mutil_t2 b from t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete a,b from t_t_mutil_t1 a,t_t_mutil_t2 b,t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2; +rollback; +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 limit 1; -- error +ERROR: syntax error at or near "limit" +LINE 1: ...util_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 limit 1; + ^ +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 order by a.col2; -- error +ERROR: syntax error at or near "order" +LINE 1: ...il_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 order by a... + ^ +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 returning *; -- error +ERROR: syntax error at or near "returning" +LINE 1: ...il_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 returning ... + ^ +delete t_t_mutil_t1 a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 limit 1; -- error +ERROR: syntax error at or near "limit" +LINE 1: ...util_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 limit 1; + ^ -- condition is false delete from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1 = 1 and a.col1=2; -- different plan diff --git a/src/test/regress/sql/delete.sql b/src/test/regress/sql/delete.sql index 84710cda6..5b1bb4700 100644 --- a/src/test/regress/sql/delete.sql +++ b/src/test/regress/sql/delete.sql @@ -27,4 +27,6 @@ DROP TABLE delete_test; --multiple delete, report error except B format; create table t_t_mutil_t1(col1 int,col2 int); create table t_t_mutil_t2(col1 int,col2 int); -delete from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1=b.col1; \ No newline at end of file +delete from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1=b.col1; +delete a from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1=b.col1; +delete a,b from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1=b.col1; \ No newline at end of file diff --git a/src/test/regress/sql/multi_delete.sql b/src/test/regress/sql/multi_delete.sql index 354a8555b..82bf844d2 100644 --- a/src/test/regress/sql/multi_delete.sql +++ b/src/test/regress/sql/multi_delete.sql @@ -17,6 +17,26 @@ select * from t_t_mutil_t1; select * from t_t_mutil_t2; select * from t_t_mutil_t3; rollback; +-- delete xx from xxx; +begin; +delete t_t_mutil_t1 a from t_t_mutil_t2 b,t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete a from t_t_mutil_t1 a,t_t_mutil_t2 b,t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete t_t_mutil_t1 a,t_t_mutil_t2 b from t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete a,b from t_t_mutil_t1 a,t_t_mutil_t2 b,t_t_mutil_t3 c where a.col2=b.col2 and b.col2=c.col2; +rollback; +begin; +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2; +rollback; +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 limit 1; -- error +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 order by a.col2; -- error +delete a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 returning *; -- error +delete t_t_mutil_t1 a from t_t_mutil_t1 a left join t_t_mutil_t2 b on a.col2=b.col2 limit 1; -- error -- condition is false delete from t_t_mutil_t1 a,t_t_mutil_t2 b where a.col1 = 1 and a.col1=2; -- different plan