]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
ecpg now accepts array elements as arguments.
authorMichael Meskes <meskes@postgresql.org>
Fri, 23 May 2003 15:19:36 +0000 (15:19 +0000)
committerMichael Meskes <meskes@postgresql.org>
Fri, 23 May 2003 15:19:36 +0000 (15:19 +0000)
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/preproc/keywords.c
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/type.c

index e14c274099a163ad496ab608456bce0dfff20f9e..a1ee4c75f92c4982d0bfcc927ac774eb317dec85 100644 (file)
@@ -1436,6 +1436,11 @@ Tue May 20 11:47:00 CEST 2003
 Thu May 22 09:33:54 CEST 2003
 
        - ecpg now recognizes named struct/union usage.
+
+Fri May 23 11:46:15 CEST 2003
+
+       - Synced parser and keyword table.
+       - ecpg now accepts array elements as input variables.
        - Set ecpg version to 2.12.0.
        - Set ecpg library to 3.4.2.
        - Set pgtypes library to 1.0.0
index e0e80f8fe3b35adad9d7c3cf3fe159f76f54715a..e6b0d6651f4c4f81e93241b338c5824e4e03d92b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.57 2003/05/16 04:59:22 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.58 2003/05/23 15:19:34 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,6 +41,7 @@ static ScanKeyword ScanKeywords[] = {
        {"analyze", ANALYZE},
        {"and", AND},
        {"any", ANY},
+       {"array", ARRAY},
        {"as", AS},
        {"asc", ASC},
        {"assertion", ASSERTION},
@@ -126,6 +127,7 @@ static ScanKeyword ScanKeywords[] = {
        {"extract", EXTRACT},
        {"false", FALSE_P},
        {"fetch", FETCH},
+       {"first", FIRST_P},
        {"float", FLOAT_P},
        {"for", FOR},
        {"force", FORCE},
@@ -141,6 +143,7 @@ static ScanKeyword ScanKeywords[] = {
        {"group", GROUP_P},
        {"handler", HANDLER},
        {"having", HAVING},
+       {"hold", HOLD},
        {"hour", HOUR_P},
        {"ilike", ILIKE},
        {"immediate", IMMEDIATE},
@@ -170,6 +173,7 @@ static ScanKeyword ScanKeywords[] = {
        {"key", KEY},
        {"lancompiler", LANCOMPILER},
        {"language", LANGUAGE},
+       {"last", LAST_P},
        {"leading", LEADING},
        {"left", LEFT},
        {"level", LEVEL},
@@ -241,6 +245,7 @@ static ScanKeyword ScanKeywords[] = {
        {"rename", RENAME},
        {"replace", REPLACE},
        {"reset", RESET},
+       {"restart", RESTART},
        {"restrict", RESTRICT},
        {"returns", RETURNS},
        {"revoke", REVOKE},
index bb00b7ed3da01012612b9629d0a7a85f6a0e5161..0e7cea0eda24c5c4b9ab3615cec36afe24e433be 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.221 2003/05/22 17:09:00 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.222 2003/05/23 15:19:34 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -32,6 +32,19 @@ struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
 
 struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
 
+static struct inf_compat_col
+{
+       char *name;
+       char *indirection;
+       struct inf_compat_col *next;
+} *informix_col;
+
+static struct inf_compat_val
+{
+       char *val;
+       struct inf_compat_val *next;
+} *informix_val;
 /*
  * Handle parsing errors and warnings
  */
@@ -135,6 +148,41 @@ make_name(void)
        return(name);
 }
 
+static char *
+create_questionmarks(char *name, bool array)
+{
+       struct variable *p = find_variable(name);
+       int count;
+       char *result = EMPTY;
+
+       /* In case we have a struct, we have to print as many "?" as there are attributes in the struct 
+        * An array is only allowed together with an element argument 
+        * This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else 
+        * so we don't have to worry here. */
+       
+       if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
+       {
+               struct ECPGstruct_member *m;
+
+               if (p->type->type == ECPGt_struct)
+                       m = p->type->u.members;
+               else
+                       m = p->type->u.element->u.members;
+
+               for (count = 0; m != NULL; m=m->next, count++);
+       }
+       else
+               count = 1;
+
+       for (; count > 0; count --)
+               result = cat2_str(result, make_str("? , "));
+
+       /* removed the trailing " ," */
+
+       result[strlen(result)-3] = '\0';
+       return(result);
+}
+
 %}
 
 %union {
@@ -178,7 +226,7 @@ make_name(void)
 
 /* ordinary key words in alphabetical order */
 %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER
-        AGGREGATE ALL ALTER ANALYSE ANALYZE AND ANY AS ASC
+        AGGREGATE ALL ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
        ASSERTION ASSIGNMENT AT AUTHORIZATION
 
         BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
@@ -197,11 +245,11 @@ make_name(void)
         EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUSIVE
         EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
 
-        FALSE_P FETCH FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
+        FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
         FULL FUNCTION
 
        GET GLOBAL GRANT GROUP_P
-        HANDLER HAVING HOUR_P
+        HANDLER HAVING HOLD HOUR_P
 
        ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCREMENT INDEX INHERITS
         INITIALLY INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P
@@ -211,7 +259,7 @@ make_name(void)
 
         KEY
 
-       LANCOMPILER LANGUAGE LEADING LEFT LEVEL LIKE LIMIT LISTEN
+       LANCOMPILER LANGUAGE LAST_P LEADING LEFT LEVEL LIKE LIMIT LISTEN
         LOAD LOCAL LOCATION LOCK_P
 
        MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
@@ -227,7 +275,7 @@ make_name(void)
        PRECISION PRESERVE PREPARE PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE
 
        READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RENAME REPLACE
-       RESET RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS RULE
+       RESET RESTART RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS RULE
 
        SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE SERIALIZABLE
         SESSION SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SOME
@@ -239,7 +287,7 @@ make_name(void)
         UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL UPDATE USAGE
         USER USING
 
-        VACUUM VALID VALUE VALUES VARCHAR VARYING VERBOSE VERSION VIEW VOLATILE
+        VACUUM VALID VALUES VARCHAR VARYING VERBOSE VERSION VIEW VOLATILE
        WHEN WHERE WITH WITHOUT WORK WRITE
         YEAR_P
         ZONE
@@ -293,7 +341,7 @@ make_name(void)
 %type  <str>   TableConstraint OptTableElementList Xconst opt_transaction 
 %type  <str>   ConstraintElem key_actions ColQualList type_name
 %type  <str>   target_list target_el update_target_list alias_clause
-%type  <str>   update_target_el opt_id qualified_name database_name
+%type  <str>   update_target_el qualified_name database_name
 %type  <str>   access_method attr_name index_name name func_name
 %type  <str>   file_name AexprConst c_expr ConstTypename var_list
 %type  <str>   a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
@@ -302,18 +350,18 @@ make_name(void)
 %type  <str>   trim_list in_expr substr_for attrs TableFuncElement
 %type  <str>   Typename SimpleTypename Numeric opt_float opt_numeric
 %type  <str>   opt_decimal Character character opt_varying opt_charset
-%type  <str>   opt_collate opt_timezone opt_interval table_ref
-%type  <str>   row_descriptor ConstDatetime AlterDomainStmt 
+%type  <str>   opt_collate opt_timezone opt_interval table_ref fetch_direction
+%type  <str>   row_descriptor ConstDatetime AlterDomainStmt AlterSeqStmt
 %type  <str>   SelectStmt into_clause OptTemp ConstraintAttributeSpec
 %type  <str>   opt_table opt_all sort_clause sortby_list ConstraintAttr
 %type  <str>   sortby OptUseOp qualified_name_list name_list ColId_or_Sconst
-%type  <str>   group_clause having_clause from_clause opt_distinct
+%type  <str>   group_clause having_clause from_clause opt_distinct opt_hold
 %type  <str>   join_outer where_clause relation_expr sub_type opt_arg
-%type  <str>   opt_column_list insert_rest InsertStmt OptimizableStmt
-%type  <str>   columnList DeleteStmt LockStmt UpdateStmt CursorStmt
+%type  <str>   opt_column_list insert_rest InsertStmt
+%type  <str>   columnList DeleteStmt LockStmt UpdateStmt DeclareCursorStmt
 %type  <str>   NotifyStmt columnElem UnlistenStmt TableElement rowdefinition
 %type  <str>   copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
-%type  <str>   FetchStmt direction fetch_how_many from_in CreateOpClassStmt
+%type  <str>   FetchStmt from_in CreateOpClassStmt
 %type  <str>   ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
 %type  <str>   opt_full func_arg OptWithOids opt_freeze opt_ecpg_into
 %type  <str>   analyze_keyword opt_name_list ExplainStmt index_params
@@ -335,22 +383,22 @@ make_name(void)
 %type  <str>   DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
 %type  <str>   TriggerActionTime CreateTrigStmt DropPLangStmt DropCastStmt
 %type  <str>   CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
-%type  <str>   ViewStmt LoadStmt CreatedbStmt createdb_opt_item
+%type  <str>   ViewStmt LoadStmt CreatedbStmt createdb_opt_item ExplainableStmt
 %type  <str>   createdb_opt_list opt_encoding OptInherit opt_equal
 %type  <str>   AlterUserSetStmt privilege_list privilege privilege_target
-%type  <str>   opt_grant_grant_option opt_revoke_grant_option
+%type  <str>   opt_grant_grant_option opt_revoke_grant_option cursor_options
 %type  <str>   transaction_mode_list_or_empty transaction_mode_list
 %type  <str>   function_with_argtypes_list function_with_argtypes
 %type  <str>   DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt
 %type  <str>   GrantStmt privileges PosAllConst constraints_set_list
-%type  <str>   opt_cursor ConstraintsSetStmt AllConst CreateDomainStmt
+%type  <str>   ConstraintsSetStmt AllConst CreateDomainStmt
 %type  <str>   case_expr when_clause_list case_default case_arg when_clause
 %type  <str>   select_clause opt_select_limit select_limit_value opt_recheck
 %type  <str>   ConstraintTimeSpec AlterDatabaseSetStmt DropAssertStmt
 %type  <str>   select_offset_value ReindexStmt join_type opt_boolean
-%type  <str>   join_qual update_list joined_table opclass_item
-%type  <str>   opt_lock lock_type OptGroupList OptGroupElem
-%type  <str>   OptConstrFromTable OptTempTableName StringConst
+%type  <str>   join_qual update_list joined_table opclass_item fetch_count
+%type  <str>   opt_lock lock_type OptGroupList OptGroupElem array_expr_list
+%type  <str>   OptConstrFromTable OptTempTableName StringConst array_expr
 %type  <str>   constraints_set_mode comment_type opt_empty_parentheses
 %type  <str>   CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
 %type  <str>   opt_force key_update CreateSchemaStmt PosIntStringConst
@@ -391,8 +439,8 @@ make_name(void)
 %type  <str>   ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
 %type  <str>   reserved_keyword unreserved_keyword ecpg_interval
 %type  <str>   col_name_keyword func_name_keyword precision opt_scale
-%type  <str>   ECPGTypeName variablelist ECPGColLabelCommon
-%type  <str>   s_struct_union_symbol
+%type  <str>   ECPGTypeName variablelist ECPGColLabelCommon c_variable
+%type  <str>   s_struct_union_symbol inf_val_list inf_col_list
 
 %type  <descriptor> ECPGGetDescriptor
 
@@ -433,55 +481,65 @@ opt_at: AT connection_target
                {
                        connection = $2;
                        /*
-                        *      if we have a variable as connection
-                        *      target, remove it from the variable
+                        *      Do we have a variable as connection target?
+                        *      Remove the variable from the variable
                         *      list or else it will be used twice
                         */
                        if (argsinsert != NULL)
                                argsinsert = NULL;
                };
 
-stmt:  AlterDatabaseSetStmt { output_statement($1, 0, connection); }
+stmt:  AlterDatabaseSetStmt            { output_statement($1, 0, connection); }
                | AlterDomainStmt       { output_statement($1, 0, connection); }
                | AlterGroupStmt        { output_statement($1, 0, connection); }
+               | AlterSeqStmt          { output_statement($1, 0, connection); }
                | AlterTableStmt        { output_statement($1, 0, connection); }
-               | AlterUserStmt         { output_statement($1, 0, connection); }
                | AlterUserSetStmt      { output_statement($1, 0, connection); }
+               | AlterUserStmt         { output_statement($1, 0, connection); }
+               | AnalyzeStmt           { output_statement($1, 0, connection); }
+               | CheckPointStmt        { output_statement($1, 0, connection); }
                | ClosePortalStmt       { output_statement($1, 0, connection); }
+               | ClusterStmt           { output_statement($1, 0, connection); }
                | CommentStmt           { output_statement($1, 0, connection); }
+               | ConstraintsSetStmt    { output_statement($1, 0, connection); }
                | CopyStmt              { output_statement($1, 0, connection); }
-               | CreateStmt            { output_statement($1, 0, connection); }
                | CreateAsStmt          { output_statement($1, 0, connection); }
+               | CreateAssertStmt      { output_statement($1, 0, connection); }
                | CreateCastStmt        { output_statement($1, 0, connection); }
+               | CreateConversionStmt  { output_statement($1, 0, connection); }
                | CreateDomainStmt      { output_statement($1, 0, connection); }
                | CreateFunctionStmt    { output_statement($1, 0, connection); }
-               | CreateSchemaStmt      { output_statement($1, 0, connection); }
                | CreateGroupStmt       { output_statement($1, 0, connection); }
-               | CreateSeqStmt         { output_statement($1, 0, connection); }
                | CreatePLangStmt       { output_statement($1, 0, connection); }
-               | CreateAssertStmt      { output_statement($1, 0, connection); }
                | CreateOpClassStmt     { output_statement($1, 0, connection); }
+               | CreateSchemaStmt      { output_statement($1, 0, connection); }
+               | CreateSeqStmt         { output_statement($1, 0, connection); }
+               | CreateStmt            { output_statement($1, 0, connection); }
                | CreateTrigStmt        { output_statement($1, 0, connection); }
                | CreateUserStmt        { output_statement($1, 0, connection); }
-               | ClusterStmt           { output_statement($1, 0, connection); }
+               | CreatedbStmt          { output_statement($1, 0, connection); }
                /*| DeallocateStmt      { output_statement($1, 0, connection); }*/
+               | DeclareCursorStmt     { output_simple_statement($1); }
                | DefineStmt            { output_statement($1, 0, connection); }
-               | DropStmt              { output_statement($1, 0, connection); }
-               | TruncateStmt          { output_statement($1, 0, connection); }
+               | DeleteStmt            { output_statement($1, 0, connection); }
+               | DropAssertStmt        { output_statement($1, 0, connection); }
                | DropCastStmt          { output_statement($1, 0, connection); }
                | DropGroupStmt         { output_statement($1, 0, connection); }
                | DropOpClassStmt       { output_statement($1, 0, connection); }
                | DropPLangStmt         { output_statement($1, 0, connection); }
-               | DropAssertStmt        { output_statement($1, 0, connection); }
-               | DropTrigStmt          { output_statement($1, 0, connection); }
                | DropRuleStmt          { output_statement($1, 0, connection); }
+               | DropStmt              { output_statement($1, 0, connection); }
+               | DropTrigStmt          { output_statement($1, 0, connection); }
                | DropUserStmt          { output_statement($1, 0, connection); }
-               | ExplainStmt           { output_statement($1, 0, connection); }/*              | ExecuteStmt           { output_statement($1, 0, connection); }*/
+               | DropdbStmt            { output_statement($1, 0, connection); }
+               | ExplainStmt           { output_statement($1, 0, connection); }
+/*             | ExecuteStmt           { output_statement($1, 0, connection); }*/
                | FetchStmt             { output_statement($1, 1, connection); }
                | GrantStmt             { output_statement($1, 0, connection); }
                | IndexStmt             { output_statement($1, 0, connection); }
+               | InsertStmt            { output_statement($1, 0, connection); }
                | ListenStmt            { output_statement($1, 0, connection); }
-               | UnlistenStmt          { output_statement($1, 0, connection); }
+               | LoadStmt              { output_statement($1, 0, connection); }
                | LockStmt              { output_statement($1, 0, connection); }
                | NotifyStmt            { output_statement($1, 0, connection); }
 /*             | PrepareStmt           { output_statement($1, 0, connection); }*/
@@ -491,32 +549,22 @@ stmt:  AlterDatabaseSetStmt { output_statement($1, 0, connection); }
                | RemoveFuncStmt        { output_statement($1, 0, connection); }
                | RenameStmt            { output_statement($1, 0, connection); }
                | RevokeStmt            { output_statement($1, 0, connection); }
-               | OptimizableStmt
-               {
-                       if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
-                               output_simple_statement($1);
-                       else
-                               output_statement($1, 1, connection);
-               }
                | RuleStmt              { output_statement($1, 0, connection); }
+               | SelectStmt            { output_statement($1, 0, connection); }
                | TransactionStmt
                {
                        fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
                        whenever_action(2);
                        free($1);
                }
-               | ViewStmt              { output_statement($1, 0, connection); }
-               | LoadStmt              { output_statement($1, 0, connection); }
-               | CreatedbStmt          { output_statement($1, 0, connection); }
-               | DropdbStmt            { output_statement($1, 0, connection); }
+               | TruncateStmt          { output_statement($1, 0, connection); }
+               | UnlistenStmt          { output_statement($1, 0, connection); }
+               | UpdateStmt            { output_statement($1, 0, connection); }
                | VacuumStmt            { output_statement($1, 0, connection); }
-               | AnalyzeStmt           { output_statement($1, 0, connection); }
                | VariableSetStmt       { output_statement($1, 0, connection); }
                | VariableShowStmt      { output_statement($1, 0, connection); }
                | VariableResetStmt     { output_statement($1, 0, connection); }
-               | ConstraintsSetStmt    { output_statement($1, 0, connection); }
-               | CheckPointStmt        { output_statement($1, 0, connection); }
-               | CreateConversionStmt  { output_statement($1, 0, connection); }
+               | ViewStmt              { output_statement($1, 0, connection); }
                | ECPGAllocateDescr
                {
                        fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
@@ -1010,6 +1058,9 @@ AlterTableStmt:
 /* ALTER TABLE <name> OWNER TO UserId */
                | ALTER TABLE qualified_name OWNER TO UserId
                        { $$ = cat_str(4, make_str("alter table"), $3, make_str("owner to"), $6); }
+/* ALTER TABLE <name> CLUSTER ON <indexname> */
+               | ALTER TABLE qualified_name CLUSTER ON name
+                       { $$ = cat_str(4, make_str("alter table"), $3, make_str("cluster on"), $6); }
                ;
 
 alter_column_default:
@@ -1025,15 +1076,11 @@ opt_drop_behavior: CASCADE                      { $$ = make_str("cascade"); }
 /*****************************************************************************
  *
  *             QUERY :
- *                             close <optname>
+ *                             close <portalname>
  *
  *****************************************************************************/
 
-ClosePortalStmt:  CLOSE opt_id { $$ = cat2_str(make_str("close"), $2); }
-               ;
-
-opt_id:  ColId                                 { $$ = $1; }
-               | /*EMPTY*/                     { $$ = NULL; }
+ClosePortalStmt:  CLOSE name   { $$ = cat2_str(make_str("close"), $2); }
                ;
 
 /*****************************************************************************
@@ -1118,20 +1165,12 @@ CreateStmt:  CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
  */
 
 OptTemp: TEMPORARY                     { $$ = make_str("temporary"); }
-               | TEMP                          { $$ = make_str("temp"); }
+               | TEMP                  { $$ = make_str("temp"); }
                | LOCAL TEMPORARY       { $$ = make_str("local temporary"); }
                | LOCAL TEMP            { $$ = make_str("local temp"); }
-               | GLOBAL TEMPORARY
-               {
-                       mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
-                       $$ = make_str("global temporary");
-               }
-               | GLOBAL TEMP
-               {
-                       mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
-                       $$ = make_str("global temp");
-               }
-               | /*EMPTY*/                     { $$ = EMPTY; }
+               | GLOBAL TEMPORARY      { $$ = make_str("global temporary"); }
+               | GLOBAL TEMP           { $$ = make_str("global temp"); }
+               | /*EMPTY*/             { $$ = EMPTY; }
                ;
 
 
@@ -1343,6 +1382,7 @@ CreateAsElement:  ColId { $$ = $1; }
  *
  *             QUERY :
  *                             CREATE SEQUENCE seqname
+ *                              ALTER SEQUENCE seqname
  *
  *****************************************************************************/
 
@@ -1350,6 +1390,10 @@ CreateSeqStmt:   CREATE OptTemp SEQUENCE qualified_name OptSeqList
                        { $$ = cat_str(4, make_str("create sequence"), $2, $4, $5); }
                ;
 
+AlterSeqStmt: ALTER SEQUENCE qualified_name OptSeqList
+                       { $$ = cat_str(3,make_str("alter sequence"), $3, $4); }
+               ;
+
 OptSeqList:  OptSeqList OptSeqElem     { $$ = cat2_str($1, $2); }
                | /*EMPTY*/                                     { $$ = EMPTY; }
                ;
@@ -1372,6 +1416,8 @@ OptSeqElem:  CACHE NumConst
                        { $$ = make_str("no minvalue"); }
                | START opt_with NumConst
                        { $$ = cat_str(3, make_str("start"), $2, $3); }
+               | RESTART opt_with NumConst
+                       { $$ = cat_str(3, make_str("restart"), $2, $3); }
                ;
 
 opt_by:                BY      { $$ = make_str("by"); }
@@ -1662,49 +1708,39 @@ TruncateStmt:  TRUNCATE opt_table qualified_name
 /*****************************************************************************
  *
  *             QUERY:
- *                                        fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
- *                                        fetch [ forward | backward | absolute | relative ]
- *                                                      [ # | all | next | prior ] [ [ in | from ] <portalname> ]
+ *                     fetch/move
  *
  *****************************************************************************/
 
-FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into
-                       { $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5); }
-               | FETCH fetch_how_many from_in name ecpg_into
+FetchStmt: FETCH fetch_direction from_in name ecpg_into
                        { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
-               | FETCH direction from_in name ecpg_into
-                       { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
-               | FETCH from_in name ecpg_into
-                       { $$ = cat_str(3, make_str("fetch"), $2, $3); }
                | FETCH name ecpg_into
                        { $$ = cat2_str(make_str("fetch"), $2); }
-               | MOVE direction fetch_how_many from_in name
-                       { $$ = cat_str(5, make_str("move"), $2, $3, $4, $5); }
-               | MOVE fetch_how_many from_in name
-                       { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
-               | MOVE direction from_in name
+               | MOVE fetch_direction from_in name
                        { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
-               | MOVE from_in name
-                       { $$ = cat_str(3, make_str("move"), $2, $3); }
                | MOVE name
                        { $$ = cat2_str(make_str("move"), $2); }
                ;
 
-direction:     FORWARD         { $$ = make_str("forward"); }
-               | BACKWARD              { $$ = make_str("backward"); }
-               | RELATIVE_P            { $$ = make_str("relative"); }
-               | ABSOLUTE_P
-               {
-                       mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported FETCH/ABSOLUTE will be passed to backend, backend will use RELATIVE");
-                       $$ = make_str("absolute");
-               }
-               ;
-
-fetch_how_many: IntConst       { $$ = $1; }
-               | ALL           { $$ = make_str("all"); }
-               | NEXT          { $$ = make_str("next"); }
-               | PRIOR         { $$ = make_str("prior"); }
-               ;
+fetch_direction: /* EMPTY */                   { $$ = EMPTY; }
+               | NEXT                          { $$ = make_str("next"); }
+               | PRIOR                         { $$ = make_str("prior"); }
+               | FIRST_P                       { $$ = make_str("first"); }
+               | LAST_P                        { $$ = make_str("last"); }
+               | ABSOLUTE_P fetch_count        { $$ = cat2_str(make_str("absolute"), $2); }
+               | RELATIVE_P fetch_count        { $$ = cat2_str(make_str("relative"), $2); }
+               | fetch_count                   { $$ = $1; }
+               | ALL                           { $$ = make_str("all"); }
+               | FORWARD                       { $$ = make_str("forward"); }
+               | FORWARD fetch_count           { $$ = cat2_str(make_str("forward"), $2); }
+               | FORWARD ALL                   { $$ = make_str("forward all"); }
+               | BACKWARD                      { $$ = make_str("backward"); }
+               | BACKWARD fetch_count          { $$ = cat2_str(make_str("backward"), $2); }
+               | BACKWARD ALL                  { $$ = make_str("backward all"); }
+               ;
+
+fetch_count: IntConst  { $$ = $1; }
+       ;
 
 from_in: IN_P                          { $$ = make_str("in"); }
                | FROM                          { $$ = make_str("from"); }
@@ -2419,12 +2455,18 @@ opt_name_list:  '(' name_list ')'
  *
  *****************************************************************************/
 
-ExplainStmt:  EXPLAIN opt_analyze opt_verbose OptimizableStmt
+ExplainStmt:  EXPLAIN opt_analyze opt_verbose ExplainableStmt
                        { $$ = cat_str(4, make_str("explain"), $2, $3, $4); }
-/*             | EXPLAIN opt_analyze opt_verbose ExecuteStmt
-                       { $$ = cat_str(4, make_str("explain"), $2, $3, $4); }*/
                ;
 
+ExplainableStmt:
+               SelectStmt
+               | InsertStmt
+                | UpdateStmt
+               | DeleteStmt
+               | DeclareCursorStmt
+               /* | ExecuteStmt */
+               ;                                                                                               
 opt_analyze:
        analyze_keyword                 { $$ = $1; }
        | /* EMPTY */                   { $$ = EMPTY; }
@@ -2434,10 +2476,17 @@ opt_analyze:
 
 conflicts with ecpg
 
-PrepareStmt: PREPARE name prep_type_clause AS OptimizableStmt
+PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt
                { $$ = cat_str(5, make_str("prepare"), $2, $3, make_str("as"), $5); }
                ;
 
+PreparableStmt:
+                       SelectStmt
+                       | InsertStmt
+                       | UpdateStmt
+                       | DeleteStmt
+               ;
+
 prep_type_clause: '(' prep_type_list ')'       { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
                        | /* EMPTY * /          { $$ = EMPTY; }
                        ;
@@ -2459,25 +2508,6 @@ DeallocateStmt: DEALLOCATE name          { $$ = cat2_str(make_str("deallocate"), $2); }
        ;
 */
 
-/*****************************************************************************
- *                                                                                                                                                      *
- *             Optimizable Stmts:                                                                                                       *
- *                                                                                                                                                      *
- *             one of the five queries processed by the planner                                         *
- *                                                                                                                                                      *
- *             [ultimately] produces query-trees as specified                                           *
- *             in the query-spec document in ~postgres/ref                                                      *
- *                                                                                                                                                      *
- *****************************************************************************/
-
-OptimizableStmt:  SelectStmt
-               | CursorStmt
-               | UpdateStmt
-               | InsertStmt
-               | DeleteStmt
-               ;
-
-
 /*****************************************************************************
  *
  *             QUERY:
@@ -2564,7 +2594,7 @@ UpdateStmt:  UPDATE relation_expr
  *                             CURSOR STATEMENTS
  *
  *****************************************************************************/
-CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
+DeclareCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
                {
                        struct cursor *ptr, *this;
 
@@ -2584,7 +2614,7 @@ CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
                        this->next = cur;
                        this->name = $2;
                        this->connection = connection;
-                       this->command =  cat_str(5, make_str("declare"), mm_strdup($2), $3, make_str("cursor for"), $6);
+                       this->command =  cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
                        this->argsinsert = argsinsert;
                        this->argsresult = argsresult;
                        argsinsert = argsresult = NULL;
@@ -2595,13 +2625,18 @@ CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
                }
                ;
 
-opt_cursor:  BINARY                            { $$ = make_str("binary"); }
-          | INSENSITIVE                        { $$ = make_str("insensitive"); }
-          | SCROLL                                     { $$ = make_str("scroll"); }
-          | INSENSITIVE SCROLL         { $$ = make_str("insensitive scroll"); }
-          | /*EMPTY*/                          { $$ = EMPTY; }
-          ;
+cursor_options:  /* EMPTY */           { $$ = EMPTY; }
+       | cursor_options BINARY         { $$ = cat2_str($1, make_str("binary")); }
+       | cursor_options INSENSITIVE    { $$ = cat2_str($1, make_str("insensitive")); }
+       | cursor_options SCROLL         { $$ = cat2_str($1, make_str("scroll")); }
+       | cursor_options NO SCROLL      { $$ = cat2_str($1, make_str("no scroll")); }
+       ;
 
+opt_hold:      /* EMPTY */             { $$ = EMPTY; }
+       | WITH HOLD                     { $$ = make_str("with hold"); }
+       | WITHOUT HOLD                  { $$ = make_str("without hold"); }
+       ;
+       
 /*****************************************************************************
  *
  *             QUERY:
@@ -2672,15 +2707,9 @@ OptTempTableName:  TEMPORARY opt_table qualified_name
                | LOCAL TEMP opt_table qualified_name
                        { $$ = cat_str(3, make_str("local temp"), $3, $4); }
                | GLOBAL TEMPORARY opt_table qualified_name
-               {
-                       mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
-                       $$ = cat_str(3, make_str("global temporary"), $3, $4);
-               }
+                       { $$ = cat_str(3, make_str("global temporary"), $3, $4); }
                | GLOBAL TEMP opt_table qualified_name
-               {
-                       mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
-                       $$ = cat_str(3, make_str("global temp"), $3, $4);
-               }
+                       { $$ = cat_str(3, make_str("global temp"), $3, $4); }
                | TABLE qualified_name
                        { $$ = cat2_str(make_str("table"), $2); }
                | qualified_name
@@ -2952,6 +2981,10 @@ Typename:  SimpleTypename opt_array_bounds
                        { $$ = cat2_str($1, $2.str); }
                | SETOF SimpleTypename opt_array_bounds
                        { $$ = cat_str(3, make_str("setof"), $2, $3); }
+               | SimpleTypename ARRAY '[' PosIntConst ']'
+                       { $$ = cat_str(4, $1, make_str("array ["), $4, make_str("]")); }
+               | SETOF SimpleTypename ARRAY '[' PosIntConst ']'
+                       { $$ = cat_str(5, make_str("setof"), $2, make_str("array ["), $5, make_str("]")); }
                ;
 
 
@@ -3461,10 +3494,10 @@ c_expr: columnref
                        { $$ = $1;      }
                | PARAM attrs opt_indirection
                        { $$ = cat_str(3, make_str("param"), $2, $3); }
-               | '(' a_expr ')'
-                       { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
                | '(' a_expr ')' attrs opt_indirection
                        { $$ = cat_str(5, make_str("("), $2, make_str(")"), $4, $5); }
+               | '(' a_expr ')' opt_indirection
+                       { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
                | case_expr
                        { $$ = $1; }
                | func_name '(' ')'
@@ -3522,8 +3555,10 @@ c_expr: columnref
                        { $$ = $1; }
                | EXISTS select_with_parens
                        { $$ = cat2_str(make_str("exists"), $2); }
-               | VALUE
-                       { $$ = make_str("value"); }
+               | ARRAY select_with_parens
+                       { $$ = cat2_str(make_str("array"), $2); }
+               | ARRAY array_expr
+                       { $$ = cat2_str(make_str("array"), $2); }
                ;
 /*
  * This used to use ecpg_expr, but since there is no shift/reduce conflict
@@ -3555,6 +3590,14 @@ type_list:       type_list ',' Typename
                        { $$ = $1; }
                ;
 
+array_expr_list: array_expr                            { $$ = $1; }
+               | array_expr_list ',' array_expr        { $$ = cat_str(3, $1, make_str(","), $3); }
+               ;
+               
+
+array_expr: '[' expr_list ']'                  { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+               | '[' array_expr_list ']'       { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+               ;
 /* Allow delimited string SCONST in extract_arg as an SQL extension.
  * - thomas 2001-04-12
  */
@@ -3714,12 +3757,74 @@ target_el:      a_expr AS ColLabel
 /* Target list as found in UPDATE table SET ... */
 update_target_list:  update_target_list ',' update_target_el
                        { $$ = cat_str(3, $1, make_str(","),$3);        }
+               | '(' inf_col_list ')' '=' '(' inf_val_list ')'
+                       {
+                               struct inf_compat_col *ptrc;
+                               struct inf_compat_val *ptrv;
+                               char *cols = make_str( "(" );
+                               char *vals = make_str( "(" );
+                               
+                               for (ptrc = informix_col, ptrv = informix_val; ptrc != NULL && ptrv != NULL; ptrc = ptrc->next, ptrv = ptrv->next)
+                               {
+                                       if ( ptrc->next != NULL )
+                                       {
+                                               cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(",") );
+                                       }
+                                       else
+                                       {
+                                               cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(")") );
+                                       }
+                                       if (ptrv->next != NULL )
+                                               vals = cat_str(3, vals, ptrv->val, make_str("," ) );
+                                       else
+                                               vals = cat_str( 3, vals, ptrv->val, make_str(")") );
+                               }
+                               $$ = cat_str( 3, cols, make_str("="), vals );
+                       }
                | update_target_el
                        { $$ = $1;      }
                | '*'
                        { $$ = make_str("*"); }
                ;
 
+inf_col_list: ColId opt_indirection
+               {
+                       struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
+                       
+                       ptr->name = $1;
+                       ptr->indirection = $2;
+                       ptr->next = NULL;
+                       informix_col = ptr;
+               }
+               | ColId opt_indirection ',' inf_col_list
+               {
+                       struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
+               
+                       ptr->name = $1;
+                       ptr->indirection = $2;
+                       ptr->next = informix_col;
+                       informix_col = ptr;
+               }
+               ;
+               
+inf_val_list: a_expr
+               {
+                       struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
+                       
+                       ptr->val = $1;
+                       ptr->next = NULL;
+                       informix_val = ptr;
+               }
+               | a_expr ',' inf_val_list
+               {
+                       struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
+               
+                       ptr->val = $1;
+                       ptr->next = informix_val;
+                       informix_val = ptr;
+               }
+               ;
+
 update_target_el:  ColId opt_indirection '=' a_expr
                        { $$ = cat_str(4, $1, $2, make_str("="), $4); }
                ;
@@ -3807,7 +3912,7 @@ AexprConst:  PosAllConst
                | NULL_P
                        { $$ = make_str("null"); }
                | civarind
-                       { $$ = make_str("?"); }
+                       { $$ = $1; }
                ;
 
 Iconst:  ICONST                                { $$ = make_name();};
@@ -3826,7 +3931,7 @@ Sconst:  SCONST
                ;
 
 PosIntConst:   Iconst          { $$ = $1; }
-               | civar                         { $$ = make_str("?"); }
+               | civar         { $$ = $1; }
                ;
 
 IntConst:      PosIntConst             { $$ = $1; }
@@ -3834,23 +3939,23 @@ IntConst:       PosIntConst             { $$ = $1; }
                ;
 
 StringConst:   Sconst          { $$ = $1; }
-               | civar                         { $$ = make_str("?"); }
+               | civar         { $$ = $1; }
                ;
 
 PosIntStringConst:     Iconst  { $$ = $1; }
-               | Sconst                        { $$ = $1; } 
-               | civar                         { $$ = make_str("?"); }
+               | Sconst        { $$ = $1; } 
+               | civar         { $$ = $1; }
                ;
 
 NumConst:      Fconst                  { $$ = $1; }
-               | Iconst                        { $$ = $1; }
+               | Iconst                { $$ = $1; }
                | '-' Fconst            { $$ = cat2_str(make_str("-"), $2); }
                | '-' Iconst            { $$ = cat2_str(make_str("-"), $2); } 
-               | civar                         { $$ = make_str("?"); }
+               | civar                 { $$ = $1; }
                ;
 
 AllConst:      Sconst                  { $$ = $1; }
-               | NumConst                      { $$ = $1; }
+               | NumConst              { $$ = $1; }
                ;
 
 PosAllConst:   Sconst          { $$ = $1; }
@@ -3858,7 +3963,7 @@ PosAllConst:      Sconst          { $$ = $1; }
                | Iconst        { $$ = $1; }
                | Bconst        { $$ = $1; }
                | Xconst        { $$ = $1; }
-               | civar         { $$ = make_str("?"); }
+               | civar         { $$ = $1; }
                ;
 
 UserId:  ColId                         { $$ = $1;};
@@ -3936,9 +4041,10 @@ connection_target: database_name opt_server opt_port
                }
                | StringConst
                {
+                       printf("MM: %s\n", $1);
                        if ($1[0] == '\"')
                                $$ = $1;
-                       else if (strcmp($1, "?") == 0) /* variable */
+                       else if (strcmp($1, " ?") == 0) /* variable */
                        {
                                enum ECPGttype type = argsinsert->variable->type->type;
 
@@ -4094,7 +4200,7 @@ opt_options: Op ColId
  * Declare a prepared cursor. The syntax is different from the standard
  * declare statement, so we create a new rule.
  */
-ECPGCursorStmt:  DECLARE name opt_cursor CURSOR FOR ident
+ECPGCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR ident
                {
                        struct cursor *ptr, *this;
                        struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
@@ -4115,14 +4221,14 @@ ECPGCursorStmt:  DECLARE name opt_cursor CURSOR FOR ident
                        this->next = cur;
                        this->name = $2;
                        this->connection = connection;
-                       this->command =  cat_str(4, make_str("declare"), mm_strdup($2), $3, make_str("cursor for ?"));
+                       this->command =  cat_str(6, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for ?"));
                        this->argsresult = NULL;
 
                        thisquery->type = &ecpg_query;
                        thisquery->brace_level = 0;
                        thisquery->next = NULL;
-                       thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($6));
-                       sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
+                       thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($7));
+                       sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $7);
 
                        this->argsinsert = NULL;
                        add_variable(&(this->argsinsert), thisquery, NULL, &no_indicator, NULL);
@@ -5004,9 +5110,9 @@ opt_ecpg_into: /*EMPTY*/                  { $$ = EMPTY; }
                | ecpg_into                                     { $$ = $1; }
                ;
 
-variable: civarind | civar
-               ;
-variablelist: variable | variable ',' variablelist;
+c_variable: civarind | civar;
+
+variablelist: c_variable | c_variable ',' variablelist;
 
 /*
  * As long as the prepare statement is not supported by the backend, we will
@@ -5471,174 +5577,180 @@ ECPGColLabel:  ECPGColLabelCommon                     { $$ = $1; }
 /* "Unreserved" keywords --- available for use as any kind of name.
  */
 unreserved_keyword:
-                 ABORT_P                                               { $$ = make_str("abort"); }
-               | ABSOLUTE_P                                    { $$ = make_str("absolute"); }
-               | ACCESS                                                { $$ = make_str("access"); }
-               | ACTION                                                { $$ = make_str("action"); }
-               | ADD                                                   { $$ = make_str("add"); }
-               | AFTER                                                 { $$ = make_str("after"); }
-               | AGGREGATE                                             { $$ = make_str("aggregate"); }
-               | ALTER                                                 { $$ = make_str("alter"); }
-               | ASSERTION                                             { $$ = make_str("assertion"); }
-               | ASSIGNMENT                                    { $$ = make_str("assignment"); }
-               | AT                                                    { $$ = make_str("at"); }
-               | BACKWARD                                              { $$ = make_str("backward"); }
-               | BEFORE                                                { $$ = make_str("before"); }
-               | BEGIN_P                                               { $$ = make_str("begin"); }
-               | BY                                                    { $$ = make_str("by"); }
-               | CACHE                                                 { $$ = make_str("cache"); }
-               | CASCADE                                               { $$ = make_str("cascade"); }
-               | CHAIN                                                 { $$ = make_str("chain"); }
-               | CHARACTERISTICS                               { $$ = make_str("characteristics"); }
-               | CHECKPOINT                                    { $$ = make_str("checkpoint"); }
-               | CLASS                                                 { $$ = make_str("class"); }
-               | CLOSE                                                 { $$ = make_str("close"); }
-               | CLUSTER                                               { $$ = make_str("cluster"); }
-               | COMMENT                                               { $$ = make_str("comment"); }
-               | COMMIT                                                { $$ = make_str("commit"); }
-               | COMMITTED                                             { $$ = make_str("committed"); }
-               | CONSTRAINTS                                   { $$ = make_str("constraints"); }
-               | CONVERSION_P                                  { $$ = make_str("conversion"); }
-               | COPY                                                  { $$ = make_str("copy"); }
-               | CREATEDB                                              { $$ = make_str("createdb"); }
-               | CREATEUSER                                    { $$ = make_str("createuser"); }
-               | CURSOR                                                { $$ = make_str("cursor"); }
-               | CYCLE                                                 { $$ = make_str("cycle"); }
-               | DATABASE                                              { $$ = make_str("database"); }
-               | DAY_P                                                 { $$ = make_str("day"); }
-               | DEALLOCATE                                    { $$ = make_str("deallocate"); }
-               | DECLARE                                               { $$ = make_str("declare"); }
-               | DEFERRED                                              { $$ = make_str("deferred"); }
-               | DELETE_P                                              { $$ = make_str("delete"); }
-               | DELIMITER                                             { $$ = make_str("delimiter"); }
-               | DELIMITERS                                    { $$ = make_str("delimiters"); }
-               | DOMAIN_P                                              { $$ = make_str("domain"); }
-               | DOUBLE_P                                              { $$ = make_str("double"); }
-               | DROP                                                  { $$ = make_str("drop"); }
-               | EACH                                                  { $$ = make_str("each"); }
-               | ENCODING                                              { $$ = make_str("encoding"); }
-               | ENCRYPTED                                             { $$ = make_str("encrypted"); }
-               | ESCAPE                                                { $$ = make_str("escape"); }
-               | EXCLUSIVE                                             { $$ = make_str("exclusive"); }
-               | EXECUTE                                               { $$ = make_str("execute"); }
-               | EXPLAIN                                               { $$ = make_str("explain"); }
-               | FETCH                                                 { $$ = make_str("fetch"); }
-               | FORCE                                                 { $$ = make_str("force"); }
-               | FORWARD                                               { $$ = make_str("forward"); }
-               | FUNCTION                                              { $$ = make_str("function"); }
-               | GLOBAL                                                { $$ = make_str("global"); }
-               | HANDLER                                               { $$ = make_str("handler"); }
-               | HOUR_P                                                { $$ = make_str("hour"); }
-               | IMMEDIATE                                             { $$ = make_str("immediate"); }
-               | IMMUTABLE                                             { $$ = make_str("immutable"); }
-               | IMPLICIT_P                                    { $$ = make_str("implicit"); }
-               | INCREMENT                                             { $$ = make_str("increment"); }
-               | INDEX                                                 { $$ = make_str("index"); }
-               | INHERITS                                              { $$ = make_str("inherits"); }
-               | INOUT                                                 { $$ = make_str("inout"); }
-               | INSENSITIVE                                   { $$ = make_str("insensitive"); }
-               | INSERT                                                { $$ = make_str("insert"); }
-               | INSTEAD                                               { $$ = make_str("instead"); }
-               | ISOLATION                                             { $$ = make_str("isolation"); }
-               | KEY                                                   { $$ = make_str("key"); }
-               | LANCOMPILER                                   { $$ = make_str("lancompiler"); }
-               | LANGUAGE                                              { $$ = make_str("language"); }
-               | LEVEL                                                 { $$ = make_str("level"); }
-               | LISTEN                                                { $$ = make_str("listen"); }
-               | LOAD                                                  { $$ = make_str("load"); }
-               | LOCAL                                                 { $$ = make_str("local"); }
-               | LOCATION                                              { $$ = make_str("location"); }
-               | LOCK_P                                                { $$ = make_str("lock"); }
-               | MATCH                                                 { $$ = make_str("match"); }
-               | MAXVALUE                                              { $$ = make_str("maxvalue"); }
-               | MINUTE_P                                              { $$ = make_str("minute"); }
-               | MINVALUE                                              { $$ = make_str("minvalue"); }
-               | MODE                                                  { $$ = make_str("mode"); }
-               | MONTH_P                                               { $$ = make_str("month"); }
-               | MOVE                                                  { $$ = make_str("move"); }
-               | NAMES                                                 { $$ = make_str("names"); }
-               | NATIONAL                                              { $$ = make_str("national"); }
-               | NEXT                                                  { $$ = make_str("next"); }
-               | NO                                                    { $$ = make_str("no"); }
-               | NOCREATEDB                                    { $$ = make_str("nocreatedb"); }
-               | NOCREATEUSER                                  { $$ = make_str("nocreateuser"); }
-               | NOTHING                                               { $$ = make_str("nothing"); }
-               | NOTIFY                                                { $$ = make_str("notify"); }
-               | OF                                                    { $$ = make_str("of"); }
-               | OIDS                                                  { $$ = make_str("oids"); }
-               | OPERATOR                                              { $$ = make_str("operator"); }
-               | OPTION                                                { $$ = make_str("option"); }
-               | OUT_P                                                 { $$ = make_str("out"); }
-               | OWNER                                                 { $$ = make_str("owner"); }
-               | PARTIAL                                               { $$ = make_str("partial"); }
-               | PASSWORD                                              { $$ = make_str("password"); }
-               | PATH_P                                                { $$ = make_str("path"); }
-               | PENDANT                                               { $$ = make_str("pendant"); }
-               | PRECISION                                             { $$ = make_str("precision"); }
-               | PREPARE                                               { $$ = make_str("prepare"); }
-               | PRESERVE                                              { $$ = make_str("preserver"); }
-               | PRIOR                                                 { $$ = make_str("prior"); }
-               | PRIVILEGES                                    { $$ = make_str("privileges"); }
-               | PROCEDURAL                                    { $$ = make_str("procedural"); }
-               | PROCEDURE                                             { $$ = make_str("procedure"); }
-               | READ                                                  { $$ = make_str("read"); }
-               | RECHECK                                               { $$ = make_str("recheck"); }
-               | REINDEX                                               { $$ = make_str("reindex"); }
-               | RELATIVE_P                                    { $$ = make_str("relative"); }
-               | RENAME                                                { $$ = make_str("rename"); }
-               | REPLACE                                               { $$ = make_str("replace"); }
-               | RESET                                                 { $$ = make_str("reset"); }
-               | RESTRICT                                              { $$ = make_str("restrict"); }
-               | RETURNS                                               { $$ = make_str("returns"); }
-               | REVOKE                                                { $$ = make_str("revoke"); }
-               | ROLLBACK                                              { $$ = make_str("rollback"); }
-               | ROWS                                                  { $$ = make_str("rows"); }
-               | RULE                                                  { $$ = make_str("rule"); }
-               | SCHEMA                                                { $$ = make_str("schema"); }
-               | SCROLL                                                { $$ = make_str("scroll"); }
-               | SECOND_P                                              { $$ = make_str("second"); }
-               | SESSION                                               { $$ = make_str("session"); }
-               | SEQUENCE                                              { $$ = make_str("sequence"); }
-               | SERIALIZABLE                                  { $$ = make_str("serializable"); }
-               | SET                                                   { $$ = make_str("set"); }
-               | SHARE                                                 { $$ = make_str("share"); }
-               | SHOW                                                  { $$ = make_str("show"); }
-               | SIMPLE                                                { $$ = make_str("simple"); }
-               | STABLE                                                { $$ = make_str("stable"); }
-               | START                                                 { $$ = make_str("start"); }
-               | STATEMENT                                             { $$ = make_str("statement"); }
-               | STATISTICS                                    { $$ = make_str("statistics"); }
-               | STDIN                                                 { $$ = make_str("stdin"); }
-               | STDOUT                                                { $$ = make_str("stdout"); }
-               | STORAGE                                               { $$ = make_str("storage"); }
-               | SYSID                                                 { $$ = make_str("sysid"); }
-               | TEMP                                                  { $$ = make_str("temp"); }
-               | TEMPLATE                                              { $$ = make_str("template"); }
-               | TEMPORARY                                             { $$ = make_str("temporary"); }
-               | TOAST                                                 { $$ = make_str("toast"); }
-               | TRANSACTION                                   { $$ = make_str("transaction"); }
-               | TRIGGER                                               { $$ = make_str("trigger"); }
-               | TRUNCATE                                              { $$ = make_str("truncate"); }
-               | TRUSTED                                               { $$ = make_str("trusted"); }
-               | TYPE_P                                                { $$ = make_str("type"); }
-               | UNENCRYPTED                                   { $$ = make_str("unencrypted"); }
-               | UNKNOWN                                               { $$ = make_str("unknown"); }
-               | UNLISTEN                                              { $$ = make_str("unlisten"); }
-               | UNTIL                                                 { $$ = make_str("until"); }
-               | UPDATE                                                { $$ = make_str("update"); }
-               | USAGE                                                 { $$ = make_str("usage"); }
-               | VACUUM                                                { $$ = make_str("vacuum"); }
-               | VALID                                                 { $$ = make_str("valid"); }
-               | VALUES                                                { $$ = make_str("values"); }
-               | VARYING                                               { $$ = make_str("varying"); }
-               | VERSION                                               { $$ = make_str("version"); }
-               | VIEW                                                  { $$ = make_str("view"); }
-               | WITH                                                  { $$ = make_str("with"); }
-               | WITHOUT                                               { $$ = make_str("without"); }
-               | WRITE                                                 { $$ = make_str("write"); }
-               | WORK                                                  { $$ = make_str("work"); }
-               | YEAR_P                                                { $$ = make_str("year"); }
-               | ZONE                                                  { $$ = make_str("zone"); }
+                 ABORT_P                       { $$ = make_str("abort"); }
+               | ABSOLUTE_P                    { $$ = make_str("absolute"); }
+               | ACCESS                        { $$ = make_str("access"); }
+               | ACTION                        { $$ = make_str("action"); }
+               | ADD                           { $$ = make_str("add"); }
+               | AFTER                         { $$ = make_str("after"); }
+               | AGGREGATE                     { $$ = make_str("aggregate"); }
+               | ALTER                         { $$ = make_str("alter"); }
+               | ASSERTION                     { $$ = make_str("assertion"); }
+               | ASSIGNMENT                    { $$ = make_str("assignment"); }
+               | AT                            { $$ = make_str("at"); }
+               | BACKWARD                      { $$ = make_str("backward"); }
+               | BEFORE                        { $$ = make_str("before"); }
+               | BEGIN_P                       { $$ = make_str("begin"); }
+               | BY                            { $$ = make_str("by"); }
+               | CACHE                         { $$ = make_str("cache"); }
+               | CASCADE                       { $$ = make_str("cascade"); }
+               | CHAIN                         { $$ = make_str("chain"); }
+               | CHARACTERISTICS               { $$ = make_str("characteristics"); }
+               | CHECKPOINT                    { $$ = make_str("checkpoint"); }
+               | CLASS                         { $$ = make_str("class"); }
+               | CLOSE                         { $$ = make_str("close"); }
+               | CLUSTER                       { $$ = make_str("cluster"); }
+               | COMMENT                       { $$ = make_str("comment"); }
+               | COMMIT                        { $$ = make_str("commit"); }
+               | COMMITTED                     { $$ = make_str("committed"); }
+               | CONSTRAINTS                   { $$ = make_str("constraints"); }
+               | CONVERSION_P                  { $$ = make_str("conversion"); }
+               | COPY                          { $$ = make_str("copy"); }
+               | CREATEDB                      { $$ = make_str("createdb"); }
+               | CREATEUSER                    { $$ = make_str("createuser"); }
+               | CURSOR                        { $$ = make_str("cursor"); }
+               | CYCLE                         { $$ = make_str("cycle"); }
+               | DATABASE                      { $$ = make_str("database"); }
+               | DAY_P                         { $$ = make_str("day"); }
+               | DEALLOCATE                    { $$ = make_str("deallocate"); }
+               | DECLARE                       { $$ = make_str("declare"); }
+               | DEFERRED                      { $$ = make_str("deferred"); }
+               | DELETE_P                      { $$ = make_str("delete"); }
+               | DELIMITER                     { $$ = make_str("delimiter"); }
+               | DELIMITERS                    { $$ = make_str("delimiters"); }
+               | DOMAIN_P                      { $$ = make_str("domain"); }
+               | DOUBLE_P                      { $$ = make_str("double"); }
+               | DROP                          { $$ = make_str("drop"); }
+               | EACH                          { $$ = make_str("each"); }
+               | ENCODING                      { $$ = make_str("encoding"); }
+               | ENCRYPTED                     { $$ = make_str("encrypted"); }
+               | ESCAPE                        { $$ = make_str("escape"); }
+               | EXCLUSIVE                     { $$ = make_str("exclusive"); }
+               | EXECUTE                       { $$ = make_str("execute"); }
+               | EXPLAIN                       { $$ = make_str("explain"); }
+               | FETCH                         { $$ = make_str("fetch"); }
+               | FIRST_P                       { $$ = make_str("first"); }
+               | FORCE                         { $$ = make_str("force"); }
+               | FORWARD                       { $$ = make_str("forward"); }
+               | FUNCTION                      { $$ = make_str("function"); }
+               | GLOBAL                        { $$ = make_str("global"); }
+               | HANDLER                       { $$ = make_str("handler"); }
+               | HOLD                          { $$ = make_str("hold"); }
+               | HOUR_P                        { $$ = make_str("hour"); }
+               | IMMEDIATE                     { $$ = make_str("immediate"); }
+               | IMMUTABLE                     { $$ = make_str("immutable"); }
+               | IMPLICIT_P                    { $$ = make_str("implicit"); }
+               | INCREMENT                     { $$ = make_str("increment"); }
+               | INDEX                         { $$ = make_str("index"); }
+               | INHERITS                      { $$ = make_str("inherits"); }
+               | INOUT                         { $$ = make_str("inout"); }
+               | INPUT_P                       { $$ = make_str("input"); }
+               | INSENSITIVE                   { $$ = make_str("insensitive"); }
+               | INSERT                        { $$ = make_str("insert"); }
+               | INSTEAD                       { $$ = make_str("instead"); }
+               | ISOLATION                     { $$ = make_str("isolation"); }
+               | KEY                           { $$ = make_str("key"); }
+               | LANCOMPILER                   { $$ = make_str("lancompiler"); }
+               | LANGUAGE                      { $$ = make_str("language"); }
+               | LAST_P                        { $$ = make_str("last"); }
+               | LEVEL                         { $$ = make_str("level"); }
+               | LISTEN                        { $$ = make_str("listen"); }
+               | LOAD                          { $$ = make_str("load"); }
+               | LOCAL                         { $$ = make_str("local"); }
+               | LOCATION                      { $$ = make_str("location"); }
+               | LOCK_P                        { $$ = make_str("lock"); }
+               | MATCH                         { $$ = make_str("match"); }
+               | MAXVALUE                      { $$ = make_str("maxvalue"); }
+               | MINUTE_P                      { $$ = make_str("minute"); }
+               | MINVALUE                      { $$ = make_str("minvalue"); }
+               | MODE                          { $$ = make_str("mode"); }
+               | MONTH_P                       { $$ = make_str("month"); }
+               | MOVE                          { $$ = make_str("move"); }
+               | NAMES                         { $$ = make_str("names"); }
+               | NATIONAL                      { $$ = make_str("national"); }
+               | NEXT                          { $$ = make_str("next"); }
+               | NO                            { $$ = make_str("no"); }
+               | NOCREATEDB                    { $$ = make_str("nocreatedb"); }
+               | NOCREATEUSER                  { $$ = make_str("nocreateuser"); }
+               | NOTHING                       { $$ = make_str("nothing"); }
+               | NOTIFY                        { $$ = make_str("notify"); }
+               | OF                            { $$ = make_str("of"); }
+               | OIDS                          { $$ = make_str("oids"); }
+               | OPERATOR                      { $$ = make_str("operator"); }
+               | OPTION                        { $$ = make_str("option"); }
+               | OUT_P                         { $$ = make_str("out"); }
+               | OWNER                         { $$ = make_str("owner"); }
+               | PARTIAL                       { $$ = make_str("partial"); }
+               | PASSWORD                      { $$ = make_str("password"); }
+               | PATH_P                        { $$ = make_str("path"); }
+               | PENDANT                       { $$ = make_str("pendant"); }
+               | PRECISION                     { $$ = make_str("precision"); }
+               | PREPARE                       { $$ = make_str("prepare"); }
+               | PRESERVE                      { $$ = make_str("preserver"); }
+               | PRIOR                         { $$ = make_str("prior"); }
+               | PRIVILEGES                    { $$ = make_str("privileges"); }
+               | PROCEDURAL                    { $$ = make_str("procedural"); }
+               | PROCEDURE                     { $$ = make_str("procedure"); }
+               | READ                          { $$ = make_str("read"); }
+               | RECHECK                       { $$ = make_str("recheck"); }
+               | REINDEX                       { $$ = make_str("reindex"); }
+               | RELATIVE_P                    { $$ = make_str("relative"); }
+               | RENAME                        { $$ = make_str("rename"); }
+               | REPLACE                       { $$ = make_str("replace"); }
+               | RESET                         { $$ = make_str("reset"); }
+               | RESTART                       { $$ = make_str("restart"); }
+               | RESTRICT                      { $$ = make_str("restrict"); }
+               | RETURNS                       { $$ = make_str("returns"); }
+               | REVOKE                        { $$ = make_str("revoke"); }
+               | ROLLBACK                      { $$ = make_str("rollback"); }
+               | ROWS                          { $$ = make_str("rows"); }
+               | RULE                          { $$ = make_str("rule"); }
+               | SCHEMA                        { $$ = make_str("schema"); }
+               | SCROLL                        { $$ = make_str("scroll"); }
+               | SECOND_P                      { $$ = make_str("second"); }
+               | SEQUENCE                      { $$ = make_str("sequence"); }
+               | SERIALIZABLE                  { $$ = make_str("serializable"); }
+               | SESSION                       { $$ = make_str("session"); }
+               | SET                           { $$ = make_str("set"); }
+               | SHARE                         { $$ = make_str("share"); }
+               | SHOW                          { $$ = make_str("show"); }
+               | SIMPLE                        { $$ = make_str("simple"); }
+               | STABLE                        { $$ = make_str("stable"); }
+               | START                         { $$ = make_str("start"); }
+               | STATEMENT                     { $$ = make_str("statement"); }
+               | STATISTICS                    { $$ = make_str("statistics"); }
+               | STDIN                         { $$ = make_str("stdin"); }
+               | STDOUT                        { $$ = make_str("stdout"); }
+               | STORAGE                       { $$ = make_str("storage"); }
+               | STRICT_P                      { $$ = make_str("strict"); }
+               | SYSID                         { $$ = make_str("sysid"); }
+               | TEMP                          { $$ = make_str("temp"); }
+               | TEMPLATE                      { $$ = make_str("template"); }
+               | TEMPORARY                     { $$ = make_str("temporary"); }
+               | TOAST                         { $$ = make_str("toast"); }
+               | TRANSACTION                   { $$ = make_str("transaction"); }
+               | TRIGGER                       { $$ = make_str("trigger"); }
+               | TRUNCATE                      { $$ = make_str("truncate"); }
+               | TRUSTED                       { $$ = make_str("trusted"); }
+               | TYPE_P                        { $$ = make_str("type"); }
+               | UNENCRYPTED                   { $$ = make_str("unencrypted"); }
+               | UNKNOWN                       { $$ = make_str("unknown"); }
+               | UNLISTEN                      { $$ = make_str("unlisten"); }
+               | UNTIL                         { $$ = make_str("until"); }
+               | UPDATE                        { $$ = make_str("update"); }
+               | USAGE                         { $$ = make_str("usage"); }
+               | VACUUM                        { $$ = make_str("vacuum"); }
+               | VALID                         { $$ = make_str("valid"); }
+               | VALUES                        { $$ = make_str("values"); }
+               | VARYING                       { $$ = make_str("varying"); }
+               | VERSION                       { $$ = make_str("version"); }
+               | VIEW                          { $$ = make_str("view"); }
+               | WITH                          { $$ = make_str("with"); }
+               | WITHOUT                       { $$ = make_str("without"); }
+               | WORK                          { $$ = make_str("work"); }
+               | WRITE                         { $$ = make_str("write"); }
+               | YEAR_P                        { $$ = make_str("year"); }
+               | ZONE                          { $$ = make_str("zone"); }
                ;
 
 /* Column identifier --- keywords that can be column, table, etc names.
@@ -5698,27 +5810,27 @@ col_name_keyword:
  *     - thomas 2000-11-28
  */
 func_name_keyword:
-                 AUTHORIZATION                                 { $$ = make_str("authorization"); }
-               | BETWEEN                                               { $$ = make_str("between"); }
-               | BINARY                                                { $$ = make_str("binary"); }
-               | CROSS                                                 { $$ = make_str("cross"); }
-               | FREEZE                                                { $$ = make_str("freeze"); }
-               | FULL                                                  { $$ = make_str("full"); }
-               | ILIKE                                                 { $$ = make_str("ilike"); }
-               | IN_P                                                  { $$ = make_str("in"); }
-               | INNER_P                                               { $$ = make_str("inner"); }
-               | IS                                                    { $$ = make_str("is"); }
-               | ISNULL                                                { $$ = make_str("isnull"); }
-               | JOIN                                                  { $$ = make_str("join"); }
-               | LEFT                                                  { $$ = make_str("left"); }
-               | LIKE                                                  { $$ = make_str("like"); }
-               | NATURAL                                               { $$ = make_str("natural"); }
-               | NOTNULL                                               { $$ = make_str("notnull"); }
-               | OUTER_P                                               { $$ = make_str("outer"); }
-               | OVERLAPS                                              { $$ = make_str("overlaps"); }
-               | RIGHT                                                 { $$ = make_str("right"); }
-               | SIMILAR                                               { $$ = make_str("similar"); }
-               | VERBOSE                                               { $$ = make_str("verbose"); }
+                 AUTHORIZATION         { $$ = make_str("authorization"); }
+               | BETWEEN               { $$ = make_str("between"); }
+               | BINARY                { $$ = make_str("binary"); }
+               | CROSS                 { $$ = make_str("cross"); }
+               | FREEZE                { $$ = make_str("freeze"); }
+               | FULL                  { $$ = make_str("full"); }
+               | ILIKE                 { $$ = make_str("ilike"); }
+               | IN_P                  { $$ = make_str("in"); }
+               | INNER_P               { $$ = make_str("inner"); }
+               | IS                    { $$ = make_str("is"); }
+               | ISNULL                { $$ = make_str("isnull"); }
+               | JOIN                  { $$ = make_str("join"); }
+               | LEFT                  { $$ = make_str("left"); }
+               | LIKE                  { $$ = make_str("like"); }
+               | NATURAL               { $$ = make_str("natural"); }
+               | NOTNULL               { $$ = make_str("notnull"); }
+               | OUTER_P               { $$ = make_str("outer"); }
+               | OVERLAPS              { $$ = make_str("overlaps"); }
+               | RIGHT                 { $$ = make_str("right"); }
+               | SIMILAR               { $$ = make_str("similar"); }
+               | VERBOSE               { $$ = make_str("verbose"); }
                ;
 
 /* Reserved keyword --- these keywords are usable only as a ColLabel.
@@ -5728,73 +5840,74 @@ func_name_keyword:
  * forced to.
  */
 reserved_keyword:
-                 ALL                                                   { $$ = make_str("all"); }
-               | ANALYSE                                               { $$ = make_str("analyse"); } /* British */
-               | ANALYZE                                               { $$ = make_str("analyze"); }
-               | AND                                                   { $$ = make_str("and"); }
-               | ANY                                                   { $$ = make_str("any"); }
-               | AS                                                    { $$ = make_str("as"); }
-               | ASC                                                   { $$ = make_str("asc"); }
-               | BOTH                                                  { $$ = make_str("both"); }
-               | CASE                                                  { $$ = make_str("case"); }
-               | CAST                                                  { $$ = make_str("cast"); }
-               | CHECK                                                 { $$ = make_str("check"); }
-               | COLLATE                                               { $$ = make_str("collate"); }
-               | COLUMN                                                { $$ = make_str("column"); }
-               | CONSTRAINT                                    { $$ = make_str("constraint"); }
-               | CREATE                                                { $$ = make_str("create"); }
-               | CURRENT_DATE                                  { $$ = make_str("current_date"); }
-               | CURRENT_TIME                                  { $$ = make_str("current_time"); }
-               | CURRENT_TIMESTAMP                             { $$ = make_str("current_timestamp"); }
-               | CURRENT_USER                                  { $$ = make_str("current_user"); }
-               | DEFAULT                                               { $$ = make_str("default"); }
-               | DEFERRABLE                                    { $$ = make_str("deferrable"); }
-               | DESC                                                  { $$ = make_str("desc"); }
-               | DISTINCT                                              { $$ = make_str("distinct"); }
-               | DO                                                    { $$ = make_str("do"); }
-               | ELSE                                                  { $$ = make_str("else"); }
-               | END_P                                                 { $$ = make_str("end"); }
-               | EXCEPT                                                { $$ = make_str("except"); }
-               | FALSE_P                                               { $$ = make_str("false"); }
-               | FOR                                                   { $$ = make_str("for"); }
-               | FOREIGN                                               { $$ = make_str("foreign"); }
-               | FROM                                                  { $$ = make_str("from"); }
-               | GRANT                                                 { $$ = make_str("grant"); }
-               | GROUP_P                                               { $$ = make_str("group"); }
-               | HAVING                                                { $$ = make_str("having"); }
-               | INITIALLY                                             { $$ = make_str("initially"); }
-               | INTERSECT                                             { $$ = make_str("intersect"); }
-               | INTO                                                  { $$ = make_str("into"); }
-               | LEADING                                               { $$ = make_str("leading"); }
-               | LIMIT                                                 { $$ = make_str("limit"); }
-               | NEW                                                   { $$ = make_str("new"); }
-               | NOT                                                   { $$ = make_str("not"); }
-               | NULL_P                                                { $$ = make_str("null"); }
-               | OFF                                                   { $$ = make_str("off"); }
-               | OFFSET                                                { $$ = make_str("offset"); }
-               | OLD                                                   { $$ = make_str("old"); }
-               | ON                                                    { $$ = make_str("on"); }
-               | ONLY                                                  { $$ = make_str("only"); }
-               | OR                                                    { $$ = make_str("or"); }
-               | ORDER                                                 { $$ = make_str("order"); }
-               | PRIMARY                                               { $$ = make_str("primary"); }
-               | REFERENCES                                    { $$ = make_str("references"); }
-               | SELECT                                                { $$ = make_str("select"); }
-               | SESSION_USER                                  { $$ = make_str("session_user"); }
-               | SOME                                                  { $$ = make_str("some"); }
-               | TABLE                                                 { $$ = make_str("table"); }
-               | THEN                                                  { $$ = make_str("then"); }
-               | TO                                                    { $$ = make_str("to"); }
-               | TRAILING                                              { $$ = make_str("trailing"); }
-               | TRUE_P                                                { $$ = make_str("true"); }
+                 ALL                           { $$ = make_str("all"); }
+               | ANALYSE                       { $$ = make_str("analyse"); } /* British */
+               | ANALYZE                       { $$ = make_str("analyze"); }
+               | AND                           { $$ = make_str("and"); }
+               | ANY                           { $$ = make_str("any"); }
+               | ARRAY                         { $$ = make_str("array"); }
+               | AS                            { $$ = make_str("as"); }
+               | ASC                           { $$ = make_str("asc"); }
+               | BOTH                          { $$ = make_str("both"); }
+               | CASE                          { $$ = make_str("case"); }
+               | CAST                          { $$ = make_str("cast"); }
+               | CHECK                         { $$ = make_str("check"); }
+               | COLLATE                       { $$ = make_str("collate"); }
+               | COLUMN                        { $$ = make_str("column"); }
+               | CONSTRAINT                    { $$ = make_str("constraint"); }
+               | CREATE                        { $$ = make_str("create"); }
+               | CURRENT_DATE                  { $$ = make_str("current_date"); }
+               | CURRENT_TIME                  { $$ = make_str("current_time"); }
+               | CURRENT_TIMESTAMP             { $$ = make_str("current_timestamp"); }
+               | CURRENT_USER                  { $$ = make_str("current_user"); }
+               | DEFAULT                       { $$ = make_str("default"); }
+               | DEFERRABLE                    { $$ = make_str("deferrable"); }
+               | DESC                          { $$ = make_str("desc"); }
+               | DISTINCT                      { $$ = make_str("distinct"); }
+               | DO                            { $$ = make_str("do"); }
+               | ELSE                          { $$ = make_str("else"); }
+               | END_P                         { $$ = make_str("end"); }
+               | EXCEPT                        { $$ = make_str("except"); }
+               | FALSE_P                       { $$ = make_str("false"); }
+               | FOR                           { $$ = make_str("for"); }
+               | FOREIGN                       { $$ = make_str("foreign"); }
+               | FROM                          { $$ = make_str("from"); }
+               | GRANT                         { $$ = make_str("grant"); }
+               | GROUP_P                       { $$ = make_str("group"); }
+               | HAVING                        { $$ = make_str("having"); }
+               | INITIALLY                     { $$ = make_str("initially"); }
+               | INTERSECT                     { $$ = make_str("intersect"); }
+               | INTO                          { $$ = make_str("into"); }
+               | LEADING                       { $$ = make_str("leading"); }
+               | LIMIT                         { $$ = make_str("limit"); }
+               | NEW                           { $$ = make_str("new"); }
+               | NOT                           { $$ = make_str("not"); }
+               | NULL_P                        { $$ = make_str("null"); }
+               | OFF                           { $$ = make_str("off"); }
+               | OFFSET                        { $$ = make_str("offset"); }
+               | OLD                           { $$ = make_str("old"); }
+               | ON                            { $$ = make_str("on"); }
+               | ONLY                          { $$ = make_str("only"); }
+               | OR                            { $$ = make_str("or"); }
+               | ORDER                         { $$ = make_str("order"); }
+               | PRIMARY                       { $$ = make_str("primary"); }
+               | REFERENCES                    { $$ = make_str("references"); }
+               | SELECT                        { $$ = make_str("select"); }
+               | SESSION_USER                  { $$ = make_str("session_user"); }
+               | SOME                          { $$ = make_str("some"); }
+               | TABLE                         { $$ = make_str("table"); }
+               | THEN                          { $$ = make_str("then"); }
+               | TO                            { $$ = make_str("to"); }
+               | TRAILING                      { $$ = make_str("trailing"); }
+               | TRUE_P                        { $$ = make_str("true"); }
 /* UNION must be excluded from ECPGColLabel because of conflict with s_union
-               | UNION                                                 { $$ = make_str("union"); }
+               | UNION                         { $$ = make_str("union"); }
  */
-               | UNIQUE                                                { $$ = make_str("unique"); }
-               | USER                                                  { $$ = make_str("user"); }
-               | USING                                                 { $$ = make_str("using"); }
-               | WHEN                                                  { $$ = make_str("when"); }
-               | WHERE                                                 { $$ = make_str("where"); }
+               | UNIQUE                        { $$ = make_str("unique"); }
+               | USER                          { $$ = make_str("user"); }
+               | USING                         { $$ = make_str("using"); }
+               | WHEN                          { $$ = make_str("when"); }
+               | WHERE                         { $$ = make_str("where"); }
                ;
 
 
@@ -5808,8 +5921,16 @@ c_args: /*EMPTY*/                { $$ = EMPTY; }
                | c_list                { $$ = $1; }
                ;
 
-coutputvariable: CVARIABLE indicator
+coutputvariable: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']' 
+                       { add_variable(&argsresult, find_variable($1), $3, find_variable($5), $7); }
+               | CVARIABLE indicator '[' Iresult ']' 
+                       { add_variable(&argsresult, find_variable($1), NULL, find_variable($2), $4); }
+               | CVARIABLE '[' Iresult ']' indicator 
+                       { add_variable(&argsresult, find_variable($1), $3, find_variable($5), NULL); }
+               | CVARIABLE indicator
                        { add_variable(&argsresult, find_variable($1), NULL, find_variable($2), NULL); }
+               | CVARIABLE '[' Iresult ']'  
+                       { add_variable(&argsresult, find_variable($1), $3, &no_indicator, NULL); }
                | CVARIABLE
                        { add_variable(&argsresult, find_variable($1), NULL, &no_indicator, NULL); }
                ;
@@ -5817,17 +5938,13 @@ coutputvariable: CVARIABLE indicator
 
 civarind: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']' 
                {
-                       if (find_variable($5)->type->type == ECPGt_array)
-                               mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
-
                        add_variable(&argsinsert, find_variable($1), $3, find_variable($5), $7);
+                       $$ = create_questionmarks($1, true);
                }
                | CVARIABLE indicator '[' Iresult ']' 
                {
-                       if (find_variable($2)->type->type == ECPGt_array)
-                               mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
-
                        add_variable(&argsinsert, find_variable($1), NULL, find_variable($2), $4);
+                       $$ = create_questionmarks($1, false);
                }
                | CVARIABLE '[' Iresult ']' indicator 
                {
@@ -5835,6 +5952,7 @@ civarind: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']'
                                mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
 
                        add_variable(&argsinsert, find_variable($1), $3, find_variable($5), NULL);
+                       $$ = create_questionmarks($1, true);
                }
                | CVARIABLE indicator
                {
@@ -5842,19 +5960,20 @@ civarind: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']'
                                mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
 
                        add_variable(&argsinsert, find_variable($1), NULL, find_variable($2), NULL);
+                       $$ = create_questionmarks($1, false);
                }
                ;
 
 civar: CVARIABLE '[' Iresult ']' 
-               {
-                       add_variable(&argsinsert, find_variable($1), $3, &no_indicator, NULL);
-                       $$ = cat_str(4, $1, make_str("["), $3, make_str("]"));
-               }
+                       {
+                               add_variable(&argsinsert, find_variable($1), mm_strdup($3), &no_indicator, NULL);
+                               $$ = create_questionmarks($1, true);
+                       }
                | CVARIABLE
-               {
-                       add_variable(&argsinsert, find_variable($1), NULL, &no_indicator, NULL);
-                       $$ = $1;
-               }
+                       {
+                               add_variable(&argsinsert, find_variable($1), NULL, &no_indicator, NULL);
+                               $$ = create_questionmarks($1, false);
+                       }
                ;
 
 indicator: CVARIABLE                           { check_indicator((find_variable($1))->type); $$ = $1; }
index 9c2491544733478f7a5d1cd711af62f44cf8dba0..8bef0b36e2019f66c8a9e6594a351a40c9db00a3 100644 (file)
@@ -233,21 +233,81 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
                                        break;
                                case ECPGt_struct:
                                case ECPGt_union:
-                                       ECPGdump_a_struct(o, name, ind_name, type->size, type->u.element, (ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element, NULL, prefix, ind_prefix);
+                                       /* If var_array_element is not equal                                                                                                                                   * NULL, we have to use the                                                                                                                                            * <var_array_element>th entry and not                                                                                                                                 * the whole array */                                                                                                                                                 if (var_array_element == NULL)
+                                               ECPGdump_a_struct(o, name, ind_name, type->size,
+                                                               type->u.element,
+                                                               (ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element,
+                                                               NULL, prefix, ind_prefix);
+                                       else
+                                       {
+                                               char *array_element = (char *)mm_alloc(strlen(name) + strlen(var_array_element) + sizeof("[]\0")), *ind_array_element;
+                                               
+                                               sprintf(array_element, "%s[%s]", name, var_array_element);
+
+                                               if (ind_type->type != ECPGt_NO_INDICATOR)
+                                               {
+                                                       ind_array_element = (char *)mm_alloc(strlen(ind_name) + strlen(ind_array_element) + sizeof("+\0"));
+                                                       sprintf(ind_array_element, "%s[%s]", ind_name, ind_array_element);
+
+                                                       ECPGdump_a_struct(o, array_element, ind_array_element, make_str("1"),
+                                                                     type->u.element, ind_type->u.element,
+                                                                     NULL, prefix, ind_prefix);
+                                                       free(ind_array_element);
+                                               }
+                                               else
+                                                       ECPGdump_a_struct(o, array_element, ind_name, make_str("1"),
+                                                               type->u.element, ind_type,
+                                                               NULL, prefix, ind_prefix);
+
+                                               free (array_element);
+                                       }
                                        break;
                                default:
                                        if (!IS_SIMPLE_TYPE(type->u.element->type))
                                                yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
 
-                                       ECPGdump_a_simple(o, name, type->u.element->type,
+                                       /* If var_array_element is not equal
+                                        * NULL, we have to use the
+                                        * <var_array_element>th entry and not
+                                        * the whole array */
+                                       if (var_array_element == NULL)
+                                               ECPGdump_a_simple(o, name,
+                                                       type->u.element->type,
                                                type->u.element->size, type->size, NULL, prefix);
+                                       else
+                                       {
+                                               char *array_element = (char *)mm_alloc(strlen(name) + strlen(var_array_element) + sizeof("+\0"));
+                                               
+                                               sprintf(array_element, "%s+%s", name, var_array_element);
+                                               ECPGdump_a_simple(o, array_element,
+                                                       type->u.element->type,
+                                                       type->u.element->size, make_str("1"), NULL, prefix);
+                                               free(array_element);
+                                               
+                                               
+                                       }
+                                       
                                        if (ind_type != NULL)
                                        {
                                                if (ind_type->type == ECPGt_NO_INDICATOR)
                                                        ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, make_str("-1"), NULL, ind_prefix);
                                                else
-                                                       ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
-                                                                                         ind_type->u.element->size, ind_type->size, NULL, prefix);
+                                               {
+                                                       if (ind_array_element == NULL)
+                                                               ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
+                                                                                 ind_type->u.element->size, ind_type->size, NULL, prefix);
+                                                       else
+                                                       {
+                                                               char *array_element = (char *)mm_alloc(strlen(ind_name) + strlen(ind_array_element) + sizeof("+\0"));
+                                                       
+                                                               sprintf(array_element, "%s+%s", ind_name, ind_array_element);
+                                                               ECPGdump_a_simple(o, array_element,
+                                                                               ind_type->u.element->type,
+                                                                               ind_type->u.element->size,
+                                                                               make_str("1"), NULL, prefix);
+                                                               free(array_element);
+                                                       }
+                                               }
                                        }
                        }
                        break;