mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Implement DO CONTINUE action for ECPG WHENEVER statement.
Author: Vinayak Pokale Reviewed-By: Masahiko Sawada
This commit is contained in:
parent
3f4c7917b3
commit
d22e9d5305
@ -4762,6 +4762,17 @@ EXEC SQL WHENEVER <replaceable>condition</replaceable> <replaceable>action</repl
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>DO CONTINUE</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Execute the C statement <literal>continue</literal>. This should
|
||||
only be used in loops statements. if executed, will cause the flow
|
||||
of control to return to the top of the loop.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>CALL <replaceable>name</replaceable> (<replaceable>args</replaceable>)</literal></term>
|
||||
<term><literal>DO <replaceable>name</replaceable> (<replaceable>args</replaceable>)</literal></term>
|
||||
@ -7799,6 +7810,7 @@ WHENEVER { NOT FOUND | SQLERROR | SQLWARNING } <replaceable class="PARAMETER">ac
|
||||
<programlisting>
|
||||
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;
|
||||
|
@ -1454,6 +1454,12 @@ action : CONTINUE_P
|
||||
$<action>$.command = NULL;
|
||||
$<action>$.str = mm_strdup("break");
|
||||
}
|
||||
| DO CONTINUE_P
|
||||
{
|
||||
$<action>$.code = W_CONTINUE;
|
||||
$<action>$.command = NULL;
|
||||
$<action>$.str = mm_strdup("continue");
|
||||
}
|
||||
| SQL_CALL name '(' c_args ')'
|
||||
{
|
||||
$<action>$.code = W_DO;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
161
src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c
Normal file
161
src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c
Normal file
@ -0,0 +1,161 @@
|
||||
/* Processed by ecpg (regression mode) */
|
||||
/* These include files are added by the preprocessor */
|
||||
#include <ecpglib.h>
|
||||
#include <ecpgerrno.h>
|
||||
#include <sqlca.h>
|
||||
/* End of automatic include section */
|
||||
#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
|
||||
|
||||
#line 1 "whenever_do_continue.pgc"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/* The 'BREAK' condition to exit the loop. */
|
||||
/* exec sql whenever not found break ; */
|
||||
#line 39 "whenever_do_continue.pgc"
|
||||
|
||||
|
||||
/* The DO CONTINUE makes the loop start at the next iteration when an error occurs.*/
|
||||
/* exec sql whenever sqlerror continue ; */
|
||||
#line 42 "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 46 "whenever_do_continue.pgc"
|
||||
|
||||
if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
|
||||
#line 46 "whenever_do_continue.pgc"
|
||||
|
||||
if (sqlca.sqlcode < 0) continue;}
|
||||
#line 46 "whenever_do_continue.pgc"
|
||||
|
||||
/* The employees with non-NULL commissions will be displayed. */
|
||||
printf("%s %7.2f %9.2f\n", emp.ename, emp.sal, emp.comm);
|
||||
}
|
||||
|
||||
/*
|
||||
* This 'CONTINUE' shuts off the 'DO CONTINUE' and allow the program to
|
||||
* proceed if any further errors do occur.
|
||||
*/
|
||||
/* exec sql whenever sqlerror continue ; */
|
||||
#line 55 "whenever_do_continue.pgc"
|
||||
|
||||
|
||||
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close c", ECPGt_EOIT, ECPGt_EORT);}
|
||||
#line 57 "whenever_do_continue.pgc"
|
||||
|
||||
|
||||
strcpy(msg, "drop");
|
||||
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table emp", ECPGt_EOIT, ECPGt_EORT);}
|
||||
#line 60 "whenever_do_continue.pgc"
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
[NO_PID]: ECPGdebug: set to 1
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ECPGconnect: opening database ecpg1_regression on <DEFAULT> port <DEFAULT>
|
||||
[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 46: query: fetch c; with 0 parameter(s) on connection ecpg1_regression
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 46: using PQexec
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_process_output on line 46: correctly got 1 tuples with 3 fields
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: aryan offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: 11110 offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: raising sqlcode -213 on line 46: null value without indicator on line 46
|
||||
[NO_PID]: sqlca: code: -213, state: 22002
|
||||
[NO_PID]: ecpg_execute on line 46: query: fetch c; with 0 parameter(s) on connection ecpg1_regression
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 46: using PQexec
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_process_output on line 46: correctly got 1 tuples with 3 fields
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: josh offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: 10000 offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: 10 offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 46: query: fetch c; with 0 parameter(s) on connection ecpg1_regression
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 46: using PQexec
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_process_output on line 46: correctly got 1 tuples with 3 fields
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: Ram offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: 111100 offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: 21 offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 46: query: fetch c; with 0 parameter(s) on connection ecpg1_regression
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 46: using PQexec
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_process_output on line 46: correctly got 1 tuples with 3 fields
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: tom offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: 20000 offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 46: RESULT: offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: raising sqlcode -213 on line 46: null value without indicator on line 46
|
||||
[NO_PID]: sqlca: code: -213, state: 22002
|
||||
[NO_PID]: ecpg_execute on line 46: query: fetch c; with 0 parameter(s) on connection ecpg1_regression
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 46: using PQexec
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_process_output on line 46: correctly got 0 tuples with 3 fields
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: raising sqlcode 100 on line 46: no data found on line 46
|
||||
[NO_PID]: sqlca: code: 100, state: 02000
|
||||
[NO_PID]: ecpg_execute on line 57: query: close c; with 0 parameter(s) on connection ecpg1_regression
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 57: using PQexec
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_process_output on line 57: OK: CLOSE CURSOR
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_execute on line 60: 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 60: using PQexec
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_process_output on line 60: OK: DROP TABLE
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
@ -0,0 +1,2 @@
|
||||
josh 10000.00 10.00
|
||||
Ram 111100.00 21.00
|
@ -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)
|
||||
|
63
src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc
Normal file
63
src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc
Normal file
@ -0,0 +1,63 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
|
||||
/* The 'BREAK' condition to exit the loop. */
|
||||
exec sql whenever not found do break;
|
||||
|
||||
/* The DO CONTINUE makes the loop start at the next iteration when an error occurs.*/
|
||||
exec sql whenever sqlerror do continue;
|
||||
|
||||
while (1)
|
||||
{
|
||||
exec sql fetch c into :emp;
|
||||
/* The employees with non-NULL commissions will be displayed. */
|
||||
printf("%s %7.2f %9.2f\n", emp.ename, emp.sal, emp.comm);
|
||||
}
|
||||
|
||||
/*
|
||||
* This 'CONTINUE' shuts off the 'DO CONTINUE' and allow the program to
|
||||
* proceed if any further errors do occur.
|
||||
*/
|
||||
exec sql whenever sqlerror continue;
|
||||
|
||||
exec sql close c;
|
||||
|
||||
strcpy(msg, "drop");
|
||||
exec sql drop table emp;
|
||||
|
||||
exit(0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user