ExecutionPlan
corresponds to the execution plan obtained
using an internal PostgreSQL SPI_prepare
call.
The ExecutionPlan
is distinct from SPIPreparedStatement
because of its greater specificity. The current PreparedStatement
behavior (though it may, in future, change) is that the types of parameters
are not inferred in a "PostgreSQL-up" manner (that is, by having PostgreSQL
parse the SQL and report what types the parameters would need to have), but
in a "Java-down" manner, driven by the types of the parameter values supplied
to the PreparedStatement
before executing it. An
ExecutionPlan
corresponds to a particular assignment of parameter
types; a subsequent use of the same PreparedStatement
with different
parameter values may (depending on their types) lead to generation of a new
plan, with the former plan displaced from the PreparedStatement
and
into the PlanCache
implemented here. Another re-use of the same
PreparedStatement
with the original parameter types will displace the
newer plan into the cache and retrieve the earlier one.
The native state of a plan is not held in a transient context, so it is not
subject to invalidation from the native side. The Java object is kept "live"
(garbage-collection prevented) by being referenced either from the
Statement
that created it, or from the cache if it has been displaced
there. The close
method does not deallocate a plan, but simply moves
it to the cache, where it may be found again if needed for the same SQL and
parameter types.
At no time (except in passing) is a plan referred to both by the cache and by
a Statement
. It is cached when displaced out of its statement,
and removed from the cache if it is later found there and claimed again by
a statement, so that one ExecutionPlan
does not end up getting
shared by multiple statement instances. (There is nothing, however,
thread-safe about these machinations.)
There are not many ways for an ExecutionPlan
to actually be freed.
That will happen if it is evicted from the cache, either because it is oldest
and the cache limit is reached, or when another plan is cached for the same
SQL and parameter types; it will also happen if a PreparedStatement
using the plan becomes unreferenced and garbage-collected without
close
being called (which would have moved the plan back to the
cache).
- Author:
- Thomas Hallgren
-
Field Summary
Modifier and TypeFieldDescriptionstatic final short
static final short
static final short
-
Method Summary
Modifier and TypeMethodDescriptionvoid
close()
Close the plan.cursorOpen
(String cursorName, Object[] parameters, short read_only) Set up a cursor that will execute the plan using the internalSPI_cursor_open
functionint
Execute the plan using the internalSPI_execp
function.boolean
Checks if thisExecutionPlan
can create aPortal
usingcursorOpen(java.lang.String, java.lang.Object[], short)
.static ExecutionPlan
Create an execution plan for a statement to be executed later using the internalSPI_prepare
function.
-
Field Details
-
SPI_READONLY_DEFAULT
public static final short SPI_READONLY_DEFAULT- See Also:
-
SPI_READONLY_FORCED
public static final short SPI_READONLY_FORCED- See Also:
-
SPI_READONLY_CLEARED
public static final short SPI_READONLY_CLEARED- See Also:
-
-
Method Details
-
close
public void close()Close the plan. -
cursorOpen
public Portal cursorOpen(String cursorName, Object[] parameters, short read_only) throws SQLException Set up a cursor that will execute the plan using the internalSPI_cursor_open
function- Parameters:
cursorName
- Name of the cursor ornull
for a system generated name.parameters
- Values for the parameters.read_only
- One of the valuesSPI_READONLY_DEFAULT
,SPI_READONLY_FORCED
, orSPI_READONLY_CLEARED
(in the default case, the native code will defer toFunction_isCurrentReadOnly
.- Returns:
- The
Portal
that represents the opened cursor. - Throws:
SQLException
- If the underlying native structure has gone stale.
-
isCursorPlan
Checks if thisExecutionPlan
can create aPortal
usingcursorOpen(java.lang.String, java.lang.Object[], short)
. This is true if the plan contains only one regularSELECT
query.- Returns:
true
if the plan can create aPortal
- Throws:
SQLException
- If the underlying native structure has gone stale.
-
execute
Execute the plan using the internalSPI_execp
function.- Parameters:
parameters
- Values for the parameters.read_only
- One of the valuesSPI_READONLY_DEFAULT
,SPI_READONLY_FORCED
, orSPI_READONLY_CLEARED
(in the default case, the native code will defer toFunction_isCurrentReadOnly
.rowCount
- The maximum number of tuples to create. A value ofrowCount
of zero is interpreted as no limit, i.e., run to completion.- Returns:
- One of the status codes declared in class
SPI
. - Throws:
SQLException
- If the underlying native structure has gone stale.
-
prepare
Create an execution plan for a statement to be executed later using the internalSPI_prepare
function.- Parameters:
statement
- The command string.argTypes
- SQL types of argument types.- Returns:
- An execution plan for the prepared statement.
- Throws:
SQLException
- See Also:
-