Review of "SQLDA support for ECPG"

Started by Noah Mischover 16 years ago13 messages
#1Noah Misch
noah@leadboat.com
3 attachment(s)

I took a look at 2-pg85-sqlda-10-ctxdiff.patch. Starting from CVS HEAD of
roughly 2009-10-03 05:00 UTC, prerequisite patches 1a-1h applied cleanly.
2-pg85-sqlda hit a trivial whitespace reject in ecpg.trailer along with a more
substantive reject at ecpg.addons:407 (FetchStmtMOVEfetch_args). Fixing it up
by hand leads to my first question - why did the transition from `opt_ecpg_into'
to `opt_ecpg_fetch_into' affect FETCH FORWARD and not FETCH BACKWARD?

The main test suite acquired no regressions, but I get failures in two tests of
the ecpg test suite (make -C src/interfaces/ecpg/test check). I attach
regression.{out,diff} and postmaster.log from the test run. The abort in
sqlda.pgc looks like the interesting failure, but I exhausted time with which to
dig into it further. preproc/cursor.pgc creates (and ideally drops) the same
table `t1' as compat_informix/{sqlda,cursor}.pgc, so a crash in either of the
others makes it fail too. Could they all use temp tables, use different table
names, or `DROP TABLE IF EXISTS t1' first?

Do those logs suggest the cause of the sqlda.pgc failure? If not, I will look
into it further. Otherwise, I'm happy to review a future iteration of the
patch.

As a side note, with patch 1* but not patch 2, test_informix entered an infinite
loop with this error:
ERROR: syntax error at or near "c" at character 15
STATEMENT: fetch forward c

Thank you,
nm

Attachments:

regression.outtext/plain; charset=us-asciiDownload
regression.diffstext/plain; charset=us-asciiDownload
*** /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout	2009-10-03 04:23:59.000000000 -0400
--- /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/results/compat_informix-sqlda.stdout	2009-10-04 01:52:52.000000000 -0400
***************
*** 1,60 ****
- FETCH RECORD 1
- name sqlda descriptor: 'id' value 1
- name sqlda descriptor: 't' value 'a'
- name sqlda descriptor: 'd1' value DECIMAL '1.0'
- name sqlda descriptor: 'd2' value 1.000000
- name sqlda descriptor: 'c' value 'a         '
- FETCH RECORD 2
- name sqlda descriptor: 'id' value 2
- name sqlda descriptor: 't' value NULL'
- name sqlda descriptor: 'd1' value NULL'
- name sqlda descriptor: 'd2' value NULL'
- name sqlda descriptor: 'c' value NULL'
- FETCH RECORD 3
- name sqlda descriptor: 'id' value 3
- name sqlda descriptor: 't' value '"c"'
- name sqlda descriptor: 'd1' value DECIMAL '-3'
- name sqlda descriptor: 'd2' value nan
- name sqlda descriptor: 'c' value 'c         '
- FETCH RECORD 4
- name sqlda descriptor: 'id' value 4
- name sqlda descriptor: 't' value 'd'
- name sqlda descriptor: 'd1' value DECIMAL '4.0'
- name sqlda descriptor: 'd2' value 4.000000
- name sqlda descriptor: 'c' value 'd         '
- FETCH RECORD 1
- name sqlda descriptor: 'id' value 1
- name sqlda descriptor: 't' value 'a'
- name sqlda descriptor: 'd1' value DECIMAL '1.0'
- name sqlda descriptor: 'd2' value 1.000000
- name sqlda descriptor: 'c' value 'a         '
- FETCH RECORD 2
- name sqlda descriptor: 'id' value 2
- name sqlda descriptor: 't' value NULL'
- name sqlda descriptor: 'd1' value NULL'
- name sqlda descriptor: 'd2' value NULL'
- name sqlda descriptor: 'c' value NULL'
- FETCH RECORD 3
- name sqlda descriptor: 'id' value 3
- name sqlda descriptor: 't' value '"c"'
- name sqlda descriptor: 'd1' value DECIMAL '-3'
- name sqlda descriptor: 'd2' value nan
- name sqlda descriptor: 'c' value 'c         '
- FETCH RECORD 4
- name sqlda descriptor: 'id' value 4
- name sqlda descriptor: 't' value 'd'
- name sqlda descriptor: 'd1' value DECIMAL '4.0'
- name sqlda descriptor: 'd2' value 4.000000
- name sqlda descriptor: 'c' value 'd         '
- EXECUTE RECORD 4
- name sqlda descriptor: 'id' value 4
- name sqlda descriptor: 't' value 'd'
- name sqlda descriptor: 'd1' value DECIMAL '4.0'
- name sqlda descriptor: 'd2' value 4.000000
- name sqlda descriptor: 'c' value 'd         '
- EXECUTE RECORD 4
- name sqlda descriptor: 'id' value 4
- name sqlda descriptor: 't' value 'd'
- name sqlda descriptor: 'd1' value DECIMAL '4.0'
- name sqlda descriptor: 'd2' value 4.000000
- name sqlda descriptor: 'c' value 'd         '
--- 0 ----

======================================================================

*** /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr	2009-10-03 04:23:59.000000000 -0400
--- /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/results/compat_informix-sqlda.stderr	2009-10-04 01:52:52.000000000 -0400
***************
*** 36,252 ****
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 111: new sqlda was built
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: 1.0 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: 2 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: 3 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: -3 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: NaN offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: 4.0 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 111: correctly got 0 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: raising sqlcode 100 on line 111: no data found on line 111
- [NO_PID]: sqlca: code: 100, state: 02000
- [NO_PID]: ecpg_execute on line 120: query: close mycur1; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 120: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 120: OK: CLOSE CURSOR
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGdeallocate on line 123: name st_id1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGprepare on line 134: name st_id2; query: "SELECT * FROM t1"
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 140: query: declare mycur2 cursor for SELECT * FROM t1; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 140: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 140: OK: DECLARE CURSOR
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 1.0 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 2 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 3 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: -3 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: NaN offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 4.0 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 148: correctly got 0 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: raising sqlcode 100 on line 148: no data found on line 148
- [NO_PID]: sqlca: code: 100, state: 02000
- [NO_PID]: ecpg_execute on line 157: query: close mycur2; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 157: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 157: OK: CLOSE CURSOR
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGdeallocate on line 160: name st_id2
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGprepare on line 183: name st_id3; query: "SELECT * FROM t1 WHERE id = $1"
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 186: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 186: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: free_params on line 186: parameter 1 = 4
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 186: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 186: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 186: RESULT: 4.0 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 186: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGdeallocate on line 191: name st_id3
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGprepare on line 220: name st_id4; query: "SELECT * FROM t1 WHERE id = $1"
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 223: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection con2
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 223: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: free_params on line 223: parameter 1 = 4
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 223: correctly got 1 tuples with 5 fields
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 223: new sqlda was built
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 223: RESULT: 4.0 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 223: putting result (1 tuple 5 fields) into sqlda descriptor
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGtrans on line 228: action "commit"; connection "con2"
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGdeallocate on line 231: name st_id4
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_finish: connection con2 closed
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 243: query: drop table t1; with 0 parameter(s) on connection regress1
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 243: using PQexec
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_execute on line 243: OK: DROP TABLE
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ECPGtrans on line 246: action "commit"; connection "regress1"
- [NO_PID]: sqlca: code: 0, state: 00000
- [NO_PID]: ecpg_finish: connection regress1 closed
- [NO_PID]: sqlca: code: 0, state: 00000
--- 36,42 ----
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_store_result on line 111: allocating memory for 1 tuples
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
  [NO_PID]: sqlca: code: 0, state: 00000

======================================================================

*** /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/expected/preproc-cursor.stdout	2009-10-03 04:19:08.000000000 -0400
--- /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/results/preproc-cursor.stdout	2009-10-04 01:52:53.000000000 -0400
***************
*** 1,24 ****
- 1 a
- 2 b
- 3 c
- 4 d
- 1 a
- 2 b
- 1 a
- 2 b
- 3 c
- 4 d
- 1 a
- 2 b
- 1 a
- 2 b
- 3 c
- 4 d
- 1 a
- 2 b
- 1 a
- 2 b
- 3 c
- 4 d
- 1 a
- 2 b
--- 0 ----

======================================================================

*** /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/expected/preproc-cursor.stderr	2009-10-03 04:19:08.000000000 -0400
--- /home/nm/src/pg/bd-sqlda/src/interfaces/ecpg/test/results/preproc-cursor.stderr	2009-10-04 01:52:53.000000000 -0400
***************
*** 12,372 ****
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 44: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 44: OK: CREATE TABLE
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 47: query: insert into t1 ( id , t ) values ( default , 'a' ); with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 47: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 47: OK: INSERT 0 1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 48: query: insert into t1 ( id , t ) values ( default , 'b' ); with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 48: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 48: OK: INSERT 0 1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 49: query: insert into t1 ( id , t ) values ( default , 'c' ); with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 49: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 49: OK: INSERT 0 1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 50: query: insert into t1 ( id , t ) values ( default , 'd' ); with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 50: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 50: OK: INSERT 0 1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ECPGtrans on line 53: action "commit"; connection "regress1"
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 62: query: declare mycur cursor for select id , t from t1; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 62: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 62: OK: DECLARE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 65: query: fetch from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 65: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 65: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 65: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 69: query: fetch mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 69: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 69: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 69: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 69: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 73: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 73: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 73: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 73: RESULT: 3 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 73: RESULT: c offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 78: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 78: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 78: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 78: RESULT: 4 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 78: RESULT: d offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 82: query: move absolute 0 in mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 82: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 82: OK: MOVE 0
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 85: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 85: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 85: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 85: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 85: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 90: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 90: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 90: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 90: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 90: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 94: query: close mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 94: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 94: OK: CLOSE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 103: query: declare mycur cursor for select id , t from t1; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 103: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 103: OK: DECLARE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 106: query: fetch from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 106: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 106: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 106: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 106: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 110: query: fetch mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 110: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 110: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 110: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 110: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 114: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 114: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 114: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 114: RESULT: 3 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 114: RESULT: c offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 119: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 119: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 119: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 119: RESULT: 4 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 119: RESULT: d offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 123: query: move absolute 0 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 123: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 123: OK: MOVE 0
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 126: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 126: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 126: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 126: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 126: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 131: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 131: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 131: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 131: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 131: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 135: query: close mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 135: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 135: OK: CLOSE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ECPGprepare on line 140: name st_id1; query: "SELECT id, t FROM t1"
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 146: query: declare mycur cursor for SELECT id, t FROM t1; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 146: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 146: OK: DECLARE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 149: query: fetch from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 149: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 149: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 149: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 149: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 153: query: fetch mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 153: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 153: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 153: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 153: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 157: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 157: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 157: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 157: RESULT: 3 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 157: RESULT: c offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 162: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 162: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 162: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 162: RESULT: 4 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 162: RESULT: d offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 166: query: move absolute 0 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 166: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 166: OK: MOVE 0
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 169: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 169: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 169: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 169: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 169: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 174: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 174: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 174: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 174: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 174: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 178: query: close mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 178: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 178: OK: CLOSE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ECPGdeallocate on line 181: name st_id1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ECPGprepare on line 190: name st_id2; query: "SELECT id, t FROM t1"
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 196: query: declare mycur cursor for SELECT id, t FROM t1; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 196: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 196: OK: DECLARE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 199: query: fetch from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 199: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 199: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 199: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 199: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 203: query: fetch mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 203: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 203: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 203: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 203: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 207: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 207: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 207: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 207: RESULT: 3 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 207: RESULT: c offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 212: query: fetch 1 from mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 212: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 212: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 212: RESULT: 4 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 212: RESULT: d offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 216: query: move absolute 0 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 216: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 216: OK: MOVE 0
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 219: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 219: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 219: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 219: RESULT: 1 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 219: RESULT: a offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 224: query: fetch 1 mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 224: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 224: correctly got 1 tuples with 2 fields
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 224: RESULT: 2 offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_get_data on line 224: RESULT: b offset: -1; array: yes
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 228: query: close mycur; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 228: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 228: OK: CLOSE CURSOR
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ECPGdeallocate on line 231: name st_id2
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 236: query: drop table t1; with 0 parameter(s) on connection regress1
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 236: using PQexec
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_execute on line 236: OK: DROP TABLE
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ECPGtrans on line 239: action "commit"; connection "regress1"
! [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_finish: connection regress1 closed
  [NO_PID]: sqlca: code: 0, state: 00000
--- 12,18 ----
  [NO_PID]: sqlca: code: 0, state: 00000
  [NO_PID]: ecpg_execute on line 44: using PQexec
  [NO_PID]: sqlca: code: 0, state: 00000
! [NO_PID]: ecpg_check_PQresult on line 44: ERROR:  relation "t1" already exists
  [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlstate 42P07 (sqlcode -400) on line 44: relation "t1" already exists on line 44
+ [NO_PID]: sqlca: code: -400, state: 42P07

======================================================================

postmaster.logtext/plain; charset=us-asciiDownload
#2Boszormenyi Zoltan
zb@cybertec.at
In reply to: Noah Misch (#1)
Re: Review of "SQLDA support for ECPG"

Hi,

thank you very much for the review.

Noah Misch �rta:

I took a look at 2-pg85-sqlda-10-ctxdiff.patch. Starting from CVS HEAD of
roughly 2009-10-03 05:00 UTC, prerequisite patches 1a-1h applied cleanly.
2-pg85-sqlda hit a trivial whitespace reject in ecpg.trailer along with a more
substantive reject at ecpg.addons:407 (FetchStmtMOVEfetch_args). Fixing it up
by hand leads to my first question - why did the transition from `opt_ecpg_into'
to `opt_ecpg_fetch_into' affect FETCH FORWARD and not FETCH BACKWARD?

This was a total oversight coming from the previous
dynamic cursorname patch. *That* was buggy as it didn't
have the two de-factorized rules for FETCH BACKWARD.
When I did the fine-grained split-up, I fixed that but I didn't
test my SQLDA patch after the new dynamic cursorname
patches.

I will post a new patch for SQLDA and for all others that need
updating.

The main test suite acquired no regressions, but I get failures in two tests of
the ecpg test suite (make -C src/interfaces/ecpg/test check). I attach
regression.{out,diff} and postmaster.log from the test run. The abort in
sqlda.pgc looks like the interesting failure, but I exhausted time with which to
dig into it further. preproc/cursor.pgc creates (and ideally drops) the same
table `t1' as compat_informix/{sqlda,cursor}.pgc, so a crash in either of the
others makes it fail too. Could they all use temp tables, use different table
names, or `DROP TABLE IF EXISTS t1' first?

Do those logs suggest the cause of the sqlda.pgc failure? If not, I will look
into it further. Otherwise, I'm happy to review a future iteration of the
patch.

No, this is not a real error. I have run into this as well,
which is quickly solved if you execute "make install"
before running "make check" under the ecpg directory.
I guess you already have an installed PG tree at the same
prefix as where you have pointed the new one with the
SQLDA patch applied. Another solution may be to use
a different prefix for the SQLDA source tree.

I start to think that the same remedy would be needed here
as the contrib subdirectory: "make installcheck" is a mental
note the you test the installed libraries, not the freshly compiled
ones under the source directory.

As a side note, with patch 1* but not patch 2, test_informix entered an infinite
loop with this error:
ERROR: syntax error at or near "c" at character 15
STATEMENT: fetch forward c

Do you mean that you applied all the split-up patches posted
for the dynamic cursorname extension? I didn't get this error.
What did you do exactly?

Best regards,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

#3Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#2)
1 attachment(s)
Re: Review of "SQLDA support for ECPG"

Hi,

Boszormenyi Zoltan �rta:

I will post a new patch for SQLDA and for all others that need
updating.

Here it is. Added the changes for the FETCH BACKWARD
rules and fixed the other reject as well.

Best regards,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

Attachments:

2-pg85-sqlda-11-ctxdiff.patchtext/x-patch; name=2-pg85-sqlda-11-ctxdiff.patchDownload
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/execute.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/execute.c	2009-09-03 14:37:34.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c	2009-10-05 13:30:08.000000000 +0200
***************
*** 25,30 ****
--- 25,31 ----
  #include "ecpgerrno.h"
  #include "extern.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "sql3types.h"
  #include "pgtypes_numeric.h"
  #include "pgtypes_date.h"
*************** ecpg_store_input(const int lineno, const
*** 1033,1038 ****
--- 1034,1040 ----
  				break;
  
  			case ECPGt_descriptor:
+ 			case ECPGt_sqlda:
  				break;
  
  			default:
*************** ecpg_execute(struct statement * stmt)
*** 1172,1177 ****
--- 1174,1235 ----
  			if (desc->count == desc_counter)
  				desc_counter = 0;
  		}
+ 		else if (var->type == ECPGt_sqlda)
+ 		{
+ 			pg_sqlda_t	  **_sqlda = (pg_sqlda_t **)var->pointer;
+ 			pg_sqlda_t	   *sqlda = *_sqlda;
+ 			struct variable	desc_inlist;
+ 			int		i;
+ 
+ 			if (sqlda == NULL)
+ 				return false;
+ 
+ 			desc_counter++;
+ 			for (i = 0; i < sqlda->sqld; i++)
+ 			{
+ 				if (i + 1 == desc_counter)
+ 				{
+ 					desc_inlist.type = ecpg_sqlda_type(sqlda->sqlvar[i].sqltype);
+ 					desc_inlist.value = sqlda->sqlvar[i].sqldata;
+ 					desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
+ 					switch (desc_inlist.type)
+ 					{
+ 						case ECPGt_char:
+ 						case ECPGt_varchar:
+ 							desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
+ 							break;
+ 						default:
+ 							desc_inlist.varcharsize = 0;
+ 							break;
+ 					}
+ 					desc_inlist.arrsize = 1;
+ 					desc_inlist.offset = 0;
+ 					if (sqlda->sqlvar[i].sqlind)
+ 					{
+ 						desc_inlist.ind_type = ECPGt_short;
+ 						/* ECPG expects indicator value < 0 */
+ 						if (*(sqlda->sqlvar[i].sqlind))
+ 							*(sqlda->sqlvar[i].sqlind) = -1;
+ 						desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
+ 						desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
+ 						desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
+ 						desc_inlist.ind_offset = 0;
+ 					}
+ 					else
+ 					{
+ 						desc_inlist.ind_type = ECPGt_NO_INDICATOR;
+ 						desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
+ 						desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
+ 					}
+ 					if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
+ 						return false;
+ 
+ 					break;
+ 				}
+ 			}
+ 			if (sqlda->sqld == desc_counter)
+ 				desc_counter = 0;
+ 		}
  		else
  		{
  			if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false))
*************** ecpg_execute(struct statement * stmt)
*** 1353,1358 ****
--- 1411,1452 ----
  				}
  				var = var->next;
  			}
+ 			else if (var != NULL && var->type == ECPGt_sqlda)
+ 			{
+ 				pg_sqlda_t	  **_sqlda = (pg_sqlda_t **)var->pointer;
+ 				pg_sqlda_t	   *sqlda = *_sqlda;
+ 				pg_sqlda_t	   *sqlda_new;
+ 
+ 				/* Build a new sqlda structure. Note that only fetching 1 record is supported */
+ 				sqlda_new = ecpg_build_sqlda_for_PGresult(stmt->lineno, results, 0);
+ 
+ 				if (!sqlda_new)
+ 				{
+ 					ecpg_log("ecpg_execute on line %d: out of memory allocating a new sqlda\n", stmt->lineno);
+ 					status = false;
+ 				}
+ 				else
+ 				{
+ 					ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno);
+ 
+ 					/* If we are passed in a previously existing sqlda then free it. */
+ 					if (sqlda)
+ 					{
+ 						if (sqlda->sqlvar != (pg_sqlvar_t *)(sqlda + 1))
+ 							free(sqlda->sqlvar);
+ 						free(sqlda);
+ 						sqlda = NULL;
+ 					}
+ 
+ 					*_sqlda = sqlda_new;
+ 
+ 					ecpg_set_sqlda_from_PGresult(stmt->lineno, _sqlda, results, 0);
+ 					ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
+ 							stmt->lineno, PQnfields(results));
+ 				}
+ 
+ 				var = var->next;
+ 			}
  			else
  				for (act_field = 0; act_field < nfields && status; act_field++)
  				{
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/extern.h pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/extern.h	2009-05-25 12:08:48.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h	2009-10-05 13:30:08.000000000 +0200
***************
*** 6,11 ****
--- 6,12 ----
  #include "postgres_fe.h"
  #include "libpq-fe.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "ecpg_config.h"
  #ifndef CHAR_BIT
  #include <limits.h>
*************** bool		ecpg_init(const struct connection 
*** 129,134 ****
--- 130,137 ----
  char	   *ecpg_strdup(const char *, int);
  const char *ecpg_type_name(enum ECPGttype);
  int			ecpg_dynamic_type(Oid);
+ int			ecpg_sqlda_type(int);
+ int			ecpg_to_sqlda_type(Oid);
  void		ecpg_free_auto_mem(void);
  void		ecpg_clear_auto_mem(void);
  
*************** void		ecpg_log(const char *format,...);
*** 149,154 ****
--- 152,160 ----
  bool		ecpg_auto_prepare(int, const char *, const int, char **, const char *);
  void		ecpg_init_sqlca(struct sqlca_t * sqlca);
  
+ pg_sqlda_t *ecpg_build_sqlda_for_PGresult(int, PGresult *, int);
+ void		ecpg_set_sqlda_from_PGresult(int, pg_sqlda_t **, const PGresult *, int);
+ 
  /* SQLSTATE values generated or processed by ecpglib (intentionally
   * not exported -- users should refer to the codes directly) */
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/Makefile pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/Makefile	2009-07-13 11:16:41.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile	2009-10-05 13:30:08.000000000 +0200
*************** override CFLAGS += $(PTHREAD_CFLAGS)
*** 24,30 ****
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))
  
! OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
  	connect.o misc.o path.o pgstrcasecmp.o \
  	$(filter snprintf.o strlcpy.o, $(LIBOBJS))
  
--- 24,30 ----
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))
  
! OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
  	connect.o misc.o path.o pgstrcasecmp.o \
  	$(filter snprintf.o strlcpy.o, $(LIBOBJS))
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/sqlda.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/sqlda.c	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c	2009-10-05 13:30:08.000000000 +0200
***************
*** 0 ****
--- 1,276 ----
+ /*
+  * Crude SQLDA support routines
+  * Only supports fetching 1 record at a time
+  *
+  * The allocated memory area pointed by an sqlda pointer
+  * contains both the metadata and the data, so freeing up
+  * is a simple free(sqlda) as expected by the ESQL/C examples.
+  */
+ 
+ #define POSTGRES_ECPG_INTERNAL
+ #include "postgres_fe.h"
+ #include "pg_type.h"
+ 
+ #include <inttypes.h>
+ #include <dlfcn.h>
+ 
+ #include "ecpg-pthread-win32.h"
+ #include "decimal.h"
+ #include "ecpgtype.h"
+ #include "ecpglib.h"
+ #include "ecpgerrno.h"
+ #include "extern.h"
+ #include "sqlca.h"
+ #include "sqlda.h"
+ #include "sqltypes.h"
+ 
+ /*
+  * Compute the next variable's offset with
+  * the current variable's size and alignment.
+  */
+ static long
+ ecpg_sqlda_size_round_align(long offset, int alignment, int size)
+ {
+ 	if (offset % alignment)
+ 		offset += alignment - (offset % alignment);
+ 	offset += size;
+ 	return offset;
+ }
+ 
+ /*
+  * Compute the current variable's offset with alignment.
+  */
+ static long
+ ecpg_sqlda_size_align(long offset, int alignment)
+ {
+ 	if (offset % alignment)
+ 		offset += alignment - (offset % alignment);
+ 	return offset;
+ }
+ 
+ static long
+ ecpg_sqlda_empty_size(const PGresult *res)
+ {
+ 	long	size;
+ 	int	i;
+ 	int	sqld = PQnfields(res);
+ 
+ 	/* Initial size to store main structure and field structures */
+ 	size = sizeof(pg_sqlda_t) + sqld * sizeof(pg_sqlvar_t);
+ 
+ 	/* Add space for field names */
+ 	for (i = 0; i < sqld; i++)
+ 		size += strlen(PQfname(res, i)) + 1;
+ 
+ 	/* Add padding to the first field value */
+ 	size = ecpg_sqlda_size_align(size, sizeof(int));
+ 
+ 	return size;
+ }
+ 
+ static long
+ ecpg_sqlda_total_size(const PGresult *res, int row)
+ {
+ 	int	i;
+ 	int	sqld = PQnfields(res);
+ 	long	size;
+ 
+ 	size = ecpg_sqlda_empty_size(res);
+ 
+ 	if (row < 0)
+ 		return size;
+ 
+ 	/* Add space for the field values */
+ 	for (i = 0; i < sqld; i++)
+ 	{
+ 		switch (ecpg_to_sqlda_type(PQftype(res, i)))
+ 		{
+ 			case SQLSMINT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(short), sizeof(short));
+ 				break;
+ 			case SQLINT:
+ 			case SQLSERIAL:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(int));
+ 				break;
+ 			case SQLFLOAT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(double), sizeof(double));
+ 				break;
+ 			case SQLSMFLOAT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(float), sizeof(float));
+ 				break;
+ 			case SQLDECIMAL:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(decimal));
+ 				break;
+ 			case SQLINT8:
+ 			case SQLSERIAL8:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int64_t), sizeof(int64_t));
+ 				break;
+ 
+ 			/*
+ 			 * These types will be passed as character strings
+ 			 * copied as is from the PGresult until we know
+ 			 * what to do with them.
+ 			 */
+ 			case SQLCHAR:
+ 			case SQLTEXT:
+ 			case SQLVCHAR:
+ 			case SQLNCHAR:
+ 			case SQLNVCHAR:
+ 			case SQLMONEY:
+ 			case SQLDATE:
+ 			case SQLDTIME:
+ 			case SQLINTERVAL:
+ 			default:
+ 				size += strlen(PQgetvalue(res, row, i)) + 1;
+ 				break;
+ 		}
+ 	}
+ 	return size;
+ }
+ 
+ /*
+  * Build pg_sqlda_t (metadata only) from PGresult
+  * leaving enough space for the field values in
+  * the given row number
+  */
+ pg_sqlda_t *
+ ecpg_build_sqlda_for_PGresult(int line, PGresult *res, int row)
+ {
+ 	pg_sqlda_t *sqlda;
+ 	pg_sqlvar_t*sqlvar;
+ 	char	   *fname;
+ 	long		size;
+ 	int		sqld;
+ 	int		i;
+ 
+ 	size = ecpg_sqlda_total_size(res, row);
+ 	sqlda = (pg_sqlda_t *)ecpg_alloc(size, line);
+ 	if (!sqlda)
+ 		return NULL;
+ 
+ 	memset(sqlda, 0, size);
+ 	sqlvar = (pg_sqlvar_t *)(sqlda + 1);
+ 	sqld = PQnfields(res);
+ 	fname = (char *)(sqlvar + sqld);
+ 
+ 	sqlda->sqld = sqld;
+ 	sqlda->desc_occ = size; /* cheat here, keep the full allocated size */
+ 	sqlda->sqlvar = sqlvar;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		sqlda->sqlvar[i].sqltype = ecpg_to_sqlda_type(PQftype(res, i));
+ 		strcpy(fname, PQfname(res, i));
+ 		sqlda->sqlvar[i].sqlname = fname;
+ 		fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
+ 		sqlda->sqlvar[i].sqlformat = (char *)(long)PQfformat(res, i);
+ 		sqlda->sqlvar[i].sqlxid = PQftype(res, i);
+ 		sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
+ 	}
+ 
+ 	return sqlda;
+ }
+ 
+ /*
+  * Sets values from PGresult.
+  */
+ void
+ ecpg_set_sqlda_from_PGresult(int lineno, pg_sqlda_t **_sqlda, const PGresult *res, int row)
+ {
+ 	pg_sqlda_t *sqlda = (*_sqlda);
+ 	int		i;
+ 	long		size;
+ 	static	int2	value_is_null = -1;
+ 	static	int2	value_is_not_null = 0;
+ 
+ 	/* Offset for the first field value */
+ 	size = ecpg_sqlda_empty_size(res);
+ 
+ 	/*
+ 	 * Set sqlvar[i]->sqldata pointers and convert values to correct format
+ 	 */
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		int type = -1, isnull;
+ 		int use_getdata = true;
+ 
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 			case SQLSMINT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(short));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				size += sizeof(short);
+ 				type = ECPGt_short;
+ 				break;
+ 			case SQLINT:
+ 			case SQLSERIAL:
+ 				size = ecpg_sqlda_size_align(size, sizeof(int));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				size += sizeof(int);
+ 				type = ECPGt_int;
+ 				break;
+ 			case SQLFLOAT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(double));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				size += sizeof(double);
+ 				type = ECPGt_double;
+ 				break;
+ 			case SQLSMFLOAT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(float));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				size += sizeof(float);
+ 				type = ECPGt_float;
+ 				break;
+ 			case SQLDECIMAL:
+ 			{
+ 				size = ecpg_sqlda_size_align(size, sizeof(int));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				size += sizeof(decimal);
+ 				type = ECPGt_decimal;
+ 				break;
+ 			}
+ 			case SQLINT8:
+ 			case SQLSERIAL8:
+ 				size = ecpg_sqlda_size_align(size, sizeof(int64_t));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				size += sizeof(int64_t);
+ 				type = ECPGt_long_long;
+ 				break;
+ 
+ 			/*
+ 			 * These types will be passed as character strings until
+ 			 * it's known what to do with them. We use sqlvar->sqldata
+ 			 * in all cases regardless of length, don't care about
+ 			 * sqlvar->sqlilongdata.
+ 			 */
+ 			case SQLCHAR:
+ 			case SQLTEXT:
+ 			case SQLVCHAR:
+ 			case SQLNCHAR:
+ 			case SQLNVCHAR:
+ 			case SQLMONEY:
+ 			case SQLDATE:
+ 			case SQLDTIME:
+ 			case SQLINTERVAL:
+ 			default:
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				size += strlen(PQgetvalue(res, row, i)) + 1;
+ 				use_getdata = false;
+ 				break;
+ 		}
+ 
+ 		isnull = PQgetisnull(res, 0, i);
+ 		sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
+ 		if (!isnull)
+ 		{
+ 			if (use_getdata)
+ 				ecpg_get_data(res, row, i, lineno,
+ 						type, ECPGt_NO_INDICATOR,
+ 						sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
+ 						ECPG_ARRAY_NONE, ECPG_COMPAT_INFORMIX, false);
+ 			else
+ 				strcpy(sqlda->sqlvar[i].sqldata, PQgetvalue(res, row, i));
+ 		}
+ 	}
+ }
+ 
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/typename.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/typename.c	2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c	2009-10-05 13:30:08.000000000 +0200
***************
*** 7,12 ****
--- 7,13 ----
  #include "ecpgtype.h"
  #include "ecpglib.h"
  #include "extern.h"
+ #include "sqltypes.h"
  #include "sql3types.h"
  #include "pg_type.h"
  
*************** ecpg_dynamic_type(Oid type)
*** 100,102 ****
--- 101,190 ----
  			return -(int) type;
  	}
  }
+ 
+ int
+ ecpg_sqlda_type(int type)
+ {
+ 	switch (type)
+ 	{
+ 		case SQLCHAR:
+ 		case SQLNCHAR:
+ 			return ECPGt_char;
+ 		case SQLSMINT:
+ 			return ECPGt_short;
+ 		case SQLINT:
+ 			return ECPGt_int;
+ 		case SQLFLOAT:
+ 			return ECPGt_double;
+ 		case SQLSMFLOAT:
+ 			return ECPGt_float;
+ 		case SQLDECIMAL:
+ 			return ECPGt_decimal;
+ 		case SQLSERIAL:
+ 			return ECPGt_int;
+ 		case SQLDATE:
+ 			return ECPGt_date;
+ #if 0
+ 		case SQLMONEY:
+ 			return ???;
+ 		case SQLNULL:
+ 			return ???;
+ #endif
+ 		case SQLDTIME:
+ 			return ECPGt_timestamp;
+ #if 0
+ 		case SQLBYTES:
+ 			return ???;
+ #endif
+ 		case SQLTEXT:
+ 			return ECPGt_char;
+ 		case SQLVCHAR:
+ 		case SQLNVCHAR:
+ 			return ECPGt_varchar;
+ 		case SQLINTERVAL:
+ 			return ECPGt_interval;
+ 		case SQLINT8:
+ 		case SQLSERIAL8:
+ 			return ECPGt_long_long;
+ 		default:
+ 			return (-type);
+ 	}
+ }
+ 
+ int
+ ecpg_to_sqlda_type(Oid type)
+ {
+ 	switch (type)
+ 	{
+ 		case CHAROID:
+ 		case BPCHAROID:
+ 			return SQLCHAR;
+ 		case INT2OID:
+ 			return SQLSMINT;
+ 		case INT4OID:
+ 			return SQLINT;
+ 		case FLOAT8OID:
+ 			return SQLFLOAT;
+ 		case FLOAT4OID:
+ 			return SQLSMFLOAT;
+ 		case NUMERICOID:
+ 			return SQLDECIMAL;
+ 		case DATEOID:
+ 			return SQLDATE;
+ 		case CASHOID:
+ 			return SQLMONEY;
+ 		case TIMESTAMPOID:
+ 		case TIMESTAMPTZOID:
+ 			return SQLDTIME;
+ 		case TEXTOID:
+ 			return SQLTEXT;
+ 		case VARCHAROID:
+ 			return SQLVCHAR;
+ 		case INTERVALOID:
+ 			return SQLINTERVAL;
+ 		case INT8OID:
+ 			return SQLINT8;
+ 		default:
+ 			return (-type);
+ 	}
+ }
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/ecpgtype.h pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/ecpgtype.h	2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h	2009-10-05 13:30:08.000000000 +0200
*************** enum ECPGttype
*** 62,68 ****
  	ECPGt_EOIT,					/* End of insert types. */
  	ECPGt_EORT,					/* End of result types. */
  	ECPGt_NO_INDICATOR,			/* no indicator */
! 	ECPGt_string                            /* trimmed (char *) type */
  };
  
   /* descriptor items */
--- 62,69 ----
  	ECPGt_EOIT,					/* End of insert types. */
  	ECPGt_EORT,					/* End of result types. */
  	ECPGt_NO_INDICATOR,			/* no indicator */
! 	ECPGt_string,				/* trimmed (char *) type */
! 	ECPGt_sqlda				/* C struct descriptor */
  };
  
   /* descriptor items */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/sqlda.h pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/sqlda.h	2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h	2009-10-05 13:30:08.000000000 +0200
***************
*** 1,3 ****
--- 1,74 ----
  /*
   * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
   */
+ 
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+ 
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int		int4;
+ typedef	short		int2;
+ #endif
+ typedef	char		int1;
+ 
+ typedef	int		mint;
+ typedef	long		mlong;
+ 
+ typedef	short		MSHORT;
+ typedef	char		MCHAR; 
+ 
+ typedef	unsigned int	uint4;
+ typedef	unsigned short	uint2;
+ typedef	unsigned char	uint1;
+ 
+ typedef	unsigned int	muint;
+ typedef	unsigned long	mulong;
+ 
+ typedef	unsigned short	MUSHORT;
+ typedef	unsigned char	MUCHAR; 
+ 
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+ 
+ typedef struct sqlvar_struct
+ {
+ 	int2	sqltype;		/* variable type                */
+ 	int4	sqllen;			/* length in bytes              */
+ 	char	   *sqldata;		/* pointer to data              */
+ 	int2	   *sqlind;		/* pointer to indicator         */
+ 	char	   *sqlname;		/* variable name                */
+ 	char	   *sqlformat;		/* reserved for future use      */
+ 	int2	sqlitype;		/* ind variable type            */
+ 	int2	sqlilen;		/* ind length in bytes          */
+ 	char	   *sqlidata;		/* ind data pointer             */
+ 	int4	sqlxid;			/* extended id type             */
+ 	char	   *sqltypename;	/* extended type name           */
+ 	int2	sqltypelen;		/* length of extended type name */
+ 	int2	sqlownerlen;		/* length of owner name         */
+ 	int2	sqlsourcetype;		/* source type for distinct of built-ins */
+ 	char	   *sqlownername;	/* owner name                   */
+ 	int4	sqlsourceid;		/* extended id of source type   */
+ 
+ 	/*
+ 	 * sqlilongdata is new.  It supports data that exceeds the 32k
+ 	 * limit.  sqlilen and sqlidata are for backward compatibility
+ 	 * and they have maximum value of <32K.
+ 	 */
+ 	char	   *sqlilongdata;	/* for data field beyond 32K    */
+ 	int4	sqlflags;		/* for internal use only        */
+ 	void	   *sqlreserved;	/* reserved for future use      */
+ } pg_sqlvar_t;
+ 
+ typedef struct sqlda
+ {
+ 	int2		sqld;
+ 	pg_sqlvar_t	   *sqlvar;
+ 	char		desc_name[19];	/* descriptor name              */
+ 	int2		desc_occ;	/* size of sqlda structure      */
+ 	struct sqlda	   *desc_next;	/* pointer to next sqlda struct */
+ 	void		   *reserved;	/* reserved for future use */
+ } pg_sqlda_t;
+ 
+ #endif /* POSTGRES_SQLDA_H */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/sqltypes.h pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/sqltypes.h	2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h	2009-10-05 13:30:08.000000000 +0200
***************
*** 30,33 ****
--- 30,55 ----
  #define CLVCHARPTRTYPE	124
  #define CTYPEMAX	25
  
+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define	SQLCHAR		0
+ #define	SQLSMINT	1
+ #define	SQLINT		2
+ #define	SQLFLOAT	3
+ #define	SQLSMFLOAT	4
+ #define	SQLDECIMAL	5
+ #define	SQLSERIAL	6
+ #define	SQLDATE		7
+ #define	SQLMONEY	8
+ #define	SQLDTIME	10
+ #define	SQLBYTES	11
+ #define	SQLTEXT		12
+ #define	SQLVCHAR	13
+ #define	SQLINTERVAL	14
+ #define	SQLNCHAR	15
+ #define	SQLNVCHAR	16
+ #define	SQLINT8		17
+ #define	SQLSERIAL8	18
+ 
  #endif   /* ndef ECPG_SQLTYPES_H */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/descriptor.c pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/descriptor.c	2009-01-30 17:28:46.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c	2009-10-05 13:30:08.000000000 +0200
*************** descriptor_variable(const char *name, in
*** 326,328 ****
--- 326,347 ----
  	strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
  	return (struct variable *) & varspace[input];
  }
+ 
+ struct variable *
+ sqlda_variable(const char *name)
+ {
+ 	struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
+ 
+ 	p->name = mm_strdup(name);
+ 	p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
+ 	p->type->type = ECPGt_sqlda;
+ 	p->type->size = NULL;
+ 	p->type->struct_sizeof = NULL;
+ 	p->type->u.element = NULL;
+ 	p->type->lineno = 0;
+ 	p->brace_level = 0;
+ 	p->next = NULL;
+ 
+ 	return p;
+ }
+ 
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.addons pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.addons	2009-10-03 01:54:43.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons	2009-10-05 13:33:06.000000000 +0200
*************** ECPG: VariableShowStmtSHOWALL block
*** 402,430 ****
  		$$ = EMPTY;
  	}
  ECPG: FetchStmtMOVEfetch_args rule
! 	| FETCH fetch_args ecpg_into
  	{
  		$$ = cat2_str(make_str("fetch"), $2);
  	}
! 	| FETCH FORWARD cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch forward"), cursor_marker);
  	}
! 	| FETCH FORWARD from_in cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
  		$$ = cat_str(2, make_str("fetch forward from"), cursor_marker);
  	}
! 	| FETCH BACKWARD cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch backward"), cursor_marker);
  	}
! 	| FETCH BACKWARD from_in cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
--- 402,430 ----
  		$$ = EMPTY;
  	}
  ECPG: FetchStmtMOVEfetch_args rule
! 	| FETCH fetch_args ecpg_fetch_into
  	{
  		$$ = cat2_str(make_str("fetch"), $2);
  	}
! 	| FETCH FORWARD cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch forward"), cursor_marker);
  	}
! 	| FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
  		$$ = cat_str(2, make_str("fetch forward from"), cursor_marker);
  	}
! 	| FETCH BACKWARD cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch backward"), cursor_marker);
  	}
! 	| FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.trailer pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.trailer	2009-10-03 02:05:58.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer	2009-10-05 13:40:15.000000000 +0200
*************** ecpg_using:	USING using_list 	{ $$ = EMP
*** 1017,1035 ****
  
  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
  			$$ = EMPTY;
  		}
  		;
  
  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
  			$$ = EMPTY;
  		}
  		;
  
! opt_sql: /*EMPTY*/ | SQL_SQL;
  
  using_list: UsingValue | UsingValue ',' using_list;
  
--- 1017,1065 ----
  
  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			if (strlen($2) || !(INFORMIX_MODE))
! 				add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
! 			else
! 			{
! 				if ($4[0] == '\"')
! 				{
! 					char *pos;
! 
! 					$4[0] = ' ';
! 					for (pos = $4; *pos; pos++)
! 						if (*pos == '\"')
! 							*pos = ' ';
! 				}
! 				add_variable_to_head(&argsinsert, sqlda_variable($4), &no_indicator);
! 			}
  			$$ = EMPTY;
  		}
  		;
  
  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			if (strlen($2) || !(INFORMIX_MODE))
! 				add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
! 			else
! 			{
! 				if ($4[0] == '\"')
! 				{
! 					char *pos;
! 
! 					$4[0] = ' ';
! 					for (pos = $4; *pos; pos++)
! 						if (*pos == '\"')
! 							*pos = ' ';
! 				}
! 				add_variable_to_head(&argsresult, sqlda_variable($4), &no_indicator);
! 			}
  			$$ = EMPTY;
  		}
  		;
  
! opt_sql: /*EMPTY*/		{ $$ = EMPTY; }
! 		| SQL_SQL	{ $$ = make_str("sql"); }
! 		;
  
  using_list: UsingValue | UsingValue ',' using_list;
  
*************** ecpg_into: INTO into_list	{ $$ = EMPTY; 
*** 2052,2058 ****
          | into_descriptor	{ $$ = $1; }
  	;
  
! opt_ecpg_into:	/* EMPTY */	{ $$ = EMPTY; }
  	| ecpg_into		{ $$ = $1; }
  	;
  
--- 2082,2103 ----
          | into_descriptor	{ $$ = $1; }
  	;
  
! ecpg_fetch_into: ecpg_into	{ $$ = $1; }
! 	| using_descriptor
! 	{
! 		struct variable *var;
! 
! 		if (!INFORMIX_MODE)
! 			mmerror(PARSE_ERROR, ET_ERROR, "Not in Informix compatibility mode");
! 
! 		var = argsinsert->variable;
! 		remove_variable_from_list(&argsinsert, var);
! 		add_variable_to_head(&argsresult, var, &no_indicator);
! 		$$ = $1;
! 	}
! 	;
! 
! opt_ecpg_fetch_into:	/* EMPTY */	{ $$ = EMPTY; }
  	| ecpg_into		{ $$ = $1; }
  	;
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.type pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.type	2009-10-03 02:03:31.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type	2009-10-05 13:30:08.000000000 +0200
***************
*** 62,67 ****
--- 62,68 ----
  %type <str> ecpg_ident
  %type <str> ecpg_interval
  %type <str> ecpg_into
+ %type <str> ecpg_fetch_into
  %type <str> ecpg_param
  %type <str> ecpg_sconst
  %type <str> ecpg_using
***************
*** 77,83 ****
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
--- 78,84 ----
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_fetch_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
***************
*** 87,92 ****
--- 88,94 ----
  %type <str> opt_reference
  %type <str> opt_scale
  %type <str> opt_server
+ %type <str> opt_sql   
  %type <str> opt_user
  %type <str> opt_opt_value
  %type <str> ora_user
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/extern.h pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/extern.h	2009-10-03 01:07:54.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h	2009-10-05 13:30:08.000000000 +0200
*************** extern void add_descriptor(char *, char 
*** 88,93 ****
--- 88,94 ----
  extern void drop_descriptor(char *, char *);
  extern struct descriptor *lookup_descriptor(char *, char *);
  extern struct variable *descriptor_variable(const char *name, int input);
+ extern struct variable *sqlda_variable(const char *name);
  extern void add_variable_to_head(struct arguments **, struct variable *, struct variable *);
  extern void add_variable_to_tail(struct arguments **, struct variable *, struct variable *);
  extern void remove_variable_from_list(struct arguments ** list, struct variable * var);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/type.c pgsql.sqlda/src/interfaces/ecpg/preproc/type.c
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/type.c	2009-09-03 12:25:47.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/type.c	2009-10-05 13:30:08.000000000 +0200
*************** get_type(enum ECPGttype type)
*** 194,199 ****
--- 194,202 ----
  		case ECPGt_descriptor:
  			return ("ECPGt_descriptor");
  			break;
+ 		case ECPGt_sqlda:
+ 			return ("ECPGt_sqlda");
+ 			break;
  		case ECPGt_date:
  			return ("ECPGt_date");
  			break;
*************** ECPGdump_a_simple(FILE *o, const char *n
*** 328,333 ****
--- 331,338 ----
  	else if (type == ECPGt_descriptor)
  		/* remember that name here already contains quotes (if needed) */
  		fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name);
+ 	else if (type == ECPGt_sqlda)
+ 		fprintf(o, "\n\tECPGt_sqlda, &%s, 0L, 0L, 0L, ", name);
  	else
  	{
  		char	   *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/Makefile pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile
*** pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/Makefile	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile	2009-10-05 13:30:08.000000000 +0200
*************** TESTS = test_informix test_informix.c \
*** 17,22 ****
--- 17,23 ----
          rfmtdate rfmtdate.c \
          rfmtlong rfmtlong.c \
          rnull rnull.c \
+         sqlda sqlda.c \
          charfuncs charfuncs.c
  
  all: $(TESTS)
*************** test_informix2.c: test_informix2.pgc ../
*** 30,35 ****
--- 31,39 ----
  cursor.c: cursor.pgc ../regression.h
  	$(ECPG) -o $@ -I$(srcdir) $<
  
+ sqlda.c: sqlda.pgc ../regression.h
+ 	$(ECPG) -o $@ -I$(srcdir) $<
+ 
  dec_test.c: dec_test.pgc ../regression.h
  	$(ECPG) -o $@ -I$(srcdir) $<
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/sqlda.pgc pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
*** pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/sqlda.pgc	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc	2009-10-05 13:30:08.000000000 +0200
***************
*** 0 ****
--- 1,252 ----
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.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 */
+ pg_sqlda_t	*inp_sqlda, *outp_sqlda;
+ 
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+ 	int	i;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+ 			printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+ 		else
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 		case SQLCHAR:
+ 		case SQLVCHAR:
+ 		case SQLTEXT:
+ 			printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL:
+ 		case SQLINT:
+ 			printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL8:
+ 		case SQLINT8:
+ 			printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLFLOAT:
+ 			printf("name sqlda descriptor: '%s' value %lf\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),
+ 		(3, '"c"', -3, 'nan'::float8, 'c'),
+ 		(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 = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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 = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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 -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule
*** pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule	2009-10-05 13:30:08.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule_tcp pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp
*** pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule_tcp	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp	2009-10-05 13:30:08.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	2009-10-05 13:30:08.000000000 +0200
***************
*** 0 ****
--- 1,585 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* Needed for informix compatibility */
+ #include <ecpg_informix.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+ 
+ #line 1 "sqlda.pgc"
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.h>
+ 
+ 
+ #line 1 "regression.h"
+ 
+ 
+ 
+ 
+ 
+ 
+ #line 5 "sqlda.pgc"
+ 
+ 
+ 
+ #line 1 "sqlda.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
+  */
+ 
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+ 
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int		int4;
+ typedef	short		int2;
+ #endif
+ typedef	char		int1;
+ 
+ typedef	int		mint;
+ typedef	long		mlong;
+ 
+ typedef	short		MSHORT;
+ typedef	char		MCHAR; 
+ 
+ typedef	unsigned int	uint4;
+ typedef	unsigned short	uint2;
+ typedef	unsigned char	uint1;
+ 
+ typedef	unsigned int	muint;
+ typedef	unsigned long	mulong;
+ 
+ typedef	unsigned short	MUSHORT;
+ typedef	unsigned char	MUCHAR; 
+ 
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+ 
+ typedef struct sqlvar_struct
+ {
+ 	int2	sqltype;		/* variable type                */
+ 	int4	sqllen;			/* length in bytes              */
+ 	char	   *sqldata;		/* pointer to data              */
+ 	int2	   *sqlind;		/* pointer to indicator         */
+ 	char	   *sqlname;		/* variable name                */
+ 	char	   *sqlformat;		/* reserved for future use      */
+ 	int2	sqlitype;		/* ind variable type            */
+ 	int2	sqlilen;		/* ind length in bytes          */
+ 	char	   *sqlidata;		/* ind data pointer             */
+ 	int4	sqlxid;			/* extended id type             */
+ 	char	   *sqltypename;	/* extended type name           */
+ 	int2	sqltypelen;		/* length of extended type name */
+ 	int2	sqlownerlen;		/* length of owner name         */
+ 	int2	sqlsourcetype;		/* source type for distinct of built-ins */
+ 	char	   *sqlownername;	/* owner name                   */
+ 	int4	sqlsourceid;		/* extended id of source type   */
+ 
+ 	/*
+ 	 * sqlilongdata is new.  It supports data that exceeds the 32k
+ 	 * limit.  sqlilen and sqlidata are for backward compatibility
+ 	 * and they have maximum value of <32K.
+ 	 */
+ 	char	   *sqlilongdata;	/* for data field beyond 32K    */
+ 	int4	sqlflags;		/* for internal use only        */
+ 	void	   *sqlreserved;	/* reserved for future use      */
+ } pg_sqlvar_t;
+ 
+ typedef struct sqlda
+ {
+ 	int2		sqld;
+ 	pg_sqlvar_t	   *sqlvar;
+ 	char		desc_name[19];	/* descriptor name              */
+ 	int2		desc_occ;	/* size of sqlda structure      */
+ 	struct sqlda	   *desc_next;	/* pointer to next sqlda struct */
+ 	void		   *reserved;	/* reserved for future use */
+ } pg_sqlda_t;
+ 
+ #endif /* POSTGRES_SQLDA_H */
+ 
+ #line 7 "sqlda.pgc"
+ 
+ 
+ #line 1 "sqltypes.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqltypes.h,v 1.9 2009/06/11 14:49:13 momjian Exp $
+  */
+ #ifndef ECPG_SQLTYPES_H
+ #define ECPG_SQLTYPES_H
+ 
+ #define CCHARTYPE	ECPGt_char
+ #define CSHORTTYPE	ECPGt_short
+ #define CINTTYPE	ECPGt_int
+ #define CLONGTYPE	ECPGt_long
+ #define CFLOATTYPE	ECPGt_float
+ #define CDOUBLETYPE ECPGt_double
+ #define CDECIMALTYPE	ECPGt_decimal
+ #define CFIXCHARTYPE	108
+ #define CSTRINGTYPE ECPGt_char
+ #define CDATETYPE	ECPGt_date
+ #define CMONEYTYPE	111
+ #define CDTIMETYPE	ECPGt_timestamp
+ #define CLOCATORTYPE	113
+ #define CVCHARTYPE	ECPGt_varchar
+ #define CINVTYPE	115
+ #define CFILETYPE	116
+ #define CINT8TYPE	ECPGt_long_long
+ #define CCOLLTYPE		118
+ #define CLVCHARTYPE		119
+ #define CFIXBINTYPE		120
+ #define CVARBINTYPE		121
+ #define CBOOLTYPE		ECPGt_bool
+ #define CROWTYPE		123
+ #define CLVCHARPTRTYPE	124
+ #define CTYPEMAX	25
+ 
+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define	SQLCHAR		0
+ #define	SQLSMINT	1
+ #define	SQLINT		2
+ #define	SQLFLOAT	3
+ #define	SQLSMFLOAT	4
+ #define	SQLDECIMAL	5
+ #define	SQLSERIAL	6
+ #define	SQLDATE		7
+ #define	SQLMONEY	8
+ #define	SQLDTIME	10
+ #define	SQLBYTES	11
+ #define	SQLTEXT		12
+ #define	SQLVCHAR	13
+ #define	SQLINTERVAL	14
+ #define	SQLNCHAR	15
+ #define	SQLNVCHAR	16
+ #define	SQLINT8		17
+ #define	SQLSERIAL8	18
+ 
+ #endif   /* ndef ECPG_SQLTYPES_H */
+ 
+ #line 8 "sqlda.pgc"
+ 
+ 
+ /* exec sql whenever sqlerror  stop ; */
+ #line 10 "sqlda.pgc"
+ 
+ 
+ /* These shouldn't be under DECLARE SECTION */
+ pg_sqlda_t	*inp_sqlda, *outp_sqlda;
+ 
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+ 	int	i;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+ 			printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+ 		else
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 		case SQLCHAR:
+ 		case SQLVCHAR:
+ 		case SQLTEXT:
+ 			printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL:
+ 		case SQLINT:
+ 			printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL8:
+ 		case SQLINT8:
+ 			printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLFLOAT:
+ 			printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname, *(double *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLDECIMAL:
+ 			{
+ 				char    val[64];
+ 				dectoasc((decimal *)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 */
+ 		  
+ 		  
+ 		
+ 		
+ 
+ #line 58 "sqlda.pgc"
+  char * stmt1 = "SELECT * FROM t1" ;
+  
+ #line 59 "sqlda.pgc"
+  char * stmt2 = "SELECT * FROM t1 WHERE id = ?" ;
+  
+ #line 60 "sqlda.pgc"
+  int rec ;
+  
+ #line 61 "sqlda.pgc"
+  int id ;
+ /* exec sql end declare section */
+ #line 62 "sqlda.pgc"
+ 
+ 
+ 	char msg[128];
+ 
+ 	ECPGdebug(1, stderr);
+ 
+ 	strcpy(msg, "connect");
+ 	{ ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , "regress1", 0); 
+ #line 69 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 69 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "set");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 72 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 72 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "create");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT);
+ #line 80 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 80 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "insert");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null , null , null , null ) , ( 3 , '\"c\"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' )", ECPGt_EOIT, ECPGt_EORT);
+ #line 87 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 87 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, NULL, "commit");
+ #line 90 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 90 "sqlda.pgc"
+ 
+ 
+ 	/* SQLDA test for getting all records from a table */
+ 
+ 	outp_sqlda = NULL;
+ 
+ 	strcpy(msg, "prepare");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1);
+ #line 97 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 97 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "declare");
+ 	ECPG_informix_reset_sqlca(); /* declare mycur1 cursor for $1 */
+ #line 100 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "open");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", 
+ 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 103 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 103 "sqlda.pgc"
+ 
+ 
+ 	/* exec sql whenever not found  break ; */
+ #line 105 "sqlda.pgc"
+ 
+ 
+ 	rec = 0;
+ 	while (1)
+ 	{
+ 		strcpy(msg, "fetch");
+ 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 111 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 111 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 111 "sqlda.pgc"
+  
+ 
+ 		printf("FETCH RECORD %d\n", ++rec);
+ 		dump_sqlda(outp_sqlda);
+ 	}
+ 
+ 	/* exec sql whenever not found  continue ; */
+ #line 117 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "close");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
+ #line 120 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 120 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id1");
+ #line 123 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 123 "sqlda.pgc"
+ 
+ 
+ 	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");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt1);
+ #line 134 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 134 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "declare");
+ 	ECPG_informix_reset_sqlca(); /* declare mycur2 cursor for $1 */
+ #line 137 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "open");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", 
+ 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 140 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 140 "sqlda.pgc"
+ 
+ 
+ 	/* exec sql whenever not found  break ; */
+ #line 142 "sqlda.pgc"
+ 
+ 
+ 	rec = 0;
+ 	while (1)
+ 	{
+ 		strcpy(msg, "fetch");
+ 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 148 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 148 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 148 "sqlda.pgc"
+ 
+ 
+ 		printf("FETCH RECORD %d\n", ++rec);
+ 		dump_sqlda(outp_sqlda);
+ 	}
+ 
+ 	/* exec sql whenever not found  continue ; */
+ #line 154 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "close");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
+ #line 157 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 157 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id2");
+ #line 160 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 160 "sqlda.pgc"
+ 
+ 
+ 	free(outp_sqlda);
+ 
+ 	/* SQLDA test for getting one record using an input descriptor */
+ 
+ 	/* Input sqlda has to be built manually */
+ 	inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id3", stmt2);
+ #line 183 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 183 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "execute");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, 1, "st_id3", 
+ 	ECPGt_sqlda, & inp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 186 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 186 "sqlda.pgc"
+ 
+ 
+ 	dump_sqlda(outp_sqlda);
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id3");
+ #line 191 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 191 "sqlda.pgc"
+ 
+ 
+ 	free(inp_sqlda->sqlvar);
+ 	free(inp_sqlda);
+ 	free(outp_sqlda);
+ 
+ 	/* SQLDA test for getting one record using an input descriptor
+ 	 * on a named connection
+ 	 */
+ 
+ 	{ ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , "con2", 0); 
+ #line 201 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 201 "sqlda.pgc"
+ 
+ 
+ 	/* Input sqlda has to be built manually */
+ 	inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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");
+ 	{ ECPGprepare(__LINE__, "con2", 0, "st_id4", stmt2);
+ #line 220 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 220 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "execute");
+ 	{ ECPGdo(__LINE__, 1, 1, "con2", 0, 1, "st_id4", 
+ 	ECPGt_sqlda, & inp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 223 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 223 "sqlda.pgc"
+ 
+ 
+ 	dump_sqlda(outp_sqlda);
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, "con2", "commit");
+ #line 228 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 228 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id4");
+ #line 231 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 231 "sqlda.pgc"
+ 
+ 
+ 	free(inp_sqlda->sqlvar);
+ 	free(inp_sqlda);
+ 	free(outp_sqlda);
+ 
+ 	strcpy(msg, "disconnect");
+ 	{ ECPGdisconnect(__LINE__, "con2");
+ #line 238 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 238 "sqlda.pgc"
+ 
+ 
+ 	/* End test */
+ 
+ 	strcpy(msg, "drop");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
+ #line 243 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 243 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, NULL, "commit");
+ #line 246 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 246 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "disconnect");
+ 	{ ECPGdisconnect(__LINE__, "CURRENT");
+ #line 249 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 249 "sqlda.pgc"
+ 
+ 
+ 	return (0);
+ }
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr	2009-10-05 13:30:08.000000000 +0200
***************
*** 0 ****
--- 1,252 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: query: create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char ( 10 ) ); with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: query: insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null , null , null , null ) , ( 3 , '"c"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' ); with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: OK: INSERT 0 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 90: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 97: name st_id1; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: query: declare mycur1 cursor for SELECT * FROM t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 111: no data found on line 111
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 120: query: close mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 123: name st_id1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 134: name st_id2; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: query: declare mycur2 cursor for SELECT * FROM t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 148: no data found on line 148
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 157: query: close mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 160: name st_id2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 183: name st_id3; query: "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: free_params on line 186: parameter 1 = 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 191: name st_id3
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 220: name st_id4; query: "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection con2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: free_params on line 223: parameter 1 = 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 228: action "commit"; connection "con2"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 231: name st_id4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection con2 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: query: drop table t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 246: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout	2009-10-05 13:30:08.000000000 +0200
***************
*** 0 ****
--- 1,60 ----
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ EXECUTE RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ EXECUTE RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
#4Noah Misch
noah@leadboat.com
In reply to: Boszormenyi Zoltan (#2)
Re: Review of "SQLDA support for ECPG"

On Mon, Oct 05, 2009 at 02:23:57PM +0200, Boszormenyi Zoltan wrote:

Noah Misch ?rta:

I will post a new patch for SQLDA and for all others that need
updating.

Thanks; that one does apply cleanly.

The main test suite acquired no regressions, but I get failures in two tests of
the ecpg test suite (make -C src/interfaces/ecpg/test check).

No, this is not a real error. I have run into this as well,
which is quickly solved if you execute "make install"
before running "make check" under the ecpg directory.
I guess you already have an installed PG tree at the same
prefix as where you have pointed the new one with the
SQLDA patch applied. Another solution may be to use
a different prefix for the SQLDA source tree.

This was exactly the problem; with an unoccupied prefix, all the tests do pass.

As a side note, with patch 1* but not patch 2, test_informix entered an infinite
loop with this error:
ERROR: syntax error at or near "c" at character 15
STATEMENT: fetch forward c

Do you mean that you applied all the split-up patches posted
for the dynamic cursorname extension? I didn't get this error.
What did you do exactly?

Having started over from a clean base tree, I can no longer reproduce this.
Another operator error, no doubt.

All tests now pass here with 1a-1h of "Dynamic cursor support for ECPG" alone,
with "SQLDA support for ECPG" also applied, and with "DESCRIBE [OUTPUT] support
for ECPG" additionally. I will report on the sqlda patch in more detail on
2009-10-10. The one concern that's clear now is a lack of documentation update.

Thank you,
nm

#5Boszormenyi Zoltan
zb@cybertec.at
In reply to: Noah Misch (#4)
1 attachment(s)
Re: Review of "SQLDA support for ECPG"

Noah Misch �rta:

I will report on the sqlda patch in more detail on
2009-10-10.

I am attaching a new one, please review this. Changes:
- set sqllen, sqlind, sqlilen and sqlitype per-field properties
- SQLINT8 and SQLSERIAL8 are ECPGt_long on 64-bit, not ECPGt_long_long

The one concern that's clear now is a lack of documentation update.

That will come in a separate patch.

Thanks,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

Attachments:

2-pg85-sqlda-12-ctxdiff.patchtext/x-patch; name=2-pg85-sqlda-12-ctxdiff.patchDownload
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/execute.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/execute.c	2009-09-03 14:37:34.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c	2009-10-05 15:18:01.000000000 +0200
***************
*** 25,30 ****
--- 25,31 ----
  #include "ecpgerrno.h"
  #include "extern.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "sql3types.h"
  #include "pgtypes_numeric.h"
  #include "pgtypes_date.h"
*************** ecpg_store_input(const int lineno, const
*** 1033,1038 ****
--- 1034,1040 ----
  				break;
  
  			case ECPGt_descriptor:
+ 			case ECPGt_sqlda:
  				break;
  
  			default:
*************** ecpg_execute(struct statement * stmt)
*** 1172,1177 ****
--- 1174,1235 ----
  			if (desc->count == desc_counter)
  				desc_counter = 0;
  		}
+ 		else if (var->type == ECPGt_sqlda)
+ 		{
+ 			pg_sqlda_t	  **_sqlda = (pg_sqlda_t **)var->pointer;
+ 			pg_sqlda_t	   *sqlda = *_sqlda;
+ 			struct variable	desc_inlist;
+ 			int		i;
+ 
+ 			if (sqlda == NULL)
+ 				return false;
+ 
+ 			desc_counter++;
+ 			for (i = 0; i < sqlda->sqld; i++)
+ 			{
+ 				if (i + 1 == desc_counter)
+ 				{
+ 					desc_inlist.type = ecpg_sqlda_type(sqlda->sqlvar[i].sqltype);
+ 					desc_inlist.value = sqlda->sqlvar[i].sqldata;
+ 					desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
+ 					switch (desc_inlist.type)
+ 					{
+ 						case ECPGt_char:
+ 						case ECPGt_varchar:
+ 							desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
+ 							break;
+ 						default:
+ 							desc_inlist.varcharsize = 0;
+ 							break;
+ 					}
+ 					desc_inlist.arrsize = 1;
+ 					desc_inlist.offset = 0;
+ 					if (sqlda->sqlvar[i].sqlind)
+ 					{
+ 						desc_inlist.ind_type = ECPGt_short;
+ 						/* ECPG expects indicator value < 0 */
+ 						if (*(sqlda->sqlvar[i].sqlind))
+ 							*(sqlda->sqlvar[i].sqlind) = -1;
+ 						desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
+ 						desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
+ 						desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
+ 						desc_inlist.ind_offset = 0;
+ 					}
+ 					else
+ 					{
+ 						desc_inlist.ind_type = ECPGt_NO_INDICATOR;
+ 						desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
+ 						desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
+ 					}
+ 					if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
+ 						return false;
+ 
+ 					break;
+ 				}
+ 			}
+ 			if (sqlda->sqld == desc_counter)
+ 				desc_counter = 0;
+ 		}
  		else
  		{
  			if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false))
*************** ecpg_execute(struct statement * stmt)
*** 1353,1358 ****
--- 1411,1452 ----
  				}
  				var = var->next;
  			}
+ 			else if (var != NULL && var->type == ECPGt_sqlda)
+ 			{
+ 				pg_sqlda_t	  **_sqlda = (pg_sqlda_t **)var->pointer;
+ 				pg_sqlda_t	   *sqlda = *_sqlda;
+ 				pg_sqlda_t	   *sqlda_new;
+ 
+ 				/* Build a new sqlda structure. Note that only fetching 1 record is supported */
+ 				sqlda_new = ecpg_build_sqlda_for_PGresult(stmt->lineno, results, 0);
+ 
+ 				if (!sqlda_new)
+ 				{
+ 					ecpg_log("ecpg_execute on line %d: out of memory allocating a new sqlda\n", stmt->lineno);
+ 					status = false;
+ 				}
+ 				else
+ 				{
+ 					ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno);
+ 
+ 					/* If we are passed in a previously existing sqlda then free it. */
+ 					if (sqlda)
+ 					{
+ 						if (sqlda->sqlvar != (pg_sqlvar_t *)(sqlda + 1))
+ 							free(sqlda->sqlvar);
+ 						free(sqlda);
+ 						sqlda = NULL;
+ 					}
+ 
+ 					*_sqlda = sqlda_new;
+ 
+ 					ecpg_set_sqlda_from_PGresult(stmt->lineno, _sqlda, results, 0);
+ 					ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
+ 							stmt->lineno, PQnfields(results));
+ 				}
+ 
+ 				var = var->next;
+ 			}
  			else
  				for (act_field = 0; act_field < nfields && status; act_field++)
  				{
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/extern.h pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/extern.h	2009-05-25 12:08:48.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h	2009-10-05 15:18:01.000000000 +0200
***************
*** 6,11 ****
--- 6,12 ----
  #include "postgres_fe.h"
  #include "libpq-fe.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "ecpg_config.h"
  #ifndef CHAR_BIT
  #include <limits.h>
*************** bool		ecpg_init(const struct connection 
*** 129,134 ****
--- 130,137 ----
  char	   *ecpg_strdup(const char *, int);
  const char *ecpg_type_name(enum ECPGttype);
  int			ecpg_dynamic_type(Oid);
+ int			ecpg_sqlda_type(int);
+ int			ecpg_to_sqlda_type(Oid);
  void		ecpg_free_auto_mem(void);
  void		ecpg_clear_auto_mem(void);
  
*************** void		ecpg_log(const char *format,...);
*** 149,154 ****
--- 152,160 ----
  bool		ecpg_auto_prepare(int, const char *, const int, char **, const char *);
  void		ecpg_init_sqlca(struct sqlca_t * sqlca);
  
+ pg_sqlda_t *ecpg_build_sqlda_for_PGresult(int, PGresult *, int);
+ void		ecpg_set_sqlda_from_PGresult(int, pg_sqlda_t **, const PGresult *, int);
+ 
  /* SQLSTATE values generated or processed by ecpglib (intentionally
   * not exported -- users should refer to the codes directly) */
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/Makefile pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/Makefile	2009-07-13 11:16:41.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile	2009-10-05 15:18:01.000000000 +0200
*************** override CFLAGS += $(PTHREAD_CFLAGS)
*** 24,30 ****
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))
  
! OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
  	connect.o misc.o path.o pgstrcasecmp.o \
  	$(filter snprintf.o strlcpy.o, $(LIBOBJS))
  
--- 24,30 ----
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))
  
! OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
  	connect.o misc.o path.o pgstrcasecmp.o \
  	$(filter snprintf.o strlcpy.o, $(LIBOBJS))
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/sqlda.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/sqlda.c	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c	2009-10-07 14:06:07.000000000 +0200
***************
*** 0 ****
--- 1,289 ----
+ /*
+  * Crude SQLDA support routines
+  * Only supports fetching 1 record at a time
+  *
+  * The allocated memory area pointed by an sqlda pointer
+  * contains both the metadata and the data, so freeing up
+  * is a simple free(sqlda) as expected by the ESQL/C examples.
+  */
+ 
+ #define POSTGRES_ECPG_INTERNAL
+ #include "postgres_fe.h"
+ #include "pg_type.h"
+ 
+ #include <inttypes.h>
+ #include <dlfcn.h>
+ 
+ #include "ecpg-pthread-win32.h"
+ #include "decimal.h"
+ #include "ecpgtype.h"
+ #include "ecpglib.h"
+ #include "ecpgerrno.h"
+ #include "extern.h"
+ #include "sqlca.h"
+ #include "sqlda.h"
+ #include "sqltypes.h"
+ 
+ /*
+  * Compute the next variable's offset with
+  * the current variable's size and alignment.
+  */
+ static long
+ ecpg_sqlda_size_round_align(long offset, int alignment, int size)
+ {
+ 	if (offset % alignment)
+ 		offset += alignment - (offset % alignment);
+ 	offset += size;
+ 	return offset;
+ }
+ 
+ /*
+  * Compute the current variable's offset with alignment.
+  */
+ static long
+ ecpg_sqlda_size_align(long offset, int alignment)
+ {
+ 	if (offset % alignment)
+ 		offset += alignment - (offset % alignment);
+ 	return offset;
+ }
+ 
+ static long
+ ecpg_sqlda_empty_size(const PGresult *res)
+ {
+ 	long	size;
+ 	int	i;
+ 	int	sqld = PQnfields(res);
+ 
+ 	/* Initial size to store main structure and field structures */
+ 	size = sizeof(pg_sqlda_t) + sqld * sizeof(pg_sqlvar_t);
+ 
+ 	/* Add space for field names */
+ 	for (i = 0; i < sqld; i++)
+ 		size += strlen(PQfname(res, i)) + 1;
+ 
+ 	/* Add padding to the first field value */
+ 	size = ecpg_sqlda_size_align(size, sizeof(int));
+ 
+ 	return size;
+ }
+ 
+ static long
+ ecpg_sqlda_total_size(const PGresult *res, int row)
+ {
+ 	int	i;
+ 	int	sqld = PQnfields(res);
+ 	long	size;
+ 
+ 	size = ecpg_sqlda_empty_size(res);
+ 
+ 	if (row < 0)
+ 		return size;
+ 
+ 	/* Add space for the field values */
+ 	for (i = 0; i < sqld; i++)
+ 	{
+ 		switch (ecpg_to_sqlda_type(PQftype(res, i)))
+ 		{
+ 			case SQLSMINT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(short), sizeof(short));
+ 				break;
+ 			case SQLINT:
+ 			case SQLSERIAL:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(int));
+ 				break;
+ 			case SQLFLOAT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(double), sizeof(double));
+ 				break;
+ 			case SQLSMFLOAT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(float), sizeof(float));
+ 				break;
+ 			case SQLDECIMAL:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(decimal));
+ 				break;
+ 			case SQLINT8:
+ 			case SQLSERIAL8:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int64_t), sizeof(int64_t));
+ 				break;
+ 
+ 			/*
+ 			 * These types will be passed as character strings
+ 			 * copied as is from the PGresult until we know
+ 			 * what to do with them.
+ 			 */
+ 			case SQLCHAR:
+ 			case SQLTEXT:
+ 			case SQLVCHAR:
+ 			case SQLNCHAR:
+ 			case SQLNVCHAR:
+ 			case SQLMONEY:
+ 			case SQLDATE:
+ 			case SQLDTIME:
+ 			case SQLINTERVAL:
+ 			default:
+ 				size += strlen(PQgetvalue(res, row, i)) + 1;
+ 				break;
+ 		}
+ 	}
+ 	return size;
+ }
+ 
+ /*
+  * Build pg_sqlda_t (metadata only) from PGresult
+  * leaving enough space for the field values in
+  * the given row number
+  */
+ pg_sqlda_t *
+ ecpg_build_sqlda_for_PGresult(int line, PGresult *res, int row)
+ {
+ 	pg_sqlda_t *sqlda;
+ 	pg_sqlvar_t*sqlvar;
+ 	char	   *fname;
+ 	long		size;
+ 	int		sqld;
+ 	int		i;
+ 
+ 	size = ecpg_sqlda_total_size(res, row);
+ 	sqlda = (pg_sqlda_t *)ecpg_alloc(size, line);
+ 	if (!sqlda)
+ 		return NULL;
+ 
+ 	memset(sqlda, 0, size);
+ 	sqlvar = (pg_sqlvar_t *)(sqlda + 1);
+ 	sqld = PQnfields(res);
+ 	fname = (char *)(sqlvar + sqld);
+ 
+ 	sqlda->sqld = sqld;
+ 	sqlda->desc_occ = size; /* cheat here, keep the full allocated size */
+ 	sqlda->sqlvar = sqlvar;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		sqlda->sqlvar[i].sqltype = ecpg_to_sqlda_type(PQftype(res, i));
+ 		strcpy(fname, PQfname(res, i));
+ 		sqlda->sqlvar[i].sqlname = fname;
+ 		fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
+ 		sqlda->sqlvar[i].sqlformat = (char *)(long)PQfformat(res, i);
+ 		sqlda->sqlvar[i].sqlxid = PQftype(res, i);
+ 		sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
+ 	}
+ 
+ 	return sqlda;
+ }
+ 
+ /*
+  * Sets values from PGresult.
+  */
+ void
+ ecpg_set_sqlda_from_PGresult(int lineno, pg_sqlda_t **_sqlda, const PGresult *res, int row)
+ {
+ 	pg_sqlda_t *sqlda = (*_sqlda);
+ 	int		i;
+ 	long		size;
+ 	static	int2	value_is_null = -1;
+ 	static	int2	value_is_not_null = 0;
+ 
+ 	/* Offset for the first field value */
+ 	size = ecpg_sqlda_empty_size(res);
+ 
+ 	/*
+ 	 * Set sqlvar[i]->sqldata pointers and convert values to correct format
+ 	 */
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		int type = -1, isnull;
+ 		int use_getdata = true;
+ 		int datalen;
+ 
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 			case SQLSMINT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(short));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(short);
+ 				size += sizeof(short);
+ 				type = ECPGt_short;
+ 				break;
+ 			case SQLINT:
+ 			case SQLSERIAL:
+ 				size = ecpg_sqlda_size_align(size, sizeof(int));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(int);
+ 				size += sizeof(int);
+ 				type = ECPGt_int;
+ 				break;
+ 			case SQLFLOAT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(double));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(double);
+ 				size += sizeof(double);
+ 				type = ECPGt_double;
+ 				break;
+ 			case SQLSMFLOAT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(float));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(float);
+ 				size += sizeof(float);
+ 				type = ECPGt_float;
+ 				break;
+ 			case SQLDECIMAL:
+ 			{
+ 				size = ecpg_sqlda_size_align(size, sizeof(int));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(decimal);
+ 				size += sizeof(decimal);
+ 				type = ECPGt_decimal;
+ 				break;
+ 			}
+ 			case SQLINT8:
+ 			case SQLSERIAL8:
+ 				size = ecpg_sqlda_size_align(size, sizeof(int64_t));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(int64_t);
+ 				size += sizeof(int64_t);
+ 				type = ECPGt_long_long;
+ 				break;
+ 
+ 			/*
+ 			 * These types will be passed as character strings until
+ 			 * it's known what to do with them. We use sqlvar->sqldata
+ 			 * in all cases regardless of length, don't care about
+ 			 * sqlvar->sqlilongdata.
+ 			 */
+ 			case SQLCHAR:
+ 			case SQLTEXT:
+ 			case SQLVCHAR:
+ 			case SQLNCHAR:
+ 			case SQLNVCHAR:
+ 			case SQLMONEY:
+ 			case SQLDATE:
+ 			case SQLDTIME:
+ 			case SQLINTERVAL:
+ 			default:
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				datalen = strlen(PQgetvalue(res, row, i)) + 1;
+ 				sqlda->sqlvar[i].sqllen = datalen;
+ 				size += datalen;
+ 				if (datalen > 32768)
+ 					sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
+ 				use_getdata = false;
+ 				break;
+ 		}
+ 
+ 		isnull = PQgetisnull(res, 0, i);
+ 		sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
+ 		sqlda->sqlvar[i].sqlitype = SQLSMINT;
+ 		sqlda->sqlvar[i].sqlilen = sizeof(short);
+ 		if (!isnull)
+ 		{
+ 			if (use_getdata)
+ 				ecpg_get_data(res, row, i, lineno,
+ 						type, ECPGt_NO_INDICATOR,
+ 						sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
+ 						ECPG_ARRAY_NONE, ECPG_COMPAT_INFORMIX, false);
+ 			else
+ 				strcpy(sqlda->sqlvar[i].sqldata, PQgetvalue(res, row, i));
+ 		}
+ 	}
+ }
+ 
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/typename.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/typename.c	2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c	2009-10-08 12:14:07.000000000 +0200
***************
*** 7,12 ****
--- 7,13 ----
  #include "ecpgtype.h"
  #include "ecpglib.h"
  #include "extern.h"
