From: Pavan Deolasee Date: Wed, 10 Oct 2018 10:51:40 +0000 (+0530) Subject: Ensure CREATE TABLE (LIKE INCLUDING ALL) honors distribution strategy X-Git-Tag: XL_10_R1~16 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=22fcb937447958b74e97c08ce5d67bf9f645aae2;p=postgres-xl.git Ensure CREATE TABLE (LIKE INCLUDING ALL) honors distribution strategy We introduce two INCLUDING/EXCLUDING options to copy the distribution strategy and the target nodes. It's quite unlikely that someone would create a LIKE table but won't want to copy the distribution information, but it gives user flexibility to do that. Since we did not want to add more keywords, we simply used DISTRIBUTE and NODE, though DISTRIBUTION and NODES may have been better names. --- diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 846e4b36a6..952ddeab10 100755 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -556,6 +556,14 @@ FROM ( { numeric_literal | INCLUDING STATISTICS is specified. + + Distribution strategy is copied to the new table if + INCLUDING DISTRIBUTE is specified. + + + Distribution nodes are copied to the new table if + INCLUDING NODE is specified. + Indexes, PRIMARY KEY, UNIQUE, and EXCLUDE constraints on the original table will be @@ -581,7 +589,7 @@ FROM ( { numeric_literal | INCLUDING ALL is an abbreviated form of - INCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING INDEXES INCLUDING STATISTICS INCLUDING STORAGE. + INCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING INDEXES INCLUDING STATISTICS INCLUDING STORAGE INCLUDING DISTRIBUTE INCLUDING NODE. Note that unlike INHERITS, columns and diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 68e0a265d7..eb29f888fd 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -3637,6 +3637,8 @@ TableLikeOption: | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; } | STATISTICS { $$ = CREATE_TABLE_LIKE_STATISTICS; } | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; } + | DISTRIBUTE { $$ = CREATE_TABLE_LIKE_DISTRIBUTE; } + | NODE { $$ = CREATE_TABLE_LIKE_NODE; } | ALL { $$ = CREATE_TABLE_LIKE_ALL; } ; diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 44ab471c62..a5c64d0c8e 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -116,11 +116,15 @@ typedef struct List *alist; /* "after list" of things to do after creating * the table */ IndexStmt *pkey; /* PRIMARY KEY index, if any */ + #ifdef PGXC FallbackSrc fallback_source; List *fallback_dist_cols; - DistributeBy *distributeby; /* original distribute by column of CREATE TABLE */ - PGXCSubCluster *subcluster; /* original subcluster option of CREATE TABLE */ + + /* original or derived distribute by column of CREATE TABLE */ + DistributeBy *distributeby; + /* original or derived subcluster option of CREATE TABLE */ + PGXCSubCluster *subcluster; #endif bool ispartitioned; /* true if table is partitioned */ PartitionBoundSpec *partbound; /* transformed FOR VALUES */ @@ -473,6 +477,11 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) stmt->tableElts = cxt.columns; stmt->constraints = cxt.ckconstraints; + if (stmt->distributeby == NULL) + stmt->distributeby = cxt.distributeby; + if (stmt->subcluster == NULL) + stmt->subcluster = cxt.subcluster; + result = lappend(cxt.blist, stmt); result = list_concat(result, cxt.alist); result = list_concat(result, save_alist); @@ -1111,6 +1120,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla AclResult aclresult; char *comment; ParseCallbackState pcbstate; + RelationLocInfo *rel_loc_info; setup_parser_errposition_callback(&pcbstate, cxt->pstate, table_like_clause->relation->location); @@ -1174,6 +1184,40 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla RelationGetRelationName(relation)); } + rel_loc_info = RelationGetLocInfo(relation); + + if ((table_like_clause->options & CREATE_TABLE_LIKE_DISTRIBUTE) && + (cxt->distributeby == NULL) && + (rel_loc_info != NULL)) + { + cxt->distributeby = makeNode(DistributeBy); + switch (rel_loc_info->locatorType) + { + case LOCATOR_TYPE_HASH: + cxt->distributeby->disttype = DISTTYPE_HASH; + cxt->distributeby->colname = pstrdup(rel_loc_info->partAttrName); + break; + case LOCATOR_TYPE_MODULO: + cxt->distributeby->disttype = DISTTYPE_MODULO; + cxt->distributeby->colname = pstrdup(rel_loc_info->partAttrName); + break; + case LOCATOR_TYPE_RROBIN: + cxt->distributeby->disttype = DISTTYPE_ROUNDROBIN; + break; + case LOCATOR_TYPE_REPLICATED: + cxt->distributeby->disttype = DISTTYPE_REPLICATION; + break; + } + } + + if ((table_like_clause->options & CREATE_TABLE_LIKE_NODE) && + (cxt->subcluster == NULL) && + (rel_loc_info != NULL)) + { + if (rel_loc_info->rl_nodeList) + cxt->subcluster = makeSubCluster(rel_loc_info->rl_nodeList); + } + tupleDesc = RelationGetDescr(relation); constr = tupleDesc->constr; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index b47e0b6261..9baa210971 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -681,6 +681,8 @@ typedef enum TableLikeOption CREATE_TABLE_LIKE_STORAGE = 1 << 4, CREATE_TABLE_LIKE_COMMENTS = 1 << 5, CREATE_TABLE_LIKE_STATISTICS = 1 << 6, + CREATE_TABLE_LIKE_DISTRIBUTE = 1 << 7, + CREATE_TABLE_LIKE_NODE = 1 << 8, CREATE_TABLE_LIKE_ALL = PG_INT32_MAX } TableLikeOption; diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out index 555e8daadd..ca25edb7f5 100644 --- a/src/test/regress/expected/create_table_like.out +++ b/src/test/regress/expected/create_table_like.out @@ -336,3 +336,70 @@ SELECT oid FROM like_test5; DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, like_test4, like_test5; +-- xl tests +CREATE TABLE like_test6 (a INT, b INT, c TEXT) DISTRIBUTE BY HASH(b); +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING ALL); +\d+ like_test7 + Table "public.like_test7" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | + c | text | | | | extended | | +Distribute By: HASH(b) +Location Nodes: ALL DATANODES + +DROP TABLE like_test7; +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE); +\d+ like_test7 + Table "public.like_test7" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | + c | text | | | | extended | | +Distribute By: HASH(b) +Location Nodes: ALL DATANODES + +DROP TABLE like_test7; +-- explicit distribution clause overwrites like clause +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE) DISTRIBUTE BY REPLICATION; +\d+ like_test7 + Table "public.like_test7" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | + c | text | | | | extended | | +Distribute By: REPLICATION +Location Nodes: ALL DATANODES + +DROP TABLE like_test7; +DROP TABLE like_test6; +CREATE TABLE like_test6 (a INT, b INT, c TEXT) DISTRIBUTE BY HASH(b) TO NODE (datanode_1); +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE INCLUDING NODE); +\d+ like_test7 + Table "public.like_test7" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | + c | text | | | | extended | | +Distribute By: HASH(b) +Location Nodes: datanode_1 + +DROP TABLE like_test7; +-- check if excluding works ok +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE EXCLUDING NODE); +\d+ like_test7 + Table "public.like_test7" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+----------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | + c | text | | | | extended | | +Distribute By: HASH(b) +Location Nodes: ALL DATANODES + +DROP TABLE like_test7; +DROP TABLE like_test6; diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql index a8a3e80873..98699798e5 100644 --- a/src/test/regress/sql/create_table_like.sql +++ b/src/test/regress/sql/create_table_like.sql @@ -152,3 +152,26 @@ CREATE TABLE like_test5 (z INTEGER, LIKE no_oid) WITH OIDS; SELECT oid FROM like_test5; DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, like_test4, like_test5; + +-- xl tests +CREATE TABLE like_test6 (a INT, b INT, c TEXT) DISTRIBUTE BY HASH(b); +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING ALL); +\d+ like_test7 +DROP TABLE like_test7; +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE); +\d+ like_test7 +DROP TABLE like_test7; +-- explicit distribution clause overwrites like clause +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE) DISTRIBUTE BY REPLICATION; +\d+ like_test7 +DROP TABLE like_test7; +DROP TABLE like_test6; +CREATE TABLE like_test6 (a INT, b INT, c TEXT) DISTRIBUTE BY HASH(b) TO NODE (datanode_1); +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE INCLUDING NODE); +\d+ like_test7 +DROP TABLE like_test7; +-- check if excluding works ok +CREATE TABLE like_test7 (LIKE like_test6 INCLUDING DISTRIBUTE EXCLUDING NODE); +\d+ like_test7 +DROP TABLE like_test7; +DROP TABLE like_test6;