diff options
author | Michael Paquier | 2012-10-22 01:23:40 +0000 |
---|---|---|
committer | Michael Paquier | 2012-10-22 01:23:40 +0000 |
commit | 23220741845f72669e5bd4bb5825d8818fb16223 (patch) | |
tree | c8ee7c286ac03dbee9aed24f1b49b5fe9a710ade | |
parent | 9ce38d3bf64c17155a0ca283c56987b7ecd9e218 (diff) |
Index expressions shippability analysis for distribution columns
This commit strengthens determination analysis of unique index expressions
shippability for value-distributed tables.
For example, in the case of a cluster with 2 Datanodes:
CREATE TABLE aa (a int) DISTRIBUTE BY HASH(a);
CREATE UNIQUE INDEX aap ON (abs(a));
INSERT INTO aa (2); -- To Datanode 1
INSERT INTO aa (-2); -- To Datanode 2
The index uniqueness is not ensured here even if the index expression constains
only the distribution column of parent relation. Such expressions are not
shippable, and as XC does not support yet global constraints such index creation
is simply blocked.
Also, if the table has its data located on a single node, its index uniqueness
can be evaluated safely in all the cases, a condition is added to treat that
case.
-rw-r--r-- | src/backend/optimizer/util/pgxcship.c | 56 | ||||
-rw-r--r-- | src/test/regress/expected/xc_constraints.out | 3 | ||||
-rw-r--r-- | src/test/regress/sql/xc_constraints.sql | 2 |
3 files changed, 26 insertions, 35 deletions
diff --git a/src/backend/optimizer/util/pgxcship.c b/src/backend/optimizer/util/pgxcship.c index 2b5b6966c6..ec8a1ab939 100644 --- a/src/backend/optimizer/util/pgxcship.c +++ b/src/backend/optimizer/util/pgxcship.c @@ -1574,6 +1574,13 @@ pgxc_check_index_shippability(RelationLocInfo *relLocInfo, } /* + * Check if relation is distributed on a single node, in this case + * the constraint can be shipped in all the cases. + */ + if (list_length(relLocInfo->nodeList) == 1) + return result; + + /* * Check the case of EXCLUSION index. * EXCLUSION constraints are shippable only for replicated relations as * such constraints need that one tuple is checked on all the others, and @@ -1619,13 +1626,9 @@ pgxc_check_index_shippability(RelationLocInfo *relLocInfo, case LOCATOR_TYPE_HASH: case LOCATOR_TYPE_MODULO: /* - * Index on Hash and Modulo tables are shippable if the index - * columns include the list of all column keys of distribution. - * We need also to check if this index uses expressions. Such - * expressions are not shippable if they do not satisfy the - * following conditions: - * - expression uses non-distribution columns - * - expression uses more than 1 distribution column + * Unique indexes on Hash and Modulo tables are shippable if the + * index expression contains all the distribution expressions of + * its parent relation. * * Here is a short example with concatenate that cannot be * shipped: @@ -1637,40 +1640,27 @@ pgxc_check_index_shippability(RelationLocInfo *relLocInfo, * go to different nodes. For such simple reasons unique * indexes on distributed tables are not shippable. * Shippability is not even ensured if all the expressions - * use as Var only distributed colums as the hash output of + * used as Var are only distributed columns as the hash output of * their value combination does not ensure that query will - * be directed to the correct remote node. + * be directed to the correct remote node. Uniqueness is not even + * protected if the index expression contains only the distribution + * column like for that with a cluster of 2 Datanodes: + * CREATE TABLE aa (a int) DISTRIBUTE BY HASH(a); + * CREATE UNIQUE INDEX aap ON (abs(a)); + * INSERT INTO aa (2); -- to Datanode 1 + * INSERT INTO aa (-2); -- to Datanode 2, breaks uniqueness * * PGXCTODO: for the time being distribution key can only be * defined on a single column, so this will need to be changed - * once such a feature is implemented. + * onde a relation distribution will be able to be defined based + * on an expression of multiple columns. */ - /* Evaluate expression shippability based on index uniqueness */ + /* Index contains expressions, it cannot be shipped safely */ if (indexExprs != NIL) { - /* - * Check if the expressions use only distribution columns. - * In order to evaluate that get all the variable expressions. - */ - List *indexVars = pull_var_clause((Node *) indexExprs, - PVC_RECURSE_AGGREGATES, - PVC_RECURSE_PLACEHOLDERS); - foreach(lc, indexVars) - { - Var *var = (Var *) lfirst(lc); - - /* - * Check if attribute is the distribution column. - * PGXCTODO: this will need modifications once - * multi-column distribution is implemented. - */ - if (var->varattno != relLocInfo->partAttrNum) - { - result = false; - break; - } - } + result = false; + break; } /* Nothing to do if no attributes */ diff --git a/src/test/regress/expected/xc_constraints.out b/src/test/regress/expected/xc_constraints.out index 7351de5381..75d891ce48 100644 --- a/src/test/regress/expected/xc_constraints.out +++ b/src/test/regress/expected/xc_constraints.out @@ -24,8 +24,9 @@ ERROR: Cannot create index whose evaluation cannot be enforced to remote nodes CREATE UNIQUE INDEX xc_cons_hash_unique1 ON xc_cons_hash(c1); -- OK, contains distribution column CREATE UNIQUE INDEX xc_cons_hash_unique2 ON xc_cons_hash(c1,c2); --- OK, expression contains only distribution column +-- error, expression contains only distribution column CREATE UNIQUE INDEX xc_cons_hash_unique3 ON xc_cons_hash((c1 || c1)); +ERROR: Cannot create index whose evaluation cannot be enforced to remote nodes -- error, expression contains other columns than distribution one CREATE UNIQUE INDEX xc_cons_hash_unique3 ON xc_cons_hash((c1 || c2)); ERROR: Cannot create index whose evaluation cannot be enforced to remote nodes diff --git a/src/test/regress/sql/xc_constraints.sql b/src/test/regress/sql/xc_constraints.sql index 8c98b2e13b..96318a1377 100644 --- a/src/test/regress/sql/xc_constraints.sql +++ b/src/test/regress/sql/xc_constraints.sql @@ -24,7 +24,7 @@ CREATE UNIQUE INDEX xc_cons_rr_unique3 ON xc_cons_rr((c2 || c3)); -- error, not CREATE UNIQUE INDEX xc_cons_hash_unique1 ON xc_cons_hash(c1); -- OK, contains distribution column CREATE UNIQUE INDEX xc_cons_hash_unique2 ON xc_cons_hash(c1,c2); --- OK, expression contains only distribution column +-- error, expression contains only distribution column CREATE UNIQUE INDEX xc_cons_hash_unique3 ON xc_cons_hash((c1 || c1)); -- error, expression contains other columns than distribution one CREATE UNIQUE INDEX xc_cons_hash_unique3 ON xc_cons_hash((c1 || c2)); |