summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier2012-10-22 01:23:40 +0000
committerMichael Paquier2012-10-22 01:23:40 +0000
commit23220741845f72669e5bd4bb5825d8818fb16223 (patch)
treec8ee7c286ac03dbee9aed24f1b49b5fe9a710ade
parent9ce38d3bf64c17155a0ca283c56987b7ecd9e218 (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.c56
-rw-r--r--src/test/regress/expected/xc_constraints.out3
-rw-r--r--src/test/regress/sql/xc_constraints.sql2
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));