+ #include "sqltypes.h"
  #include "sql3types.h"
  #include "pg_type.h"
  
*************** ecpg_dynamic_type(Oid type)
*** 100,102 ****
--- 101,194 ----
  			return -(int) type;
  	}
  }
+ 
+ int
+ ecpg_sqlda_type(int type)
+ {
+ 	switch (type)
+ 	{
+ 		case SQLCHAR:
+ 		case SQLNCHAR:
+ 			return ECPGt_char;
+ 		case SQLSMINT:
+ 			return ECPGt_short;
+ 		case SQLINT:
+ 			return ECPGt_int;
+ 		case SQLFLOAT:
+ 			return ECPGt_double;
+ 		case SQLSMFLOAT:
+ 			return ECPGt_float;
+ 		case SQLDECIMAL:
+ 			return ECPGt_decimal;
+ 		case SQLSERIAL:
+ 			return ECPGt_int;
+ 		case SQLDATE:
+ 			return ECPGt_date;
+ #if 0
+ 		case SQLMONEY:
+ 			return ???;
+ 		case SQLNULL:
+ 			return ???;
+ #endif
+ 		case SQLDTIME:
+ 			return ECPGt_timestamp;
+ #if 0
+ 		case SQLBYTES:
+ 			return ???;
+ #endif
+ 		case SQLTEXT:
+ 			return ECPGt_char;
+ 		case SQLVCHAR:
+ 		case SQLNVCHAR:
+ 			return ECPGt_varchar;
+ 		case SQLINTERVAL:
+ 			return ECPGt_interval;
+ 		case SQLINT8:
+ 		case SQLSERIAL8:
+ #ifdef HAVE_LONG_LONG_INT_64
+ 			return ECPGt_long_long;
+ #else
+ 			return ECPGt_long;
+ #endif
+ 		default:
+ 			return (-type);
+ 	}
+ }
+ 
+ int
+ ecpg_to_sqlda_type(Oid type)
+ {
+ 	switch (type)
+ 	{
+ 		case CHAROID:
+ 		case BPCHAROID:
+ 			return SQLCHAR;
+ 		case INT2OID:
+ 			return SQLSMINT;
+ 		case INT4OID:
+ 			return SQLINT;
+ 		case FLOAT8OID:
+ 			return SQLFLOAT;
+ 		case FLOAT4OID:
+ 			return SQLSMFLOAT;
+ 		case NUMERICOID:
+ 			return SQLDECIMAL;
+ 		case DATEOID:
+ 			return SQLDATE;
+ 		case CASHOID:
+ 			return SQLMONEY;
+ 		case TIMESTAMPOID:
+ 		case TIMESTAMPTZOID:
+ 			return SQLDTIME;
+ 		case TEXTOID:
+ 			return SQLTEXT;
+ 		case VARCHAROID:
+ 			return SQLVCHAR;
+ 		case INTERVALOID:
+ 			return SQLINTERVAL;
+ 		case INT8OID:
+ 			return SQLINT8;
+ 		default:
+ 			return (-type);
+ 	}
+ }
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/ecpgtype.h pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/ecpgtype.h	2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h	2009-10-05 15:18:01.000000000 +0200
*************** enum ECPGttype
*** 62,68 ****
  	ECPGt_EOIT,					/* End of insert types. */
  	ECPGt_EORT,					/* End of result types. */
  	ECPGt_NO_INDICATOR,			/* no indicator */
! 	ECPGt_string                            /* trimmed (char *) type */
  };
  
   /* descriptor items */
--- 62,69 ----
  	ECPGt_EOIT,					/* End of insert types. */
  	ECPGt_EORT,					/* End of result types. */
  	ECPGt_NO_INDICATOR,			/* no indicator */
! 	ECPGt_string,				/* trimmed (char *) type */
! 	ECPGt_sqlda				/* C struct descriptor */
  };
  
   /* descriptor items */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/sqlda.h pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/sqlda.h	2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h	2009-10-05 15:18:01.000000000 +0200
***************
*** 1,3 ****
--- 1,74 ----
  /*
   * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
   */
+ 
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+ 
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int		int4;
+ typedef	short		int2;
+ #endif
+ typedef	char		int1;
+ 
+ typedef	int		mint;
+ typedef	long		mlong;
+ 
+ typedef	short		MSHORT;
+ typedef	char		MCHAR; 
+ 
+ typedef	unsigned int	uint4;
+ typedef	unsigned short	uint2;
+ typedef	unsigned char	uint1;
+ 
+ typedef	unsigned int	muint;
+ typedef	unsigned long	mulong;
+ 
+ typedef	unsigned short	MUSHORT;
+ typedef	unsigned char	MUCHAR; 
+ 
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+ 
+ typedef struct sqlvar_struct
+ {
+ 	int2	sqltype;		/* variable type                */
+ 	int4	sqllen;			/* length in bytes              */
+ 	char	   *sqldata;		/* pointer to data              */
+ 	int2	   *sqlind;		/* pointer to indicator         */
+ 	char	   *sqlname;		/* variable name                */
+ 	char	   *sqlformat;		/* reserved for future use      */
+ 	int2	sqlitype;		/* ind variable type            */
+ 	int2	sqlilen;		/* ind length in bytes          */
+ 	char	   *sqlidata;		/* ind data pointer             */
+ 	int4	sqlxid;			/* extended id type             */
+ 	char	   *sqltypename;	/* extended type name           */
+ 	int2	sqltypelen;		/* length of extended type name */
+ 	int2	sqlownerlen;		/* length of owner name         */
+ 	int2	sqlsourcetype;		/* source type for distinct of built-ins */
+ 	char	   *sqlownername;	/* owner name                   */
+ 	int4	sqlsourceid;		/* extended id of source type   */
+ 
+ 	/*
+ 	 * sqlilongdata is new.  It supports data that exceeds the 32k
+ 	 * limit.  sqlilen and sqlidata are for backward compatibility
+ 	 * and they have maximum value of <32K.
+ 	 */
+ 	char	   *sqlilongdata;	/* for data field beyond 32K    */
+ 	int4	sqlflags;		/* for internal use only        */
+ 	void	   *sqlreserved;	/* reserved for future use      */
+ } pg_sqlvar_t;
+ 
+ typedef struct sqlda
+ {
+ 	int2		sqld;
+ 	pg_sqlvar_t	   *sqlvar;
+ 	char		desc_name[19];	/* descriptor name              */
+ 	int2		desc_occ;	/* size of sqlda structure      */
+ 	struct sqlda	   *desc_next;	/* pointer to next sqlda struct */
+ 	void		   *reserved;	/* reserved for future use */
+ } pg_sqlda_t;
+ 
+ #endif /* POSTGRES_SQLDA_H */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/sqltypes.h pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/sqltypes.h	2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h	2009-10-05 15:18:01.000000000 +0200
***************
*** 30,33 ****
--- 30,55 ----
  #define CLVCHARPTRTYPE	124
  #define CTYPEMAX	25
  
+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define	SQLCHAR		0
+ #define	SQLSMINT	1
+ #define	SQLINT		2
+ #define	SQLFLOAT	3
+ #define	SQLSMFLOAT	4
+ #define	SQLDECIMAL	5
+ #define	SQLSERIAL	6
+ #define	SQLDATE		7
+ #define	SQLMONEY	8
+ #define	SQLDTIME	10
+ #define	SQLBYTES	11
+ #define	SQLTEXT		12
+ #define	SQLVCHAR	13
+ #define	SQLINTERVAL	14
+ #define	SQLNCHAR	15
+ #define	SQLNVCHAR	16
+ #define	SQLINT8		17
+ #define	SQLSERIAL8	18
+ 
  #endif   /* ndef ECPG_SQLTYPES_H */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/descriptor.c pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/descriptor.c	2009-01-30 17:28:46.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c	2009-10-05 15:18:01.000000000 +0200
*************** descriptor_variable(const char *name, in
*** 326,328 ****
--- 326,347 ----
  	strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
  	return (struct variable *) & varspace[input];
  }
+ 
+ struct variable *
+ sqlda_variable(const char *name)
+ {
+ 	struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
+ 
+ 	p->name = mm_strdup(name);
+ 	p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
+ 	p->type->type = ECPGt_sqlda;
+ 	p->type->size = NULL;
+ 	p->type->struct_sizeof = NULL;
+ 	p->type->u.element = NULL;
+ 	p->type->lineno = 0;
+ 	p->brace_level = 0;
+ 	p->next = NULL;
+ 
+ 	return p;
+ }
+ 
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.addons pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.addons	2009-10-03 01:54:43.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons	2009-10-05 15:18:01.000000000 +0200
*************** ECPG: VariableShowStmtSHOWALL block
*** 402,430 ****
  		$$ = EMPTY;
  	}
  ECPG: FetchStmtMOVEfetch_args rule
