Fix behavior of ecpg's "EXEC SQL elif name".
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Aug 2020 13:46:12 +0000 (09:46 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Aug 2020 13:46:12 +0000 (09:46 -0400)
This ought to work much like C's "#elif defined(name)"; but the code
implemented it in a way equivalent to endif followed by ifdef, so that
it didn't matter whether any previous branch of the IF construct had
succeeded.  Fix that; add some test cases covering elif and nested IFs;
and improve the documentation, which also seemed a bit confused.

AFAICS the code has been like this since the feature was added in 1999
(commit b57b0e044).  So while it's surely wrong, there might be code
out there relying on the current behavior.  Hence, don't back-patch
into stable branches.  It seems all right to fix it in v13 though.

Per report from Ashutosh Sharma.  Reviewed by Ashutosh Sharma and
Michael Meskes.

Discussion: https://postgr.es/m/CAE9k0P=dQk9X0cU2tN49S7a9tv733-e1pVdpB1P-pWJ5PdTktg@mail.gmail.com

doc/src/sgml/ecpg.sgml
src/interfaces/ecpg/preproc/pgc.l
src/interfaces/ecpg/test/expected/preproc-define.c
src/interfaces/ecpg/test/expected/preproc-define.stderr
src/interfaces/ecpg/test/preproc/define.pgc

index 106ae0984e8aae594c0858be3dd9e0334273dd07..1f9d35eeb3ebccebff96438bdae0af301acc619f 100644 (file)
@@ -5695,7 +5695,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER;
   </sect2>
 
   <sect2 id="ecpg-ifdef">
-   <title>ifdef, ifndef, else, elif, and endif Directives</title>
+   <title>ifdef, ifndef, elif, else, and endif Directives</title>
    <para>
    You can use the following directives to compile code sections conditionally:
 
@@ -5705,7 +5705,7 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER;
      <listitem>
      <para>
       Checks a <replaceable>name</replaceable> and processes subsequent lines if
-      <replaceable>name</replaceable> has been created with <literal>EXEC SQL define
+      <replaceable>name</replaceable> has been defined via <literal>EXEC SQL define
       <replaceable>name</replaceable></literal>.
      </para>
      </listitem>
@@ -5716,30 +5716,40 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER;
      <listitem>
      <para>
       Checks a <replaceable>name</replaceable> and processes subsequent lines if
-      <replaceable>name</replaceable> has <emphasis>not</emphasis> been created with
+      <replaceable>name</replaceable> has <emphasis>not</emphasis> been defined via
       <literal>EXEC SQL define <replaceable>name</replaceable></literal>.
      </para>
      </listitem>
     </varlistentry>
 
     <varlistentry>
-     <term><literal>EXEC SQL else;</literal></term>
+     <term><literal>EXEC SQL elif <replaceable>name</replaceable>;</literal></term>
      <listitem>
      <para>
-      Starts processing an alternative section to a section introduced by
-      either <literal>EXEC SQL ifdef <replaceable>name</replaceable></literal> or
-      <literal>EXEC SQL ifndef <replaceable>name</replaceable></literal>.
+      Begins an optional alternative section after an
+      <literal>EXEC SQL ifdef <replaceable>name</replaceable></literal> or
+      <literal>EXEC SQL ifndef <replaceable>name</replaceable></literal>
+      directive.  Any number of <literal>elif</literal> sections can appear.
+      Lines following an <literal>elif</literal> will be processed
+      if <replaceable>name</replaceable> has been
+      defined <emphasis>and</emphasis> no previous section of the same
+      <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+      construct has been processed.
      </para>
      </listitem>
     </varlistentry>
 
     <varlistentry>
-     <term><literal>EXEC SQL elif <replaceable>name</replaceable>;</literal></term>
+     <term><literal>EXEC SQL else;</literal></term>
      <listitem>
      <para>
-      Checks <replaceable>name</replaceable> and starts an alternative section if
-      <replaceable>name</replaceable> has been created with <literal>EXEC SQL define
-      <replaceable>name</replaceable></literal>.
+      Begins an optional, final alternative section after an
+      <literal>EXEC SQL ifdef <replaceable>name</replaceable></literal> or
+      <literal>EXEC SQL ifndef <replaceable>name</replaceable></literal>
+      directive.  Subsequent lines will be processed if no previous section
+      of the same
+      <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+      construct has been processed.
      </para>
      </listitem>
     </varlistentry>
@@ -5748,7 +5758,9 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER;
      <term><literal>EXEC SQL endif;</literal></term>
      <listitem>
      <para>
-      Ends an alternative section.
+      Ends an
+      <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+      construct.  Subsequent lines are processed normally.
      </para>
      </listitem>
     </varlistentry>
@@ -5756,14 +5768,20 @@ EXEC SQL UPDATE Tbl SET col = MYNUMBER;
    </para>
 
    <para>
-    Example:
+    <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+    constructs can be nested, up to 127 levels deep.
+   </para>
+
+   <para>
+    This example will compile exactly one of the three <literal>SET
+    TIMEZONE</literal> commands:
 <programlisting>
-EXEC SQL ifndef TZVAR;
-EXEC SQL SET TIMEZONE TO 'GMT';
+EXEC SQL ifdef TZVAR;
+EXEC SQL SET TIMEZONE TO TZVAR;
 EXEC SQL elif TZNAME;
 EXEC SQL SET TIMEZONE TO TZNAME;
 EXEC SQL else;
-EXEC SQL SET TIMEZONE TO TZVAR;
+EXEC SQL SET TIMEZONE TO 'GMT';
 EXEC SQL endif;
 </programlisting>
    </para>
index f6052798fd54d5dbc112673cee167a6f3e475617..466bbac6a7b01406862876b4d20dd069e5e9033c 100644 (file)
@@ -79,13 +79,29 @@ struct _yy_buffer
 
 static char *old;
 
+/*
+ * Vars for handling ifdef/elif/endif constructs.  preproc_tos is the current
+ * nesting depth of such constructs, and stacked_if_value[preproc_tos] is the
+ * state for the innermost level.  (For convenience, stacked_if_value[0] is
+ * initialized as though we are in the active branch of some outermost IF.)
+ * The active field is true if the current branch is active (being expanded).
+ * The saw_active field is true if we have found any successful branch,
+ * so that all subsequent branches of this level should be skipped.
+ * The else_branch field is true if we've found an 'else' (so that another
+ * 'else' or 'elif' at this level is an error.)
+ * For IFs nested within an inactive branch, all branches always have active
+ * set to false, but saw_active and else_branch are maintained normally.
+ * ifcond is valid only while evaluating an if-condition; it's true if we
+ * are doing ifdef, false if ifndef.
+ */
 #define MAX_NESTED_IF 128
 static short preproc_tos;
-static short ifcond;
+static bool ifcond;
 static struct _if_value
 {
-   short condition;
-   short else_branch;
+   bool active;
+   bool saw_active;
+   bool else_branch;
 } stacked_if_value[MAX_NESTED_IF];
 
 %}
@@ -1165,11 +1181,26 @@ cppline         {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                          return S_ANYTHING;
                      }
                    }
-<C,xskip>{exec_sql}{ifdef}{space}* { ifcond = true; BEGIN(xcond); }
+<C,xskip>{exec_sql}{ifdef}{space}* {
+                     if (preproc_tos >= MAX_NESTED_IF-1)
+                         mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
+                     preproc_tos++;
+                     stacked_if_value[preproc_tos].active = false;
+                     stacked_if_value[preproc_tos].saw_active = false;
+                     stacked_if_value[preproc_tos].else_branch = false;
+                     ifcond = true;
+                     BEGIN(xcond);
+                   }
 <C,xskip>{informix_special}{ifdef}{space}* {
                      /* are we simulating Informix? */
                      if (INFORMIX_MODE)
                      {
+                         if (preproc_tos >= MAX_NESTED_IF-1)
+                             mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
+                         preproc_tos++;
+                         stacked_if_value[preproc_tos].active = false;
+                         stacked_if_value[preproc_tos].saw_active = false;
+                         stacked_if_value[preproc_tos].else_branch = false;
                          ifcond = true;
                          BEGIN(xcond);
                      }
@@ -1179,11 +1210,26 @@ cppline         {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                          return S_ANYTHING;
                      }
                    }
-<C,xskip>{exec_sql}{ifndef}{space}* { ifcond = false; BEGIN(xcond); }
+<C,xskip>{exec_sql}{ifndef}{space}* {
+                     if (preproc_tos >= MAX_NESTED_IF-1)
+                         mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
+                     preproc_tos++;
+                     stacked_if_value[preproc_tos].active = false;
+                     stacked_if_value[preproc_tos].saw_active = false;
+                     stacked_if_value[preproc_tos].else_branch = false;
+                     ifcond = false;
+                     BEGIN(xcond);
+                   }
 <C,xskip>{informix_special}{ifndef}{space}* {
                      /* are we simulating Informix? */
                      if (INFORMIX_MODE)
                      {
+                         if (preproc_tos >= MAX_NESTED_IF-1)
+                             mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
+                         preproc_tos++;
+                         stacked_if_value[preproc_tos].active = false;
+                         stacked_if_value[preproc_tos].saw_active = false;
+                         stacked_if_value[preproc_tos].else_branch = false;
                          ifcond = false;
                          BEGIN(xcond);
                      }
@@ -1193,16 +1239,13 @@ cppline         {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                          return S_ANYTHING;
                      }
                    }
-<C,xskip>{exec_sql}{elif}{space}*  {   /* pop stack */
-                       if ( preproc_tos == 0 ) {
+<C,xskip>{exec_sql}{elif}{space}*  {
+                       if (preproc_tos == 0)
                            mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
-                       }
-                       else if ( stacked_if_value[preproc_tos].else_branch )
+                       if (stacked_if_value[preproc_tos].else_branch)
                            mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\"");
-                       else
-                           preproc_tos--;
-
-                       ifcond = true; BEGIN(xcond);
+                       ifcond = true;
+                       BEGIN(xcond);
                    }
 <C,xskip>{informix_special}{elif}{space}* {
                    /* are we simulating Informix? */
@@ -1210,11 +1253,8 @@ cppline          {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                    {
                        if (preproc_tos == 0)
                            mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
-                       else if (stacked_if_value[preproc_tos].else_branch)
+                       if (stacked_if_value[preproc_tos].else_branch)
                            mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\"");
-                       else
-                           preproc_tos--;
-
                        ifcond = true;
                        BEGIN(xcond);
                    }
@@ -1226,16 +1266,19 @@ cppline         {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                }
 
 <C,xskip>{exec_sql}{else}{space}*";" { /* only exec sql endif pops the stack, so take care of duplicated 'else' */
-                   if (stacked_if_value[preproc_tos].else_branch)
+                   if ( preproc_tos == 0 )
+                       mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
+                   else if (stacked_if_value[preproc_tos].else_branch)
                        mmfatal(PARSE_ERROR, "more than one EXEC SQL ELSE");
                    else
                    {
                        stacked_if_value[preproc_tos].else_branch = true;
-                       stacked_if_value[preproc_tos].condition =
-                           (stacked_if_value[preproc_tos-1].condition &&
-                            !stacked_if_value[preproc_tos].condition);
+                       stacked_if_value[preproc_tos].active =
+                           (stacked_if_value[preproc_tos-1].active &&
+                            !stacked_if_value[preproc_tos].saw_active);
+                       stacked_if_value[preproc_tos].saw_active = true;
 
-                       if (stacked_if_value[preproc_tos].condition)
+                       if (stacked_if_value[preproc_tos].active)
                            BEGIN(C);
                        else
                            BEGIN(xskip);
@@ -1245,16 +1288,19 @@ cppline         {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                    /* are we simulating Informix? */
                    if (INFORMIX_MODE)
                    {
-                       if (stacked_if_value[preproc_tos].else_branch)
+                       if ( preproc_tos == 0 )
+                           mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
+                       else if (stacked_if_value[preproc_tos].else_branch)
                            mmfatal(PARSE_ERROR, "more than one EXEC SQL ELSE");
                        else
                        {
                            stacked_if_value[preproc_tos].else_branch = true;
-                           stacked_if_value[preproc_tos].condition =
-                           (stacked_if_value[preproc_tos-1].condition &&
-                            !stacked_if_value[preproc_tos].condition);
+                           stacked_if_value[preproc_tos].active =
+                               (stacked_if_value[preproc_tos-1].active &&
+                                !stacked_if_value[preproc_tos].saw_active);
+                           stacked_if_value[preproc_tos].saw_active = true;
 
-                           if (stacked_if_value[preproc_tos].condition)
+                           if (stacked_if_value[preproc_tos].active)
                                BEGIN(C);
                            else
                                BEGIN(xskip);
@@ -1272,7 +1318,7 @@ cppline           {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                    else
                        preproc_tos--;
 
-                   if (stacked_if_value[preproc_tos].condition)
+                   if (stacked_if_value[preproc_tos].active)
                       BEGIN(C);
                    else
                       BEGIN(xskip);
@@ -1286,7 +1332,7 @@ cppline           {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                        else
                            preproc_tos--;
 
-                       if (stacked_if_value[preproc_tos].condition)
+                       if (stacked_if_value[preproc_tos].active)
                            BEGIN(C);
                        else
                            BEGIN(xskip);
@@ -1301,12 +1347,10 @@ cppline         {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
 <xskip>{other}     { /* ignore */ }
 
 <xcond>{identifier}{space}*";" {
-                   if (preproc_tos >= MAX_NESTED_IF-1)
-                       mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
-                   else
                    {
                        struct _defines *defptr;
                        unsigned int i;
+                       bool this_active;
 
                        /*
                         *  Skip the ";" and trailing whitespace. Note that yytext
@@ -1324,13 +1368,15 @@ cppline         {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                             defptr = defptr->next)
                            /* skip */ ;
 
-                       preproc_tos++;
-                       stacked_if_value[preproc_tos].else_branch = false;
-                       stacked_if_value[preproc_tos].condition =
-                       (defptr ? ifcond : !ifcond) && stacked_if_value[preproc_tos-1].condition;
+                       this_active = (defptr ? ifcond : !ifcond);
+                       stacked_if_value[preproc_tos].active =
+                           (stacked_if_value[preproc_tos-1].active &&
+                            !stacked_if_value[preproc_tos].saw_active &&
+                            this_active);
+                       stacked_if_value[preproc_tos].saw_active |= this_active;
                    }
 
-                   if (stacked_if_value[preproc_tos].condition)
+                   if (stacked_if_value[preproc_tos].active)
                        BEGIN(C);
                    else
                        BEGIN(xskip);
@@ -1442,10 +1488,12 @@ lex_init(void)
    parenths_open = 0;
    current_function = NULL;
 
-   preproc_tos = 0;
    yylineno = 1;
-   ifcond = true;
-   stacked_if_value[preproc_tos].condition = ifcond;
+
+   /* initialize state for if/else/endif */
+   preproc_tos = 0;
+   stacked_if_value[preproc_tos].active = true;
+   stacked_if_value[preproc_tos].saw_active = true;
    stacked_if_value[preproc_tos].else_branch = false;
 
    /* initialize literal buffer to a reasonable but expansible size */
index bde15b74a0e7c38897577f96d7e5ad1825dc95db..0256609b1f96c4236b5c143679306efafb052162 100644 (file)
@@ -40,73 +40,90 @@ main(void)
 {
 /* exec sql begin declare section */
 
+
       typedef char  string [ 8 ];
 
-#line 21 "define.pgc"
+#line 22 "define.pgc"
 
     
       
-        
 
-#line 22 "define.pgc"
+      
+
+       
+
+
+
+      
+
+  
+      
+  
+          
+
+      
+
+
+
+#line 23 "define.pgc"
  intarray amount ;
  
-#line 23 "define.pgc"
+#line 24 "define.pgc"
  char name [ 6 ] [ 8 ] ;
  
-#line 24 "define.pgc"
+#line 37 "define.pgc"
  char letter [ 6 ] [ 1 ] ;
  
 #if 0
  
-#line 26 "define.pgc"
+#line 39 "define.pgc"
  int not_used ;
  
 #endif
 /* exec sql end declare section */
-#line 29 "define.pgc"
+#line 46 "define.pgc"
 
    int i,j;
 
    ECPGdebug(1, stderr);
 
    { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); 
-#line 34 "define.pgc"
+#line 51 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 34 "define.pgc"
+#line 51 "define.pgc"
 
 
    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test ( name char ( 8 ) , amount int , letter char ( 1 ) )", ECPGt_EOIT, ECPGt_EORT);
-#line 36 "define.pgc"
+#line 53 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 36 "define.pgc"
+#line 53 "define.pgc"
 
    { ECPGtrans(__LINE__, NULL, "commit");
-#line 37 "define.pgc"
+#line 54 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 37 "define.pgc"
+#line 54 "define.pgc"
 
 
    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into Test ( name , amount , letter ) values ( 'false' , 1 , 'f' )", ECPGt_EOIT, ECPGt_EORT);
-#line 39 "define.pgc"
+#line 56 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 39 "define.pgc"
+#line 56 "define.pgc"
 
    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into test ( name , amount , letter ) values ( 'true' , 2 , 't' )", ECPGt_EOIT, ECPGt_EORT);
-#line 40 "define.pgc"
+#line 57 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 40 "define.pgc"
+#line 57 "define.pgc"
 
    { ECPGtrans(__LINE__, NULL, "commit");
-#line 41 "define.pgc"
+#line 58 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 41 "define.pgc"
+#line 58 "define.pgc"
 
 
    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select * from test", ECPGt_EOIT, 
@@ -116,10 +133,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
    ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
    ECPGt_char,(letter),(long)1,(long)6,(1)*sizeof(char), 
    ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
-#line 43 "define.pgc"
+#line 60 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 43 "define.pgc"
+#line 60 "define.pgc"
 
 
    for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
@@ -129,16 +146,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
           
           
        
-#line 48 "define.pgc"
+#line 65 "define.pgc"
  string n ;
  
-#line 49 "define.pgc"
+#line 66 "define.pgc"
  char l = letter [ i ] [ 0 ] ;
  
-#line 50 "define.pgc"
+#line 67 "define.pgc"
  int a = amount [ i ] ;
 /* exec sql end declare section */
-#line 51 "define.pgc"
+#line 68 "define.pgc"
 
 
        strncpy(n, name[i],  8);
@@ -146,22 +163,22 @@ if (sqlca.sqlcode < 0) sqlprint();}
    }
 
    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test", ECPGt_EOIT, ECPGt_EORT);
-#line 57 "define.pgc"
+#line 74 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 57 "define.pgc"
+#line 74 "define.pgc"
 
    { ECPGtrans(__LINE__, NULL, "commit");
-#line 58 "define.pgc"
+#line 75 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 58 "define.pgc"
+#line 75 "define.pgc"
 
    { ECPGdisconnect(__LINE__, "CURRENT");
-#line 59 "define.pgc"
+#line 76 "define.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 59 "define.pgc"
+#line 76 "define.pgc"
 
 
    return 0;
index 722cdc7572f868d01eb925ce9f4bcbfa7aaa2de5..869dc46b0dc01dda3b6fded135db229d7fb7942f 100644 (file)
@@ -2,53 +2,53 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ECPGconnect: opening database ecpg1_regression on <DEFAULT> port <DEFAULT>  
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 36: query: create table test ( name char ( 8 ) , amount int , letter char ( 1 ) ); with 0 parameter(s) on connection ecpg1_regression
+[NO_PID]: ecpg_execute on line 53: query: create table test ( name char ( 8 ) , amount int , letter char ( 1 ) ); with 0 parameter(s) on connection ecpg1_regression
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 36: using PQexec
+[NO_PID]: ecpg_execute on line 53: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 36: OK: CREATE TABLE
+[NO_PID]: ecpg_process_output on line 53: OK: CREATE TABLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ECPGtrans on line 37: action "commit"; connection "ecpg1_regression"
+[NO_PID]: ECPGtrans on line 54: action "commit"; connection "ecpg1_regression"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 39: query: insert into Test ( name , amount , letter ) values ( 'false' , 1 , 'f' ); with 0 parameter(s) on connection ecpg1_regression
+[NO_PID]: ecpg_execute on line 56: query: insert into Test ( name , amount , letter ) values ( 'false' , 1 , 'f' ); with 0 parameter(s) on connection ecpg1_regression
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 39: using PQexec
+[NO_PID]: ecpg_execute on line 56: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 39: OK: INSERT 0 1
+[NO_PID]: ecpg_process_output on line 56: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 40: query: insert into test ( name , amount , letter ) values ( 'true' , 2 , 't' ); with 0 parameter(s) on connection ecpg1_regression
+[NO_PID]: ecpg_execute on line 57: query: insert into test ( name , amount , letter ) values ( 'true' , 2 , 't' ); with 0 parameter(s) on connection ecpg1_regression
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 40: using PQexec
+[NO_PID]: ecpg_execute on line 57: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 40: OK: INSERT 0 1
+[NO_PID]: ecpg_process_output on line 57: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ECPGtrans on line 41: action "commit"; connection "ecpg1_regression"
+[NO_PID]: ECPGtrans on line 58: action "commit"; connection "ecpg1_regression"
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 43: query: select * from test; with 0 parameter(s) on connection ecpg1_regression
+[NO_PID]: ecpg_execute on line 60: query: select * from test; with 0 parameter(s) on connection ecpg1_regression
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 43: using PQexec
+[NO_PID]: ecpg_execute on line 60: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 43: correctly got 2 tuples with 3 fields
+[NO_PID]: ecpg_process_output on line 60: correctly got 2 tuples with 3 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 43: RESULT: false    offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 60: RESULT: false    offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 43: RESULT: true     offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 60: RESULT: true     offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 43: RESULT: 1 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 60: RESULT: 1 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 43: RESULT: 2 offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 60: RESULT: 2 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 43: RESULT: f offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 60: RESULT: f offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 43: RESULT: t offset: -1; array: no
+[NO_PID]: ecpg_get_data on line 60: RESULT: t offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 57: query: drop table test; with 0 parameter(s) on connection ecpg1_regression
+[NO_PID]: ecpg_execute on line 74: query: drop table test; with 0 parameter(s) on connection ecpg1_regression
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 57: using PQexec
+[NO_PID]: ecpg_execute on line 74: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_process_output on line 57: OK: DROP TABLE
+[NO_PID]: ecpg_process_output on line 74: OK: DROP TABLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ECPGtrans on line 58: action "commit"; connection "ecpg1_regression"
+[NO_PID]: ECPGtrans on line 75: action "commit"; connection "ecpg1_regression"
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_finish: connection ecpg1_regression closed
 [NO_PID]: sqlca: code: 0, state: 00000
index 0d07ebfe6363c3d0dbbaf90f84ff78276d9711f1..d360da7ece2a89f24812d9da8d5ecbc82546879b 100644 (file)
@@ -17,15 +17,32 @@ int
 main(void)
 {
 exec sql begin declare section;
+
 exec sql ifdef NAMELEN;
    typedef char string[NAMELEN];
    intarray amount;
    char name[AMOUNT][NAMELEN];
+exec sql elif AMOUNT;
+   should not get here;
+exec sql else;
+   should not get here either;
+exec sql endif;
+
+exec sql ifndef NAMELEN;
+   should not get here;
+exec sql elif AMOUNT;
+  exec sql ifdef NOSUCHNAME;
+   should not get here;
+  exec sql else;
    char letter[AMOUNT][1];
 #if 0
    int not_used;
 #endif
+  exec sql endif;
+exec sql elif AMOUNT;
+   should not get here;
 exec sql endif;
+
 exec sql end declare section;
    int i,j;