diff options
| author | Pavan Deolasee | 2017-07-13 07:24:55 +0000 |
|---|---|---|
| committer | Pavan Deolasee | 2017-07-13 07:31:20 +0000 |
| commit | e26a0e07d863777079bfe9fc335ca2b71377b731 (patch) | |
| tree | aa11f6d30e3b98c4951b0e9cb77ea2acf96c220e /src/backend/parser | |
| parent | a0f550b412fb208ea6722ed0c81f299e1d3e507f (diff) | |
Ensure that child table inherits distribution stretegy from the parent.
For partitioned tables or in general inherited tables, we now enforce that the
child table always inherit the distribution strategy of the parent. This not
only makes it far easier to handle various cases correctly, but would also
allow us to optimise distributed queries on partitioned tables much easily.
Tank.zhang <6220104@qq.com> originally reported a problem with partitioned
tables and incorrect query execution. Upon investigations, we decided to make
these restrictions to simplify things.
Diffstat (limited to 'src/backend/parser')
| -rw-r--r-- | src/backend/parser/parse_utilcmd.c | 113 |
1 files changed, 66 insertions, 47 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 1cdeacf3b5..67658db41d 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -361,6 +361,72 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) stmt->options); /* + * If the table is inherited then use the distribution strategy of the + * parent. We must have already checked for multiple parents and raised an + * ERROR since Postgres-XL does not support inheriting from multiple + * parents. + */ + if (stmt->inhRelations && IS_PGXC_COORDINATOR && autodistribute) + { + RangeVar *inh = (RangeVar *) linitial(stmt->inhRelations); + Relation rel; + + Assert(IsA(inh, RangeVar)); + rel = heap_openrv(inh, AccessShareLock); + if ((rel->rd_rel->relkind != RELKIND_RELATION) && + (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("inherited relation \"%s\" is not a table", + inh->relname))); + + if (stmt->distributeby) + { + if (!rel->rd_locator_info) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("parent table \"%s\" is not distributed, but " + "distribution is specified for the child table \"%s\"", + RelationGetRelationName(rel), + stmt->relation->relname))); + ereport(WARNING, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("Inherited/partition tables inherit" + " distribution from the parent"), + errdetail("Explicitly specified distribution will be ignored"))); + } + else + stmt->distributeby = makeNode(DistributeBy); + + + if (rel->rd_locator_info) + { + switch (rel->rd_locator_info->locatorType) + { + case LOCATOR_TYPE_HASH: + stmt->distributeby->disttype = DISTTYPE_HASH; + stmt->distributeby->colname = + pstrdup(rel->rd_locator_info->partAttrName); + break; + case LOCATOR_TYPE_MODULO: + stmt->distributeby->disttype = DISTTYPE_MODULO; + stmt->distributeby->colname = + pstrdup(rel->rd_locator_info->partAttrName); + break; + case LOCATOR_TYPE_REPLICATED: + stmt->distributeby->disttype = DISTTYPE_REPLICATION; + break; + case LOCATOR_TYPE_RROBIN: + default: + stmt->distributeby->disttype = DISTTYPE_ROUNDROBIN; + break; + } + stmt->subcluster = makeSubCluster(rel->rd_locator_info->rl_nodeList); + } + heap_close(rel, NoLock); + } + + /* * transformIndexConstraints wants cxt.alist to contain only index * statements, so transfer anything we already have into save_alist. */ @@ -418,53 +484,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) stmt->distributeby->colname = NULL; } /* - * If there are parent tables ingerit distribution of the first parent - */ - else if (cxt.fallback_source < FBS_UIDX && stmt->inhRelations) - { - RangeVar *inh = (RangeVar *) linitial(stmt->inhRelations); - Relation rel; - - Assert(IsA(inh, RangeVar)); - rel = heap_openrv(inh, AccessShareLock); - if ((rel->rd_rel->relkind != RELKIND_RELATION) && - (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("inherited relation \"%s\" is not a table", - inh->relname))); - - if (rel->rd_locator_info) - { - switch (rel->rd_locator_info->locatorType) - { - case LOCATOR_TYPE_HASH: - stmt->distributeby->disttype = DISTTYPE_HASH; - stmt->distributeby->colname = - pstrdup(rel->rd_locator_info->partAttrName); - break; - case LOCATOR_TYPE_MODULO: - stmt->distributeby->disttype = DISTTYPE_MODULO; - stmt->distributeby->colname = - pstrdup(rel->rd_locator_info->partAttrName); - break; - case LOCATOR_TYPE_REPLICATED: - stmt->distributeby->disttype = DISTTYPE_REPLICATION; - break; - case LOCATOR_TYPE_RROBIN: - default: - stmt->distributeby->disttype = DISTTYPE_ROUNDROBIN; - break; - } - /* - * Use defined node, if nothing defined get from the parent - */ - if (stmt->subcluster == NULL) - stmt->subcluster = makeSubCluster(rel->rd_locator_info->rl_nodeList); - } - heap_close(rel, NoLock); - } - /* * If there are columns suitable for hash distribution distribute on * first of them. */ |
