diff -dcrpN pgsql.orig/src/backend/parser/gram.y pgsql.ufd-opt-fromin-fetch/src/backend/parser/gram.y
*** pgsql.orig/src/backend/parser/gram.y	2009-09-23 19:25:40.000000000 +0200
--- pgsql.ufd-opt-fromin-fetch/src/backend/parser/gram.y	2009-10-02 23:57:32.000000000 +0200
*************** static TypeName *TableFuncTypeName(List 
*** 330,336 ****
  %type <ival>	opt_column event cursor_options opt_hold opt_set_data
  %type <objtype>	reindex_type drop_type comment_type
  
! %type <node>	fetch_direction limit_clause select_limit_value
  				offset_clause select_offset_value
  				select_offset_value2 opt_select_fetch_first_value
  %type <ival>	row_or_rows first_or_next
--- 330,336 ----
  %type <ival>	opt_column event cursor_options opt_hold opt_set_data
  %type <objtype>	reindex_type drop_type comment_type
  
! %type <node>	fetch_args limit_clause select_limit_value
  				offset_clause select_offset_value
  				select_offset_value2 opt_select_fetch_first_value
  %type <ival>	row_or_rows first_or_next
*************** comment_text:
*** 4137,4278 ****
   *
   *****************************************************************************/
  
! FetchStmt:	FETCH fetch_direction from_in name
  				{
  					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;
  					$$ = (Node *)n;
  				}
! 			| MOVE fetch_direction from_in name
  				{
  					FetchStmt *n = (FetchStmt *) $2;
- 					n->portalname = $4;
  					n->ismove = TRUE;
  					$$ = (Node *)n;
  				}
! 			| MOVE name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
- 					n->portalname = $2;
- 					n->ismove = TRUE;
  					$$ = (Node *)n;
  				}
! 		;
! 
! fetch_direction:
! 			/*EMPTY*/
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| NEXT
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| PRIOR
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_BACKWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| FIRST_P
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_ABSOLUTE;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| LAST_P
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_ABSOLUTE;
  					n->howMany = -1;
  					$$ = (Node *)n;
  				}
! 			| ABSOLUTE_P SignedIconst
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_ABSOLUTE;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| RELATIVE_P SignedIconst
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_RELATIVE;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| SignedIconst
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = $1;
  					$$ = (Node *)n;
  				}
! 			| ALL
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = FETCH_ALL;
  					$$ = (Node *)n;
  				}
! 			| FORWARD
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| FORWARD SignedIconst
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| FORWARD ALL
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_FORWARD;
  					n->howMany = FETCH_ALL;
  					$$ = (Node *)n;
  				}
! 			| BACKWARD
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_BACKWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| BACKWARD SignedIconst
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_BACKWARD;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| BACKWARD ALL
  				{
  					FetchStmt *n = makeNode(FetchStmt);
  					n->direction = FETCH_BACKWARD;
  					n->howMany = FETCH_ALL;
  					$$ = (Node *)n;
--- 4137,4280 ----
   *
   *****************************************************************************/
  
! FetchStmt:	FETCH fetch_args
  				{
  					FetchStmt *n = (FetchStmt *) $2;
  					n->ismove = FALSE;
  					$$ = (Node *)n;
  				}
! 			| MOVE fetch_args
  				{
  					FetchStmt *n = (FetchStmt *) $2;
  					n->ismove = TRUE;
  					$$ = (Node *)n;
  				}
! 		;
! 
! fetch_args:	name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $1;
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $2;
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| NEXT opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| PRIOR opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_BACKWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| FIRST_P opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_ABSOLUTE;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| LAST_P opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_ABSOLUTE;
  					n->howMany = -1;
  					$$ = (Node *)n;
  				}
! 			| ABSOLUTE_P SignedIconst opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $4;
  					n->direction = FETCH_ABSOLUTE;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| RELATIVE_P SignedIconst opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $4;
  					n->direction = FETCH_RELATIVE;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| SignedIconst opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_FORWARD;
  					n->howMany = $1;
  					$$ = (Node *)n;
  				}
! 			| ALL opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_FORWARD;
  					n->howMany = FETCH_ALL;
  					$$ = (Node *)n;
  				}
! 			| FORWARD opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_FORWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| FORWARD SignedIconst opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $4;
  					n->direction = FETCH_FORWARD;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| FORWARD ALL opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $4;
  					n->direction = FETCH_FORWARD;
  					n->howMany = FETCH_ALL;
  					$$ = (Node *)n;
  				}
! 			| BACKWARD opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $3;
  					n->direction = FETCH_BACKWARD;
  					n->howMany = 1;
  					$$ = (Node *)n;
  				}
! 			| BACKWARD SignedIconst opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $4;
  					n->direction = FETCH_BACKWARD;
  					n->howMany = $2;
  					$$ = (Node *)n;
  				}
! 			| BACKWARD ALL opt_from_in name
  				{
  					FetchStmt *n = makeNode(FetchStmt);
+ 					n->portalname = $4;
  					n->direction = FETCH_BACKWARD;
  					n->howMany = FETCH_ALL;
  					$$ = (Node *)n;
*************** from_in:	FROM									{}
*** 4283,4288 ****
--- 4285,4295 ----
  			| IN_P									{}
  		;
  
+ opt_from_in:	FROM									{}
+ 			| IN_P									{}
+ 			| /* EMPTY */								{}
+ 		;
+ 
  
  /*****************************************************************************
   *
diff -dcrpN pgsql.orig/src/interfaces/ecpg/preproc/ecpg.addons pgsql.ufd-opt-fromin-fetch/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql.orig/src/interfaces/ecpg/preproc/ecpg.addons	2009-08-14 16:27:41.000000000 +0200
--- pgsql.ufd-opt-fromin-fetch/src/interfaces/ecpg/preproc/ecpg.addons	2009-10-03 00:50:37.000000000 +0200
*************** ECPG: ConstraintAttributeSpecConstraintT
*** 206,221 ****
  			if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
  				mmerror(PARSE_ERROR, ET_ERROR, "constraint declared INITIALLY DEFERRED must be DEFERRABLE");
  ECPG: var_valueNumericOnly addon
- ECPG: fetch_directionSignedIconst addon
  		if ($1[0] == '$')
  		{
  			free($1);
  			$1 = make_str("$0");
  		}
! ECPG: fetch_directionABSOLUTE_PSignedIconst addon
! ECPG: fetch_directionRELATIVE_PSignedIconst addon
! ECPG: fetch_directionFORWARDSignedIconst addon
! ECPG: fetch_directionBACKWARDSignedIconst addon
  		if ($2[0] == '$')
  		{
  			free($2);
--- 206,241 ----
  			if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
  				mmerror(PARSE_ERROR, ET_ERROR, "constraint declared INITIALLY DEFERRED must be DEFERRABLE");
  ECPG: var_valueNumericOnly addon
  		if ($1[0] == '$')
  		{
  			free($1);
  			$1 = make_str("$0");
  		}
! ECPG: fetch_argsname addon
! 		add_additional_variables($1, false);
! ECPG: fetch_argsfrom_inname 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    
! 		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] == '$')
  		{
  			free($2);
*************** ECPG: VariableShowStmtSHOWALL block
*** 336,382 ****
  		mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL is not implemented");
  		$$ = EMPTY;
  	}
! ECPG: FetchStmtFETCHfetch_directionfrom_inname block 
! 	{
! 		add_additional_variables($4, false);
! 		$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
! 	}
! ECPG: FetchStmtFETCHname block
  	{
! 		add_additional_variables($2, false);
! 		$$ = 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: SpecialRuleRelationOLD addon
  		if (!QueryIsRule)
  			mmerror(PARSE_ERROR, ET_ERROR, "OLD used in query that is not in a rule");
--- 356,366 ----
  		mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL is not implemented");
  		$$ = EMPTY;
  	}
! ECPG: FetchStmtMOVEfetch_args rule
! 	| FETCH fetch_args ecpg_into
  	{
! 		$$ = cat2_str(make_str("fetch"), $2);
  	}
  ECPG: SpecialRuleRelationOLD addon
  		if (!QueryIsRule)
  			mmerror(PARSE_ERROR, ET_ERROR, "OLD used in query that is not in a rule");
diff -dcrpN pgsql.orig/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c pgsql.ufd-opt-fromin-fetch/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c
*** pgsql.orig/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c	2009-08-14 16:27:41.000000000 +0200
--- pgsql.ufd-opt-fromin-fetch/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c	2009-10-03 00:33:14.000000000 +0200
*************** if (sqlca.sqlcode < 0) dosqlprint ( );}
*** 158,164 ****
  
  	while (1)
  	{
! 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward from c", ECPGt_EOIT, 
  	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
  	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
  	ECPGt_decimal,&(j),(long)1,(long)1,sizeof(decimal), 
--- 158,164 ----
  
  	while (1)
  	{
! 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward c", ECPGt_EOIT, 
  	ECPGt_int,&(i),(long)1,(long)1,sizeof(int), 
  	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
  	ECPGt_decimal,&(j),(long)1,(long)1,sizeof(decimal), 
diff -dcrpN pgsql.orig/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr pgsql.ufd-opt-fromin-fetch/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr
*** pgsql.orig/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr	2009-08-14 16:27:41.000000000 +0200
--- pgsql.ufd-opt-fromin-fetch/src/interfaces/ecpg/test/expected/compat_informix-test_informix.stderr	2009-10-03 00:33:15.000000000 +0200
*************** DETAIL:  Key (i)=(7) already exists.
*** 63,69 ****
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 95: OK: DECLARE CURSOR
  [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]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 57: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
--- 63,69 ----
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 95: OK: DECLARE CURSOR
  [NO_PID]: sqlca: code: 0, state: 00000
! [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]: ecpg_execute on line 57: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
*************** DETAIL:  Key (i)=(7) already exists.
*** 75,81 ****
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_get_data on line 57: RESULT: test    offset: -1; array: yes
  [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]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 57: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
--- 75,81 ----
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_get_data on line 57: RESULT: test    offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [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]: ecpg_execute on line 57: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
*************** DETAIL:  Key (i)=(7) already exists.
*** 87,93 ****
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_get_data on line 57: RESULT: a       offset: -1; array: yes
  [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]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 57: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
--- 87,93 ----
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_get_data on line 57: RESULT: a       offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [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]: ecpg_execute on line 57: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
