mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Added LIMIT/OFFSET functionality including new regression test for it.
Removed CURRENT keyword for rule queries and changed rules regression accordingly. CURRENT has beed announced to disappear in v6.5. Jan
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: analyze.c,v 1.97 1999/02/02 03:44:32 momjian Exp $
|
||||
* $Id: analyze.c,v 1.98 1999/02/08 14:14:11 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -205,7 +205,11 @@ transformStmt(ParseState *pstate, Node *parseTree)
|
||||
|
||||
case T_SelectStmt:
|
||||
if (!((SelectStmt *) parseTree)->portalname)
|
||||
{
|
||||
result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
|
||||
result->limitOffset = ((SelectStmt *)parseTree)->limitOffset;
|
||||
result->limitCount = ((SelectStmt *)parseTree)->limitCount;
|
||||
}
|
||||
else
|
||||
result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
|
||||
break;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.53 1999/02/07 19:02:19 wieck Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.54 1999/02/08 14:14:12 wieck Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/numeric.h"
|
||||
#include "parser/analyze.h"
|
||||
#include "catalog/pg_type.h"
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
#include "mb/pg_wchar.h"
|
||||
@@ -168,7 +169,8 @@ Oid param_type(int t); /* used in parse_expr.c */
|
||||
sort_clause, sortby_list, index_params, index_list, name_list,
|
||||
from_clause, from_list, opt_array_bounds, nest_array_bounds,
|
||||
expr_list, attrs, res_target_list, res_target_list2,
|
||||
def_list, opt_indirection, group_clause, TriggerFuncArgs
|
||||
def_list, opt_indirection, group_clause, TriggerFuncArgs,
|
||||
opt_select_limit
|
||||
|
||||
%type <node> func_return
|
||||
%type <boolean> set_opt
|
||||
@@ -197,6 +199,8 @@ Oid param_type(int t); /* used in parse_expr.c */
|
||||
|
||||
%type <ival> fetch_how_many
|
||||
|
||||
%type <node> select_limit_value, select_offset_value
|
||||
|
||||
%type <list> OptSeqList
|
||||
%type <defelt> OptSeqElem
|
||||
|
||||
@@ -306,9 +310,10 @@ Oid param_type(int t); /* used in parse_expr.c */
|
||||
DATABASE, DELIMITERS, DO, EACH, ENCODING, EXPLAIN, EXTEND,
|
||||
FORWARD, FUNCTION, HANDLER,
|
||||
INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
|
||||
LANCOMPILER, LISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE, MINVALUE, MOVE,
|
||||
LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
|
||||
MAXVALUE, MINVALUE, MOVE,
|
||||
NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
|
||||
OIDS, OPERATOR, PASSWORD, PROCEDURAL,
|
||||
OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
|
||||
RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
|
||||
SEQUENCE, SERIAL, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
|
||||
UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
|
||||
@@ -2731,7 +2736,7 @@ opt_of: OF columnList
|
||||
*
|
||||
* The rule returns a SelectStmt Node having the set operations attached to
|
||||
* unionClause and intersectClause (NIL if no set operations were present) */
|
||||
SelectStmt: select_w_o_sort sort_clause for_update_clause
|
||||
SelectStmt: select_w_o_sort sort_clause for_update_clause opt_select_limit
|
||||
{
|
||||
/* There were no set operations, so just attach the sortClause */
|
||||
if IsA($1, SelectStmt)
|
||||
@@ -2739,6 +2744,8 @@ SelectStmt: select_w_o_sort sort_clause for_update_clause
|
||||
SelectStmt *n = (SelectStmt *)$1;
|
||||
n->sortClause = $2;
|
||||
n->forUpdate = $3;
|
||||
n->limitOffset = nth(0, $4);
|
||||
n->limitCount = nth(1, $4);
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* There were set operations: The root of the operator tree
|
||||
@@ -2920,6 +2927,84 @@ OptUseOp: USING Op { $$ = $2; }
|
||||
| /*EMPTY*/ { $$ = "<"; /*default*/ }
|
||||
;
|
||||
|
||||
|
||||
opt_select_limit: LIMIT select_limit_value ',' select_offset_value
|
||||
{ $$ = lappend(lappend(NIL, $4), $2); }
|
||||
| LIMIT select_limit_value OFFSET select_offset_value
|
||||
{ $$ = lappend(lappend(NIL, $4), $2); }
|
||||
| LIMIT select_limit_value
|
||||
{ $$ = lappend(lappend(NIL, NULL), $2); }
|
||||
| OFFSET select_offset_value LIMIT select_limit_value
|
||||
{ $$ = lappend(lappend(NIL, $2), $4); }
|
||||
| OFFSET select_offset_value
|
||||
{ $$ = lappend(lappend(NIL, $2), NULL); }
|
||||
| /* EMPTY */
|
||||
{ $$ = lappend(lappend(NIL, NULL), NULL); }
|
||||
;
|
||||
|
||||
select_limit_value: Iconst
|
||||
{
|
||||
Const *n = makeNode(Const);
|
||||
|
||||
if ($1 < 1)
|
||||
elog(ERROR, "selection limit must be ALL or a positive integer value > 0");
|
||||
|
||||
n->consttype = INT4OID;
|
||||
n->constlen = sizeof(int4);
|
||||
n->constvalue = (Datum)$1;
|
||||
n->constisnull = FALSE;
|
||||
n->constbyval = TRUE;
|
||||
n->constisset = FALSE;
|
||||
n->constiscast = FALSE;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALL
|
||||
{
|
||||
Const *n = makeNode(Const);
|
||||
|
||||
n->consttype = INT4OID;
|
||||
n->constlen = sizeof(int4);
|
||||
n->constvalue = (Datum)0;
|
||||
n->constisnull = FALSE;
|
||||
n->constbyval = TRUE;
|
||||
n->constisset = FALSE;
|
||||
n->constiscast = FALSE;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| PARAM
|
||||
{
|
||||
Param *n = makeNode(Param);
|
||||
|
||||
n->paramkind = PARAM_NUM;
|
||||
n->paramid = $1;
|
||||
n->paramtype = INT4OID;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
select_offset_value: Iconst
|
||||
{
|
||||
Const *n = makeNode(Const);
|
||||
|
||||
n->consttype = INT4OID;
|
||||
n->constlen = sizeof(int4);
|
||||
n->constvalue = (Datum)$1;
|
||||
n->constisnull = FALSE;
|
||||
n->constbyval = TRUE;
|
||||
n->constisset = FALSE;
|
||||
n->constiscast = FALSE;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| PARAM
|
||||
{
|
||||
Param *n = makeNode(Param);
|
||||
|
||||
n->paramkind = PARAM_NUM;
|
||||
n->paramid = $1;
|
||||
n->paramtype = INT4OID;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
/*
|
||||
* jimmy bell-style recursive queries aren't supported in the
|
||||
* current system.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.52 1999/02/02 03:44:42 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.53 1999/02/08 14:14:13 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -68,9 +68,6 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"createdb", CREATEDB},
|
||||
{"createuser", CREATEUSER},
|
||||
{"cross", CROSS},
|
||||
{"current", CURRENT}, /* 6.4 to 6.5 is migration time! CURRENT
|
||||
* will be removed in 6.5! Use OLD keyword
|
||||
* in rules. Jan */
|
||||
{"current_date", CURRENT_DATE},
|
||||
{"current_time", CURRENT_TIME},
|
||||
{"current_timestamp", CURRENT_TIMESTAMP},
|
||||
@@ -139,6 +136,7 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"left", LEFT},
|
||||
{"level", LEVEL},
|
||||
{"like", LIKE},
|
||||
{"limit", LIMIT},
|
||||
{"listen", LISTEN},
|
||||
{"load", LOAD},
|
||||
{"local", LOCAL},
|
||||
@@ -168,6 +166,7 @@ static ScanKeyword ScanKeywords[] = {
|
||||
{"nullif", NULLIF},
|
||||
{"numeric", NUMERIC},
|
||||
{"of", OF},
|
||||
{"offset", OFFSET},
|
||||
{"oids", OIDS},
|
||||
{"old", CURRENT},
|
||||
{"on", ON},
|
||||
|
||||
Reference in New Issue
Block a user