aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_clause.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2020-04-07 16:22:13 -0400
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2020-04-07 16:22:13 -0400
commit357889eb17bb9c9336c4f324ceb1651da616fe57 (patch)
treeef30422c7a6ebc2844492bd045ffbfeb30e54516 /src/backend/parser/parse_clause.c
parent26a944cf29ba67bb49f42656dd2be98fe2485f5f (diff)
downloadpostgresql-357889eb17bb9c9336c4f324ceb1651da616fe57.tar.gz
postgresql-357889eb17bb9c9336c4f324ceb1651da616fe57.zip
Support FETCH FIRST WITH TIES
WITH TIES is an option to the FETCH FIRST N ROWS clause (the SQL standard's spelling of LIMIT), where you additionally get rows that compare equal to the last of those N rows by the columns in the mandatory ORDER BY clause. There was a proposal by Andrew Gierth to implement this functionality in a more powerful way that would yield more features, but the other patch had not been finished at this time, so we decided to use this one for now in the spirit of incremental development. Author: Surafel Temesgen <surafel3000@gmail.com> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Reviewed-by: Tomas Vondra <tomas.vondra@2ndquadrant.com> Discussion: https://postgr.es/m/CALAY4q9ky7rD_A4vf=FVQvCGngm3LOes-ky0J6euMrg=_Se+ag@mail.gmail.com Discussion: https://postgr.es/m/87o8wvz253.fsf@news-spur.riddles.org.uk
Diffstat (limited to 'src/backend/parser/parse_clause.c')
-rw-r--r--src/backend/parser/parse_clause.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 36a3efff876..6fff13479e4 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -1745,7 +1745,8 @@ transformWhereClause(ParseState *pstate, Node *clause,
*/
Node *
transformLimitClause(ParseState *pstate, Node *clause,
- ParseExprKind exprKind, const char *constructName)
+ ParseExprKind exprKind, const char *constructName,
+ LimitOption limitOption)
{
Node *qual;
@@ -1759,6 +1760,18 @@ transformLimitClause(ParseState *pstate, Node *clause,
/* LIMIT can't refer to any variables of the current query */
checkExprIsVarFree(pstate, qual, constructName);
+ /*
+ * Don't allow NULLs in FETCH FIRST .. WITH TIES. This test is ugly and
+ * extremely simplistic, in that you can pass a NULL anyway by hiding it
+ * inside an expression -- but this protects ruleutils against emitting an
+ * unadorned NULL that's not accepted back by the grammar.
+ */
+ if (exprKind == EXPR_KIND_LIMIT && limitOption == LIMIT_OPTION_WITH_TIES &&
+ IsA(clause, A_Const) && ((A_Const *) clause)->val.type == T_Null)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE),
+ errmsg("row count cannot be NULL in FETCH FIRST ... WITH TIES clause")));
+
return qual;
}