Commit 2ea179f3 authored by Alvaro Herrera's avatar Alvaro Herrera

Support optional FROM/IN in FETCH and MOVE

The main motivation for this is that it's required for Informix compatibility
in ECPG.

This patch makes the ECPG and core grammars a bit closer to one another for
these productions.

Author: Zoltan Boszormenyi
parent 90bfe999
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.690 2009/11/09 18:38:48 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.691 2009/11/11 19:25:40 alvherre Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -332,7 +332,7 @@ static TypeName *TableFuncTypeName(List *columns); ...@@ -332,7 +332,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <ival> opt_column event cursor_options opt_hold opt_set_data %type <ival> opt_column event cursor_options opt_hold opt_set_data
%type <objtype> reindex_type drop_type comment_type %type <objtype> reindex_type drop_type comment_type
%type <node> fetch_direction limit_clause select_limit_value %type <node> fetch_args limit_clause select_limit_value
offset_clause select_offset_value offset_clause select_offset_value
select_offset_value2 opt_select_fetch_first_value select_offset_value2 opt_select_fetch_first_value
%type <ival> row_or_rows first_or_next %type <ival> row_or_rows first_or_next
...@@ -4180,142 +4180,144 @@ comment_text: ...@@ -4180,142 +4180,144 @@ comment_text:
* *
*****************************************************************************/ *****************************************************************************/
FetchStmt: FETCH fetch_direction from_in name FetchStmt: FETCH fetch_args
{ {
FetchStmt *n = (FetchStmt *) $2; FetchStmt *n = (FetchStmt *) $2;
n->portalname = $4;
n->ismove = FALSE;
$$ = (Node *)n;
}
| FETCH name
{
FetchStmt *n = makeNode(FetchStmt);
n->direction = FETCH_FORWARD;
n->howMany = 1;
n->portalname = $2;
n->ismove = FALSE; n->ismove = FALSE;
$$ = (Node *)n; $$ = (Node *)n;
} }
| MOVE fetch_direction from_in name | MOVE fetch_args
{ {
FetchStmt *n = (FetchStmt *) $2; FetchStmt *n = (FetchStmt *) $2;
n->portalname = $4;
n->ismove = TRUE; n->ismove = TRUE;
$$ = (Node *)n; $$ = (Node *)n;
} }
| MOVE name ;
fetch_args: name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $1;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = 1; n->howMany = 1;
n->portalname = $2;
n->ismove = TRUE;
$$ = (Node *)n; $$ = (Node *)n;
} }
; | from_in name
fetch_direction:
/*EMPTY*/
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $2;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = 1; n->howMany = 1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| NEXT | NEXT opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = 1; n->howMany = 1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| PRIOR | PRIOR opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_BACKWARD; n->direction = FETCH_BACKWARD;
n->howMany = 1; n->howMany = 1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| FIRST_P | FIRST_P opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_ABSOLUTE; n->direction = FETCH_ABSOLUTE;
n->howMany = 1; n->howMany = 1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| LAST_P | LAST_P opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_ABSOLUTE; n->direction = FETCH_ABSOLUTE;
n->howMany = -1; n->howMany = -1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ABSOLUTE_P SignedIconst | ABSOLUTE_P SignedIconst opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $4;
n->direction = FETCH_ABSOLUTE; n->direction = FETCH_ABSOLUTE;
n->howMany = $2; n->howMany = $2;
$$ = (Node *)n; $$ = (Node *)n;
} }
| RELATIVE_P SignedIconst | RELATIVE_P SignedIconst opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $4;
n->direction = FETCH_RELATIVE; n->direction = FETCH_RELATIVE;
n->howMany = $2; n->howMany = $2;
$$ = (Node *)n; $$ = (Node *)n;
} }
| SignedIconst | SignedIconst opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = $1; n->howMany = $1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALL | ALL opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = FETCH_ALL; n->howMany = FETCH_ALL;
$$ = (Node *)n; $$ = (Node *)n;
} }
| FORWARD | FORWARD opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = 1; n->howMany = 1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| FORWARD SignedIconst | FORWARD SignedIconst opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $4;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = $2; n->howMany = $2;
$$ = (Node *)n; $$ = (Node *)n;
} }
| FORWARD ALL | FORWARD ALL opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $4;
n->direction = FETCH_FORWARD; n->direction = FETCH_FORWARD;
n->howMany = FETCH_ALL; n->howMany = FETCH_ALL;
$$ = (Node *)n; $$ = (Node *)n;
} }
| BACKWARD | BACKWARD opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $3;
n->direction = FETCH_BACKWARD; n->direction = FETCH_BACKWARD;
n->howMany = 1; n->howMany = 1;
$$ = (Node *)n; $$ = (Node *)n;
} }
| BACKWARD SignedIconst | BACKWARD SignedIconst opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $4;
n->direction = FETCH_BACKWARD; n->direction = FETCH_BACKWARD;
n->howMany = $2; n->howMany = $2;
$$ = (Node *)n; $$ = (Node *)n;
} }
| BACKWARD ALL | BACKWARD ALL opt_from_in name
{ {
FetchStmt *n = makeNode(FetchStmt); FetchStmt *n = makeNode(FetchStmt);
n->portalname = $4;
n->direction = FETCH_BACKWARD; n->direction = FETCH_BACKWARD;
n->howMany = FETCH_ALL; n->howMany = FETCH_ALL;
$$ = (Node *)n; $$ = (Node *)n;
...@@ -4326,6 +4328,10 @@ from_in: FROM {} ...@@ -4326,6 +4328,10 @@ from_in: FROM {}
| IN_P {} | IN_P {}
; ;
opt_from_in: from_in {}
| /* EMPTY */ {}
;
/***************************************************************************** /*****************************************************************************
* *
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.addons,v 1.6 2009/11/05 23:24:27 tgl Exp $ */ /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.addons,v 1.7 2009/11/11 19:25:40 alvherre Exp $ */
ECPG: stmtClosePortalStmt block ECPG: stmtClosePortalStmt block
{ {
...@@ -206,16 +206,38 @@ ECPG: ConstraintAttributeSpecConstraintTimeSpecConstraintDeferrabilitySpec addon ...@@ -206,16 +206,38 @@ ECPG: ConstraintAttributeSpecConstraintTimeSpecConstraintDeferrabilitySpec addon
if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 ) if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
mmerror(PARSE_ERROR, ET_ERROR, "constraint declared INITIALLY DEFERRED must be DEFERRABLE"); mmerror(PARSE_ERROR, ET_ERROR, "constraint declared INITIALLY DEFERRED must be DEFERRABLE");
ECPG: var_valueNumericOnly addon ECPG: var_valueNumericOnly addon
ECPG: fetch_directionSignedIconst addon
if ($1[0] == '$') if ($1[0] == '$')
{ {
free($1); free($1);
$1 = make_str("$0"); $1 = make_str("$0");
} }
ECPG: fetch_directionABSOLUTE_PSignedIconst addon ECPG: fetch_argsname addon
ECPG: fetch_directionRELATIVE_PSignedIconst addon add_additional_variables($1, false);
ECPG: fetch_directionFORWARDSignedIconst addon ECPG: fetch_argsfrom_inname addon
ECPG: fetch_directionBACKWARDSignedIconst addon add_additional_variables($2, false);
ECPG: fetch_argsNEXTopt_from_inname addon
ECPG: fetch_argsPRIORopt_from_inname addon
ECPG: fetch_argsFIRST_Popt_from_inname addon
ECPG: fetch_argsLAST_Popt_from_inname addon
ECPG: fetch_argsALLopt_from_inname addon
ECPG: fetch_argsFORWARDopt_from_inname addon
ECPG: fetch_argsBACKWARDopt_from_inname addon
add_additional_variables($3, false);
ECPG: fetch_argsSignedIconstopt_from_inname addon
add_additional_variables($3, false);
if ($1[0] == '$')
{
free($1);
$1 = make_str("$0");
}
ECPG: fetch_argsFORWARDALLopt_from_inname addon
ECPG: fetch_argsBACKWARDALLopt_from_inname addon
add_additional_variables($4, false);
ECPG: fetch_argsABSOLUTE_PSignedIconstopt_from_inname addon
ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_inname addon
ECPG: fetch_argsFORWARDSignedIconstopt_from_inname addon
ECPG: fetch_argsBACKWARDSignedIconstopt_from_inname addon
add_additional_variables($4, false);
if ($2[0] == '$') if ($2[0] == '$')
{ {
free($2); free($2);
...@@ -336,47 +358,11 @@ ECPG: VariableShowStmtSHOWALL block ...@@ -336,47 +358,11 @@ ECPG: VariableShowStmtSHOWALL block
mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL is not implemented"); mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL is not implemented");
$$ = EMPTY; $$ = EMPTY;
} }
ECPG: FetchStmtFETCHfetch_directionfrom_inname block ECPG: FetchStmtMOVEfetch_args rule
{ | FETCH fetch_args ecpg_into
add_additional_variables($4, false);
$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
}
ECPG: FetchStmtFETCHname block
{ {
add_additional_variables($2, false); $$ = cat2_str(make_str("fetch"), $2);
$$ = cat_str(2, make_str("fetch"), $2);
} }
ECPG: FetchStmtMOVEname rule
| FETCH fetch_direction from_in name ecpg_into
{
add_additional_variables($4, false);
$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
}
| FETCH fetch_direction name ecpg_into
{
add_additional_variables($3, false);
$$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
}
| FETCH from_in name ecpg_into
{
add_additional_variables($3, false);
$$ = cat_str(3, make_str("fetch"), $2, $3);
}
| FETCH name ecpg_into
{
add_additional_variables($2, false);
$$ = cat2_str(make_str("fetch"), $2);
}
| FETCH fetch_direction name
{
add_additional_variables($3, false);
$$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
}
| FETCH from_in name
{
add_additional_variables($3, false);
$$ = cat_str(3, make_str("fetch"), $2, $3);
}
ECPG: select_limitLIMITselect_limit_value','select_offset_value block ECPG: select_limitLIMITselect_limit_value','select_offset_value block
{ {
mmerror(PARSE_ERROR, ET_WARNING, "no longer supported LIMIT #,# syntax passed to server"); mmerror(PARSE_ERROR, ET_WARNING, "no longer supported LIMIT #,# syntax passed to server");
......
...@@ -158,7 +158,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );} ...@@ -158,7 +158,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );}
while (1) while (1)
{ {
{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward from c", ECPGt_EOIT, { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward c", ECPGt_EOIT,
ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_int,&(i),(long)1,(long)1,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
ECPGt_decimal,&(j),(long)1,(long)1,sizeof(decimal), ECPGt_decimal,&(j),(long)1,(long)1,sizeof(decimal),
......
...@@ -63,7 +63,7 @@ DETAIL: Key (i)=(7) already exists. ...@@ -63,7 +63,7 @@ DETAIL: Key (i)=(7) already exists.
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 95: OK: DECLARE CURSOR [NO_PID]: ecpg_execute on line 95: OK: DECLARE CURSOR
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: query: fetch forward from c; with 0 parameter(s) on connection regress1 [NO_PID]: ecpg_execute on line 57: query: fetch forward c; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: using PQexec [NO_PID]: ecpg_execute on line 57: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
...@@ -75,7 +75,7 @@ DETAIL: Key (i)=(7) already exists. ...@@ -75,7 +75,7 @@ DETAIL: Key (i)=(7) already exists.
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 57: RESULT: test offset: -1; array: yes [NO_PID]: ecpg_get_data on line 57: RESULT: test offset: -1; array: yes
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: query: fetch forward from c; with 0 parameter(s) on connection regress1 [NO_PID]: ecpg_execute on line 57: query: fetch forward c; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: using PQexec [NO_PID]: ecpg_execute on line 57: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
...@@ -87,7 +87,7 @@ DETAIL: Key (i)=(7) already exists. ...@@ -87,7 +87,7 @@ DETAIL: Key (i)=(7) already exists.
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 57: RESULT: a offset: -1; array: yes [NO_PID]: ecpg_get_data on line 57: RESULT: a offset: -1; array: yes
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: query: fetch forward from c; with 0 parameter(s) on connection regress1 [NO_PID]: ecpg_execute on line 57: query: fetch forward c; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: using PQexec [NO_PID]: ecpg_execute on line 57: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: sqlca: code: 0, state: 00000
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment