From 8e10afb89d9f7de3e0e8f9e0cf206b44438284a4 Mon Sep 17 00:00:00 2001 From: Vinayak Pokale Date: Mon, 12 Jun 2017 13:03:21 +0900 Subject: [PATCH] WHENEVER statement DO CONTINUE support --- doc/src/sgml/ecpg.sgml | 12 ++ src/interfaces/ecpg/preproc/ecpg.trailer | 6 + src/interfaces/ecpg/preproc/output.c | 3 + src/interfaces/ecpg/test/ecpg_schedule | 1 + .../test/expected/preproc-whenever_do_continue.c | 155 ++++++++++++++++++++ .../expected/preproc-whenever_do_continue.stderr | 116 +++++++++++++++ .../expected/preproc-whenever_do_continue.stdout | 2 + src/interfaces/ecpg/test/preproc/Makefile | 1 + .../ecpg/test/preproc/whenever_do_continue.pgc | 57 +++++++ 9 files changed, 353 insertions(+), 0 deletions(-) create mode 100644 src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c create mode 100644 src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stderr create mode 100644 src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stdout create mode 100644 src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index f13a0e9..3cb4001 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -4763,6 +4763,17 @@ EXEC SQL WHENEVER condition action + DO CONTINUE + + + Execute the C statement continue. This should + only be used in loops statements. if executed, will cause the flow + of control to return to the top of the loop. + + + + + CALL name (args) DO name (args) @@ -7799,6 +7810,7 @@ WHENEVER { NOT FOUND | SQLERROR | SQLWARNING } ac EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL WHENEVER NOT FOUND DO BREAK; +EXEC SQL WHENEVER NOT FOUND DO CONTINUE; EXEC SQL WHENEVER SQLWARNING SQLPRINT; EXEC SQL WHENEVER SQLWARNING DO warn(); EXEC SQL WHENEVER SQLERROR sqlprint; diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 1c10879..b42bca4 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -1454,6 +1454,12 @@ action : CONTINUE_P $$.command = NULL; $$.str = mm_strdup("break"); } + | DO CONTINUE_P + { + $$.code = W_CONTINUE; + $$.command = NULL; + $$.str = mm_strdup("continue"); + } | SQL_CALL name '(' c_args ')' { $$.code = W_DO; diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c index 59d5d30..14d7066 100644 --- a/src/interfaces/ecpg/preproc/output.c +++ b/src/interfaces/ecpg/preproc/output.c @@ -51,6 +51,9 @@ print_action(struct when * w) case W_BREAK: fprintf(base_yyout, "break;"); break; + case W_CONTINUE: + fprintf(base_yyout, "continue;"); + break; default: fprintf(base_yyout, "{/* %d not implemented yet */}", w->code); break; diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule index c3ec125..cff4eeb 100644 --- a/src/interfaces/ecpg/test/ecpg_schedule +++ b/src/interfaces/ecpg/test/ecpg_schedule @@ -28,6 +28,7 @@ test: preproc/type test: preproc/variable test: preproc/outofscope test: preproc/whenever +test: preproc/whenever_do_continue test: sql/array test: sql/binary test: sql/code100 diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c new file mode 100644 index 0000000..2c9d16f --- /dev/null +++ b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c @@ -0,0 +1,155 @@ +/* Processed by ecpg (regression mode) */ +/* These include files are added by the preprocessor */ +#include +#include +#include +/* End of automatic include section */ +#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + +#line 1 "whenever_do_continue.pgc" +#include + + +#line 1 "regression.h" + + + + + + +#line 3 "whenever_do_continue.pgc" + + +/* exec sql whenever sqlerror sqlprint ; */ +#line 5 "whenever_do_continue.pgc" + + +int main(void) +{ + /* exec sql begin declare section */ + + + + + + + + + +#line 15 "whenever_do_continue.pgc" + struct { +#line 12 "whenever_do_continue.pgc" + char ename [ 12 ] ; + +#line 13 "whenever_do_continue.pgc" + float sal ; + +#line 14 "whenever_do_continue.pgc" + float comm ; + } emp ; + +#line 17 "whenever_do_continue.pgc" + char msg [ 128 ] ; +/* exec sql end declare section */ +#line 18 "whenever_do_continue.pgc" + + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); +#line 23 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 23 "whenever_do_continue.pgc" + + + strcpy(msg, "create"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table emp ( ename varchar , sal double precision , comm double precision )", ECPGt_EOIT, ECPGt_EORT); +#line 26 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 26 "whenever_do_continue.pgc" + + + strcpy(msg, "insert"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into emp values ( 'Ram' , 111100 , 21 )", ECPGt_EOIT, ECPGt_EORT); +#line 29 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 29 "whenever_do_continue.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into emp values ( 'aryan' , 11110 , null )", ECPGt_EOIT, ECPGt_EORT); +#line 30 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 30 "whenever_do_continue.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into emp values ( 'josh' , 10000 , 10 )", ECPGt_EOIT, ECPGt_EORT); +#line 31 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 31 "whenever_do_continue.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into emp values ( 'tom' , 20000 , null )", ECPGt_EOIT, ECPGt_EORT); +#line 32 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 32 "whenever_do_continue.pgc" + + + /* declare c cursor for select ename , sal , comm from emp order by ename asc */ +#line 34 "whenever_do_continue.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare c cursor for select ename , sal , comm from emp order by ename asc", ECPGt_EOIT, ECPGt_EORT); +#line 36 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 36 "whenever_do_continue.pgc" + + + /* exec sql whenever not found break ; */ +#line 38 "whenever_do_continue.pgc" + + + /* exec sql whenever sqlerror continue ; */ +#line 40 "whenever_do_continue.pgc" + + + while (1) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch c", ECPGt_EOIT, + ECPGt_char,&(emp.ename),(long)12,(long)1,(12)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_float,&(emp.sal),(long)1,(long)1,sizeof(float), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_float,&(emp.comm),(long)1,(long)1,sizeof(float), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 44 "whenever_do_continue.pgc" + +if (sqlca.sqlcode == ECPG_NOT_FOUND) break; +#line 44 "whenever_do_continue.pgc" + +if (sqlca.sqlcode < 0) continue;} +#line 44 "whenever_do_continue.pgc" + + printf("%s %7.2f %9.2f\n", emp.ename, emp.sal, emp.comm); + } + + /* exec sql whenever sqlerror continue ; */ +#line 48 "whenever_do_continue.pgc" + + + strcpy(msg, "drop"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table emp", ECPGt_EOIT, ECPGt_EORT);} +#line 51 "whenever_do_continue.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c", ECPGt_EOIT, ECPGt_EORT);} +#line 53 "whenever_do_continue.pgc" + + + exit(0); +} + diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stderr b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stderr new file mode 100644 index 0000000..d0cdec5 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stderr @@ -0,0 +1,116 @@ +[NO_PID]: ECPGdebug: set to 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: opening database ecpg1_regression on port +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 26: query: create table emp ( ename varchar , sal double precision , comm double precision ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 26: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 26: OK: CREATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 29: query: insert into emp values ( 'Ram' , 111100 , 21 ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 29: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 29: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 30: query: insert into emp values ( 'aryan' , 11110 , null ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 30: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 30: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 31: query: insert into emp values ( 'josh' , 10000 , 10 ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 31: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 31: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 32: query: insert into emp values ( 'tom' , 20000 , null ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 32: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 32: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 36: query: declare c cursor for select ename , sal , comm from emp order by ename asc; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 36: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 36: OK: DECLARE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 44: query: fetch c; with 0 parameter(s) on connection ecpg1_regression +[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_process_output on line 44: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: aryan offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: 11110 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode -213 on line 44: null value without indicator on line 44 +[NO_PID]: sqlca: code: -213, state: 22002 +[NO_PID]: ecpg_execute on line 44: query: fetch c; with 0 parameter(s) on connection ecpg1_regression +[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_process_output on line 44: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: josh offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: 10000 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: 10 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 44: query: fetch c; with 0 parameter(s) on connection ecpg1_regression +[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_process_output on line 44: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: Ram offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: 111100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: 21 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 44: query: fetch c; with 0 parameter(s) on connection ecpg1_regression +[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_process_output on line 44: correctly got 1 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: tom offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: 20000 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 44: RESULT: offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode -213 on line 44: null value without indicator on line 44 +[NO_PID]: sqlca: code: -213, state: 22002 +[NO_PID]: ecpg_execute on line 44: query: fetch c; with 0 parameter(s) on connection ecpg1_regression +[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_process_output on line 44: correctly got 0 tuples with 3 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode 100 on line 44: no data found on line 44 +[NO_PID]: sqlca: code: 100, state: 02000 +[NO_PID]: ecpg_execute on line 51: query: drop table emp; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 51: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_check_PQresult on line 51: bad response - ERROR: cannot DROP TABLE "emp" because it is being used by active queries in this session +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlstate 55006 (sqlcode -400): cannot DROP TABLE "emp" because it is being used by active queries in this session on line 51 +[NO_PID]: sqlca: code: -400, state: 55006 +[NO_PID]: ecpg_execute on line 53: query: close c; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 53: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_check_PQresult on line 53: bad response - ERROR: current transaction is aborted, commands ignored until end of transaction block +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlstate 25P02 (sqlcode -400): current transaction is aborted, commands ignored until end of transaction block on line 53 +[NO_PID]: sqlca: code: -400, state: 25P02 diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stdout b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stdout new file mode 100644 index 0000000..75fb6ce --- /dev/null +++ b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.stdout @@ -0,0 +1,2 @@ +josh 10000.00 10.00 +Ram 111100.00 21.00 diff --git a/src/interfaces/ecpg/test/preproc/Makefile b/src/interfaces/ecpg/test/preproc/Makefile index d658a4d..39b1974 100644 --- a/src/interfaces/ecpg/test/preproc/Makefile +++ b/src/interfaces/ecpg/test/preproc/Makefile @@ -15,6 +15,7 @@ TESTS = array_of_struct array_of_struct.c \ type type.c \ variable variable.c \ whenever whenever.c \ + whenever_do_continue whenever_do_continue.c \ pointer_to_struct pointer_to_struct.c all: $(TESTS) diff --git a/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc b/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc new file mode 100644 index 0000000..f3c8a10 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc @@ -0,0 +1,57 @@ +#include + +exec sql include ../regression; + +exec sql whenever sqlerror sqlprint; + +int main(void) +{ + exec sql begin declare section; + struct + { + char ename[12]; + float sal; + float comm; + } emp; + + char msg[128]; + exec sql end declare section; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + exec sql connect to REGRESSDB1; + + strcpy(msg, "create"); + exec sql create table emp(ename varchar,sal double precision, comm double precision); + + strcpy(msg, "insert"); + exec sql insert into emp values ('Ram',111100,21); + exec sql insert into emp values ('aryan',11110,null); + exec sql insert into emp values ('josh',10000,10); + exec sql insert into emp values ('tom',20000,null); + + exec sql declare c cursor for select ename, sal, comm from emp order by ename asc; + + exec sql open c; + + exec sql whenever not found do break; + + exec sql whenever sqlerror do continue; + + while (1) + { + exec sql fetch c into :emp; + printf("%s %7.2f %9.2f\n", emp.ename, emp.sal, emp.comm); + } + + exec sql whenever sqlerror continue; + + strcpy(msg, "drop"); + exec sql drop table emp; + + exec sql close c; + + exit(0); +} + -- 1.7.1