]> granicus.if.org Git - postgresql/commitdiff
- Fixed bug in adjust_informix that treated arrays as simple variables.
authorMichael Meskes <meskes@postgresql.org>
Wed, 5 May 2004 15:03:04 +0000 (15:03 +0000)
committerMichael Meskes <meskes@postgresql.org>
Wed, 5 May 2004 15:03:04 +0000 (15:03 +0000)
- Synced parser again.
- Synced lexer.

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ecpglib/data.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/preproc/pgc.l
src/interfaces/ecpg/preproc/preproc.y

index b21b5646aa4a9681043e0f11d0c70d58c8b3706d..b1f3a52c3f43eabdeef5219c7508b3c98fa5c705 100644 (file)
@@ -1777,6 +1777,13 @@ Thu Apr 22 14:13:57 CEST 2004
 Thu Apr 29 16:06:37 CEST 2004
 
        - Synced parser and keyword list.
+       
+Wed May  5 11:51:47 CEST 2004
+
+       - Fixed bug in adjust_informix that treated arrays as simple
+         variables.
+       - Synced parser again.
+       - Synced lexer.
        - Set pgtypes library version to 1.2.
        - Set ecpg version to 3.2.0.
        - Set compat library version to 1.2.
index 54d81fd684916d158044f5a1b1b2024a03f5b599..5626b0debcfe681597b7682d4161c29cf00aa6fa 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.22 2003/11/29 19:52:08 pgsql Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.23 2004/05/05 15:03:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -44,7 +44,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
        char       *pval = (char *) PQgetvalue(results, act_tuple, act_field);
        int                     value_for_indicator = 0;
 
-       ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld array: %d\n", lineno, pval ? pval : "", offset, isarray);
+       ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld array: %s\n", lineno, pval ? pval : "", offset, isarray?"Yes":"No");
 
        /* pval is a pointer to the value */
        /* let's check if it really is an array if it should be one */
index 758f878ff89a7e5861fefd487a66cf7549c1edd8..2cee7c70c9c0e6929c99cc32d2033c091b64a558 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.32 2004/01/28 09:52:14 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.33 2004/05/05 15:03:04 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -333,7 +333,7 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
        }
        PQclear(query);
        ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
-       ECPGlog("ECPGis_type_an_array line %d: TYPE database: %d C: %d array: %d\n", stmt->lineno, type, var->type, isarray);
+       ECPGlog("ECPGis_type_an_array line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, type, var->type, isarray?"Yes":"No");
        return isarray;
 }
 
index 2202a17da3979927d0040e6d79342a75d2d6294b..a6d9d755438424187fd75e0b38f3d428b3e6c473 100644 (file)
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.127 2004/03/02 06:45:05 meskes Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.128 2004/05/05 15:03:04 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,6 +28,7 @@
 extern YYSTYPE yylval;
 
 static int             xcdepth = 0;    /* depth of nesting in slash-star comments */
+static char    *dolqstart;      /* current $foo$ quote start string */
 
 /*
  * literalbuf is used to accumulate literal values when multiple rules
@@ -93,6 +94,7 @@ static struct _if_value
  *     <xd> delimited identifiers (double-quoted identifiers) - thomas 1997-10-27
  *     <xh> hexadecimal numeric string - thomas 1997-11-16
  *     <xq> quoted strings - thomas 1997-07-30
+ *     <xdolq> $foo$ quoted strings
  */
 
 %x xb
@@ -101,6 +103,7 @@ static struct _if_value
 %x xdc
 %x xh
 %x xq
+%x xdolq
 %x xpre
 %x xcond
 %x xskip
@@ -128,7 +131,7 @@ xnstart                        [nN]{quote}
 xch                    0[xX][0-9A-Fa-f]*
 
 /* Extended quote
- * xqdouble implements SQL92 embedded quote
+ * xqdouble implements embedded quote
  * xqcat allows strings to cross input lines
  */
 quote                  '
@@ -140,6 +143,17 @@ xqescape                [\\][^0-7]
 xqoctesc                [\\][0-7]{1,3}
 xqcat                  {quote}{whitespace_with_newline}{quote}
 
