diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:46:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:46:48 +0000 |
commit | 311bcfc6b3acdd6fd152798c7f287ddf74fa2a98 (patch) | |
tree | 0ec307299b1dada3701e42f4ca6eda57d708261e /src/interfaces/ecpg/test/sql | |
parent | Initial commit. (diff) | |
download | postgresql-15-311bcfc6b3acdd6fd152798c7f287ddf74fa2a98.tar.xz postgresql-15-311bcfc6b3acdd6fd152798c7f287ddf74fa2a98.zip |
Adding upstream version 15.4.upstream/15.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/interfaces/ecpg/test/sql')
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; +} |