ECPG support for string pseudo-type

Поиск
Список
Период
Сортировка
От Boszormenyi Zoltan
Тема ECPG support for string pseudo-type
Дата
Msg-id 4A4F5B82.2070403@cybertec.at
обсуждение исходный текст
Ответы Re: ECPG support for string pseudo-type  (Tom Lane <tgl@sss.pgh.pa.us>)
Re: ECPG support for string pseudo-type  (Michael Meskes <meskes@postgresql.org>)
Список pgsql-hackers
Hi,

in a continued effort for better Informix ESQL/C compatibility,
we added the "string" pseudo-type handling to ECPG.
This type in ESQL/C is documented as:

--------------------------------------------------
The string Data Type

The string data type is an ESQL/C data type that holds character data
that is
null terminated and does not contain trailing blanks. When an application
reads a value from a CHAR column into a host variable of data type
string, it
strips the value of any trailing blanks and appends a null terminator. The
behavior is the same if an application reads a value from a VARCHAR column
into a host variable of data type string.
Declare the string data type with a length of [n+1] (where n is the size
of the
column with values that you want read) to allow for the null terminator. Use
the following syntax to declare a host variable of the string data type:
     EXEC SQL BEGIN DECLARE SECTION;
          string str_name[n + 1];
     EXEC SQL END DECLARE SECTION;
--------------------------------------------------

So, we added it accordingly. This means the following:
- "string" has become a type name, reserved word in ECPG.
- When ECPG encounters "string", it will be transparently replaced by
   "char" in the generated C source, but ECPGt_string will be passed
   to ECPGdo()
- ecpg_get_data() right-trims the string value if ECPGt_string was passed.

Two regression tests had to be modified because "string" is now
a type name: preproc/define.pgc and preproc/type.pgc.

The attached patch is built upon our previous patch supporting
dynamic cursor and SQLDA.

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 postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/data.c
postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/data.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/data.c    2009-01-15 12:52:55.000000000 +0100
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/data.c    2009-07-04 12:27:57.000000000 +0200
*************** ecpg_get_data(const PGresult *results, i
*** 138,143 ****
--- 138,144 ----
              case ECPGt_char:
              case ECPGt_unsigned_char:
              case ECPGt_varchar:
+             case ECPGt_string:
                  break;

              default:
*************** ecpg_get_data(const PGresult *results, i
*** 389,394 ****
--- 390,396 ----

                  case ECPGt_char:
                  case ECPGt_unsigned_char:
+                 case ECPGt_string:
                      if (pval)
                      {
                          if (varcharsize == 0 || varcharsize > size)
*************** ecpg_get_data(const PGresult *results, i
*** 426,431 ****
--- 428,454 ----
                                  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
                              }
                          }
+                         /* Do the rtrim() */
+                         if (type == ECPGt_string)
+                         {
+                             char    *str = (char *) ((long) var + offset * act_tuple);
+                             char    *last;
+                             int    len = strlen(str);
+
+                             last = str + len;
+                             while (last > str)
+                             {
+                                 if (*last == '\0')
+                                     last--;
+                                 else if (*last == ' ')
+                                 {
+                                     *last = '\0';
+                                     last--;
+                                 }
+                                 else
+                                     break;
+                             }
+                         }
                          pval += size;
                      }
                      break;
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/descriptor.c
postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/descriptor.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/descriptor.c    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/descriptor.c    2009-07-04 12:12:02.000000000 +0200
*************** get_char_item(int lineno, void *var, enu
*** 201,206 ****
--- 201,207 ----
      {
          case ECPGt_char:
          case ECPGt_unsigned_char:
+         case ECPGt_string:
              strncpy((char *) var, value, varcharsize);
              break;
          case ECPGt_varchar:
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/execute.c
postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/execute.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/execute.c    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/execute.c    2009-07-04 12:12:02.000000000 +0200
*************** ecpg_store_result(const PGresult *result
*** 360,365 ****
--- 360,366 ----
              {
                  case ECPGt_char:
                  case ECPGt_unsigned_char:
+                 case ECPGt_string:
                      if (!var->varcharsize && !var->arrsize)
                      {
                          /* special mode for handling char**foo=0 */
*************** ecpg_store_result(const PGresult *result
*** 419,425 ****

      /* fill the variable with the tuple(s) */
      if (!var->varcharsize && !var->arrsize &&
!         (var->type == ECPGt_char || var->type == ECPGt_unsigned_char))
      {
          /* special mode for handling char**foo=0 */

--- 420,426 ----

      /* fill the variable with the tuple(s) */
      if (!var->varcharsize && !var->arrsize &&
!         (var->type == ECPGt_char || var->type == ECPGt_unsigned_char || var->type == ECPGt_string))
      {
          /* special mode for handling char**foo=0 */

*************** ecpg_store_input(const int lineno, const
*** 758,763 ****
--- 759,765 ----

              case ECPGt_char:
              case ECPGt_unsigned_char:
+             case ECPGt_string:
                  {
                      /* set slen to string length if type is char * */
                      int            slen = (var->varcharsize == 0) ? strlen((char *) var->value) : (unsigned int)
var->varcharsize;
*************** ecpg_execute(struct statement * stmt)
*** 1196,1201 ****
--- 1198,1204 ----
                      {
                          case ECPGt_char:
                          case ECPGt_varchar:
+                         case ECPGt_string:
                              desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
                              break;
                          default:
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/misc.c
postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/misc.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/misc.c    2009-06-11 16:49:13.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/misc.c    2009-07-04 12:12:02.000000000 +0200
*************** ECPGset_noind_null(enum ECPGttype type,
*** 295,300 ****
--- 295,301 ----
      {
          case ECPGt_char:
          case ECPGt_unsigned_char:
+         case ECPGt_string:
              *((char *) ptr) = '\0';
              break;
          case ECPGt_short:
*************** ECPGis_noind_null(enum ECPGttype type, v
*** 361,366 ****
--- 362,368 ----
      {
          case ECPGt_char:
          case ECPGt_unsigned_char:
+         case ECPGt_string:
              if (*((char *) ptr) == '\0')
                  return true;
              break;
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/typename.c
postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/typename.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/ecpglib/typename.c    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/ecpglib/typename.c    2009-07-04 12:12:02.000000000 +0200
*************** ecpg_type_name(enum ECPGttype typ)
*** 20,25 ****
--- 20,26 ----
      switch (typ)
      {
          case ECPGt_char:
+         case ECPGt_string:
              return "char";
          case ECPGt_unsigned_char:
              return "unsigned char";
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/include/ecpgtype.h
postgresql-8.4.0-string/src/interfaces/ecpg/include/ecpgtype.h
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/include/ecpgtype.h    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/include/ecpgtype.h    2009-07-04 12:06:05.000000000 +0200
*************** enum ECPGttype
*** 62,68 ****
      ECPGt_EOIT,                    /* End of insert types. */
      ECPGt_EORT,                    /* End of result types. */
      ECPGt_NO_INDICATOR,            /* no indicator */
!     ECPGt_sqlda                /* INFORMIX-compatible sqlda_t descriptor */
  };

   /* descriptor items */
--- 62,69 ----
      ECPGt_EOIT,                    /* End of insert types. */
      ECPGt_EORT,                    /* End of result types. */
      ECPGt_NO_INDICATOR,            /* no indicator */
!     ECPGt_sqlda,                /* INFORMIX-compatible sqlda_t descriptor */
!     ECPGt_string                /* trimmed (char *) type */
  };

   /* descriptor items */
*************** enum ECPGdtype
*** 87,93 ****
      ECPGd_cardinality
  };

! #define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_interval)

  /* we also have to handle different statement types */
  enum ECPG_statement_type
--- 88,94 ----
      ECPGd_cardinality
  };

! #define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string))

  /* we also have to handle different statement types */
  enum ECPG_statement_type
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/c_keywords.c
postgresql-8.4.0-string/src/interfaces/ecpg/preproc/c_keywords.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/c_keywords.c    2009-06-11 16:49:13.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/c_keywords.c    2009-07-04 13:40:14.000000000 +0200
*************** static const ScanKeyword ScanCKeywords[]
*** 45,50 ****
--- 45,51 ----
      {"short", SQL_SHORT, 0},
      {"signed", SQL_SIGNED, 0},
      {"static", S_STATIC, 0},
+     {"string", STRING_P, 0},
      {"struct", SQL_STRUCT, 0},
      {"to", TO, 0},
      {"typedef", S_TYPEDEF, 0},
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.addons
postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.addons
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.addons    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.addons    2009-07-04 14:26:02.000000000 +0200
*************** ECPG: ColIdcol_name_keyword rule
*** 331,336 ****
--- 331,337 ----
      | ECPGKeywords                  { $$ = $1; }
      | ECPGCKeywords                 { $$ = $1; }
      | CHAR_P                        { $$ = make_str("char"); }
+     | STRING_P                      { $$ = make_str("char"); }
      | VALUES                        { $$ = make_str("values"); }
  ECPG: type_function_nametype_func_name_keyword rule
      | ECPGKeywords                          { $$ = $1; }
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.header
postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.header
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.header    2009-06-11 01:11:52.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.header    2009-07-04 11:49:50.000000000 +0200
*************** adjust_informix(struct arguments *list)
*** 256,267 ****
          original_var = ptr->variable->name;
          sprintf(temp, "%d))", ecpg_informix_var);

!         if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char &&
ptr->variable->type->type!= ECPGt_unsigned_char) && 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) && 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++);
--- 256,267 ----
          original_var = ptr->variable->name;
          sprintf(temp, "%d))", ecpg_informix_var);

!         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++);
*************** add_typedef(char *name, char * dimension
*** 371,376 ****
--- 371,377 ----
          if (type_enum != ECPGt_varchar &&
              type_enum != ECPGt_char &&
              type_enum != ECPGt_unsigned_char &&
+             type_enum != ECPGt_string &&
              atoi(this->type->type_index) >= 0)
              mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported");

diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.tokens
postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.tokens
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.tokens    2008-11-14 11:03:33.000000000 +0100
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.tokens    2009-07-04 10:59:43.000000000 +0200
***************
*** 25,28 ****
  %token TYPECAST
  %token CSTRING CVARIABLE CPP_LINE IP
  %token DOLCONST ECONST NCONST UCONST UIDENT
!
--- 25,28 ----
  %token TYPECAST
  %token CSTRING CVARIABLE CPP_LINE IP
  %token DOLCONST ECONST NCONST UCONST UIDENT
! %token STRING_P
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.trailer
postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.trailer
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/ecpg.trailer    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/ecpg.trailer    2009-07-04 11:51:06.000000000 +0200
*************** char_variable: cvariable
*** 213,218 ****
--- 213,219 ----
                  {
                      case ECPGt_char:
                      case ECPGt_unsigned_char:
+                     case ECPGt_string:
                          $$ = $1;
                          break;
                      case ECPGt_varchar:
*************** signed_type: SQL_SHORT                { $$ = ECPGt_s
*** 795,800 ****
--- 796,802 ----
          }
          | SQL_BOOL                    { $$ = ECPGt_bool; }
          | CHAR_P                    { $$ = ECPGt_char; }
+         | STRING_P                    { $$ = ECPGt_string; }
          | DOUBLE_P                    { $$ = ECPGt_double; }
          ;

*************** variable: opt_pointer ECPGColLabel opt_a
*** 855,860 ****
--- 857,863 ----

                  case ECPGt_char:
                  case ECPGt_unsigned_char:
+                 case ECPGt_string:
                      if (atoi(dimension) == -1)
                      {
                          int i = strlen($5);
*************** ECPGVar: SQL_VAR
*** 1331,1336 ****
--- 1334,1340 ----

                      case ECPGt_char:
                      case ECPGt_unsigned_char:
+                     case ECPGt_string:
                          if (atoi(dimension) == -1)
                              type = ECPGmake_simple_type($5.type_enum, length, 0);
                          else
*************** c_anything:  ecpg_ident                { $$ = $1; }
*** 2017,2022 ****
--- 2021,2027 ----
          | SQL_UNSIGNED            { $$ = make_str("unsigned"); }
          | YEAR_P            { $$ = make_str("year"); }
          | CHAR_P            { $$ = make_str("char"); }
+         | STRING_P            { $$ = make_str("char"); }
          | FLOAT_P            { $$ = make_str("float"); }
          | TO                { $$ = make_str("to"); }
          | UNION                { $$ = make_str("union"); }
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/type.c
postgresql-8.4.0-string/src/interfaces/ecpg/preproc/type.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/type.c    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/type.c    2009-07-04 14:12:07.000000000 +0200
*************** get_type(enum ECPGttype type)
*** 200,205 ****
--- 200,208 ----
          case ECPGt_timestamp:
              return ("ECPGt_timestamp");
              break;
+         case ECPGt_string:
+             return ("ECPGt_string");
+             break;
          default:
              mmerror(PARSE_ERROR, ET_ERROR, "unrecognized variable type code %d", type);
      }
*************** ECPGdump_a_simple(FILE *o, const char *n
*** 368,373 ****
--- 371,377 ----
              case ECPGt_char:
              case ECPGt_unsigned_char:
              case ECPGt_char_variable:
+             case ECPGt_string:

                  /*
                   * we have to use the pointer except for arrays with given
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/variable.c
postgresql-8.4.0-string/src/interfaces/ecpg/preproc/variable.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/preproc/variable.c    2009-07-04 10:42:50.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/preproc/variable.c    2009-07-04 11:45:25.000000000 +0200
*************** adjust_array(enum ECPGttype type_enum, c
*** 524,530 ****
                                                  "multilevel pointers (more than 2 levels) are not supported; found %d
levels",pointer_len), 
                  pointer_len);

!     if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char)
          mmerror(PARSE_ERROR, ET_FATAL, "pointer to pointer is not supported for this data type");

      if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
--- 524,530 ----
                                                  "multilevel pointers (more than 2 levels) are not supported; found %d
levels",pointer_len), 
                  pointer_len);

!     if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
          mmerror(PARSE_ERROR, ET_FATAL, "pointer to pointer is not supported for this data type");

      if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
*************** adjust_array(enum ECPGttype type_enum, c
*** 563,568 ****
--- 563,569 ----
              break;
          case ECPGt_char:
          case ECPGt_unsigned_char:
+         case ECPGt_string:
              /* char ** */
              if (pointer_len == 2)
              {
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-define.c
postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-define.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-define.c    2008-12-29 18:07:06.000000000 +0100
--- postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-define.c    2009-07-04 14:41:02.000000000 +0200
*************** main(void)
*** 40,46 ****
  {
  /* exec sql begin declare section */

!        typedef char  string [ 8 ];

  #line 21 "define.pgc"

--- 40,46 ----
  {
  /* exec sql begin declare section */

!        typedef char  str [ 8 ];

  #line 21 "define.pgc"

diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-type.c
postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-type.c
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-type.c    2008-12-29 18:07:06.000000000 +0100
--- postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-type.c    2009-07-04 14:42:08.000000000 +0200
*************** typedef short  mmSmallInt ;
*** 40,52 ****
  #line 8 "type.pgc"


- /* exec sql type string is char [ 11 ] */
- #line 10 "type.pgc"
-
- typedef char string[11];
-
  /* exec sql type c is char reference */
! #line 13 "type.pgc"

  typedef char* c;

--- 40,47 ----
  #line 8 "type.pgc"


  /* exec sql type c is char reference */
! #line 10 "type.pgc"

  typedef char* c;

*************** typedef char* c;
*** 58,73 ****


  struct TBempl {
! #line 19 "type.pgc"
   mmInteger idnum ;

! #line 20 "type.pgc"
   mmChar name [ 21 ] ;

! #line 21 "type.pgc"
   mmSmallInt accs ;
   } ;/* exec sql end declare section */
! #line 23 "type.pgc"


  int
--- 53,68 ----


  struct TBempl {
! #line 16 "type.pgc"
   mmInteger idnum ;

! #line 17 "type.pgc"
   mmChar name [ 21 ] ;

! #line 18 "type.pgc"
   mmSmallInt accs ;
   } ;/* exec sql end declare section */
! #line 20 "type.pgc"


  int
*************** main (void)
*** 83,117 ****



! #line 29 "type.pgc"
   struct TBempl empl ;

! #line 30 "type.pgc"
!  string str ;

! #line 31 "type.pgc"
   c ptr = NULL ;

! #line 36 "type.pgc"
   struct varchar_vc {
! #line 34 "type.pgc"
   int len ;

! #line 35 "type.pgc"
   char text [ 10 ] ;
   } vc ;
  /* exec sql end declare section */
! #line 37 "type.pgc"


    /* exec sql var vc is [ 10 ] */
! #line 39 "type.pgc"

    ECPGdebug (1, stderr);

    empl.idnum = 1;
    { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
! #line 43 "type.pgc"

    if (sqlca.sqlcode)
      {
--- 78,112 ----



! #line 26 "type.pgc"
   struct TBempl empl ;

! #line 27 "type.pgc"
!  char str [ 11 ] ;

! #line 28 "type.pgc"
   c ptr = NULL ;

! #line 33 "type.pgc"
   struct varchar_vc {
! #line 31 "type.pgc"
   int len ;

! #line 32 "type.pgc"
   char text [ 10 ] ;
   } vc ;
  /* exec sql end declare section */
! #line 34 "type.pgc"


    /* exec sql var vc is [ 10 ] */
! #line 36 "type.pgc"

    ECPGdebug (1, stderr);

    empl.idnum = 1;
    { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
! #line 40 "type.pgc"

    if (sqlca.sqlcode)
      {
*************** main (void)
*** 120,126 ****
      }

    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table empl ( idnum integer , name char ( 20 ) , accs
smallint, string1 char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT);} 
! #line 51 "type.pgc"

    if (sqlca.sqlcode)
      {
--- 115,121 ----
      }

    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table empl ( idnum integer , name char ( 20 ) , accs
smallint, string1 char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT);} 
! #line 48 "type.pgc"

    if (sqlca.sqlcode)
      {
*************** main (void)
*** 129,135 ****
      }

    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into empl values ( 1 , 'user name' , 320 , 'first str' ,
'secondstr' , 'third str' )", ECPGt_EOIT, ECPGt_EORT);} 
! #line 58 "type.pgc"

    if (sqlca.sqlcode)
      {
--- 124,130 ----
      }

    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into empl values ( 1 , 'user name' , 320 , 'first str' ,
'secondstr' , 'third str' )", ECPGt_EOIT, ECPGt_EORT);} 
! #line 55 "type.pgc"

    if (sqlca.sqlcode)
      {
*************** main (void)
*** 146,158 ****
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_char,(str),(long)11,(long)1,(11)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_char,&(ptr),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_varchar,&(vc),(long)10,(long)1,sizeof(struct varchar_vc),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
! #line 68 "type.pgc"

    if (sqlca.sqlcode)
      {
--- 141,153 ----
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
!     ECPGt_string,&(str),(long)11,(long)1,sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_char,&(ptr),(long)0,(long)1,(1)*sizeof(char),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
      ECPGt_varchar,&(vc),(long)10,(long)1,sizeof(struct varchar_vc),
      ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
! #line 65 "type.pgc"

    if (sqlca.sqlcode)
      {
*************** main (void)
*** 162,168 ****
    printf ("id=%ld name='%s' accs=%d str='%s' ptr='%s' vc='%10.10s'\n", empl.idnum, empl.name, empl.accs, str, ptr,
vc.text);

    { ECPGdisconnect(__LINE__, "CURRENT");}
! #line 76 "type.pgc"


    free(ptr);
--- 157,163 ----
    printf ("id=%ld name='%s' accs=%d str='%s' ptr='%s' vc='%10.10s'\n", empl.idnum, empl.name, empl.accs, str, ptr,
vc.text);

    { ECPGdisconnect(__LINE__, "CURRENT");}
! #line 73 "type.pgc"


    free(ptr);
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-type.stderr
postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-type.stderr
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-type.stderr    2008-12-29 18:07:06.000000000 +0100
--- postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-type.stderr    2009-07-04 14:42:09.000000000
+0200
***************
*** 2,40 ****
  [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 50: query: create table empl ( idnum integer , name char ( 20 ) , accs smallint ,
string1char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) ); with 0 parameter(s) on connection regress1 
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 50: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 50: OK: CREATE TABLE
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 58: query: insert into empl values ( 1 , 'user name' , 320 , 'first str' , 'second
str', 'third str' ); with 0 parameter(s) on connection regress1 
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 58: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 58: OK: INSERT 0 1
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 65: query: select idnum , name , accs , string1 , string2 , string3 from empl where
idnum= $1 ; with 1 parameter(s) on connection regress1 
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 65: using PQexecParams
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: free_params on line 65: parameter 1 = 1
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 65: correctly got 1 tuples with 6 fields
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: 1 offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: user name            offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: 320 offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: first str  offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_store_result on line 65: allocating memory for 1 tuples
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: second str offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: third str  offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_finish: connection regress1 closed
  [NO_PID]: sqlca: code: 0, state: 00000
--- 2,40 ----
  [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 47: query: create table empl ( idnum integer , name char ( 20 ) , accs smallint ,
string1char ( 10 ) , string2 char ( 10 ) , string3 char ( 10 ) ); with 0 parameter(s) on connection regress1 
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 47: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 47: OK: CREATE TABLE
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 55: query: insert into empl values ( 1 , 'user name' , 320 , 'first str' , 'second
str', 'third str' ); with 0 parameter(s) on connection regress1 
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 55: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 55: OK: INSERT 0 1
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 62: query: select idnum , name , accs , string1 , string2 , string3 from empl where
idnum= $1 ; with 1 parameter(s) on connection regress1 
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 62: using PQexecParams
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: free_params on line 62: parameter 1 = 1
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 62: correctly got 1 tuples with 6 fields
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 62: RESULT: 1 offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 62: RESULT: user name            offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 62: RESULT: 320 offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 62: RESULT: first str  offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_store_result on line 62: allocating memory for 1 tuples
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 62: RESULT: second str offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 62: RESULT: third str  offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_finish: connection regress1 closed
  [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-type.stdout
postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-type.stdout
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/expected/preproc-type.stdout    2006-09-08 11:03:40.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/test/expected/preproc-type.stdout    2009-07-04 14:42:10.000000000
+0200
***************
*** 1 ****
! id=1 name='user name           ' accs=320 str='first str ' ptr='second str' vc='third str '
--- 1 ----
! id=1 name='user name           ' accs=320 str='first str' ptr='second str' vc='third str '
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/preproc/define.pgc
postgresql-8.4.0-string/src/interfaces/ecpg/test/preproc/define.pgc
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/preproc/define.pgc    2006-09-08 11:03:40.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/test/preproc/define.pgc    2009-07-04 14:03:18.000000000 +0200
*************** main(void)
*** 18,24 ****
  {
  exec sql begin declare section;
  exec sql ifdef NAMELEN;
!     typedef char string[NAMELEN];
      intarray amount;
      char name[AMOUNT][NAMELEN];
      char letter[AMOUNT][1];
--- 18,24 ----
  {
  exec sql begin declare section;
  exec sql ifdef NAMELEN;
!     typedef char str[NAMELEN];
      intarray amount;
      char name[AMOUNT][NAMELEN];
      char letter[AMOUNT][1];
diff -dcrpN postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/preproc/type.pgc
postgresql-8.4.0-string/src/interfaces/ecpg/test/preproc/type.pgc
*** postgresql-8.4.0-sqlda/src/interfaces/ecpg/test/preproc/type.pgc    2006-09-08 15:32:29.000000000 +0200
--- postgresql-8.4.0-string/src/interfaces/ecpg/test/preproc/type.pgc    2009-07-04 14:04:29.000000000 +0200
*************** EXEC SQL typedef long mmInteger;
*** 7,15 ****
  EXEC SQL typedef char mmChar;
  EXEC SQL typedef short mmSmallInt;

- exec sql type string is char[11];
- typedef char string[11];
-
  exec sql type c is char reference;
  typedef char* c;

--- 7,12 ----
*************** main (void)
*** 27,33 ****
  {
    EXEC SQL BEGIN DECLARE SECTION;
    struct TBempl empl;
!   string str;
    c ptr = NULL;
    struct varchar_vc
    {
--- 24,30 ----
  {
    EXEC SQL BEGIN DECLARE SECTION;
    struct TBempl empl;
!   string str[11];
    c ptr = NULL;
    struct varchar_vc
    {

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Greg Stark
Дата:
Сообщение: Re: pg_migrator mention in documentation
Следующее
От: Tom Lane
Дата:
Сообщение: Re: ECPG support for string pseudo-type