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;