Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
d4266620
Commit
d4266620
authored
Aug 31, 2000
by
Jan Wieck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added EXECUTE command to PL/pgSQL for execution of
dynamic SQL and utility statements. Jan
parent
16dc9baf
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
368 additions
and
9 deletions
+368
-9
src/pl/plpgsql/src/gram.y
src/pl/plpgsql/src/gram.y
+49
-1
src/pl/plpgsql/src/pl_comp.c
src/pl/plpgsql/src/pl_comp.c
+3
-3
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/pl_exec.c
+253
-1
src/pl/plpgsql/src/pl_funcs.c
src/pl/plpgsql/src/pl_funcs.c
+37
-1
src/pl/plpgsql/src/plpgsql.h
src/pl/plpgsql/src/plpgsql.h
+24
-2
src/pl/plpgsql/src/scan.l
src/pl/plpgsql/src/scan.l
+2
-1
No files found.
src/pl/plpgsql/src/gram.y
View file @
d4266620
...
...
@@ -4,7 +4,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.1
0 2000/06/05 07:29:14 tgl
Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.1
1 2000/08/31 13:26:15 wieck
Exp $
*
* 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_return, stmt_raise, stmt_execsql, stmt_fori
%type <stmt> stmt_fors, stmt_select, stmt_perform
%type <stmt> stmt_dynexecute, stmt_dynfors
%type <dtlist> raise_params
%type <ival> raise_level, raise_param
...
...
@@ -134,6 +135,7 @@ static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row);
%token K_ELSE
%token K_END
%token K_EXCEPTION
%token K_EXECUTE
%token K_EXIT
%token K_FOR
%token K_FROM
...
...
@@ -568,6 +570,10 @@ proc_stmt : pl_block
{ $$ = $1; }
| stmt_execsql
{ $$ = $1; }
| stmt_dynexecute
{ $$ = $1; }
| stmt_dynfors
{ $$ = $1; }
| stmt_perform
{ $$ = $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;
}
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
{
$$ = 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
{ $$ = strdup(yytext); }
| T_ERROR
...
...
src/pl/plpgsql/src/pl_comp.c
View file @
d4266620
...
...
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.2
2 2000/08/03 16:34:57 tgl
Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.2
3 2000/08/31 13:26:16 wieck
Exp $
*
* 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_oid
=
fn_oid
;
function
->
fn_name
=
DatumGetCString
(
DirectFunctionCall1
(
nameout
,
NameGetDatum
(
&
(
procStruct
->
proname
))));
function
->
fn_name
=
strdup
(
DatumGetCString
(
DirectFunctionCall1
(
nameout
,
NameGetDatum
(
&
(
procStruct
->
proname
))))
)
;
switch
(
functype
)
{
...
...
src/pl/plpgsql/src/pl_exec.c
View file @
d4266620
...
...
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.2
8 2000/08/24 03:29:15 tgl
Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.2
9 2000/08/31 13:26:16 wieck
Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
...
...
@@ -100,6 +100,10 @@ static int exec_stmt_raise(PLpgSQL_execstate * estate,
PLpgSQL_stmt_raise
*
stmt
);
static
int
exec_stmt_execsql
(
PLpgSQL_execstate
*
estate
,
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
,
PLpgSQL_expr
*
expr
);
...
...
@@ -219,6 +223,12 @@ plpgsql_exec_function(PLpgSQL_function * func, FunctionCallInfo fcinfo)
case
PLPGSQL_STMT_EXECSQL
:
stmttype
=
"SQL statement"
;
break
;
case
PLPGSQL_STMT_DYNEXECUTE
:
stmttype
=
"execute statement"
;
break
;
case
PLPGSQL_STMT_DYNFORS
:
stmttype
=
"for over execute statement"
;
break
;
default:
stmttype
=
"unknown"
;
break
;
...
...
@@ -522,6 +532,12 @@ plpgsql_exec_trigger(PLpgSQL_function * func,
case
PLPGSQL_STMT_EXECSQL
:
stmttype
=
"SQL statement"
;
break
;
case
PLPGSQL_STMT_DYNEXECUTE
:
stmttype
=
"execute statement"
;
break
;
case
PLPGSQL_STMT_DYNFORS
:
stmttype
=
"for over execute statement"
;
break
;
default:
stmttype
=
"unknown"
;
break
;
...
...
@@ -995,6 +1011,14 @@ exec_stmt(PLpgSQL_execstate * estate, PLpgSQL_stmt * stmt)
rc
=
exec_stmt_execsql
(
estate
,
(
PLpgSQL_stmt_execsql
*
)
stmt
);
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:
error_info_stmt
=
save_estmt
;
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
* a variable.
...
...
src/pl/plpgsql/src/pl_funcs.c
View file @
d4266620
...
...
@@ -3,7 +3,7 @@
* procedural language
*
* 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.
*
...
...
@@ -388,6 +388,8 @@ static void dump_exit(PLpgSQL_stmt_exit * stmt);
static
void
dump_return
(
PLpgSQL_stmt_return
*
stmt
);
static
void
dump_raise
(
PLpgSQL_stmt_raise
*
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
);
...
...
@@ -442,6 +444,12 @@ dump_stmt(PLpgSQL_stmt * stmt)
case
PLPGSQL_STMT_EXECSQL
:
dump_execsql
((
PLpgSQL_stmt_execsql
*
)
stmt
);
break
;
case
PLPGSQL_STMT_DYNEXECUTE
:
dump_dynexecute
((
PLpgSQL_stmt_dynexecute
*
)
stmt
);
break
;
case
PLPGSQL_STMT_DYNFORS
:
dump_dynfors
((
PLpgSQL_stmt_dynfors
*
)
stmt
);
break
;
default:
elog
(
ERROR
,
"plpgsql_dump: unknown cmd_type %d
\n
"
,
stmt
->
cmd_type
);
break
;
...
...
@@ -662,6 +670,34 @@ dump_execsql(PLpgSQL_stmt_execsql * stmt)
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
dump_expr
(
PLpgSQL_expr
*
expr
)
{
...
...
src/pl/plpgsql/src/plpgsql.h
View file @
d4266620
...
...
@@ -3,7 +3,7 @@
* procedural language
*
* 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.
*
...
...
@@ -91,7 +91,9 @@ enum
PLPGSQL_STMT_EXIT
,
PLPGSQL_STMT_RETURN
,
PLPGSQL_STMT_RAISE
,
PLPGSQL_STMT_EXECSQL
PLPGSQL_STMT_EXECSQL
,
PLPGSQL_STMT_DYNEXECUTE
,
PLPGSQL_STMT_DYNFORS
};
...
...
@@ -318,6 +320,18 @@ typedef struct
}
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
{
/* SELECT ... INTO statement */
int
cmd_type
;
...
...
@@ -366,6 +380,14 @@ typedef struct
}
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
{
/* Complete compiled function */
Oid
fn_oid
;
...
...
src/pl/plpgsql/src/scan.l
View file @
d4266620
...
...
@@ -4,7 +4,7 @@
* procedural language
*
* 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.
*
...
...
@@ -100,6 +100,7 @@ default { return K_DEFAULT; }
else { return K_ELSE; }
end { return K_END; }
exception { return K_EXCEPTION; }
execute { return K_EXECUTE; }
exit { return K_EXIT; }
for { return K_FOR; }
from { return K_FROM; }
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment