Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3b7ab43

Browse files
author
Michael Meskes
committed
Add Oracle like handling of char arrays.
In some cases Oracle Pro*C handles char array differently than ECPG. This patchadds a Oracle compatibility mode to make ECPG behave like Pro*C.Patch by David Rader <davidr@openscg.com>
1 parentdb2fc80 commit3b7ab43

File tree

12 files changed

+513
-5
lines changed

12 files changed

+513
-5
lines changed

‎src/interfaces/ecpg/ecpglib/data.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,45 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
464464

465465
if (varcharsize==0||varcharsize>size)
466466
{
467-
strncpy(str,pval,size+1);
467+
/* compatibility mode, blank pad and null terminate char array */
468+
if (ORACLE_MODE(compat)&& (type==ECPGt_char||type==ECPGt_unsigned_char))
469+
{
470+
memset(str,' ',varcharsize);
471+
memcpy(str,pval,size);
472+
str[varcharsize-1]='\0';
473+
474+
/* compatiblity mode empty string gets -1 indicator but no warning */
475+
if (size==0) {
476+
/* truncation */
477+
switch (ind_type)
478+
{
479+
caseECPGt_short:
480+
caseECPGt_unsigned_short:
481+
*((short*) (ind+ind_offset*act_tuple))=-1;
482+
break;
483+
caseECPGt_int:
484+
caseECPGt_unsigned_int:
485+
*((int*) (ind+ind_offset*act_tuple))=-1;
486+
break;
487+
caseECPGt_long:
488+
caseECPGt_unsigned_long:
489+
*((long*) (ind+ind_offset*act_tuple))=-1;
490+
break;
491+
#ifdefHAVE_LONG_LONG_INT
492+
caseECPGt_long_long:
493+
caseECPGt_unsigned_long_long:
494+
*((long longint*) (ind+ind_offset*act_tuple))=-1;
495+
break;
496+
#endif/* HAVE_LONG_LONG_INT */
497+
default:
498+
break;
499+
}
500+
}
501+
}
502+
else
503+
{
504+
strncpy(str,pval,size+1);
505+
}
468506
/* do the rtrim() */
469507
if (type==ECPGt_string)
470508
{
@@ -481,7 +519,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
481519
{
482520
strncpy(str,pval,varcharsize);
483521

484-
if (varcharsize<size)
522+
/* compatibility mode, null terminate char array */
523+
if (ORACLE_MODE(compat)&& (varcharsize-1)<size)
524+
{
525+
if (type==ECPGt_char||type==ECPGt_unsigned_char)
526+
str[varcharsize-1]='\0';
527+
}
528+
529+
if (varcharsize<size|| (ORACLE_MODE(compat)&& (varcharsize-1)<size))
485530
{
486531
/* truncation */
487532
switch (ind_type)

‎src/interfaces/ecpg/ecpglib/extern.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515

1616
enumCOMPAT_MODE
1717
{
18-
ECPG_COMPAT_PGSQL=0,ECPG_COMPAT_INFORMIX,ECPG_COMPAT_INFORMIX_SE
18+
ECPG_COMPAT_PGSQL=0,ECPG_COMPAT_INFORMIX,ECPG_COMPAT_INFORMIX_SE,ECPG_COMPAT_ORACLE
1919
};
2020

2121
externboolecpg_internal_regression_mode;
2222

2323
#defineINFORMIX_MODE(X) ((X) == ECPG_COMPAT_INFORMIX || (X) == ECPG_COMPAT_INFORMIX_SE)
24+
#defineORACLE_MODE(X) ((X) == ECPG_COMPAT_ORACLE)
2425

2526
enumARRAY_TYPE
2627
{

‎src/interfaces/ecpg/preproc/ecpg.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ help(const char *progname)
4141
printf(_(" -c automatically generate C code from embedded SQL code;\n"
4242
" this affects EXEC SQL TYPE\n"));
4343
printf(_(" -C MODE set compatibility mode; MODE can be one of\n"
44-
" \"INFORMIX\", \"INFORMIX_SE\"\n"));
44+
" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n"));
4545
#ifdefYYDEBUG
4646
printf(_(" -d generate parser debug output\n"));
4747
#endif
@@ -208,6 +208,10 @@ main(int argc, char *const argv[])
208208
snprintf(informix_path,MAXPGPATH,"%s/informix/esql",pkginclude_path);
209209
add_include_path(informix_path);
210210
}
211+
elseif (strncmp(optarg,"ORACLE",strlen("ORACLE"))==0)
212+
{
213+
compat=ECPG_COMPAT_ORACLE;
214+
}
211215
else
212216
{
213217
fprintf(stderr,_("Try \"%s --help\" for more information.\n"),argv[0]);

‎src/interfaces/ecpg/preproc/extern.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,12 @@ extern intfiltered_base_yylex(void);
122122

123123
enumCOMPAT_MODE
124124
{
125-
ECPG_COMPAT_PGSQL=0,ECPG_COMPAT_INFORMIX,ECPG_COMPAT_INFORMIX_SE
125+
ECPG_COMPAT_PGSQL=0,ECPG_COMPAT_INFORMIX,ECPG_COMPAT_INFORMIX_SE,ECPG_COMPAT_ORACLE
126126
};
127127
externenumCOMPAT_MODEcompat;
128128

129129
#defineINFORMIX_MODE(compat == ECPG_COMPAT_INFORMIX || compat == ECPG_COMPAT_INFORMIX_SE)
130+
#defineORACLE_MODE (compat == ECPG_COMPAT_ORACLE)
131+
130132

131133
#endif/* _ECPG_PREPROC_EXTERN_H */

‎src/interfaces/ecpg/test/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ all install installdirs uninstall distprep:
3030
$(MAKE) -C pgtypeslib$@
3131
$(MAKE) -C preproc$@
3232
$(MAKE) -C compat_informix$@
33+
$(MAKE) -C compat_oracle$@
3334
$(MAKE) -C thread$@
3435

3536
cleandistcleanmaintainer-clean:
@@ -38,6 +39,7 @@ clean distclean maintainer-clean:
3839
$(MAKE) -C pgtypeslib$@
3940
$(MAKE) -C preproc$@
4041
$(MAKE) -C compat_informix$@
42+
$(MAKE) -C compat_oracle$@
4143
$(MAKE) -C thread$@
4244
rm -rf tmp_check results log
4345
rm -f pg_regress regression.diffs regression.out pg_regress_ecpg.o$(WIN32RES)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/char_array
2+
/char_array.c
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
subdir = src/interfaces/ecpg/test/compat_oracle
2+
top_builddir = ../../../../..
3+
include$(top_builddir)/src/Makefile.global
4+
include$(top_srcdir)/$(subdir)/../Makefile.regress
5+
6+
# Use special oracle compatibility switch for all tests in this directory
7+
ECPG += -C ORACLE
8+
9+
TESTS = char_array char_array.c
10+
11+
all:$(TESTS)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
EXEC SQL INCLUDE ../regression;
6+
7+
static void warn();
8+
9+
/* Compatible handling of char array to retrieve varchar field to char array
10+
should be fixed-length, blank-padded, then null-terminated.
11+
Conforms to the ANSI Fixed Character type. */
12+
13+
int main() {
14+
15+
ECPGdebug(1, stderr);
16+
EXEC SQL CONNECT TO REGRESSDB1;
17+
18+
EXEC SQL WHENEVER SQLWARNING do warn();
19+
EXEC SQL WHENEVER SQLERROR SQLPRINT;
20+
21+
const char *ppppp = "XXXXX";
22+
23+
EXEC SQL BEGIN DECLARE SECTION;
24+
char shortstr[5];
25+
char bigstr[11];
26+
short shstr_ind = 0;
27+
short bigstr_ind = 0;
28+
EXEC SQL END DECLARE SECTION;
29+
30+
EXEC SQL CREATE TABLE strdbase (strval varchar(10));
31+
EXEC SQL INSERT INTO strdbase values ('');
32+
EXEC SQL INSERT INTO strdbase values ('AB');
33+
EXEC SQL INSERT INTO strdbase values ('ABCD');
34+
EXEC SQL INSERT INTO strdbase values ('ABCDE');
35+
EXEC SQL INSERT INTO strdbase values ('ABCDEF');
36+
EXEC SQL INSERT INTO strdbase values ('ABCDEFGHIJ');
37+
38+
EXEC SQL declare C cursor for select strval, strval from strdbase;
39+
EXEC SQL OPEN C;
40+
41+
EXEC SQL WHENEVER NOT FOUND DO BREAK;
42+
43+
printf("Full Str. : Short Ind.\n");
44+
while(1) {
45+
strncpy(shortstr, ppppp, sizeof shortstr);
46+
memset(bigstr, 0, sizeof bigstr);
47+
EXEC SQL FETCH C into :bigstr :bigstr_ind, :shortstr :shstr_ind;
48+
printf("\"%s\": \"%s\" %d\n", bigstr, shortstr, shstr_ind);
49+
}
50+
51+
EXEC SQL close cstr;
52+
EXEC SQL DROP TABLE strdbase;
53+
54+
printf("\nGOOD-BYE!!\n\n");
55+
56+
EXEC SQL COMMIT WORK;
57+
58+
EXEC SQL DISCONNECT ALL;
59+
60+
return 0;
61+
}
62+
63+
static void warn(void)
64+
{
65+
fprintf(stderr, "Warning: At least one column was truncated\n");
66+
}

‎src/interfaces/ecpg/test/ecpg_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ test: compat_informix/sqlda
77
test: compat_informix/describe
88
test: compat_informix/test_informix
99
test: compat_informix/test_informix2
10+
test: compat_oracle/char_array
1011
test: connect/test2
1112
test: connect/test3
1213
test: connect/test4

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp