Class ExecutionPlan

java.lang.Object
org.postgresql.pljava.internal.ExecutionPlan

public class ExecutionPlan extends Object
The 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 Details

  • 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 internal SPI_cursor_open function
      Parameters:
      cursorName - Name of the cursor or null for a system generated name.
      parameters - Values for the parameters.
      read_only - One of the values SPI_READONLY_DEFAULT, SPI_READONLY_FORCED, or SPI_READONLY_CLEARED (in the default case, the native code will defer to Function_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 this ExecutionPlan can create a Portal using cursorOpen(java.lang.String, java.lang.Object[], short). This is true if the plan contains only one regular SELECT query.
      Returns:
      true if the plan can create a Portal
      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 internal SPI_execp function.
      Parameters:
      parameters - Values for the parameters.
      read_only - One of the values SPI_READONLY_DEFAULT, SPI_READONLY_FORCED, or SPI_READONLY_CLEARED (in the default case, the native code will defer to Function_isCurrentReadOnly.
      rowCount - The maximum number of tuples to create. A value of rowCount 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 internal SPI_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: