1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-20 15:22:23 +03:00

Redesign the plancache mechanism for more flexibility and efficiency.

Rewrite plancache.c so that a "cached plan" (which is rather a misnomer
at this point) can support generation of custom, parameter-value-dependent
plans, and can make an intelligent choice between using custom plans and
the traditional generic-plan approach.  The specific choice algorithm
implemented here can probably be improved in future, but this commit is
all about getting the mechanism in place, not the policy.

In addition, restructure the API to greatly reduce the amount of extraneous
data copying needed.  The main compromise needed to make that possible was
to split the initial creation of a CachedPlanSource into two steps.  It's
worth noting in particular that SPI_saveplan is now deprecated in favor of
SPI_keepplan, which accomplishes the same end result with zero data
copying, and no need to then spend even more cycles throwing away the
original SPIPlan.  The risk of long-term memory leaks while manipulating
SPIPlans has also been greatly reduced.  Most of this improvement is based
on use of the recently-added MemoryContextSetParent primitive.
This commit is contained in:
Tom Lane
2011-09-16 00:42:53 -04:00
parent 09e98a3e17
commit e6faf910d7
27 changed files with 1994 additions and 1424 deletions

View File

@ -839,12 +839,10 @@ PREPARE <replaceable>statement_name</>(integer, integer) AS SELECT $1 &lt; $2;
and then this prepared statement is <command>EXECUTE</>d for each
execution of the <command>IF</> statement, with the current values
of the <application>PL/pgSQL</application> variables supplied as
parameter values.
The query plan prepared in this way is saved for the life of the database
connection, as described in
<xref linkend="plpgsql-plan-caching">. Normally these details are
parameter values. Normally these details are
not important to a <application>PL/pgSQL</application> user, but
they are useful to know when trying to diagnose a problem.
More information appears in <xref linkend="plpgsql-plan-caching">.
</para>
</sect1>
@ -919,10 +917,9 @@ my_record.user_id := 20;
<para>
When executing a SQL command in this way,
<application>PL/pgSQL</application> plans the command just once
and re-uses the plan on subsequent executions, for the life of
the database connection. The implications of this are discussed
in detail in <xref linkend="plpgsql-plan-caching">.
<application>PL/pgSQL</application> may cache and re-use the execution
plan for the command, as discussed in
<xref linkend="plpgsql-plan-caching">.
</para>
<para>
@ -1137,8 +1134,8 @@ EXECUTE <replaceable class="command">command-string</replaceable> <optional> INT
<para>
Also, there is no plan caching for commands executed via
<command>EXECUTE</command>. Instead, the
command is prepared each time the statement is run. Thus the command
<command>EXECUTE</command>. Instead, the command is always planned
each time the statement is run. Thus the command
string can be dynamically created within the function to perform
actions on different tables and columns.
</para>
@ -1206,11 +1203,11 @@ EXECUTE 'SELECT count(*) FROM '
The important difference is that <command>EXECUTE</> will re-plan
the command on each execution, generating a plan that is specific
to the current parameter values; whereas
<application>PL/pgSQL</application> normally creates a generic plan
and caches it for re-use. In situations where the best plan depends
strongly on the parameter values, <command>EXECUTE</> can be
significantly faster; while when the plan is not sensitive to parameter
values, re-planning will be a waste.
<application>PL/pgSQL</application> may otherwise create a generic plan
and cache it for re-use. In situations where the best plan depends
strongly on the parameter values, it can be helpful to use
<command>EXECUTE</> to positively ensure that a generic plan is not
selected.
</para>
<para>
@ -4103,17 +4100,14 @@ $$ LANGUAGE plpgsql;
</indexterm>
As each expression and <acronym>SQL</acronym> command is first
executed 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).
parses and analyzes the command to create a prepared statement,
using the <acronym>SPI</acronym> manager's
<function>SPI_prepare</function> function.
Subsequent visits to that expression or command
reuse 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 execution plans for the statements in a
<application>PL/pgSQL</> function. A disadvantage is that errors
reuse the prepared statement. Thus, a function with conditional code
paths that are seldom visited will never incur the overhead of
analyzing those commands that are never executed within the current
session. A disadvantage is that errors
in a specific expression or command cannot be detected until that
part of the function is reached in execution. (Trivial syntax
errors will be detected during the initial parsing pass, but
@ -4121,46 +4115,31 @@ $$ LANGUAGE plpgsql;
</para>
<para>
A saved plan will be re-planned automatically if there is any schema
change to any table used in the query, or if any user-defined function
used in the query is redefined. This makes the re-use of prepared plans
transparent in most cases, but there are corner cases where a stale plan
might be re-used. An example is that dropping and re-creating a
user-defined operator won't affect already-cached plans; they'll continue
to call the original operator's underlying function, if that has not been
changed. When necessary, the cache can be flushed by starting a fresh
database session.
<application>PL/pgSQL</> (or more precisely, the SPI manager) can
furthermore attempt to cache the execution plan associated with any
particular prepared statement. If a cached plan is not used, then
a fresh execution plan is generated on each visit to the statement,
and the current parameter values (that is, <application>PL/pgSQL</>
variable values) can be used to optimize the selected plan. If the
statement has no parameters, or is executed many times, the SPI manager
will consider creating a <firstterm>generic</> plan that is not dependent
on specific parameter values, and caching that for re-use. Typically
this will happen only if the execution plan is not very sensitive to
the values of the <application>PL/pgSQL</> variables referenced in it.
If it is, generating a plan each time is a net win.
</para>
<para>
Because <application>PL/pgSQL</application> saves execution plans
in this way, SQL commands that appear directly in a
Because <application>PL/pgSQL</application> saves prepared statements
and sometimes execution plans in this way,
SQL commands that appear directly in a
<application>PL/pgSQL</application> function must refer to the
same tables and columns on every execution; that is, you cannot use
a parameter as the name of a table or column in an SQL command. To get
around this restriction, you can construct dynamic commands using
the <application>PL/pgSQL</application> <command>EXECUTE</command>
statement &mdash; at the price of constructing a new execution plan on
every execution.
</para>
<para>
Another important point is that the prepared plans are parameterized
to allow the values of <application>PL/pgSQL</application> variables
to change from one use to the next, as discussed in detail above.
Sometimes this means that a plan is less efficient than it would be
if generated for a specific variable value. As an example, consider
<programlisting>
SELECT * INTO myrec FROM dictionary WHERE word LIKE search_term;
</programlisting>
where <literal>search_term</> is a <application>PL/pgSQL</application>
variable. The cached plan for this query will never use an index on
<structfield>word</>, since the planner cannot assume that the
<literal>LIKE</> pattern will be left-anchored at run time. To use
an index the query must be planned with a specific constant
<literal>LIKE</> pattern provided. This is another situation where
<command>EXECUTE</command> can be used to force a new plan to be
generated for each execution.
statement &mdash; at the price of performing new parse analysis and
constructing a new execution plan on every execution.
</para>
<para>
@ -4168,14 +4147,14 @@ SELECT * INTO myrec FROM dictionary WHERE word LIKE search_term;
connection. When fields of a record variable are used in
expressions or statements, the data types of the fields must not
change from one call of the function to the next, since each
expression will be planned using the data type that is present
expression will be analyzed using the data type that is present
when the expression is first reached. <command>EXECUTE</command> can be
used to get around this problem when necessary.
</para>
<para>
If the same function is used as a trigger for more than one table,
<application>PL/pgSQL</application> prepares and caches plans
<application>PL/pgSQL</application> prepares and caches statements
independently for each such table &mdash; that is, there is a cache
for each trigger function and table combination, not just for each
function. This alleviates some of the problems with varying
@ -4186,14 +4165,14 @@ SELECT * INTO myrec FROM dictionary WHERE word LIKE search_term;
<para>
Likewise, functions having polymorphic argument types have a separate
plan cache for each combination of actual argument types they have been
invoked for, so that data type differences do not cause unexpected
statement cache for each combination of actual argument types they have
been invoked for, so that data type differences do not cause unexpected
failures.
</para>
<para>
Plan caching can sometimes have surprising effects on the interpretation
of time-sensitive values. For example there
Statement caching can sometimes have surprising effects on the
interpretation of time-sensitive values. For example there
is a difference between what these two functions do:
<programlisting>
@ -4221,15 +4200,17 @@ $$ LANGUAGE plpgsql;
<para>
In the case of <function>logfunc1</function>, the
<productname>PostgreSQL</productname> main parser knows when
preparing the plan for the <command>INSERT</command> that the
analyzing the <command>INSERT</command> that the
string <literal>'now'</literal> should be interpreted as
<type>timestamp</type>, because the target column of
<classname>logtable</classname> is of that type. Thus,
<literal>'now'</literal> will be converted to a constant when the
<command>INSERT</command> is planned, and then used in all
<literal>'now'</literal> will be converted to a <type>timestamp</type>
constant when the
<command>INSERT</command> is analyzed, and then used in all
invocations of <function>logfunc1</function> during the lifetime
of the session. Needless to say, this isn't what the programmer
wanted.
wanted. A better idea is to use the <literal>now()</> or
<literal>current_timestamp</> function.
</para>
<para>
@ -4243,7 +4224,9 @@ $$ LANGUAGE plpgsql;
string to the <type>timestamp</type> type by calling the
<function>text_out</function> and <function>timestamp_in</function>
functions for the conversion. So, the computed time stamp is updated
on each execution as the programmer expects.
on each execution as the programmer expects. Even though this
happens to work as expected, it's not terribly efficient, so
use of the <literal>now()</> function would still be a better idea.
</para>
</sect2>

View File

@ -125,9 +125,8 @@
into multiple steps. The state retained between steps is represented
by two types of objects: <firstterm>prepared statements</> and
<firstterm>portals</>. A prepared statement represents the result of
parsing, semantic analysis, and (optionally) planning of a textual query
string.
A prepared statement is not necessarily ready to execute, because it might
parsing and semantic analysis of a textual query string.
A prepared statement is not in itself ready to execute, because it might
lack specific values for <firstterm>parameters</>. A portal represents
a ready-to-execute or already-partially-executed statement, with any
missing parameter values filled in. (For <command>SELECT</> statements,
@ -692,7 +691,7 @@
the unnamed statement as destination is issued. (Note that a simple
Query message also destroys the unnamed statement.) Named prepared
statements must be explicitly closed before they can be redefined by
a Parse message, but this is not required for the unnamed statement.
another Parse message, but this is not required for the unnamed statement.
Named prepared statements can also be created and accessed at the SQL
command level, using <command>PREPARE</> and <command>EXECUTE</>.
</para>
@ -722,44 +721,23 @@
</note>
<para>
Query planning for named prepared-statement objects occurs when the Parse
message is processed. If a query will be repeatedly executed with
different parameters, it might be beneficial to send a single Parse message
containing a parameterized query, followed by multiple Bind
and Execute messages. This will avoid replanning the query on each
execution.
Query planning typically occurs when the Bind message is processed.
If the prepared statement has no parameters, or is executed repeatedly,
the server might save the created plan and re-use it during subsequent
Bind messages for the same prepared statement. However, it will do so
only if it finds that a generic plan can be created that is not much
less efficient than a plan that depends on the specific parameter values
supplied. This happens transparently so far as the protocol is concerned.
</para>
<para>
The unnamed prepared statement is likewise planned during Parse processing
if the Parse message defines no parameters. But if there are parameters,
query planning occurs every time Bind parameters are supplied. This allows the
planner to make use of the actual values of the parameters provided by
each Bind message, rather than use generic estimates.
</para>
<note>
<para>
Query plans generated from a parameterized query might be less
efficient than query plans generated from an equivalent query with actual
parameter values substituted. The query planner cannot make decisions
based on actual parameter values (for example, index selectivity) when
planning a parameterized query assigned to a named prepared-statement
object. This possible penalty is avoided when using the unnamed
statement, since it is not planned until actual parameter values are
available. The cost is that planning must occur afresh for each Bind,
even if the query stays the same.
</para>
</note>
<para>
If successfully created, a named portal object lasts till the end of the
current transaction, unless explicitly destroyed. An unnamed portal is
destroyed at the end of the transaction, or as soon as the next Bind
statement specifying the unnamed portal as destination is issued. (Note
that a simple Query message also destroys the unnamed portal.) Named
portals must be explicitly closed before they can be redefined by a Bind
message, but this is not required for the unnamed portal.
portals must be explicitly closed before they can be redefined by another
Bind message, but this is not required for the unnamed portal.
Named portals can also be created and accessed at the SQL
command level, using <command>DECLARE CURSOR</> and <command>FETCH</>.
</para>
@ -1280,7 +1258,9 @@
The frontend should also be prepared to handle an ErrorMessage
response to SSLRequest from the server. This would only occur if
the server predates the addition of <acronym>SSL</acronym> support
to <productname>PostgreSQL</>. In this case the connection must
to <productname>PostgreSQL</>. (Such servers are now very ancient,
and likely do not exist in the wild anymore.)
In this case the connection must
be closed, but the frontend might choose to open a fresh connection
and proceed without requesting <acronym>SSL</acronym>.
</para>

View File

@ -37,11 +37,11 @@ PREPARE <replaceable class="PARAMETER">name</replaceable> [ ( <replaceable class
<command>PREPARE</command> creates a prepared statement. A prepared
statement is a server-side object that can be used to optimize
performance. When the <command>PREPARE</command> statement is
executed, the specified statement is parsed, rewritten, and
planned. When an <command>EXECUTE</command> command is subsequently
issued, the prepared statement need only be executed. Thus, the
parsing, rewriting, and planning stages are only performed once,
instead of every time the statement is executed.
executed, the specified statement is parsed, analyzed, and rewritten.
When an <command>EXECUTE</command> command is subsequently
issued, the prepared statement is planned and executed. This division
of labor avoids repetitive parse analysis work, while allowing
the execution plan to depend on the specific parameter values supplied.
</para>
<para>
@ -65,7 +65,7 @@ PREPARE <replaceable class="PARAMETER">name</replaceable> [ ( <replaceable class
forgotten, so it must be recreated before being used again. This
also means that a single prepared statement cannot be used by
multiple simultaneous database clients; however, each client can create
their own prepared statement to use. The prepared statement can be
their own prepared statement to use. Prepared statements can be
manually cleaned up using the <xref linkend="sql-deallocate"> command.
</para>
@ -127,20 +127,22 @@ PREPARE <replaceable class="PARAMETER">name</replaceable> [ ( <replaceable class
<title>Notes</title>
<para>
In some situations, the query plan produced for a prepared
statement will be inferior to the query plan that would have been
chosen if the statement had been submitted and executed
normally. This is because when the statement is planned and the
planner attempts to determine the optimal query plan, the actual
values of any parameters specified in the statement are
unavailable. <productname>PostgreSQL</productname> collects
statistics on the distribution of data in the table, and can use
constant values in a statement to make guesses about the likely
result of executing the statement. Since this data is unavailable
when planning prepared statements with parameters, the chosen plan
might be suboptimal. To examine the query plan
<productname>PostgreSQL</productname> has chosen for a prepared
statement, use <xref linkend="sql-explain">.
If a prepared statement is executed enough times, the server may eventually
decide to save and re-use a generic plan rather than re-planning each time.
This will occur immediately if the prepared statement has no parameters;
otherwise it occurs only if the generic plan appears to be not much more
expensive than a plan that depends on specific parameter values.
Typically, a generic plan will be selected only if the query's performance
is estimated to be fairly insensitive to the specific parameter values
supplied.
</para>
<para>
To examine the query plan <productname>PostgreSQL</productname> is using
for a prepared statement, use <xref linkend="sql-explain">.
If a generic plan is in use, it will contain parameter symbols
<literal>$<replaceable>n</></literal>, while a custom plan will have the
current actual parameter values substituted into it.
</para>
<para>
@ -151,7 +153,7 @@ PREPARE <replaceable class="PARAMETER">name</replaceable> [ ( <replaceable class
</para>
<para>
You can see all available prepared statements of a session by querying the
You can see all prepared statements available in the session by querying the
<link linkend="view-pg-prepared-statements"><structname>pg_prepared_statements</structname></link>
system view.
</para>

View File

@ -733,7 +733,8 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>,
<para>
Similar results can be achieved with <function>SPI_prepare</> followed by
<function>SPI_execute_plan</function>; however, when using this function
the query plan is customized to the specific parameter values provided.
the query plan is always customized to the specific parameter values
provided.
For one-time query execution, this function should be preferred.
If the same command is to be executed with many different parameters,
either method might be faster, depending on the cost of re-planning
@ -840,7 +841,7 @@ int SPI_execute_with_args(const char *<parameter>command</parameter>,
<refnamediv>
<refname>SPI_prepare</refname>
<refpurpose>prepare a plan for a command, without executing it yet</refpurpose>
<refpurpose>prepare a statement, without executing it yet</refpurpose>
</refnamediv>
<indexterm><primary>SPI_prepare</primary></indexterm>
@ -855,17 +856,22 @@ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <paramet
<title>Description</title>
<para>
<function>SPI_prepare</function> creates and returns an execution
plan for the specified command, but doesn't execute the command.
This function should only be called from a connected procedure.
<function>SPI_prepare</function> creates and returns a prepared
statement for the specified command, but doesn't execute the command.
The prepared statement can later be executed repeatedly using
<function>SPI_execute_plan</function>.
</para>
<para>
When the same or a similar command is to be executed repeatedly, it
might be advantageous to perform the planning only once.
<function>SPI_prepare</function> converts a command string into an
execution plan that can be executed repeatedly using
<function>SPI_execute_plan</function>.
is generally advantageous to perform parse analysis only once, and
might furthermore be advantageous to re-use an execution plan for the
command.
<function>SPI_prepare</function> converts a command string into a
prepared statement that encapsulates the results of parse analysis.
The prepared statement also provides a place for caching an execution plan
if it is found that generating a custom plan for each execution is not
helpful.
</para>
<para>
@ -878,11 +884,11 @@ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <paramet
</para>
<para>
The plan returned by <function>SPI_prepare</function> can be used
The statement returned by <function>SPI_prepare</function> can be used
only in the current invocation of the procedure, since
<function>SPI_finish</function> frees memory allocated for a plan.
But a plan can be saved for longer using the function
<function>SPI_saveplan</function>.
<function>SPI_finish</function> frees memory allocated for such a
statement. But the statement can be saved for longer using the functions
<function>SPI_keepplan</function> or <function>SPI_saveplan</function>.
</para>
</refsect1>
@ -925,7 +931,8 @@ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <paramet
<para>
<function>SPI_prepare</function> returns a non-null pointer to an
execution plan. On error, <symbol>NULL</symbol> will be returned,
<type>SPIPlan</>, which is an opaque struct representing a prepared
statement. On error, <symbol>NULL</symbol> will be returned,
and <varname>SPI_result</varname> will be set to one of the same
error codes used by <function>SPI_execute</function>, except that
it is set to <symbol>SPI_ERROR_ARGUMENT</symbol> if
@ -938,6 +945,26 @@ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <paramet
<refsect1>
<title>Notes</title>
<para>
If no parameters are defined, a generic plan will be created at the
first use of <function>SPI_execute_plan</function>, and used for all
subsequent executions as well. If there are parameters, the first few uses
of <function>SPI_execute_plan</function> will generate custom plans
that are specific to the supplied parameter values. After enough uses
of the same prepared statement, <function>SPI_execute_plan</function> will
build a generic plan, and if that is not too much more expensive than the
custom plans, it will start using the generic plan instead of re-planning
each time. If this default behavior is unsuitable, you can alter it by
passing the <literal>CURSOR_OPT_GENERIC_PLAN</> or
<literal>CURSOR_OPT_CUSTOM_PLAN</> flag to
<function>SPI_prepare_cursor</function>, to force use of generic or custom
plans respectively.
</para>
<para>
This function should only be called from a connected procedure.
</para>
<para>
<type>SPIPlanPtr</> is declared as a pointer to an opaque struct type in
<filename>spi.h</>. It is unwise to try to access its contents
@ -946,10 +973,8 @@ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <paramet
</para>
<para>
There is a disadvantage to using parameters: since the planner does
not know the values that will be supplied for the parameters, it
might make worse planning choices than it would make for a normal
command with all constants visible.
The name <type>SPIPlanPtr</> is somewhat historical, since the data
structure no longer necessarily contains an execution plan.
</para>
</refsect1>
</refentry>
@ -964,7 +989,7 @@ SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <paramet
<refnamediv>
<refname>SPI_prepare_cursor</refname>
<refpurpose>prepare a plan for a command, without executing it yet</refpurpose>
<refpurpose>prepare a statement, without executing it yet</refpurpose>
</refnamediv>
<indexterm><primary>SPI_prepare_cursor</primary></indexterm>
@ -1047,8 +1072,10 @@ SPIPlanPtr SPI_prepare_cursor(const char * <parameter>command</parameter>, int <
<para>
Useful bits to set in <parameter>cursorOptions</> include
<symbol>CURSOR_OPT_SCROLL</symbol>,
<symbol>CURSOR_OPT_NO_SCROLL</symbol>, and
<symbol>CURSOR_OPT_FAST_PLAN</symbol>. Note in particular that
<symbol>CURSOR_OPT_NO_SCROLL</symbol>,
<symbol>CURSOR_OPT_FAST_PLAN</symbol>,
<symbol>CURSOR_OPT_GENERIC_PLAN</symbol>, and
<symbol>CURSOR_OPT_CUSTOM_PLAN</symbol>. Note in particular that
<symbol>CURSOR_OPT_HOLD</symbol> is ignored.
</para>
</refsect1>
@ -1064,7 +1091,7 @@ SPIPlanPtr SPI_prepare_cursor(const char * <parameter>command</parameter>, int <
<refnamediv>
<refname>SPI_prepare_params</refname>
<refpurpose>prepare a plan for a command, without executing it yet</refpurpose>
<refpurpose>prepare a statement, without executing it yet</refpurpose>
</refnamediv>
<indexterm><primary>SPI_prepare_params</primary></indexterm>
@ -1082,8 +1109,8 @@ SPIPlanPtr SPI_prepare_params(const char * <parameter>command</parameter>,
<title>Description</title>
<para>
<function>SPI_prepare_params</function> creates and returns an execution
plan for the specified command, but doesn't execute the command.
<function>SPI_prepare_params</function> creates and returns a prepared
statement for the specified command, but doesn't execute the command.
This function is equivalent to <function>SPI_prepare_cursor</function>,
with the addition that the caller can specify parser hook functions
to control the parsing of external parameter references.
@ -1152,7 +1179,7 @@ SPIPlanPtr SPI_prepare_params(const char * <parameter>command</parameter>,
<refnamediv>
<refname>SPI_getargcount</refname>
<refpurpose>return the number of arguments needed by a plan
<refpurpose>return the number of arguments needed by a statement
prepared by <function>SPI_prepare</function></refpurpose>
</refnamediv>
@ -1169,7 +1196,7 @@ int SPI_getargcount(SPIPlanPtr <parameter>plan</parameter>)
<para>
<function>SPI_getargcount</function> returns the number of arguments needed
to execute a plan prepared by <function>SPI_prepare</function>.
to execute a statement prepared by <function>SPI_prepare</function>.
</para>
</refsect1>
@ -1181,7 +1208,7 @@ int SPI_getargcount(SPIPlanPtr <parameter>plan</parameter>)
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -1210,7 +1237,7 @@ int SPI_getargcount(SPIPlanPtr <parameter>plan</parameter>)
<refnamediv>
<refname>SPI_getargtypeid</refname>
<refpurpose>return the data type OID for an argument of
a plan prepared by <function>SPI_prepare</function></refpurpose>
a statement prepared by <function>SPI_prepare</function></refpurpose>
</refnamediv>
<indexterm><primary>SPI_getargtypeid</primary></indexterm>
@ -1226,7 +1253,7 @@ Oid SPI_getargtypeid(SPIPlanPtr <parameter>plan</parameter>, int <parameter>argI
<para>
<function>SPI_getargtypeid</function> returns the OID representing the type
for the <parameter>argIndex</parameter>'th argument of a plan prepared by
for the <parameter>argIndex</parameter>'th argument of a statement prepared by
<function>SPI_prepare</function>. First argument is at index zero.
</para>
</refsect1>
@ -1239,7 +1266,7 @@ Oid SPI_getargtypeid(SPIPlanPtr <parameter>plan</parameter>, int <parameter>argI
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -1279,7 +1306,7 @@ Oid SPI_getargtypeid(SPIPlanPtr <parameter>plan</parameter>, int <parameter>argI
<refnamediv>
<refname>SPI_is_cursor_plan</refname>
<refpurpose>return <symbol>true</symbol> if a plan
<refpurpose>return <symbol>true</symbol> if a statement
prepared by <function>SPI_prepare</function> can be used with
<function>SPI_cursor_open</function></refpurpose>
</refnamediv>
@ -1297,7 +1324,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>)
<para>
<function>SPI_is_cursor_plan</function> returns <symbol>true</symbol>
if a plan prepared by <function>SPI_prepare</function> can be passed
if a statement prepared by <function>SPI_prepare</function> can be passed
as an argument to <function>SPI_cursor_open</function>, or
<symbol>false</symbol> if that is not the case. The criteria are that the
<parameter>plan</parameter> represents one single command and that this
@ -1316,7 +1343,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>)
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -1348,7 +1375,7 @@ bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>)
<refnamediv>
<refname>SPI_execute_plan</refname>
<refpurpose>execute a plan prepared by <function>SPI_prepare</function></refpurpose>
<refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
</refnamediv>
<indexterm><primary>SPI_execute_plan</primary></indexterm>
@ -1364,8 +1391,9 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>
<title>Description</title>
<para>
<function>SPI_execute_plan</function> executes a plan prepared by
<function>SPI_prepare</function>. <parameter>read_only</parameter> and
<function>SPI_execute_plan</function> executes a statement prepared by
<function>SPI_prepare</function> or one of its siblings.
<parameter>read_only</parameter> and
<parameter>count</parameter> have the same interpretation as in
<function>SPI_execute</function>.
</para>
@ -1379,7 +1407,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -1389,7 +1417,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>
<listitem>
<para>
An array of actual parameter values. Must have same length as the
plan's number of arguments.
statement's number of arguments.
</para>
</listitem>
</varlistentry>
@ -1399,7 +1427,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>
<listitem>
<para>
An array describing which parameters are null. Must have same length as
the plan's number of arguments.
the statement's number of arguments.
<literal>n</literal> indicates a null value (entry in
<parameter>values</> will be ignored); a space indicates a
nonnull value (entry in <parameter>values</> is valid).
@ -1479,7 +1507,7 @@ int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>
<refnamediv>
<refname>SPI_execute_plan_with_paramlist</refname>
<refpurpose>execute a plan prepared by <function>SPI_prepare</function></refpurpose>
<refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
</refnamediv>
<indexterm><primary>SPI_execute_plan_with_paramlist</primary></indexterm>
@ -1497,7 +1525,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr <parameter>plan</parameter>,
<title>Description</title>
<para>
<function>SPI_execute_plan_with_paramlist</function> executes a plan
<function>SPI_execute_plan_with_paramlist</function> executes a statement
prepared by <function>SPI_prepare</function>.
This function is equivalent to <function>SPI_execute_plan</function>
except that information about the parameter values to be passed to the
@ -1516,7 +1544,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr <parameter>plan</parameter>,
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -1573,7 +1601,7 @@ int SPI_execute_plan_with_paramlist(SPIPlanPtr <parameter>plan</parameter>,
<refnamediv>
<refname>SPI_execp</refname>
<refpurpose>execute a plan in read/write mode</refpurpose>
<refpurpose>execute a statement in read/write mode</refpurpose>
</refnamediv>
<indexterm><primary>SPI_execp</primary></indexterm>
@ -1603,7 +1631,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values<
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -1613,7 +1641,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values<
<listitem>
<para>
An array of actual parameter values. Must have same length as the
plan's number of arguments.
statement's number of arguments.
</para>
</listitem>
</varlistentry>
@ -1623,7 +1651,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values<
<listitem>
<para>
An array describing which parameters are null. Must have same length as
the plan's number of arguments.
the statement's number of arguments.
<literal>n</literal> indicates a null value (entry in
<parameter>values</> will be ignored); a space indicates a
nonnull value (entry in <parameter>values</> is valid).
@ -1673,7 +1701,7 @@ int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values<
<refnamediv>
<refname>SPI_cursor_open</refname>
<refpurpose>set up a cursor using a plan created with <function>SPI_prepare</function></refpurpose>
<refpurpose>set up a cursor using a statement created with <function>SPI_prepare</function></refpurpose>
</refnamediv>
<indexterm><primary>SPI_cursor_open</primary></indexterm>
@ -1691,14 +1719,14 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par
<para>
<function>SPI_cursor_open</function> sets up a cursor (internally,
a portal) that will execute a plan prepared by
a portal) that will execute a statement prepared by
<function>SPI_prepare</function>. The parameters have the same
meanings as the corresponding parameters to
<function>SPI_execute_plan</function>.
</para>
<para>
Using a cursor instead of executing the plan directly has two
Using a cursor instead of executing the statement directly has two
benefits. First, the result rows can be retrieved a few at a time,
avoiding memory overrun for queries that return many rows. Second,
a portal can outlive the current procedure (it can, in fact, live
@ -1731,7 +1759,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -1741,7 +1769,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par
<listitem>
<para>
An array of actual parameter values. Must have same length as the
plan's number of arguments.
statement's number of arguments.
</para>
</listitem>
</varlistentry>
@ -1751,7 +1779,7 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <par
<listitem>
<para>
An array describing which parameters are null. Must have same length as
the plan's number of arguments.
the statement's number of arguments.
<literal>n</literal> indicates a null value (entry in
<parameter>values</> will be ignored); a space indicates a
nonnull value (entry in <parameter>values</> is valid).
@ -1958,7 +1986,7 @@ Portal SPI_cursor_open_with_paramlist(const char *<parameter>name</parameter>,
<para>
<function>SPI_cursor_open_with_paramlist</function> sets up a cursor
(internally, a portal) that will execute a plan prepared by
(internally, a portal) that will execute a statement prepared by
<function>SPI_prepare</function>.
This function is equivalent to <function>SPI_cursor_open</function>
except that information about the parameter values to be passed to the
@ -1992,7 +2020,7 @@ Portal SPI_cursor_open_with_paramlist(const char *<parameter>name</parameter>,
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
execution plan (returned by <function>SPI_prepare</function>)
prepared statement (returned by <function>SPI_prepare</function>)
</para>
</listitem>
</varlistentry>
@ -2495,6 +2523,75 @@ void SPI_cursor_close(Portal <parameter>portal</parameter>)
<!-- *********************************************** -->
<refentry id="spi-spi-keepplan">
<refmeta>
<refentrytitle>SPI_keepplan</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>SPI_keepplan</refname>
<refpurpose>save a prepared statement</refpurpose>
</refnamediv>
<indexterm><primary>SPI_keepplan</primary></indexterm>
<refsynopsisdiv>
<synopsis>
int SPI_keepplan(SPIPlanPtr <parameter>plan</parameter>)
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<function>SPI_keepplan</function> saves a passed statement (prepared by
<function>SPI_prepare</function>) so that it will not be freed
by <function>SPI_finish</function> nor by the transaction manager.
This gives you the ability to reuse prepared statements in the subsequent
invocations of your procedure in the current session.
</para>
</refsect1>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
the prepared statement to be saved
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Return Value</title>
<para>
0 on success;
<symbol>SPI_ERROR_ARGUMENT</symbol> if <parameter>plan</parameter>
is <symbol>NULL</symbol> or invalid
</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
The passed-in statement is relocated to permanent storage by means
of pointer adjustment (no data copying is required). If you later
wish to delete it, use <function>SPI_freeplan</function> on it.
</para>
</refsect1>
</refentry>
<!-- *********************************************** -->
<refentry id="spi-spi-saveplan">
<refmeta>
<refentrytitle>SPI_saveplan</refentrytitle>
@ -2503,7 +2600,7 @@ void SPI_cursor_close(Portal <parameter>portal</parameter>)
<refnamediv>
<refname>SPI_saveplan</refname>
<refpurpose>save a plan</refpurpose>
<refpurpose>save a prepared statement</refpurpose>
</refnamediv>
<indexterm><primary>SPI_saveplan</primary></indexterm>
@ -2518,11 +2615,11 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
<title>Description</title>
<para>
<function>SPI_saveplan</function> saves a passed plan (prepared by
<function>SPI_prepare</function>) in memory that will not be freed
<function>SPI_saveplan</function> copies a passed statement (prepared by
<function>SPI_prepare</function>) into memory that will not be freed
by <function>SPI_finish</function> nor by the transaction manager,
and returns a pointer to the saved plan. This gives you the
ability to reuse prepared plans in the subsequent invocations of
and returns a pointer to the copied statement. This gives you the
ability to reuse prepared statements in the subsequent invocations of
your procedure in the current session.
</para>
</refsect1>
@ -2535,7 +2632,7 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
the plan to be saved
the prepared statement to be saved
</para>
</listitem>
</varlistentry>
@ -2546,7 +2643,7 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
<title>Return Value</title>
<para>
Pointer to the saved plan; <symbol>NULL</symbol> if unsuccessful.
Pointer to the copied statement; or <symbol>NULL</symbol> if unsuccessful.
On error, <varname>SPI_result</varname> is set thus:
<variablelist>
@ -2575,16 +2672,15 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
<title>Notes</title>
<para>
The passed-in plan is not freed, so you might wish to do
The originally passed-in statement is not freed, so you might wish to do
<function>SPI_freeplan</function> on it to avoid leaking memory
until <function>SPI_finish</>.
</para>
<para>
If one of the objects (a table, function, etc.) referenced by the
prepared plan is dropped or redefined, then future executions of
<function>SPI_execute_plan</function> may fail or return different
results than the plan initially indicates.
In most cases, <function>SPI_keepplan</function> is preferred to this
function, since it accomplishes largely the same result without needing
to physically copy the prepared statement's data structures.
</para>
</refsect1>
</refentry>
@ -3809,7 +3905,7 @@ void SPI_freetuptable(SPITupleTable * <parameter>tuptable</parameter>)
<refnamediv>
<refname>SPI_freeplan</refname>
<refpurpose>free a previously saved plan</refpurpose>
<refpurpose>free a previously saved prepared statement</refpurpose>
</refnamediv>
<indexterm><primary>SPI_freeplan</primary></indexterm>
@ -3824,9 +3920,9 @@ int SPI_freeplan(SPIPlanPtr <parameter>plan</parameter>)
<title>Description</title>
<para>
<function>SPI_freeplan</function> releases a command execution plan
<function>SPI_freeplan</function> releases a prepared statement
previously returned by <function>SPI_prepare</function> or saved by
<function>SPI_saveplan</function>.
<function>SPI_keepplan</function> or <function>SPI_saveplan</function>.
</para>
</refsect1>
@ -3838,7 +3934,7 @@ int SPI_freeplan(SPIPlanPtr <parameter>plan</parameter>)
<term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
<listitem>
<para>
pointer to plan to free
pointer to statement to free
</para>
</listitem>
</varlistentry>
@ -3849,6 +3945,7 @@ int SPI_freeplan(SPIPlanPtr <parameter>plan</parameter>)
<title>Return Value</title>
<para>
0 on success;
<symbol>SPI_ERROR_ARGUMENT</symbol> if <parameter>plan</parameter>
is <symbol>NULL</symbol> or invalid
</para>