mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Added EXECUTE command to PL/pgSQL for execution of
dynamic SQL and utility statements. Jan
This commit is contained in:
parent
16dc9bafb7
commit
d4266620e1
@ -4,7 +4,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.10 2000/06/05 07:29:14 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.11 2000/08/31 13:26:15 wieck Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -113,6 +113,7 @@ static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
|
|||||||
%type <stmt> stmt_assign, stmt_if, stmt_loop, stmt_while, stmt_exit
|
%type <stmt> stmt_assign, stmt_if, stmt_loop, stmt_while, stmt_exit
|
||||||
%type <stmt> stmt_return, stmt_raise, stmt_execsql, stmt_fori
|
%type <stmt> stmt_return, stmt_raise, stmt_execsql, stmt_fori
|
||||||
%type <stmt> stmt_fors, stmt_select, stmt_perform
|
%type <stmt> stmt_fors, stmt_select, stmt_perform
|
||||||
|
%type <stmt> stmt_dynexecute, stmt_dynfors
|
||||||
|
|
||||||
%type <dtlist> raise_params
|
%type <dtlist> raise_params
|
||||||
%type <ival> raise_level, raise_param
|
%type <ival> raise_level, raise_param
|
||||||
@ -134,6 +135,7 @@ static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
|
|||||||
%token K_ELSE
|
%token K_ELSE
|
||||||
%token K_END
|
%token K_END
|
||||||
%token K_EXCEPTION
|
%token K_EXCEPTION
|
||||||
|
%token K_EXECUTE
|
||||||
%token K_EXIT
|
%token K_EXIT
|
||||||
%token K_FOR
|
%token K_FOR
|
||||||
%token K_FROM
|
%token K_FROM
|
||||||
@ -568,6 +570,10 @@ proc_stmt : pl_block
|
|||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
| stmt_execsql
|
| stmt_execsql
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
|
| stmt_dynexecute
|
||||||
|
{ $$ = $1; }
|
||||||
|
| stmt_dynfors
|
||||||
|
{ $$ = $1; }
|
||||||
| stmt_perform
|
| stmt_perform
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
@ -844,6 +850,35 @@ stmt_fors : opt_label K_FOR lno fors_target K_IN K_SELECT expr_until_loop loop_b
|
|||||||
$$ = (PLpgSQL_stmt *)new;
|
$$ = (PLpgSQL_stmt *)new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stmt_dynfors : opt_label K_FOR lno fors_target K_IN K_EXECUTE expr_until_loop loop_body
|
||||||
|
{
|
||||||
|
PLpgSQL_stmt_dynfors *new;
|
||||||
|
|
||||||
|
new = malloc(sizeof(PLpgSQL_stmt_dynfors));
|
||||||
|
memset(new, 0, sizeof(PLpgSQL_stmt_dynfors));
|
||||||
|
|
||||||
|
new->cmd_type = PLPGSQL_STMT_DYNFORS;
|
||||||
|
new->lineno = $3;
|
||||||
|
new->label = $1;
|
||||||
|
switch ($4->dtype) {
|
||||||
|
case PLPGSQL_DTYPE_REC:
|
||||||
|
new->rec = $4;
|
||||||
|
break;
|
||||||
|
case PLPGSQL_DTYPE_ROW:
|
||||||
|
new->row = (PLpgSQL_row *)$4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
plpgsql_comperrinfo();
|
||||||
|
elog(ERROR, "unknown dtype %d in stmt_dynfors", $4->dtype);
|
||||||
|
}
|
||||||
|
new->query = $7;
|
||||||
|
new->body = $8;
|
||||||
|
|
||||||
|
plpgsql_ns_pop();
|
||||||
|
|
||||||
|
$$ = (PLpgSQL_stmt *)new;
|
||||||
|
}
|
||||||
|
|
||||||
fors_target : T_RECORD
|
fors_target : T_RECORD
|
||||||
{
|
{
|
||||||
$$ = yylval.rec;
|
$$ = yylval.rec;
|
||||||
@ -1028,6 +1063,19 @@ stmt_execsql : execsql_start lno
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
stmt_dynexecute : K_EXECUTE lno expr_until_semi
|
||||||
|
{
|
||||||
|
PLpgSQL_stmt_dynexecute *new;
|
||||||
|
|
||||||
|
new = malloc(sizeof(PLpgSQL_stmt_dynexecute));
|
||||||
|
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
|
||||||
|
new->lineno = $2;
|
||||||
|
new->query = $3;
|
||||||
|
|
||||||
|
$$ = (PLpgSQL_stmt *)new;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
execsql_start : T_WORD
|
execsql_start : T_WORD
|
||||||
{ $$ = strdup(yytext); }
|
{ $$ = strdup(yytext); }
|
||||||
| T_ERROR
|
| T_ERROR
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.22 2000/08/03 16:34:57 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.23 2000/08/31 13:26:16 wieck Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -159,8 +159,8 @@ plpgsql_compile(Oid fn_oid, int functype)
|
|||||||
|
|
||||||
function->fn_functype = functype;
|
function->fn_functype = functype;
|
||||||
function->fn_oid = fn_oid;
|
function->fn_oid = fn_oid;
|
||||||
function->fn_name = DatumGetCString(DirectFunctionCall1(nameout,
|
function->fn_name = strdup(DatumGetCString(DirectFunctionCall1(nameout,
|
||||||
NameGetDatum(&(procStruct->proname))));
|
NameGetDatum(&(procStruct->proname)))));
|
||||||
|
|
||||||
switch (functype)
|
switch (functype)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.28 2000/08/24 03:29:15 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.29 2000/08/31 13:26:16 wieck Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -100,6 +100,10 @@ static int exec_stmt_raise(PLpgSQL_execstate * estate,
|
|||||||
PLpgSQL_stmt_raise * stmt);
|
PLpgSQL_stmt_raise * stmt);
|
||||||
static int exec_stmt_execsql(PLpgSQL_execstate * estate,
|
static int exec_stmt_execsql(PLpgSQL_execstate * estate,
|
||||||
PLpgSQL_stmt_execsql * stmt);
|
PLpgSQL_stmt_execsql * stmt);
|
||||||
|
static int exec_stmt_dynexecute(PLpgSQL_execstate * estate,
|
||||||
|
PLpgSQL_stmt_dynexecute * stmt);
|
||||||
|
static int exec_stmt_dynfors(PLpgSQL_execstate * estate,
|
||||||
|
PLpgSQL_stmt_dynfors * stmt);
|
||||||
|
|
||||||
static void exec_prepare_plan(PLpgSQL_execstate * estate,
|
static void exec_prepare_plan(PLpgSQL_execstate * estate,
|
||||||
PLpgSQL_expr * expr);
|
PLpgSQL_expr * expr);
|
||||||
@ -219,6 +223,12 @@ plpgsql_exec_function(PLpgSQL_function * func, FunctionCallInfo fcinfo)
|
|||||||
case PLPGSQL_STMT_EXECSQL:
|
case PLPGSQL_STMT_EXECSQL:
|
||||||
stmttype = "SQL statement";
|
stmttype = "SQL statement";
|
||||||
break;
|
break;
|
||||||
|
case PLPGSQL_STMT_DYNEXECUTE:
|
||||||
|
stmttype = "execute statement";
|
||||||
|
break;
|
||||||
|
case PLPGSQL_STMT_DYNFORS:
|
||||||
|
stmttype = "for over execute statement";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
stmttype = "unknown";
|
stmttype = "unknown";
|
||||||
break;
|
break;
|
||||||
@ -522,6 +532,12 @@ plpgsql_exec_trigger(PLpgSQL_function * func,
|
|||||||
case PLPGSQL_STMT_EXECSQL:
|
case PLPGSQL_STMT_EXECSQL:
|
||||||
stmttype = "SQL statement";
|
stmttype = "SQL statement";
|
||||||
break;
|
break;
|
||||||
|
case PLPGSQL_STMT_DYNEXECUTE:
|
||||||
|
stmttype = "execute statement";
|
||||||
|
break;
|
||||||
|
case PLPGSQL_STMT_DYNFORS:
|
||||||
|
stmttype = "for over execute statement";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
stmttype = "unknown";
|
stmttype = "unknown";
|
||||||
break;
|
break;
|
||||||
@ -995,6 +1011,14 @@ exec_stmt(PLpgSQL_execstate * estate, PLpgSQL_stmt * stmt)
|
|||||||
rc = exec_stmt_execsql(estate, (PLpgSQL_stmt_execsql *) stmt);
|
rc = exec_stmt_execsql(estate, (PLpgSQL_stmt_execsql *) stmt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PLPGSQL_STMT_DYNEXECUTE:
|
||||||
|
rc = exec_stmt_dynexecute(estate, (PLpgSQL_stmt_dynexecute *) stmt);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLPGSQL_STMT_DYNFORS:
|
||||||
|
rc = exec_stmt_dynfors(estate, (PLpgSQL_stmt_dynfors *) stmt);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_info_stmt = save_estmt;
|
error_info_stmt = save_estmt;
|
||||||
elog(ERROR, "unknown cmdtype %d in exec_stmt",
|
elog(ERROR, "unknown cmdtype %d in exec_stmt",
|
||||||
@ -1852,6 +1876,234 @@ exec_stmt_execsql(PLpgSQL_execstate * estate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* exec_stmt_dynexecute Execute a dynamic SQL query not
|
||||||
|
* returning any data.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
exec_stmt_dynexecute(PLpgSQL_execstate * estate,
|
||||||
|
PLpgSQL_stmt_dynexecute * stmt)
|
||||||
|
{
|
||||||
|
Datum query;
|
||||||
|
bool isnull = false;
|
||||||
|
Oid restype;
|
||||||
|
char *querystr;
|
||||||
|
HeapTuple typetup;
|
||||||
|
Form_pg_type typeStruct;
|
||||||
|
FmgrInfo finfo_output;
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* First we evaluate the string expression after the
|
||||||
|
* EXECUTE keyword. It's result is the querystring we have
|
||||||
|
* to execute.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
query = exec_eval_expr(estate, stmt->query, &isnull, &restype);
|
||||||
|
if (isnull)
|
||||||
|
elog(ERROR, "cannot EXECUTE NULL-query");
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Get the C-String representation.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
typetup = SearchSysCacheTuple(TYPEOID,
|
||||||
|
ObjectIdGetDatum(restype), 0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(typetup))
|
||||||
|
elog(ERROR, "cache lookup for type %u failed (1)", restype);
|
||||||
|
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
|
||||||
|
|
||||||
|
fmgr_info(typeStruct->typoutput, &finfo_output);
|
||||||
|
querystr = DatumGetCString(FunctionCall3(&finfo_output,
|
||||||
|
query,
|
||||||
|
ObjectIdGetDatum(typeStruct->typelem),
|
||||||
|
Int32GetDatum(-1)));
|
||||||
|
|
||||||
|
if(!typeStruct->typbyval)
|
||||||
|
pfree((void *)query);
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Call SPI_exec() without preparing a saved plan.
|
||||||
|
* The returncode can be any OK except for OK_SELECT.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
switch(SPI_exec(querystr, 0))
|
||||||
|
{
|
||||||
|
case SPI_OK_UTILITY:
|
||||||
|
case SPI_OK_SELINTO:
|
||||||
|
case SPI_OK_INSERT:
|
||||||
|
case SPI_OK_UPDATE:
|
||||||
|
case SPI_OK_DELETE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPI_OK_SELECT:
|
||||||
|
elog(ERROR, "unexpected SELECT operation in EXECUTE of query '%s'",
|
||||||
|
querystr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unexpected error in EXECUTE for query '%s'",
|
||||||
|
querystr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(querystr);
|
||||||
|
return PLPGSQL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* exec_stmt_dynfors Execute a dynamic query, assign each
|
||||||
|
* tuple to a record or row and
|
||||||
|
* execute a group of statements
|
||||||
|
* for it.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
|
||||||
|
{
|
||||||
|
Datum query;
|
||||||
|
bool isnull = false;
|
||||||
|
Oid restype;
|
||||||
|
char *querystr;
|
||||||
|
PLpgSQL_rec *rec = NULL;
|
||||||
|
PLpgSQL_row *row = NULL;
|
||||||
|
SPITupleTable *tuptab;
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
int n;
|
||||||
|
HeapTuple typetup;
|
||||||
|
Form_pg_type typeStruct;
|
||||||
|
FmgrInfo finfo_output;
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Initialize the global found variable to false
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
exec_set_found(estate, false);
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Determine if we assign to a record or a row
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
if (stmt->rec != NULL)
|
||||||
|
rec = (PLpgSQL_rec *) (estate->datums[stmt->rec->recno]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (stmt->row != NULL)
|
||||||
|
row = (PLpgSQL_row *) (estate->datums[stmt->row->rowno]);
|
||||||
|
else
|
||||||
|
elog(ERROR, "unsupported target in exec_stmt_fors()");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Evaluate the string expression after the
|
||||||
|
* EXECUTE keyword. It's result is the querystring we have
|
||||||
|
* to execute.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
query = exec_eval_expr(estate, stmt->query, &isnull, &restype);
|
||||||
|
if (isnull)
|
||||||
|
elog(ERROR, "cannot EXECUTE NULL-query");
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Get the C-String representation.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
typetup = SearchSysCacheTuple(TYPEOID,
|
||||||
|
ObjectIdGetDatum(restype), 0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(typetup))
|
||||||
|
elog(ERROR, "cache lookup for type %u failed (1)", restype);
|
||||||
|
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
|
||||||
|
|
||||||
|
fmgr_info(typeStruct->typoutput, &finfo_output);
|
||||||
|
querystr = DatumGetCString(FunctionCall3(&finfo_output,
|
||||||
|
query,
|
||||||
|
ObjectIdGetDatum(typeStruct->typelem),
|
||||||
|
Int32GetDatum(-1)));
|
||||||
|
|
||||||
|
if(!typeStruct->typbyval)
|
||||||
|
pfree((void *)query);
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Run the query
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
if (SPI_exec(querystr, 0) != SPI_OK_SELECT)
|
||||||
|
elog(ERROR, "FOR ... EXECUTE query '%s' was no SELECT", querystr);
|
||||||
|
pfree(querystr);
|
||||||
|
|
||||||
|
n = SPI_processed;
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* If the query didn't return any row, set the target
|
||||||
|
* to NULL and return.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
exec_move_row(estate, rec, row, NULL, NULL);
|
||||||
|
return PLPGSQL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* There are tuples, so set found to true
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
exec_set_found(estate, true);
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Now do the loop
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
tuptab = SPI_tuptable;
|
||||||
|
SPI_tuptable = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
/* ----------
|
||||||
|
* Assign the tuple to the target
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
exec_move_row(estate, rec, row, tuptab->vals[i], tuptab->tupdesc);
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Execute the statements
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
rc = exec_stmts(estate, stmt->body);
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Check returncode
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
switch (rc)
|
||||||
|
{
|
||||||
|
case PLPGSQL_RC_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PLPGSQL_RC_EXIT:
|
||||||
|
if (estate->exitlabel == NULL)
|
||||||
|
return PLPGSQL_RC_OK;
|
||||||
|
if (stmt->label == NULL)
|
||||||
|
return PLPGSQL_RC_EXIT;
|
||||||
|
if (strcmp(stmt->label, estate->exitlabel))
|
||||||
|
return PLPGSQL_RC_EXIT;
|
||||||
|
estate->exitlabel = NULL;
|
||||||
|
return PLPGSQL_RC_OK;
|
||||||
|
|
||||||
|
case PLPGSQL_RC_RETURN:
|
||||||
|
return PLPGSQL_RC_RETURN;
|
||||||
|
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unknown rc %d from exec_stmts()", rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PLPGSQL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* exec_assign_expr Put an expressions result into
|
* exec_assign_expr Put an expressions result into
|
||||||
* a variable.
|
* a variable.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.6 2000/06/14 18:18:00 petere Exp $
|
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.7 2000/08/31 13:26:16 wieck Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -388,6 +388,8 @@ static void dump_exit(PLpgSQL_stmt_exit * stmt);
|
|||||||
static void dump_return(PLpgSQL_stmt_return * stmt);
|
static void dump_return(PLpgSQL_stmt_return * stmt);
|
||||||
static void dump_raise(PLpgSQL_stmt_raise * stmt);
|
static void dump_raise(PLpgSQL_stmt_raise * stmt);
|
||||||
static void dump_execsql(PLpgSQL_stmt_execsql * stmt);
|
static void dump_execsql(PLpgSQL_stmt_execsql * stmt);
|
||||||
|
static void dump_dynexecute(PLpgSQL_stmt_dynexecute * stmt);
|
||||||
|
static void dump_dynfors(PLpgSQL_stmt_dynfors * stmt);
|
||||||
static void dump_expr(PLpgSQL_expr * expr);
|
static void dump_expr(PLpgSQL_expr * expr);
|
||||||
|
|
||||||
|
|
||||||
@ -442,6 +444,12 @@ dump_stmt(PLpgSQL_stmt * stmt)
|
|||||||
case PLPGSQL_STMT_EXECSQL:
|
case PLPGSQL_STMT_EXECSQL:
|
||||||
dump_execsql((PLpgSQL_stmt_execsql *) stmt);
|
dump_execsql((PLpgSQL_stmt_execsql *) stmt);
|
||||||
break;
|
break;
|
||||||
|
case PLPGSQL_STMT_DYNEXECUTE:
|
||||||
|
dump_dynexecute((PLpgSQL_stmt_dynexecute *) stmt);
|
||||||
|
break;
|
||||||
|
case PLPGSQL_STMT_DYNFORS:
|
||||||
|
dump_dynfors((PLpgSQL_stmt_dynfors *) stmt);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "plpgsql_dump: unknown cmd_type %d\n", stmt->cmd_type);
|
elog(ERROR, "plpgsql_dump: unknown cmd_type %d\n", stmt->cmd_type);
|
||||||
break;
|
break;
|
||||||
@ -662,6 +670,34 @@ dump_execsql(PLpgSQL_stmt_execsql * stmt)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_dynexecute(PLpgSQL_stmt_dynexecute * stmt)
|
||||||
|
{
|
||||||
|
dump_ind();
|
||||||
|
printf("EXECUTE ");
|
||||||
|
dump_expr(stmt->query);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_dynfors(PLpgSQL_stmt_dynfors * stmt)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dump_ind();
|
||||||
|
printf("FORS %s EXECUTE ", (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
|
||||||
|
dump_expr(stmt->query);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
dump_indent += 2;
|
||||||
|
for (i = 0; i < stmt->body->stmts_used; i++)
|
||||||
|
dump_stmt((PLpgSQL_stmt *) (stmt->body->stmts[i]));
|
||||||
|
dump_indent -= 2;
|
||||||
|
|
||||||
|
dump_ind();
|
||||||
|
printf(" ENDFORS\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_expr(PLpgSQL_expr * expr)
|
dump_expr(PLpgSQL_expr * expr)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.9 2000/05/28 17:56:28 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.10 2000/08/31 13:26:16 wieck Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -91,7 +91,9 @@ enum
|
|||||||
PLPGSQL_STMT_EXIT,
|
PLPGSQL_STMT_EXIT,
|
||||||
PLPGSQL_STMT_RETURN,
|
PLPGSQL_STMT_RETURN,
|
||||||
PLPGSQL_STMT_RAISE,
|
PLPGSQL_STMT_RAISE,
|
||||||
PLPGSQL_STMT_EXECSQL
|
PLPGSQL_STMT_EXECSQL,
|
||||||
|
PLPGSQL_STMT_DYNEXECUTE,
|
||||||
|
PLPGSQL_STMT_DYNFORS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -318,6 +320,18 @@ typedef struct
|
|||||||
} PLpgSQL_stmt_fors;
|
} PLpgSQL_stmt_fors;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{ /* FOR statement running over EXECUTE */
|
||||||
|
int cmd_type;
|
||||||
|
int lineno;
|
||||||
|
char *label;
|
||||||
|
PLpgSQL_rec *rec;
|
||||||
|
PLpgSQL_row *row;
|
||||||
|
PLpgSQL_expr *query;
|
||||||
|
PLpgSQL_stmts *body;
|
||||||
|
} PLpgSQL_stmt_dynfors;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{ /* SELECT ... INTO statement */
|
{ /* SELECT ... INTO statement */
|
||||||
int cmd_type;
|
int cmd_type;
|
||||||
@ -366,6 +380,14 @@ typedef struct
|
|||||||
} PLpgSQL_stmt_execsql;
|
} PLpgSQL_stmt_execsql;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{ /* Dynamic SQL string to execute */
|
||||||
|
int cmd_type;
|
||||||
|
int lineno;
|
||||||
|
PLpgSQL_expr *query;
|
||||||
|
} PLpgSQL_stmt_dynexecute;
|
||||||
|
|
||||||
|
|
||||||
typedef struct PLpgSQL_function
|
typedef struct PLpgSQL_function
|
||||||
{ /* Complete compiled function */
|
{ /* Complete compiled function */
|
||||||
Oid fn_oid;
|
Oid fn_oid;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.5 2000/08/22 14:59:28 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/Attic/scan.l,v 1.6 2000/08/31 13:26:16 wieck Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -100,6 +100,7 @@ default { return K_DEFAULT; }
|
|||||||
else { return K_ELSE; }
|
else { return K_ELSE; }
|
||||||
end { return K_END; }
|
end { return K_END; }
|
||||||
exception { return K_EXCEPTION; }
|
exception { return K_EXCEPTION; }
|
||||||
|
execute { return K_EXECUTE; }
|
||||||
exit { return K_EXIT; }
|
exit { return K_EXIT; }
|
||||||
for { return K_FOR; }
|
for { return K_FOR; }
|
||||||
from { return K_FROM; }
|
from { return K_FROM; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user