! 	| FETCH fetch_args ecpg_into
  	{
  		$$ = cat2_str(make_str("fetch"), $2);
  	}
! 	| FETCH FORWARD cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch forward"), cursor_marker);
  	}
! 	| FETCH FORWARD from_in cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
  		$$ = cat_str(2, make_str("fetch forward from"), cursor_marker);
  	}
! 	| FETCH BACKWARD cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch backward"), cursor_marker);
  	}
! 	| FETCH BACKWARD from_in cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
--- 402,430 ----
  		$$ = EMPTY;
  	}
  ECPG: FetchStmtMOVEfetch_args rule
! 	| FETCH fetch_args ecpg_fetch_into
  	{
  		$$ = cat2_str(make_str("fetch"), $2);
  	}
! 	| FETCH FORWARD cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch forward"), cursor_marker);
  	}
! 	| FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
  		$$ = cat_str(2, make_str("fetch forward from"), cursor_marker);
  	}
! 	| FETCH BACKWARD cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch backward"), cursor_marker);
  	}
! 	| FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.trailer pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.trailer	2009-10-03 02:05:58.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer	2009-10-05 15:18:01.000000000 +0200
*************** ecpg_using:	USING using_list 	{ $$ = EMP
*** 1017,1035 ****
  
  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
  			$$ = EMPTY;
  		}
  		;
  
  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
  			$$ = EMPTY;
  		}
  		;
  
! opt_sql: /*EMPTY*/ | SQL_SQL;
  
  using_list: UsingValue | UsingValue ',' using_list;
  
--- 1017,1065 ----
  
  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			if (strlen($2) || !(INFORMIX_MODE))
! 				add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
! 			else
! 			{
! 				if ($4[0] == '\"')
! 				{
! 					char *pos;
! 
! 					$4[0] = ' ';
! 					for (pos = $4; *pos; pos++)
! 						if (*pos == '\"')
! 							*pos = ' ';
! 				}
! 				add_variable_to_head(&argsinsert, sqlda_variable($4), &no_indicator);
! 			}
  			$$ = EMPTY;
  		}
  		;
  
  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			if (strlen($2) || !(INFORMIX_MODE))
! 				add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
! 			else
! 			{
! 				if ($4[0] == '\"')
! 				{
! 					char *pos;
! 
! 					$4[0] = ' ';
! 					for (pos = $4; *pos; pos++)
! 						if (*pos == '\"')
! 							*pos = ' ';
! 				}
! 				add_variable_to_head(&argsresult, sqlda_variable($4), &no_indicator);
! 			}
  			$$ = EMPTY;
  		}
  		;
  
! opt_sql: /*EMPTY*/		{ $$ = EMPTY; }
! 		| SQL_SQL	{ $$ = make_str("sql"); }
! 		;
  
  using_list: UsingValue | UsingValue ',' using_list;
  
*************** ecpg_into: INTO into_list	{ $$ = EMPTY; 
*** 2052,2058 ****
          | into_descriptor	{ $$ = $1; }
  	;
  
! opt_ecpg_into:	/* EMPTY */	{ $$ = EMPTY; }
  	| ecpg_into		{ $$ = $1; }
  	;
  
--- 2082,2103 ----
          | into_descriptor	{ $$ = $1; }
  	;
  
! ecpg_fetch_into: ecpg_into	{ $$ = $1; }
! 	| using_descriptor
! 	{
! 		struct variable *var;
! 
! 		if (!INFORMIX_MODE)
! 			mmerror(PARSE_ERROR, ET_ERROR, "Not in Informix compatibility mode");
! 
! 		var = argsinsert->variable;
! 		remove_variable_from_list(&argsinsert, var);
! 		add_variable_to_head(&argsresult, var, &no_indicator);
! 		$$ = $1;
! 	}
! 	;
! 
! opt_ecpg_fetch_into:	/* EMPTY */	{ $$ = EMPTY; }
  	| ecpg_into		{ $$ = $1; }
  	;
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.type pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.type	2009-10-03 02:03:31.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type	2009-10-05 15:18:01.000000000 +0200
***************
*** 62,67 ****
--- 62,68 ----
  %type <str> ecpg_ident
  %type <str> ecpg_interval
  %type <str> ecpg_into
+ %type <str> ecpg_fetch_into
  %type <str> ecpg_param
  %type <str> ecpg_sconst
  %type <str> ecpg_using
***************
*** 77,83 ****
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
--- 78,84 ----
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_fetch_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
***************
*** 87,92 ****
--- 88,94 ----
  %type <str> opt_reference
  %type <str> opt_scale
  %type <str> opt_server
+ %type <str> opt_sql   
  %type <str> opt_user
  %type <str> opt_opt_value
  %type <str> ora_user
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/extern.h pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/extern.h	2009-10-03 01:07:54.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h	2009-10-05 15:18:01.000000000 +0200
*************** extern void add_descriptor(char *, char 
*** 88,93 ****
--- 88,94 ----
  extern void drop_descriptor(char *, char *);
  extern struct descriptor *lookup_descriptor(char *, char *);
  extern struct variable *descriptor_variable(const char *name, int input);
+ extern struct variable *sqlda_variable(const char *name);
  extern void add_variable_to_head(struct arguments **, struct variable *, struct variable *);
  extern void add_variable_to_tail(struct arguments **, struct variable *, struct variable *);
  extern void remove_variable_from_list(struct arguments ** list, struct variable * var);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/type.c pgsql.sqlda/src/interfaces/ecpg/preproc/type.c
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/type.c	2009-09-03 12:25:47.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/type.c	2009-10-05 15:18:01.000000000 +0200
*************** get_type(enum ECPGttype type)
*** 194,199 ****
--- 194,202 ----
  		case ECPGt_descriptor:
  			return ("ECPGt_descriptor");
  			break;
+ 		case ECPGt_sqlda:
+ 			return ("ECPGt_sqlda");
+ 			break;
  		case ECPGt_date:
  			return ("ECPGt_date");
  			break;
*************** ECPGdump_a_simple(FILE *o, const char *n
*** 328,333 ****
--- 331,338 ----
  	else if (type == ECPGt_descriptor)
  		/* remember that name here already contains quotes (if needed) */
  		fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name);
+ 	else if (type == ECPGt_sqlda)
+ 		fprintf(o, "\n\tECPGt_sqlda, &%s, 0L, 0L, 0L, ", name);
  	else
  	{
  		char	   *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/Makefile pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile
*** pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/Makefile	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile	2009-10-05 15:18:01.000000000 +0200
*************** TESTS = test_informix test_informix.c \
*** 17,22 ****
--- 17,23 ----
          rfmtdate rfmtdate.c \
          rfmtlong rfmtlong.c \
          rnull rnull.c \
+         sqlda sqlda.c \
          charfuncs charfuncs.c
  
  all: $(TESTS)
*************** test_informix2.c: test_informix2.pgc ../
*** 30,35 ****
--- 31,39 ----
  cursor.c: cursor.pgc ../regression.h
  	$(ECPG) -o $@ -I$(srcdir) $<
  
+ sqlda.c: sqlda.pgc ../regression.h
+ 	$(ECPG) -o $@ -I$(srcdir) $<
+ 
  dec_test.c: dec_test.pgc ../regression.h
  	$(ECPG) -o $@ -I$(srcdir) $<
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/sqlda.pgc pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
*** pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/sqlda.pgc	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,252 ----
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.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 */
+ pg_sqlda_t	*inp_sqlda, *outp_sqlda;
+ 
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+ 	int	i;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+ 			printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+ 		else
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 		case SQLCHAR:
+ 		case SQLVCHAR:
+ 		case SQLTEXT:
+ 			printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL:
+ 		case SQLINT:
+ 			printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL8:
+ 		case SQLINT8:
+ 			printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLFLOAT:
+ 			printf("name sqlda descriptor: '%s' value %lf\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),
+ 		(3, '"c"', -3, 'nan'::float8, 'c'),
+ 		(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 = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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 = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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 -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule
*** pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule	2009-10-05 15:18:01.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule_tcp pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp
*** pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule_tcp	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp	2009-10-05 15:18:01.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,585 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* Needed for informix compatibility */
+ #include <ecpg_informix.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+ 
+ #line 1 "sqlda.pgc"
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.h>
+ 
+ 
+ #line 1 "regression.h"
+ 
+ 
+ 
+ 
+ 
+ 
+ #line 5 "sqlda.pgc"
+ 
+ 
+ 
+ #line 1 "sqlda.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
+  */
+ 
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+ 
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int		int4;
+ typedef	short		int2;
+ #endif
+ typedef	char		int1;
+ 
+ typedef	int		mint;
+ typedef	long		mlong;
+ 
+ typedef	short		MSHORT;
+ typedef	char		MCHAR; 
+ 
+ typedef	unsigned int	uint4;
+ typedef	unsigned short	uint2;
+ typedef	unsigned char	uint1;
+ 
+ typedef	unsigned int	muint;
+ typedef	unsigned long	mulong;
+ 
+ typedef	unsigned short	MUSHORT;
+ typedef	unsigned char	MUCHAR; 
+ 
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+ 
+ typedef struct sqlvar_struct
+ {
+ 	int2	sqltype;		/* variable type                */
+ 	int4	sqllen;			/* length in bytes              */
+ 	char	   *sqldata;		/* pointer to data              */
+ 	int2	   *sqlind;		/* pointer to indicator         */
+ 	char	   *sqlname;		/* variable name                */
+ 	char	   *sqlformat;		/* reserved for future use      */
+ 	int2	sqlitype;		/* ind variable type            */
+ 	int2	sqlilen;		/* ind length in bytes          */
+ 	char	   *sqlidata;		/* ind data pointer             */
+ 	int4	sqlxid;			/* extended id type             */
+ 	char	   *sqltypename;	/* extended type name           */
+ 	int2	sqltypelen;		/* length of extended type name */
+ 	int2	sqlownerlen;		/* length of owner name         */
+ 	int2	sqlsourcetype;		/* source type for distinct of built-ins */
+ 	char	   *sqlownername;	/* owner name                   */
+ 	int4	sqlsourceid;		/* extended id of source type   */
+ 
+ 	/*
+ 	 * sqlilongdata is new.  It supports data that exceeds the 32k
+ 	 * limit.  sqlilen and sqlidata are for backward compatibility
+ 	 * and they have maximum value of <32K.
+ 	 */
+ 	char	   *sqlilongdata;	/* for data field beyond 32K    */
+ 	int4	sqlflags;		/* for internal use only        */
+ 	void	   *sqlreserved;	/* reserved for future use      */
+ } pg_sqlvar_t;
+ 
+ typedef struct sqlda
+ {
+ 	int2		sqld;
+ 	pg_sqlvar_t	   *sqlvar;
+ 	char		desc_name[19];	/* descriptor name              */
+ 	int2		desc_occ;	/* size of sqlda structure      */
+ 	struct sqlda	   *desc_next;	/* pointer to next sqlda struct */
+ 	void		   *reserved;	/* reserved for future use */
+ } pg_sqlda_t;
+ 
+ #endif /* POSTGRES_SQLDA_H */
+ 
+ #line 7 "sqlda.pgc"
+ 
+ 
+ #line 1 "sqltypes.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqltypes.h,v 1.9 2009/06/11 14:49:13 momjian Exp $
+  */
+ #ifndef ECPG_SQLTYPES_H
+ #define ECPG_SQLTYPES_H
+ 
+ #define CCHARTYPE	ECPGt_char
+ #define CSHORTTYPE	ECPGt_short
+ #define CINTTYPE	ECPGt_int
+ #define CLONGTYPE	ECPGt_long
+ #define CFLOATTYPE	ECPGt_float
+ #define CDOUBLETYPE ECPGt_double
+ #define CDECIMALTYPE	ECPGt_decimal
+ #define CFIXCHARTYPE	108
+ #define CSTRINGTYPE ECPGt_char
+ #define CDATETYPE	ECPGt_date
+ #define CMONEYTYPE	111
+ #define CDTIMETYPE	ECPGt_timestamp
+ #define CLOCATORTYPE	113
+ #define CVCHARTYPE	ECPGt_varchar
+ #define CINVTYPE	115
+ #define CFILETYPE	116
+ #define CINT8TYPE	ECPGt_long_long
+ #define CCOLLTYPE		118
+ #define CLVCHARTYPE		119
+ #define CFIXBINTYPE		120
+ #define CVARBINTYPE		121
+ #define CBOOLTYPE		ECPGt_bool
+ #define CROWTYPE		123
+ #define CLVCHARPTRTYPE	124
+ #define CTYPEMAX	25
+ 
+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define	SQLCHAR		0
+ #define	SQLSMINT	1
+ #define	SQLINT		2
+ #define	SQLFLOAT	3
+ #define	SQLSMFLOAT	4
+ #define	SQLDECIMAL	5
+ #define	SQLSERIAL	6
+ #define	SQLDATE		7
+ #define	SQLMONEY	8
+ #define	SQLDTIME	10
+ #define	SQLBYTES	11
+ #define	SQLTEXT		12
+ #define	SQLVCHAR	13
+ #define	SQLINTERVAL	14
+ #define	SQLNCHAR	15
+ #define	SQLNVCHAR	16
+ #define	SQLINT8		17
+ #define	SQLSERIAL8	18
+ 
+ #endif   /* ndef ECPG_SQLTYPES_H */
+ 
+ #line 8 "sqlda.pgc"
+ 
+ 
+ /* exec sql whenever sqlerror  stop ; */
+ #line 10 "sqlda.pgc"
+ 
+ 
+ /* These shouldn't be under DECLARE SECTION */
+ pg_sqlda_t	*inp_sqlda, *outp_sqlda;
+ 
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+ 	int	i;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+ 			printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+ 		else
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 		case SQLCHAR:
+ 		case SQLVCHAR:
+ 		case SQLTEXT:
+ 			printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL:
+ 		case SQLINT:
+ 			printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL8:
+ 		case SQLINT8:
+ 			printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLFLOAT:
+ 			printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname, *(double *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLDECIMAL:
+ 			{
+ 				char    val[64];
+ 				dectoasc((decimal *)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 */
+ 		  
+ 		  
+ 		
+ 		
+ 
+ #line 58 "sqlda.pgc"
+  char * stmt1 = "SELECT * FROM t1" ;
+  
+ #line 59 "sqlda.pgc"
+  char * stmt2 = "SELECT * FROM t1 WHERE id = ?" ;
+  
+ #line 60 "sqlda.pgc"
+  int rec ;
+  
+ #line 61 "sqlda.pgc"
+  int id ;
+ /* exec sql end declare section */
+ #line 62 "sqlda.pgc"
+ 
+ 
+ 	char msg[128];
+ 
+ 	ECPGdebug(1, stderr);
+ 
+ 	strcpy(msg, "connect");
+ 	{ ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , "regress1", 0); 
+ #line 69 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 69 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "set");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 72 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 72 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "create");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT);
+ #line 80 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 80 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "insert");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null , null , null , null ) , ( 3 , '\"c\"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' )", ECPGt_EOIT, ECPGt_EORT);
+ #line 87 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 87 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, NULL, "commit");
+ #line 90 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 90 "sqlda.pgc"
+ 
+ 
+ 	/* SQLDA test for getting all records from a table */
+ 
+ 	outp_sqlda = NULL;
+ 
+ 	strcpy(msg, "prepare");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1);
+ #line 97 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 97 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "declare");
+ 	ECPG_informix_reset_sqlca(); /* declare mycur1 cursor for $1 */
+ #line 100 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "open");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", 
+ 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 103 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 103 "sqlda.pgc"
+ 
+ 
+ 	/* exec sql whenever not found  break ; */
+ #line 105 "sqlda.pgc"
+ 
+ 
+ 	rec = 0;
+ 	while (1)
+ 	{
+ 		strcpy(msg, "fetch");
+ 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 111 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 111 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 111 "sqlda.pgc"
+  
+ 
+ 		printf("FETCH RECORD %d\n", ++rec);
+ 		dump_sqlda(outp_sqlda);
+ 	}
+ 
+ 	/* exec sql whenever not found  continue ; */
+ #line 117 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "close");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
+ #line 120 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 120 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id1");
+ #line 123 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 123 "sqlda.pgc"
+ 
+ 
+ 	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");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt1);
+ #line 134 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 134 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "declare");
+ 	ECPG_informix_reset_sqlca(); /* declare mycur2 cursor for $1 */
+ #line 137 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "open");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", 
+ 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 140 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 140 "sqlda.pgc"
+ 
+ 
+ 	/* exec sql whenever not found  break ; */
+ #line 142 "sqlda.pgc"
+ 
+ 
+ 	rec = 0;
+ 	while (1)
+ 	{
+ 		strcpy(msg, "fetch");
+ 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 148 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 148 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 148 "sqlda.pgc"
+ 
+ 
+ 		printf("FETCH RECORD %d\n", ++rec);
+ 		dump_sqlda(outp_sqlda);
+ 	}
+ 
+ 	/* exec sql whenever not found  continue ; */
+ #line 154 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "close");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
+ #line 157 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 157 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id2");
+ #line 160 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 160 "sqlda.pgc"
+ 
+ 
+ 	free(outp_sqlda);
+ 
+ 	/* SQLDA test for getting one record using an input descriptor */
+ 
+ 	/* Input sqlda has to be built manually */
+ 	inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id3", stmt2);
+ #line 183 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 183 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "execute");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, 1, "st_id3", 
+ 	ECPGt_sqlda, & inp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 186 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 186 "sqlda.pgc"
+ 
+ 
+ 	dump_sqlda(outp_sqlda);
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id3");
+ #line 191 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 191 "sqlda.pgc"
+ 
+ 
+ 	free(inp_sqlda->sqlvar);
+ 	free(inp_sqlda);
+ 	free(outp_sqlda);
+ 
+ 	/* SQLDA test for getting one record using an input descriptor
+ 	 * on a named connection
+ 	 */
+ 
+ 	{ ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , "con2", 0); 
+ #line 201 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 201 "sqlda.pgc"
+ 
+ 
+ 	/* Input sqlda has to be built manually */
+ 	inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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");
+ 	{ ECPGprepare(__LINE__, "con2", 0, "st_id4", stmt2);
+ #line 220 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 220 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "execute");
+ 	{ ECPGdo(__LINE__, 1, 1, "con2", 0, 1, "st_id4", 
+ 	ECPGt_sqlda, & inp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 223 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 223 "sqlda.pgc"
+ 
+ 
+ 	dump_sqlda(outp_sqlda);
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, "con2", "commit");
+ #line 228 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 228 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id4");
+ #line 231 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 231 "sqlda.pgc"
+ 
+ 
+ 	free(inp_sqlda->sqlvar);
+ 	free(inp_sqlda);
+ 	free(outp_sqlda);
+ 
+ 	strcpy(msg, "disconnect");
+ 	{ ECPGdisconnect(__LINE__, "con2");
+ #line 238 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 238 "sqlda.pgc"
+ 
+ 
+ 	/* End test */
+ 
+ 	strcpy(msg, "drop");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
+ #line 243 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 243 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, NULL, "commit");
+ #line 246 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 246 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "disconnect");
+ 	{ ECPGdisconnect(__LINE__, "CURRENT");
+ #line 249 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 249 "sqlda.pgc"
+ 
+ 
+ 	return (0);
+ }
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,252 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: query: create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char ( 10 ) ); with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: query: insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null , null , null , null ) , ( 3 , '"c"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' ); with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: OK: INSERT 0 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 90: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 97: name st_id1; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: query: declare mycur1 cursor for SELECT * FROM t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 111: no data found on line 111
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 120: query: close mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 123: name st_id1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 134: name st_id2; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: query: declare mycur2 cursor for SELECT * FROM t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 148: no data found on line 148
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 157: query: close mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 160: name st_id2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 183: name st_id3; query: "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: free_params on line 186: parameter 1 = 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 191: name st_id3
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 220: name st_id4; query: "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection con2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: free_params on line 223: parameter 1 = 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 228: action "commit"; connection "con2"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 231: name st_id4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection con2 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: query: drop table t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 246: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,60 ----
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ EXECUTE RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ EXECUTE RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
#6Robert Haas
robertmhaas@gmail.com
In reply to: Boszormenyi Zoltan (#5)
Re: Review of "SQLDA support for ECPG"

On Thu, Oct 8, 2009 at 6:22 AM, Boszormenyi Zoltan <zb@cybertec.at> wrote:

Noah Misch írta:

I will report on the sqlda patch in more detail on
2009-10-10.

I am attaching a new one, please review this. Changes:
- set sqllen, sqlind, sqlilen and sqlitype per-field properties
- SQLINT8 and SQLSERIAL8 are ECPGt_long on 64-bit, not ECPGt_long_long

  The one concern that's clear now is a lack of documentation update.

That will come in a separate patch.

What's the point of that? It can't be applied without documentation,
and it just makes life more complicated to have two separate patch
files floating around.

...Robert

#7Boszormenyi Zoltan
zb@cybertec.at
In reply to: Robert Haas (#6)
1 attachment(s)
Re: Review of "SQLDA support for ECPG"

Robert Haas �rta:

On Thu, Oct 8, 2009 at 6:22 AM, Boszormenyi Zoltan <zb@cybertec.at> wrote:

Noah Misch �rta:

I will report on the sqlda patch in more detail on
2009-10-10.

I am attaching a new one, please review this. Changes:
- set sqllen, sqlind, sqlilen and sqlitype per-field properties
- SQLINT8 and SQLSERIAL8 are ECPGt_long on 64-bit, not ECPGt_long_long

The one concern that's clear now is a lack of documentation update.

That will come in a separate patch.

What's the point of that? It can't be applied without documentation,
and it just makes life more complicated to have two separate patch
files floating around.

...Robert

It's easier to write the documentation for all changes at once.
I would have the same situation that happened with the code,
the patches with the documentation added would strictly depend
on each other again. Also, Michael Meskes applied the "string"
pseudo-type patch without the documentation, despite the patch
had it, maybe at an improper place. With a tongue-in-cheek
"no comment" ;-) I point to this paragraph in the ECPG part of
the documentation:

"This documentation is quite incomplete. But since this interface is
standardized,
additional information can be found in many resources about SQL."

The doc patch is attached. Details:
- documented "string" pseudo-type
- documented two more statements under section
"Additional embedded SQL statements" which is now called
"Additional/missing embedded SQL statements"
This is about the current state of ECPG, no code changed.
- document that INTO and USING are interchangeable if
the target is a Descriptor Areas
- document that the SQL keyword is not optional for DAs
- document SQLDA
- document DESCRIBE in section "Using SQL Descriptor Areas"

Best regards,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

Attachments:

ecpg-doc.patchtext/x-patch; name=ecpg-doc.patchDownload
*** pgsql.doc/doc/src/sgml/ecpg.sgml.old	2009-10-07 12:05:28.000000000 +0200
--- pgsql.doc/doc/src/sgml/ecpg.sgml	2009-10-08 12:55:15.785009096 +0200
***************
*** 2420,2428 ****
    </para>
  
    <sect2>
!    <title>Additional embedded SQL statements</title>
     <para>
      <variablelist>
       <varlistentry>
        <term><literal>CLOSE DATABASE</></term>
        <listitem>
--- 2420,2445 ----
    </para>
  
    <sect2>
!    <title>Additional types</title>
!    <para>
!     The Informix-special "string" pseudo-type for storing right-trimmed character string data is now
!     supported in Informix-mode without using <literal>typedef</literal>. In fact, in Informix-mode,
!     ECPG refuses to process source files that contain <literal>typedef sometype string;</literal>
! <programlisting>
!     EXEC SQL BEGIN DECLARE SECTION;
!     string userid; /* this variable will contain trimmed data */
!     EXEC SQL END DECLARE SECTION;
! 
!     EXEC SQL FETCH MYCUR INTO :userid;
! </programlisting>
!    </para>
!   </sect2>
! 
!   <sect2>
!    <title>Additional/missing embedded SQL statements</title>
     <para>
      <variablelist>
+ 
       <varlistentry>
        <term><literal>CLOSE DATABASE</></term>
        <listitem>
***************
*** 2436,2446 ****
--- 2453,2755 ----
         </para>
        </listitem>
       </varlistentry>
+ 
+      <varlistentry>
+       <term><literal>FREE cursor_name</></term>
+       <listitem>
+        <para>
+         Due to the differences how ECPG works (i.e. which steps are purely grammar transformations
+         and which steps rely on the underlying runtime library compared to Informix's ESQL/C)
+         there is no <literal>FREE cursor_name</> statement in ECPG. This is because in ECPG,
+         <literal>DECLARE CURSOR</literal> previously didn't translate to a function call into
+         the runtime library at all. Now it does, just to simply reset SQLCA to follow Informix
+         behaviour. But it's still true that there's no runtime bookkeeping of SQL cursors in
+         the ECPG runtime library, only in the PostgreSQL server.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+       <term><literal>FREE statement_name</></term>
+       <listitem>
+        <para>
+         <literal>FREE statement_name</> is a synonym for <literal>DEALLOCATE PREPARE statement_name</>.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+     </variablelist>
+    </para>
+   </sect2>
+ 
+   <sect2>
+   <title>Additional syntax forms</title>
+    <para>
+     <variablelist>
+ 
+      <varlistentry>
+       <term>Interchangeable <literal>USING</> and <literal>INTO</></term>
+       <listitem>
+        <para>
+         In <literal>DECRIBE</> and <literal>FETCH</> statements, the <literal>USING</>
+         and <literal>INTO</> keywords are interchangeable if the target is a Descriptor Area.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+       <term>Non-optional <literal>SQL</> keyword for Descriptor Areas</term>
+        <listitem>
+         <para>
+          In <literal>DECRIBE</> and <literal>FETCH</> statements using Descriptor Areas,
+          the <literal>SQL</> keyword is not optional. <literal>DESCRIPTOR</> means an
+          SQLDA Descriptor Area, <literal>SQL DESCRIPTOR</> means a named SQL Descriptor Area.
+         </para>
+        </listitem>
+      </varlistentry>
+ 
      </variablelist>
     </para>
    </sect2>
  
    <sect2>
+    <title>Additional SQL descriptor type: SQLDA C-structure</title>
+    <para>
+     Besides the named SQL descriptors, ECPG now supports Informix-special SQLDA descriptors
+     for accessing fields properties and data from low-level C code. Global properties are:
+ 
+     <variablelist>
+ 
+      <varlistentry>
+      <term><literal>sqld</></term>
+       <listitem>
+        <para>
+         The number of fields in the <literal>SQLDA</> descriptor.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlvar</></term>
+       <listitem>
+        <para>
+         Pointer to the per-field properties.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>desc_name</></term>
+       <listitem>
+        <para>
+         Unused, filled with zerobytes.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>desc_occ</></term>
+       <listitem>
+        <para>
+         Size of the allocated structure.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>desc_next</></term>
+       <listitem>
+        <para>
+         Pointer to the structure, unused, contains NULL.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>reserved</></term>
+       <listitem>
+        <para>
+         Unused pointer, contains NULL. Kept for Informix-compatibility.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+     </variablelist>
+ 
+     The per-field properties are below, they are stored in the <literal>sqlvar</literal> array:
+ 
+     <variablelist>
+ 
+      <varlistentry>
+      <term><literal>sqltype</></term>
+       <listitem>
+        <para>
+         Type of the field. Constants are in <literal>sqltypes.h</literal>
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqllen</></term>
+       <listitem>
+        <para>
+         Length of the field data.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqldata</></term>
+       <listitem>
+        <para>
+         Pointer to the field data. The pointer is of <literal>char *</literal> type,
+         the data pointed by it is in a binary format. Example:
+ <programlisting>
+     int intval;
+ 
+     switch (sqldata->sqlvar[i].sqltype)
+     {
+       case SQLINTEGER:
+         intval = *(int *)sqldata->sqlvar[i].sqldata;
+         break;
+       ...
+     }
+ </programlisting>
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlind</></term>
+       <listitem>
+        <para>
+         Pointer to the NULL indicator. If returned by DESCRIBE or FETCH then it's always a valid pointer.
+         If used as input for <literal>EXECUTE ... USING sqlda;</literal> then NULL-pointer value means
+         that the value for this field is non-NULL. Otherwise a valid pointer and <literal>sqlitype</literal>
+         has to be properly set. Example:
+ <programlisting>
+     if (*(int2 *)sqldata->sqlvar[i].sqlind != 0)
+       printf("value is NULL\n");
+ </programlisting>
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlname</></term>
+       <listitem>
+        <para>
+         Name of the field. 0-terminated string.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlformat</></term>
+       <listitem>
+        <para>
+         Reserved in Informix, value of PQfformat() for the field.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlitype</></term>
+       <listitem>
+        <para>
+         Type of the NULL indicator data. It's always SQLSMINT when returning data from the server.
+         When the <literal>SQLDA</literal> is used for a parametrized query, the data is treated
+         according to the set type.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlilen</></term>
+       <listitem>
+        <para>
+         Length of the NULL indicator data.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlxid</></term>
+       <listitem>
+        <para>
+         Extended type of the field, result of PQftype().
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqltypename</></term>
+      <term><literal>sqltypelen</></term>
+      <term><literal>sqlownerlen</></term>
+      <term><literal>sqlsourcetype</></term>
+      <term><literal>sqlownername</></term>
+      <term><literal>sqlsourceid</></term>
+      <term><literal>sqlflags</></term>
+      <term><literal>sqlreserved</></term>
+       <listitem>
+        <para>
+         Unused.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
+      <term><literal>sqlilongdata</></term>
+       <listitem>
+        <para>
+         It equals to <literal>sqldata</literal> if <literal>sqllen</literal> is larger than 32KB.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+     </variablelist>
+ 
+     Example:
+ <programlisting>
+     EXEC SQL INCLUDE sqlda.h;
+ 
+     pg_sqlda_t	*sqlda; /* This doesn't need to be under embedded DECLARE SECTION */
+ 
+     EXEC SQL BEGIN DECLARE SECTION;
+     char *prep_stmt = "select * from table1";
+     int i;
+     EXEC SQL END DECLARE SECTION;
+ 
+     ...
+ 
+     EXEC SQL PREPARE mystmt FROM :prep_stmt;
+ 
+     EXEC SQL DESCRIBE mystmt INTO sqlda;
+ 
+     printf("# of fields: %d\n", sqlda->sqld);
+     for (i = 0; i < sqlda->sqld; i++)
+ 	printf("field %d: \"%s\"\n", sqlda->sqlvar[i]->sqlname);
+ 
+     EXEC SQL DECLARE mycursor CURSOR FOR mystmt;
+     EXEC SQL OPEN mycursor;
+     EXEC SQL WHENEVER NOT FOUND GOTO out;
+ 
+     while (1)
+     {
+       EXEC SQL FETCH mycursor USING sqlda;
+     }
+ 
+     EXEC SQL CLOSE mycursor;
+ 
+     free(sqlda); /* The main structure is all to be free(),
+                   * sqlda and sqlda->sqlvar is in one allocated area */
+ </programlisting>
+     For more information, see the <literal>sqlda.h</> header and the
+     <literal>src/interfaces/ecpg/test/compat_informix/sqlda.pgc</literal> regression test.
+    </para>
+   </sect2>
+ 
+   <sect2>
     <title>Additional functions</title>
     <para>
      <variablelist>
***************
*** 3696,3705 ****
  
    <para>
     To use a descriptor area, specify it as the storage target in an
!    <literal>INTO</literal> clause, instead of listing host variables:
  <programlisting>
  EXEC SQL FETCH NEXT FROM mycursor INTO DESCRIPTOR mydesc;
  </programlisting>
    </para>
  
    <para>
--- 4005,4028 ----
  
    <para>
     To use a descriptor area, specify it as the storage target in an
!    <literal>INTO</literal> clause in a <literal>DESCRIBE [OUTPUT]</literal> statement:
! <programlisting>
! EXEC SQL BEGIN DECLARE SECTION;
! char *stmt = "SELECT * FROM table1";
! EXEC SQL END DECLARE SECTION;
! 
! EXEC SQL PREPARE stmt1 FROM :stmt;
! EXEC SQL DESCRIBE stmt1 INTO DESCRIPTOR mydesc;
! EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc; /* the SQL keyword is optional */
! </programlisting>
!    or a <literal>FETCH</literal> statement, instead of listing host variables:
  <programlisting>
  EXEC SQL FETCH NEXT FROM mycursor INTO DESCRIPTOR mydesc;
+ EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc /* the SQL keyword is optional */;
  </programlisting>
+   The difference between <literal>DESCRIBE</literal> and <literal>FETCH</literal>
+   statements above is that <literal>DESCRIBE</literal> on an empty resultset
+   gives the field metadata, e.g. its name, while <literal>FETCH</literal> doesn't.
    </para>
  
    <para>
#8Boszormenyi Zoltan
zb@cybertec.at
In reply to: Boszormenyi Zoltan (#5)
1 attachment(s)
Re: Review of "SQLDA support for ECPG"

Boszormenyi Zoltan �rta:

Noah Misch �rta:

I will report on the sqlda patch in more detail on
2009-10-10.

I am attaching a new one, please review this. Changes:
- set sqllen, sqlind, sqlilen and sqlitype per-field properties
- SQLINT8 and SQLSERIAL8 are ECPGt_long on 64-bit, not ECPGt_long_long

New one attached, the second one is now really fixed, sorry
for the previous one.

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

Attachments:

2-pg85-sqlda-13-ctxdiff.patchtext/x-patch; name=2-pg85-sqlda-13-ctxdiff.patchDownload
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/execute.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/execute.c	2009-09-03 14:37:34.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c	2009-10-05 15:18:01.000000000 +0200
***************
*** 25,30 ****
--- 25,31 ----
  #include "ecpgerrno.h"
  #include "extern.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "sql3types.h"
  #include "pgtypes_numeric.h"
  #include "pgtypes_date.h"
*************** ecpg_store_input(const int lineno, const
*** 1033,1038 ****
--- 1034,1040 ----
  				break;
  
  			case ECPGt_descriptor:
+ 			case ECPGt_sqlda:
  				break;
  
  			default:
*************** ecpg_execute(struct statement * stmt)
*** 1172,1177 ****
--- 1174,1235 ----
  			if (desc->count == desc_counter)
  				desc_counter = 0;
  		}
+ 		else if (var->type == ECPGt_sqlda)
+ 		{
+ 			pg_sqlda_t	  **_sqlda = (pg_sqlda_t **)var->pointer;
+ 			pg_sqlda_t	   *sqlda = *_sqlda;
+ 			struct variable	desc_inlist;
+ 			int		i;
+ 
+ 			if (sqlda == NULL)
+ 				return false;
+ 
+ 			desc_counter++;
+ 			for (i = 0; i < sqlda->sqld; i++)
+ 			{
+ 				if (i + 1 == desc_counter)
+ 				{
+ 					desc_inlist.type = ecpg_sqlda_type(sqlda->sqlvar[i].sqltype);
+ 					desc_inlist.value = sqlda->sqlvar[i].sqldata;
+ 					desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
+ 					switch (desc_inlist.type)
+ 					{
+ 						case ECPGt_char:
+ 						case ECPGt_varchar:
+ 							desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
+ 							break;
+ 						default:
+ 							desc_inlist.varcharsize = 0;
+ 							break;
+ 					}
+ 					desc_inlist.arrsize = 1;
+ 					desc_inlist.offset = 0;
+ 					if (sqlda->sqlvar[i].sqlind)
+ 					{
+ 						desc_inlist.ind_type = ECPGt_short;
+ 						/* ECPG expects indicator value < 0 */
+ 						if (*(sqlda->sqlvar[i].sqlind))
+ 							*(sqlda->sqlvar[i].sqlind) = -1;
+ 						desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
+ 						desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
+ 						desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
+ 						desc_inlist.ind_offset = 0;
+ 					}
+ 					else
+ 					{
+ 						desc_inlist.ind_type = ECPGt_NO_INDICATOR;
+ 						desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
+ 						desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
+ 					}
+ 					if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
+ 						return false;
+ 
+ 					break;
+ 				}
+ 			}
+ 			if (sqlda->sqld == desc_counter)
+ 				desc_counter = 0;
+ 		}
  		else
  		{
  			if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false))
*************** ecpg_execute(struct statement * stmt)
*** 1353,1358 ****
--- 1411,1452 ----
  				}
  				var = var->next;
  			}
+ 			else if (var != NULL && var->type == ECPGt_sqlda)
+ 			{
+ 				pg_sqlda_t	  **_sqlda = (pg_sqlda_t **)var->pointer;
+ 				pg_sqlda_t	   *sqlda = *_sqlda;
+ 				pg_sqlda_t	   *sqlda_new;
+ 
+ 				/* Build a new sqlda structure. Note that only fetching 1 record is supported */
+ 				sqlda_new = ecpg_build_sqlda_for_PGresult(stmt->lineno, results, 0);
+ 
+ 				if (!sqlda_new)
+ 				{
+ 					ecpg_log("ecpg_execute on line %d: out of memory allocating a new sqlda\n", stmt->lineno);
+ 					status = false;
+ 				}
+ 				else
+ 				{
+ 					ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno);
+ 
+ 					/* If we are passed in a previously existing sqlda then free it. */
+ 					if (sqlda)
+ 					{
+ 						if (sqlda->sqlvar != (pg_sqlvar_t *)(sqlda + 1))
+ 							free(sqlda->sqlvar);
+ 						free(sqlda);
+ 						sqlda = NULL;
+ 					}
+ 
+ 					*_sqlda = sqlda_new;
+ 
+ 					ecpg_set_sqlda_from_PGresult(stmt->lineno, _sqlda, results, 0);
+ 					ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
+ 							stmt->lineno, PQnfields(results));
+ 				}
+ 
+ 				var = var->next;
+ 			}
  			else
  				for (act_field = 0; act_field < nfields && status; act_field++)
  				{
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/extern.h pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/extern.h	2009-05-25 12:08:48.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h	2009-10-05 15:18:01.000000000 +0200
***************
*** 6,11 ****
--- 6,12 ----
  #include "postgres_fe.h"
  #include "libpq-fe.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "ecpg_config.h"
  #ifndef CHAR_BIT
  #include <limits.h>
*************** bool		ecpg_init(const struct connection 
*** 129,134 ****
--- 130,137 ----
  char	   *ecpg_strdup(const char *, int);
  const char *ecpg_type_name(enum ECPGttype);
  int			ecpg_dynamic_type(Oid);
+ int			ecpg_sqlda_type(int);
+ int			ecpg_to_sqlda_type(Oid);
  void		ecpg_free_auto_mem(void);
  void		ecpg_clear_auto_mem(void);
  
*************** void		ecpg_log(const char *format,...);
*** 149,154 ****
--- 152,160 ----
  bool		ecpg_auto_prepare(int, const char *, const int, char **, const char *);
  void		ecpg_init_sqlca(struct sqlca_t * sqlca);
  
+ pg_sqlda_t *ecpg_build_sqlda_for_PGresult(int, PGresult *, int);
+ void		ecpg_set_sqlda_from_PGresult(int, pg_sqlda_t **, const PGresult *, int);
+ 
  /* SQLSTATE values generated or processed by ecpglib (intentionally
   * not exported -- users should refer to the codes directly) */
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/Makefile pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/Makefile	2009-07-13 11:16:41.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile	2009-10-05 15:18:01.000000000 +0200
*************** override CFLAGS += $(PTHREAD_CFLAGS)
*** 24,30 ****
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))
  
! OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
  	connect.o misc.o path.o pgstrcasecmp.o \
  	$(filter snprintf.o strlcpy.o, $(LIBOBJS))
  
--- 24,30 ----
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))
  
! OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
  	connect.o misc.o path.o pgstrcasecmp.o \
  	$(filter snprintf.o strlcpy.o, $(LIBOBJS))
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/sqlda.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/sqlda.c	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c	2009-10-08 13:32:44.000000000 +0200
***************
*** 0 ****
--- 1,293 ----
+ /*
+  * Crude SQLDA support routines
+  * Only supports fetching 1 record at a time
+  *
+  * The allocated memory area pointed by an sqlda pointer
+  * contains both the metadata and the data, so freeing up
+  * is a simple free(sqlda) as expected by the ESQL/C examples.
+  */
+ 
+ #define POSTGRES_ECPG_INTERNAL
+ #include "postgres_fe.h"
+ #include "pg_type.h"
+ 
+ #include <inttypes.h>
+ #include <dlfcn.h>
+ 
+ #include "ecpg-pthread-win32.h"
+ #include "decimal.h"
+ #include "ecpgtype.h"
+ #include "ecpglib.h"
+ #include "ecpgerrno.h"
+ #include "extern.h"
+ #include "sqlca.h"
+ #include "sqlda.h"
+ #include "sqltypes.h"
+ 
+ /*
+  * Compute the next variable's offset with
+  * the current variable's size and alignment.
+  */
+ static long
+ ecpg_sqlda_size_round_align(long offset, int alignment, int size)
+ {
+ 	if (offset % alignment)
+ 		offset += alignment - (offset % alignment);
+ 	offset += size;
+ 	return offset;
+ }
+ 
+ /*
+  * Compute the current variable's offset with alignment.
+  */
+ static long
+ ecpg_sqlda_size_align(long offset, int alignment)
+ {
+ 	if (offset % alignment)
+ 		offset += alignment - (offset % alignment);
+ 	return offset;
+ }
+ 
+ static long
+ ecpg_sqlda_empty_size(const PGresult *res)
+ {
+ 	long	size;
+ 	int	i;
+ 	int	sqld = PQnfields(res);
+ 
+ 	/* Initial size to store main structure and field structures */
+ 	size = sizeof(pg_sqlda_t) + sqld * sizeof(pg_sqlvar_t);
+ 
+ 	/* Add space for field names */
+ 	for (i = 0; i < sqld; i++)
+ 		size += strlen(PQfname(res, i)) + 1;
+ 
+ 	/* Add padding to the first field value */
+ 	size = ecpg_sqlda_size_align(size, sizeof(int));
+ 
+ 	return size;
+ }
+ 
+ static long
+ ecpg_sqlda_total_size(const PGresult *res, int row)
+ {
+ 	int	i;
+ 	int	sqld = PQnfields(res);
+ 	long	size;
+ 
+ 	size = ecpg_sqlda_empty_size(res);
+ 
+ 	if (row < 0)
+ 		return size;
+ 
+ 	/* Add space for the field values */
+ 	for (i = 0; i < sqld; i++)
+ 	{
+ 		switch (ecpg_to_sqlda_type(PQftype(res, i)))
+ 		{
+ 			case SQLSMINT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(short), sizeof(short));
+ 				break;
+ 			case SQLINT:
+ 			case SQLSERIAL:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(int));
+ 				break;
+ 			case SQLFLOAT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(double), sizeof(double));
+ 				break;
+ 			case SQLSMFLOAT:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(float), sizeof(float));
+ 				break;
+ 			case SQLDECIMAL:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(decimal));
+ 				break;
+ 			case SQLINT8:
+ 			case SQLSERIAL8:
+ 				size = ecpg_sqlda_size_round_align(size, sizeof(int64_t), sizeof(int64_t));
+ 				break;
+ 
+ 			/*
+ 			 * These types will be passed as character strings
+ 			 * copied as is from the PGresult until we know
+ 			 * what to do with them.
+ 			 */
+ 			case SQLCHAR:
+ 			case SQLTEXT:
+ 			case SQLVCHAR:
+ 			case SQLNCHAR:
+ 			case SQLNVCHAR:
+ 			case SQLMONEY:
+ 			case SQLDATE:
+ 			case SQLDTIME:
+ 			case SQLINTERVAL:
+ 			default:
+ 				size += strlen(PQgetvalue(res, row, i)) + 1;
+ 				break;
+ 		}
+ 	}
+ 	return size;
+ }
+ 
+ /*
+  * Build pg_sqlda_t (metadata only) from PGresult
+  * leaving enough space for the field values in
+  * the given row number
+  */
+ pg_sqlda_t *
+ ecpg_build_sqlda_for_PGresult(int line, PGresult *res, int row)
+ {
+ 	pg_sqlda_t *sqlda;
+ 	pg_sqlvar_t*sqlvar;
+ 	char	   *fname;
+ 	long		size;
+ 	int		sqld;
+ 	int		i;
+ 
+ 	size = ecpg_sqlda_total_size(res, row);
+ 	sqlda = (pg_sqlda_t *)ecpg_alloc(size, line);
+ 	if (!sqlda)
+ 		return NULL;
+ 
+ 	memset(sqlda, 0, size);
+ 	sqlvar = (pg_sqlvar_t *)(sqlda + 1);
+ 	sqld = PQnfields(res);
+ 	fname = (char *)(sqlvar + sqld);
+ 
+ 	sqlda->sqld = sqld;
+ 	sqlda->desc_occ = size; /* cheat here, keep the full allocated size */
+ 	sqlda->sqlvar = sqlvar;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		sqlda->sqlvar[i].sqltype = ecpg_to_sqlda_type(PQftype(res, i));
+ 		strcpy(fname, PQfname(res, i));
+ 		sqlda->sqlvar[i].sqlname = fname;
+ 		fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
+ 		sqlda->sqlvar[i].sqlformat = (char *)(long)PQfformat(res, i);
+ 		sqlda->sqlvar[i].sqlxid = PQftype(res, i);
+ 		sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
+ 	}
+ 
+ 	return sqlda;
+ }
+ 
+ /*
+  * Sets values from PGresult.
+  */
+ void
+ ecpg_set_sqlda_from_PGresult(int lineno, pg_sqlda_t **_sqlda, const PGresult *res, int row)
+ {
+ 	pg_sqlda_t *sqlda = (*_sqlda);
+ 	int		i;
+ 	long		size;
+ 	static	int2	value_is_null = -1;
+ 	static	int2	value_is_not_null = 0;
+ 
+ 	/* Offset for the first field value */
+ 	size = ecpg_sqlda_empty_size(res);
+ 
+ 	/*
+ 	 * Set sqlvar[i]->sqldata pointers and convert values to correct format
+ 	 */
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		int type = -1, isnull;
+ 		int use_getdata = true;
+ 		int datalen;
+ 
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 			case SQLSMINT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(short));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(short);
+ 				size += sizeof(short);
+ 				type = ECPGt_short;
+ 				break;
+ 			case SQLINT:
+ 			case SQLSERIAL:
+ 				size = ecpg_sqlda_size_align(size, sizeof(int));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(int);
+ 				size += sizeof(int);
+ 				type = ECPGt_int;
+ 				break;
+ 			case SQLFLOAT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(double));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(double);
+ 				size += sizeof(double);
+ 				type = ECPGt_double;
+ 				break;
+ 			case SQLSMFLOAT:
+ 				size = ecpg_sqlda_size_align(size, sizeof(float));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(float);
+ 				size += sizeof(float);
+ 				type = ECPGt_float;
+ 				break;
+ 			case SQLDECIMAL:
+ 			{
+ 				size = ecpg_sqlda_size_align(size, sizeof(int));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(decimal);
+ 				size += sizeof(decimal);
+ 				type = ECPGt_decimal;
+ 				break;
+ 			}
+ 			case SQLINT8:
+ 			case SQLSERIAL8:
+ 				size = ecpg_sqlda_size_align(size, sizeof(int64_t));
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				sqlda->sqlvar[i].sqllen = sizeof(int64_t);
+ 				size += sizeof(int64_t);
+ #ifdef HAVE_LONG_LONG_INT_64
+ 				type = ECPGt_long_long;
+ #else
+ 				type = ECPGt_long;
+ #endif
+ 				break;
+ 
+ 			/*
+ 			 * These types will be passed as character strings until
+ 			 * it's known what to do with them. We use sqlvar->sqldata
+ 			 * in all cases regardless of length, don't care about
+ 			 * sqlvar->sqlilongdata.
+ 			 */
+ 			case SQLCHAR:
+ 			case SQLTEXT:
+ 			case SQLVCHAR:
+ 			case SQLNCHAR:
+ 			case SQLNVCHAR:
+ 			case SQLMONEY:
+ 			case SQLDATE:
+ 			case SQLDTIME:
+ 			case SQLINTERVAL:
+ 			default:
+ 				sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+ 				datalen = strlen(PQgetvalue(res, row, i)) + 1;
+ 				sqlda->sqlvar[i].sqllen = datalen;
+ 				size += datalen;
+ 				if (datalen > 32768)
+ 					sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
+ 				use_getdata = false;
+ 				break;
+ 		}
+ 
+ 		isnull = PQgetisnull(res, 0, i);
+ 		sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
+ 		sqlda->sqlvar[i].sqlitype = SQLSMINT;
+ 		sqlda->sqlvar[i].sqlilen = sizeof(short);
+ 		if (!isnull)
+ 		{
+ 			if (use_getdata)
+ 				ecpg_get_data(res, row, i, lineno,
+ 						type, ECPGt_NO_INDICATOR,
+ 						sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
+ 						ECPG_ARRAY_NONE, ECPG_COMPAT_INFORMIX, false);
+ 			else
+ 				strcpy(sqlda->sqlvar[i].sqldata, PQgetvalue(res, row, i));
+ 		}
+ 	}
+ }
+ 
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/typename.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c
*** pgsql.fixparsepl/src/interfaces/ecpg/ecpglib/typename.c	2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c	2009-10-08 12:14:07.000000000 +0200
***************
*** 7,12 ****
--- 7,13 ----
  #include "ecpgtype.h"
  #include "ecpglib.h"
  #include "extern.h"
+ #include "sqltypes.h"
  #include "sql3types.h"
  #include "pg_type.h"
  
*************** ecpg_dynamic_type(Oid type)
*** 100,102 ****
--- 101,194 ----
  			return -(int) type;
  	}
  }
+ 
+ int
+ ecpg_sqlda_type(int type)
+ {
+ 	switch (type)
+ 	{
+ 		case SQLCHAR:
+ 		case SQLNCHAR:
+ 			return ECPGt_char;
+ 		case SQLSMINT:
+ 			return ECPGt_short;
+ 		case SQLINT:
+ 			return ECPGt_int;
+ 		case SQLFLOAT:
+ 			return ECPGt_double;
+ 		case SQLSMFLOAT:
+ 			return ECPGt_float;
+ 		case SQLDECIMAL:
+ 			return ECPGt_decimal;
+ 		case SQLSERIAL:
+ 			return ECPGt_int;
+ 		case SQLDATE:
+ 			return ECPGt_date;
+ #if 0
+ 		case SQLMONEY:
+ 			return ???;
+ 		case SQLNULL:
+ 			return ???;
+ #endif
+ 		case SQLDTIME:
+ 			return ECPGt_timestamp;
+ #if 0
+ 		case SQLBYTES:
+ 			return ???;
+ #endif
+ 		case SQLTEXT:
+ 			return ECPGt_char;
+ 		case SQLVCHAR:
+ 		case SQLNVCHAR:
+ 			return ECPGt_varchar;
+ 		case SQLINTERVAL:
+ 			return ECPGt_interval;
+ 		case SQLINT8:
+ 		case SQLSERIAL8:
+ #ifdef HAVE_LONG_LONG_INT_64
+ 			return ECPGt_long_long;
+ #else
+ 			return ECPGt_long;
+ #endif
+ 		default:
+ 			return (-type);
+ 	}
+ }
+ 
+ int
+ ecpg_to_sqlda_type(Oid type)
+ {
+ 	switch (type)
+ 	{
+ 		case CHAROID:
+ 		case BPCHAROID:
+ 			return SQLCHAR;
+ 		case INT2OID:
+ 			return SQLSMINT;
+ 		case INT4OID:
+ 			return SQLINT;
+ 		case FLOAT8OID:
+ 			return SQLFLOAT;
+ 		case FLOAT4OID:
+ 			return SQLSMFLOAT;
+ 		case NUMERICOID:
+ 			return SQLDECIMAL;
+ 		case DATEOID:
+ 			return SQLDATE;
+ 		case CASHOID:
+ 			return SQLMONEY;
+ 		case TIMESTAMPOID:
+ 		case TIMESTAMPTZOID:
+ 			return SQLDTIME;
+ 		case TEXTOID:
+ 			return SQLTEXT;
+ 		case VARCHAROID:
+ 			return SQLVCHAR;
+ 		case INTERVALOID:
+ 			return SQLINTERVAL;
+ 		case INT8OID:
+ 			return SQLINT8;
+ 		default:
+ 			return (-type);
+ 	}
+ }
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/ecpgtype.h pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/ecpgtype.h	2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h	2009-10-05 15:18:01.000000000 +0200
*************** enum ECPGttype
*** 62,68 ****
  	ECPGt_EOIT,					/* End of insert types. */
  	ECPGt_EORT,					/* End of result types. */
  	ECPGt_NO_INDICATOR,			/* no indicator */
! 	ECPGt_string                            /* trimmed (char *) type */
  };
  
   /* descriptor items */
--- 62,69 ----
  	ECPGt_EOIT,					/* End of insert types. */
  	ECPGt_EORT,					/* End of result types. */
  	ECPGt_NO_INDICATOR,			/* no indicator */
! 	ECPGt_string,				/* trimmed (char *) type */
! 	ECPGt_sqlda				/* C struct descriptor */
  };
  
   /* descriptor items */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/sqlda.h pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/sqlda.h	2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h	2009-10-05 15:18:01.000000000 +0200
***************
*** 1,3 ****
--- 1,74 ----
  /*
   * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
   */
+ 
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+ 
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int		int4;
+ typedef	short		int2;
+ #endif
+ typedef	char		int1;
+ 
+ typedef	int		mint;
+ typedef	long		mlong;
+ 
+ typedef	short		MSHORT;
+ typedef	char		MCHAR; 
+ 
+ typedef	unsigned int	uint4;
+ typedef	unsigned short	uint2;
+ typedef	unsigned char	uint1;
+ 
+ typedef	unsigned int	muint;
+ typedef	unsigned long	mulong;
+ 
+ typedef	unsigned short	MUSHORT;
+ typedef	unsigned char	MUCHAR; 
+ 
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+ 
+ typedef struct sqlvar_struct
+ {
+ 	int2	sqltype;		/* variable type                */
+ 	int4	sqllen;			/* length in bytes              */
+ 	char	   *sqldata;		/* pointer to data              */
+ 	int2	   *sqlind;		/* pointer to indicator         */
+ 	char	   *sqlname;		/* variable name                */
+ 	char	   *sqlformat;		/* reserved for future use      */
+ 	int2	sqlitype;		/* ind variable type            */
+ 	int2	sqlilen;		/* ind length in bytes          */
+ 	char	   *sqlidata;		/* ind data pointer             */
+ 	int4	sqlxid;			/* extended id type             */
+ 	char	   *sqltypename;	/* extended type name           */
+ 	int2	sqltypelen;		/* length of extended type name */
+ 	int2	sqlownerlen;		/* length of owner name         */
+ 	int2	sqlsourcetype;		/* source type for distinct of built-ins */
+ 	char	   *sqlownername;	/* owner name                   */
+ 	int4	sqlsourceid;		/* extended id of source type   */
+ 
+ 	/*
+ 	 * sqlilongdata is new.  It supports data that exceeds the 32k
+ 	 * limit.  sqlilen and sqlidata are for backward compatibility
+ 	 * and they have maximum value of <32K.
+ 	 */
+ 	char	   *sqlilongdata;	/* for data field beyond 32K    */
+ 	int4	sqlflags;		/* for internal use only        */
+ 	void	   *sqlreserved;	/* reserved for future use      */
+ } pg_sqlvar_t;
+ 
+ typedef struct sqlda
+ {
+ 	int2		sqld;
+ 	pg_sqlvar_t	   *sqlvar;
+ 	char		desc_name[19];	/* descriptor name              */
+ 	int2		desc_occ;	/* size of sqlda structure      */
+ 	struct sqlda	   *desc_next;	/* pointer to next sqlda struct */
+ 	void		   *reserved;	/* reserved for future use */
+ } pg_sqlda_t;
+ 
+ #endif /* POSTGRES_SQLDA_H */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/include/sqltypes.h pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h
*** pgsql.fixparsepl/src/interfaces/ecpg/include/sqltypes.h	2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h	2009-10-05 15:18:01.000000000 +0200
***************
*** 30,33 ****
--- 30,55 ----
  #define CLVCHARPTRTYPE	124
  #define CTYPEMAX	25
  
+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define	SQLCHAR		0
+ #define	SQLSMINT	1
+ #define	SQLINT		2
+ #define	SQLFLOAT	3
+ #define	SQLSMFLOAT	4
+ #define	SQLDECIMAL	5
+ #define	SQLSERIAL	6
+ #define	SQLDATE		7
+ #define	SQLMONEY	8
+ #define	SQLDTIME	10
+ #define	SQLBYTES	11
+ #define	SQLTEXT		12
+ #define	SQLVCHAR	13
+ #define	SQLINTERVAL	14
+ #define	SQLNCHAR	15
+ #define	SQLNVCHAR	16
+ #define	SQLINT8		17
+ #define	SQLSERIAL8	18
+ 
  #endif   /* ndef ECPG_SQLTYPES_H */
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/descriptor.c pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/descriptor.c	2009-01-30 17:28:46.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c	2009-10-05 15:18:01.000000000 +0200
*************** descriptor_variable(const char *name, in
*** 326,328 ****
--- 326,347 ----
  	strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
  	return (struct variable *) & varspace[input];
  }
+ 
+ struct variable *
+ sqlda_variable(const char *name)
+ {
+ 	struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
+ 
+ 	p->name = mm_strdup(name);
+ 	p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
+ 	p->type->type = ECPGt_sqlda;
+ 	p->type->size = NULL;
+ 	p->type->struct_sizeof = NULL;
+ 	p->type->u.element = NULL;
+ 	p->type->lineno = 0;
+ 	p->brace_level = 0;
+ 	p->next = NULL;
+ 
+ 	return p;
+ }
+ 
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.addons pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.addons	2009-10-03 01:54:43.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons	2009-10-05 15:18:01.000000000 +0200
*************** ECPG: VariableShowStmtSHOWALL block
*** 402,430 ****
  		$$ = EMPTY;
  	}
  ECPG: FetchStmtMOVEfetch_args rule
! 	| FETCH fetch_args ecpg_into
  	{
  		$$ = cat2_str(make_str("fetch"), $2);
  	}
! 	| FETCH FORWARD cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch forward"), cursor_marker);
  	}
! 	| FETCH FORWARD from_in cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
  		$$ = cat_str(2, make_str("fetch forward from"), cursor_marker);
  	}
! 	| FETCH BACKWARD cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch backward"), cursor_marker);
  	}
! 	| FETCH BACKWARD from_in cursor_name opt_ecpg_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
--- 402,430 ----
  		$$ = EMPTY;
  	}
  ECPG: FetchStmtMOVEfetch_args rule
! 	| FETCH fetch_args ecpg_fetch_into
  	{
  		$$ = cat2_str(make_str("fetch"), $2);
  	}
! 	| FETCH FORWARD cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch forward"), cursor_marker);
  	}
! 	| FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
  		$$ = cat_str(2, make_str("fetch forward from"), cursor_marker);
  	}
! 	| FETCH BACKWARD cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
  		add_additional_variables($3, false);
  		$$ = cat_str(2, make_str("fetch backward"), cursor_marker);
  	}
! 	| FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
  	{
  		char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
  		add_additional_variables($4, false);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.trailer pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.trailer	2009-10-03 02:05:58.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer	2009-10-05 15:18:01.000000000 +0200
*************** ecpg_using:	USING using_list 	{ $$ = EMP
*** 1017,1035 ****
  
  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
  			$$ = EMPTY;
  		}
  		;
  
  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
  			$$ = EMPTY;
  		}
  		;
  
! opt_sql: /*EMPTY*/ | SQL_SQL;
  
  using_list: UsingValue | UsingValue ',' using_list;
  
--- 1017,1065 ----
  
  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			if (strlen($2) || !(INFORMIX_MODE))
! 				add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
! 			else
! 			{
! 				if ($4[0] == '\"')
! 				{
! 					char *pos;
! 
! 					$4[0] = ' ';
! 					for (pos = $4; *pos; pos++)
! 						if (*pos == '\"')
! 							*pos = ' ';
! 				}
! 				add_variable_to_head(&argsinsert, sqlda_variable($4), &no_indicator);
! 			}
  			$$ = EMPTY;
  		}
  		;
  
  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
  		{
! 			if (strlen($2) || !(INFORMIX_MODE))
! 				add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
! 			else
! 			{
! 				if ($4[0] == '\"')
! 				{
! 					char *pos;
! 
! 					$4[0] = ' ';
! 					for (pos = $4; *pos; pos++)
! 						if (*pos == '\"')
! 							*pos = ' ';
! 				}
! 				add_variable_to_head(&argsresult, sqlda_variable($4), &no_indicator);
! 			}
  			$$ = EMPTY;
  		}
  		;
  
! opt_sql: /*EMPTY*/		{ $$ = EMPTY; }
! 		| SQL_SQL	{ $$ = make_str("sql"); }
! 		;
  
  using_list: UsingValue | UsingValue ',' using_list;
  
*************** ecpg_into: INTO into_list	{ $$ = EMPTY; 
*** 2052,2058 ****
          | into_descriptor	{ $$ = $1; }
  	;
  
! opt_ecpg_into:	/* EMPTY */	{ $$ = EMPTY; }
  	| ecpg_into		{ $$ = $1; }
  	;
  
--- 2082,2103 ----
          | into_descriptor	{ $$ = $1; }
  	;
  
! ecpg_fetch_into: ecpg_into	{ $$ = $1; }
! 	| using_descriptor
! 	{
! 		struct variable *var;
! 
! 		if (!INFORMIX_MODE)
! 			mmerror(PARSE_ERROR, ET_ERROR, "Not in Informix compatibility mode");
! 
! 		var = argsinsert->variable;
! 		remove_variable_from_list(&argsinsert, var);
! 		add_variable_to_head(&argsresult, var, &no_indicator);
! 		$$ = $1;
! 	}
! 	;
! 
! opt_ecpg_fetch_into:	/* EMPTY */	{ $$ = EMPTY; }
  	| ecpg_into		{ $$ = $1; }
  	;
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.type pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/ecpg.type	2009-10-03 02:03:31.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type	2009-10-05 15:18:01.000000000 +0200
***************
*** 62,67 ****
--- 62,68 ----
  %type <str> ecpg_ident
  %type <str> ecpg_interval
  %type <str> ecpg_into
+ %type <str> ecpg_fetch_into
  %type <str> ecpg_param
  %type <str> ecpg_sconst
  %type <str> ecpg_using
***************
*** 77,83 ****
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
--- 78,84 ----
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_fetch_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
***************
*** 87,92 ****
--- 88,94 ----
  %type <str> opt_reference
  %type <str> opt_scale
  %type <str> opt_server
+ %type <str> opt_sql   
  %type <str> opt_user
  %type <str> opt_opt_value
  %type <str> ora_user
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/extern.h pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/extern.h	2009-10-03 01:07:54.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h	2009-10-05 15:18:01.000000000 +0200
*************** extern void add_descriptor(char *, char 
*** 88,93 ****
--- 88,94 ----
  extern void drop_descriptor(char *, char *);
  extern struct descriptor *lookup_descriptor(char *, char *);
  extern struct variable *descriptor_variable(const char *name, int input);
+ extern struct variable *sqlda_variable(const char *name);
  extern void add_variable_to_head(struct arguments **, struct variable *, struct variable *);
  extern void add_variable_to_tail(struct arguments **, struct variable *, struct variable *);
  extern void remove_variable_from_list(struct arguments ** list, struct variable * var);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/preproc/type.c pgsql.sqlda/src/interfaces/ecpg/preproc/type.c
*** pgsql.fixparsepl/src/interfaces/ecpg/preproc/type.c	2009-09-03 12:25:47.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/type.c	2009-10-05 15:18:01.000000000 +0200
*************** get_type(enum ECPGttype type)
*** 194,199 ****
--- 194,202 ----
  		case ECPGt_descriptor:
  			return ("ECPGt_descriptor");
  			break;
+ 		case ECPGt_sqlda:
+ 			return ("ECPGt_sqlda");
+ 			break;
  		case ECPGt_date:
  			return ("ECPGt_date");
  			break;
*************** ECPGdump_a_simple(FILE *o, const char *n
*** 328,333 ****
--- 331,338 ----
  	else if (type == ECPGt_descriptor)
  		/* remember that name here already contains quotes (if needed) */
  		fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name);
+ 	else if (type == ECPGt_sqlda)
+ 		fprintf(o, "\n\tECPGt_sqlda, &%s, 0L, 0L, 0L, ", name);
  	else
  	{
  		char	   *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/Makefile pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile
*** pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/Makefile	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile	2009-10-05 15:18:01.000000000 +0200
*************** TESTS = test_informix test_informix.c \
*** 17,22 ****
--- 17,23 ----
          rfmtdate rfmtdate.c \
          rfmtlong rfmtlong.c \
          rnull rnull.c \
+         sqlda sqlda.c \
          charfuncs charfuncs.c
  
  all: $(TESTS)
*************** test_informix2.c: test_informix2.pgc ../
*** 30,35 ****
--- 31,39 ----
  cursor.c: cursor.pgc ../regression.h
  	$(ECPG) -o $@ -I$(srcdir) $<
  
+ sqlda.c: sqlda.pgc ../regression.h
+ 	$(ECPG) -o $@ -I$(srcdir) $<
+ 
  dec_test.c: dec_test.pgc ../regression.h
  	$(ECPG) -o $@ -I$(srcdir) $<
  
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/sqlda.pgc pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
*** pgsql.fixparsepl/src/interfaces/ecpg/test/compat_informix/sqlda.pgc	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,252 ----
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.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 */
+ pg_sqlda_t	*inp_sqlda, *outp_sqlda;
+ 
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+ 	int	i;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+ 			printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+ 		else
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 		case SQLCHAR:
+ 		case SQLVCHAR:
+ 		case SQLTEXT:
+ 			printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL:
+ 		case SQLINT:
+ 			printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL8:
+ 		case SQLINT8:
+ 			printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLFLOAT:
+ 			printf("name sqlda descriptor: '%s' value %lf\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),
+ 		(3, '"c"', -3, 'nan'::float8, 'c'),
+ 		(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 = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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 = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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 -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule
*** pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule	2009-10-05 15:18:01.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule_tcp pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp
*** pgsql.fixparsepl/src/interfaces/ecpg/test/ecpg_schedule_tcp	2009-10-03 02:11:20.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp	2009-10-05 15:18:01.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,585 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* Needed for informix compatibility */
+ #include <ecpg_informix.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+ 
+ #line 1 "sqlda.pgc"
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.h>
+ 
+ 
+ #line 1 "regression.h"
+ 
+ 
+ 
+ 
+ 
+ 
+ #line 5 "sqlda.pgc"
+ 
+ 
+ 
+ #line 1 "sqlda.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
+  */
+ 
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+ 
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int		int4;
+ typedef	short		int2;
+ #endif
+ typedef	char		int1;
+ 
+ typedef	int		mint;
+ typedef	long		mlong;
+ 
+ typedef	short		MSHORT;
+ typedef	char		MCHAR; 
+ 
+ typedef	unsigned int	uint4;
+ typedef	unsigned short	uint2;
+ typedef	unsigned char	uint1;
+ 
+ typedef	unsigned int	muint;
+ typedef	unsigned long	mulong;
+ 
+ typedef	unsigned short	MUSHORT;
+ typedef	unsigned char	MUCHAR; 
+ 
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+ 
+ typedef struct sqlvar_struct
+ {
+ 	int2	sqltype;		/* variable type                */
+ 	int4	sqllen;			/* length in bytes              */
+ 	char	   *sqldata;		/* pointer to data              */
+ 	int2	   *sqlind;		/* pointer to indicator         */
+ 	char	   *sqlname;		/* variable name                */
+ 	char	   *sqlformat;		/* reserved for future use      */
+ 	int2	sqlitype;		/* ind variable type            */
+ 	int2	sqlilen;		/* ind length in bytes          */
+ 	char	   *sqlidata;		/* ind data pointer             */
+ 	int4	sqlxid;			/* extended id type             */
+ 	char	   *sqltypename;	/* extended type name           */
+ 	int2	sqltypelen;		/* length of extended type name */
+ 	int2	sqlownerlen;		/* length of owner name         */
+ 	int2	sqlsourcetype;		/* source type for distinct of built-ins */
+ 	char	   *sqlownername;	/* owner name                   */
+ 	int4	sqlsourceid;		/* extended id of source type   */
+ 
+ 	/*
+ 	 * sqlilongdata is new.  It supports data that exceeds the 32k
+ 	 * limit.  sqlilen and sqlidata are for backward compatibility
+ 	 * and they have maximum value of <32K.
+ 	 */
+ 	char	   *sqlilongdata;	/* for data field beyond 32K    */
+ 	int4	sqlflags;		/* for internal use only        */
+ 	void	   *sqlreserved;	/* reserved for future use      */
+ } pg_sqlvar_t;
+ 
+ typedef struct sqlda
+ {
+ 	int2		sqld;
+ 	pg_sqlvar_t	   *sqlvar;
+ 	char		desc_name[19];	/* descriptor name              */
+ 	int2		desc_occ;	/* size of sqlda structure      */
+ 	struct sqlda	   *desc_next;	/* pointer to next sqlda struct */
+ 	void		   *reserved;	/* reserved for future use */
+ } pg_sqlda_t;
+ 
+ #endif /* POSTGRES_SQLDA_H */
+ 
+ #line 7 "sqlda.pgc"
+ 
+ 
+ #line 1 "sqltypes.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqltypes.h,v 1.9 2009/06/11 14:49:13 momjian Exp $
+  */
+ #ifndef ECPG_SQLTYPES_H
+ #define ECPG_SQLTYPES_H
+ 
+ #define CCHARTYPE	ECPGt_char
+ #define CSHORTTYPE	ECPGt_short
+ #define CINTTYPE	ECPGt_int
+ #define CLONGTYPE	ECPGt_long
+ #define CFLOATTYPE	ECPGt_float
+ #define CDOUBLETYPE ECPGt_double
+ #define CDECIMALTYPE	ECPGt_decimal
+ #define CFIXCHARTYPE	108
+ #define CSTRINGTYPE ECPGt_char
+ #define CDATETYPE	ECPGt_date
+ #define CMONEYTYPE	111
+ #define CDTIMETYPE	ECPGt_timestamp
+ #define CLOCATORTYPE	113
+ #define CVCHARTYPE	ECPGt_varchar
+ #define CINVTYPE	115
+ #define CFILETYPE	116
+ #define CINT8TYPE	ECPGt_long_long
+ #define CCOLLTYPE		118
+ #define CLVCHARTYPE		119
+ #define CFIXBINTYPE		120
+ #define CVARBINTYPE		121
+ #define CBOOLTYPE		ECPGt_bool
+ #define CROWTYPE		123
+ #define CLVCHARPTRTYPE	124
+ #define CTYPEMAX	25
+ 
+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define	SQLCHAR		0
+ #define	SQLSMINT	1
+ #define	SQLINT		2
+ #define	SQLFLOAT	3
+ #define	SQLSMFLOAT	4
+ #define	SQLDECIMAL	5
+ #define	SQLSERIAL	6
+ #define	SQLDATE		7
+ #define	SQLMONEY	8
+ #define	SQLDTIME	10
+ #define	SQLBYTES	11
+ #define	SQLTEXT		12
+ #define	SQLVCHAR	13
+ #define	SQLINTERVAL	14
+ #define	SQLNCHAR	15
+ #define	SQLNVCHAR	16
+ #define	SQLINT8		17
+ #define	SQLSERIAL8	18
+ 
+ #endif   /* ndef ECPG_SQLTYPES_H */
+ 
+ #line 8 "sqlda.pgc"
+ 
+ 
+ /* exec sql whenever sqlerror  stop ; */
+ #line 10 "sqlda.pgc"
+ 
+ 
+ /* These shouldn't be under DECLARE SECTION */
+ pg_sqlda_t	*inp_sqlda, *outp_sqlda;
+ 
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+ 	int	i;
+ 
+ 	for (i = 0; i < sqlda->sqld; i++)
+ 	{
+ 		if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+ 			printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+ 		else
+ 		switch (sqlda->sqlvar[i].sqltype)
+ 		{
+ 		case SQLCHAR:
+ 		case SQLVCHAR:
+ 		case SQLTEXT:
+ 			printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL:
+ 		case SQLINT:
+ 			printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLSERIAL8:
+ 		case SQLINT8:
+ 			printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLFLOAT:
+ 			printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname, *(double *)sqlda->sqlvar[i].sqldata);
+ 			break;
+ 		case SQLDECIMAL:
+ 			{
+ 				char    val[64];
+ 				dectoasc((decimal *)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 */
+ 		  
+ 		  
+ 		
+ 		
+ 
+ #line 58 "sqlda.pgc"
+  char * stmt1 = "SELECT * FROM t1" ;
+  
+ #line 59 "sqlda.pgc"
+  char * stmt2 = "SELECT * FROM t1 WHERE id = ?" ;
+  
+ #line 60 "sqlda.pgc"
+  int rec ;
+  
+ #line 61 "sqlda.pgc"
+  int id ;
+ /* exec sql end declare section */
+ #line 62 "sqlda.pgc"
+ 
+ 
+ 	char msg[128];
+ 
+ 	ECPGdebug(1, stderr);
+ 
+ 	strcpy(msg, "connect");
+ 	{ ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , "regress1", 0); 
+ #line 69 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 69 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "set");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 72 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 72 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "create");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT);
+ #line 80 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 80 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "insert");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null , null , null , null ) , ( 3 , '\"c\"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' )", ECPGt_EOIT, ECPGt_EORT);
+ #line 87 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 87 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, NULL, "commit");
+ #line 90 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 90 "sqlda.pgc"
+ 
+ 
+ 	/* SQLDA test for getting all records from a table */
+ 
+ 	outp_sqlda = NULL;
+ 
+ 	strcpy(msg, "prepare");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1);
+ #line 97 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 97 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "declare");
+ 	ECPG_informix_reset_sqlca(); /* declare mycur1 cursor for $1 */
+ #line 100 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "open");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1", 
+ 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 103 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 103 "sqlda.pgc"
+ 
+ 
+ 	/* exec sql whenever not found  break ; */
+ #line 105 "sqlda.pgc"
+ 
+ 
+ 	rec = 0;
+ 	while (1)
+ 	{
+ 		strcpy(msg, "fetch");
+ 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 111 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 111 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 111 "sqlda.pgc"
+  
+ 
+ 		printf("FETCH RECORD %d\n", ++rec);
+ 		dump_sqlda(outp_sqlda);
+ 	}
+ 
+ 	/* exec sql whenever not found  continue ; */
+ #line 117 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "close");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
+ #line 120 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 120 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id1");
+ #line 123 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 123 "sqlda.pgc"
+ 
+ 
+ 	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");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt1);
+ #line 134 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 134 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "declare");
+ 	ECPG_informix_reset_sqlca(); /* declare mycur2 cursor for $1 */
+ #line 137 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "open");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1", 
+ 	ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char), 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 140 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 140 "sqlda.pgc"
+ 
+ 
+ 	/* exec sql whenever not found  break ; */
+ #line 142 "sqlda.pgc"
+ 
+ 
+ 	rec = 0;
+ 	while (1)
+ 	{
+ 		strcpy(msg, "fetch");
+ 		{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from mycur2", ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 148 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 148 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 148 "sqlda.pgc"
+ 
+ 
+ 		printf("FETCH RECORD %d\n", ++rec);
+ 		dump_sqlda(outp_sqlda);
+ 	}
+ 
+ 	/* exec sql whenever not found  continue ; */
+ #line 154 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "close");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
+ #line 157 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 157 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id2");
+ #line 160 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 160 "sqlda.pgc"
+ 
+ 
+ 	free(outp_sqlda);
+ 
+ 	/* SQLDA test for getting one record using an input descriptor */
+ 
+ 	/* Input sqlda has to be built manually */
+ 	inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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");
+ 	{ ECPGprepare(__LINE__, NULL, 0, "st_id3", stmt2);
+ #line 183 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 183 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "execute");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, 1, "st_id3", 
+ 	ECPGt_sqlda, & inp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 186 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 186 "sqlda.pgc"
+ 
+ 
+ 	dump_sqlda(outp_sqlda);
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id3");
+ #line 191 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 191 "sqlda.pgc"
+ 
+ 
+ 	free(inp_sqlda->sqlvar);
+ 	free(inp_sqlda);
+ 	free(outp_sqlda);
+ 
+ 	/* SQLDA test for getting one record using an input descriptor
+ 	 * on a named connection
+ 	 */
+ 
+ 	{ ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , "con2", 0); 
+ #line 201 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 201 "sqlda.pgc"
+ 
+ 
+ 	/* Input sqlda has to be built manually */
+ 	inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+ 	memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+ 	inp_sqlda->sqld = 1;
+ 	inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+ 	memset(inp_sqlda->sqlvar, 0, sizeof(pg_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");
+ 	{ ECPGprepare(__LINE__, "con2", 0, "st_id4", stmt2);
+ #line 220 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 220 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "execute");
+ 	{ ECPGdo(__LINE__, 1, 1, "con2", 0, 1, "st_id4", 
+ 	ECPGt_sqlda, & inp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
+ 	ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L, 
+ 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 223 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 223 "sqlda.pgc"
+ 
+ 
+ 	dump_sqlda(outp_sqlda);
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, "con2", "commit");
+ #line 228 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 228 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "deallocate");
+ 	{ ECPGdeallocate(__LINE__, 1, NULL, "st_id4");
+ #line 231 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 231 "sqlda.pgc"
+ 
+ 
+ 	free(inp_sqlda->sqlvar);
+ 	free(inp_sqlda);
+ 	free(outp_sqlda);
+ 
+ 	strcpy(msg, "disconnect");
+ 	{ ECPGdisconnect(__LINE__, "con2");
+ #line 238 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 238 "sqlda.pgc"
+ 
+ 
+ 	/* End test */
+ 
+ 	strcpy(msg, "drop");
+ 	{ ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
+ #line 243 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 243 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "commit");
+ 	{ ECPGtrans(__LINE__, NULL, "commit");
+ #line 246 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 246 "sqlda.pgc"
+ 
+ 
+ 	strcpy(msg, "disconnect");
+ 	{ ECPGdisconnect(__LINE__, "CURRENT");
+ #line 249 "sqlda.pgc"
+ 
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 249 "sqlda.pgc"
+ 
+ 
+ 	return (0);
+ }
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,252 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: query: create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char ( 10 ) ); with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: query: insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null , null , null , null ) , ( 3 , '"c"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' ); with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: OK: INSERT 0 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 90: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 97: name st_id1; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: query: declare mycur1 cursor for SELECT * FROM t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 111: no data found on line 111
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 120: query: close mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 123: name st_id1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 134: name st_id2; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: query: declare mycur2 cursor for SELECT * FROM t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 148: no data found on line 148
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 157: query: close mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 160: name st_id2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 183: name st_id3; query: "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: free_params on line 186: parameter 1 = 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 191: name st_id3
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 220: name st_id4; query: "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection con2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: free_params on line 223: parameter 1 = 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: new sqlda was built
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 223: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 223: putting result (1 tuple 5 fields) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 228: action "commit"; connection "con2"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 231: name st_id4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection con2 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: query: drop table t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 243: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 246: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout
*** pgsql.fixparsepl/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout	1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout	2009-10-05 15:18:01.000000000 +0200
***************
*** 0 ****
--- 1,60 ----
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ EXECUTE RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ EXECUTE RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
#9Robert Haas
robertmhaas@gmail.com
In reply to: Boszormenyi Zoltan (#7)
Re: Review of "SQLDA support for ECPG"

On Thu, Oct 8, 2009 at 7:15 AM, Boszormenyi Zoltan <zb@cybertec.at> wrote:

It's easier to write the documentation for all changes at once.
I would have the same situation that happened with the code,
the patches with the documentation added would strictly depend
on each other again. Also, Michael Meskes applied the "string"
pseudo-type patch without the documentation, despite the patch
had it, maybe at an improper place. With a tongue-in-cheek
"no comment" ;-) I point to this paragraph in the ECPG part of
the documentation:

"This documentation is quite incomplete. But since this interface is
standardized,
additional information can be found in many resources about SQL."

OK, maybe I was overly optimistic. :-(

At least for parts of PostgreSQL other than ECPG, it is our usual
practice to require documentation to be submitted with the patch.

I have not looked at your patches and am not familiar with ECPG, but I
wonder if part of the issue here is that there are too many
interrelated changes. Maybe you'd be better off submitting some
smaller changes, wait to see how they get committed, and then move on
to the next thing. On the other hand, given that Michael seems to
have no time to review ECPG patches or provide feedback, and given
that none of the other committers seem to want to touch this with a
ten-foot-pole, maybe that would make this take forever.

...Robert

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#9)
Re: Review of "SQLDA support for ECPG"

Robert Haas <robertmhaas@gmail.com> writes:

I have not looked at your patches and am not familiar with ECPG, but I
wonder if part of the issue here is that there are too many
interrelated changes. Maybe you'd be better off submitting some
smaller changes, wait to see how they get committed, and then move on
to the next thing. On the other hand, given that Michael seems to
have no time to review ECPG patches or provide feedback, and given
that none of the other committers seem to want to touch this with a
ten-foot-pole, maybe that would make this take forever.

I presume that at some point Michael will have more free time than
he does now; we cannot expect him to do the work exactly in sync with
an arbitrarily-scheduled commit fest. Since ECPG stuff isn't really
blocking anything else, I have no problem with waiting till he does
have time. But in the meantime, I think it's probably true that
breaking things down into independently-reviewable patches might be
helpful.

(On the other hand, there are already four separate patches for ECPG
in the queue ... does it really need to be broken down more than
that?)

regards, tom lane

#11Michael Meskes
meskes@postgresql.org
In reply to: Boszormenyi Zoltan (#7)
Re: Review of "SQLDA support for ECPG"

On Thu, Oct 08, 2009 at 01:15:58PM +0200, Boszormenyi Zoltan wrote:

What's the point of that? It can't be applied without documentation,
and it just makes life more complicated to have two separate patch
files floating around.

It's easier to write the documentation for all changes at once.
I would have the same situation that happened with the code,
the patches with the documentation added would strictly depend
on each other again. Also, Michael Meskes applied the "string"
pseudo-type patch without the documentation, despite the patch
had it, maybe at an improper place. With a tongue-in-cheek

I don't get it. Are you blaming me for committing you patch although it had no
documentation? Or for not committing the documentation part of it? I definitely
did not remove anything on purpose. But if I missed something a short note
would have been a better way to tell me. If the first interpretation is right I
better not comment.

Michael
--
Michael Meskes
Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)
Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org
ICQ: 179140304, AIM/Yahoo/Skype: michaelmeskes, Jabber: meskes@jabber.org
Go VfL Borussia! Go SF 49ers! Use Debian GNU/Linux! Use PostgreSQL!

#12Boszormenyi Zoltan
zb@cybertec.at
In reply to: Michael Meskes (#11)
Re: Review of "SQLDA support for ECPG"

Michael Meskes �rta:

On Thu, Oct 08, 2009 at 01:15:58PM +0200, Boszormenyi Zoltan wrote:

What's the point of that? It can't be applied without documentation,
and it just makes life more complicated to have two separate patch
files floating around.

It's easier to write the documentation for all changes at once.
I would have the same situation that happened with the code,
the patches with the documentation added would strictly depend
on each other again. Also, Michael Meskes applied the "string"
pseudo-type patch without the documentation, despite the patch
had it, maybe at an improper place. With a tongue-in-cheek

I don't get it. Are you blaming me for committing you patch although it had no
documentation?

No blaming, but sorry, it definitely had, in both these rounds
of split-up ECPG patchsets:

2009-05-15:
http://archives.postgresql.org/message-id/4A5E0F1D.7030004@cybertec.at
2009-08-03:
http://archives.postgresql.org/message-id/4A770C7B.1060404@cybertec.at

I assumed you have applied it from the second mail, this was
the last version sent for the "string" patch. It is my fault that
I haven't put it on the CommitFest page. Indeed, the version
on the CF page doesn't have documentation. But the code you
committed seems to be the one (or very close, with some
editorialization) in the second mail quoted above.

Or for not committing the documentation part of it? I definitely
did not remove anything on purpose.

I guessed that it was not on purpose, but I only realized
last thursday that the documentation for "string" is missing
when I wrote the docs for the other patches.

But if I missed something a short note
would have been a better way to tell me.

Yes, of course. Sorry.

Best regards,
Zolt�n B�sz�rm�nyi

--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zolt�n B�sz�rm�nyi
Cybertec Sch�nig & Sch�nig GmbH
http://www.postgresql.at/

#13Robert Haas
robertmhaas@gmail.com
In reply to: Boszormenyi Zoltan (#12)
Re: Review of "SQLDA support for ECPG"

On Sat, Oct 10, 2009 at 2:09 PM, Boszormenyi Zoltan <zb@cybertec.at> wrote:

Michael Meskes írta:

On Thu, Oct 08, 2009 at 01:15:58PM +0200, Boszormenyi Zoltan wrote:

What's the point of that?  It can't be applied without documentation,
and it just makes life more complicated to have two separate patch
files floating around.

It's easier to write the documentation for all changes at once.
I would have the same situation that happened with the code,
the patches with the documentation added would strictly depend
on each other again. Also, Michael Meskes applied the "string"
pseudo-type patch without the documentation, despite the patch
had it, maybe at an improper place. With a tongue-in-cheek

I don't get it. Are you blaming me for committing you patch although it had no
documentation?

No blaming, but sorry, it definitely had, in both these rounds
of split-up ECPG patchsets:

2009-05-15:
http://archives.postgresql.org/message-id/4A5E0F1D.7030004@cybertec.at
2009-08-03:
http://archives.postgresql.org/message-id/4A770C7B.1060404@cybertec.at

I assumed you have applied it from the second mail, this was
the last version sent for the "string" patch. It is my fault that
I haven't put it on the CommitFest page. Indeed, the version
on the CF page doesn't have documentation. But the code you
committed seems to be the one (or very close, with some
editorialization) in the second mail quoted above.

Since it doesn't seem that any of the patches are going to get
committed RSN, I have moved all of the open ECPG patches to the next
CommitFest and given them their own section.

...Robert