- java.lang.Object
-
- org.postgresql.pljava.internal.ExecutionPlan
-
public class ExecutionPlan extends Object
TheExecutionPlan
corresponds to the execution plan obtained using an internal PostgreSQLSPI_prepare
call.The
ExecutionPlan
is distinct fromSPIPreparedStatement
because of its greater specificity. The currentPreparedStatement
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 thePreparedStatement
before executing it. AnExecutionPlan
corresponds to a particular assignment of parameter types; a subsequent use of the samePreparedStatement
with different parameter values may (depending on their types) lead to generation of a new plan, with the former plan displaced from thePreparedStatement
and into thePlanCache
implemented here. Another re-use of the samePreparedStatement
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. Theclose
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 oneExecutionPlan
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 aPreparedStatement
using the plan becomes unreferenced and garbage-collected withoutclose
being called (which would have moved the plan back to the cache).- Author:
- Thomas Hallgren
-
-
Field Summary
Fields Modifier and Type Field Description static short
SPI_READONLY_CLEARED
static short
SPI_READONLY_DEFAULT
static short
SPI_READONLY_FORCED
-
Method Summary
Modifier and Type Method Description void
close()
Close the plan.Portal
cursorOpen(String cursorName, Object[] parameters, short read_only)
Set up a cursor that will execute the plan using the internalSPI_cursor_open
functionint
execute(Object[] parameters, short read_only, int rowCount)
Execute the plan using the internalSPI_execp
function.boolean
isCursorPlan()
Checks if thisExecutionPlan
can create aPortal
usingcursorOpen(java.lang.String, java.lang.Object[], short)
.static ExecutionPlan
prepare(String statement, Oid[] argTypes)
Create an execution plan for a statement to be executed later using the internalSPI_prepare
function.
-
-
-
Field Detail
-
SPI_READONLY_DEFAULT
public static final short SPI_READONLY_DEFAULT
- See Also:
- Constant Field Values
-
SPI_READONLY_FORCED
public static final short SPI_READONLY_FORCED
- See Also:
- Constant Field Values
-
SPI_READONLY_CLEARED
public static final short SPI_READONLY_CLEARED
- See Also:
- Constant Field Values
-
-
Method Detail
-
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
public boolean isCursorPlan() throws SQLException
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
public int execute(Object[] parameters, short read_only, int rowCount) throws SQLException
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
public static ExecutionPlan prepare(String statement, Oid[] argTypes) throws SQLException
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:
Types
-
-