]> granicus.if.org Git - postgresql/commitdiff
Fixed auto allocation for binary data types.
authorMichael Meskes <meskes@postgresql.org>
Mon, 2 Feb 2009 16:14:06 +0000 (16:14 +0000)
committerMichael Meskes <meskes@postgresql.org>
Mon, 2 Feb 2009 16:14:06 +0000 (16:14 +0000)
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/test/expected/sql-binary.c
src/interfaces/ecpg/test/expected/sql-binary.stderr
src/interfaces/ecpg/test/expected/sql-binary.stdout
src/interfaces/ecpg/test/sql/binary.pgc

index cd0482dab64809595b939c61515ccdebd5ba4931..ea40d4c4a35cda8a67c416a734b756e8df5cbb7a 100644 (file)
@@ -2409,6 +2409,7 @@ Wed, 17 Dec 2008 17:49:11 +0100
 Mon, 02 Feb 2009 16:34:53 +0100
 
        - Fixed bug in handling of "%s" pattern in PGTYPEStimestamp_defmt_asc().
+       - Fixed auto allocation for binary data types.
        - Set pgtypes library version to 3.1.
        - Set compat library version to 3.1.
        - Set ecpg library version to 6.2.
index 1605ec0dc8a2248406e6c2e7f0eb513fdfd71141..54636c4bc95099a62c55a07d960d6ea606b607b1 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.79 2009/01/15 11:52:55 petere Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.80 2009/02/02 16:14:06 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -353,40 +353,45 @@ ecpg_store_result(const PGresult *results, int act_field,
        {
                int                     len = 0;
 
-               switch (var->type)
+               if (!PQfformat(results, act_field)) 
                {
-                       case ECPGt_char:
-                       case ECPGt_unsigned_char:
-                               if (!var->varcharsize && !var->arrsize)
-                               {
-                                       /* special mode for handling char**foo=0 */
-                                       for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
-                                               len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
-                                       len *= var->offset; /* should be 1, but YMNK */
-                                       len += (ntuples + 1) * sizeof(char *);
-                               }
-                               else
-                               {
-                                       var->varcharsize = 0;
-                                       /* check strlen for each tuple */
-                                       for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+                       switch (var->type)
+                       {
+                               case ECPGt_char:
+                               case ECPGt_unsigned_char:
+                                       if (!var->varcharsize && !var->arrsize)
+                                       {
+                                               /* special mode for handling char**foo=0 */
+                                               for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+                                                       len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
+                                               len *= var->offset; /* should be 1, but YMNK */
+                                               len += (ntuples + 1) * sizeof(char *);
+                                       }
+                                       else
                                        {
-                                               int                     len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
+                                               var->varcharsize = 0;
+                                               /* check strlen for each tuple */
+                                               for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
+                                               {
+                                                       int                     len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 
-                                               if (len > var->varcharsize)
-                                                       var->varcharsize = len;
+                                                       if (len > var->varcharsize)
+                                                               var->varcharsize = len;
+                                               }
+                                               var->offset *= var->varcharsize;
+                                               len = var->offset * ntuples;
                                        }
-                                       var->offset *= var->varcharsize;
+                                       break;
+                               case ECPGt_varchar:
+                                       len = ntuples * (var->varcharsize + sizeof(int));
+                                       break;
+                               default:
                                        len = var->offset * ntuples;
-                               }
-                               break;
-                       case ECPGt_varchar:
-                               len = ntuples * (var->varcharsize + sizeof(int));
-                               break;
-                       default:
-                               len = var->offset * ntuples;
-                               break;
+                                       break;
+                       }
                }
+               else
+                       len = PQgetlength(results, act_tuple, act_field);
                ecpg_log("ecpg_store_result on line %d: allocating memory for %d tuples\n", stmt->lineno, ntuples);
                var->value = (char *) ecpg_alloc(len, stmt->lineno);
                if (!var->value)
index fb2606d4e976562ff672955a4ba82d4e1ba48703..95f8056917d70552f01f293412f13f70178cf3c7 100644 (file)
@@ -51,14 +51,18 @@ main (void)
   /* exec sql begin declare section */
     
      
+     
   
 #line 20 "binary.pgc"
  struct TBempl empl ;
  
 #line 21 "binary.pgc"
+ char * pointer = NULL ;
+#line 22 "binary.pgc"
  char * data = "\\001\\155\\000\\212" ;
 /* exec sql end declare section */
-#line 22 "binary.pgc"
+#line 23 "binary.pgc"
 
   int i;
 
@@ -66,7 +70,7 @@ main (void)
 
   empl.idnum = 1;
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 28 "binary.pgc"
+#line 29 "binary.pgc"
 
   if (sqlca.sqlcode)
     {
@@ -75,7 +79,7 @@ main (void)
     }
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table empl ( idnum integer , name char ( 20 ) , accs smallint , byte bytea )", ECPGt_EOIT, ECPGt_EORT);}
-#line 36 "binary.pgc"
+#line 37 "binary.pgc"
 
   if (sqlca.sqlcode)
     {
@@ -86,7 +90,7 @@ main (void)
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into empl values ( 1 , 'first user' , 320 , $1  )", 
        ECPGt_char,&(data),(long)0,(long)1,(1)*sizeof(char), 
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
-#line 43 "binary.pgc"
+#line 44 "binary.pgc"
 
   if (sqlca.sqlcode)
     {
@@ -95,12 +99,12 @@ main (void)
     }
 
   /* declare C cursor for select name , accs , byte from empl where idnum = $1  */
-#line 50 "binary.pgc"
+#line 51 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", 
        ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
-#line 51 "binary.pgc"
+#line 52 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, 
        ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), 
@@ -109,7 +113,7 @@ main (void)
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
        ECPGt_char,(empl.byte),(long)20,(long)1,(20)*sizeof(char), 
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 52 "binary.pgc"
+#line 53 "binary.pgc"
 
   if (sqlca.sqlcode)
     {
@@ -119,15 +123,13 @@ main (void)
 
   printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
 
-  memset(empl.name, 0, 21L);
-  memset(empl.byte, '#', 20L);
   /* declare B binary cursor for select name , accs , byte from empl where idnum = $1  */
-#line 63 "binary.pgc"
+#line 62 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", 
        ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
-#line 64 "binary.pgc"
+#line 63 "binary.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch B", ECPGt_EOIT, 
        ECPGt_char,(empl.name),(long)21,(long)1,(21)*sizeof(char), 
@@ -136,7 +138,7 @@ main (void)
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
        ECPGt_char,(empl.byte),(long)20,(long)1,(20)*sizeof(char), 
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 65 "binary.pgc"
+#line 64 "binary.pgc"
 
   if (sqlca.sqlcode)
     {
@@ -145,20 +147,46 @@ main (void)
     }
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close B", ECPGt_EOIT, ECPGt_EORT);}
-#line 72 "binary.pgc"
+#line 71 "binary.pgc"
 
 
   /* do not print a.accs because big/little endian will have different outputs here */
   printf ("name=%s, byte=", empl.name);
-  for (i=0; i<20; i++)
-  {
-       if (empl.byte[i] == '#')
-               break;
+  for (i=0; i<4; i++)
        printf("(%o)", (unsigned char)empl.byte[i]);
-  }
   printf("\n");
+
+  /* declare A binary cursor for select byte from empl where idnum = $1  */
+#line 79 "binary.pgc"
+
+  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", 
+       ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);}
+#line 80 "binary.pgc"
+
+  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch A", ECPGt_EOIT, 
+       ECPGt_char,&(pointer),(long)0,(long)1,(1)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 81 "binary.pgc"
+
+  if (sqlca.sqlcode)
+    {
+      printf ("fetch error = %ld\n", sqlca.sqlcode);
+      exit (sqlca.sqlcode);
+    }
+
+  { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close A", ECPGt_EOIT, ECPGt_EORT);}
+#line 88 "binary.pgc"
+
+
+  printf ("pointer=");
+  for (i=0; i<4; i++)
+       printf("(%o)", (unsigned char)pointer[i]);
+  printf("\n");
+  free(pointer);
+
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 83 "binary.pgc"
+#line 96 "binary.pgc"
 
   exit (0);
 }
index 8f4434fbe5dc429db7afea924f6e2a16a2863076..f0530f24c11c92d89c044a423f30a262168095a9 100644 (file)
@@ -2,65 +2,89 @@
 [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 35: query: create table empl ( idnum integer , name char ( 20 ) , accs smallint , byte bytea ); with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 36: query: create table empl ( idnum integer , name char ( 20 ) , accs smallint , byte bytea ); 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]: ecpg_execute on line 36: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 35: OK: CREATE TABLE
+[NO_PID]: ecpg_execute on line 36: OK: CREATE TABLE
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 43: query: insert into empl values ( 1 , 'first user' , 320 , $1  ); with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 44: query: insert into empl values ( 1 , 'first user' , 320 , $1  ); with 1 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 43: using PQexecParams
+[NO_PID]: ecpg_execute on line 44: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 43: parameter 1 = \001\155\000\212
+[NO_PID]: free_params on line 44: parameter 1 = \001\155\000\212
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 43: OK: INSERT 0 1
+[NO_PID]: ecpg_execute on line 44: OK: INSERT 0 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 51: query: declare C cursor for select name , accs , byte from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 52: query: declare C cursor for select name , accs , byte 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 51: using PQexecParams
+[NO_PID]: ecpg_execute on line 52: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 51: parameter 1 = 1
+[NO_PID]: free_params on line 52: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 51: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 52: OK: DECLARE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 52: query: fetch C; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 53: query: fetch C; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 52: using PQexec
+[NO_PID]: ecpg_execute on line 53: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 52: correctly got 1 tuples with 3 fields
+[NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 3 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 52: RESULT: first user           offset: -1; array: yes
+[NO_PID]: ecpg_get_data on line 53: RESULT: first user           offset: -1; array: yes
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 52: RESULT: 320 offset: -1; array: yes
+[NO_PID]: ecpg_get_data on line 53: RESULT: 320 offset: -1; array: yes
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 52: RESULT: \001m\000\212 offset: -1; array: yes
+[NO_PID]: ecpg_get_data on line 53: RESULT: \001m\000\212 offset: -1; array: yes
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 64: query: declare B binary cursor for select name , accs , byte from empl where idnum = $1 ; with 1 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 63: query: declare B binary cursor for select name , accs , byte 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 64: using PQexecParams
+[NO_PID]: ecpg_execute on line 63: using PQexecParams
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: free_params on line 64: parameter 1 = 1
+[NO_PID]: free_params on line 63: parameter 1 = 1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 64: OK: DECLARE CURSOR
+[NO_PID]: ecpg_execute on line 63: OK: DECLARE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 65: query: fetch B; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 64: query: fetch B; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 65: using PQexec
+[NO_PID]: ecpg_execute on line 64: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 65: correctly got 1 tuples with 3 fields
+[NO_PID]: ecpg_execute on line 64: correctly got 1 tuples with 3 fields
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: BINARY offset: -1; array: yes
+[NO_PID]: ecpg_get_data on line 64: RESULT: BINARY offset: -1; array: yes
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: BINARY offset: -1; array: yes
+[NO_PID]: ecpg_get_data on line 64: RESULT: BINARY offset: -1; array: yes
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_get_data on line 65: RESULT: BINARY offset: -1; array: yes
+[NO_PID]: ecpg_get_data on line 64: RESULT: BINARY offset: -1; array: yes
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 72: query: close B; with 0 parameter(s) on connection regress1
+[NO_PID]: ecpg_execute on line 71: query: close B; with 0 parameter(s) on connection regress1
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 72: using PQexec
+[NO_PID]: ecpg_execute on line 71: using PQexec
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ecpg_execute on line 72: OK: CLOSE CURSOR
+[NO_PID]: ecpg_execute on line 71: OK: CLOSE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 80: query: declare A binary cursor for select byte 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 80: using PQexecParams
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: free_params on line 80: parameter 1 = 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 80: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 81: query: fetch 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: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_store_result on line 81: allocating memory for 1 tuples
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 81: RESULT: BINARY offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 88: query: close A; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 88: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 88: OK: CLOSE CURSOR
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_finish: connection regress1 closed
 [NO_PID]: sqlca: code: 0, state: 00000
index e8b925631905e65c2b462f680016763b64cf95a7..b2a94db6d1d984f358bc48282295c997b56fe2b3 100644 (file)
@@ -1,2 +1,3 @@
 name=first user          , accs=320 byte=\001m\000\212
 name=first user          , byte=(1)(155)(0)(212)
+pointer=(1)(155)(0)(212)
index 9be73409135b1055cae83c875c9a218c684ae237..a86aa283b6bfb19ba77dce0b17bffb536b4078a2 100644 (file)
@@ -18,6 +18,7 @@ main (void)
 {
   EXEC SQL BEGIN DECLARE SECTION;
   struct TBempl empl;
+  char *pointer = NULL;
   char *data = "\\001\\155\\000\\212";
   EXEC SQL END DECLARE SECTION;
   int i;
@@ -58,8 +59,6 @@ main (void)
 
   printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
 
-  memset(empl.name, 0, 21L);
-  memset(empl.byte, '#', 20L);
   EXEC SQL DECLARE B BINARY CURSOR FOR select name, accs, byte from empl where idnum =:empl.idnum;
   EXEC SQL OPEN B;
   EXEC SQL FETCH B INTO :empl.name,:empl.accs,:empl.byte;
@@ -73,13 +72,27 @@ main (void)
 
   /* do not print a.accs because big/little endian will have different outputs here */
   printf ("name=%s, byte=", empl.name);
-  for (i=0; i<20; i++)
-  {
-       if (empl.byte[i] == '#')
-               break;
+  for (i=0; i<4; i++)
        printf("(%o)", (unsigned char)empl.byte[i]);
-  }
   printf("\n");
+
+  EXEC SQL DECLARE A BINARY CURSOR FOR select byte from empl where idnum =:empl.idnum;
+  EXEC SQL OPEN A;
+  EXEC SQL FETCH A INTO :pointer;
+  if (sqlca.sqlcode)
+    {
+      printf ("fetch error = %ld\n", sqlca.sqlcode);
+      exit (sqlca.sqlcode);
+    }
+
+  EXEC SQL CLOSE A;
+
+  printf ("pointer=");
+  for (i=0; i<4; i++)
+       printf("(%o)", (unsigned char)pointer[i]);
+  printf("\n");
+  free(pointer);
+
   EXEC SQL disconnect;
   exit (0);
 }