Re: ECPG support for struct in INTO list - Mailing list pgsql-hackers

From Boszormenyi Zoltan
Subject Re: ECPG support for struct in INTO list
Date
Msg-id 4A85C0AF.2080704@cybertec.at
Whole thread Raw
In response to Re: ECPG support for struct in INTO list  (Boszormenyi Zoltan <zb@cybertec.at>)
List pgsql-hackers
Hi,

I got around to fix the struct problem, when ECPG aborted
upon finding the following statement:

DECLARE mycur
    CURSOR FOR
    SELECT *
    INTO :mystruct [:myindicatorstruct] ...

As I found out earlier, ECPG also aborted when the variable
is a pointer, like:
    struct mytype   *myvar;

I fixed both cases, and added the quirk to the lexer to keep
the last identifier as a function name before any ( or { is
encountered and this allowed me to detect and handle
out of scope DECLARE/OPEN/FETCH.
You know the ecpg lexer/grammar better than me,
you may find a better way to do this.

Anyway, the end result is that now in compat mode
ECPGinformix_get_var() type vars are not always used,
only when OPEN and FETCH are out of scope, i.e. they
are in a function different from where the cursor was
DECLAREd.

I added two regression tests, one tests only the struct
usability in compat mode, which didn't work before and
started this little "crusade". :-) The other tests struct pointers
and out of scope DECLARE/OPEN/FETCH.

Tell me that this isn't a useful feature in non-compat mode.
I will leave the rewrite to you if you find it so, I left a comment
for you in the code. ;-)

Best regards,
Zoltán Böszörményi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
http://www.postgresql.at/

diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/descriptor.c
pgsql.ooscur/src/interfaces/ecpg/preproc/descriptor.c
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/descriptor.c    2009-08-11 10:32:34.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/descriptor.c    2009-08-14 09:59:15.000000000 +0200
*************** struct variable *
*** 317,323 ****
  descriptor_variable(const char *name, int input)
  {
      static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
!     static const struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, {NULL}, 0};
      static const struct variable varspace[2] = {
          {descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL},
          {descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL}
--- 317,323 ----
  descriptor_variable(const char *name, int input)
  {
      static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
!     static const struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
      static const struct variable varspace[2] = {
          {descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL},
          {descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL}
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.addons
pgsql.ooscur/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.addons    2009-08-13 17:40:41.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/ecpg.addons    2009-08-14 21:18:34.000000000 +0200
*************** ECPG: DeclareCursorStmtDECLAREcursor_nam
*** 309,314 ****
--- 309,315 ----

          this->next = cur;
          this->name = $2;
+         this->function = (current_function ? mm_strdup(current_function) : NULL);
          this->connection = connection;
          this->opened = false;
          this->command =  cat_str(7, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for"),
$7);
*************** ECPG: DeclareCursorStmtDECLAREcursor_nam
*** 328,337 ****
              {
                  char *command = (char *)mm_alloc(sizeof("ECPGreset_sqlca(__LINE__, );") + strlen(con));
                  sprintf(command, "ECPGreset_sqlca(__LINE__, %s);", con);
!                 $$ = cat_str(4, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), command,
comment);
              }
              else
!                 $$ = cat_str(3, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), comment);
          }
          else
              $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
--- 329,338 ----
              {
                  char *command = (char *)mm_alloc(sizeof("ECPGreset_sqlca(__LINE__, );") + strlen(con));
                  sprintf(command, "ECPGreset_sqlca(__LINE__, %s);", con);
!                 $$ = cat_str(4, adjust_informix(this, true), adjust_informix(this, false), command, comment);
              }
              else
!                 $$ = cat_str(3, adjust_informix(this, true), adjust_informix(this, false), comment);
          }
          else
              $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.header
pgsql.ooscur/src/interfaces/ecpg/preproc/ecpg.header
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.header    2009-08-13 17:37:57.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/ecpg.header    2009-08-14 21:49:27.000000000 +0200
***************
*** 33,38 ****
--- 33,39 ----
   */
  int struct_level = 0;
  int braces_open; /* brace level counter */
+ char *current_function;
  int ecpg_informix_var = 0;
  char    *connection = NULL;
  char    *input_filename = NULL;
*************** static char *ECPGstruct_sizeof = NULL;
*** 53,62 ****
  /* for forward declarations we have to store some data as well */
  static char *forward_name = NULL;

! struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, NULL, NULL, {NULL}, 0};
  struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};

! struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, {NULL}, 0};

  /*
   * Handle parsing errors and warnings
--- 54,63 ----
  /* for forward declarations we have to store some data as well */
  static char *forward_name = NULL;

! struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, NULL, NULL, NULL, {NULL}, 0};
  struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};

! struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NULL}, 0};

  /*
   * Handle parsing errors and warnings
*************** create_questionmarks(char *name, bool ar
*** 230,236 ****
  }

  static char *
! adjust_informix(struct arguments *list)
  {
      /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
        * for instance you can declare variables in a function, and then subsequently use them
--- 231,237 ----
  }

  static char *
! adjust_informix(struct cursor *cur, bool insert)
  {
      /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
        * for instance you can declare variables in a function, and then subsequently use them
*************** adjust_informix(struct arguments *list)
*** 244,252 ****
--- 245,275 ----
       * We have to change the variables to our own struct and just store the pointer instead of the variable
       */

+      struct arguments *list;
       struct arguments *ptr;
+      struct arguments *newlist = NULL;
+      struct variable *newvar, *newind;
       char *result = make_str("");

+ /*
+  * This only needed if the out-of-scope DECLARE is
+  * decided to be useful for non-compat mode, too.
+  * DECLARE has just been proved to be a non-declarative
+  * statement in Informix.
+  */
+ #if 0
+     /*
+      * If we're outside of a function, then DECLARE can only reference
+      * variables in the global scope. They don't need transforming.
+      * This also prevents emitting ECPGinformix_set_var() calls
+      * outside of functions.
+      */
+      if (cur->function == NULL) /* same as checking for (braces_open == 0) */
+         return result;
+ #endif
+
+      list = (insert ? cur->argsinsert : cur->argsresult);
+
       for (ptr = list; ptr != NULL; ptr = ptr->next)
       {
           char temp[20]; /* this should be sufficient unless you have 8 byte integers */
*************** adjust_informix(struct arguments *list)
*** 258,274 ****

          if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char &&
ptr->variable->type->type!= ECPGt_unsigned_char && ptr->variable->type->type != ECPGt_string) &&
atoi(ptr->variable->type->size)> 1) 
          {
!             ptr->variable = new_variable(cat_str(4, make_str("("),
mm_strdup(ecpg_type_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->u.element->lineno),ptr->variable->type->size), 0); 
              sprintf(temp, "%d, (", ecpg_informix_var++);
          }
          else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char ||
ptr->variable->type->type== ECPGt_unsigned_char || ptr->variable->type->type == ECPGt_string) &&
atoi(ptr->variable->type->size)> 1) 
          {
!             ptr->variable = new_variable(cat_str(4, make_str("("),
mm_strdup(ecpg_type_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, ptr->variable->type->lineno), 0); 
              sprintf(temp, "%d, (", ecpg_informix_var++);
          }
          else
          {
!             ptr->variable = new_variable(cat_str(4, make_str("*("),
mm_strdup(ecpg_type_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, ptr->variable->type->lineno), 0); 
              sprintf(temp, "%d, &(", ecpg_informix_var++);
          }

--- 281,317 ----

          if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char &&
ptr->variable->type->type!= ECPGt_unsigned_char && ptr->variable->type->type != ECPGt_string) &&
atoi(ptr->variable->type->size)> 1) 
          {
!             newvar = new_variable(cat_str(4, make_str("("),
mm_strdup(ecpg_type_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->u.element->lineno),ptr->variable->type->size), 0); 
              sprintf(temp, "%d, (", ecpg_informix_var++);
          }
          else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char ||
ptr->variable->type->type== ECPGt_unsigned_char || ptr->variable->type->type == ECPGt_string) &&
atoi(ptr->variable->type->size)> 1) 
          {
!             newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_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,ptr->variable->type->lineno), 0); 
              sprintf(temp, "%d, (", ecpg_informix_var++);
          }
+         else if (ptr->variable->type->type == ECPGt_struct || ptr->variable->type->type == ECPGt_union)
+         {
+             sprintf(temp, "%d)))", ecpg_informix_var);
+             newvar = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->variable->type->type_name), make_str("
*)(ECPG_informix_get_var("),mm_strdup(temp)), ECPGmake_struct_type(ptr->variable->type->u.members,
ptr->variable->type->type,ptr->variable->type->type_name, ptr->variable->type->struct_sizeof), 0); 
+             sprintf(temp, "%d, &(", ecpg_informix_var++);
+         }
+         else if (ptr->variable->type->type == ECPGt_array)
+         {
+             if (ptr->variable->type->u.element->type == ECPGt_struct || ptr->variable->type->u.element->type ==
ECPGt_union)
+             {
+                 sprintf(temp, "%d)))", ecpg_informix_var);
+                 newvar = new_variable(cat_str(4, make_str("(*("),
mm_strdup(ptr->variable->type->u.element->type_name),make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)),
ECPGmake_struct_type(ptr->variable->type->u.element->u.members,ptr->variable->type->u.element->type,
ptr->variable->type->u.element->type_name,ptr->variable->type->u.element->struct_sizeof), 0); 
+                 sprintf(temp, "%d, (", ecpg_informix_var++);
+             }
+             else
+             {
+                 newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)),
make_str("*)(ECPG_informix_get_var("), mm_strdup(temp)),
ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type,ptr->variable->type->u.element->size,
ptr->variable->type->u.element->lineno),ptr->variable->type->size), 0); 
+                 sprintf(temp, "%d, &(", ecpg_informix_var++);
+             }
+         }
          else
          {
!             newvar = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_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,ptr->variable->type->lineno), 0); 
              sprintf(temp, "%d, &(", ecpg_informix_var++);
          }

*************** adjust_informix(struct arguments *list)
*** 276,305 ****
          result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var),
make_str("),__LINE__);\n")); 

          /* now the indicator if there is one */
!         if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)
          {
              /* change variable name to "ECPG_informix_get_var(<counter>)" */
              original_var = ptr->indicator->name;
              sprintf(temp, "%d))", ecpg_informix_var);

              /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
!             if (atoi(ptr->indicator->type->size) > 1)
              {
!                 ptr->indicator = new_variable(cat_str(4, make_str("("),
mm_strdup(ecpg_type_name(ptr->indicator->type->type)),make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)),
ECPGmake_simple_type(ptr->indicator->type->type,ptr->indicator->type->size, ptr->variable->type->lineno), 0); 
                  sprintf(temp, "%d, (", ecpg_informix_var++);
              }
              else
              {
!                 ptr->indicator = new_variable(cat_str(4, make_str("*("),
mm_strdup(ecpg_type_name(ptr->indicator->type->type)),make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)),
ECPGmake_simple_type(ptr->indicator->type->type,ptr->indicator->type->size, ptr->variable->type->lineno), 0); 
                  sprintf(temp, "%d, &(", ecpg_informix_var++);
              }
              result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var),
make_str("),__LINE__);\n")); 
          }
       }

       return result;
  }

  static struct cursor *
  add_additional_variables(char *name, bool insert)
  {
--- 319,384 ----
          result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var),
make_str("),__LINE__);\n")); 

          /* now the indicator if there is one */
!         if (ptr->indicator->type->type == ECPGt_NO_INDICATOR)
!         {
!             newind = ptr->indicator;
!         }
!         else
          {
              /* change variable name to "ECPG_informix_get_var(<counter>)" */
              original_var = ptr->indicator->name;
              sprintf(temp, "%d))", ecpg_informix_var);

              /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
!             if (ptr->indicator->type->type == ECPGt_struct || ptr->indicator->type->type == ECPGt_union)
              {
!                 sprintf(temp, "%d)))", ecpg_informix_var);
!                 newind = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->indicator->type->type_name),
make_str("*)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->indicator->type->u.members,
ptr->indicator->type->type,ptr->indicator->type->type_name, ptr->indicator->type->struct_sizeof), 0); 
!                 sprintf(temp, "%d, &(", ecpg_informix_var++);
!             }
!             else if (ptr->indicator->type->type == ECPGt_array)
!             {
!                 if (ptr->indicator->type->u.element->type == ECPGt_struct || ptr->indicator->type->u.element->type ==
ECPGt_union)
!                 {
!                     sprintf(temp, "%d)))", ecpg_informix_var);
!                     newind = new_variable(cat_str(4, make_str("(*("),
mm_strdup(ptr->indicator->type->u.element->type_name),make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)),
ECPGmake_struct_type(ptr->indicator->type->u.element->u.members,ptr->indicator->type->u.element->type,
ptr->indicator->type->u.element->type_name,ptr->indicator->type->u.element->struct_sizeof), 0); 
!                     sprintf(temp, "%d, (", ecpg_informix_var++);
!                 }
!                 else
!                 {
!                     newind = new_variable(cat_str(4, make_str("("),
mm_strdup(ecpg_type_name(ptr->indicator->type->u.element->type)),make_str(" *)(ECPG_informix_get_var("),
mm_strdup(temp)),ECPGmake_array_type(ECPGmake_simple_type(ptr->indicator->type->u.element->type,
ptr->indicator->type->u.element->size,ptr->indicator->type->u.element->lineno), ptr->indicator->type->size), 0); 
!                     sprintf(temp, "%d, &(", ecpg_informix_var++);
!                 }
!             }
!             else if (atoi(ptr->indicator->type->size) > 1)
!             {
!                 newind = new_variable(cat_str(4, make_str("("),
mm_strdup(ecpg_type_name(ptr->indicator->type->type)),make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)),
ECPGmake_simple_type(ptr->indicator->type->type,ptr->indicator->type->size, ptr->variable->type->lineno), 0); 
                  sprintf(temp, "%d, (", ecpg_informix_var++);
              }
              else
              {
!                 newind = new_variable(cat_str(4, make_str("*("),
mm_strdup(ecpg_type_name(ptr->indicator->type->type)),make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)),
ECPGmake_simple_type(ptr->indicator->type->type,ptr->indicator->type->size, ptr->variable->type->lineno), 0); 
                  sprintf(temp, "%d, &(", ecpg_informix_var++);
              }
              result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var),
make_str("),__LINE__);\n")); 
          }
+
+         add_variable_to_tail(&newlist, newvar, newind);
       }

+      if (insert)
+         cur->argsinsert_oos = newlist;
+      else
+         cur->argsresult_oos = newlist;
+
       return result;
  }

+ /* This tests whether the cursor was declared and opened in the same function. */
+ #define SAMEFUNC(cur)    \
+     ((cur->function == NULL) ||        \
+      (cur->function != NULL && !strcmp(cur->function, current_function)))
+
  static struct cursor *
  add_additional_variables(char *name, bool insert)
  {
*************** add_additional_variables(char *name, boo
*** 322,333 ****
      {
          /* add all those input variables that were given earlier
           * note that we have to append here but have to keep the existing order */
!         for (p = ptr->argsinsert; p; p = p->next)
              add_variable_to_tail(&argsinsert, p->variable, p->indicator);
      }

      /* add all those output variables that were given earlier */
!     for (p = ptr->argsresult; p; p = p->next)
          add_variable_to_tail(&argsresult, p->variable, p->indicator);

      return ptr;
--- 401,412 ----
      {
          /* add all those input variables that were given earlier
           * note that we have to append here but have to keep the existing order */
!         for (p = (SAMEFUNC(ptr) ? ptr->argsinsert : ptr->argsinsert_oos); p; p = p->next)
              add_variable_to_tail(&argsinsert, p->variable, p->indicator);
      }

      /* add all those output variables that were given earlier */
!     for (p = (SAMEFUNC(ptr) ? ptr->argsresult : ptr->argsresult_oos); p; p = p->next)
          add_variable_to_tail(&argsresult, p->variable, p->indicator);

      return ptr;
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.trailer
pgsql.ooscur/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/ecpg.trailer    2009-08-13 17:48:27.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/ecpg.trailer    2009-08-14 21:19:35.000000000 +0200
*************** statement: ecpgstart at stmt ';'
*** 16,22 ****
                  | c_thing               { fprintf(yyout, "%s", $1); free($1); }
                  | CPP_LINE              { fprintf(yyout, "%s", $1); free($1); }
                  | '{'                   { braces_open++; fputs("{", yyout); }
!                 | '}'                   { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}",
yyout);} 
                  ;

  CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data
--- 16,32 ----
                  | c_thing               { fprintf(yyout, "%s", $1); free($1); }
                  | CPP_LINE              { fprintf(yyout, "%s", $1); free($1); }
                  | '{'                   { braces_open++; fputs("{", yyout); }
!                 | '}'
!         {
!             remove_typedefs(braces_open);
!             remove_variables(braces_open--);
!             if (braces_open == 0)
!             {
!                 free(current_function);
!                 current_function = NULL;
!             }
!             fputs("}", yyout);
!         }
                  ;

  CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data
*************** ECPGCursorStmt:  DECLARE cursor_name cur
*** 336,341 ****
--- 346,352 ----
              /* initial definition */
              this->next = cur;
              this->name = $2;
+             this->function = (current_function ? mm_strdup(current_function) : NULL);
              this->connection = connection;
              this->command =  cat_str(6, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for
$1"));
              this->argsresult = NULL;
*************** var_declaration: storage_declaration
*** 452,457 ****
--- 463,469 ----
          var_type
          {
              actual_type[struct_level].type_enum = $2.type_enum;
+             actual_type[struct_level].type_str = $2.type_str;
              actual_type[struct_level].type_dimension = $2.type_dimension;
              actual_type[struct_level].type_index = $2.type_index;
              actual_type[struct_level].type_sizeof = $2.type_sizeof;
*************** var_declaration: storage_declaration
*** 465,470 ****
--- 477,483 ----
          | var_type
          {
              actual_type[struct_level].type_enum = $1.type_enum;
+             actual_type[struct_level].type_str = $1.type_str;
              actual_type[struct_level].type_dimension = $1.type_dimension;
              actual_type[struct_level].type_index = $1.type_index;
              actual_type[struct_level].type_sizeof = $1.type_sizeof;
*************** variable: opt_pointer ECPGColLabel opt_a
*** 876,884 ****
                  case ECPGt_struct:
                  case ECPGt_union:
                      if (atoi(dimension) < 0)
!                         type = ECPGmake_struct_type(struct_member_list[struct_level],
actual_type[struct_level].type_enum,actual_type[struct_level].type_sizeof); 
                      else
!                         type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level],
actual_type[struct_level].type_enum,actual_type[struct_level].type_sizeof), dimension); 

                      $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
                      break;
--- 889,897 ----
                  case ECPGt_struct:
                  case ECPGt_union:
                      if (atoi(dimension) < 0)
!                         type = ECPGmake_struct_type(struct_member_list[struct_level],
actual_type[struct_level].type_enum,actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof); 
                      else
!                         type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level],
actual_type[struct_level].type_enum,actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof),
dimension);

                      $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
                      break;
*************** ECPGVar: SQL_VAR
*** 1382,1390 ****
                      case ECPGt_struct:
                      case ECPGt_union:
                          if (atoi(dimension) < 0)
!                             type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum,
$5.type_sizeof);
                          else
!                             type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level],
$5.type_enum,$5.type_sizeof),dimension); 
                          break;

                      case ECPGt_varchar:
--- 1395,1403 ----
                      case ECPGt_struct:
                      case ECPGt_union:
                          if (atoi(dimension) < 0)
!                             type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str,
$5.type_sizeof);
                          else
!                             type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level],
$5.type_enum,$5.type_str, $5.type_sizeof), dimension); 
                          break;

                      case ECPGt_varchar:
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/extern.h
pgsql.ooscur/src/interfaces/ecpg/preproc/extern.h
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/extern.h    2009-08-13 17:14:43.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/extern.h    2009-08-13 16:32:38.000000000 +0200
*************** extern int    braces_open,
*** 29,34 ****
--- 29,35 ----
              ecpg_informix_var,
              regression_mode,
              auto_prepare;
+ extern char *current_function;
  extern char *descriptor_index;
  extern char *descriptor_name;
  extern char *connection;
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/pgc.l pgsql.ooscur/src/interfaces/ecpg/preproc/pgc.l
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/pgc.l    2009-08-13 17:14:15.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/pgc.l    2009-08-14 21:23:48.000000000 +0200
*************** static char    *literalbuf = NULL;        /* e
*** 41,46 ****
--- 41,49 ----
  static int        literallen;                /* actual current length */
  static int        literalalloc;            /* current allocated buffer size */

+ /* Used for detecting global state together with braces_open */
+ static int        parenths_open;
+
  #define startlit()    (literalbuf[0] = '\0', literallen = 0)
  static void addlit(char *ytext, int yleng);
  static void addlitchar (unsigned char);
*************** cppline            {space}*#(.*\\{space})*.*{newl
*** 788,794 ****
                      }
  <C>{identifier}     {
                          const ScanKeyword        *keyword;
!
                          /* Informix uses SQL defines only in SQL space */
                          /* however, some defines have to be taken care of for compatibility */
                          if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine())
--- 791,807 ----
                      }
  <C>{identifier}     {
                          const ScanKeyword        *keyword;
!
!                         /*
!                          * Try to detect a function name:
!                          * look for identifiers at the global scope
!                          * keep the last identifier before the first '(' and '{' */
!                         if (braces_open == 0 && parenths_open == 0)
!                         {
!                             if (current_function)
!                                 free(current_function);
!                             current_function = mm_strdup(yytext);
!                         }
                          /* Informix uses SQL defines only in SQL space */
                          /* however, some defines have to be taken care of for compatibility */
                          if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine())
*************** cppline            {space}*#(.*\\{space})*.*{newl
*** 811,818 ****
  <C>"/"                { return('/'); }
  <C>"+"                { return('+'); }
  <C>"-"                { return('-'); }
! <C>"("                { return('('); }
! <C>")"                { return(')'); }
  <C,xskip>{space}        { ECHO; }
  <C>\{                { return('{'); }
  <C>\}                { return('}'); }
--- 824,831 ----
  <C>"/"                { return('/'); }
  <C>"+"                { return('+'); }
  <C>"-"                { return('-'); }
! <C>"("                { parenths_open++; return('('); }
! <C>")"                { parenths_open--; return(')'); }
  <C,xskip>{space}        { ECHO; }
  <C>\{                { return('{'); }
  <C>\}                { return('}'); }
*************** void
*** 1178,1183 ****
--- 1191,1198 ----
  lex_init(void)
  {
      braces_open = 0;
+     parenths_open = 0;
+     current_function = NULL;

      preproc_tos = 0;
      yylineno = 1;
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/type.c
pgsql.ooscur/src/interfaces/ecpg/preproc/type.c
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/type.c    2009-08-11 11:46:04.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/type.c    2009-08-14 20:11:34.000000000 +0200
*************** ECPGstruct_member_dup(struct ECPGstruct_
*** 46,52 ****
          {
              case ECPGt_struct:
              case ECPGt_union:
!                 type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof);
                  break;
              case ECPGt_array:

--- 46,52 ----
          {
              case ECPGt_struct:
              case ECPGt_union:
!                 type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->type_name,
rm->type->struct_sizeof);
                  break;
              case ECPGt_array:

*************** ECPGstruct_member_dup(struct ECPGstruct_
*** 55,61 ****
                   * create the struct too
                   */
                  if (rm->type->u.element->type == ECPGt_struct)
!                     type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type,
rm->type->u.element->struct_sizeof);
                  else
                      type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type,
rm->type->u.element->size,rm->type->u.element->lineno), rm->type->size); 
                  break;
--- 55,61 ----
                   * create the struct too
                   */
                  if (rm->type->u.element->type == ECPGt_struct)
!                     type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type,
rm->type->u.element->type_name,rm->type->u.element->struct_sizeof); 
                  else
                      type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type,
rm->type->u.element->size,rm->type->u.element->lineno), rm->type->size); 
                  break;
*************** ECPGmake_simple_type(enum ECPGttype type
*** 98,103 ****
--- 98,104 ----
      struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));

      ne->type = type;
+     ne->type_name = NULL;
      ne->size = size;
      ne->u.element = NULL;
      ne->struct_sizeof = NULL;
*************** ECPGmake_array_type(struct ECPGtype * ty
*** 117,126 ****
  }

  struct ECPGtype *
! ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *struct_sizeof)
  {
      struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"), 0);

      ne->u.members = ECPGstruct_member_dup(rm);
      ne->struct_sizeof = struct_sizeof;

--- 118,128 ----
  }

  struct ECPGtype *
! ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *type_name, char *struct_sizeof)
  {
      struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"), 0);

+     ne->type_name = mm_strdup(type_name);
      ne->u.members = ECPGstruct_member_dup(rm);
      ne->struct_sizeof = struct_sizeof;

diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/type.h
pgsql.ooscur/src/interfaces/ecpg/preproc/type.h
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/type.h    2009-06-13 18:25:05.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/type.h    2009-08-14 20:11:34.000000000 +0200
*************** struct ECPGstruct_member
*** 17,22 ****
--- 17,23 ----
  struct ECPGtype
  {
      enum ECPGttype type;
+     char       *type_name;            /* For struct and union types it is the struct name */
      char       *size;            /* For array it is the number of elements. For
                                   * varchar it is the maxsize of the area. */
      char       *struct_sizeof;    /* For a struct this is the sizeof() type as
*************** void        ECPGmake_struct_member(char *, str
*** 36,42 ****
  struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, char *, int);
  struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
  struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, char *);
! struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *);
  struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *);

  /* Frees a type. */
--- 37,43 ----
  struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, char *, int);
  struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long);
  struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, char *);
! struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *, char *);
  struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *);

  /* Frees a type. */
*************** struct _include_path
*** 123,133 ****
--- 124,137 ----
  struct cursor
  {
      char       *name;
+     char       *function;
      char       *command;
      char       *connection;
      bool        opened;
      struct arguments *argsinsert;
+     struct arguments *argsinsert_oos;
      struct arguments *argsresult;
+     struct arguments *argsresult_oos;
      struct cursor *next;
  };

diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/variable.c
pgsql.ooscur/src/interfaces/ecpg/preproc/variable.c
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/preproc/variable.c    2009-08-09 15:42:06.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/preproc/variable.c    2009-08-14 10:16:01.000000000 +0200
*************** find_struct_member(char *name, char *str
*** 47,53 ****
                          return (new_variable(name,
ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type,members->type->u.element->size,
members->type->u.element->lineno),members->type->size), brace_level)); 
                      case ECPGt_struct:
                      case ECPGt_union:
!                         return (new_variable(name, ECPGmake_struct_type(members->type->u.members,
members->type->type,members->type->struct_sizeof), brace_level)); 
                      default:
                          return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size,
members->type->lineno),brace_level)); 
                  }
--- 47,53 ----
                          return (new_variable(name,
ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type,members->type->u.element->size,
members->type->u.element->lineno),members->type->size), brace_level)); 
                      case ECPGt_struct:
                      case ECPGt_union:
!                         return (new_variable(name, ECPGmake_struct_type(members->type->u.members,
members->type->type,members->type->type_name, members->type->struct_sizeof), brace_level)); 
                      default:
                          return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size,
members->type->lineno),brace_level)); 
                  }
*************** find_struct_member(char *name, char *str
*** 94,100 ****
                                  return (new_variable(name,
ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type,
members->type->u.element->u.element->size,members->type->u.element->u.element->lineno),
members->type->u.element->size),brace_level)); 
                              case ECPGt_struct:
                              case ECPGt_union:
!                                 return (new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members,
members->type->u.element->type,members->type->u.element->struct_sizeof), brace_level)); 
                              default:
                                  return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type,
members->type->u.element->size,members->type->u.element->lineno), brace_level)); 
                          }
--- 94,100 ----
                                  return (new_variable(name,
ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type,
members->type->u.element->u.element->size,members->type->u.element->u.element->lineno),
members->type->u.element->size),brace_level)); 
                              case ECPGt_struct:
                              case ECPGt_union:
!                                 return (new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members,
members->type->u.element->type,members->type->u.element->type_name, members->type->u.element->struct_sizeof),
brace_level));
                              default:
                                  return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type,
members->type->u.element->size,members->type->u.element->lineno), brace_level)); 
                          }
*************** find_variable(char *name)
*** 235,241 ****
                          return (new_variable(name,
ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type,p->type->u.element->u.element->size,
p->type->u.element->u.element->lineno),p->type->u.element->size), p->brace_level)); 
                      case ECPGt_struct:
                      case ECPGt_union:
!                         return (new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members,
p->type->u.element->type,p->type->u.element->struct_sizeof), p->brace_level)); 
                      default:
                          return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type,
p->type->u.element->size,p->type->u.element->lineno), p->brace_level)); 
                  }
--- 235,241 ----
                          return (new_variable(name,
ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type,p->type->u.element->u.element->size,
p->type->u.element->u.element->lineno),p->type->u.element->size), p->brace_level)); 
                      case ECPGt_struct:
                      case ECPGt_union:
!                         return (new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members,
p->type->u.element->type,p->type->u.element->type_name, p->type->u.element->struct_sizeof), p->brace_level)); 
                      default:
                          return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type,
p->type->u.element->size,p->type->u.element->lineno), p->brace_level)); 
                  }
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/Makefile
pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/Makefile
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/Makefile    2009-08-11 16:56:15.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/Makefile    2009-08-14 20:59:01.000000000 +0200
*************** TESTS = test_informix test_informix.c \
*** 14,19 ****
--- 14,21 ----
          test_informix2 test_informix2.c \
          cursor cursor.c \
          describe describe.c \
+         struct struct.c \
+         outofscope outofscope.c \
          dec_test dec_test.c \
          rfmtdate rfmtdate.c \
          rfmtlong rfmtlong.c \
*************** describe.c: describe.pgc ../regression.h
*** 38,43 ****
--- 40,51 ----
  sqlda.c: sqlda.pgc ../regression.h
      $(ECPG) -o $@ -I$(srcdir) $<

+ struct.c: struct.pgc ../regression.h
+     $(ECPG) -o $@ -I$(srcdir) $<
+
+ outofscope.c: outofscope.pgc ../regression.h
+     $(ECPG) -o $@ -I$(srcdir) $<
+
  dec_test.c: dec_test.pgc ../regression.h
      $(ECPG) -o $@ -I$(srcdir) $<

diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/outofscope.pgc
pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/outofscope.pgc
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/outofscope.pgc    1970-01-01 01:00:00.000000000
+0100
--- pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/outofscope.pgc    2009-08-14 21:32:41.000000000 +0200
***************
*** 0 ****
--- 1,122 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+ exec sql include ../regression;
+
+ exec sql begin declare section;
+ exec sql include struct.h;
+ exec sql end declare section;
+
+ exec sql whenever sqlerror stop;
+
+ static void
+ get_var(MYTYPE **myvar0, MYNULLTYPE **mynullvar0)
+ {
+     exec sql begin declare section;
+     MYTYPE        *myvar = malloc(sizeof(MYTYPE));
+     MYNULLTYPE    *mynullvar = malloc(sizeof(MYNULLTYPE));
+     exec sql end declare section;
+
+     /* Test DECLARE ... SELECT ... INTO with pointers */
+
+     exec sql declare mycur cursor for select * INTO :myvar :mynullvar from a1;
+
+     if (sqlca.sqlcode != 0)
+         exit(1);
+
+     *myvar0 = myvar;
+     *mynullvar0 = mynullvar;
+ }
+
+ static void
+ open_cur(void)
+ {
+     exec sql open mycur;
+
+     if (sqlca.sqlcode != 0)
+         exit(1);
+ }
+
+ static void
+ get_record(void)
+ {
+     exec sql fetch mycur;
+
+     if (sqlca.sqlcode != 0 && sqlca.sqlcode != SQLNOTFOUND)
+         exit(1);
+ }
+
+ static void
+ close_cur(void)
+ {
+     exec sql close mycur;
+
+     if (sqlca.sqlcode != 0)
+         exit(1);
+ }
+
+ int
+ main (void)
+ {
+     MYTYPE        *myvar;
+     MYNULLTYPE    *mynullvar;
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     exec sql connect to REGRESSDB1;
+
+     strcpy(msg, "set");
+     exec sql set datestyle to iso;
+
+     strcpy(msg, "create");
+     exec sql create table a1(id serial primary key, t text, d1 numeric, d2 float8, c character(10));
+
+     strcpy(msg, "insert");
+     exec sql insert into a1(id, t, d1, d2, c) values (default, 'a', 1.0, 2, 'a');
+     exec sql insert into a1(id, t, d1, d2, c) values (default, null, null, null, null);
+     exec sql insert into a1(id, t, d1, d2, c) values (default, '"a"', -1.0, 'nan'::float8, 'a');
+     exec sql insert into a1(id, t, d1, d2, c) values (default, 'b', 2.0, 3, 'b');
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     /* Test out-of-scope DECLARE/OPEN/FETCH/CLOSE */
+
+     get_var(&myvar, &mynullvar);
+     open_cur();
+
+     exec sql whenever not found do break;
+
+     while (1)
+     {
+         memset(myvar, 0, sizeof(MYTYPE));
+         get_record();
+         if (sqlca.sqlcode == SQLNOTFOUND)
+             break;
+         printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n",
+             myvar->id, mynullvar->id ? " (NULL)" : "",
+             myvar->t, mynullvar->t ? " (NULL)" : "",
+             myvar->d1, mynullvar->d1 ? " (NULL)" : "",
+             myvar->d2, mynullvar->d2 ? " (NULL)" : "",
+             myvar->c, mynullvar->c ? " (NULL)" : "");
+     }
+
+     close_cur();
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     exec sql drop table a1;
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     strcpy(msg, "disconnect");
+     exec sql disconnect;
+
+     return (0);
+ }
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/struct.h
pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/struct.h
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/struct.h    1970-01-01 01:00:00.000000000 +0100
--- pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/struct.h    2009-08-14 20:34:35.000000000 +0200
***************
*** 0 ****
--- 1,18 ----
+
+ struct mytype {
+     int    id;
+     char    t[64];
+     double    d1; /* dec_t */
+     double    d2;
+     char    c[30];
+ };
+ typedef struct mytype MYTYPE;
+
+ struct mynulltype {
+     int    id;
+     int    t;
+     int    d1;
+     int    d2;
+     int    c;
+ };
+ typedef struct mynulltype MYNULLTYPE;
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/struct.pgc
pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/struct.pgc
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/compat_informix/struct.pgc    1970-01-01 01:00:00.000000000
+0100
--- pgsql.ooscur/src/interfaces/ecpg/test/compat_informix/struct.pgc    2009-08-14 21:26:31.000000000 +0200
***************
*** 0 ****
--- 1,76 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+ exec sql include ../regression;
+
+ exec sql begin declare section;
+ exec sql include struct.h;
+ exec sql end declare section;
+
+ exec sql whenever sqlerror stop;
+
+ int
+ main (void)
+ {
+     exec sql begin declare section;
+     MYTYPE        myvar;
+     MYNULLTYPE    mynullvar;
+     exec sql end declare section;
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     exec sql connect to REGRESSDB1;
+
+     strcpy(msg, "set");
+     exec sql set datestyle to iso;
+
+     strcpy(msg, "create");
+     exec sql create table a1(id serial primary key, t text, d1 numeric, d2 float8, c character(10));
+
+     strcpy(msg, "insert");
+     exec sql insert into a1(id, t, d1, d2, c) values (default, 'a', 1.0, 2, 'a');
+     exec sql insert into a1(id, t, d1, d2, c) values (default, null, null, null, null);
+     exec sql insert into a1(id, t, d1, d2, c) values (default, '"a"', -1.0, 'nan'::float8, 'a');
+     exec sql insert into a1(id, t, d1, d2, c) values (default, 'b', 2.0, 3, 'b');
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     /* Test DECLARE ... SELECT ... INTO with struct type */
+
+     exec sql declare mycur cursor for select * into :myvar :mynullvar from a1;
+     exec sql open mycur;
+
+     exec sql whenever not found do break;
+
+     while (1)
+     {
+         memset(&myvar, 0, sizeof(myvar));
+         exec sql fetch mycur;
+         printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n",
+             myvar.id, mynullvar.id ? " (NULL)" : "",
+             myvar.t, mynullvar.t ? " (NULL)" : "",
+             myvar.d1, mynullvar.d1 ? " (NULL)" : "",
+             myvar.d2, mynullvar.d2 ? " (NULL)" : "",
+             myvar.c, mynullvar.c ? " (NULL)" : "");
+     }
+
+     exec sql close mycur;
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     exec sql drop table a1;
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     strcpy(msg, "disconnect");
+     exec sql disconnect;
+
+     return (0);
+ }
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/ecpg_schedule
pgsql.ooscur/src/interfaces/ecpg/test/ecpg_schedule
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/ecpg_schedule    2009-08-11 17:00:27.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/test/ecpg_schedule    2009-08-14 20:59:24.000000000 +0200
*************** test: compat_informix/rnull
*** 6,11 ****
--- 6,13 ----
  test: compat_informix/cursor
  test: compat_informix/sqlda
  test: compat_informix/describe
+ test: compat_informix/struct
+ test: compat_informix/outofscope
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/ecpg_schedule_tcp
pgsql.ooscur/src/interfaces/ecpg/test/ecpg_schedule_tcp
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/ecpg_schedule_tcp    2009-08-11 17:00:33.000000000 +0200
--- pgsql.ooscur/src/interfaces/ecpg/test/ecpg_schedule_tcp    2009-08-14 20:59:24.000000000 +0200
*************** test: compat_informix/rnull
*** 6,11 ****
--- 6,13 ----
  test: compat_informix/cursor
  test: compat_informix/sqlda
  test: compat_informix/describe
+ test: compat_informix/struct
+ test: compat_informix/outofscope
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-cursor.c
pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-cursor.c
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-cursor.c    2009-08-13
17:00:25.000000000+0200 
--- pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-cursor.c    2009-08-14 21:30:57.000000000 +0200
*************** if (sqlca.sqlcode < 0) exit (1);}
*** 162,168 ****

      strcpy(msg, "open");
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare $0 cursor for select id , t from t1",
!     ECPGt_char,&(*( char  *)(ECPG_informix_get_var( 0))),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
  #line 62 "cursor.pgc"

--- 162,168 ----

      strcpy(msg, "open");
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare $0 cursor for select id , t from t1",
!     ECPGt_char,&(curname1),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
  #line 62 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 298,308 ****

      strcpy(msg, "open");
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare $0 cursor for select id , t from t1",
!     ECPGt_char,&(*( char  *)(ECPG_informix_get_var( 3))),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 103 "cursor.pgc"

--- 298,308 ----

      strcpy(msg, "open");
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare $0 cursor for select id , t from t1",
!     ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 103 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 314,322 ****
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 106 "cursor.pgc"

--- 314,322 ----
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 106 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 329,337 ****
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 110 "cursor.pgc"

--- 329,337 ----
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 110 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 344,352 ****
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 114 "cursor.pgc"

--- 344,352 ----
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 114 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 362,370 ****
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 119 "cursor.pgc"

--- 362,370 ----
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 119 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 377,385 ****
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "move absolute 0 $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 123 "cursor.pgc"

--- 377,385 ----
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "move absolute 0 $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 123 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 391,399 ****
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 126 "cursor.pgc"

--- 391,399 ----
      { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 $0",
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 126 "cursor.pgc"

*************** if (sqlca.sqlcode < 0) exit (1);}
*** 409,417 ****
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(*( int  *)(ECPG_informix_get_var( 2))),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(( char  *)(ECPG_informix_get_var( 1))),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 131 "cursor.pgc"

--- 409,417 ----
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
!     ECPGt_int,&(id),(long)1,(long)1,sizeof(int),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(t),(long)64,(long)1,(64)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
  #line 131 "cursor.pgc"

diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-outofscope.c
pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-outofscope.c
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-outofscope.c    1970-01-01
01:00:00.000000000+0100 
--- pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-outofscope.c    2009-08-14 21:33:31.000000000 +0200
***************
*** 0 ****
--- 1,308 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* Needed for informix compatibility */
+ #include <ecpg_informix.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+ #line 1 "outofscope.pgc"
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+
+ #line 1 "regression.h"
+
+
+
+
+
+
+ #line 5 "outofscope.pgc"
+
+
+ /* exec sql begin declare section */
+
+ #line 1 "struct.h"
+
+
+
+
+          /* dec_t */
+
+
+
+    typedef struct mytype  MYTYPE ;
+
+ #line 9 "struct.h"
+
+
+
+
+
+
+
+
+
+    typedef struct mynulltype  MYNULLTYPE ;
+
+ #line 18 "struct.h"
+
+
+ #line 8 "outofscope.pgc"
+
+ struct mytype {
+ #line 3 "struct.h"
+  int id ;
+
+ #line 4 "struct.h"
+  char t [ 64 ] ;
+
+ #line 5 "struct.h"
+  double d1 ;
+
+ #line 6 "struct.h"
+  double d2 ;
+
+ #line 7 "struct.h"
+  char c [ 30 ] ;
+  } ; struct mynulltype {
+ #line 12 "struct.h"
+  int id ;
+
+ #line 13 "struct.h"
+  int t ;
+
+ #line 14 "struct.h"
+  int d1 ;
+
+ #line 15 "struct.h"
+  int d2 ;
+
+ #line 16 "struct.h"
+  int c ;
+  } ;/* exec sql end declare section */
+ #line 9 "outofscope.pgc"
+
+
+ /* exec sql whenever sqlerror  stop ; */
+ #line 11 "outofscope.pgc"
+
+
+ static void
+ get_var(MYTYPE **myvar0, MYNULLTYPE **mynullvar0)
+ {
+     /* exec sql begin declare section */
+
+
+
+ #line 17 "outofscope.pgc"
+  MYTYPE * myvar = malloc ( sizeof ( MYTYPE ) ) ;
+
+ #line 18 "outofscope.pgc"
+  MYNULLTYPE * mynullvar = malloc ( sizeof ( MYNULLTYPE ) ) ;
+ /* exec sql end declare section */
+ #line 19 "outofscope.pgc"
+
+
+     /* Test DECLARE ... SELECT ... INTO with pointers */
+
+     ECPG_informix_set_var( 0, ( myvar ), __LINE__);\
+  ECPG_informix_set_var( 1, ( mynullvar ), __LINE__);\
+  ECPGreset_sqlca(__LINE__, NULL); /* declare mycur cursor for select * from a1 */
+ #line 23 "outofscope.pgc"
+
+
+     if (sqlca.sqlcode != 0)
+         exit(1);
+
+     *myvar0 = myvar;
+     *mynullvar0 = mynullvar;
+ }
+
+ static void
+ open_cur(void)
+ {
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT,
+     ECPGt_int,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).id),(long)1,(long)1,sizeof(int),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).id),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).t),(long)64,(long)1,(64)*sizeof(char),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).t),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).d1),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).d1),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).d2),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).d2),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).c),(long)30,(long)1,(30)*sizeof(char),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).c),(long)1,(long)1,sizeof(int), ECPGt_EORT);
+ #line 35 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 35 "outofscope.pgc"
+
+
+     if (sqlca.sqlcode != 0)
+         exit(1);
+ }
+
+ static void
+ get_record(void)
+ {
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT,
+     ECPGt_int,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).id),(long)1,(long)1,sizeof(int),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).id),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).t),(long)64,(long)1,(64)*sizeof(char),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).t),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).d1),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).d1),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).d2),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).d2),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&((*( MYTYPE  *)(ECPG_informix_get_var( 0))).c),(long)30,(long)1,(30)*sizeof(char),
+     ECPGt_int,&((*( MYNULLTYPE  *)(ECPG_informix_get_var( 1))).c),(long)1,(long)1,sizeof(int), ECPGt_EORT);
+ #line 44 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 44 "outofscope.pgc"
+
+
+     if (sqlca.sqlcode != 0 && sqlca.sqlcode != SQLNOTFOUND)
+         exit(1);
+ }
+
+ static void
+ close_cur(void)
+ {
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT);
+ #line 53 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 53 "outofscope.pgc"
+
+
+     if (sqlca.sqlcode != 0)
+         exit(1);
+ }
+
+ int
+ main (void)
+ {
+     MYTYPE        *myvar;
+     MYNULLTYPE    *mynullvar;
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     { ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , NULL, 0);
+ #line 70 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 70 "outofscope.pgc"
+
+
+     strcpy(msg, "set");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 73 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 73 "outofscope.pgc"
+
+
+     strcpy(msg, "create");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "create table a1 ( id serial primary key , t text , d1 numeric ,
d2float8 , c character ( 10 ) )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 76 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 76 "outofscope.pgc"
+
+
+     strcpy(msg, "insert");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a'
,1.0 , 2 , 'a' )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 79 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 79 "outofscope.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , null
,null , null , null )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 80 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 80 "outofscope.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default ,
'\"a\"', - 1.0 , 'nan' :: float8 , 'a' )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 81 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 81 "outofscope.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b'
,2.0 , 3 , 'b' )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 82 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 82 "outofscope.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 85 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 85 "outofscope.pgc"
+
+
+     /* Test out-of-scope DECLARE/OPEN/FETCH/CLOSE */
+
+     get_var(&myvar, &mynullvar);
+     open_cur();
+
+     /* exec sql whenever not found  break ; */
+ #line 92 "outofscope.pgc"
+
+
+     while (1)
+     {
+         memset(myvar, 0, sizeof(MYTYPE));
+         get_record();
+         if (sqlca.sqlcode == SQLNOTFOUND)
+             break;
+         printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n",
+             myvar->id, mynullvar->id ? " (NULL)" : "",
+             myvar->t, mynullvar->t ? " (NULL)" : "",
+             myvar->d1, mynullvar->d1 ? " (NULL)" : "",
+             myvar->d2, mynullvar->d2 ? " (NULL)" : "",
+             myvar->c, mynullvar->c ? " (NULL)" : "");
+     }
+
+     close_cur();
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table a1", ECPGt_EOIT, ECPGt_EORT);
+ #line 113 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 113 "outofscope.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 116 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 116 "outofscope.pgc"
+
+
+     strcpy(msg, "disconnect");
+     { ECPGdisconnect(__LINE__, "CURRENT");
+ #line 119 "outofscope.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 119 "outofscope.pgc"
+
+
+     return (0);
+ }
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stderr
pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stderr
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stderr    1970-01-01
01:00:00.000000000+0100 
--- pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stderr    2009-08-14 21:33:31.000000000
+0200
***************
*** 0 ****
--- 1,136 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 73: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 73: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 73: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 76: query: create table a1 ( id serial primary key , t text , d1 numeric , d2 float8 ,
ccharacter ( 10 ) ); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 76: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 76: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 79: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a' , 1.0 , 2 ,
'a'); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 79: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 79: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 80: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , null , null ,
null, null ); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 80: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 80: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 81: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , '"a"' , - 1.0 ,
'nan':: float8 , 'a' ); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 81: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 81: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 82: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b' , 2.0 , 3 ,
'b'); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 82: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 82: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 85: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: query: declare mycur cursor for select * from a1; with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: a offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: a          offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: "a" offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: -1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: a          offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: b offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 2.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 44: RESULT: b          offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 44: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 44: no data found on line 44
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 53: query: close mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 113: query: drop table a1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 113: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 113: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 116: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stdout
pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stdout
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stdout    1970-01-01
01:00:00.000000000+0100 
--- pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-outofscope.stdout    2009-08-14 21:33:31.000000000
+0200
***************
*** 0 ****
--- 1,4 ----
+ id=1 t='a' d1=1.000000 d2=2.000000 c = 'a         '
+ id=2 t='' (NULL) d1=0.000000 (NULL) d2=0.000000 (NULL) c = '' (NULL)
+ id=3 t='"a"' d1=-1.000000 d2=nan c = 'a         '
+ id=4 t='b' d1=2.000000 d2=3.000000 c = 'b         '
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-struct.c
pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-struct.c
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-struct.c    1970-01-01
01:00:00.000000000+0100 
--- pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-struct.c    2009-08-14 21:28:18.000000000 +0200
***************
*** 0 ****
--- 1,265 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* Needed for informix compatibility */
+ #include <ecpg_informix.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+ #line 1 "struct.pgc"
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+
+ #line 1 "regression.h"
+
+
+
+
+
+
+ #line 5 "struct.pgc"
+
+
+ /* exec sql begin declare section */
+
+ #line 1 "struct.h"
+
+
+
+
+          /* dec_t */
+
+
+
+    typedef struct mytype  MYTYPE ;
+
+ #line 9 "struct.h"
+
+
+
+
+
+
+
+
+
+    typedef struct mynulltype  MYNULLTYPE ;
+
+ #line 18 "struct.h"
+
+
+ #line 8 "struct.pgc"
+
+ struct mytype {
+ #line 3 "struct.h"
+  int id ;
+
+ #line 4 "struct.h"
+  char t [ 64 ] ;
+
+ #line 5 "struct.h"
+  double d1 ;
+
+ #line 6 "struct.h"
+  double d2 ;
+
+ #line 7 "struct.h"
+  char c [ 30 ] ;
+  } ; struct mynulltype {
+ #line 12 "struct.h"
+  int id ;
+
+ #line 13 "struct.h"
+  int t ;
+
+ #line 14 "struct.h"
+  int d1 ;
+
+ #line 15 "struct.h"
+  int d2 ;
+
+ #line 16 "struct.h"
+  int c ;
+  } ;/* exec sql end declare section */
+ #line 9 "struct.pgc"
+
+
+ /* exec sql whenever sqlerror  stop ; */
+ #line 11 "struct.pgc"
+
+
+ int
+ main (void)
+ {
+     /* exec sql begin declare section */
+
+
+
+ #line 17 "struct.pgc"
+  MYTYPE myvar ;
+
+ #line 18 "struct.pgc"
+  MYNULLTYPE mynullvar ;
+ /* exec sql end declare section */
+ #line 19 "struct.pgc"
+
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     { ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , NULL, 0);
+ #line 26 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 26 "struct.pgc"
+
+
+     strcpy(msg, "set");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 29 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 29 "struct.pgc"
+
+
+     strcpy(msg, "create");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "create table a1 ( id serial primary key , t text , d1 numeric ,
d2float8 , c character ( 10 ) )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 32 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 32 "struct.pgc"
+
+
+     strcpy(msg, "insert");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a'
,1.0 , 2 , 'a' )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 35 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 35 "struct.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , null
,null , null , null )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 36 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 36 "struct.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default ,
'\"a\"', - 1.0 , 'nan' :: float8 , 'a' )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 37 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 37 "struct.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b'
,2.0 , 3 , 'b' )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 38 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 38 "struct.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 41 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 41 "struct.pgc"
+
+
+     /* Test DECLARE ... SELECT ... INTO with struct type */
+
+     ECPG_informix_set_var( 0, &( myvar ), __LINE__);\
+  ECPG_informix_set_var( 1, &( mynullvar ), __LINE__);\
+  ECPGreset_sqlca(__LINE__, NULL); /* declare mycur cursor for select * from a1 */
+ #line 45 "struct.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT,
+     ECPGt_int,&(myvar.id),(long)1,(long)1,sizeof(int),
+     ECPGt_int,&(mynullvar.id),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&(myvar.t),(long)64,(long)1,(64)*sizeof(char),
+     ECPGt_int,&(mynullvar.t),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&(myvar.d1),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&(mynullvar.d1),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&(myvar.d2),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&(mynullvar.d2),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&(myvar.c),(long)30,(long)1,(30)*sizeof(char),
+     ECPGt_int,&(mynullvar.c),(long)1,(long)1,sizeof(int), ECPGt_EORT);
+ #line 46 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 46 "struct.pgc"
+
+
+     /* exec sql whenever not found  break ; */
+ #line 48 "struct.pgc"
+
+
+     while (1)
+     {
+         memset(&myvar, 0, sizeof(myvar));
+         { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT,
+     ECPGt_int,&(myvar.id),(long)1,(long)1,sizeof(int),
+     ECPGt_int,&(mynullvar.id),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&(myvar.t),(long)64,(long)1,(64)*sizeof(char),
+     ECPGt_int,&(mynullvar.t),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&(myvar.d1),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&(mynullvar.d1),(long)1,(long)1,sizeof(int),
+     ECPGt_double,&(myvar.d2),(long)1,(long)1,sizeof(double),
+     ECPGt_int,&(mynullvar.d2),(long)1,(long)1,sizeof(int),
+     ECPGt_char,&(myvar.c),(long)30,(long)1,(30)*sizeof(char),
+     ECPGt_int,&(mynullvar.c),(long)1,(long)1,sizeof(int), ECPGt_EORT);
+ #line 53 "struct.pgc"
+
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 53 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 53 "struct.pgc"
+
+         printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n",
+             myvar.id, mynullvar.id ? " (NULL)" : "",
+             myvar.t, mynullvar.t ? " (NULL)" : "",
+             myvar.d1, mynullvar.d1 ? " (NULL)" : "",
+             myvar.d2, mynullvar.d2 ? " (NULL)" : "",
+             myvar.c, mynullvar.c ? " (NULL)" : "");
+     }
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT);
+ #line 62 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 62 "struct.pgc"
+
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table a1", ECPGt_EOIT, ECPGt_EORT);
+ #line 67 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 67 "struct.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 70 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 70 "struct.pgc"
+
+
+     strcpy(msg, "disconnect");
+     { ECPGdisconnect(__LINE__, "CURRENT");
+ #line 73 "struct.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 73 "struct.pgc"
+
+
+     return (0);
+ }
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-struct.stderr
pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-struct.stderr
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-struct.stderr    1970-01-01
01:00:00.000000000+0100 
--- pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-struct.stderr    2009-08-14 21:28:19.000000000 +0200
***************
*** 0 ****
--- 1,136 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 29: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 29: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 29: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 32: query: create table a1 ( id serial primary key , t text , d1 numeric , d2 float8 ,
ccharacter ( 10 ) ); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 32: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 32: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a' , 1.0 , 2 ,
'a'); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , null , null ,
null, null ); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , '"a"' , - 1.0 ,
'nan':: float8 , 'a' ); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b' , 2.0 , 3 ,
'b'); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 41: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 46: query: declare mycur cursor for select * from a1; with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 46: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 46: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: a offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: a          offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT:  offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: "a" offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: -1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: a          offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: b offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 2.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 53: RESULT: b          offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 53: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 53: no data found on line 53
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 62: query: close mycur; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 62: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 62: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 67: query: drop table a1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 67: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 67: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 70: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-struct.stdout
pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-struct.stdout
*** pgsql.declare-reset-sqlca/src/interfaces/ecpg/test/expected/compat_informix-struct.stdout    1970-01-01
01:00:00.000000000+0100 
--- pgsql.ooscur/src/interfaces/ecpg/test/expected/compat_informix-struct.stdout    2009-08-14 21:28:20.000000000 +0200
***************
*** 0 ****
--- 1,4 ----
+ id=1 t='a' d1=1.000000 d2=2.000000 c = 'a         '
+ id=2 t='' (NULL) d1=0.000000 (NULL) d2=0.000000 (NULL) c = '' (NULL)
+ id=3 t='"a"' d1=-1.000000 d2=nan c = 'a         '
+ id=4 t='b' d1=2.000000 d2=3.000000 c = 'b         '

pgsql-hackers by date:

Previous
From: Michael Meskes
Date:
Subject: Re: Split-up ECPG patches
Next
From: Boszormenyi Zoltan
Date:
Subject: Re: Split-up ECPG patches