Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: update connExecutor logic for pausable portals #99663

Merged
merged 8 commits into from
Apr 7, 2023

Commits on Apr 7, 2023

  1. pgwire: update comments for limitedCommandResult

    With the introduction of pausable portals, the comment for `limitedCommandResult`
    needs to be updated to reflect the current behavior.
    
    Release note: None
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    0f2db80 View commit details
    Browse the repository at this point in the history
  2. sql: add session variable for multiple active portals

    This change introduces a new session variable for a preview feature. When set to `true`,
    all non-internal portals with read-only [`SELECT`](../v23.1/selection-queries.html)
    queries without sub-queries or post-queries can be paused and resumed in an interleaving
    manner, but are executed with a local plan.
    
    Release note (SQL change): Added the session variable `multiple_active_portals_enabled`.
    This setting is only for a preview feature. When set to `true`, it allows
    multiple portals to be open at the same time, with their execution interleaved
    with each other. In other words, these portals can be paused. The underlying
    statement for a pausable portal must be a read-only `SELECT` query without
    sub-queries or post-queries, and such a portal is always executed with a local
    plan.
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    26da6a7 View commit details
    Browse the repository at this point in the history
  3. sql: add clean-up steps for pausable portals to ensure proper resourc…

    …e persistence
    
    This commit is part of the implementation of multiple active portals. In order to
    execute portals interleavingly, certain resources need to be persisted and their
    clean-up must be delayed until the portal is closed. Additionally, these resources
    don't need to be re-setup when the portal is re-executed.
    
    To achieve this, we store the cleanup steps in the `cleanup` function stacks in
    `portalPauseInfo`, and they are called when any of the following events occur:
    
    1. SQL transaction is committed or rolled back
    2. Connection executor is closed
    3. An error is encountered when executing the portal
    4. The portal is explicited closed by the user
    
    The cleanup functions should be called in the original order of a normal portal.
    Since a portal's execution follows the `execPortal() -> execStmtInOpenState() ->
    dispatchToExecutionEngine() -> flow.Run()` function flow, we categorize the cleanup
    functions into 4 "layers", which are stored accordingly in `PreparedPortal.pauseInfo`.
    The cleanup is always LIFO, following the
    
    - resumableFlow.cleanup
    - dispatchToExecutionEngine.cleanup
    - execStmtInOpenState.cleanup
    - exhaustPortal.cleanup`
    
    order. Additionally, if an error occurs in any layer, we clean up the current and
    proceeding layers. For example, if an error occurs in `execStmtInOpenState()`, we
    perform `resumableFlow.cleanup` and `dispatchToExecutionEngine.cleanup` (proceeding)
    and then `execStmtInOpenState.cleanup` (current) before returning the error to
    `execPortal()`, where `exhaustPortal.cleanup` will eventually be called. This is to
    maintain the previous clean-up process for portals as much as possible.
    
    We also pass the `PreparedPortal` as a reference to the planner in
    `execStmtInOpenState()`,so that the portal's flow can be set and reused.
    
    Release note: None
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    6eff5ce View commit details
    Browse the repository at this point in the history
  4. sql: store retErr and retPayload for pausable portals

    When executing or cleaning up a pausable portal, we may encounter an error and
    need to run the corresponding clean-up steps, where we need to check the latest
    `retErr` and `retPayload` rather than the ones evaluated when creating the
    cleanup functions.
    
    To address this, we use portal.pauseInfo.retErr and .retPayload to record the
    latest error and payload. They need to be updated for each execution.
    
    Specifically,
    
    1. If the error happens during portal execution, we ensure `portal.pauseInfo`
    records the error by adding the following code to the main body of
    `execStmtInOpenState()`:
    
    ``` go
    defer func() {
    	updateRetErrAndPayload(retErr, retPayload)
    }()
    ```
    
    Note this defer should always happen _after_ the defer of running the cleanups.
    
    2. If the error occurs during a certain cleanup step for the pausable portal,
    we ensure that cleanup steps after it can see the error by always having
    `updateRetErrAndPayload(retErr, retPayload)` run at the end of each cleanup step.
    
    Release note: None
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    dcbcca9 View commit details
    Browse the repository at this point in the history
  5. sql: add restrictions to pausable portals

    This commit adds several restrictions to pausable portals to ensure that they
    work properly with the current changes to the consumer-receiver model.
    Specifically, pausable portals must meet the following criteria:
    
    1. Not be internal queries
    2. Be read-only queries
    3. Not contain sub-queries or post-queries
    4. Only use local plans
    
    These restrictions are necessary because the current changes to the
    consumer-receiver model only consider the local push-based case.
    
    Release note: None
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    aa6cd36 View commit details
    Browse the repository at this point in the history
  6. sql: correctly set inner plan for leafTxn when resuming flow for portal

    When resuming a portal, we always reset the planner. However we still need the
    planner to respect the outer txn's situation, as we did in cockroachdb#98120.
    
    Release note: None
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    3d20ce5 View commit details
    Browse the repository at this point in the history
  7. pgwire: add tests for multiple active portals

    Release note: None
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    789c2cd View commit details
    Browse the repository at this point in the history
  8. sql: disable multiple active portals for TestDistSQLReceiverDrainsMeta.

    We now only support multiple active portals with local plan, so explicitly
    disable it for this test for now.
    
    Release note: None
    ZhouXing19 committed Apr 7, 2023
    Configuration menu
    Copy the full SHA
    199b177 View commit details
    Browse the repository at this point in the history