summaryrefslogtreecommitdiffstats
path: root/src/interfaces/ecpg/test/preproc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:15:05 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:15:05 +0000
commit46651ce6fe013220ed397add242004d764fc0153 (patch)
tree6e5299f990f88e60174a1d3ae6e48eedd2688b2b /src/interfaces/ecpg/test/preproc
parentInitial commit. (diff)
downloadpostgresql-14-upstream.tar.xz
postgresql-14-upstream.zip
Adding upstream version 14.5.upstream/14.5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/interfaces/ecpg/test/preproc/.gitignore26
-rw-r--r--src/interfaces/ecpg/test/preproc/Makefile33
-rw-r--r--src/interfaces/ecpg/test/preproc/array_of_struct.pgc95
-rw-r--r--src/interfaces/ecpg/test/preproc/autoprep.pgc72
-rw-r--r--src/interfaces/ecpg/test/preproc/comment.pgc21
-rw-r--r--src/interfaces/ecpg/test/preproc/cursor.pgc256
-rw-r--r--src/interfaces/ecpg/test/preproc/define.pgc78
-rw-r--r--src/interfaces/ecpg/test/preproc/init.pgc100
-rw-r--r--src/interfaces/ecpg/test/preproc/outofscope.pgc116
-rw-r--r--src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc100
-rw-r--r--src/interfaces/ecpg/test/preproc/strings.h8
-rw-r--r--src/interfaces/ecpg/test/preproc/strings.pgc32
-rw-r--r--src/interfaces/ecpg/test/preproc/struct.h19
-rw-r--r--src/interfaces/ecpg/test/preproc/type.pgc80
-rw-r--r--src/interfaces/ecpg/test/preproc/variable.pgc101
-rw-r--r--src/interfaces/ecpg/test/preproc/whenever.pgc67
-rw-r--r--src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc63
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);
+}