1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

Do honest transformation and preprocessing of LIMIT/OFFSET clauses,

instead of the former kluge whereby gram.y emitted already-transformed
expressions.  This is needed so that Params appearing in these clauses
actually work correctly.  I suppose some might claim that the side effect
of 'SELECT ... LIMIT 2+2' working is a new feature, but I say this is
a bug fix.
This commit is contained in:
Tom Lane
2003-07-03 19:07:54 +00:00
parent 455891bf96
commit b89140a7ec
8 changed files with 150 additions and 86 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.116 2003/06/16 02:03:37 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.117 2003/07/03 19:07:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -317,10 +317,7 @@ transformJoinOnClause(ParseState *pstate, JoinExpr *j,
save_namespace = pstate->p_namespace;
pstate->p_namespace = makeList2(j->larg, j->rarg);
/* This part is just like transformWhereClause() */
result = transformExpr(pstate, j->quals);
result = coerce_to_boolean(pstate, result, "JOIN/ON");
result = transformWhereClause(pstate, j->quals, "JOIN/ON");
pstate->p_namespace = save_namespace;
@ -945,10 +942,14 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype,
/*
* transformWhereClause -
* transforms the qualification and make sure it is of type Boolean
* Transform the qualification and make sure it is of type boolean.
* Used for WHERE and allied clauses.
*
* constructName does not affect the semantics, but is used in error messages
*/
Node *
transformWhereClause(ParseState *pstate, Node *clause)
transformWhereClause(ParseState *pstate, Node *clause,
const char *constructName)
{
Node *qual;
@ -957,7 +958,55 @@ transformWhereClause(ParseState *pstate, Node *clause)
qual = transformExpr(pstate, clause);
qual = coerce_to_boolean(pstate, qual, "WHERE");
qual = coerce_to_boolean(pstate, qual, constructName);
return qual;
}
/*
* transformLimitClause -
* Transform the expression and make sure it is of type integer.
* Used for LIMIT and allied clauses.
*
* constructName does not affect the semantics, but is used in error messages
*/
Node *
transformLimitClause(ParseState *pstate, Node *clause,
const char *constructName)
{
Node *qual;
if (clause == NULL)
return NULL;
qual = transformExpr(pstate, clause);
qual = coerce_to_integer(pstate, qual, constructName);
/*
* LIMIT can't refer to any vars or aggregates of the current query;
* we don't allow subselects either (though that case would at least
* be sensible)
*/
if (contain_vars_of_level(qual, 0))
{
/* translator: %s is name of a SQL construct, eg LIMIT */
elog(ERROR, "argument of %s must not contain variables",
constructName);
}
if (checkExprHasAggs(qual))
{
/* translator: %s is name of a SQL construct, eg LIMIT */
elog(ERROR, "argument of %s must not contain aggregates",
constructName);
}
if (contain_subplans(qual))
{
/* translator: %s is name of a SQL construct, eg LIMIT */
elog(ERROR, "argument of %s must not contain subselects",
constructName);
}
return qual;
}