Module org.firebirdsql.jaybird
Package org.firebirdsql.gds.ng

# Interface FbStatement

All Superinterfaces:
  `AutoCloseable`, `ExceptionListenable`

All Known Subinterfaces:
  `FbWireStatement`

All Known Implementing Classes:
  `AbstractFbStatement`, `AbstractFbWireStatement`, `V10Statement`, `V11Statement`, `V12Statement`, `V13Statement`, `V16Statement`, `V18Statement`, `V19Statement`

public interface FbStatement extends ExceptionListenable, AutoCloseable
API for statement handles.

All methods defined in this interface are required to notify all `SQLException` thrown from the methods defined in this interface.

Since:
  3.0
Author:
  Mark Rotteveel

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addStatementListener(StatementListener statementListener)`
  Registers a `StatementListener`.
  `void`
  `addWeakStatementListener(StatementListener statementListener)`
  Adds a `StatementListener` instance to this database using a weak reference.
  `default void`
  `asyncFetchRows(int fetchSize)`
  Requests the server to perform an asynchronous fetch for `fetch size`.
  `default void`
  `batchCancel()`
  Cancels the server side batch (that is, clear any rows batched on the server).
  `default BatchCompletion`
  `batchExecute()`
  Execute the batch on the server.
  `default void`
  `clearCursorFlag(CursorFlag flag)`
  Clears cursor flag.
  `void`
  `close()`
  Close and deallocate this statement.
  `void`
  `closeCursor()`
  Closes the cursor associated with this statement, leaving the statement itself allocated.
  `void`
  `closeCursor(boolean transactionEnd)`
  Closes the cursor associated with this statement, leaving the statement itself allocated.
  `default BatchParameterBuffer`
  `createBatchParameterBuffer()`
  Creates a `BatchParameterBuffer` instance compatible with this protocol version.
  `default void`
  `deferredBatchCreate(FbBatchConfig batchConfig, DeferredResponse<Void> onResponse)`
  Sends batch create with deferred response processing.
  `default void`
  `deferredBatchRelease(DeferredResponse<Void> onResponse)`
  Closes (releases) the batch on the server with deferred response processing.
  `default void`
  `deferredBatchSend(Collection<RowValue> rowValues, DeferredResponse<Void> onResponse)`
  Sends batch data with deferred response processing.
  `RowDescriptor`
  `emptyRowDescriptor()`
  `void`
  `ensureClosedCursor(boolean transactionEnd)`
  Ensures that the statement cursor is closed.
  `void`
  `execute(RowValue parameters)`
  Execute the statement.
  `void`
  `fetchRows(int fetchSize)`
  Requests this statement to fetch the next `fetchSize` rows.
  `default void`
  `fetchScroll(FetchType fetchType, int fetchSize, int position)`
  Requests this statement to fetch rows using the specified fetch type.
  `default byte[]`
  `getCursorInfo(byte[] requestItems, int bufferLength)`
  Request cursor info.
  `default <T> T`
  `getCursorInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor)`
  Request cursor info.
  `FbDatabase`
  `getDatabase()`
  `int`
  `getDefaultSqlInfoSize()`
  `String`
  `getExecutionPlan()`
  `String`
  `getExplainedExecutionPlan()`
  `int`
  `getHandle()`
  `int`
  `getMaxSqlInfoSize()`
  `RowDescriptor`
  `getParameterDescriptor()`
  `RowDescriptor`
  `getRowDescriptor()`
  `SqlCountHolder`
  `getSqlCounts()`
  Retrieves the SQL counts for the last execution of this statement.
  `byte[]`
  `getSqlInfo(byte[] requestItems, int bufferLength)`
  Request statement info.
  `<T> T`
  `getSqlInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor)`
  Request statement info.
  `StatementState`
  `getState()`
  `long`
  `getTimeout()`
  Gets the current statement timeout for this statement.
  `FbTransaction`
  `getTransaction()`
  `StatementType`
  `getType()`
  `boolean`
  `hasFetched()`
  Has at least one fetch been executed on the current cursor?
  `default boolean`
  `isCursorFlagSet(CursorFlag flag)`
  Reports whether a cursor flag is set.
  `void`
  `prepare(String statementText)`
  Prepare the statement text.
  `void`
  `removeStatementListener(StatementListener statementListener)`
  Removes a `StatementListener`.
  `default void`
  `setCursorFlag(CursorFlag flag)`
  Set cursor flag.
  `void`
  `setCursorName(String cursorName)`
  Sets the named cursor name for this statement.
  `void`
  `setTimeout(long timeoutMillis)`
  Sets the statement timeout.
  `void`
  `setTransaction(FbTransaction transaction)`
  Associates a transaction with this statement
  `default boolean`
  `supportBatchUpdates()`
  Reports whether this statement implementation supports server-side batch updates.
  `default boolean`
  `supportsCursorInfo()`
  Reports whether this statement implementation supports `getCursorInfo(byte[], int, InfoProcessor)` and `getCursorInfo(byte[], int)`.
  `default boolean`
  `supportsFetchScroll()`
  Reports whether this statement implementation supports `fetchScroll(FetchType, int, int)` with anything other than `FetchType.NEXT`.
  `void`
  `unprepare()`
  Attempts to unprepare the currently prepared statement.
  `void`
  `validateParameters(RowValue parameters)`
  Validates if the number of parameters matches the expected number and types, and if all values have been set.
  `LockCloseable`
  `withLock()`
  Locks the lock with `Lock.lock()` (or equivalent).

  ### Methods inherited from interface org.firebirdsql.gds.ng.listeners.ExceptionListenable

  `addExceptionListener, removeExceptionListener`

- ## Method Details

  - ### getTransaction

    FbTransaction getTransaction()
    Returns:
      Transaction currently associated with this statement

  - ### getDatabase

    FbDatabase getDatabase()
    Returns:
      The database connection that created this statement

  - ### setTransaction

    void setTransaction(FbTransaction transaction) throws SQLException
    Associates a transaction with this statement
    Parameters:
      `transaction` - The transaction
    Throws:
      `SQLException`

  - ### getParameterDescriptor

    RowDescriptor getParameterDescriptor()
    Returns:
      descriptor of the parameters of this statement

  - ### getRowDescriptor

    RowDescriptor getRowDescriptor()
    Returns:
      descriptor of the row returned by this statement

  - ### getType

    StatementType getType()
    Returns:
      The statement type

  - ### getState

    StatementState getState()
    Returns:
      The current state of this statement

  - ### getHandle

    int getHandle()
    Returns:
      The Firebird statement handle identifier

  - ### close

    void close() throws SQLException
    Close and deallocate this statement.
    Specified by:
      `close` in interface `AutoCloseable`
    Throws:
      `SQLException`

  - ### closeCursor

    void closeCursor() throws SQLException
    Closes the cursor associated with this statement, leaving the statement itself allocated.

    Equivalent to calling `closeCursor(boolean)` with `false`.

    Throws:
      `SQLException`

  - ### closeCursor

    void closeCursor(boolean transactionEnd) throws SQLException
    Closes the cursor associated with this statement, leaving the statement itself allocated.

    When this method is called in preparation of a commit, rollback or another operation which will close the cursor (see `transactionEnd`), then implementations may opt to not close the cursor on the server as the server closes the cursor automatically, or the statement as a whole is closed by the implementation.

    Parameters:
      `transactionEnd` - close is in response to a transaction end or another operation which will implicitly close the cursor
    Throws:
      `SQLException`

  - ### prepare

    void prepare(String statementText) throws SQLException
    Prepare the statement text.

    If this handle is in state `StatementState.NEW` then it will first allocate the statement.

    Parameters:
      `statementText` - Statement text
    Throws:
      `SQLException` - If a database access error occurs, or this statement is currently executing a query.

  - ### unprepare

    void unprepare() throws SQLException
    Attempts to unprepare the currently prepared statement.

    For Firebird versions that do not support `DSQL_unprepare`, the implementation should attempt to close the cursor (using `closeCursor()`).

    Throws:
      `SQLException` - If a database access error occurs

  - ### validateParameters

    void validateParameters(RowValue parameters) throws SQLException
    Validates if the number of parameters matches the expected number and types, and if all values have been set.
    Parameters:
      `parameters` - Parameter values to validate
    Throws:
      `SQLException` - When the number or type of parameters does not match `getParameterDescriptor()`, or when a parameter has not been set.

  - ### execute

    void execute(RowValue parameters) throws SQLException
    Execute the statement.
    Parameters:
      `parameters` - The list of parameter values to use for execution.
    Throws:
      `SQLException` - When the number of type of parameters does not match the types returned by `getParameterDescriptor()`, a parameter value was not set, or when an error occurred executing this statement.

  - ### fetchRows

    void fetchRows(int fetchSize) throws SQLException
    Requests this statement to fetch the next `fetchSize` rows.

    Fetched rows are not returned from this method, but sent to the registered `StatementListener` instances.

    If an asynchronous fetch is pending, that pending fetch should be completed instead of performing a new fetch.

    Parameters:
      `fetchSize` - Number of rows to fetch (must be greater than `0`)
    Throws:
      `SQLException` - For database access errors, when called on a closed statement, when no cursor is open or when the fetch size is not greater than `0`
    See Also:
      - `asyncFetchRows(int)`

  - ### fetchScroll

    default void fetchScroll(FetchType fetchType, int fetchSize, int position) throws SQLException
    Requests this statement to fetch rows using the specified fetch type.

    The default implementation only supports `FetchType.NEXT` by redirecting to `fetchRows(int)` and throws an `SQLFeatureNotSupported` for other types.

    The caller is responsible for tracking and correcting for server-side positional state, taking into account any rows already fetched. For example, if 100 rows have been fetched with `NEXT` or `PRIOR`, and 80 rows are still in the local buffer, the server-side position is actually 80 rows ahead (or behind). The next fetch with `RELATIVE` will need to correct this in `position`, and a `PRIOR` after a `NEXT` or a `NEXT` after a `PRIOR` will need to reposition with `RELATIVE` or `ABSOLUTE`, or know how many rows to ignore from the fetched batch.

    If an asynchronous fetch is pending, the behaviour depends on the value of `fetchType`: if `FetchType.NEXT`, the fetch should be completed instead of performing a new fetch. For any other value, a `SQLException` should be thrown. Given `asyncFetchRows(int)` should be a no-op for scrollable cursors, this should not normally happen.

    Parameters:
      `fetchType` - Fetch type
      `fetchSize` - Number of rows to fetch (must be `> 0`) (ignored by server for types other than `FetchType.NEXT` and `FetchType.PRIOR`)
      `position` - Absolute or relative position for the row to fetch (ignored by server for types other than `FetchType.ABSOLUTE` and `FetchType.RELATIVE`)
    Throws:
      `SQLFeatureNotSupportedException` - For types other than `FetchType.NEXT` if the protocol version or the implementation does not support scroll fetch
      `SQLException` - For database access errors, when called on a closed statement, when no cursor is open, when an async fetch is pending and `fetchType` is not `NEXT`, or for server-side error conditions
    Since:
      5
    See Also:
      - `supportsFetchScroll()`

  - ### asyncFetchRows

    default void asyncFetchRows(int fetchSize) throws SQLException
    Requests the server to perform an asynchronous fetch for `fetch size`.

    Asynchronous fetching is an optional feature. If an implementation does not support asynchronous fetching, it should return immediately and do nothing. Although this interface provides a default implementation which does nothing, implementations should override it, to throw an exception when called on a closed statement.

    For implementations which do support async fetching, this call should not do anything if one of the following is true:

    - an asynchronous fetch is already pending
    - `fetchSize` is `1` or the statement has a cursor name set
    - the current statement has a scrollable cursor (flag `CURSOR_TYPE_SCROLLABLE` set)
    - the connection property `asyncFetch` is `false`

    An asynchronous fetch can be completed explicitly by calling `fetchRows(int)`, or implicitly by other network operations.

    Parameters:
      `fetchSize` - number of rows to fetch (must be greater than `0`)
    Throws:
      `SQLException` - for database access errors, when called on a closed statement, when no cursor is open or when the fetch size is not greater than `0`
    Since:
      6
    See Also:
      - `fetchRows(int)`

  - ### hasFetched

    boolean hasFetched()
    Has at least one fetch been executed on the current cursor?
    Returns:
      `true` if at least one fetch has been executed on the current cursor, `false` otherwise (including if nothing has been executed, or the current statement has no cursor)
    Since:
      5

  - ### supportsFetchScroll

    default boolean supportsFetchScroll()
    Reports whether this statement implementation supports `fetchScroll(FetchType, int, int)` with anything other than `FetchType.NEXT`.
    Returns:
      `true` `fetchScroll` supported, `false` if not supported (default implementation returns `false`)
    Since:
      5

  - ### addStatementListener

    void addStatementListener(StatementListener statementListener)
    Registers a `StatementListener`.
    Parameters:
      `statementListener` - The statement listener

  - ### addWeakStatementListener

    void addWeakStatementListener(StatementListener statementListener)
    Adds a `StatementListener` instance to this database using a weak reference.

    If the listener is already strongly referenced, this call will be ignored

    Parameters:
      `statementListener` - statement listener

  - ### removeStatementListener

    void removeStatementListener(StatementListener statementListener)
    Removes a `StatementListener`.
    Parameters:
      `statementListener` - The statement listener

  - ### getSqlInfo

    <T> T getSqlInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) throws SQLException
    Request statement info.
    Parameters:
      `requestItems` - Array of info items to request
      `bufferLength` - Response buffer length to use
      `infoProcessor` - Implementation of `InfoProcessor` to transform the info response
    Returns:
      Transformed info response of type T
    Throws:
      `SQLException` - For errors retrieving or transforming the response.

  - ### getSqlInfo

    byte[] getSqlInfo(byte[] requestItems, int bufferLength) throws SQLException
    Request statement info.
    Parameters:
      `requestItems` - Array of info items to request
      `bufferLength` - Response buffer length to use
    Returns:
      Response buffer
    Throws:
      `SQLException` - For errors retrieving or transforming the response.

  - ### getCursorInfo

    default <T> T getCursorInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) throws SQLException
    Request cursor info.
    Parameters:
      `requestItems` - Array of info items to request
      `bufferLength` - Response buffer length to use
      `infoProcessor` - Implementation of `InfoProcessor` to transform the info response
    Returns:
      Transformed info response of type T
    Throws:
      `SQLException` - For errors retrieving or transforming the response
      `SQLFeatureNotSupportedException` - If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)
    Since:
      5
    See Also:
      - `supportsCursorInfo()`

  - ### getCursorInfo

    default byte[] getCursorInfo(byte[] requestItems, int bufferLength) throws SQLException
    Request cursor info.
    Parameters:
      `requestItems` - Array of info items to request
      `bufferLength` - Response buffer length to use
    Returns:
      Response buffer
    Throws:
      `SQLException` - For errors retrieving or transforming the response
      `SQLFeatureNotSupportedException` - If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)
    Since:
      5

  - ### supportsCursorInfo

    default boolean supportsCursorInfo()
    Reports whether this statement implementation supports `getCursorInfo(byte[], int, InfoProcessor)` and `getCursorInfo(byte[], int)`.
    Returns:
      `true` `getCursorInfo` supported, `false` if not supported (default implementation returns `false`)
    Since:
      5

  - ### getDefaultSqlInfoSize

    int getDefaultSqlInfoSize()
    Returns:
      The default size to use for the sql info buffer

  - ### getMaxSqlInfoSize

    int getMaxSqlInfoSize()
    Returns:
      The maximum size to use for the sql info buffer

  - ### getExecutionPlan

    String getExecutionPlan() throws SQLException
    Returns:
      The execution plan of the currently prepared statement
    Throws:
      `SQLException` - If this statement is closed.

  - ### getExplainedExecutionPlan

    String getExplainedExecutionPlan() throws SQLException
    Returns:
      The detailed execution plan of the currently prepared statement
    Throws:
      `SQLException` - If this statement is closed.

  - ### getSqlCounts

    SqlCountHolder getSqlCounts() throws SQLException
    Retrieves the SQL counts for the last execution of this statement.

    The retrieved SQL counts are also notified to all registered `StatementListener`s.

    In general the `FbStatement` will (should) retrieve and notify listeners of the SQL counts automatically at times where it is relevant (eg after executing a statement that does not produce multiple rows, or after fetching all rows).

    Returns:
      The SQL counts of the last execution of this statement
    Throws:
      `SQLException` - If this statement is closed, or if this statement is in state `StatementState.CURSOR_OPEN` and not all rows have been fetched.

  - ### setCursorName

    void setCursorName(String cursorName) throws SQLException
    Sets the named cursor name for this statement.
    Parameters:
      `cursorName` - Name of the cursor
    Throws:
      `SQLException` - If this statement is closed, or if the cursor name is set and `cursorName` is different from the current cursor name

  - ### emptyRowDescriptor

    RowDescriptor emptyRowDescriptor()
    Returns:
      A potentially cached empty row descriptor for this statement or database.

  - ### ensureClosedCursor

    void ensureClosedCursor(boolean transactionEnd) throws SQLException
    Ensures that the statement cursor is closed. Resets a statement, so it is ready to be reused for re-execute or prepare.
    Parameters:
      `transactionEnd` - Close is in response to a transaction end
    Throws:
      `SQLException` - If this statement is closed or the cursor could not be closed.
    Since:
      3.0.6

  - ### setTimeout

    void setTimeout(long timeoutMillis) throws SQLException
    Sets the statement timeout.

    The statement timeout value is ignored in implementations that do not support timeouts. If the provided timeout value is greater than supported (eg greater than â€4294967295â€¬ milliseconds on Firebird 4), the implementation should behave as if zero (`0`) was set, but still report the original value.

    The configured timeout only affects subsequent executes on this statement. The timeout includes time spent between reading from the result set.

    Parameters:
      `timeoutMillis` - Timeout value in milliseconds
    Throws:
      `SQLException` - If the value is less than zero, this statement is closed, or a database access error occurs
    Since:
      4.0

  - ### getTimeout

    long getTimeout() throws SQLException
    Gets the current statement timeout for this statement.

    This method will only return the current statement timeout value for this method, it will not consider attachment or connection level timeouts. This is an implementation decision that might change in a point release.

    Returns:
      The configured timeout in milliseconds; read the documentation in `setTimeout(long)`
    Throws:
      `SQLException` - If this statement is closed, or a database access error occurs
    Since:
      4.0
    See Also:
      - `setTimeout(long)`

  - ### setCursorFlag

    default void setCursorFlag(CursorFlag flag)
    Set cursor flag.

    If a protocol version does not support cursor flags, this is silently ignored.

    Parameters:
      `flag` - Cursor flag to set
    Since:
      5

  - ### clearCursorFlag

    default void clearCursorFlag(CursorFlag flag)
    Clears cursor flag.

    Setting a cursor flag only affects subsequent executes. A currently open cursor will not be affected.

    If a protocol version does not support cursor flags, this is silently ignored.

    Parameters:
      `flag` - Cursor flag to clear
    Since:
      5

  - ### isCursorFlagSet

    default boolean isCursorFlagSet(CursorFlag flag)
    Reports whether a cursor flag is set.

    If a protocol version does not support cursor flags, `false` should be returned.

    Parameters:
      `flag` - Cursor flag
    Returns:
      `true` when set, `false` otherwise
    Since:
      5

  - ### supportBatchUpdates

    default boolean supportBatchUpdates()
    Reports whether this statement implementation supports server-side batch updates.
    Returns:
      `true` server-side batch updates supported, `false` if not supported (default implementation returns `false`)
    Since:
      5

  - ### deferredBatchCreate

    default void deferredBatchCreate(FbBatchConfig batchConfig, DeferredResponse<Void> onResponse) throws SQLException
    Sends batch create with deferred response processing.

    Implementations that do not supported deferred or async response processing should call `DeferredResponse.onResponse(Object)` and - optionally - `DeferredResponse.onException(Exception)` synchronously. If the response is deferred, but the implementation is not capable of connecting the response back, it should call `onResponse` before method return, and any exceptions generated by deferred processing should then be thrown from the method that causes the response to be received.

    Parameters:
      `batchConfig` - batch configuration
      `onResponse` - deferred action to call when response is received
    Throws:
      `SQLException` - for database access errors (I/O errors)
      `SQLFeatureNotSupportedException` - when this statement implementation does not support batch updates
    Since:
      5
    See Also:
      - `supportBatchUpdates()`

  - ### deferredBatchSend

    default void deferredBatchSend(Collection<RowValue> rowValues, DeferredResponse<Void> onResponse) throws SQLException
    Sends batch data with deferred response processing.

    For implementations that do not supported deferred or async response processing, see `deferredBatchCreate(FbBatchConfig, DeferredResponse)` for expected behaviour.

    Parameters:
      `rowValues` - collection of row values
      `onResponse` - deferred action to call when response is received
    Throws:
      `SQLException` - for database access errors (I/O errors)
      `SQLFeatureNotSupportedException` - when this statement implementation does not support batch updates
    Since:
      5
    See Also:
      - `supportBatchUpdates()`

  - ### batchExecute

    default BatchCompletion batchExecute() throws SQLException
    Execute the batch on the server.
    Returns:
      batch completion response
    Throws:
      `SQLException` - for database access errors
      `SQLFeatureNotSupportedException` - when this statement implementation does not support batch updates
    Since:
      5
    See Also:
      - `supportBatchUpdates()`

  - ### batchCancel

    default void batchCancel() throws SQLException
    Cancels the server side batch (that is, clear any rows batched on the server).
    Throws:
      `SQLException` - for database access errors
      `SQLFeatureNotSupportedException` - when this statement implementation does not support batch updates
    Since:
      5
    See Also:
      - `supportBatchUpdates()`

  - ### deferredBatchRelease

    default void deferredBatchRelease(DeferredResponse<Void> onResponse) throws SQLException
    Closes (releases) the batch on the server with deferred response processing.

    For implementations that do not supported deferred or async response processing, see `deferredBatchCreate(FbBatchConfig, DeferredResponse)` for expected behaviour.

    Parameters:
      `onResponse` - deferred action to call when response is received
    Throws:
      `SQLException` - for database access errors
      `SQLFeatureNotSupportedException` - when this statement implementation does not support batch updates
    Since:
      5
    See Also:
      - `supportBatchUpdates()`

  - ### createBatchParameterBuffer

    default BatchParameterBuffer createBatchParameterBuffer() throws SQLException
    Creates a `BatchParameterBuffer` instance compatible with this protocol version.
    Returns:
      batch parameter buffer
    Throws:
      `SQLException` - if this statement is closed, or a database access error occurs, or when the parameter buffer could not be created for other reasons
      `SQLFeatureNotSupportedException` - when this statement implementation does not support batch updates
    Since:
      5
    See Also:
      - `supportBatchUpdates()`

  - ### withLock

    LockCloseable withLock()
    Locks the lock with `Lock.lock()` (or equivalent).

    Implementations are expected to apply the same lock as `FbAttachment.withLock()`.

    Returns:
      lock closeable which unlocks the lock on close
    See Also:
      - `FbAttachment.withLock()`