summaryrefslogtreecommitdiffstats
path: root/src/interfaces/ecpg/test/sql
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/sql
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 'src/interfaces/ecpg/test/sql')
-rw-r--r--src/interfaces/ecpg/test/sql/.gitignore50
-rw-r--r--src/interfaces/ecpg/test/sql/Makefile36
-rw-r--r--src/interfaces/ecpg/test/sql/array.pgc111
-rw-r--r--src/interfaces/ecpg/test/sql/binary.pgc70
-rw-r--r--src/interfaces/ecpg/test/sql/bytea.pgc120
-rw-r--r--src/interfaces/ecpg/test/sql/code100.pgc52
-rw-r--r--src/interfaces/ecpg/test/sql/copystdout.pgc25
-rw-r--r--src/interfaces/ecpg/test/sql/createtableas.pgc41
-rw-r--r--src/interfaces/ecpg/test/sql/declare.pgc212
-rw-r--r--src/interfaces/ecpg/test/sql/define.pgc58
-rw-r--r--src/interfaces/ecpg/test/sql/desc.pgc89
-rw-r--r--src/interfaces/ecpg/test/sql/describe.pgc199
-rw-r--r--src/interfaces/ecpg/test/sql/dynalloc.pgc89
-rw-r--r--src/interfaces/ecpg/test/sql/dynalloc2.pgc55
-rw-r--r--src/interfaces/ecpg/test/sql/dyntest.pgc199
-rw-r--r--src/interfaces/ecpg/test/sql/execute.pgc113
-rw-r--r--src/interfaces/ecpg/test/sql/fetch.pgc58
-rw-r--r--src/interfaces/ecpg/test/sql/func.pgc47
-rw-r--r--src/interfaces/ecpg/test/sql/indicators.pgc50
-rw-r--r--src/interfaces/ecpg/test/sql/insupd.pgc36
-rw-r--r--src/interfaces/ecpg/test/sql/oldexec.pgc90
-rw-r--r--src/interfaces/ecpg/test/sql/parser.pgc39
-rw-r--r--src/interfaces/ecpg/test/sql/prepareas.pgc198
-rw-r--r--src/interfaces/ecpg/test/sql/quote.pgc61
-rw-r--r--src/interfaces/ecpg/test/sql/show.pgc41
-rw-r--r--src/interfaces/ecpg/test/sql/sqlda.pgc266
-rw-r--r--src/interfaces/ecpg/test/sql/twophase.pgc44
27 files changed, 2449 insertions, 0 deletions
diff --git a/src/interfaces/ecpg/test/sql/.gitignore b/src/interfaces/ecpg/test/sql/.gitignore
new file mode 100644
index 0000000..d3aaa62
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/.gitignore
@@ -0,0 +1,50 @@
+/array
+/array.c
+/binary
+/binary.c
+/bytea
+/bytea.c
+/code100
+/code100.c
+/copystdout
+/copystdout.c
+/createtableas
+/createtableas.c
+/declare
+/declare.c
+/define
+/define.c
+/desc
+/desc.c
+/describe
+/describe.c
+/dynalloc
+/dynalloc.c
+/dynalloc2
+/dynalloc2.c
+/dyntest
+/dyntest.c
+/execute
+/execute.c
+/fetch
+/fetch.c
+/func
+/func.c
+/indicators
+/indicators.c
+/insupd
+/insupd.c
+/oldexec
+/oldexec.c
+/parser
+/parser.c
+/prepareas
+/prepareas.c
+/quote
+/quote.c
+/show
+/show.c
+/sqlda
+/sqlda.c
+/twophase
+/twophase.c
diff --git a/src/interfaces/ecpg/test/sql/Makefile b/src/interfaces/ecpg/test/sql/Makefile
new file mode 100644
index 0000000..876ca8d
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/Makefile
@@ -0,0 +1,36 @@
+subdir = src/interfaces/ecpg/test/sql
+top_builddir = ../../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/$(subdir)/../Makefile.regress
+
+TESTS = array array.c \
+ binary binary.c \
+ code100 code100.c \
+ copystdout copystdout.c \
+ createtableas createtableas.c \
+ define define.c \
+ desc desc.c \
+ sqlda sqlda.c \
+ describe describe.c \
+ dyntest dyntest.c \
+ dynalloc dynalloc.c \
+ dynalloc2 dynalloc2.c \
+ execute execute.c \
+ fetch fetch.c \
+ func func.c \
+ indicators indicators.c \
+ oldexec oldexec.c \
+ parser parser.c \
+ quote quote.c \
+ show show.c \
+ insupd insupd.c \
+ twophase twophase.c \
+ insupd insupd.c \
+ declare declare.c \
+ bytea bytea.c \
+ prepareas prepareas.c
+
+all: $(TESTS)
+
+oldexec.c: oldexec.pgc $(ECPG_TEST_DEPENDENCIES)
+ $(ECPG) -r questionmarks -o $@ $<
diff --git a/src/interfaces/ecpg/test/sql/array.pgc b/src/interfaces/ecpg/test/sql/array.pgc
new file mode 100644
index 0000000..8ca9992
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/array.pgc
@@ -0,0 +1,111 @@
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <pgtypes_date.h>
+#include <pgtypes_interval.h>
+#include <pgtypes_numeric.h>
+#include <pgtypes_timestamp.h>
+
+exec sql whenever sqlerror sqlprint;
+
+exec sql include sqlca;
+exec sql include ../regression;
+
+int
+main (void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ int i = 1, j;
+ int *did = &i;
+ short a[10] = {9,8,7,6,5,4,3,2,1,0};
+ timestamp ts[10];
+ date d[10];
+ interval in[10];
+ numeric n[10];
+ char text[25] = "klmnopqrst";
+ char *t = (char *)malloc(11);
+ double f;
+EXEC SQL END DECLARE SECTION;
+
+ strcpy(t, "0123456789");
+ setlocale(LC_ALL, "C");
+
+ ECPGdebug(1, stderr);
+
+ for (j = 0; j < 10; j++) {
+ char str[28];
+ numeric *value;
+ interval *inter;
+
+ sprintf(str, "2000-1-1 0%d:00:00", j);
+ ts[j] = PGTYPEStimestamp_from_asc(str, NULL);
+ sprintf(str, "2000-1-1%d\n", j);
+ d[j] = PGTYPESdate_from_asc(str, NULL);
+ sprintf(str, "%d hours", j+10);
+ inter = PGTYPESinterval_from_asc(str, NULL);
+ in[j] = *inter;
+ value = PGTYPESnumeric_new();
+ PGTYPESnumeric_from_int(j, value);
+ n[j] = *value;
+ }
+
+ EXEC SQL CONNECT TO REGRESSDB1;
+
+ EXEC SQL SET AUTOCOMMIT = ON;
+
+ EXEC SQL BEGIN WORK;
+
+ EXEC SQL CREATE TABLE test (f float, i int, a int[10], text char(10), ts timestamp[10], n numeric[10], d date[10], inter interval[10]);
+
+ EXEC SQL INSERT INTO test(f,i,a,text,ts,n,d,inter) VALUES(404.90,3,'{0,1,2,3,4,5,6,7,8,9}','abcdefghij',:ts,:n,:d,:in);
+
+ EXEC SQL INSERT INTO test(f,i,a,text,ts,n,d,inter) VALUES(140787.0,2,:a,:text,:ts,:n,:d,:in);
+
+ EXEC SQL INSERT INTO test(f,i,a,text,ts,n,d,inter) VALUES(14.07,:did,:a,:t,:ts,:n,:d,:in);
+
+ EXEC SQL COMMIT;
+
+ for (j = 0; j < 10; j++) {
+ ts[j] = PGTYPEStimestamp_from_asc("1900-01-01 00:00:00", NULL);
+ d[j] = PGTYPESdate_from_asc("1900-01-01", NULL);
+ in[j] = *PGTYPESinterval_new();
+ n[j] = *PGTYPESnumeric_new();
+ }
+ EXEC SQL BEGIN WORK;
+
+ EXEC SQL SELECT f,text
+ INTO :f,:text
+ FROM test
+ WHERE i = 1;
+
+ printf("Found f=%f text=%10.10s\n", f, text);
+
+ f=140787;
+ EXEC SQL SELECT a,text,ts,n,d,inter
+ INTO :a,:t,:ts,:n,:d,:in
+ FROM test
+ WHERE f = :f;
+
+ for (i = 0; i < 10; i++)
+ printf("Found a[%d] = %d ts[%d] = %s n[%d] = %s d[%d] = %s in[%d] = %s\n", i, a[i], i, PGTYPEStimestamp_to_asc(ts[i]), i, PGTYPESnumeric_to_asc(&(n[i]), -1), i, PGTYPESdate_to_asc(d[i]), i, PGTYPESinterval_to_asc(&(in[i])));
+
+ printf("Found text=%10.10s\n", t);
+
+ EXEC SQL SELECT a
+ INTO :text
+ FROM test
+ WHERE f = :f;
+
+ printf("Found text=%s\n", text);
+
+ EXEC SQL DROP TABLE test;
+
+ EXEC SQL COMMIT;
+
+ EXEC SQL DISCONNECT;
+
+ free(t);
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/binary.pgc b/src/interfaces/ecpg/test/sql/binary.pgc
new file mode 100644
index 0000000..1f6abd1
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/binary.pgc
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+EXEC SQL include ../regression;
+
+EXEC SQL BEGIN DECLARE SECTION;
+struct TBempl
+{
+ long idnum;
+ char name[21];
+ short accs;
+ char byte[20];
+};
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL WHENEVER SQLERROR STOP;
+
+int
+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;
+
+ ECPGdebug (1, stderr);
+
+ empl.idnum = 1;
+ EXEC SQL connect to REGRESSDB1;
+ EXEC SQL set bytea_output = escape;
+ EXEC SQL create table empl
+ (idnum integer, name char (20), accs smallint, byte bytea);
+ EXEC SQL insert into empl values (1, 'first user', 320, :data);
+ EXEC SQL DECLARE C CURSOR FOR select name, accs, byte from empl where idnum =:empl.idnum;
+ EXEC SQL OPEN C;
+ EXEC SQL FETCH C INTO:empl.name,:empl.accs,:empl.byte;
+ printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte);
+
+ EXEC SQL CLOSE C;
+
+ memset(empl.name, 0, 21L);
+ 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;
+ EXEC SQL CLOSE B;
+
+ /* do not print a.accs because big/little endian will have different outputs here */
+ printf ("name=%s, byte=", empl.name);
+ 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;
+ EXEC SQL CLOSE A;
+
+ if (pointer) {
+ printf ("pointer=");
+ for (i=0; i<4; i++)
+ printf("(%o)", (unsigned char)pointer[i]);
+ printf("\n");
+ free(pointer);
+ }
+
+ EXEC SQL disconnect;
+ exit (0);
+}
diff --git a/src/interfaces/ecpg/test/sql/bytea.pgc b/src/interfaces/ecpg/test/sql/bytea.pgc
new file mode 100644
index 0000000..e874123
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/bytea.pgc
@@ -0,0 +1,120 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+exec sql include ../regression;
+exec sql whenever sqlerror sqlprint;
+
+static void
+dump_binary(char *buf, int len, int ind)
+{
+ int i;
+
+ printf("len=%d, ind=%d, data=0x", len, ind);
+ for (i = 0; i < len; ++i)
+ printf("%02x", 0xff & buf[i]);
+ printf("\n");
+}
+
+#define DATA_SIZE 0x200
+#define LACK_SIZE 13
+#
+int
+main(void)
+{
+exec sql begin declare section;
+ bytea send_buf[2][512];
+ bytea recv_buf[2][DATA_SIZE];
+ bytea recv_vlen_buf[][DATA_SIZE];
+ bytea recv_short_buf[DATA_SIZE - LACK_SIZE];
+ int ind[2];
+exec sql end declare section;
+ int i, j, c;
+
+#define init() { \
+ for (i = 0; i < 2; ++i) \
+ { \
+ memset(recv_buf[i].arr, 0x0, sizeof(recv_buf[i].arr)); \
+ recv_buf[i].len = 0; \
+ ind[i] = 0; \
+ } \
+ recv_vlen_buf = NULL, \
+ memset(recv_short_buf.arr, 0x0, sizeof(recv_short_buf.arr)); \
+} \
+while (0)
+
+ ECPGdebug(1, stderr);
+
+ for (i = 0; i < 2; ++i)
+ {
+ for (j = 0, c = 0xff; (c == -1 ? c = 0xff : 1), j < DATA_SIZE; ++j, --c)
+ send_buf[i].arr[j] = c;
+
+ send_buf[i].len = DATA_SIZE;
+ }
+
+ exec sql connect to REGRESSDB1;
+
+ exec sql create table if not exists test (data1 bytea, data2 bytea);
+
+ exec sql prepare ins_stmt from "insert into test values(?,?)";
+ exec sql prepare sel_stmt from "select data1,data2 from test";
+ exec sql allocate descriptor idesc;
+ exec sql allocate descriptor odesc;
+
+ /* Test for static sql statement with normal host variable, indicator */
+ init();
+ exec sql truncate test;
+ exec sql insert into test values(:send_buf[0], :send_buf[1]);
+ exec sql select data1,data2 into :recv_buf[0]:ind[0], :recv_short_buf:ind[1] from test;
+ dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]);
+ dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]);
+
+ /* Test for cursor */
+ init();
+ exec sql truncate test;
+ exec sql insert into test values(:send_buf[0], :send_buf[1]);
+ exec sql declare cursor1 cursor for select data1 from test where data1 = :send_buf[0];
+ exec sql open cursor1;
+ exec sql fetch from cursor1 INTO :recv_buf[0];
+ exec sql close cursor1;
+ exec sql free cursor1 ;
+ dump_binary(recv_buf[0].arr, recv_buf[0].len, 0);
+
+ /* Test for variable length array */
+ init();
+ exec sql truncate test;
+ exec sql insert into test values(:send_buf[0], :send_buf[1]);
+ exec sql insert into test values(:send_buf[0], :send_buf[1]);
+ exec sql select data1 into :recv_vlen_buf from test;
+ dump_binary(recv_vlen_buf[0].arr, recv_vlen_buf[0].len, 0);
+ dump_binary(recv_vlen_buf[1].arr, recv_vlen_buf[1].len, 0);
+ free(recv_vlen_buf);
+
+ /* Test for dynamic sql statement with normal host variable, indicator */
+ init();
+ exec sql truncate test;
+ exec sql execute ins_stmt using :send_buf[0], :send_buf[1];
+ exec sql execute sel_stmt into :recv_buf[0]:ind[0], :recv_short_buf:ind[1];
+ dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]);
+ dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]);
+
+ /* Test for dynamic sql statement with sql descriptor */
+ init();
+ exec sql truncate test;
+ exec sql set descriptor idesc value 1 data = :send_buf[0];
+ exec sql set descriptor idesc value 2 data = :send_buf[1];
+ exec sql execute ins_stmt using sql descriptor idesc;
+ exec sql execute sel_stmt into sql descriptor odesc;
+ exec sql get descriptor odesc value 1 :recv_buf[0] = data, :ind[0] = indicator;
+ exec sql get descriptor odesc value 2 :recv_short_buf = data, :ind[1] = indicator;
+ dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]);
+ dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]);
+
+ exec sql drop table test;
+ exec sql commit;
+ exec sql disconnect;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/code100.pgc b/src/interfaces/ecpg/test/sql/code100.pgc
new file mode 100644
index 0000000..d9a5e52
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/code100.pgc
@@ -0,0 +1,52 @@
+exec sql include sqlca;
+#include <stdio.h>
+
+exec sql include ../regression;
+
+
+int main()
+{ exec sql begin declare section;
+ int index;
+ exec sql end declare section;
+
+
+ ECPGdebug(1,stderr);
+
+ exec sql connect to REGRESSDB1;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql create table test (
+ "index" numeric(3) primary key,
+ "payload" int4 NOT NULL);
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ for (index=0;index<10;++index)
+ { exec sql insert into test
+ (payload, index)
+ values (0, :index);
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ }
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql update test
+ set payload=payload+1 where index=-1;
+ if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql delete from test where index=-1;
+ if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql insert into test (select * from test where index=-1);
+ if (sqlca.sqlcode!=100) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql drop table test;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ exec sql commit work;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+
+ exec sql disconnect;
+ if (sqlca.sqlcode) printf("%ld:%s\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/copystdout.pgc b/src/interfaces/ecpg/test/sql/copystdout.pgc
new file mode 100644
index 0000000..9ecce7d
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/copystdout.pgc
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+EXEC SQL INCLUDE sqlca;
+exec sql include ../regression;
+
+EXEC SQL WHENEVER SQLERROR sqlprint;
+
+int
+main ()
+{
+ ECPGdebug (1, stderr);
+
+ EXEC SQL CONNECT TO REGRESSDB1;
+ EXEC SQL CREATE TABLE foo (a int, b varchar);
+ EXEC SQL INSERT INTO foo VALUES (5, 'abc');
+ EXEC SQL INSERT INTO foo VALUES (6, 'def');
+ EXEC SQL INSERT INTO foo VALUES (7, 'ghi');
+
+ EXEC SQL COPY foo TO STDOUT WITH DELIMITER ',';
+ printf ("copy to STDOUT : sqlca.sqlcode = %ld\n", sqlca.sqlcode);
+
+ EXEC SQL DISCONNECT;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/createtableas.pgc b/src/interfaces/ecpg/test/sql/createtableas.pgc
new file mode 100644
index 0000000..72f7077
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/createtableas.pgc
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+exec sql include ../regression;
+
+exec sql whenever sqlerror sqlprint;
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int id;
+ EXEC SQL END DECLARE SECTION;
+
+ ECPGdebug(1, stderr);
+ EXEC SQL connect to REGRESSDB1;
+
+ EXEC SQL SET AUTOCOMMIT TO ON;
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+ EXEC SQL CREATE TABLE cta_test (id int);
+ EXEC SQL INSERT INTO cta_test values (100);
+
+ EXEC SQL CREATE TABLE IF NOT EXISTS cta_test1 AS SELECT * FROM cta_test;
+ EXEC SQL SELECT id INTO :id FROM cta_test1;
+ printf("ID = %d\n", id);
+
+ EXEC SQL CREATE TABLE cta_test2 AS SELECT * FROM cta_test WITH NO DATA;
+ EXEC SQL SELECT count(id) INTO :id FROM cta_test2;
+ printf("ID = %d\n", id);
+
+ EXEC SQL DROP TABLE cta_test;
+ EXEC SQL DROP TABLE cta_test1;
+ EXEC SQL DROP TABLE cta_test2;
+ EXEC SQL DISCONNECT all;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/declare.pgc b/src/interfaces/ecpg/test/sql/declare.pgc
new file mode 100644
index 0000000..e7ee4aa
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/declare.pgc
@@ -0,0 +1,212 @@
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+
+EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+EXEC SQL INCLUDE sqlca;
+EXEC SQL INCLUDE ../regression;
+
+#define ARRAY_SIZE 2
+
+void execute_test(void);
+void commitTable(void);
+void reset(void);
+void printResult(char *tc_name, int loop);
+
+EXEC SQL BEGIN DECLARE SECTION;
+int f1[ARRAY_SIZE];
+int f2[ARRAY_SIZE];
+char f3[ARRAY_SIZE][20];
+EXEC SQL END DECLARE SECTION;
+
+int main(void)
+{
+ setlocale(LC_ALL, "C");
+
+ ECPGdebug(1, stderr);
+
+ EXEC SQL CONNECT TO REGRESSDB1 AS con1;
+ EXEC SQL CONNECT TO REGRESSDB2 AS con2;
+
+ EXEC SQL AT con1 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20));
+ EXEC SQL AT con2 CREATE TABLE source(f1 integer, f2 integer, f3 varchar(20));
+
+ EXEC SQL AT con1 INSERT INTO source VALUES(1, 10, 'db on con1');
+ EXEC SQL AT con1 INSERT INTO source VALUES(2, 20, 'db on con1');
+
+ EXEC SQL AT con2 INSERT INTO source VALUES(1, 10, 'db on con2');
+ EXEC SQL AT con2 INSERT INTO source VALUES(2, 20, 'db on con2');
+
+ commitTable();
+
+ execute_test();
+
+ EXEC SQL AT con1 DROP TABLE IF EXISTS source;
+ EXEC SQL AT con2 DROP TABLE IF EXISTS source;
+
+ commitTable();
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
+
+/*
+ * default connection: con2
+ * Non-default connection: con1
+ *
+ */
+void execute_test(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int i, count, length;
+ char *selectString = "SELECT f1,f2,f3 FROM source";
+ EXEC SQL END DECLARE SECTION;
+
+ /*
+ * testcase1. using DECLARE STATEMENT without using AT clause,
+ * using PREPARE and CURSOR statement without using AT clause
+ */
+ reset();
+
+ EXEC SQL DECLARE stmt_1 STATEMENT;
+ EXEC SQL PREPARE stmt_1 FROM :selectString;
+ EXEC SQL DECLARE cur_1 CURSOR FOR stmt_1;
+ EXEC SQL OPEN cur_1;
+
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+ i = 0;
+ while (1)
+ {
+ EXEC SQL FETCH cur_1 INTO :f1[i], :f2[i], :f3[i];
+ i++;
+ }
+ EXEC SQL CLOSE cur_1;
+ EXEC SQL DEALLOCATE PREPARE stmt_1;
+ EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+ printResult("testcase1", 2);
+
+
+ /*
+ * testcase2. using DECLARE STATEMENT at con1,
+ * using PREPARE and CURSOR statement without using AT clause
+ */
+ reset();
+
+ EXEC SQL AT con1 DECLARE stmt_2 STATEMENT;
+ EXEC SQL PREPARE stmt_2 FROM :selectString;
+ EXEC SQL DECLARE cur_2 CURSOR FOR stmt_2;
+ EXEC SQL OPEN cur_2;
+
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+ i = 0;
+ while (1)
+ {
+ EXEC SQL FETCH cur_2 INTO :f1[i], :f2[i], :f3[i];
+ i++;
+ }
+ EXEC SQL CLOSE cur_2;
+ EXEC SQL DEALLOCATE PREPARE stmt_2;
+ EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+ printResult("testcase2", 2);
+
+ /*
+ * testcase3. using DECLARE STATEMENT without using AT clause,
+ * using PREPARE and EXECUTE statement without using AT clause
+ */
+ reset();
+
+ EXEC SQL DECLARE stmt_3 STATEMENT;
+ EXEC SQL PREPARE stmt_3 FROM :selectString;
+ EXEC SQL EXECUTE stmt_3 INTO :f1, :f2, :f3;
+
+ EXEC SQL DEALLOCATE PREPARE stmt_3;
+
+ printResult("testcase3", 2);
+
+ /*
+ * testcase4. using DECLARE STATEMENT without using AT clause,
+ * using PREPARE and CURSOR statement at con2
+ */
+ reset();
+
+ EXEC SQL DECLARE stmt_4 STATEMENT;
+ EXEC SQL AT con2 PREPARE stmt_4 FROM :selectString;
+ EXEC SQL AT con2 DECLARE cur_4 CURSOR FOR stmt_4;
+ EXEC SQL AT con2 OPEN cur_4;
+
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+ i = 0;
+ while (1)
+ {
+ EXEC SQL AT con2 FETCH cur_4 INTO :f1[i], :f2[i], :f3[i];
+ i++;
+ }
+ EXEC SQL AT con2 CLOSE cur_4;
+ EXEC SQL AT con2 DEALLOCATE PREPARE stmt_4;
+ EXEC SQL WHENEVER NOT FOUND CONTINUE;
+
+ printResult("testcase4", 2);
+
+ /*
+ * DESCRIBE statement is also supported.
+ */
+ EXEC SQL AT con1 DECLARE stmt_desc STATEMENT;
+ EXEC SQL PREPARE stmt_desc FROM :selectString;
+ EXEC SQL DECLARE cur_desc CURSOR FOR stmt_desc;
+ EXEC SQL OPEN cur_desc;
+
+ /* descriptor can be used for describe statement */
+ EXEC SQL AT con1 ALLOCATE DESCRIPTOR desc_for_describe;
+ EXEC SQL DESCRIBE stmt_desc INTO SQL DESCRIPTOR desc_for_describe;
+
+ EXEC SQL AT con1 GET DESCRIPTOR desc_for_describe :count = COUNT;
+ EXEC SQL AT con1 GET DESCRIPTOR desc_for_describe VALUE 3 :length = LENGTH;
+
+ EXEC SQL AT con1 DEALLOCATE DESCRIPTOR desc_for_describe;
+
+ /* for fetch statement */
+ EXEC SQL AT con1 ALLOCATE DESCRIPTOR desc_for_fetch;
+ EXEC SQL FETCH cur_desc INTO SQL DESCRIPTOR desc_for_fetch;
+
+ EXEC SQL AT con1 GET DESCRIPTOR desc_for_fetch VALUE 3 :f3[0] = DATA;
+
+ EXEC SQL AT con1 DEALLOCATE DESCRIPTOR desc_for_fetch;
+ EXEC SQL CLOSE cur_desc;
+ EXEC SQL DEALLOCATE stmt_desc;
+
+ printf("****descriptor results****\n");
+ printf("count: %d, length: %d, data: %s\n", count, length, f3[0]);
+}
+
+void commitTable()
+{
+ EXEC SQL AT con1 COMMIT;
+ EXEC SQL AT con2 COMMIT;
+}
+
+/*
+ * reset all the output variables
+ */
+void reset()
+{
+ memset(f1, 0, sizeof(f1));
+ memset(f2, 0, sizeof(f2));
+ memset(f3, 0, sizeof(f3));
+}
+
+void printResult(char *tc_name, int loop)
+{
+ int i;
+
+ if (tc_name)
+ printf("****%s test results:****\n", tc_name);
+
+ for (i = 0; i < loop; i++)
+ printf("f1=%d, f2=%d, f3=%s\n", f1[i], f2[i], f3[i]);
+
+ printf("\n");
+}
diff --git a/src/interfaces/ecpg/test/sql/define.pgc b/src/interfaces/ecpg/test/sql/define.pgc
new file mode 100644
index 0000000..ed58a4b
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/define.pgc
@@ -0,0 +1,58 @@
+exec sql include sqlca;
+exec sql include ../regression;
+exec sql define STR 'abcdef';
+exec sql define INSERTNULL 1;
+exec sql define NUMBER 29;
+
+int main(void)
+{
+ exec sql begin declare section;
+ int i;
+ char s[200];
+ exec sql end declare section;
+
+ ECPGdebug(1, stderr);
+
+ exec sql whenever sqlerror do sqlprint();
+ exec sql connect to REGRESSDB1;
+
+ exec sql create table test (a int, b text);
+ exec sql insert into test values (NUMBER, STR);
+
+ exec sql ifdef INSERTNULL;
+ exec sql insert into test values (NULL, 'defined');
+ exec sql endif;
+
+ exec sql ifndef INSERTNULL;
+ exec sql insert into test values (NULL, 'not defined');
+ exec sql elif SOMEOTHERVAR;
+ exec sql insert into test values (NULL, 'someothervar defined');
+ exec sql else;
+ exec sql insert into test values (NULL, 'someothervar not defined');
+ exec sql endif;
+
+ exec sql define NUMBER 29;
+
+ exec sql select INSERTNULL, NUMBER::text || '-' || STR INTO :i, :s;
+
+ printf("i: %d, s: %s\n", i, s);
+
+ exec sql undef STR;
+ exec sql ifndef STR;
+ exec sql insert into test values (NUMBER, 'no string');
+ exec sql endif;
+
+ exec sql define TZVAR; /* no value */
+ exec sql define TZVAR 'UTC';
+
+ exec sql ifndef TZVAR;
+ exec sql SET TIMEZONE TO 'GMT';
+ exec sql elif TZNAME;
+ exec sql SET TIMEZONE TO TZNAME;
+ exec sql else;
+ exec sql SET TIMEZONE TO TZVAR;
+ exec sql endif;
+
+ exec sql disconnect;
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/desc.pgc b/src/interfaces/ecpg/test/sql/desc.pgc
new file mode 100644
index 0000000..abda771
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/desc.pgc
@@ -0,0 +1,89 @@
+EXEC SQL INCLUDE ../regression;
+EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *stmt1 = "INSERT INTO test1 VALUES ($1, $2)";
+ char *stmt2 = "SELECT * from test1 where a = $1 and b = $2";
+ char *stmt3 = "SELECT * from test1 where :var = a";
+
+ int val1 = 1;
+ char val2[4] = "one", val2output[] = "AAA";
+ int val1output = 2, val2i = 0;
+ int val2null = -1;
+ int ind1, ind2;
+ char desc1[8] = "outdesc";
+ EXEC SQL END DECLARE SECTION;
+
+ ECPGdebug(1, stderr);
+
+ EXEC SQL ALLOCATE DESCRIPTOR indesc;
+ EXEC SQL ALLOCATE DESCRIPTOR :desc1;
+
+ EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1;
+ EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2i, DATA = :val2;
+
+ EXEC SQL CONNECT TO REGRESSDB1;
+
+ EXEC SQL CREATE TABLE test1 (a int, b text);
+ EXEC SQL PREPARE foo1 FROM :stmt1;
+ EXEC SQL PREPARE "Foo-1" FROM :stmt1;
+ EXEC SQL PREPARE foo2 FROM :stmt2;
+ EXEC SQL PREPARE foo3 FROM :stmt3;
+
+ EXEC SQL EXECUTE foo1 USING SQL DESCRIPTOR indesc;
+
+ EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2;
+ EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2null, DATA = :val2;
+
+ EXEC SQL EXECUTE foo1 USING SQL DESCRIPTOR indesc;
+
+ EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 3;
+ EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val1, DATA = 'this is a long test';
+
+ EXEC SQL EXECUTE "Foo-1" USING SQL DESCRIPTOR indesc;
+
+ EXEC SQL DEALLOCATE "Foo-1";
+
+ EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1;
+ EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2i, DATA = :val2;
+
+ EXEC SQL EXECUTE foo2 USING SQL DESCRIPTOR indesc INTO SQL DESCRIPTOR :desc1;
+
+ EXEC SQL GET DESCRIPTOR :desc1 VALUE 1 :val2output = DATA;
+ printf("output = %s\n", val2output);
+
+ EXEC SQL DECLARE c1 CURSOR FOR foo2;
+ EXEC SQL OPEN c1 USING SQL DESCRIPTOR indesc;
+
+ EXEC SQL FETCH next FROM c1 INTO :val1output:ind1, :val2output:ind2;
+ printf("val1=%d (ind1: %d) val2=%s (ind2: %d)\n",
+ val1output, ind1, val2output, ind2);
+
+ EXEC SQL CLOSE c1;
+
+ EXEC SQL SET DESCRIPTOR indesc COUNT = 1;
+ EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2;
+
+ EXEC SQL DECLARE c2 CURSOR FOR foo3;
+ EXEC SQL OPEN c2 USING SQL DESCRIPTOR indesc;
+
+ EXEC SQL FETCH next FROM c2 INTO :val1output, :val2output :val2i;
+ printf("val1=%d val2=%s\n", val1output, val2i ? "null" : val2output);
+
+ EXEC SQL CLOSE c2;
+
+ EXEC SQL SELECT * INTO :val1output, :val2output:val2i FROM test1 where a = 3;
+ printf("val1=%d val2=%c%c%c%c warn=%c truncate=%d\n", val1output, val2output[0], val2output[1], val2output[2], val2output[3], sqlca.sqlwarn[0], val2i);
+
+ EXEC SQL DROP TABLE test1;
+ EXEC SQL DEALLOCATE ALL;
+ EXEC SQL DISCONNECT;
+
+ EXEC SQL DEALLOCATE DESCRIPTOR indesc;
+ EXEC SQL DEALLOCATE DESCRIPTOR :desc1;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/describe.pgc b/src/interfaces/ecpg/test/sql/describe.pgc
new file mode 100644
index 0000000..87d6bd9
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/describe.pgc
@@ -0,0 +1,199 @@
+#include <stdlib.h>
+#include <string.h>
+
+exec sql include ../regression;
+exec sql include sqlda.h;
+
+exec sql whenever sqlerror stop;
+
+sqlda_t *sqlda1, *sqlda2, *sqlda3;
+
+int
+main (void)
+{
+exec sql begin declare section;
+ char *stmt1 = "SELECT id, t FROM descr_t2";
+ char *stmt2 = "SELECT id, t FROM descr_t2 WHERE id = -1";
+ int i, count1, count2;
+ char field_name1[30] = "not set";
+ char field_name2[30] = "not set";
+exec sql end declare section;
+
+ 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 descr_t2(id serial primary key, t text);
+
+ strcpy(msg, "insert");
+ exec sql insert into descr_t2(id, t) values (default, 'a');
+ exec sql insert into descr_t2(id, t) values (default, 'b');
+ exec sql insert into descr_t2(id, t) values (default, 'c');
+ exec sql insert into descr_t2(id, t) values (default, 'd');
+
+ strcpy(msg, "commit");
+ exec sql commit;
+
+ /*
+ * Test DESCRIBE with a query producing tuples.
+ * DESCRIPTOR and SQL DESCRIPTOR are NOT the same in
+ * Informix-compat mode.
+ */
+
+ strcpy(msg, "allocate");
+ exec sql allocate descriptor desc1;
+ exec sql allocate descriptor desc2;
+
+ strcpy(msg, "prepare");
+ exec sql prepare st_id1 FROM :stmt1;
+
+ sqlda1 = sqlda2 = sqlda3 = NULL;
+
+ strcpy(msg, "describe");
+ exec sql describe st_id1 into sql descriptor desc1;
+ exec sql describe st_id1 using sql descriptor desc2;
+
+ exec sql describe st_id1 into descriptor sqlda1;
+ exec sql describe st_id1 using descriptor sqlda2;
+ exec sql describe st_id1 into sqlda3;
+
+ if (sqlda1 == NULL)
+ {
+ printf("sqlda1 NULL\n");
+ exit(1);
+ }
+
+ if (sqlda2 == NULL)
+ {
+ printf("sqlda2 NULL\n");
+ exit(1);
+ }
+
+ if (sqlda3 == NULL)
+ {
+ printf("sqlda3 NULL\n");
+ exit(1);
+ }
+
+ strcpy(msg, "get descriptor");
+ exec sql get descriptor desc1 :count1 = count;
+ exec sql get descriptor desc1 :count2 = count;
+
+ if (count1 != count2)
+ {
+ printf("count1 (%d) != count2 (%d)\n", count1, count2);
+ exit(1);
+ }
+
+ if (count1 != sqlda1->sqld)
+ {
+ printf("count1 (%d) != sqlda1->sqld (%d)\n", count1, sqlda1->sqld);
+ exit(1);
+ }
+
+ if (count1 != sqlda2->sqld)
+ {
+ printf("count1 (%d) != sqlda2->sqld (%d)\n", count1, sqlda2->sqld);
+ exit(1);
+ }
+
+ if (count1 != sqlda3->sqld)
+ {
+ printf("count1 (%d) != sqlda3->sqld (%d)\n", count1, sqlda3->sqld);
+ exit(1);
+ }
+
+ for (i = 1; i <= count1; i++)
+ {
+ exec sql get descriptor desc1 value :i :field_name1 = name;
+ exec sql get descriptor desc2 value :i :field_name2 = name;
+ printf("%d\n\tfield_name1 '%s'\n\tfield_name2 '%s'\n\t"
+ "sqlda1 '%s'\n\tsqlda2 '%s'\n\tsqlda3 '%s'\n",
+ i, field_name1, field_name2,
+ sqlda1->sqlvar[i-1].sqlname.data,
+ sqlda2->sqlvar[i-1].sqlname.data,
+ sqlda3->sqlvar[i-1].sqlname.data);
+ }
+
+ strcpy(msg, "deallocate");
+ exec sql deallocate descriptor desc1;
+ exec sql deallocate descriptor desc2;
+ free(sqlda1);
+ free(sqlda2);
+ free(sqlda3);
+
+ exec sql deallocate prepare st_id1;
+
+ /* Test DESCRIBE with a query not producing tuples */
+
+ strcpy(msg, "allocate");
+ exec sql allocate descriptor desc1;
+ exec sql allocate descriptor desc2;
+
+ strcpy(msg, "prepare");
+ exec sql prepare st_id2 FROM :stmt2;
+
+ sqlda1 = sqlda2 = sqlda3 = NULL;
+
+ strcpy(msg, "describe");
+ exec sql describe st_id2 into sql descriptor desc1;
+ exec sql describe st_id2 using sql descriptor desc2;
+
+ exec sql describe st_id2 into descriptor sqlda1;
+ exec sql describe st_id2 using descriptor sqlda2;
+ exec sql describe st_id2 into sqlda3;
+
+ if (sqlda1 == NULL || sqlda2 == NULL || sqlda3 == NULL)
+ exit(1);
+
+ strcpy(msg, "get descriptor");
+ exec sql get descriptor desc1 :count1 = count;
+ exec sql get descriptor desc1 :count2 = count;
+
+ if (!( count1 == count2 &&
+ count1 == sqlda1->sqld &&
+ count1 == sqlda2->sqld &&
+ count1 == sqlda3->sqld))
+ exit(1);
+
+ for (i = 1; i <= count1; i++)
+ {
+ exec sql get descriptor desc1 value :i :field_name1 = name;
+ exec sql get descriptor desc2 value :i :field_name2 = name;
+ printf("%d\n\tfield_name1 '%s'\n\tfield_name2 '%s'\n\t"
+ "sqlda1 '%s'\n\tsqlda2 '%s'\n\tsqlda3 '%s'\n",
+ i, field_name1, field_name2,
+ sqlda1->sqlvar[i-1].sqlname.data,
+ sqlda2->sqlvar[i-1].sqlname.data,
+ sqlda3->sqlvar[i-1].sqlname.data);
+ }
+
+ strcpy(msg, "deallocate");
+ exec sql deallocate descriptor desc1;
+ exec sql deallocate descriptor desc2;
+ free(sqlda1);
+ free(sqlda2);
+ free(sqlda3);
+
+ exec sql deallocate prepare st_id2;
+
+ /* End test */
+
+ strcpy(msg, "drop");
+ exec sql drop table descr_t2;
+
+ strcpy(msg, "commit");
+ exec sql commit;
+
+ strcpy(msg, "disconnect");
+ exec sql disconnect;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/dynalloc.pgc b/src/interfaces/ecpg/test/sql/dynalloc.pgc
new file mode 100644
index 0000000..8aa810f
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/dynalloc.pgc
@@ -0,0 +1,89 @@
+#include <stdio.h>
+exec sql include sqlca;
+#include <stdlib.h>
+exec sql include ../regression;
+
+int main(void)
+{
+ exec sql begin declare section;
+ int *d1=0;
+ double *d2=0;
+ char **d3=0;
+ char **d4=0;
+ char **d5=0;
+ char **d6=0;
+ char **d7=0;
+/* char **d8=0; */
+ char **d9=0;
+ int *i1=0;
+ int *i2=0;
+ int *i3=0;
+ int *i4=0;
+ int *i5=0;
+ int *i6=0;
+ int *i7=0;
+/* int *i8=0; */
+ int *i9=0;
+ exec sql end declare section;
+ int i;
+
+ ECPGdebug(1, stderr);
+
+ exec sql whenever sqlerror do sqlprint();
+ exec sql connect to REGRESSDB1;
+
+ exec sql set datestyle to mdy;
+
+ exec sql create table test (a serial, b numeric(12,3), c varchar, d varchar(3), e char(4), f timestamptz, g boolean, h box, i inet);
+ exec sql insert into test (b, c, d, e, f, g, h, i) values (23.456, 'varchar', 'v', 'c', '2003-03-03 12:33:07 PDT', true, '(1,2,3,4)', '2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128');
+ exec sql insert into test (b, c, d, e, f, g, h, i) values (2.446456, NULL, 'v', 'c', '2003-03-03 12:33:07 PDT', false, NULL, NULL);
+
+ exec sql allocate descriptor mydesc;
+ exec sql select a,b,c,d,e,f,g,h,i into sql descriptor mydesc from test order by a;
+ exec sql get descriptor mydesc value 1 :d1=DATA, :i1=INDICATOR;
+ exec sql get descriptor mydesc value 2 :d2=DATA, :i2=INDICATOR;
+ exec sql get descriptor mydesc value 3 :d3=DATA, :i3=INDICATOR;
+ exec sql get descriptor mydesc value 4 :d4=DATA, :i4=INDICATOR;
+ exec sql get descriptor mydesc value 5 :d5=DATA, :i5=INDICATOR;
+ exec sql get descriptor mydesc value 6 :d6=DATA, :i6=INDICATOR;
+ exec sql get descriptor mydesc value 7 :d7=DATA, :i7=INDICATOR;
+ /* skip box for now */
+ /* exec sql get descriptor mydesc value 8 :d8=DATA, :i8=INDICATOR; */
+ exec sql get descriptor mydesc value 9 :d9=DATA, :i9=INDICATOR;
+
+ printf("Result:\n");
+ for (i=0;i<sqlca.sqlerrd[2];++i)
+ {
+ if (i1[i]) printf("NULL, ");
+ else printf("%d, ",d1[i]);
+
+ if (i2[i]) printf("NULL, ");
+ else printf("%f, ",d2[i]);
+
+ if (i3[i]) printf("NULL, ");
+ else printf("'%s', ",d3[i]);
+
+ if (i4[i]) printf("NULL, ");
+ else printf("'%s', ",d4[i]);
+
+ if (i5[i]) printf("NULL, ");
+ else printf("'%s', ",d5[i]);
+
+ if (i6[i]) printf("NULL, ");
+ else printf("'%s', ",d6[i]);
+
+ if (i7[i]) printf("NULL, ");
+ else printf("'%s', ",d7[i]);
+
+ if (i9[i]) printf("NULL, ");
+ else printf("'%s', ",d9[i]);
+
+ printf("\n");
+ }
+ ECPGfree_auto_mem();
+ printf("\n");
+
+ exec sql deallocate descriptor mydesc;
+ exec sql disconnect;
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/dynalloc2.pgc b/src/interfaces/ecpg/test/sql/dynalloc2.pgc
new file mode 100644
index 0000000..67d9077
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/dynalloc2.pgc
@@ -0,0 +1,55 @@
+#include <stdio.h>
+exec sql include sqlca;
+#include <stdlib.h>
+exec sql include ../regression;
+
+int main(void)
+{
+ exec sql begin declare section;
+ int *ip1=0;
+ char **cp2=0;
+ int *ipointer1=0;
+ int *ipointer2=0;
+ int colnum;
+ exec sql end declare section;
+ int i;
+
+ ECPGdebug(1, stderr);
+
+ exec sql whenever sqlerror do sqlprint();
+ exec sql connect to REGRESSDB1;
+
+ exec sql set datestyle to postgres;
+
+ exec sql create table test (a int, b text);
+ exec sql insert into test values (1, 'one');
+ exec sql insert into test values (2, 'two');
+ exec sql insert into test values (NULL, 'three');
+ exec sql insert into test values (4, 'four');
+ exec sql insert into test values (5, NULL);
+ exec sql insert into test values (NULL, NULL);
+
+ exec sql allocate descriptor mydesc;
+ exec sql select * into sql descriptor mydesc from test;
+ exec sql get descriptor mydesc :colnum=COUNT;
+ exec sql get descriptor mydesc value 1 :ip1=DATA, :ipointer1=INDICATOR;
+ exec sql get descriptor mydesc value 2 :cp2=DATA, :ipointer2=INDICATOR;
+
+ printf("Result (%d columns):\n", colnum);
+ for (i=0;i < sqlca.sqlerrd[2];++i)
+ {
+ if (ipointer1[i]) printf("NULL, ");
+ else printf("%d, ",ip1[i]);
+
+ if (ipointer2[i]) printf("NULL, ");
+ else printf("'%s', ",cp2[i]);
+ printf("\n");
+ }
+ ECPGfree_auto_mem();
+ printf("\n");
+
+ exec sql deallocate descriptor mydesc;
+ exec sql rollback;
+ exec sql disconnect;
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/dyntest.pgc b/src/interfaces/ecpg/test/sql/dyntest.pgc
new file mode 100644
index 0000000..0222c89
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/dyntest.pgc
@@ -0,0 +1,199 @@
+/* dynamic SQL test program
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+exec sql include sql3types;
+exec sql include sqlca;
+exec sql include ../regression;
+
+static void
+error (void)
+{
+ printf ("\n#%ld:%s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
+ exit (1);
+}
+
+int
+main ()
+{
+ exec sql begin declare section;
+ int COUNT;
+ int INTVAR;
+ int INDEX;
+ int INDICATOR;
+ int TYPE, LENGTH, OCTET_LENGTH, PRECISION, SCALE, RETURNED_OCTET_LENGTH;
+ int DATETIME_INTERVAL_CODE;
+ char NAME[120], BOOLVAR;
+ char STRINGVAR[1024];
+ double DOUBLEVAR;
+ char *QUERY;
+ exec sql end declare section;
+ int done = 0;
+
+ exec sql var BOOLVAR is bool;
+
+ ECPGdebug (1, stderr);
+
+ QUERY = "select * from dyntest";
+
+ exec sql whenever sqlerror
+ do
+ error ();
+
+ exec sql allocate descriptor MYDESC;
+
+ exec sql connect to REGRESSDB1;
+
+ exec sql set datestyle to german;
+
+ exec sql create table dyntest (name char (14), d float8, i int,
+ bignumber int8, b boolean, comment text,
+ day date);
+ exec sql insert into dyntest values ('first entry', 14.7, 14, 123045607890, true, 'The world''s most advanced open source database.', '1987-07-14');
+ exec sql insert into dyntest values ('second entry', 1407.87, 1407, 987065403210, false, 'The elephant never forgets.', '1999-11-5');
+
+ exec sql prepare MYQUERY from :QUERY;
+ exec sql declare MYCURS cursor for MYQUERY;
+
+ exec sql open MYCURS;
+
+ while (1)
+ {
+ exec sql fetch in MYCURS into sql descriptor MYDESC;
+
+ if (sqlca.sqlcode)
+ break;
+
+ exec sql get descriptor MYDESC:COUNT = count;
+ if (!done)
+ {
+ printf ("Found %d columns\n", COUNT);
+ done = 1;
+ }
+
+ for (INDEX = 1; INDEX <= COUNT; ++INDEX)
+ {
+ exec sql get descriptor MYDESC value :INDEX
+ :TYPE = type,
+ :LENGTH = length,
+ :OCTET_LENGTH = octet_length,
+ :RETURNED_OCTET_LENGTH = returned_octet_length,
+ :PRECISION = precision,
+ :SCALE = scale,
+ :NAME = name,
+ :INDICATOR = indicator;
+ printf ("%2d\t%s (type: %d length: %d precision: %d scale: %d = " , INDEX, NAME, TYPE, LENGTH, PRECISION, SCALE);
+ switch (TYPE)
+ {
+ case SQL3_BOOLEAN:
+ printf ("bool");
+ break;
+ case SQL3_NUMERIC:
+ printf ("numeric(%d,%d)", PRECISION, SCALE);
+ break;
+ case SQL3_DECIMAL:
+ printf ("decimal(%d,%d)", PRECISION, SCALE);
+ break;
+ case SQL3_INTEGER:
+ printf ("integer");
+ break;
+ case SQL3_SMALLINT:
+ printf ("smallint");
+ break;
+ case SQL3_FLOAT:
+ printf ("float(%d,%d)", PRECISION, SCALE);
+ break;
+ case SQL3_REAL:
+ printf ("real");
+ break;
+ case SQL3_DOUBLE_PRECISION:
+ printf ("double precision");
+ break;
+ case SQL3_DATE_TIME_TIMESTAMP:
+ exec sql get descriptor MYDESC value :INDEX
+ :DATETIME_INTERVAL_CODE = datetime_interval_code;
+ switch (DATETIME_INTERVAL_CODE)
+ {
+ case SQL3_DDT_DATE:
+ printf ("date");
+ break;
+ case SQL3_DDT_TIME:
+ printf ("time");
+ break;
+ case SQL3_DDT_TIMESTAMP:
+ printf ("timestamp");
+ break;
+ case SQL3_DDT_TIME_WITH_TIME_ZONE:
+ printf ("time with time zone");
+ break;
+ case SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE:
+ printf ("timestamp with time zone");
+ break;
+ }
+ break;
+ case SQL3_INTERVAL:
+ printf ("interval");
+ break;
+ case SQL3_CHARACTER:
+ if (LENGTH > 0)
+ printf ("char(%d)", LENGTH);
+ else
+ printf ("text");
+ break;
+ case SQL3_CHARACTER_VARYING:
+ if (LENGTH > 0)
+ printf ("varchar(%d)", LENGTH);
+ else
+ printf ("varchar()");
+ break;
+ default:
+ printf ("<SQL3 %d>", TYPE);
+ break;
+ }
+ printf (")\n\toctet_length: %d returned_octet_length: %d)\n\t= ",
+ OCTET_LENGTH, RETURNED_OCTET_LENGTH);
+ if (INDICATOR == -1)
+ printf ("NULL\n");
+ else
+ switch (TYPE)
+ {
+ case SQL3_BOOLEAN:
+ exec sql get descriptor MYDESC value :INDEX :BOOLVAR = data;
+ printf ("%s\n", BOOLVAR ? "true" : "false");
+ break;
+ case SQL3_INTEGER:
+ case SQL3_SMALLINT:
+ exec sql get descriptor MYDESC value :INDEX :INTVAR = data;
+ printf ("%d\n", INTVAR);
+ break;
+ case SQL3_DOUBLE_PRECISION:
+ exec sql get descriptor MYDESC value :INDEX :DOUBLEVAR = data;
+ printf ("%.*f\n", PRECISION, DOUBLEVAR);
+ break;
+ case SQL3_DATE_TIME_TIMESTAMP:
+ exec sql get descriptor MYDESC value :INDEX
+ :DATETIME_INTERVAL_CODE = datetime_interval_code,
+ :STRINGVAR = data;
+ printf ("%d \"%s\"\n", DATETIME_INTERVAL_CODE, STRINGVAR);
+ break;
+ case SQL3_CHARACTER:
+ case SQL3_CHARACTER_VARYING:
+ exec sql get descriptor MYDESC value :INDEX :STRINGVAR = data;
+ printf ("\"%s\"\n", STRINGVAR);
+ break;
+ default:
+ exec sql get descriptor MYDESC value :INDEX :STRINGVAR = data;
+ printf ("<\"%s\">\n", STRINGVAR);
+ break;
+ }
+ }
+ }
+
+ exec sql close MYCURS;
+
+ exec sql deallocate descriptor MYDESC;
+
+ return 0;
+ }
diff --git a/src/interfaces/ecpg/test/sql/execute.pgc b/src/interfaces/ecpg/test/sql/execute.pgc
new file mode 100644
index 0000000..43171bb
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/execute.pgc
@@ -0,0 +1,113 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+exec sql include ../regression;
+
+exec sql whenever sqlerror sqlprint;
+
+int
+main(void)
+{
+exec sql begin declare section;
+ int amount[8];
+ int increment=100;
+ char name[8][8];
+ char letter[8][1];
+ char command[128];
+exec sql end declare section;
+ int i,j;
+
+ ECPGdebug(1, stderr);
+
+ exec sql connect to REGRESSDB1 as main;
+ exec sql create table test (name char(8), amount int, letter char(1));
+ exec sql commit;
+
+ /* test handling of embedded quotes in EXECUTE IMMEDIATE "literal" */
+ exec sql execute immediate "insert into test (name, \042amount\042, letter) values ('db: ''r1''', 1, 'f')";
+
+ sprintf(command, "insert into test (name, amount, letter) values ('db: ''r1''', 2, 't')");
+ exec sql execute immediate :command;
+
+ sprintf(command, "insert into test (name, amount, letter) select name, amount+10, letter from test");
+ exec sql execute immediate :command;
+
+ printf("Inserted %ld tuples via execute immediate\n", sqlca.sqlerrd[2]);
+
+ sprintf(command, "insert into test (name, amount, letter) select name, amount+$1, letter from test");
+ exec sql prepare I from :command;
+ exec sql execute I using :increment;
+
+ printf("Inserted %ld tuples via prepared execute\n", sqlca.sqlerrd[2]);
+
+ exec sql commit;
+
+ sprintf (command, "select * from test");
+
+ exec sql prepare f from :command;
+ exec sql declare CUR cursor for f;
+
+ exec sql open CUR;
+ exec sql fetch 8 in CUR into :name, :amount, :letter;
+
+ for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
+ {
+ exec sql begin declare section;
+ char n[8], l = letter[i][0];
+ int a = amount[i];
+ exec sql end declare section;
+
+ strncpy(n, name[i], 8);
+ printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
+ }
+
+ exec sql close CUR;
+ exec sql deallocate f;
+
+ sprintf (command, "select * from test where amount = $1");
+
+ exec sql prepare f from :command;
+ exec sql declare CUR2 cursor for f;
+
+ exec sql open CUR2 using 1;
+ exec sql fetch in CUR2 into :name, :amount, :letter;
+
+ for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
+ {
+ exec sql begin declare section;
+ char n[8], l = letter[i][0];
+ int a = amount[i];
+ exec sql end declare section;
+
+ strncpy(n, name[i], 8);
+ printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
+ }
+
+ exec sql close CUR2;
+ exec sql deallocate f;
+
+ sprintf (command, "select * from test where amount = $1");
+
+ exec sql prepare f from :command;
+ exec sql execute f using 2 into :name, :amount, :letter;
+
+ for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
+ {
+ exec sql begin declare section;
+ char n[8], l = letter[i][0];
+ int a = amount[i];
+ exec sql end declare section;
+
+ strncpy(n, name[i], 8);
+ printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
+ }
+
+ exec sql deallocate f;
+ exec sql drop table test;
+ exec sql commit;
+ exec sql disconnect;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/fetch.pgc b/src/interfaces/ecpg/test/sql/fetch.pgc
new file mode 100644
index 0000000..31e525e
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/fetch.pgc
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+EXEC SQL INCLUDE ../regression;
+
+int main() {
+ EXEC SQL BEGIN DECLARE SECTION;
+ char str[25];
+ int i, count=1, loopcount;
+ EXEC SQL END DECLARE SECTION;
+
+ ECPGdebug(1, stderr);
+ EXEC SQL CONNECT TO REGRESSDB1;
+
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ EXEC SQL WHENEVER SQLERROR STOP;
+
+ EXEC SQL CREATE TABLE My_Table ( Item1 int, Item2 text );
+
+ EXEC SQL INSERT INTO My_Table VALUES ( 1, 'text1');
+ EXEC SQL INSERT INTO My_Table VALUES ( 2, 'text2');
+ EXEC SQL INSERT INTO My_Table VALUES ( 3, 'text3');
+ EXEC SQL INSERT INTO My_Table VALUES ( 4, 'text4');
+
+ EXEC SQL DECLARE C CURSOR FOR SELECT * FROM My_Table;
+
+ EXEC SQL OPEN C;
+
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+ for (loopcount = 0; loopcount < 100; loopcount++) {
+ EXEC SQL FETCH 1 IN C INTO :i, :str;
+ printf("%d: %s\n", i, str);
+ }
+
+ EXEC SQL WHENEVER NOT FOUND CONTINUE;
+ EXEC SQL MOVE BACKWARD 2 IN C;
+
+ EXEC SQL FETCH :count IN C INTO :i, :str;
+ printf("%d: %s\n", i, str);
+
+ EXEC SQL CLOSE C;
+
+ EXEC SQL DECLARE D CURSOR FOR SELECT * FROM My_Table WHERE Item1 = $1;
+
+ EXEC SQL OPEN D using 1;
+
+ EXEC SQL FETCH 1 IN D INTO :i, :str;
+ printf("%d: %s\n", i, str);
+
+ EXEC SQL CLOSE D;
+
+ EXEC SQL DROP TABLE My_Table;
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/func.pgc b/src/interfaces/ecpg/test/sql/func.pgc
new file mode 100644
index 0000000..5ebcafa
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/func.pgc
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+EXEC SQL INCLUDE ../regression;
+
+int main() {
+ EXEC SQL char text[25];
+
+ ECPGdebug(1, stderr);
+ EXEC SQL CONNECT TO REGRESSDB1;
+
+ EXEC SQL SET AUTOCOMMIT TO ON;
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+ EXEC SQL CREATE TABLE My_Table ( Item1 int, Item2 text );
+ EXEC SQL CREATE TABLE Log (name text, w text);
+
+ EXEC SQL CREATE FUNCTION My_Table_Check() RETURNS trigger
+ AS $test$
+ BEGIN
+ INSERT INTO Log VALUES(TG_NAME, TG_WHEN);
+ RETURN NEW;
+ END; $test$
+ LANGUAGE plpgsql;
+
+ EXEC SQL CREATE TRIGGER My_Table_Check_Trigger
+ BEFORE INSERT
+ ON My_Table
+ FOR EACH ROW
+ EXECUTE PROCEDURE My_Table_Check();
+
+ EXEC SQL INSERT INTO My_Table VALUES (1234, 'Some random text');
+ EXEC SQL INSERT INTO My_Table VALUES (5678, 'The Quick Brown');
+ EXEC SQL SELECT name INTO :text FROM Log LIMIT 1;
+ printf("Trigger %s fired.\n", text);
+
+ EXEC SQL DROP TRIGGER My_Table_Check_Trigger ON My_Table;
+ EXEC SQL DROP FUNCTION My_Table_Check();
+ EXEC SQL DROP TABLE Log;
+ EXEC SQL DROP TABLE My_Table;
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/indicators.pgc b/src/interfaces/ecpg/test/sql/indicators.pgc
new file mode 100644
index 0000000..c1f26e3
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/indicators.pgc
@@ -0,0 +1,50 @@
+#include <stdio.h>
+
+exec sql include sqlca;
+exec sql include ../regression;
+
+int main()
+{
+ exec sql begin declare section;
+ int intvar = 5;
+ int nullind = -1;
+ exec sql end declare section;
+
+ ECPGdebug(1,stderr);
+
+ exec sql connect to REGRESSDB1;
+ exec sql set autocommit to off;
+
+ exec sql create table indicator_test (
+ "id" int primary key,
+ "str" text NOT NULL,
+ val int null);
+ exec sql commit work;
+
+ exec sql insert into indicator_test (id, str, val) values ( 1, 'Hello', 0);
+
+ /* use indicator in insert */
+ exec sql insert into indicator_test (id, str, val) values ( 2, 'Hi there', :intvar :nullind);
+ nullind = 0;
+ exec sql insert into indicator_test (id, str, val) values ( 3, 'Good evening', :intvar :nullind);
+ exec sql commit work;
+
+ /* use indicators to get information about selects */
+ exec sql select val into :intvar from indicator_test where id = 1;
+ exec sql select val into :intvar :nullind from indicator_test where id = 2;
+ printf("intvar: %d, nullind: %d\n", intvar, nullind);
+ exec sql select val into :intvar :nullind from indicator_test where id = 3;
+ printf("intvar: %d, nullind: %d\n", intvar, nullind);
+
+ /* use indicators for update */
+ intvar = 5; nullind = -1;
+ exec sql update indicator_test set val = :intvar :nullind where id = 1;
+ exec sql select val into :intvar :nullind from indicator_test where id = 1;
+ printf("intvar: %d, nullind: %d\n", intvar, nullind);
+
+ exec sql drop table indicator_test;
+ exec sql commit work;
+
+ exec sql disconnect;
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/insupd.pgc b/src/interfaces/ecpg/test/sql/insupd.pgc
new file mode 100644
index 0000000..b12f66f
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/insupd.pgc
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+EXEC SQL INCLUDE ../regression;
+
+int main() {
+ EXEC SQL BEGIN DECLARE SECTION;
+ int i1[3], i2[3], i3[3], i4;
+ 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 insupd_test(a int, b int);
+
+ EXEC SQL INSERT INTO insupd_test (a,b) values (1, 1);
+ EXEC SQL INSERT INTO insupd_test (a,b) values (2, 2);
+ EXEC SQL INSERT INTO insupd_test (a,b) values (3, 3) returning a into :i4;
+
+ EXEC SQL UPDATE insupd_test set a=a+1 returning a into :i3;
+ EXEC SQL UPDATE insupd_test set (a,b)=(5,5) where a = 4;
+ EXEC SQL UPDATE insupd_test set a=4 where a=3;;
+
+ EXEC SQL SELECT a,b into :i1,:i2 from insupd_test order by a;
+
+ printf("changes\n%d %d %d %d\n", i3[0], i3[1], i3[2], i4);
+ printf("test\na b\n%d %d\n%d %d\n%d %d\n", i1[0], i2[0], i1[1], i2[1], i1[2], i2[2]);
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/oldexec.pgc b/src/interfaces/ecpg/test/sql/oldexec.pgc
new file mode 100644
index 0000000..4f94a18
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/oldexec.pgc
@@ -0,0 +1,90 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+exec sql include ../regression;
+
+exec sql whenever sqlerror sqlprint;
+
+int
+main(void)
+{
+exec sql begin declare section;
+ int amount[8];
+ int increment=100;
+ char name[8][8];
+ char letter[8][1];
+ char command[128];
+exec sql end declare section;
+ int i,j;
+
+ ECPGdebug(1, stderr);
+
+ exec sql connect to REGRESSDB1 as main;
+
+ exec sql create table test (name char(8), amount int, letter char(1));
+ exec sql commit;
+
+ sprintf(command, "insert into test (name, amount, letter) values ('db: ''r1''', 1, 'f')");
+ exec sql execute immediate :command;
+
+ sprintf(command, "insert into test (name, amount, letter) values ('db: ''r1''', 2, 't')");
+ exec sql execute immediate :command;
+
+ sprintf(command, "insert into test (name, amount, letter) select name, amount+10, letter from test");
+ exec sql execute immediate :command;
+
+ printf("Inserted %ld tuples via execute immediate\n", sqlca.sqlerrd[2]);
+
+ sprintf(command, "insert into test (name, amount, letter) select name, amount+$1, letter from test");
+ exec sql prepare I from :command;
+ exec sql execute I using :increment;
+
+ printf("Inserted %ld tuples via prepared execute\n", sqlca.sqlerrd[2]);
+
+ exec sql commit;
+
+ sprintf (command, "select * from test");
+
+ exec sql prepare F from :command;
+ exec sql declare CUR cursor for F;
+
+ exec sql open CUR;
+ exec sql fetch 8 in CUR into :name, :amount, :letter;
+
+ for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
+ {
+ char n[8], l = letter[i][0];
+ int a = amount[i];
+
+ strncpy(n, name[i], 8);
+ printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
+ }
+
+ exec sql close CUR;
+
+ sprintf (command, "select * from test where ? = amount");
+
+ exec sql prepare F from :command;
+ exec sql declare CUR3 cursor for F;
+
+ exec sql open CUR3 using 1;
+ exec sql fetch in CUR3 into :name, :amount, :letter;
+
+ for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
+ {
+ char n[8], l = letter[i][0];
+ int a = amount[i];
+
+ strncpy(n, name[i], 8);
+ printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, n, i, a, i, l);
+ }
+
+ exec sql close CUR3;
+ exec sql drop table test;
+ exec sql commit;
+ exec sql disconnect;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/parser.pgc b/src/interfaces/ecpg/test/sql/parser.pgc
new file mode 100644
index 0000000..6e15f13
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/parser.pgc
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* test parser addition that merges two tokens into one */
+EXEC SQL INCLUDE ../regression;
+
+int main() {
+ EXEC SQL BEGIN DECLARE SECTION;
+ int item[3], ind[3], i;
+ EXEC SQL END DECLARE SECTION;
+
+ ECPGdebug(1, stderr);
+ EXEC SQL CONNECT TO REGRESSDB1;
+
+ EXEC SQL SET AUTOCOMMIT TO ON;
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+ EXEC SQL CREATE TABLE T ( Item1 int, Item2 int );
+
+ EXEC SQL INSERT INTO t
+ SELECT 1,nullif(y-1,0)
+ FROM generate_series(1,3) WITH ORDINALITY AS series(x,y);
+
+ EXEC SQL SELECT Item2 INTO :item:ind FROM T ORDER BY Item2 NULLS LAST;
+
+ for (i=0; i<3; i++)
+ printf("item[%d] = %d\n", i, ind[i] ? -1 : item[i]);
+
+ EXEC SQL ALTER TABLE T ALTER Item1 TYPE bigint;
+ EXEC SQL ALTER TABLE T ALTER COLUMN Item2 SET DATA TYPE smallint;
+
+ EXEC SQL DROP TABLE T;
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/prepareas.pgc b/src/interfaces/ecpg/test/sql/prepareas.pgc
new file mode 100644
index 0000000..85f03d7
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/prepareas.pgc
@@ -0,0 +1,198 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+exec sql include ../regression;
+exec sql whenever sqlerror sqlprint;
+
+static void
+check_result_of_insert(void)
+{
+ exec sql begin declare section;
+ int ivar1 = 0, ivar2 = 0;
+ exec sql end declare section;
+
+ exec sql select c1,c2 into :ivar1,:ivar2 from test;
+ printf("%d %d\n", ivar1, ivar2);
+}
+
+int main(void)
+{
+ exec sql begin declare section;
+ int ivar1 = 1, ivar2 = 2;
+ char v_include_dq_name[16], v_include_ws_name[16], v_normal_name[16], v_query[64];
+ exec sql end declare section;
+
+ strcpy(v_normal_name, "normal_name");
+ strcpy(v_include_dq_name, "include_\"_name");
+ strcpy(v_include_ws_name, "include_ _name");
+ strcpy(v_query, "insert into test values(?,?)");
+
+ /*
+ * preparing for test
+ */
+ exec sql connect to REGRESSDB1;
+ exec sql begin;
+ exec sql create table test (c1 int, c2 int);
+ exec sql commit work;
+ exec sql begin;
+
+ /*
+ * Non dynamic statement
+ */
+ exec sql truncate test;
+ printf("+++++ Test for prepnormal +++++\n");
+ printf("insert into test values(:ivar1,:ivar2)\n");
+ exec sql insert into test values(:ivar1,:ivar2);
+ check_result_of_insert();
+
+ exec sql truncate test;
+ printf("+++++ Test for execute immediate +++++\n");
+ printf("execute immediate \"insert into test values(1,2)\"\n");
+ exec sql execute immediate "insert into test values(1,2)";
+ check_result_of_insert();
+
+ /*
+ * PREPARE FROM
+ */
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE ident FROM CString +++++\n");
+ printf("prepare ident_name from \"insert into test values(?,?)\"\n");
+ exec sql prepare ident_name from "insert into test values(?,?)";
+ printf("execute ident_name using :ivar1,:ivar2\n");
+ exec sql execute ident_name using :ivar1,:ivar2;
+ check_result_of_insert();
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE char_variable_normal_name FROM char_variable +++++\n");
+ printf("prepare :v_normal_name from :v_query\n");
+ exec sql prepare :v_normal_name from :v_query;
+ printf("execute :v_normal_name using :ivar1,:ivar2\n");
+ exec sql execute :v_normal_name using :ivar1,:ivar2;
+ check_result_of_insert();
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE char_variable_inc_dq_name FROM char_variable +++++\n");
+ printf("prepare :v_include_dq_name from :v_query\n");
+ exec sql prepare :v_include_dq_name from :v_query;
+ printf("execute :v_include_dq_name using :ivar1,:ivar2\n");
+ exec sql execute :v_include_dq_name using :ivar1,:ivar2;
+ check_result_of_insert();
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE char_variable_inc_ws_name FROM char_variable +++++\n");
+ printf("prepare :v_include_ws_name from :v_query\n");
+ exec sql prepare :v_include_ws_name from :v_query;
+ printf("execute :v_include_ws_name using :ivar1,:ivar2\n");
+ exec sql execute :v_include_ws_name using :ivar1,:ivar2;
+ check_result_of_insert();
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE CString_inc_ws_name FROM char_variable +++++\n");
+ printf("prepare \"include_ _name\" from :v_query\n");
+ exec sql prepare "include_ _name" from :v_query;
+ printf("exec sql execute \"include_ _name\" using :ivar1,:ivar2\n");
+ exec sql execute "include_ _name" using :ivar1,:ivar2;
+ check_result_of_insert();
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE CString_normal_name FROM char_variable +++++\n");
+ printf("prepare \"norma_name\" from :v_query\n");
+ exec sql prepare "normal_name" from :v_query;
+ printf("exec sql execute \"normal_name\" using :ivar1,:ivar2\n");
+ exec sql execute "normal_name" using :ivar1,:ivar2;
+ check_result_of_insert();
+
+ /*
+ * PREPARE AS
+ */
+ exec sql deallocate "ident_name";
+ exec sql deallocate "normal_name";
+ exec sql deallocate "include_ _name";
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE ident(typelist) AS +++++\n");
+ printf("prepare ident_name(int,int) as insert into test values($1,$2)\n");
+ exec sql prepare ident_name(int,int) as insert into test values($1,$2);
+ printf("execute ident_name(:ivar1,:ivar2)\n");
+ exec sql execute ident_name(:ivar1,:ivar2);
+ check_result_of_insert();
+ exec sql deallocate "ident_name";
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE CString_normal_name(typelist) AS +++++\n");
+ printf("prepare \"normal_name\"(int,int) as insert into test values($1,$2)\n");
+ exec sql prepare "normal_name"(int,int) as insert into test values($1,$2);
+ printf("execute \"normal_name\"(:ivar1,:ivar2)\n");
+ exec sql execute "normal_name"(:ivar1,:ivar2);
+ check_result_of_insert();
+ exec sql deallocate "normal_name";
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE CString_include_ws_name(typelist) AS +++++\n");
+ printf("prepare \"include_ _name\"(int,int) as insert into test values($1,$2)\n");
+ exec sql prepare "include_ _name"(int,int) as insert into test values($1,$2);
+ printf("execute \"include_ _name\"(:ivar1,:ivar2)\n");
+ exec sql execute "include_ _name"(:ivar1,:ivar2);
+ check_result_of_insert();
+ exec sql deallocate "include_ _name";
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE char_variable_normal_name(typelist) AS +++++\n");
+ printf("prepare :v_normal_name(int,int) as insert into test values($1,$2)\n");
+ exec sql prepare :v_normal_name(int,int) as insert into test values($1,$2);
+ printf("execute :v_normal_name(:ivar1,:ivar2)\n");
+ exec sql execute :v_normal_name(:ivar1,:ivar2);
+ check_result_of_insert();
+ exec sql deallocate "normal_name";
+
+ exec sql truncate test;
+ printf("+++++ Test for PREPARE char_variable_include_ws_name(typelist) AS +++++\n");
+ printf("prepare :v_include_ws_name(int,int) as insert into test values($1,$2)\n");
+ exec sql prepare :v_include_ws_name(int,int) as insert into test values($1,$2);
+ printf("execute :v_include_ws_name(:ivar1,:ivar2)\n");
+ exec sql execute :v_include_ws_name(:ivar1,:ivar2);
+ check_result_of_insert();
+ exec sql deallocate "include_ _name";
+
+ exec sql truncate test;
+ printf("+++++ Test for EXECUTE :v_normal_name(const,const) +++++\n");
+ printf("prepare :v_normal_name from :v_query\n");
+ exec sql prepare :v_normal_name from :v_query;
+ printf("execute :v_normal_name(1,2)\n");
+ exec sql execute :v_normal_name(1,2);
+ check_result_of_insert();
+ exec sql deallocate "normal_name";
+
+ exec sql truncate test;
+ printf("+++++ Test for EXECUTE :v_normal_name(expr,expr) +++++\n");
+ printf("prepare :v_normal_name from :v_query\n");
+ exec sql prepare :v_normal_name from :v_query;
+ printf("execute :v_normal_name(0+1,1+1)\n");
+ exec sql execute :v_normal_name(0+1,1+1);
+ check_result_of_insert();
+ exec sql deallocate "normal_name";
+
+ exec sql truncate test;
+ printf("+++++ Test for combination PREPARE FROM and EXECUTE ident(typelist) +++++\n");
+ printf("prepare ident_name from :v_query\n");
+ exec sql prepare ident_name from :v_query;
+ printf("execute ident_name(:ivar1,:ivar2)\n");
+ exec sql execute ident_name(:ivar1,:ivar2);
+ check_result_of_insert();
+ exec sql deallocate "ident_name";
+
+ exec sql truncate test;
+ printf("+++++ Test for combination PREPARE FROM and EXECUTE CString_include_ws_name(typelist) +++++\n");
+ printf("prepare \"include_ _name\" from :v_query\n");
+ exec sql prepare "include_ _name" from :v_query;
+ printf("execute \"include_ _name\"(:ivar1,:ivar2)\n");
+ exec sql execute "include_ _name"(:ivar1,:ivar2);
+ check_result_of_insert();
+ exec sql deallocate "include_ _name";
+
+ exec sql drop table test;
+ exec sql commit work;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/quote.pgc b/src/interfaces/ecpg/test/sql/quote.pgc
new file mode 100644
index 0000000..9b62b7d
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/quote.pgc
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+EXEC SQL INCLUDE ../regression;
+
+int main() {
+ EXEC SQL BEGIN DECLARE SECTION;
+ char var[25];
+ int i, loopcount;
+ EXEC SQL END DECLARE SECTION;
+
+ ECPGdebug(1, stderr);
+ EXEC SQL CONNECT TO REGRESSDB1;
+
+ EXEC SQL SET AUTOCOMMIT TO ON;
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ EXEC SQL WHENEVER SQLERROR STOP;
+
+ EXEC SQL CREATE TABLE "My_Table" ( Item1 int, Item2 text );
+
+ EXEC SQL SET standard_conforming_strings TO off;
+
+ EXEC SQL SHOW standard_conforming_strings INTO :var;
+ printf("Standard conforming strings: %s\n", var);
+
+ /* this is a\\b actually */
+ EXEC SQL INSERT INTO "My_Table" VALUES ( 1, 'a\\\\b' );
+ /* this is a\\b */
+ EXEC SQL INSERT INTO "My_Table" VALUES ( 1, E'a\\\\b' );
+
+ EXEC SQL SET standard_conforming_strings TO on;
+
+ EXEC SQL SHOW standard_conforming_strings INTO :var;
+ printf("Standard conforming strings: %s\n", var);
+
+ /* this is a\\\\b actually */
+ EXEC SQL INSERT INTO "My_Table" VALUES ( 2, 'a\\\\b' );
+ /* this is a\\b */
+ EXEC SQL INSERT INTO "My_Table" VALUES ( 2, E'a\\\\b' );
+
+ EXEC SQL BEGIN;
+ EXEC SQL DECLARE C CURSOR FOR SELECT * FROM "My_Table";
+
+ EXEC SQL OPEN C;
+
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ for (loopcount = 0; loopcount < 100; loopcount++)
+ {
+ EXEC SQL FETCH C INTO :i, :var;
+ printf("value: %d %s\n", i, var);
+ }
+
+ EXEC SQL ROLLBACK;
+ EXEC SQL DROP TABLE "My_Table";
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/show.pgc b/src/interfaces/ecpg/test/sql/show.pgc
new file mode 100644
index 0000000..339678a
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/show.pgc
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+EXEC SQL INCLUDE ../regression;
+
+int main() {
+ EXEC SQL BEGIN DECLARE SECTION;
+ char var[25] = "public";
+ 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 SET search_path TO :var;
+ EXEC SQL SHOW search_path INTO :var;
+ printf("Var: Search path: %s\n", var);
+
+ EXEC SQL SET search_path TO 'public';
+ EXEC SQL SHOW search_path INTO :var;
+ printf("Var: Search path: %s\n", var);
+
+ EXEC SQL SET standard_conforming_strings TO off;
+ EXEC SQL SHOW standard_conforming_strings INTO :var;
+ printf("Var: Standard conforming strings: %s\n", var);
+
+ EXEC SQL SET TIME ZONE PST8PDT;
+ EXEC SQL SHOW TIME ZONE INTO :var;
+ printf("Time Zone: %s\n", var);
+
+ EXEC SQL SET TRANSACTION ISOLATION LEVEL read committed;
+ EXEC SQL SHOW TRANSACTION ISOLATION LEVEL INTO :var;
+ printf("Transaction isolation level: %s\n", var);
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/sqlda.pgc b/src/interfaces/ecpg/test/sql/sqlda.pgc
new file mode 100644
index 0000000..e551385
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/sqlda.pgc
@@ -0,0 +1,266 @@
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "ecpg_config.h"
+
+exec sql include ../regression;
+exec sql include sqlda.h;
+exec sql include pgtypes_numeric.h;
+
+exec sql whenever sqlerror stop;
+
+/* These shouldn't be under DECLARE SECTION */
+sqlda_t *inp_sqlda, *outp_sqlda, *outp_sqlda1;
+
+static void
+dump_sqlda(sqlda_t *sqlda)
+{
+ int i;
+
+ if (sqlda == NULL)
+ {
+ printf("dump_sqlda called with NULL sqlda\n");
+ return;
+ }
+
+ for (i = 0; i < sqlda->sqld; i++)
+ {
+ if (sqlda->sqlvar[i].sqlind && *(sqlda->sqlvar[i].sqlind) == -1)
+ printf("name sqlda descriptor: '%s' value NULL'\n", sqlda->sqlvar[i].sqlname.data);
+ else
+ switch (sqlda->sqlvar[i].sqltype)
+ {
+ case ECPGt_char:
+ printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname.data, sqlda->sqlvar[i].sqldata);
+ break;
+ case ECPGt_int:
+ printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname.data, *(int *)sqlda->sqlvar[i].sqldata);
+ break;
+ case ECPGt_long:
+ printf("name sqlda descriptor: '%s' value %ld\n", sqlda->sqlvar[i].sqlname.data, *(long int *)sqlda->sqlvar[i].sqldata);
+ break;
+ case ECPGt_long_long:
+ printf(
+#ifdef _WIN32
+ "name sqlda descriptor: '%s' value %I64d\n",
+#else
+ "name sqlda descriptor: '%s' value %lld\n",
+#endif
+ sqlda->sqlvar[i].sqlname.data, *(long long int *)sqlda->sqlvar[i].sqldata);
+ break;
+ case ECPGt_double:
+ printf("name sqlda descriptor: '%s' value %f\n", sqlda->sqlvar[i].sqlname.data, *(double *)sqlda->sqlvar[i].sqldata);
+ break;
+ case ECPGt_numeric:
+ {
+ char *val;
+
+ val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1);
+ printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname.data, val);
+ PGTYPESchar_free(val);
+ break;
+ }
+ }
+ }
+}
+
+int
+main (void)
+{
+exec sql begin declare section;
+ char *stmt1 = "SELECT * FROM t1";
+ char *stmt2 = "SELECT * FROM t1 WHERE id = ?";
+ int rec;
+ int id;
+exec sql end declare section;
+
+ char msg[128];
+
+ ECPGdebug(1, stderr);
+
+ strcpy(msg, "connect");
+ exec sql connect to REGRESSDB1 as regress1;
+
+ strcpy(msg, "set");
+ exec sql set datestyle to iso;
+
+ strcpy(msg, "create");
+ exec sql create table t1(
+ id integer,
+ t text,
+ d1 numeric,
+ d2 float8,
+ c char(10),
+ big bigint
+ );
+
+ strcpy(msg, "insert");
+ exec sql insert into t1 values
+ (1, 'a', 1.0, 1, 'a',1111111111111111111),
+ (2, null, null, null, null,null),
+ (3, 'c', 0.0, 3, 'c',3333333333333333333),
+ (4, 'd', 'NaN', 4, 'd',4444444444444444444),
+ (5, 'e', 0.001234, 5, 'e',5555555555555555555);
+
+ strcpy(msg, "commit");
+ exec sql commit;
+
+ /* SQLDA test for getting all records from a table */
+
+ outp_sqlda = NULL;
+
+ strcpy(msg, "prepare");
+ exec sql prepare st_id1 from :stmt1;
+
+ strcpy(msg, "declare");
+ exec sql declare mycur1 cursor for st_id1;
+
+ strcpy(msg, "open");
+ exec sql open mycur1;
+
+ exec sql whenever not found do break;
+
+ rec = 0;
+ while (1)
+ {
+ strcpy(msg, "fetch");
+ exec sql fetch 1 from mycur1 into descriptor outp_sqlda;
+
+ printf("FETCH RECORD %d\n", ++rec);
+ dump_sqlda(outp_sqlda);
+ }
+
+ exec sql whenever not found continue;
+
+ strcpy(msg, "close");
+ exec sql close mycur1;
+
+ strcpy(msg, "deallocate");
+ exec sql deallocate prepare st_id1;
+
+ free(outp_sqlda);
+
+ /* SQLDA test for getting ALL records into the sqlda list */
+
+ outp_sqlda = NULL;
+
+ strcpy(msg, "prepare");
+ exec sql prepare st_id2 from :stmt1;
+
+ strcpy(msg, "declare");
+ exec sql declare mycur2 cursor for st_id2;
+
+ strcpy(msg, "open");
+ exec sql open mycur2;
+
+ strcpy(msg, "fetch");
+ exec sql fetch all from mycur2 into descriptor outp_sqlda;
+
+ outp_sqlda1 = outp_sqlda;
+ rec = 0;
+ while (outp_sqlda1)
+ {
+ sqlda_t *ptr;
+ printf("FETCH RECORD %d\n", ++rec);
+ dump_sqlda(outp_sqlda1);
+
+ ptr = outp_sqlda1;
+ outp_sqlda1 = outp_sqlda1->desc_next;
+ free(ptr);
+ }
+
+ strcpy(msg, "close");
+ exec sql close mycur2;
+
+ strcpy(msg, "deallocate");
+ exec sql deallocate prepare st_id2;
+
+ /* SQLDA test for getting one record using an input descriptor */
+
+ /*
+ * Input sqlda has to be built manually
+ * sqlda_t contains 1 sqlvar_t structure already.
+ */
+ inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t));
+ memset(inp_sqlda, 0, sizeof(sqlda_t));
+ inp_sqlda->sqln = 1;
+
+ inp_sqlda->sqlvar[0].sqltype = ECPGt_int;
+ inp_sqlda->sqlvar[0].sqldata = (char *)&id;
+
+ printf("EXECUTE RECORD 4\n");
+
+ id = 4;
+
+ outp_sqlda = NULL;
+
+ strcpy(msg, "prepare");
+ exec sql prepare st_id3 FROM :stmt2;
+
+ strcpy(msg, "execute");
+ exec sql execute st_id3 using descriptor inp_sqlda into descriptor outp_sqlda;
+
+ dump_sqlda(outp_sqlda);
+
+ strcpy(msg, "deallocate");
+ exec sql deallocate prepare st_id3;
+
+ free(inp_sqlda);
+ free(outp_sqlda);
+
+ /* SQLDA test for getting one record using an input descriptor
+ * on a named connection
+ */
+
+ exec sql connect to REGRESSDB1 as con2;
+
+ /*
+ * Input sqlda has to be built manually
+ * sqlda_t contains 1 sqlvar_t structure already.
+ */
+ inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t));
+ memset(inp_sqlda, 0, sizeof(sqlda_t));
+ inp_sqlda->sqln = 1;
+
+ inp_sqlda->sqlvar[0].sqltype = ECPGt_int;
+ inp_sqlda->sqlvar[0].sqldata = (char *)&id;
+
+ printf("EXECUTE RECORD 4\n");
+
+ id = 4;
+
+ outp_sqlda = NULL;
+
+ strcpy(msg, "prepare");
+ exec sql at con2 prepare st_id4 FROM :stmt2;
+
+ strcpy(msg, "execute");
+ exec sql at con2 execute st_id4 using descriptor inp_sqlda into descriptor outp_sqlda;
+
+ dump_sqlda(outp_sqlda);
+
+ strcpy(msg, "commit");
+ exec sql at con2 commit;
+
+ strcpy(msg, "deallocate");
+ exec sql deallocate prepare st_id4;
+
+ free(inp_sqlda);
+ free(outp_sqlda);
+
+ strcpy(msg, "disconnect");
+ exec sql disconnect con2;
+
+ /* End test */
+
+ strcpy(msg, "drop");
+ exec sql drop table t1;
+
+ strcpy(msg, "commit");
+ exec sql commit;
+
+ strcpy(msg, "disconnect");
+ exec sql disconnect;
+
+ return 0;
+}
diff --git a/src/interfaces/ecpg/test/sql/twophase.pgc b/src/interfaces/ecpg/test/sql/twophase.pgc
new file mode 100644
index 0000000..38913d7
--- /dev/null
+++ b/src/interfaces/ecpg/test/sql/twophase.pgc
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+exec sql include ../regression;
+
+exec sql whenever sqlerror sqlprint;
+
+int main(void)
+{
+ char msg[128];
+
+ ECPGdebug(1, stderr);
+
+ strcpy(msg, "connect");
+ exec sql connect to REGRESSDB1;
+ exec sql set autocommit to off;
+
+ strcpy(msg, "create");
+ exec sql create table t1(c int);
+
+ strcpy(msg, "commit");
+ exec sql commit;
+
+ strcpy(msg, "begin");
+ exec sql begin;
+
+ strcpy(msg, "insert");
+ exec sql insert into t1 values(1);
+
+ strcpy(msg, "prepare transaction");
+ exec sql prepare transaction 'gxid';
+
+ strcpy(msg, "commit prepared");
+ exec sql commit prepared 'gxid';
+
+ strcpy(msg, "drop");
+ exec sql drop table t1;
+
+ strcpy(msg, "disconnect");
+ exec sql disconnect current;
+
+ return 0;
+}