aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/test/compat_oracle/char_array.pgc
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2023-04-18 11:20:47 +0900
committerMichael Paquier <michael@paquier.xyz>2023-04-18 11:20:47 +0900
commit8c746be44002e8f95dcf8e98f58a47ac851563ee (patch)
treedf033fa375860353f7896bde0b8a79fec2560f26 /src/interfaces/ecpg/test/compat_oracle/char_array.pgc
parent2207df7c34bfcecec33da2a47068e94d7882ffdb (diff)
downloadpostgresql-8c746be44002e8f95dcf8e98f58a47ac851563ee.tar.gz
postgresql-8c746be44002e8f95dcf8e98f58a47ac851563ee.zip
ecpg: Fix handling of strings in ORACLE compat code with SQLDA
When compiled with -C ORACLE, ecpg_get_data() had a one-off issue where it would incorrectly store the null terminator byte to str[-1] when varcharsize is 0, which is something that can happen when using SQLDA. This would eat 1 byte from the previous field stored, corrupting the results generated. All the callers of ecpg_get_data() estimate and allocate enough storage for the data received, and the fix of this commit relies on this assumption. Note that this maps to the case where no padding or truncation is required. This issue has been introduced by 3b7ab43 with the Oracle compatibility option, so backpatch down to v11. Author: Kyotaro Horiguchi Discussion: https://postgr.es/m/20230410.173500.440060475837236886.horikyota.ntt@gmail.com Backpatch-through: 11
Diffstat (limited to 'src/interfaces/ecpg/test/compat_oracle/char_array.pgc')
-rw-r--r--src/interfaces/ecpg/test/compat_oracle/char_array.pgc31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/interfaces/ecpg/test/compat_oracle/char_array.pgc b/src/interfaces/ecpg/test/compat_oracle/char_array.pgc
index 6a5d383d4eb..de18cbb57ff 100644
--- a/src/interfaces/ecpg/test/compat_oracle/char_array.pgc
+++ b/src/interfaces/ecpg/test/compat_oracle/char_array.pgc
@@ -2,6 +2,10 @@
#include <stdlib.h>
#include <string.h>
+#include <pgtypes_numeric.h>
+
+EXEC SQL INCLUDE sqlda.h;
+
EXEC SQL INCLUDE ../regression;
static void warn(void)
@@ -20,6 +24,8 @@ int main() {
const char *ppppp = "XXXXX";
int loopcount;
+ sqlda_t *sqlda = NULL;
+
EXEC SQL BEGIN DECLARE SECTION;
char shortstr[5];
char bigstr[11];
@@ -53,11 +59,34 @@ int main() {
EXEC SQL CLOSE C;
EXEC SQL DROP TABLE strdbase;
+ EXEC SQL COMMIT WORK;
- printf("\nGOOD-BYE!!\n\n");
+ /* SQLDA handling */
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ EXEC SQL WHENEVER NOT FOUND STOP;
+ EXEC SQL PREPARE stmt1 FROM "SELECT 123::numeric(3,0), 't'::varchar(2)";
+ EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
+ EXEC SQL OPEN cur1;
+ EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda;
+
+ printf("\n-----------------\ntype : data\n");
+ for (int i = 0 ; i < sqlda->sqld ; i++)
+ {
+ sqlvar_t v = sqlda->sqlvar[i];
+ char *sqldata = v.sqldata;
+
+ if (v.sqltype == ECPGt_numeric)
+ sqldata =
+ PGTYPESnumeric_to_asc((numeric*) sqlda->sqlvar[i].sqldata, -1);
+
+ printf("%-8s: \"%s\"\n", v.sqlname.data, sqldata);
+ }
+ EXEC SQL CLOSE cur1;
EXEC SQL COMMIT WORK;
+ printf("\nGOOD-BYE!!\n\n");
+
EXEC SQL DISCONNECT ALL;
return 0;