On Fri, 23 Jun 2017 15:57:54 +0900
Yugo Nagata <nag...@sraoss.co.jp> wrote:

> Hi,
> 
> When we create a range partitioned table, we cannot use
> a column more than once in the partition key.
> 
>  postgres=# create table t (i int) partition by range(i,i);
>  ERROR:  column "i" appears more than once in partition key
> 
> However, I can use same expression more than once in partition key.
> 
> postgres=# create table t (i int) partition by range((i),(i));
> CREATE TABLE
> 
> Although this can be blocked by the attached parch, for example,
> the following is still possible.

I forgot to attach it.

> 
> postgres=# create table t (i int) partition by range((i),i);
> CREATE TABLE
> 
> Can these definition be a problem in the internal of partitioning?
> If not, we might not need to check column that apears more than once 
> in the partition key.
> 
> Regards,
> 
> 
> 
> -- 
> Yugo Nagata <nag...@sraoss.co.jp>


-- 
Yugo Nagata <nag...@sraoss.co.jp>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 7d9c769..dc4540b 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -13171,6 +13171,19 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
 		PartitionElem *pelem = castNode(PartitionElem, lfirst(l));
 		ListCell   *lc;
 
+		if (pelem->expr)
+		{
+			/* Copy, to avoid scribbling on the input */
+			pelem = copyObject(pelem);
+
+			/* Now do parse transformation of the expression */
+			pelem->expr = transformExpr(pstate, pelem->expr,
+										EXPR_KIND_PARTITION_EXPRESSION);
+
+			/* we have to fix its collations too */
+			assign_expr_collations(pstate, pelem->expr);
+		}
+
 		/* Check for PARTITION BY ... (foo, foo) */
 		foreach(lc, newspec->partParams)
 		{
@@ -13183,19 +13196,11 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy)
 						 errmsg("column \"%s\" appears more than once in partition key",
 								pelem->name),
 						 parser_errposition(pstate, pelem->location)));
-		}
-
-		if (pelem->expr)
-		{
-			/* Copy, to avoid scribbling on the input */
-			pelem = copyObject(pelem);
-
-			/* Now do parse transformation of the expression */
-			pelem->expr = transformExpr(pstate, pelem->expr,
-										EXPR_KIND_PARTITION_EXPRESSION);
-
-			/* we have to fix its collations too */
-			assign_expr_collations(pstate, pelem->expr);
+			else if (pelem->expr && pparam->expr && equal(pelem->expr, pparam->expr))
+				ereport(ERROR,
+						(errcode(ERRCODE_DUPLICATE_COLUMN),
+						 errmsg("same expression appears more than once in partition key"),
+						 parser_errposition(pstate, pelem->location)));
 		}
 
 		newspec->partParams = lappend(newspec->partParams, pelem);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to