Commit 1e5e4efd authored by Peter Eisentraut's avatar Peter Eisentraut

Error position support for partition specifications

Add support for error position reporting for partition specifications.
Reviewed-by: default avatarFabien COELHO <coelho@cri.ensmp.fr>
parent a4a232b1
...@@ -478,7 +478,7 @@ static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, ...@@ -478,7 +478,7 @@ static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid,
static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid,
Oid oldrelid, void *arg); Oid oldrelid, void *arg);
static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy); static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy);
static void ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, static void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs,
List **partexprs, Oid *partopclass, Oid *partcollation, char strategy); List **partexprs, Oid *partopclass, Oid *partcollation, char strategy);
static void CreateInheritance(Relation child_rel, Relation parent_rel); static void CreateInheritance(Relation child_rel, Relation parent_rel);
static void RemoveInheritance(Relation child_rel, Relation parent_rel); static void RemoveInheritance(Relation child_rel, Relation parent_rel);
...@@ -875,6 +875,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ...@@ -875,6 +875,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
*/ */
if (stmt->partspec) if (stmt->partspec)
{ {
ParseState *pstate;
char strategy; char strategy;
int partnatts; int partnatts;
AttrNumber partattrs[PARTITION_MAX_KEYS]; AttrNumber partattrs[PARTITION_MAX_KEYS];
...@@ -882,6 +883,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ...@@ -882,6 +883,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
Oid partcollation[PARTITION_MAX_KEYS]; Oid partcollation[PARTITION_MAX_KEYS];
List *partexprs = NIL; List *partexprs = NIL;
pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString;
partnatts = list_length(stmt->partspec->partParams); partnatts = list_length(stmt->partspec->partParams);
/* Protect fixed-size arrays here and in executor */ /* Protect fixed-size arrays here and in executor */
...@@ -900,7 +904,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ...@@ -900,7 +904,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
stmt->partspec = transformPartitionSpec(rel, stmt->partspec, stmt->partspec = transformPartitionSpec(rel, stmt->partspec,
&strategy); &strategy);
ComputePartitionAttrs(rel, stmt->partspec->partParams, ComputePartitionAttrs(pstate, rel, stmt->partspec->partParams,
partattrs, &partexprs, partopclass, partattrs, &partexprs, partopclass,
partcollation, strategy); partcollation, strategy);
...@@ -13695,7 +13699,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) ...@@ -13695,7 +13699,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
* Expressions in the PartitionElems must be parse-analyzed already. * Expressions in the PartitionElems must be parse-analyzed already.
*/ */
static void static void
ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs,
List **partexprs, Oid *partopclass, Oid *partcollation, List **partexprs, Oid *partopclass, Oid *partcollation,
char strategy) char strategy)
{ {
...@@ -13722,14 +13726,16 @@ ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, ...@@ -13722,14 +13726,16 @@ ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs,
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN), (errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" named in partition key does not exist", errmsg("column \"%s\" named in partition key does not exist",
pelem->name))); pelem->name),
parser_errposition(pstate, pelem->location)));
attform = (Form_pg_attribute) GETSTRUCT(atttuple); attform = (Form_pg_attribute) GETSTRUCT(atttuple);
if (attform->attnum <= 0) if (attform->attnum <= 0)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("cannot use system column \"%s\" in partition key", errmsg("cannot use system column \"%s\" in partition key",
pelem->name))); pelem->name),
parser_errposition(pstate, pelem->location)));
partattrs[attn] = attform->attnum; partattrs[attn] = attform->attnum;
atttype = attform->atttypid; atttype = attform->atttypid;
......
...@@ -328,11 +328,15 @@ CREATE TABLE partitioned ( ...@@ -328,11 +328,15 @@ CREATE TABLE partitioned (
a int a int
) PARTITION BY RANGE (b); ) PARTITION BY RANGE (b);
ERROR: column "b" named in partition key does not exist ERROR: column "b" named in partition key does not exist
LINE 3: ) PARTITION BY RANGE (b);
^
-- cannot use system columns in partition key -- cannot use system columns in partition key
CREATE TABLE partitioned ( CREATE TABLE partitioned (
a int a int
) PARTITION BY RANGE (xmin); ) PARTITION BY RANGE (xmin);
ERROR: cannot use system column "xmin" in partition key ERROR: cannot use system column "xmin" in partition key
LINE 3: ) PARTITION BY RANGE (xmin);
^
-- functions in key must be immutable -- functions in key must be immutable
CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL; CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL;
CREATE TABLE partitioned ( CREATE TABLE partitioned (
...@@ -719,6 +723,8 @@ SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::reg ...@@ -719,6 +723,8 @@ SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::reg
-- specify PARTITION BY for a partition -- specify PARTITION BY for a partition
CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c); CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c);
ERROR: column "c" named in partition key does not exist ERROR: column "c" named in partition key does not exist
LINE 1: ...TITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c);
^
CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b)); CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b));
-- create a level-2 partition -- create a level-2 partition
CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10); CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment