From: Michael Meskes Date: Mon, 2 Feb 2009 16:14:06 +0000 (+0000) Subject: Fixed auto allocation for binary data types. X-Git-Tag: REL8_4_BETA1~320 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2d3c6911465a2214c0f82fb604c6098d9975c5a5;p=postgresql Fixed auto allocation for binary data types. --- diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index cd0482dab6..ea40d4c4a3 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -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. diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 1605ec0dc8..54636c4bc9 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -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) diff --git a/src/interfaces/ecpg/test/expected/sql-binary.c b/src/interfaces/ecpg/test/expected/sql-binary.c index fb2606d4e9..95f8056917 100644 --- a/src/interfaces/ecpg/test/expected/sql-binary.c +++ b/src/interfaces/ecpg/test/expected/sql-binary.c @@ -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); } diff --git a/src/interfaces/ecpg/test/expected/sql-binary.stderr b/src/interfaces/ecpg/test/expected/sql-binary.stderr index 8f4434fbe5..f0530f24c1 100644 --- a/src/interfaces/ecpg/test/expected/sql-binary.stderr +++ b/src/interfaces/ecpg/test/expected/sql-binary.stderr @@ -2,65 +2,89 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ECPGconnect: opening database regress1 on port [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 diff --git a/src/interfaces/ecpg/test/expected/sql-binary.stdout b/src/interfaces/ecpg/test/expected/sql-binary.stdout index e8b9256319..b2a94db6d1 100644 --- a/src/interfaces/ecpg/test/expected/sql-binary.stdout +++ b/src/interfaces/ecpg/test/expected/sql-binary.stdout @@ -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) diff --git a/src/interfaces/ecpg/test/sql/binary.pgc b/src/interfaces/ecpg/test/sql/binary.pgc index 9be7340913..a86aa283b6 100644 --- a/src/interfaces/ecpg/test/sql/binary.pgc +++ b/src/interfaces/ecpg/test/sql/binary.pgc @@ -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); }