diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:15:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:15:05 +0000 |
commit | 46651ce6fe013220ed397add242004d764fc0153 (patch) | |
tree | 6e5299f990f88e60174a1d3ae6e48eedd2688b2b /src/interfaces/ecpg/test/preproc | |
parent | Initial commit. (diff) | |
download | postgresql-14-46651ce6fe013220ed397add242004d764fc0153.tar.xz postgresql-14-46651ce6fe013220ed397add242004d764fc0153.zip |
Adding upstream version 14.5.upstream/14.5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/interfaces/ecpg/test/preproc')
-rw-r--r-- | src/interfaces/ecpg/test/preproc/.gitignore | 26 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/Makefile | 33 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/array_of_struct.pgc | 95 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/autoprep.pgc | 72 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/comment.pgc | 21 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/cursor.pgc | 256 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/define.pgc | 78 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/init.pgc | 100 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/outofscope.pgc | 116 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc | 100 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/strings.h | 8 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/strings.pgc | 32 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/struct.h | 19 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/type.pgc | 80 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/variable.pgc | 101 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/whenever.pgc | 67 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc | 63 |
17 files changed, 1267 insertions, 0 deletions
diff --git a/src/interfaces/ecpg/test/preproc/.gitignore b/src/interfaces/ecpg/test/preproc/.gitignore new file mode 100644 index 0000000..fd63e64 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/.gitignore @@ -0,0 +1,26 @@ +/array_of_struct +/array_of_struct.c +/autoprep +/autoprep.c +/comment +/comment.c +/cursor +/cursor.c +/define +/define.c +/init +/init.c +/outofscope +/outofscope.c +/pointer_to_struct +/pointer_to_struct.c +/strings +/strings.c +/type +/type.c +/variable +/variable.c +/whenever +/whenever.c +/whenever_do_continue +/whenever_do_continue.c diff --git a/src/interfaces/ecpg/test/preproc/Makefile b/src/interfaces/ecpg/test/preproc/Makefile new file mode 100644 index 0000000..39b1974 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/Makefile @@ -0,0 +1,33 @@ +subdir = src/interfaces/ecpg/test/preproc +top_builddir = ../../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/$(subdir)/../Makefile.regress + + +TESTS = array_of_struct array_of_struct.c \ + autoprep autoprep.c \ + comment comment.c \ + cursor cursor.c \ + define define.c \ + init init.c \ + strings strings.c \ + outofscope outofscope.c \ + type type.c \ + variable variable.c \ + whenever whenever.c \ + whenever_do_continue whenever_do_continue.c \ + pointer_to_struct pointer_to_struct.c + +all: $(TESTS) + +array_of_struct.c: array_of_struct.pgc $(ECPG_TEST_DEPENDENCIES) + $(ECPG) -c -o $@ $< + +pointer_to_struct.c: pointer_to_struct.pgc $(ECPG_TEST_DEPENDENCIES) + $(ECPG) -c -o $@ $< + +autoprep.c: autoprep.pgc $(ECPG_TEST_DEPENDENCIES) + $(ECPG) -r prepare -o $@ $< + +strings.c: strings.pgc strings.h $(ECPG_TEST_DEPENDENCIES) + $(ECPG) -i -o $@ $< diff --git a/src/interfaces/ecpg/test/preproc/array_of_struct.pgc b/src/interfaces/ecpg/test/preproc/array_of_struct.pgc new file mode 100644 index 0000000..69f5758 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/array_of_struct.pgc @@ -0,0 +1,95 @@ +#include <stdio.h> + +exec sql include ../regression; + +EXEC SQL WHENEVER sqlerror sqlprint; +EXEC SQL WHENEVER sqlwarning sqlprint; +EXEC SQL WHENEVER not found sqlprint; + +EXEC SQL TYPE customer IS + struct + { + varchar name[50]; + int phone; + }; + +EXEC SQL TYPE cust_ind IS + struct ind + { + short name_ind; + short phone_ind; + }; + +int main() +{ + EXEC SQL begin declare section; + customer custs1[10]; + cust_ind inds[10]; + typedef struct + { + varchar name[50]; + int phone; + } customer2; + customer2 custs2[10]; + struct customer3 + { + varchar name[50]; + int phone; + } custs3[10]; + struct customer4 + { + varchar name[50]; + int phone; + } custs4; + int r; + varchar onlyname[2][50]; + EXEC SQL end declare section; + + ECPGdebug(1, stderr); + + EXEC SQL connect to REGRESSDB1; + + EXEC SQL create table customers (c varchar(50), p int); + EXEC SQL insert into customers values ('John Doe', '12345'); + EXEC SQL insert into customers values ('Jane Doe', '67890'); + + EXEC SQL select * INTO :custs1:inds from customers limit 2; + printf("custs1:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", custs1[r].name.arr ); + printf( "phone - %d\n", custs1[r].phone ); + } + + EXEC SQL select * INTO :custs2:inds from customers limit 2; + printf("\ncusts2:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", custs2[r].name.arr ); + printf( "phone - %d\n", custs2[r].phone ); + } + + EXEC SQL select * INTO :custs3:inds from customers limit 2; + printf("\ncusts3:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", custs3[r].name.arr ); + printf( "phone - %d\n", custs3[r].phone ); + } + + EXEC SQL select * INTO :custs4:inds[0] from customers limit 1; + printf("\ncusts4:\n"); + printf( "name - %s\n", custs4.name.arr ); + printf( "phone - %d\n", custs4.phone ); + + EXEC SQL select c INTO :onlyname from customers limit 2; + printf("\nname:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", onlyname[r].arr ); + } + + EXEC SQL disconnect all; + + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/autoprep.pgc b/src/interfaces/ecpg/test/preproc/autoprep.pgc new file mode 100644 index 0000000..d3d9305 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/autoprep.pgc @@ -0,0 +1,72 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* test automatic prepare for all statements */ +EXEC SQL INCLUDE ../regression; + +static void test(void) { + EXEC SQL BEGIN DECLARE SECTION; + int item[4], ind[4], i = 1; + int item1, ind1; + char sqlstr[64] = "SELECT item2 FROM T ORDER BY item2 NULLS LAST"; + EXEC SQL END DECLARE SECTION; + + ECPGdebug(1, stderr); + EXEC SQL CONNECT TO REGRESSDB1; + + EXEC SQL WHENEVER SQLWARNING SQLPRINT; + EXEC SQL WHENEVER SQLERROR SQLPRINT; + + EXEC SQL CREATE TABLE T ( Item1 int, Item2 int ); + + EXEC SQL INSERT INTO T VALUES ( 1, null ); + EXEC SQL INSERT INTO T VALUES ( 1, :i ); + i++; + EXEC SQL INSERT INTO T VALUES ( 1, :i ); + EXEC SQL PREPARE I AS INSERT INTO T VALUES ( 1, 2 ); + EXEC SQL EXECUTE I; + + EXEC SQL SELECT Item2 INTO :item:ind FROM T ORDER BY Item2 NULLS LAST; + + for (i=0; i<4; i++) + printf("item[%d] = %d\n", i, ind[i] ? -1 : item[i]); + + EXEC SQL DECLARE C CURSOR FOR SELECT Item1 FROM T; + + EXEC SQL OPEN C; + + EXEC SQL FETCH 1 IN C INTO :i; + printf("i = %d\n", i); + + EXEC SQL CLOSE C; + + EXEC SQL PREPARE stmt1 FROM :sqlstr; + + EXEC SQL DECLARE cur1 CURSOR FOR stmt1; + + EXEC SQL OPEN cur1; + + EXEC SQL WHENEVER NOT FOUND DO BREAK; + + i = 0; + while (i < 100) + { + EXEC SQL FETCH cur1 INTO :item1:ind1; + printf("item[%d] = %d\n", i, ind1 ? -1 : item1); + i++; + } + + EXEC SQL CLOSE cur1; + + EXEC SQL DROP TABLE T; + + EXEC SQL DISCONNECT ALL; +} + +int main() { + test(); + test(); /* retry */ + + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/comment.pgc b/src/interfaces/ecpg/test/preproc/comment.pgc new file mode 100644 index 0000000..c3ce20c --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/comment.pgc @@ -0,0 +1,21 @@ +#include <stdlib.h> + +exec sql include ../regression; + +/* just a test comment */ int i; +/* just a test comment int j*/; + +/****************************************************************************/ +/* Test comment */ +/*--------------------------------------------------------------------------*/ + +int main(void) +{ + ECPGdebug(1, stderr); + + exec sql --this is a comment too + connect to REGRESSDB1; + + exec sql disconnect; + exit (0); +} diff --git a/src/interfaces/ecpg/test/preproc/cursor.pgc b/src/interfaces/ecpg/test/preproc/cursor.pgc new file mode 100644 index 0000000..8a286ad --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/cursor.pgc @@ -0,0 +1,256 @@ +#include <stdlib.h> +#include <string.h> + +exec sql include ../regression; + +exec sql whenever sqlerror stop; + +exec sql type c is char reference; +typedef char* c; + +exec sql type ind is union { int integer; short smallint; }; +typedef union { int integer; short smallint; } ind; + +#define BUFFERSIZ 8 +exec sql type str is varchar[BUFFERSIZ]; + +#define CURNAME "mycur" + +int +main (void) +{ +exec sql begin declare section; + char *stmt1 = "SELECT id, t FROM t1"; + char *curname1 = CURNAME; + char *curname2 = CURNAME; + char *curname3 = CURNAME; + varchar curname4[50]; + char *curname5 = CURNAME; + int count; + int id; + char t[64]; +exec sql end declare section; + + char msg[128]; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + exec sql connect to REGRESSDB1 as test1; + exec sql connect to REGRESSDB2 as test2; + + strcpy(msg, "set"); + exec sql at test1 set datestyle to iso; + + strcpy(msg, "create"); + exec sql at test1 create table t1(id serial primary key, t text); + exec sql at test2 create table t1(id serial primary key, t text); + + strcpy(msg, "insert"); + exec sql at test1 insert into t1(id, t) values (default, 'a'); + exec sql at test1 insert into t1(id, t) values (default, 'b'); + exec sql at test1 insert into t1(id, t) values (default, 'c'); + exec sql at test1 insert into t1(id, t) values (default, 'd'); + exec sql at test2 insert into t1(id, t) values (default, 'e'); + + strcpy(msg, "commit"); + exec sql at test1 commit; + exec sql at test2 commit; + + /* Dynamic cursorname test with INTO list in FETCH stmts */ + + strcpy(msg, "declare"); + exec sql at test1 declare :curname1 cursor for + select id, t from t1; + + strcpy(msg, "open"); + exec sql at test1 open :curname1; + + strcpy(msg, "fetch from"); + exec sql at test1 fetch forward from :curname1 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch"); + exec sql at test1 fetch forward :curname1 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch 1 from"); + exec sql at test1 fetch 1 from :curname1 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count from"); + count = 1; + exec sql at test1 fetch :count from :curname1 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "move in"); + exec sql at test1 move absolute 0 in :curname1; + + strcpy(msg, "fetch 1"); + exec sql at test1 fetch 1 :curname1 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count"); + count = 1; + exec sql at test1 fetch :count :curname1 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "close"); + exec sql at test1 close :curname1; + + /* Dynamic cursorname test with INTO list in DECLARE stmt */ + + strcpy(msg, "declare"); + exec sql at test1 declare :curname2 cursor for + select id, t into :id, :t from t1; + + strcpy(msg, "open"); + exec sql at test1 open :curname2; + + strcpy(msg, "fetch from"); + exec sql at test1 fetch from :curname2; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch"); + exec sql at test1 fetch :curname2; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch 1 from"); + exec sql at test1 fetch 1 from :curname2; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count from"); + count = 1; + exec sql at test1 fetch :count from :curname2; + printf("%d %s\n", id, t); + + strcpy(msg, "move"); + exec sql at test1 move absolute 0 :curname2; + + strcpy(msg, "fetch 1"); + exec sql at test1 fetch 1 :curname2; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count"); + count = 1; + exec sql at test1 fetch :count :curname2; + printf("%d %s\n", id, t); + + strcpy(msg, "close"); + exec sql at test1 close :curname2; + + /* Dynamic cursorname test with PREPARED stmt */ + + strcpy(msg, "prepare"); + exec sql at test1 prepare st_id1 from :stmt1; + exec sql at test2 prepare st_id1 from :stmt1; + + strcpy(msg, "declare"); + exec sql at test1 declare :curname3 cursor for st_id1; + exec sql at test2 declare :curname5 cursor for st_id1; + + strcpy(msg, "open"); + exec sql at test1 open :curname3; + exec sql at test2 open :curname5; + + strcpy(msg, "fetch"); + exec sql at test2 fetch :curname5 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch from"); + exec sql at test1 fetch from :curname3 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch 1 from"); + exec sql at test1 fetch 1 from :curname3 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count from"); + count = 1; + exec sql at test1 fetch :count from :curname3 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "move"); + exec sql at test1 move absolute 0 :curname3; + + strcpy(msg, "fetch 1"); + exec sql at test1 fetch 1 :curname3 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count"); + count = 1; + exec sql at test1 fetch :count :curname3 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "close"); + exec sql at test1 close :curname3; + exec sql at test2 close :curname5; + + strcpy(msg, "deallocate prepare"); + exec sql at test1 deallocate prepare st_id1; + exec sql at test2 deallocate prepare st_id1; + + /* Dynamic cursorname test with PREPARED stmt, + cursor name in varchar */ + + curname4.len = strlen(CURNAME); + strcpy(curname4.arr, CURNAME); + + strcpy(msg, "prepare"); + exec sql at test1 prepare st_id2 from :stmt1; + + strcpy(msg, "declare"); + exec sql at test1 declare :curname4 cursor for st_id2; + + strcpy(msg, "open"); + exec sql at test1 open :curname4; + + strcpy(msg, "fetch from"); + exec sql at test1 fetch from :curname4 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch"); + exec sql at test1 fetch :curname4 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch 1 from"); + exec sql at test1 fetch 1 from :curname4 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count from"); + count = 1; + exec sql at test1 fetch :count from :curname4 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "move"); + exec sql at test1 move absolute 0 :curname4; + + strcpy(msg, "fetch 1"); + exec sql at test1 fetch 1 :curname4 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "fetch :count"); + count = 1; + exec sql at test1 fetch :count :curname4 into :id, :t; + printf("%d %s\n", id, t); + + strcpy(msg, "close"); + exec sql at test1 close :curname4; + + strcpy(msg, "deallocate prepare"); + exec sql at test1 deallocate prepare st_id2; + + /* End test */ + + strcpy(msg, "drop"); + exec sql at test1 drop table t1; + exec sql at test2 drop table t1; + + strcpy(msg, "commit"); + exec sql at test1 commit; + + strcpy(msg, "disconnect"); + exec sql disconnect all; + + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/define.pgc b/src/interfaces/ecpg/test/preproc/define.pgc new file mode 100644 index 0000000..90dc328 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/define.pgc @@ -0,0 +1,78 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +exec sql include ../regression; + +exec sql whenever sqlerror sqlprint; + +exec sql define AMOUNT 6; +exec sql define NAMELEN 8; + +exec sql type intarray is int[AMOUNT]; +typedef int intarray[AMOUNT]; + +int +main(void) +{ +exec sql begin declare section; + +exec sql ifdef NAMELEN; + typedef char string[NAMELEN]; + intarray amount; + char name[AMOUNT][NAMELEN]; +exec sql elif AMOUNT; + should not get here; +exec sql else; + should not get here either; +exec sql endif; + +exec sql ifndef NAMELEN; + should not get here; +exec sql elif AMOUNT; + exec sql ifdef NOSUCHNAME; + should not get here; + exec sql else; + char letter[AMOUNT][1]; +#if 0 + int not_used; +#endif + exec sql endif; +exec sql elif AMOUNT; + should not get here; +exec sql endif; + +exec sql end declare section; + int i,j; + + ECPGdebug(1, stderr); + + exec sql connect to REGRESSDB1; + + exec sql create table test (name char(NAMELEN), amount int, letter char(1)); + exec sql commit; + + exec sql insert into Test (name, amount, letter) values ('false', 1, 'f'); + exec sql insert into test (name, amount, letter) values ('true', 2, 't'); + exec sql commit; + + exec sql select * into :name, :amount, :letter from test; + + for (i=0, j=sqlca.sqlerrd[2]; i<j; i++) + { + exec sql begin declare section; + string n; + char l = letter[i][0]; + int a = amount[i]; + exec sql end declare section; + + strncpy(n, name[i], NAMELEN); + printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l); + } + + exec sql drop table test; + exec sql commit; + exec sql disconnect; + + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/init.pgc b/src/interfaces/ecpg/test/preproc/init.pgc new file mode 100644 index 0000000..b1f7199 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/init.pgc @@ -0,0 +1,100 @@ +exec sql include sqlca; + +enum e { ENUM0, ENUM1 }; +struct sa { int member; }; + +static int fa(void) +{ + printf("in fa\n"); + return 2; +} + +static int +fb(int x) +{ + printf("in fb (%d)\n", x); + return x; +} + +static int +fc(const char *x) +{ + printf("in fc (%s)\n", x); + return *x; +} + +static int fd(const char *x,int i) +{ + printf("in fd (%s, %d)\n", x, i); + return (*x)*i; +} + +static int fe(enum e x) +{ + printf("in fe (%d)\n", (int) x); + return (int)x; +} + +static void sqlnotice(const char *notice, short trans) +{ + if (!notice) + notice = "-empty-"; + printf("in sqlnotice (%s, %d)\n", notice, trans); +} + +exec sql define NONO 0; + +#define YES 1 + +#ifdef _cplusplus +namespace N +{ + static const int i=2; +}; +#endif + +int main(void) +{ + struct sa x = { 14 },*y = &x; + exec sql begin declare section; + int a=(int)2; + int b=2+2; + int b2=(14*7); + int d=x.member; + int g=fb(2); + int i=3^1; + int j=1?1:2; + + int e=y->member; + int c=10>>2; + bool h=2||1; + long iay /* = 1L */ ; + exec sql end declare section; + + int f=fa(); + +#ifdef _cplusplus + exec sql begin declare section; + int k=N::i; /* compile error */ + exec sql end declare section; +#endif + + ECPGdebug(1, stderr); + + printf("%d %d %d %d %d %d %d %d %d %d %d\n", a, b, b2, c, d, e, f, g, h, i, j); + iay = 0; + printf("%ld\n", iay); + exec sql whenever sqlerror do fa(); + exec sql select now(); + exec sql whenever sqlerror do fb(20); + exec sql select now(); + exec sql whenever sqlerror do fc("50"); + exec sql select now(); + exec sql whenever sqlerror do fd("50",1); + exec sql select now(); + exec sql whenever sqlerror do fe(ENUM0); + exec sql select now(); + exec sql whenever sqlerror do sqlnotice(NULL, NONO); + exec sql select now(); + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/outofscope.pgc b/src/interfaces/ecpg/test/preproc/outofscope.pgc new file mode 100644 index 0000000..ed60782 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/outofscope.pgc @@ -0,0 +1,116 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +exec sql include ../regression; + +exec sql include pgtypes_numeric.h; + +exec sql begin declare section; +exec sql include struct.h; +exec sql end declare section; + +exec sql whenever sqlerror stop; + +/* Functions for test 1 */ + +static void +get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0) +{ + exec sql begin declare section; + MYTYPE *myvar = malloc(sizeof(MYTYPE)); + MYNULLTYPE *mynullvar = malloc(sizeof(MYNULLTYPE)); + exec sql end declare section; + + /* Test DECLARE ... SELECT ... INTO with pointers */ + + exec sql declare mycur cursor for select * INTO :myvar :mynullvar from a1; + + if (sqlca.sqlcode != 0) + exit(1); + + *myvar0 = myvar; + *mynullvar0 = mynullvar; +} + +static void +open_cur1(void) +{ + exec sql open mycur; +} + +static void +get_record1(void) +{ + exec sql fetch mycur; +} + +static void +close_cur1(void) +{ + exec sql close mycur; +} + +int +main (void) +{ + MYTYPE *myvar; + MYNULLTYPE *mynullvar; + int loopcount; + char msg[128]; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + exec sql connect to REGRESSDB1; + + strcpy(msg, "set"); + exec sql set datestyle to iso; + + strcpy(msg, "create"); + exec sql create table a1(id serial primary key, t text, d1 numeric, d2 float8, c character(10)); + + strcpy(msg, "insert"); + exec sql insert into a1(id, t, d1, d2, c) values (default, 'a', 1.0, 2, 'a'); + exec sql insert into a1(id, t, d1, d2, c) values (default, null, null, null, null); + exec sql insert into a1(id, t, d1, d2, c) values (default, 'b', 2.0, 3, 'b'); + + strcpy(msg, "commit"); + exec sql commit; + + /* Test out-of-scope DECLARE/OPEN/FETCH/CLOSE */ + + get_var1(&myvar, &mynullvar); + open_cur1(); + + for (loopcount = 0; loopcount < 100; loopcount++) + { + memset(myvar, 0, sizeof(MYTYPE)); + get_record1(); + if (sqlca.sqlcode == ECPG_NOT_FOUND) + break; + printf("id=%d%s t='%s'%s d1=%f%s d2=%f%s c = '%s'%s\n", + myvar->id, mynullvar->id ? " (NULL)" : "", + myvar->t, mynullvar->t ? " (NULL)" : "", + myvar->d1, mynullvar->d1 ? " (NULL)" : "", + myvar->d2, mynullvar->d2 ? " (NULL)" : "", + myvar->c, mynullvar->c ? " (NULL)" : ""); + } + + close_cur1(); + + free(myvar); + free(mynullvar); + + strcpy(msg, "drop"); + exec sql drop table a1; + + strcpy(msg, "commit"); + exec sql commit; + + strcpy(msg, "disconnect"); + exec sql disconnect; + + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc b/src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc new file mode 100644 index 0000000..1ec651e --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc @@ -0,0 +1,100 @@ +#include <stdio.h> +#include <stdlib.h> + +exec sql include ../regression; + +EXEC SQL WHENEVER sqlerror sqlprint; +EXEC SQL WHENEVER sqlwarning sqlprint; +EXEC SQL WHENEVER not found sqlprint; + +EXEC SQL TYPE customer IS + struct + { + varchar name[50]; + int phone; + }; + +EXEC SQL TYPE cust_ind IS + struct ind + { + short name_ind; + short phone_ind; + }; + +int main() +{ + EXEC SQL begin declare section; + customer *custs1 = (customer *) malloc(sizeof(customer) * 10); + cust_ind *inds = (cust_ind *) malloc(sizeof(cust_ind) * 10); + typedef struct + { + varchar name[50]; + int phone; + } customer2; + customer2 *custs2 = (customer2 *) malloc(sizeof(customer2) * 10); + + struct customer3 + { + char name[50]; + int phone; + } *custs3 = (struct customer3 *) malloc(sizeof(struct customer3) * 10); + + struct customer4 + { + varchar name[50]; + int phone; + } *custs4 = (struct customer4 *) malloc(sizeof(struct customer4)); + + int r; + varchar onlyname[2][50]; + EXEC SQL end declare section; + + ECPGdebug(1, stderr); + + EXEC SQL connect to REGRESSDB1; + + EXEC SQL create table customers (c varchar(50), p int); + EXEC SQL insert into customers values ('John Doe', '12345'); + EXEC SQL insert into customers values ('Jane Doe', '67890'); + + EXEC SQL select * INTO :custs1:inds from customers limit 2; + printf("custs1:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", custs1[r].name.arr ); + printf( "phone - %d\n", custs1[r].phone ); + } + + EXEC SQL select * INTO :custs2:inds from customers limit 2; + printf("\ncusts2:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", custs2[r].name.arr ); + printf( "phone - %d\n", custs2[r].phone ); + } + + EXEC SQL select * INTO :custs3:inds from customers limit 2; + printf("\ncusts3:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", custs3[r].name ); + printf( "phone - %d\n", custs3[r].phone ); + } + + EXEC SQL select * INTO :custs4:inds from customers limit 1; + printf("\ncusts4:\n"); + printf( "name - %s\n", custs4->name.arr ); + printf( "phone - %d\n", custs4->phone ); + + EXEC SQL select c INTO :onlyname from customers limit 2; + printf("\nname:\n"); + for (r = 0; r < 2; r++) + { + printf( "name - %s\n", onlyname[r].arr ); + } + + EXEC SQL disconnect all; + + /* All the memory will anyway be freed at the end */ + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/strings.h b/src/interfaces/ecpg/test/preproc/strings.h new file mode 100644 index 0000000..edb5be5 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/strings.h @@ -0,0 +1,8 @@ +char *s1, + *s2, + *s3, + *s4, + *s5, + *s6, + *s7, + *s8; diff --git a/src/interfaces/ecpg/test/preproc/strings.pgc b/src/interfaces/ecpg/test/preproc/strings.pgc new file mode 100644 index 0000000..f3b253e --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/strings.pgc @@ -0,0 +1,32 @@ +#include <../regression.h> + +exec sql begin declare section; +#include <strings.h> +exec sql end declare section; + +int main(void) +{ + ECPGdebug(1, stderr); + + exec sql connect to REGRESSDB1; + + exec sql set standard_conforming_strings to on; + + exec sql select 'abc''d\ef', + N'abc''d\ef' AS foo, + E'abc''d\\ef' AS "foo""bar", + U&'d\0061t\0061' AS U&"foo""bar", + U&'d!+000061t!+000061' uescape '!', + $foo$abc$def$foo$ + into :s1, :s2, :s3, :s4, :s5, :s6; + + printf("%s %s %s %s %s %s\n", s1, s2, s3, s4, s5, s6); + + exec sql select b'0010', X'019ABcd' + into :s7, :s8; + + printf("%s %s\n", s7, s8); + + exec sql disconnect; + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/struct.h b/src/interfaces/ecpg/test/preproc/struct.h new file mode 100644 index 0000000..19da316 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/struct.h @@ -0,0 +1,19 @@ +struct mytype +{ + int id; + char t[64]; + double d1; /* dec_t */ + double d2; + char c[30]; +}; +typedef struct mytype MYTYPE; + +struct mynulltype +{ + int id; + int t; + int d1; + int d2; + int c; +}; +typedef struct mynulltype MYNULLTYPE; diff --git a/src/interfaces/ecpg/test/preproc/type.pgc b/src/interfaces/ecpg/test/preproc/type.pgc new file mode 100644 index 0000000..3200c91 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/type.pgc @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <stdlib.h> + +EXEC SQL include ../regression; + +EXEC SQL typedef long mmInteger; +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; + +EXEC SQL BEGIN DECLARE SECTION; +struct TBempl +{ + mmInteger idnum; + mmChar name[21]; + mmSmallInt accs; +}; +EXEC SQL END DECLARE SECTION; + +int +main (void) +{ + EXEC SQL BEGIN DECLARE SECTION; + struct TBempl empl; + string str; + c ptr = NULL; + struct varchar + { + int len; + char text[10]; + } vc; + EXEC SQL END DECLARE SECTION; + + EXEC SQL var vc is varchar[10]; + ECPGdebug (1, stderr); + + empl.idnum = 1; + EXEC SQL connect to REGRESSDB1; + if (sqlca.sqlcode) + { + printf ("connect error = %ld\n", sqlca.sqlcode); + exit (sqlca.sqlcode); + } + + EXEC SQL create table empl + (idnum integer, name char(20), accs smallint, string1 char(10), string2 char(10), string3 char(10)); + if (sqlca.sqlcode) + { + printf ("create error = %ld\n", sqlca.sqlcode); + exit (sqlca.sqlcode); + } + + EXEC SQL insert into empl values (1, 'user name', 320, 'first str', 'second str', 'third str'); + if (sqlca.sqlcode) + { + printf ("insert error = %ld\n", sqlca.sqlcode); + exit (sqlca.sqlcode); + } + + EXEC SQL select idnum, name, accs, string1, string2, string3 + into :empl, :str, :ptr, :vc + from empl + where idnum =:empl.idnum; + if (sqlca.sqlcode) + { + printf ("select error = %ld\n", sqlca.sqlcode); + exit (sqlca.sqlcode); + } + 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); + + EXEC SQL disconnect; + + free(ptr); + exit (0); +} diff --git a/src/interfaces/ecpg/test/preproc/variable.pgc b/src/interfaces/ecpg/test/preproc/variable.pgc new file mode 100644 index 0000000..423a01c --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/variable.pgc @@ -0,0 +1,101 @@ +#include <stdlib.h> +#include <string.h> + +exec sql include ../regression; + +exec sql whenever sqlerror stop; + +exec sql type c is char reference; +typedef char* c; + +exec sql type ind is union { int integer; short smallint; }; +typedef union { int integer; short smallint; } ind; + +#define BUFFERSIZ 8 +exec sql type str is varchar[BUFFERSIZ]; + +exec sql declare cur cursor for + select name, born, age, married, children from family; + +int +main (void) +{ + exec sql struct birthinfo { long born; short age; }; +exec sql begin declare section; + struct personal_struct { str name; + struct birthinfo birth; + } personal, *p; + struct personal_indicator { int ind_name; + struct birthinfo ind_birth; + } ind_personal, *i; + ind ind_children; + struct t1 { str name; }; struct t2 { str name; }; +exec sql end declare section; + + exec sql char *married = NULL; + exec sql long ind_married; + exec sql ind children; + int loopcount; + char msg[128]; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + exec sql connect to REGRESSDB1; + + strcpy(msg, "set"); + exec sql set datestyle to iso; + + strcpy(msg, "create"); + exec sql create table family(name char(8), born integer, age smallint, married date, children integer); + + strcpy(msg, "insert"); + exec sql insert into family(name, married, children) values ('Mum', '19870714', 3); + exec sql insert into family(name, born, married, children) values ('Dad', '19610721', '19870714', 3); + exec sql insert into family(name, age) values ('Child 1', 16); + exec sql insert into family(name, age) values ('Child 2', 14); + exec sql insert into family(name, age) values ('Child 3', 9); + + strcpy(msg, "commit"); + exec sql commit; + + strcpy(msg, "open"); + exec sql open cur; + + exec sql whenever not found do break; + + p=&personal; + i=&ind_personal; + memset(i, 0, sizeof(ind_personal)); + for (loopcount = 0; loopcount < 100; loopcount++) { + strcpy(msg, "fetch"); + exec sql fetch cur into :p:i, :married:ind_married, :children.integer:ind_children.smallint; + printf("%8.8s", personal.name.arr); + if (i->ind_birth.born >= 0) + printf(", born %ld", personal.birth.born); + if (i->ind_birth.age >= 0) + printf(", age = %d", personal.birth.age); + if (ind_married >= 0) + printf(", married %s", married); + if (ind_children.smallint >= 0) + printf(", children = %d", children.integer); + putchar('\n'); + + free(married); + married = NULL; + } + + strcpy(msg, "close"); + exec sql close cur; + + strcpy(msg, "drop"); + exec sql drop table family; + + strcpy(msg, "commit"); + exec sql commit; + + strcpy(msg, "disconnect"); + exec sql disconnect; + + return 0; +} diff --git a/src/interfaces/ecpg/test/preproc/whenever.pgc b/src/interfaces/ecpg/test/preproc/whenever.pgc new file mode 100644 index 0000000..6090e5f --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/whenever.pgc @@ -0,0 +1,67 @@ +#include <stdlib.h> + +exec sql include ../regression; + +exec sql whenever sqlerror sqlprint; + +static void print(const char *msg) +{ + fprintf(stderr, "Error in statement '%s':\n", msg); + sqlprint(); +} + +static void print2(void) +{ + fprintf(stderr, "Found another error\n"); + sqlprint(); +} + +static void warn(void) +{ + fprintf(stderr, "Warning: At least one column was truncated\n"); +} + +int main(void) +{ + exec sql int i; + exec sql char c[6]; + + ECPGdebug(1, stderr); + + exec sql connect to REGRESSDB1; + exec sql create table test(i int, c char(10)); + exec sql insert into test values(1, 'abcdefghij'); + + exec sql whenever sqlwarning do warn(); + exec sql select * into :i, :c from test; + exec sql rollback; + + exec sql select * into :i from nonexistent; + exec sql rollback; + + exec sql whenever sqlerror do print("select"); + exec sql select * into :i from nonexistent; + exec sql rollback; + + exec sql whenever sqlerror call print2(); + exec sql select * into :i from nonexistent; + exec sql rollback; + + exec sql whenever sqlerror continue; + exec sql select * into :i from nonexistent; + exec sql rollback; + + exec sql whenever sqlerror goto error; + exec sql select * into :i from nonexistent; + printf("Should not be reachable\n"); + + error: + exec sql rollback; + + exec sql whenever sqlerror stop; + /* This cannot fail, thus we don't get an exit value not equal 0. */ + /* However, it still test the precompiler output. */ + exec sql select 1 into :i; + exec sql rollback; + exit (0); +} diff --git a/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc b/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc new file mode 100644 index 0000000..025ac12 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc @@ -0,0 +1,63 @@ +#include <stdlib.h> + +exec sql include ../regression; + +exec sql whenever sqlerror stop; + +int main(void) +{ + exec sql begin declare section; + struct + { + char ename[12]; + float sal; + float comm; + } emp; + int loopcount; + char msg[128]; + exec sql end declare section; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + exec sql connect to REGRESSDB1; + + strcpy(msg, "create"); + exec sql create table emp(ename varchar,sal double precision, comm double precision); + + strcpy(msg, "insert"); + exec sql insert into emp values ('Ram',111100,21); + exec sql insert into emp values ('aryan',11110,null); + exec sql insert into emp values ('josh',10000,10); + exec sql insert into emp values ('tom',20000,null); + + exec sql declare c cursor for select ename, sal, comm from emp order by ename collate "C" asc; + + exec sql open c; + + /* The 'BREAK' condition to exit the loop. */ + exec sql whenever not found do break; + + /* The DO CONTINUE makes the loop start at the next iteration when an error occurs.*/ + exec sql whenever sqlerror do continue; + + for (loopcount = 0; loopcount < 100; loopcount++) + { + exec sql fetch c into :emp; + /* The employees with non-NULL commissions will be displayed. */ + printf("%s %7.2f %9.2f\n", emp.ename, emp.sal, emp.comm); + } + + /* + * This 'CONTINUE' shuts off the 'DO CONTINUE' and allow the program to + * proceed if any further errors do occur. + */ + exec sql whenever sqlerror continue; + + exec sql close c; + + strcpy(msg, "drop"); + exec sql drop table emp; + + exit(0); +} |