BUG #15176: ecpg generation error - Mailing list pgsql-bugs
From | PG Bug reporting form |
---|---|
Subject | BUG #15176: ecpg generation error |
Date | |
Msg-id | 152468741102.19805.13932148777494153815@wrigleys.postgresql.org Whole thread Raw |
Responses |
Re: BUG #15176: ecpg generation error
|
List | pgsql-bugs |
The following bug has been logged on the website: Bug reference: 15176 Logged by: Uwe Höppner Email address: uhoeppner@psi.de PostgreSQL version: 10.3 Operating system: PostgreSQL 10.3, compiled by Visual C++ build 180 Description: Hello, we are very happy, that PostgreSQL exists as an alternative and we want to migrate to postgresql and try to use ecpg to precompile our existing code to produce c-Code to access our pg-database. But the generated code does not compile. We tested with Microsoft Visual Studio Professional 2015, Version 14. Our C++ applications have a lot of embedded SQL, so it is not possible to change fast to other frameworks. The main problem arises, when we use structs with VARCHAR elements. an example-table: CREATE TABLE public.test_ta ( bb double precision, ii integer, nname character varying(80) ) WITH ( OIDS = FALSE ); ALTER TABLE public.test_ta OWNER to postgres; ---------------------------------------------------------------------------------------------------------- pgc-Code snippet start: int fkt1() { EXEC SQL BEGIN DECLARE SECTION; struct a_t { double b; int i; VARCHAR name[180]; }; struct a_ind_t { short b; short i; short name; }; struct a_t a_var; struct a_ind_t a_ind_var; EXEC SQL END DECLARE SECTION; EXEC SQL SELECT bb,ii, nname INTO :a_var:a_ind_var FROM test_ta; pgc-code snippet stop -------------------------------------------------------------------------------------------------------------------------- ecpg generates the following output: int fkt1() { /* exec sql begin declare section */ (yes, these empty lines are produced by ecpg :-) ) struct a_t { #line 37 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" double b ; #line 38 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" int i ; #line 39 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" struct varchar_1 { int len; char arr[ 180 ]; } name ; } ; struct a_ind_t { #line 44 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" short b ; #line 45 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" short i ; #line 46 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" short name ; } ; #line 49 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" struct a_t a_var ; #line 50 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" struct a_ind_t a_ind_var ; /* exec sql end declare section */ #line 52 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select bb , ii , nname from test_ta", ECPGt_EOIT, ECPGt_double,&(a_var.b),(long)1,(long)1,sizeof( struct a_t ), ECPGt_short,&(a_ind_var.b),(long)1,(long)1,sizeof( struct a_ind_t ), ECPGt_int,&(a_var.i),(long)1,(long)1,sizeof( struct a_t ), ECPGt_short,&(a_ind_var.i),(long)1,(long)1,sizeof( struct a_ind_t ), ECPGt_varchar,&(a_var.name),(long)180,(long)1,sizeof( struct a_t ), ECPGt_short,&(a_ind_var.name),(long)1,(long)1,sizeof( struct a_ind_t ), ECPGt_EORT);} #line 54 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" -------------------------------------------------------------------------------------------------------------------------- For select statements the generated code compiles, but IMO, the parameters of all sizeof() calls are wrong. I would expect code like this: { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select bb , ii , nname from test_ta", ECPGt_EOIT, ECPGt_double,&(a_var.b),(long)1,(long)1,sizeof(a_var.b), ECPGt_short,&(a_ind_var.b),(long)1,(long)1,sizeof(a_ind_var.b), ECPGt_int,&(a_var.i),(long)1,(long)1,sizeof(a_var.i), ECPGt_short,&(a_ind_var.i),(long)1,(long)1,sizeof(a_ind_var.i), ECPGt_varchar,&(a_var.name),(long)180,(long)1,sizeof(a_var.name), ECPGt_short,&(a_ind_var.name),(long)1,(long)1,sizeof(a_ind_var.name), ECPGt_EORT);} -------------------------------------------------------------------------------------------------------------------------- The result is even worse, if you try to insert into the database. the pgc-code: a_var.b = 1.0; a_var.i = 2; //a_var.name is empty EXEC SQL INSERT INTO test_ta(bb,ii,nname) VALUES(:a_var.b, :a_var.i, :a_var.name); pgc-code stop -------------------------------------------------------------------------------------------------------------------------- ecpg generates the following output: a_var.b = 1.0; a_var.i = 2; //a_var.name is empty { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into test_ta ( bb , ii , nname ) values ( $1 , $2 , $3 )", ECPGt_double,&(a_var.b),(long)1,(long)1,sizeof(double), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_int,&(a_var.i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_varchar,&(a_var.name),(long)180,(long)1,sizeof(struct varchar_1), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} #line 62 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" -------------------------------------------------------------------------------------------------------------------------- This code does not compile! If you look to #line 39 you can see the definition of struct varchar_1 inside of struct a_t in function fkt1. So this results in the following error message: 1>d:\dev\ems\master\src\db\bdp\app\pgtest\ctestapp.pc(67): error C2027: Verwendung des undefinierten Typs "fkt1::varchar_1" varchar_1 is unknown. After manual correction it compiles: { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into test_ta ( bb , ii , nname ) values ( $1 , $2 , $3 )", ECPGt_double,&(a_var.b),(long)1,(long)1,sizeof(double), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_int,&(a_var.i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, /* ECPGt_varchar,&(a_var.name),(long)180,(long)1,sizeof(struct varchar_1), wrong generated */ /* ECPGt_varchar,&(a_var.name),(long)180,(long)1,sizeof(struct a_t::varchar_1), also okay */ ECPGt_varchar, &(a_var.name), (long)180, (long)1, sizeof(a_var.name), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);} #line 62 "D:/dev/ems/master/src/db/bdp/app/pgtest/CTestApp.pc" I would prefer the variant with use of the variable over the variant with the type. Both seem ok. Could you please repair ecpg, so it generates code, that compiles. :-) Cheers, Uwe
pgsql-bugs by date: