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
1b69b122
Commit
1b69b122
authored
Sep 14, 2002
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Some PL/PgSQL documentation improvements from Neil Conway.
parent
c91b8bc5
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
111 additions
and
63 deletions
+111
-63
doc/src/sgml/plpgsql.sgml
doc/src/sgml/plpgsql.sgml
+111
-63
No files found.
doc/src/sgml/plpgsql.sgml
View file @
1b69b122
<
!--
$
Header
:
/
cvsroot
/
pgsql
/
doc
/
src
/
sgml
/
plpgsql
.
sgml
,
v
1.
6
2002
/
09
/
01
16
:
28
:
05
tgl
Exp
$
$
Header
:
/
cvsroot
/
pgsql
/
doc
/
src
/
sgml
/
plpgsql
.
sgml
,
v
1.
7
2002
/
09
/
14
20
:
11
:
16
tgl
Exp
$
-->
<
chapter
id
=
"plpgsql"
>
...
...
@@ -70,18 +70,19 @@ $Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.6 2002/09/01 16:28:05 tgl
</para>
<para>
As each expression and <acronym>SQL</acronym> query is first used
in the function, the <application>PL/pgSQL</> interpreter creates a
prepared execution plan (using the <acronym>SPI</acronym> manager'
s
<
function
>
SPI_prepare
</
function
>
and
<
function
>
SPI_saveplan
</
function
>
functions
).
Subsequent
visits
to
that
expression
or
query
re
-
use
the
prepared
plan
.
Thus
,
a
function
with
conditional
code
that
contains
many
statements
for
which
execution
plans
might
be
required
,
will
only
prepare
and
save
those
plans
that
are
really
used
during
the
lifetime
of
the
database
connection
.
This
can
provide
a
considerable
savings
of
parsing
activity
.
A
disadvantage
is
that
errors
in
a
specific
expression
or
query
may
not
be
detected
until
that
part
of
the
function
is
reached
in
execution
.
in the function, the <application>PL/pgSQL</> interpreter creates
a prepared execution plan (using the <acronym>SPI</acronym>
manager'
s
<
function
>
SPI_prepare
</
function
>
and
<
function
>
SPI_saveplan
</
function
>
functions
).
Subsequent
visits
to
that
expression
or
query
re
-
use
the
prepared
plan
.
Thus
,
a
function
with
conditional
code
that
contains
many
statements
for
which
execution
plans
might
be
required
will
only
prepare
and
save
those
plans
that
are
really
used
during
the
lifetime
of
the
database
connection
.
This
can
substantially
reduce
the
total
amount
of
time
required
to
parse
,
and
generate
query
plans
for
the
statements
in
a
procedural
language
function
.
A
disadvantage
is
that
errors
in
a
specific
expression
or
query
may
not
be
detected
until
that
part
of
the
function
is
reached
in
execution
.
</
para
>
<
para
>
Once
<
application
>
PL
/
pgSQL
</>
has
made
a
query
plan
for
a
particular
...
...
@@ -110,14 +111,26 @@ END;
</
para
>
<
para
>
Because
<
application
>
PL
/
pgSQL
</
application
>
saves
execution
plans
in
this
way
,
queries
that
appear
directly
in
a
<
application
>
PL
/
pgSQL
</
application
>
function
must
refer
to
the
same
tables
and
fields
on
every
execution
;
that
is
,
you
cannot
use
a
parameter
as
the
name
of
a
table
or
field
in
a
query
.
To
get
around
this
restriction
,
you
can
construct
dynamic
queries
using
the
<
application
>
PL
/
pgSQL
</
application
>
EXECUTE
statement
---
at
the
price
of
constructing
a
new
query
plan
on
every
execution
.
Because
<
application
>
PL
/
pgSQL
</
application
>
saves
execution
plans
in
this
way
,
queries
that
appear
directly
in
a
<
application
>
PL
/
pgSQL
</
application
>
function
must
refer
to
the
same
tables
and
fields
on
every
execution
;
that
is
,
you
cannot
use
a
parameter
as
the
name
of
a
table
or
field
in
a
query
.
To
get
around
this
restriction
,
you
can
construct
dynamic
queries
using
the
<
application
>
PL
/
pgSQL
</
application
>
EXECUTE
statement
---
at
the
price
of
constructing
a
new
query
plan
on
every
execution
.
</
para
>
<
note
>
<
para
>
The
<
application
>
PL
/
pgSQL
</
application
>
EXECUTE
statement
is
not
related
to
the
EXECUTE
statement
supported
by
the
<
productname
>
PostgreSQL
</
productname
>
backend
.
The
backend
EXECUTE
statement
cannot
be
used
within
PL
/
PgSQL
functions
(
and
is
not
needed
).
</
para
>
</
note
>
<
para
>
Except
for
input
/
output
conversion
and
calculation
functions
for
user
defined
types
,
anything
that
can
be
defined
in
C
language
...
...
@@ -152,11 +165,11 @@ END;
<
title
>
Better
Performance
</
title
>
<
para
>
<
acronym
>
SQL
</
acronym
>
is
the
language
<
productname
>
PostgreSQL
</>
(
and
most
other
Relational
Databases
)
use
as
query
language
.
It
's portable and easy to learn. But every
<acronym>SQL</acronym> statement must be executed
individually by the database server.
<
acronym
>
SQL
</
acronym
>
is
the
language
<
productname
>
PostgreSQL
</>
(
and
most
other
relational
databases
)
use
as
query
language
.
It
's portable and easy to learn. But
every
<acronym>SQL</acronym> statement must be executed
individually by the database server.
</para>
<para>
...
...
@@ -195,9 +208,10 @@ END;
<
title
>
Portability
</
title
>
<
para
>
Because
<
application
>
PL
/
pgSQL
</
application
>
functions
run
inside
<
productname
>
PostgreSQL
</>,
these
functions
will
run
on
any
platform
where
<
productname
>
PostgreSQL
</>
runs
.
Thus
you
can
reuse
code
and
have
less
development
costs
.
Because
<
application
>
PL
/
pgSQL
</
application
>
functions
run
inside
<
productname
>
PostgreSQL
</>,
these
functions
will
run
on
any
platform
where
<
productname
>
PostgreSQL
</>
runs
.
Thus
you
can
reuse
code
and
reduce
development
costs
.
</
para
>
</
sect3
>
</
sect2
>
...
...
@@ -227,16 +241,17 @@ END;
</
para
>
<
para
>
One
good
way
to
develop
in
<
application
>
PL
/
pgSQL
</>
is
to
simply
use
the
text
editor
of
your
choice
to
create
your
functions
,
and
in
another
console
,
use
<
command
>
psql
</
command
>
(
PostgreSQL
's interactive monitor) to load
those functions. If you are doing it this way, it is a good
idea to write the function using <command>CREATE OR REPLACE
FUNCTION</command>. That way you can reload the file to update
the function definition. For example:
One
good
way
to
develop
in
<
application
>
PL
/
pgSQL
</>
is
to
simply
use
the
text
editor
of
your
choice
to
create
your
functions
,
and
in
another
window
,
use
<
command
>
psql
</
command
>
(<
productname
>
PostgreSQL
</>
's interactive monitor) to load those
functions. If you are doing it this way, it is a good idea to
write the function using <command>CREATE OR REPLACE
FUNCTION</>. That way you can reload the file to update the
function definition. For example:
<programlisting>
CREATE OR REPLACE FUNCTION testfunc(INTEGER) RETURNS INTEGER AS '
....
....
end
;
' LANGUAGE '
plpgsql
';
</programlisting>
...
...
@@ -645,9 +660,9 @@ RENAME this_var TO that_var;
<
note
>
<
para
>
RENAME
appears
to
be
broken
as
of
PostgreSQL
7.2
.
Fixing
this
is
of
low
priority
,
since
ALIAS
covers
most
of
the
practical
uses
of
RENAME
.
RENAME
appears
to
be
broken
as
of
<
productname
>
PostgreSQL
</>
7.3
.
Fixing
this
is
of
low
priority
,
since
ALIAS
covers
most
of
the
practical
uses
of
RENAME
.
</
para
>
</
note
>
...
...
@@ -898,7 +913,7 @@ END;
PERFORM <replaceable>query</replaceable>;
</synopsis>
This executes a <
literal>SELECT</literal
>
This executes a <
command>SELECT</command
>
<replaceable>query</replaceable> and discards the
result. <application>PL/pgSQL</application> variables are
substituted in the query as usual. Also, the special variable
...
...
@@ -1044,6 +1059,10 @@ END;
<
title
>
Obtaining
result
status
</
title
>
<
para
>
There
are
several
ways
to
determine
the
effect
of
a
command
.
The
first
method
is
to
use
the
<
literal
>
GET
DIAGNOSTICS
</
literal
>,
which
has
the
form
:
<
synopsis
>
GET
DIAGNOSTICS
<
replaceable
>
variable
</
replaceable
>
=
<
replaceable
>
item
</
replaceable
>
<
optional
>
,
...
</
optional
>
;
</
synopsis
>
...
...
@@ -1166,10 +1185,19 @@ RETURN <replaceable>expression</replaceable>;
<para>
When a <application>PL/pgSQL</> function is declared to return
<literal>SETOF</literal> <replaceable>sometype</>, the procedure
to follow is slightly different. The individual items to be returned
are specified in RETURN NEXT commands, and then a final RETURN with
no argument is given to indicate that the function is done generating
items.
to follow is slightly different. In that case, the individual
items to return are specified in RETURN NEXT commands, and then a
final RETURN command with no arguments is used to indicate that
the function has finished executing. RETURN NEXT can be used with
both scalar and composite data types; in the later case, an
entire "table" of results will be returned. Functions that use
RETURN NEXT should be called in the following fashion:
<programlisting>
SELECT * FROM some_func();
</programlisting>
That is, the function is used as a table source in a FROM clause.
<synopsis>
RETURN NEXT <replaceable>expression</replaceable>;
...
...
@@ -1184,6 +1212,24 @@ RETURN NEXT <replaceable>expression</replaceable>;
RETURN, which need have no argument, causes control to exit
the function.
</para>
<note>
<para>
The current implementation of RETURN NEXT for PL/PgSQL stores
the entire result set before returning from the function, as
discussed above. That means that if a PL/PgSQL function
produces a very large result set, performance may be poor: data
will be written to disk to avoid memory exhaustion, but the
function itself will not return until the entire
result set has been generated. A future version of PL/PgSQL may
allow users to allow users to define set-returning functions
that do not have this limitation. Currently, the point at which
data begins being written to disk is controlled by the
<option>SORT_MEM</> configuration variable. Administrators who
have sufficient memory to store larger result sets in memory
should consider increasing this parameter.
</para>
</note>
</sect2>
<sect2 id="plpgsql-conditionals">
...
...
@@ -1904,13 +1950,14 @@ RAISE EXCEPTION ''Inexistent ID --> %'',user_id;
<
title
>
Trigger
Procedures
</
title
>
<
para
>
<
application
>
PL
/
pgSQL
</
application
>
can
be
used
to
define
trigger
procedures
.
A
trigger
procedure
is
created
with
the
<
command
>
CREATE
FUNCTION
</
command
>
command
as
a
function
with
no
arguments
and
a
return
type
of
<
type
>
TRIGGER
</
type
>.
Note
that
the
function
must
be
declared
with
no
arguments
even
if
it
expects
to
receive
arguments
specified
in
<
command
>
CREATE
TRIGGER
</>
---
trigger
arguments
are
passed
via
<
varname
>
TG_ARGV
</>,
as
described
below
.
<
application
>
PL
/
pgSQL
</
application
>
can
be
used
to
define
trigger
procedures
.
A
trigger
procedure
is
created
with
the
<
command
>
CREATE
FUNCTION
</>
command
as
a
function
with
no
arguments
and
a
return
type
of
<
type
>
TRIGGER
</
type
>.
Note
that
the
function
must
be
declared
with
no
arguments
even
if
it
expects
to
receive
arguments
specified
in
<
command
>
CREATE
TRIGGER
</>
---
trigger
arguments
are
passed
via
<
varname
>
TG_ARGV
</>,
as
described
below
.
</
para
>
<
para
>
...
...
@@ -2106,14 +2153,15 @@ CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
</para>
<para>
One painful detail in writing functions in <application>PL/pgSQL</application> is the handling
of single quotes. The function'
s
source
text
in
<
command
>
CREATE
FUNCTION
</
command
>
must
be
a
literal
string
.
Single
quotes
inside
of
literal
strings
must
be
either
doubled
or
quoted
with
a
backslash
.
We
are
still
looking
for
an
elegant
alternative
.
In
the
meantime
,
doubling
the
single
quotes
as
in
the
examples
below
should
be
used
.
Any
solution
for
this
in
future
versions
of
<
productname
>
PostgreSQL
</
productname
>
will
be
forward
compatible
.
One painful detail in writing functions in
<application>PL/pgSQL</application> is the handling of single
quotes. The function'
s
source
text
in
<
command
>
CREATE
FUNCTION
</>
must
be
a
literal
string
.
Single
quotes
inside
of
literal
strings
must
be
either
doubled
or
quoted
with
a
backslash
.
We
are
still
looking
for
an
elegant
alternative
.
In
the
meantime
,
doubling
the
single
quotes
as
in
the
examples
below
should
be
used
.
Any
solution
for
this
in
future
versions
of
<
productname
>
PostgreSQL
</
productname
>
will
be
forward
compatible
.
</
para
>
<
para
>
...
...
@@ -2504,7 +2552,7 @@ END;
<para>
The following procedure grabs rows from a
<
literal>SELECT</literal
> statement and builds a large function
<
command>SELECT</command
> statement and builds a large function
with the results in <literal>IF</literal> statements, for the
sake of efficiency. Notice particularly the differences in
cursors, <literal>FOR</literal> loops, and the need to escape
...
...
@@ -2735,7 +2783,7 @@ show errors
<
callout
arearefs
=
"co.plpgsql-porting-locktable"
>
<
para
>
If
you
do
a
<
literal
>
LOCK
TABLE
</
literal
>
in
<
application
>
PL
/
pgSQL
</>,
the
lock
If
you
do
a
<
command
>
LOCK
TABLE
</
command
>
in
<
application
>
PL
/
pgSQL
</>,
the
lock
will
not
be
released
until
the
calling
transaction
is
finished
.
</
para
>
</
callout
>
...
...
@@ -2746,7 +2794,7 @@ show errors
entire
function
(
and
other
functions
called
from
therein
)
is
executed
in
a
transaction
and
<
productname
>
PostgreSQL
</>
rolls
back
the
results
if
something
goes
wrong
.
Therefore
only
one
<
literal
>
BEGIN
</
literal
>
statement
is
allowed
.
<
command
>
BEGIN
</
command
>
statement
is
allowed
.
</
para
>
</
callout
>
...
...
@@ -2895,7 +2943,7 @@ END;
<
title
>
EXECUTE
</
title
>
<
para
>
The
<
productname
>
PostgreSQL
</>
version
of
<
literal
>
EXECUTE
</
literal
>
works
The
<
productname
>
PostgreSQL
</>
version
of
<
command
>
EXECUTE
</
command
>
works
nicely
,
but
you
have
to
remember
to
use
<
function
>
quote_literal
(
TEXT
)</
function
>
and
<
function
>
quote_string
(
TEXT
)</
function
>
as
described
in
<
xref
...
...
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