diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-03-24 15:29:52 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-03-24 15:29:52 -0400 |
commit | 3bba9ce945a702ab116fcedb9c0b970ecd69c9dd (patch) | |
tree | 577ec34231982a915e13db6ea8ed98521ebc2150 /src/backend/commands | |
parent | 472671e133da77f280e87cb47c6544c75572df6b (diff) | |
download | postgresql-3bba9ce945a702ab116fcedb9c0b970ecd69c9dd.tar.gz postgresql-3bba9ce945a702ab116fcedb9c0b970ecd69c9dd.zip |
Clean up handling of COLLATE clauses in index column definitions.
Ensure that COLLATE at the top level of an index expression is treated the
same as a grammatically separate COLLATE. Fix bogus reverse-parsing logic
in pg_get_indexdef.
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/indexcmds.c | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index dafa6d5efc1..cfcce559675 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -837,49 +837,62 @@ ComputeIndexAttrs(IndexInfo *indexInfo, attcollation = attform->attcollation; ReleaseSysCache(atttuple); } - else if (attribute->expr && IsA(attribute->expr, Var) && - ((Var *) attribute->expr)->varattno != InvalidAttrNumber) - { - /* Tricky tricky, he wrote (column) ... treat as simple attr */ - Var *var = (Var *) attribute->expr; - - indexInfo->ii_KeyAttrNumbers[attn] = var->varattno; - atttype = get_atttype(relId, var->varattno); - attcollation = var->varcollid; - } else { /* Index expression */ - Assert(attribute->expr != NULL); - indexInfo->ii_KeyAttrNumbers[attn] = 0; /* marks expression */ - indexInfo->ii_Expressions = lappend(indexInfo->ii_Expressions, - attribute->expr); - atttype = exprType(attribute->expr); - attcollation = exprCollation(attribute->expr); + Node *expr = attribute->expr; - /* - * We don't currently support generation of an actual query plan - * for an index expression, only simple scalar expressions; hence - * these restrictions. - */ - if (contain_subplans(attribute->expr)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot use subquery in index expression"))); - if (contain_agg_clause(attribute->expr)) - ereport(ERROR, - (errcode(ERRCODE_GROUPING_ERROR), - errmsg("cannot use aggregate function in index expression"))); + Assert(expr != NULL); + atttype = exprType(expr); + attcollation = exprCollation(expr); /* - * A expression using mutable functions is probably wrong, since - * if you aren't going to get the same result for the same data - * every time, it's not clear what the index entries mean at all. + * Strip any top-level COLLATE clause. This ensures that we treat + * "x COLLATE y" and "(x COLLATE y)" alike. */ - if (CheckMutability((Expr *) attribute->expr)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("functions in index expression must be marked IMMUTABLE"))); + while (IsA(expr, CollateExpr)) + expr = (Node *) ((CollateExpr *) expr)->arg; + + if (IsA(expr, Var) && + ((Var *) expr)->varattno != InvalidAttrNumber) + { + /* + * User wrote "(column)" or "(column COLLATE something)". + * Treat it like simple attribute anyway. + */ + indexInfo->ii_KeyAttrNumbers[attn] = ((Var *) expr)->varattno; + } + else + { + indexInfo->ii_KeyAttrNumbers[attn] = 0; /* marks expression */ + indexInfo->ii_Expressions = lappend(indexInfo->ii_Expressions, + expr); + + /* + * We don't currently support generation of an actual query + * plan for an index expression, only simple scalar + * expressions; hence these restrictions. + */ + if (contain_subplans(expr)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot use subquery in index expression"))); + if (contain_agg_clause(expr)) + ereport(ERROR, + (errcode(ERRCODE_GROUPING_ERROR), + errmsg("cannot use aggregate function in index expression"))); + + /* + * A expression using mutable functions is probably wrong, + * since if you aren't going to get the same result for the + * same data every time, it's not clear what the index entries + * mean at all. + */ + if (CheckMutability((Expr *) expr)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("functions in index expression must be marked IMMUTABLE"))); + } } /* |