diff options
author | Tomas Vondra | 2017-06-16 20:59:48 +0000 |
---|---|---|
committer | Tomas Vondra | 2017-06-17 21:28:11 +0000 |
commit | 93656ace7562bf6892764d314311c802fbfdc34f (patch) | |
tree | 20b32b687ad68885ed968466d91526f5c57d4bdc | |
parent | b11c6ff119ffce5174b221deb7e65c2720da6623 (diff) |
Prevent dropping distribution keys for MODULO
Due to a coding issue in IsDistColumnForRelId() it was possible to drop
columns that were used as modulo distribution keys. A simple example
demonstrates the behavior:
CREATE TABLE t (a INT, b INT, c INT) DISTRIBUTE BY MODULO (a);
ALTER TABLE t DROP COLUMN a;
test=# \d+ t
Table "public.t"
Column | Type | Modifiers | Storage | Stats target | Description
--------+---------+-----------+---------+--------------+-------------
b | integer | | plain | |
c | integer | | plain | |
Distribute By: MODULO(........pg.dropped.1........)
Location Nodes: ALL DATANODES
With this commit, the ALTER TABLE command fails as expected:
ERROR: Distribution column cannot be dropped
The commit simplifies the coding a bit, and removes several functions
that were not needed anymore (and unused outside locator.c).
-rw-r--r-- | src/backend/pgxc/locator/locator.c | 83 | ||||
-rw-r--r-- | src/include/pgxc/locator.h | 4 | ||||
-rwxr-xr-x | src/test/regress/expected/xl_alter_table.out | 2 | ||||
-rwxr-xr-x | src/test/regress/sql/xl_alter_table.sql | 2 |
4 files changed, 17 insertions, 74 deletions
diff --git a/src/backend/pgxc/locator/locator.c b/src/backend/pgxc/locator/locator.c index 2ecffe45ac..2c8aa676ae 100644 --- a/src/backend/pgxc/locator/locator.c +++ b/src/backend/pgxc/locator/locator.c @@ -261,54 +261,28 @@ GetRelationHashColumn(RelationLocInfo * rel_loc_info) } /* - * IsHashColumn - return whether or not column for relation is hashed. - * - */ -bool -IsHashColumn(RelationLocInfo *rel_loc_info, char *part_col_name) -{ - bool ret_value = false; - - if (!rel_loc_info || !part_col_name) - ret_value = false; - else if (rel_loc_info->locatorType != LOCATOR_TYPE_HASH) - ret_value = false; - else - ret_value = !strcmp(part_col_name, rel_loc_info->partAttrName); - - return ret_value; -} - - -/* - * IsHashColumnForRelId - return whether or not column for relation is hashed. - * - */ -bool -IsHashColumnForRelId(Oid relid, char *part_col_name) -{ - RelationLocInfo *rel_loc_info = GetRelationLocInfo(relid); - - return IsHashColumn(rel_loc_info, part_col_name); -} - -/* * IsDistColumnForRelId - return whether or not column for relation is used for hash or modulo distribution * */ bool IsDistColumnForRelId(Oid relid, char *part_col_name) { - bool bRet; RelationLocInfo *rel_loc_info; - rel_loc_info = GetRelationLocInfo(relid); - bRet = false; + /* if no column is specified, we're done */ + if (!part_col_name) + return false; + + /* if no locator, we're done too */ + if (!(rel_loc_info = GetRelationLocInfo(relid))) + return false; + + /* is the table distributed by column value */ + if (!IsRelationDistributedByValue(rel_loc_info)) + return false; - bRet = IsHashColumn(rel_loc_info, part_col_name); - if (bRet == false) - IsModuloColumn(rel_loc_info, part_col_name); - return bRet; + /* does the column name match the distribution column */ + return !strcmp(part_col_name, rel_loc_info->partAttrName); } @@ -348,37 +322,6 @@ GetRelationModuloColumn(RelationLocInfo * rel_loc_info) } /* - * IsModuloColumn - return whether or not column for relation is used for modulo distribution. - * - */ -bool -IsModuloColumn(RelationLocInfo *rel_loc_info, char *part_col_name) -{ - bool ret_value = false; - - if (!rel_loc_info || !part_col_name) - ret_value = false; - else if (rel_loc_info->locatorType != LOCATOR_TYPE_MODULO) - ret_value = false; - else - ret_value = !strcmp(part_col_name, rel_loc_info->partAttrName); - - return ret_value; -} - - -/* - * IsModuloColumnForRelId - return whether or not column for relation is used for modulo distribution. - */ -bool -IsModuloColumnForRelId(Oid relid, char *part_col_name) -{ - RelationLocInfo *rel_loc_info = GetRelationLocInfo(relid); - - return IsModuloColumn(rel_loc_info, part_col_name); -} - -/* * Update the round robin node for the relation * * PGXCTODO - may not want to bother with locking here, we could track diff --git a/src/include/pgxc/locator.h b/src/include/pgxc/locator.h index 5062cebe83..21c7e3fe1d 100644 --- a/src/include/pgxc/locator.h +++ b/src/include/pgxc/locator.h @@ -162,8 +162,6 @@ extern RelationLocInfo *CopyRelationLocInfo(RelationLocInfo *src_info); extern char GetRelationLocType(Oid relid); extern bool IsTableDistOnPrimary(RelationLocInfo *rel_loc_info); extern bool IsLocatorInfoEqual(RelationLocInfo *rel_loc_info1, RelationLocInfo *rel_loc_info2); -extern bool IsHashColumn(RelationLocInfo *rel_loc_info, char *part_col_name); -extern bool IsHashColumnForRelId(Oid relid, char *part_col_name); extern int GetRoundRobinNode(Oid relid); extern ExecNodes *GetRelationNodes(RelationLocInfo *rel_loc_info, Datum valueForDistCol, @@ -184,8 +182,6 @@ extern void FreeRelationLocInfo(RelationLocInfo *relationLocInfo); extern bool IsTypeModuloDistributable(Oid col_type); extern char *GetRelationModuloColumn(RelationLocInfo *rel_loc_info); -extern bool IsModuloColumn(RelationLocInfo *rel_loc_info, char *part_col_name); -extern bool IsModuloColumnForRelId(Oid relid, char *part_col_name); extern char *GetRelationDistColumn(RelationLocInfo *rel_loc_info); extern bool IsDistColumnForRelId(Oid relid, char *part_col_name); extern void FreeExecNodes(ExecNodes **exec_nodes); diff --git a/src/test/regress/expected/xl_alter_table.out b/src/test/regress/expected/xl_alter_table.out index 6d578b898a..edfe8b6d13 100755 --- a/src/test/regress/expected/xl_alter_table.out +++ b/src/test/regress/expected/xl_alter_table.out @@ -82,6 +82,8 @@ CREATE TABLE xl_at2m ( product_no INT8, product_id INT2 ) DISTRIBUTE BY MODULO (product_id); +ALTER TABLE xl_at2m DROP COLUMN product_id;--fail - distribution column cannot be dropped. +ERROR: Distribution column cannot be dropped ALTER TABLE xl_at2m DISTRIBUTE BY HASH(product_id); ALTER TABLE xl_at2m DISTRIBUTE BY MODULO(product_id); ALTER TABLE xl_at2m DROP COLUMN product_no; diff --git a/src/test/regress/sql/xl_alter_table.sql b/src/test/regress/sql/xl_alter_table.sql index 1f1c112b2b..5e2477cc5e 100755 --- a/src/test/regress/sql/xl_alter_table.sql +++ b/src/test/regress/sql/xl_alter_table.sql @@ -137,6 +137,8 @@ CREATE TABLE xl_at2m ( product_id INT2 ) DISTRIBUTE BY MODULO (product_id); +ALTER TABLE xl_at2m DROP COLUMN product_id;--fail - distribution column cannot be dropped. + ALTER TABLE xl_at2m DISTRIBUTE BY HASH(product_id); ALTER TABLE xl_at2m DISTRIBUTE BY MODULO(product_id); |