+/* $foo$ style quotes ("dollar quoting")
+ * The quoted string starts with $foo$ where "foo" is an optional string
+ * in the form of an identifier, except that it may not contain "$",
+ * and extends to the first occurrence of an identical string.
+ * There is *no* processing of the quoted text.
+ */
+dolq_start             [A-Za-z\200-\377_]
+dolq_cont              [A-Za-z\200-\377_0-9]
+dolqdelim              \$({dolq_start}{dolq_cont}*)?\$
+dolqinside             [^$]+
+
 /* Double quote
  * Allows embedded spaces and other special characters into identifiers.
  */
@@ -171,8 +185,7 @@ xdcinside           ({xdcqq}|{xdcqdq}|{xdcother})
  * 2. In the operator rule, check for slash-star within the operator, and
  *       if found throw it back with yyless().  This handles the plus-slash-star
  *       problem.
- * SQL92-style comments, which start with dash-dash, have similar interactions
- * with the operator rule.
+ * Dash-dash comments have similar interactions with the operator rule.
  */
 xcstart                        \/\*{op_chars}*
 xcstop                 \*+\/
@@ -279,9 +292,10 @@ cppinclude                 {space}*#{include}{space}*
 cppline                        {space}*#(.*\\{space})+.*
 
 /*
- * Quoted strings must allow some special characters such as single-quote
+ * Dollar quoted strings are totally opaque, and no escaping is done on them.
+ * Other quoted strings must allow some special characters such as single-quote
  *     and newline.
- * Embedded single-quotes are implemented both in the SQL92-standard
+ * Embedded single-quotes are implemented both in the SQL standard
  *     style of two adjacent single quotes "''" and in the Postgres/Java style
  *     of escaped-quote "\'".
  * Other embedded escaped characters are matched explicitly and the leading
@@ -341,7 +355,7 @@ cppline                     {space}*#(.*\\{space})+.*
                                                BEGIN(SQL);
                                                if (literalbuf[strspn(literalbuf, "01") + 1] != '\0')
                                                        mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string input.");
-                                               yylval.str = literalbuf;
+                                               yylval.str = mm_strdup(literalbuf);
                                                return BCONST;
                                        }
 
@@ -358,7 +372,7 @@ cppline                     {space}*#(.*\\{space})+.*
                                                addlitchar('x');
                                        }
 <xh>{xhstop}           {
-                                               yylval.str = literalbuf;
+                                               yylval.str = mm_strdup(literalbuf);
                                                return XCONST;
                                        }
 
@@ -388,8 +402,44 @@ cppline                    {space}*#(.*\\{space})+.*
 <xq>{xqescape}         { addlit(yytext, yyleng); }
 <xq>{xqoctesc}          { addlit(yytext, yyleng); }
 <xq>{xqcat}            { /* ignore */ }
-
+<xq>.                   {
+                                       /* This is only needed for \ just before EOF */
+                                       addlitchar(yytext[0]);
+                        }
 <xq><<EOF>>            { mmerror(PARSE_ERROR, ET_FATAL, "Unterminated quoted string"); }
+<SQL>{dolqdelim}        {
+                               token_start = yytext;
+                               dolqstart = mm_strdup(yytext);
+                               BEGIN(xdolq);
+                               startlit();
+                       }
+<xdolq>{dolqdelim}      {
+                               if (strcmp(yytext, dolqstart) == 0)
+                               {
+                                       free(dolqstart);
+                                       BEGIN(SQL);
+                                       yylval.str = mm_strdup(literalbuf);
+                                       return SCONST;
+                               }
+                               else
+                               {
+                                       /*
+                                        * When we fail to match $...$ to dolqstart, transfer
+                                        * the $... part to the output, but put back the final
+                                        * $ for rescanning.  Consider $delim$...$junk$delim$
+                                        */
+                                       addlit(yytext, yyleng-1);
+                                       yyless(yyleng-1);
+                               }
+                       }
+<xdolq>{dolqinside}    {
+                               addlit(yytext, yyleng);
+                       }
+<xdolq>.               {
+                               /* This is only needed for $ inside the quoted text */
+                               addlitchar(yytext[0]);
+                       }
+<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
 
 <SQL>{xdstart}         {
                                                state_before = YYSTATE;
@@ -400,6 +450,7 @@ cppline                     {space}*#(.*\\{space})+.*
                                                BEGIN(state_before);
                                                if (literallen == 0)
                                                        mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier");
+                                               /* The backend will truncate the idnetifier here. We do not as it does not change the result. */
                                                yylval.str = mm_strdup(literalbuf);
                                                return CSTRING;
                                        }
