From 7d69182adadef754676e29cd844f3cdebaef38c5 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 22 Aug 2018 08:46:58 +0200 Subject: [PATCH v2 2/3] Error position support for partition specifications Add support for error position reporting for partition specifications. --- src/backend/commands/tablecmds.c | 16 +++++++++++----- src/test/regress/expected/create_table.out | 6 ++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 552ad8c592..48743dbfa8 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -478,7 +478,7 @@ static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, Oid oldrelid, void *arg); 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); static void CreateInheritance(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, */ if (stmt->partspec) { + ParseState *pstate; char strategy; int partnatts; AttrNumber partattrs[PARTITION_MAX_KEYS]; @@ -882,6 +883,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, Oid partcollation[PARTITION_MAX_KEYS]; List *partexprs = NIL; + pstate = make_parsestate(NULL); + pstate->p_sourcetext = queryString; + partnatts = list_length(stmt->partspec->partParams); /* Protect fixed-size arrays here and in executor */ @@ -900,7 +904,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, stmt->partspec = transformPartitionSpec(rel, stmt->partspec, &strategy); - ComputePartitionAttrs(rel, stmt->partspec->partParams, + ComputePartitionAttrs(pstate, rel, stmt->partspec->partParams, partattrs, &partexprs, partopclass, partcollation, strategy); @@ -13695,7 +13699,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) * Expressions in the PartitionElems must be parse-analyzed already. */ static void -ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, +ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs, List **partexprs, Oid *partopclass, Oid *partcollation, char strategy) { @@ -13722,14 +13726,16 @@ ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), 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); if (attform->attnum <= 0) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("cannot use system column \"%s\" in partition key", - pelem->name))); + pelem->name), + parser_errposition(pstate, pelem->location))); partattrs[attn] = attform->attnum; atttype = attform->atttypid; diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index 8927b21ba2..744b9990a6 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -328,11 +328,15 @@ CREATE TABLE partitioned ( a int ) PARTITION BY RANGE (b); ERROR: column "b" named in partition key does not exist +LINE 3: ) PARTITION BY RANGE (b); + ^ -- cannot use system columns in partition key CREATE TABLE partitioned ( a int ) PARTITION BY RANGE (xmin); ERROR: cannot use system column "xmin" in partition key +LINE 3: ) PARTITION BY RANGE (xmin); + ^ -- functions in key must be immutable CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL; CREATE TABLE partitioned ( @@ -719,6 +723,8 @@ SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::reg -- specify PARTITION BY for a partition 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 +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 a level-2 partition CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10); -- 2.18.0