mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Error position support for partition specifications
Add support for error position reporting for partition specifications. Reviewed-by: Fabien COELHO <coelho@cri.ensmp.fr>
This commit is contained in:
		@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user