diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:15:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:15:05 +0000 |
commit | 46651ce6fe013220ed397add242004d764fc0153 (patch) | |
tree | 6e5299f990f88e60174a1d3ae6e48eedd2688b2b /src/interfaces/ecpg/test/compat_informix | |
parent | Initial commit. (diff) | |
download | postgresql-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/compat_informix')
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/.gitignore | 18 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/Makefile | 24 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/charfuncs.pgc | 31 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/dec_test.pgc | 238 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/describe.pgc | 199 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/rfmtdate.pgc | 175 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/rfmtlong.pgc | 73 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/rnull.pgc | 97 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/sqlda.pgc | 250 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/test_informix.pgc | 95 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/compat_informix/test_informix2.pgc | 122 |
11 files changed, 1322 insertions, 0 deletions
diff --git a/src/interfaces/ecpg/test/compat_informix/.gitignore b/src/interfaces/ecpg/test/compat_informix/.gitignore new file mode 100644 index 0000000..f97706b --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/.gitignore @@ -0,0 +1,18 @@ +/charfuncs +/charfuncs.c +/dec_test +/dec_test.c +/describe +/describe.c +/rfmtdate +/rfmtdate.c +/rfmtlong +/rfmtlong.c +/rnull +/rnull.c +/sqlda +/sqlda.c +/test_informix +/test_informix.c +/test_informix2 +/test_informix2.c diff --git a/src/interfaces/ecpg/test/compat_informix/Makefile b/src/interfaces/ecpg/test/compat_informix/Makefile new file mode 100644 index 0000000..d50fdc2 --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/Makefile @@ -0,0 +1,24 @@ +subdir = src/interfaces/ecpg/test/compat_informix +top_builddir = ../../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/$(subdir)/../Makefile.regress + +# Use special informix compatibility switch for all tests in this directory +ECPG += -C INFORMIX + +LDFLAGS_INTERNAL += -L../../compatlib -lecpg_compat + +TESTS = test_informix test_informix.c \ + test_informix2 test_informix2.c \ + dec_test dec_test.c \ + rfmtdate rfmtdate.c \ + rfmtlong rfmtlong.c \ + rnull rnull.c \ + sqlda sqlda.c \ + describe describe.c \ + charfuncs charfuncs.c + +all: $(TESTS) + +rnull.c: rnull.pgc $(ECPG_TEST_DEPENDENCIES) + $(ECPG) -r no_indicator -o $@ $< diff --git a/src/interfaces/ecpg/test/compat_informix/charfuncs.pgc b/src/interfaces/ecpg/test/compat_informix/charfuncs.pgc new file mode 100644 index 0000000..3605c9d --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/charfuncs.pgc @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sqltypes.h> + +int main(void) +{ + char t1[] = "abc def ghi "; + /* 123456789012345 */ + char buf[50]; + int k; + + printf("t1: _%s_\n", t1); + rupshift(t1); + printf("t1: _%s_\n", t1); + + k = 2; + ldchar(t1, k, buf); + printf("byleng(t1, %d): %d, ldchar: _%s_\n", k, byleng(t1, k), buf); + k = 5; + ldchar(t1, k, buf); + printf("byleng(t1, %d): %d, ldchar: _%s_\n", k, byleng(t1, k), buf); + k = 9; + ldchar(t1, k, buf); + printf("byleng(t1, %d): %d, ldchar: _%s_\n", k, byleng(t1, k), buf); + k = 15; + ldchar(t1, k, buf); + printf("byleng(t1, %d): %d, ldchar: _%s_\n", k, byleng(t1, k), buf); + + + return 0; +} diff --git a/src/interfaces/ecpg/test/compat_informix/dec_test.pgc b/src/interfaces/ecpg/test/compat_informix/dec_test.pgc new file mode 100644 index 0000000..f6a9f42 --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/dec_test.pgc @@ -0,0 +1,238 @@ +#include <stdio.h> +#include <stdlib.h> +#include <pgtypes_numeric.h> +#include <pgtypes_error.h> +#include <decimal.h> +#include <sqltypes.h> + +exec sql include ../regression; + +exec sql include ../printf_hack; + + +/* +TODO: + deccmp => DECUNKNOWN + decimal point: , and/or . ? + ECPG_INFORMIX_BAD_EXPONENT ? +*/ + +char* decs[] = { "2E394", "-2", ".794", "3.44", "592.49E21", "-32.84e4", + "2E-394", ".1E-2", "+.0", "-592.49E-07", "+32.84e-4", + ".500001", "-.5000001", + "1234567890123456789012345678.91", /* 30 digits should fit + into decimal */ + "1234567890123456789012345678.921", /* 31 digits should NOT + fit into decimal */ + "not a number", + NULL}; + + +static void +check_errno(void); + +#define BUFSIZE 200 + +int +main(void) +{ + decimal *dec, *din; + char buf[BUFSIZE]; + long l; + int i, j, k, q, r, count = 0; + double dbl; + decimal **decarr = (decimal **) calloc(1, sizeof(decimal)); + + ECPGdebug(1, stderr); + + for (i = 0; decs[i]; i++) + { + dec = PGTYPESdecimal_new(); + r = deccvasc(decs[i], strlen(decs[i]), dec); + if (r) + { + check_errno(); + printf("dec[%d,0]: r: %d\n", i, r); + PGTYPESdecimal_free(dec); + continue; + } + decarr = realloc(decarr, sizeof(decimal *) * (count + 1)); + decarr[count++] = dec; + + r = dectoasc(dec, buf, BUFSIZE-1, -1); + if (r < 0) check_errno(); + printf("dec[%d,1]: r: %d, %s\n", i, r, buf); + + r = dectoasc(dec, buf, BUFSIZE-1, 0); + if (r < 0) check_errno(); + printf("dec[%d,2]: r: %d, %s\n", i, r, buf); + r = dectoasc(dec, buf, BUFSIZE-1, 1); + if (r < 0) check_errno(); + printf("dec[%d,3]: r: %d, %s\n", i, r, buf); + r = dectoasc(dec, buf, BUFSIZE-1, 2); + if (r < 0) check_errno(); + printf("dec[%d,4]: r: %d, %s\n", i, r, buf); + + din = PGTYPESdecimal_new(); + r = dectoasc(din, buf, BUFSIZE-1, 2); + if (r < 0) check_errno(); + printf("dec[%d,5]: r: %d, %s\n", i, r, buf); + + r = dectolong(dec, &l); + if (r) check_errno(); + printf("dec[%d,6]: %ld (r: %d)\n", i, r?0L:l, r); + if (r == 0) + { + r = deccvlong(l, din); + if (r) check_errno(); + dectoasc(din, buf, BUFSIZE-1, 2); + q = deccmp(dec, din); + printf("dec[%d,7]: %s (r: %d - cmp: %d)\n", i, buf, r, q); + } + + r = dectoint(dec, &k); + if (r) check_errno(); + printf("dec[%d,8]: %d (r: %d)\n", i, r?0:k, r); + if (r == 0) + { + r = deccvint(k, din); + if (r) check_errno(); + dectoasc(din, buf, BUFSIZE-1, 2); + q = deccmp(dec, din); + printf("dec[%d,9]: %s (r: %d - cmp: %d)\n", i, buf, r, q); + } + + if (i != 6) + { + /* underflow does not work reliable on several archs, so not testing it here */ + /* this is a libc problem since we only call strtod() */ + r = dectodbl(dec, &dbl); + if (r) check_errno(); + printf("dec[%d,10]: ", i); + print_double(r ? 0.0 : dbl); + printf(" (r: %d)\n", r); + } + + PGTYPESdecimal_free(din); + printf("\n"); + } + + /* add a NULL value */ + dec = PGTYPESdecimal_new(); + decarr = realloc(decarr, sizeof(decimal *) * (count + 1)); + decarr[count++] = dec; + + rsetnull(CDECIMALTYPE, (char *) decarr[count-1]); + printf("dec[%d]: %sNULL\n", count-1, + risnull(CDECIMALTYPE, (char *) decarr[count-1]) ? "" : "NOT "); + printf("dec[0]: %sNULL\n", + risnull(CDECIMALTYPE, (char *) decarr[0]) ? "" : "NOT "); + + r = dectoasc(decarr[3], buf, -1, -1); + check_errno(); printf("dectoasc with len == -1: r: %d\n", r); + r = dectoasc(decarr[3], buf, 0, -1); + check_errno(); printf("dectoasc with len == 0: r: %d\n", r); + + for (i = 0; i < count; i++) + { + for (j = 0; j < count; j++) + { + decimal a, s, m, d; + int c; + c = deccmp(decarr[i], decarr[j]); + printf("dec[c,%d,%d]: %d\n", i, j, c); + + r = decadd(decarr[i], decarr[j], &a); + if (r) + { + check_errno(); + printf("r: %d\n", r); + } + else + { + dectoasc(&a, buf, BUFSIZE-1, -1); + printf("dec[a,%d,%d]: %s\n", i, j, buf); + } + + r = decsub(decarr[i], decarr[j], &s); + if (r) + { + check_errno(); + printf("r: %d\n", r); + } + else + { + dectoasc(&s, buf, BUFSIZE-1, -1); + printf("dec[s,%d,%d]: %s\n", i, j, buf); + } + + r = decmul(decarr[i], decarr[j], &m); + if (r) + { + check_errno(); + printf("r: %d\n", r); + } + else + { + dectoasc(&m, buf, BUFSIZE-1, -1); + printf("dec[m,%d,%d]: %s\n", i, j, buf); + } + + r = decdiv(decarr[i], decarr[j], &d); + if (r) + { + check_errno(); + printf("r: %d\n", r); + } + else + { + dectoasc(&d, buf, BUFSIZE-1, -1); + printf("dec[d,%d,%d]: %s\n", i, j, buf); + } + } + } + + for (i = 0; i < count; i++) + { + dectoasc(decarr[i], buf, BUFSIZE-1, -1); + printf("%d: %s\n", i, buf); + + PGTYPESdecimal_free(decarr[i]); + } + free(decarr); + + return 0; +} + +static void +check_errno(void) +{ + switch(errno) + { + case 0: + printf("(no errno set) - "); + break; + case ECPG_INFORMIX_NUM_OVERFLOW: + printf("(errno == ECPG_INFORMIX_NUM_OVERFLOW) - "); + break; + case ECPG_INFORMIX_NUM_UNDERFLOW: + printf("(errno == ECPG_INFORMIX_NUM_UNDERFLOW) - "); + break; + case PGTYPES_NUM_OVERFLOW: + printf("(errno == PGTYPES_NUM_OVERFLOW) - "); + break; + case PGTYPES_NUM_UNDERFLOW: + printf("(errno == PGTYPES_NUM_UNDERFLOW) - "); + break; + case PGTYPES_NUM_BAD_NUMERIC: + printf("(errno == PGTYPES_NUM_BAD_NUMERIC) - "); + break; + case PGTYPES_NUM_DIVIDE_ZERO: + printf("(errno == PGTYPES_NUM_DIVIDE_ZERO) - "); + break; + default: + printf("(unknown errno (%d))\n", errno); + printf("(libc: (%s)) ", strerror(errno)); + break; + } +} diff --git a/src/interfaces/ecpg/test/compat_informix/describe.pgc b/src/interfaces/ecpg/test/compat_informix/describe.pgc new file mode 100644 index 0000000..4ee7254 --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/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_t1"; + char *stmt2 = "SELECT id, t FROM descr_t1 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_t1(id serial primary key, t text); + + strcpy(msg, "insert"); + exec sql insert into descr_t1(id, t) values (default, 'a'); + exec sql insert into descr_t1(id, t) values (default, 'b'); + exec sql insert into descr_t1(id, t) values (default, 'c'); + exec sql insert into descr_t1(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, + sqlda2->sqlvar[i-1].sqlname, + sqlda3->sqlvar[i-1].sqlname); + } + + 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, + sqlda2->sqlvar[i-1].sqlname, + sqlda3->sqlvar[i-1].sqlname); + } + + 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_t1; + + strcpy(msg, "commit"); + exec sql commit; + + strcpy(msg, "disconnect"); + exec sql disconnect; + + return 0; +} diff --git a/src/interfaces/ecpg/test/compat_informix/rfmtdate.pgc b/src/interfaces/ecpg/test/compat_informix/rfmtdate.pgc new file mode 100644 index 0000000..a147f40 --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/rfmtdate.pgc @@ -0,0 +1,175 @@ +#include <stdio.h> +#include <stdlib.h> +#include <pgtypes_error.h> +#include <sqltypes.h> + +/* + * This file tests various forms of date-input/output by means of + * rfmtdate / rdefmtdate / rstrdate + */ + + +static void +check_return(int ret); + +static void +date_test_strdate(const char *input) +{ + static int i; + date d; + int r, q; + char dbuf[11]; + + r = rstrdate(input, &d); + printf("r: %d ", r); + if (r == 0) + { + q = rdatestr(d, dbuf); + printf("q: %d ", q); + if (q == 0) + { + printf("date %d: %s\n", i++, dbuf); + } + else + printf("\n"); + } + else + check_return(r); +} + +static void +date_test_defmt(const char *fmt, const char *input) +{ + static int i; + char dbuf[11]; + date d; + int q, r; + + r = rdefmtdate(&d, fmt, input); + printf("r: %d ", r); + if (r == 0) + { + q = rdatestr(d, dbuf); + printf("q: %d ", q); + if (q == 0) + { + printf("date %d: %s\n", i++, dbuf); + } + else + printf("\n"); + } + else + check_return(r); +} + +static void +date_test_fmt(date d, const char *fmt) +{ + static int i; + char buf[200]; + int r; + + r = rfmtdate(d, fmt, buf); + printf("r: %d ", r); + if (r != 0) + check_return(r); + else + printf("date: %d: %s\n", i++, buf); +} + + +int +main(void) +{ + short mdy[3] = { 11, 23, 1959 }; + char dbuf[11]; + date d; + int r; + + ECPGdebug(1, stderr); + + r = rmdyjul(mdy, &d); + printf("create: r: %d\n", r); + if (r == 0) + { + rdatestr(d, dbuf); + printf("date: %s\n", dbuf); + } + + /* input mask is mmddyyyy */ + date_test_strdate("12031994"); + date_test_strdate("9.6.1994"); + + date_test_fmt(d, "mmddyy"); + date_test_fmt(d, "ddmmyy"); + date_test_fmt(d, "yymmdd"); + date_test_fmt(d, "yy/mm/dd"); + date_test_fmt(d, "yy mm dd"); + date_test_fmt(d, "yy.mm.dd"); + date_test_fmt(d, ".mm.yyyy.dd."); + date_test_fmt(d, "mmm. dd, yyyy"); + date_test_fmt(d, "mmm dd yyyy"); + date_test_fmt(d, "yyyy dd mm"); + date_test_fmt(d, "ddd, mmm. dd, yyyy"); + date_test_fmt(d, "(ddd) mmm. dd, yyyy"); + + date_test_defmt("ddmmyy", "21-2-54"); + date_test_defmt("ddmmyy", "2-12-54"); + date_test_defmt("ddmmyy", "20111954"); + date_test_defmt("ddmmyy", "130464"); + date_test_defmt("mmm.dd.yyyy", "MAR-12-1967"); + date_test_defmt("yy/mm/dd", "1954, February 3rd"); + date_test_defmt("mmm.dd.yyyy", "041269"); + date_test_defmt("yy/mm/dd", "In the year 2525, in the month of July, mankind will be alive on the 28th day"); + date_test_defmt("dd-mm-yy", "I said on the 28th of July in the year 2525"); + date_test_defmt("mmm.dd.yyyy", "9/14/58"); + date_test_defmt("yy/mm/dd", "47/03/29"); + date_test_defmt("mmm.dd.yyyy", "oct 28 1975"); + date_test_defmt("mmddyy", "Nov 14th, 1985"); + /* ok: still contains dd mm yy */ + date_test_defmt("bladdfoommbaryybong", "20/11/1954"); + /* 1994 is not a leap year, it accepts the date as 01-03-1994 */ + date_test_defmt("ddmmyy", "29-02-1994"); + + /* ECPG_INFORMIX_ENOTDMY, need "dd", "mm" and "yy" */ + date_test_defmt("dmy", "20/11/1954"); + + /* ECPG_INFORMIX_ENOSHORTDATE */ + date_test_defmt("ddmmyy", "21254"); + date_test_defmt("ddmmyy", " 21254 "); + + /* ECPG_INFORMIX_BAD_DAY */ + date_test_defmt("ddmmyy", "320494"); + + /* ECPG_INFORMIX_BAD_MONTH */ + date_test_defmt("mm-yyyy-dd", "13-1993-21"); + + /* ECPG_INFORMIX_BAD_YEAR */ + /* ??? */ + + return 0; +} + +static void +check_return(int ret) +{ + switch(ret) + { + case ECPG_INFORMIX_ENOTDMY: + printf("(ECPG_INFORMIX_ENOTDMY)"); + break; + case ECPG_INFORMIX_ENOSHORTDATE: + printf("(ECPG_INFORMIX_ENOSHORTDATE)"); + break; + case ECPG_INFORMIX_BAD_DAY: + printf("(ECPG_INFORMIX_BAD_DAY)"); + break; + case ECPG_INFORMIX_BAD_MONTH: + printf("(ECPG_INFORMIX_BAD_MONTH)"); + break; + default: + printf("(unknown ret: %d)", ret); + break; + } + printf("\n"); +} diff --git a/src/interfaces/ecpg/test/compat_informix/rfmtlong.pgc b/src/interfaces/ecpg/test/compat_informix/rfmtlong.pgc new file mode 100644 index 0000000..2ecf09c --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/rfmtlong.pgc @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <stdlib.h> +#include <pgtypes_error.h> +#include <sqltypes.h> + +/* + * This file tests various forms of long-input/output by means of + * rfmtlong + */ + + +static void +check_return(int ret); + +static void +fmtlong(long lng, const char *fmt) +{ + static int i; + int r; + char buf[30]; + + r = rfmtlong(lng, fmt, buf); + printf("r: %d ", r); + if (r == 0) + { + printf("%d: %s (fmt was: %s)\n", i++, buf, fmt); + } + else + check_return(r); +} + +int +main(void) +{ + ECPGdebug(1, stderr); + + fmtlong(-8494493, "-<<<<,<<<,<<<,<<<"); + fmtlong(-8494493, "################"); + fmtlong(-8494493, "+++$$$$$$$$$$$$$.##"); + fmtlong(-8494493, "(&,&&&,&&&,&&&.)"); + fmtlong(-8494493, "<<<<,<<<,<<<,<<<"); + fmtlong(-8494493, "$************.**"); + fmtlong(-8494493, "---$************.**"); + fmtlong(-8494493, "+-+################"); + fmtlong(-8494493, "abc: ################+-+"); + fmtlong(-8494493, "+<<<<,<<<,<<<,<<<"); + + return 0; +} + +static void +check_return(int ret) +{ + switch(ret) + { + case ECPG_INFORMIX_ENOTDMY: + printf("(ECPG_INFORMIX_ENOTDMY)"); + break; + case ECPG_INFORMIX_ENOSHORTDATE: + printf("(ECPG_INFORMIX_ENOSHORTDATE)"); + break; + case ECPG_INFORMIX_BAD_DAY: + printf("(ECPG_INFORMIX_BAD_DAY)"); + break; + case ECPG_INFORMIX_BAD_MONTH: + printf("(ECPG_INFORMIX_BAD_MONTH)"); + break; + default: + printf("(unknown ret: %d)", ret); + break; + } + printf("\n"); +} diff --git a/src/interfaces/ecpg/test/compat_informix/rnull.pgc b/src/interfaces/ecpg/test/compat_informix/rnull.pgc new file mode 100644 index 0000000..a6ad35e --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/rnull.pgc @@ -0,0 +1,97 @@ +#include "sqltypes.h" +#include <stdlib.h> + +$include ../regression; +$define NUMBER 12; + +static void +test_null(int type, char *ptr) +{ + printf("null: %d\n", risnull(type, ptr)); +} + +int main(void) +{ + $char c[] = "abc"; + $short s = 17; + $int i = -74874; + $bool b = 1; + $float f = 3.71; + $long l = 487444; + $double dbl = 404.404; + $decimal dec; + $date dat; + $timestamp tmp; + + ECPGdebug(1, stderr); + $whenever sqlerror do sqlprint(); + + $connect to REGRESSDB1; + + $create table test(id int, c char(10), s smallint, i int, b bool, + f float, l bigint, dbl double precision, + dec decimal, dat date, tmp timestamptz); + $commit; + + $insert into test (id, c, s, i, b, f, l, dbl) values ( + 1, :c, :s, :i, :b, :f, :l, :dbl + ); + $commit; + + rsetnull(CCHARTYPE, (char *) c); + rsetnull(CSHORTTYPE, (char *) &s); + rsetnull(CINTTYPE, (char *) &i); + rsetnull(CBOOLTYPE, (char *) &b); + rsetnull(CFLOATTYPE, (char *) &f); + rsetnull(CLONGTYPE, (char *) &l); + rsetnull(CDOUBLETYPE, (char *) &dbl); + rsetnull(CDECIMALTYPE, (char *) &dec); + rsetnull(CDATETYPE, (char *) &dat); + rsetnull(CDTIMETYPE, (char *) &tmp); + + $insert into test (id, c, s, i, b, f, l, dbl, dec, dat, tmp) values ( + 2, :c, :s, :i, :b, :f, :l, :dbl, :dec, :dat, :tmp + ); + $commit; + + printf("first select\n"); + + $select c, s, i, b, f, l, dbl, dec, dat, tmp + into :c, :s, :i, :b, :f, :l, :dbl, :dec, :dat, :tmp + from test where id = 1; + + test_null(CCHARTYPE, (char *) c); + test_null(CSHORTTYPE, (char *) &s); + test_null(CINTTYPE, (char *) &i); + test_null(CBOOLTYPE, (char *) &b); + test_null(CFLOATTYPE, (char *) &f); + test_null(CLONGTYPE, (char *) &l); + test_null(CDOUBLETYPE, (char *) &dbl); + test_null(CDECIMALTYPE, (char *) &dec); + test_null(CDATETYPE, (char *) &dat); + test_null(CDTIMETYPE, (char *) &tmp); + + printf("second select\n"); + + $select c, s, i, b, f, l, dbl, dec, dat, tmp + into :c, :s, :i, :b, :f, :l, :dbl, :dec, :dat, :tmp + from test where id = 2; + + test_null(CCHARTYPE, (char *) c); + test_null(CSHORTTYPE, (char *) &s); + test_null(CINTTYPE, (char *) &i); + test_null(CBOOLTYPE, (char *) &b); + test_null(CFLOATTYPE, (char *) &f); + test_null(CLONGTYPE, (char *) &l); + test_null(CDOUBLETYPE, (char *) &dbl); + test_null(CDECIMALTYPE, (char *) &dec); + test_null(CDATETYPE, (char *) &dat); + test_null(CDTIMETYPE, (char *) &tmp); + + $drop table test; + $commit; + + $close database; + + return 0; +} diff --git a/src/interfaces/ecpg/test/compat_informix/sqlda.pgc b/src/interfaces/ecpg/test/compat_informix/sqlda.pgc new file mode 100644 index 0000000..87e0110 --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/sqlda.pgc @@ -0,0 +1,250 @@ +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +exec sql include ../regression; + +exec sql include sqlda.h; +exec sql include sqltypes.h; + +exec sql whenever sqlerror stop; + +/* These shouldn't be under DECLARE SECTION */ +sqlda_t *inp_sqlda, *outp_sqlda; + +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); + else + switch (sqlda->sqlvar[i].sqltype) + { + case SQLCHAR: + printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata); + break; + case SQLINT: + printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata); + break; + case SQLFLOAT: + printf("name sqlda descriptor: '%s' value %f\n", sqlda->sqlvar[i].sqlname, *(double *)sqlda->sqlvar[i].sqldata); + break; + case SQLDECIMAL: + { + char val[64]; + dectoasc((dec_t *)sqlda->sqlvar[i].sqldata, val, 64, -1); + printf("name sqlda descriptor: '%s' value DECIMAL '%s'\n", sqlda->sqlvar[i].sqlname, 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)); + + strcpy(msg, "insert"); + exec sql insert into t1 values + (1, 'a', 1.0, 1, 'a'), + (2, null, null, null, null), + (4, 'd', 4.0, 4, 'd'); + + 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 from a table + using the Informix-specific FETCH ... USING DESCRIPTOR + */ + + 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; + + exec sql whenever not found do break; + + rec = 0; + while (1) + { + strcpy(msg, "fetch"); + exec sql fetch from mycur2 using 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 mycur2; + + strcpy(msg, "deallocate"); + exec sql deallocate prepare st_id2; + + free(outp_sqlda); + + /* SQLDA test for getting one record using an input descriptor */ + + /* Input sqlda has to be built manually */ + inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t)); + memset(inp_sqlda, 0, sizeof(sqlda_t)); + inp_sqlda->sqld = 1; + inp_sqlda->sqlvar = malloc(sizeof(sqlvar_t)); + memset(inp_sqlda->sqlvar, 0, sizeof(sqlvar_t)); + + inp_sqlda->sqlvar[0].sqltype = SQLINT; + 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->sqlvar); + 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 */ + inp_sqlda = (sqlda_t *)malloc(sizeof(sqlda_t)); + memset(inp_sqlda, 0, sizeof(sqlda_t)); + inp_sqlda->sqld = 1; + inp_sqlda->sqlvar = malloc(sizeof(sqlvar_t)); + memset(inp_sqlda->sqlvar, 0, sizeof(sqlvar_t)); + + inp_sqlda->sqlvar[0].sqltype = SQLINT; + 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->sqlvar); + 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/compat_informix/test_informix.pgc b/src/interfaces/ecpg/test/compat_informix/test_informix.pgc new file mode 100644 index 0000000..0911efe --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/test_informix.pgc @@ -0,0 +1,95 @@ +#include "sqltypes.h" +#include <stdlib.h> + +$include ../regression; +$define NUMBER 12; + +static void openit(void); +static void dosqlprint(void) { + printf("doSQLprint: Error: %s\n", sqlca.sqlerrm.sqlerrmc); +} + +int main(void) +{ + $int i = 14, loopcount; + $decimal j, m, n; + $string c[10]; + + ECPGdebug(1, stderr); + $whenever sqlerror do dosqlprint(); + + $connect to REGRESSDB1; + if (sqlca.sqlcode != 0) exit(1); + + $create table test(i int primary key, j int, c text); + + /* this INSERT works */ + rsetnull(CDECIMALTYPE, (char *)&j); + $insert into test (i, j, c) values (7, :j, 'test '); + $commit; + + /* this INSERT should fail because i is a unique column */ + $insert into test (i, j, c) values (7, NUMBER, 'a'); + printf("INSERT: %ld=%s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + if (sqlca.sqlcode != 0) $rollback; + + $insert into test (i, j, c) values (:i, 1, 'a '); + $commit; + + /* this will fail (more than one row in subquery) */ + $select i from test where j=(select j from test); + $rollback; + + /* this however should be ok */ + $select i from test where j=(select j from test order by i limit 1); + printf("SELECT: %ld=%s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); + if (sqlca.sqlcode != 0) $rollback; + + sqlca.sqlcode = 100; + $declare c cursor for select * from test where i <= :i; + printf ("%ld\n", sqlca.sqlcode); + openit(); + + deccvint(0, &j); + + for (loopcount = 0; loopcount < 100; loopcount++) + { + $fetch forward c into :i, :j, :c; + if (sqlca.sqlcode == 100) break; + + if (risnull(CDECIMALTYPE, (char *)&j)) + printf("%d NULL\n", i); + else + { + int a; + + dectoint(&j, &a); + printf("%d %d \"%s\"\n", i, a, c); + } + } + + deccvint(7, &j); + deccvint(14, &m); + decadd(&j, &m, &n); + $delete from test where i= :n::decimal; + printf("DELETE: %ld\n", sqlca.sqlcode); + + $select 1 from test where i=14; + printf("Exists: %ld\n", sqlca.sqlcode); + + $select 1 from test where i=147; + printf("Does not exist: %ld\n", sqlca.sqlcode); + + $commit; + $drop table test; + $commit; + + $close database; + + return 0; +} + +static void openit(void) +{ + $open c; +} diff --git a/src/interfaces/ecpg/test/compat_informix/test_informix2.pgc b/src/interfaces/ecpg/test/compat_informix/test_informix2.pgc new file mode 100644 index 0000000..224f2da --- /dev/null +++ b/src/interfaces/ecpg/test/compat_informix/test_informix2.pgc @@ -0,0 +1,122 @@ +#include <stdio.h> +#include <stdlib.h> +#include "sqltypes.h" + +EXEC SQL include sqlca.h; +EXEC SQL include ../regression; +EXEC SQL DEFINE MAXDBLEN 30; + +/* Check SQLCODE, and produce a "standard error" if it's wrong! */ +static void sql_check(const char *fn, const char *caller, int ignore) +{ + char errorstring[255]; + + if (SQLCODE == ignore) + return; + else + { + if (SQLCODE != 0) + { + + sprintf(errorstring, "**SQL error %ld doing '%s' in function '%s'. [%s]", + SQLCODE, caller, fn, sqlca.sqlerrm.sqlerrmc); + fprintf(stderr, "%s", errorstring); + printf("%s\n", errorstring); + + /* attempt a ROLLBACK */ + EXEC SQL rollback; + + if (SQLCODE == 0) + { + sprintf(errorstring, "Rollback successful.\n"); + } else { + sprintf(errorstring, "Rollback failed with code %ld.\n", SQLCODE); + } + + fprintf(stderr, "%s", errorstring); + printf("%s\n", errorstring); + + exit(1); + } + } +} + +int main(void) +{ + EXEC SQL BEGIN DECLARE SECTION; + int c; + timestamp d; + timestamp e; + timestamp maxd; + char dbname[30]; + EXEC SQL END DECLARE SECTION; + + interval *intvl; + + EXEC SQL whenever sqlerror stop; + + ECPGdebug(1, stderr); + + strcpy(dbname, "ecpg1_regression"); + EXEC SQL connect to :dbname; + sql_check("main", "connect", 0); + + EXEC SQL SET DateStyle TO 'DMY'; + + EXEC SQL create table history (customerid integer, timestamp timestamp without time zone, action_taken char(5), narrative varchar(100)); + sql_check("main", "create", 0); + + EXEC SQL insert into history + (customerid, timestamp, action_taken, narrative) + values(1, '2003-05-07 13:28:34 CEST', 'test', 'test'); + sql_check("main", "insert", 0); + + EXEC SQL select max(timestamp) + into :maxd + from history; + sql_check("main", "select max", 100); + + EXEC SQL select customerid, timestamp + into :c, :d + from history + where timestamp = :maxd + limit 1; + sql_check("main", "select", 0); + + printf("Read in customer %d\n", c); + + intvl = PGTYPESinterval_from_asc("1 day 2 hours 24 minutes 65 seconds", NULL); + PGTYPEStimestamp_add_interval(&d, intvl, &e); + free(intvl); + c++; + + EXEC SQL insert into history + (customerid, timestamp, action_taken, narrative) + values(:c, :e, 'test', 'test'); + sql_check("main", "update", 0); + + EXEC SQL commit; + + EXEC SQL drop table history; + sql_check("main", "drop", 0); + + EXEC SQL commit; + + EXEC SQL disconnect; + sql_check("main", "disconnect", 0); + + printf("All OK!\n"); + + exit(0); + +/* + Table "public.history" + Column | Type | Nullable +--------------+-----------------------------+---------- + customerid | integer | not null + timestamp | timestamp without time zone | not null + action_taken | character(5) | not null + narrative | character varying(100) | +*/ + +} |