@@ -459,12 +510,12 @@ cppline                   {space}*#(.*\\{space})+.*
                                                        nchars = slashstar - yytext;
 
                                                /*
-                                                * For SQL92 compatibility, '+' and '-' cannot be the
+                                                * For SQL compatibility, '+' and '-' cannot be the
                                                 * last char of a multi-char operator unless the operator
-                                                * contains chars that are not in SQL92 operators.
+                                                * contains chars that are not in SQL operators.
                                                 * The idea is to lex '=-' as two operators, but not
                                                 * to forbid operator names like '?-' that could not be
-                                                * sequences of SQL92 operators.
+                                                * sequences of SQL operators.
                                                 */
                                                while (nchars > 1 &&
                                                           (yytext[nchars-1] == '+' ||
index aca66367ca621770033519e054b2f49b66614641..3dd7d8b361a7f6e96303608d17c94b52ba090b04 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.278 2004/04/29 14:08:10 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.279 2004/05/05 15:03:04 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -211,7 +211,7 @@ adjust_informix(struct arguments *list)
                
                if (atoi(ptr->variable->type->size) > 1)
                {
-                       ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0);
+                       ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1")), ptr->variable->type->size), 0);
                        sprintf(temp, "%d, (", ecpg_informix_var++);
                }
                else
@@ -442,7 +442,7 @@ add_additional_variables(char *name, bool insert)
 %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 qualified_name database_name
+%type  <str>   update_target_el qualified_name database_name alter_using
 %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
@@ -464,15 +464,15 @@ add_additional_variables(char *name, bool insert)
 %type  <str>   copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
 %type  <str>   FetchStmt from_in CreateOpClassStmt like_including_defaults
 %type  <str>   ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
-%type  <str>   opt_full func_arg OptWithOids opt_freeze 
+%type  <str>   opt_full func_arg OptWithOids opt_freeze alter_table_cmd 
 %type  <str>   analyze_keyword opt_name_list ExplainStmt index_params
-%type  <str>   index_elem opt_class access_method_clause
+%type  <str>   index_elem opt_class access_method_clause alter_table_cmds
 %type  <str>   index_opt_unique IndexStmt func_return ConstInterval
 %type  <str>   func_args_list func_args opt_with def_arg overlay_placing
 %type  <str>   def_elem def_list definition DefineStmt select_with_parens
 %type  <str>   opt_instead event RuleActionList opt_using CreateAssertStmt
 %type  <str>   RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
-%type  <str>   RuleStmt opt_column opt_name oper_argtypes NumConst
+%type  <str>   RuleStmt opt_column oper_argtypes NumConst
 %type  <str>   MathOp RemoveFuncStmt aggr_argtype for_update_clause
 %type  <str>   RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt
 %type  <str>   RemoveOperStmt RenameStmt all_Op opt_Trusted opt_lancompiler
@@ -1140,45 +1140,58 @@ CheckPointStmt: CHECKPOINT         { $$= make_str("checkpoint"); }
  *****************************************************************************/
 
 AlterTableStmt:
+               ALTER TABLE relation_expr alter_table_cmds
+                       { $$ = cat_str(3, make_str("alter table"), $3, $4); }
+               ;
+
+alter_table_cmds:
+               alter_table_cmd                         { $$ = $1; }
+               | alter_table_cmds ',' alter_table_cmd  { $$ = cat_str(3, $1, make_str(","), $3); }
+               ;
+
+alter_table_cmd:
+               ADD opt_column columnDef
 /* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
-               ALTER TABLE relation_expr ADD opt_column columnDef
-                       { $$ = cat_str(5, make_str("alter table"), $3, make_str("add"), $5, $6); }
+                       { $$ = cat_str(3, make_str("add"), $2, $3); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
-               | ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
-                       { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, $7); }
+               | ALTER opt_column ColId alter_column_default
+                       { $$ = cat_str(4, make_str("alter"), $2, $3, $4); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
-               | ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P
-                       { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("drop not null")); }
+               | ALTER opt_column ColId DROP NOT NULL_P
+                       { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("drop not null")); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
-               | ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P
-                       { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set not null")); }
+               | ALTER opt_column ColId SET NOT NULL_P
+                       { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("set not null")); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <IntegerOnly> */
-               | ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS PosIntConst
-                       { $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set statistics"), $9); }
+               | ALTER opt_column ColId SET STATISTICS PosIntConst
+                       { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set statistics"), $6); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
-               | ALTER TABLE relation_expr ALTER opt_column ColId SET STORAGE ColId
-                       { $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set storage"), $9); }
+               | ALTER opt_column ColId SET STORAGE ColId
+                       { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set storage"), $6); }
 /* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
-               | ALTER TABLE relation_expr DROP opt_column ColId opt_drop_behavior
-                       { $$ = cat_str(6, make_str("alter table"), $3, make_str("drop"), $5, $6, $7); }
+               | DROP opt_column ColId opt_drop_behavior
+                       { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
+/* ALTER TABLE <relation> ALTER [COLUMN] <colname> TYPE <typename> [ USING <expression> ] */
+               | ALTER opt_column ColId TYPE_P Typename alter_using
+                       { $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); }
 /* ALTER TABLE <relation> ADD CONSTRAINT ... */
-               | ALTER TABLE relation_expr ADD TableConstraint
-                       { $$ = cat_str(4, make_str("alter table"), $3, make_str("add"), $5); }
+               | ADD TableConstraint
+                       { $$ = cat_str(2, make_str("add"), $2); }
 /* ALTER TABLE <relation> DROP CONSTRAINT ... */
-               | ALTER TABLE relation_expr DROP CONSTRAINT name opt_drop_behavior
-                       { $$ = cat_str(5, make_str("alter table"), $3, make_str("drop constraint"), $6, $7); }
+               | DROP CONSTRAINT name opt_drop_behavior
+                       { $$ = cat_str(3, make_str("drop constraint"), $3, $4); }
 /* ALTER TABLE <relation> SET WITHOUT OIDS  */
-               | ALTER TABLE relation_expr SET WITHOUT OIDS
-                       { $$ = cat_str(3, make_str("alter table"), $3, make_str("set without oids")); }
+               | SET WITHOUT OIDS
+                       { $$ = make_str("set without oids"); }
  /* ALTER TABLE <name> CREATE TOAST TABLE */
-               | ALTER TABLE qualified_name CREATE TOAST TABLE
-                       { $$ = cat_str(3, make_str("alter table"), $3, make_str("create toast table")); }
+               | CREATE TOAST TABLE
+                       { $$ = make_str("create toast table"); }
 /* 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); }
+               | OWNER TO UserId
+                       { $$ = cat_str(2, make_str("owner to"), $3); }
 /* 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); }
+               | CLUSTER ON name
+                       { $$ = cat_str(2, make_str("cluster on"), $3); }
                ;
 
 alter_column_default:
@@ -1191,6 +1204,10 @@ opt_drop_behavior: CASCADE                       { $$ = make_str("cascade"); }
                | /* EMPTY */                   { $$ = EMPTY; }
                ;
 
+alter_using:   USING a_expr                    { $$ = cat2_str(make_str("using"), $2); }
+               | /* EMPTY */                   { $$ = EMPTY; }
+               ;
+                               
 /*****************************************************************************
  *
  *             QUERY :
@@ -2310,7 +2327,9 @@ RenameStmt:  ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
                        { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
        | ALTER SCHEMA name RENAME TO name
                        { $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
-       | ALTER TABLE relation_expr RENAME opt_column opt_name TO name
+       | ALTER TABLE relation_expr RENAME TO name
+                       { $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
+       | ALTER TABLE relation_expr RENAME opt_column name TO name
                        { $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
        | ALTER TRIGGER name ON relation_expr RENAME TO name
                        { $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
@@ -2318,10 +2337,6 @@ RenameStmt:  ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
                        { $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
                ;
 
-opt_name:  name                                { $$ = $1; }
-               | /*EMPTY*/                     { $$ = EMPTY; }
-               ;
-
 opt_column:  COLUMN                    { $$ = make_str("column"); }
                | /*EMPTY*/                     { $$ = EMPTY; }
                ;