[/ Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] [section:pipeline (Experimental) Pipelines] [nochunk] Functions like [refmemunq any_connection execute], [refmemunq any_connection prepare_statement] and their async counterparts are half-duplex: they write a single request to the server and wait for its response. In contrast, pipelines can increase efficiency by coalescing several requests into a single message, saving round-trips to the server. [warning The MySQL client/server protocol doesn't have explicit support for pipelines. [*From the server's point of view, a pipeline is just a sequence of unrelated requests]. The server will try to execute all stages in each pipeline, regardless of the result of previous stages. Pipelines are considered an [*advanced feature]. Please read [link mysql.pipeline.pitfalls the pitfalls section] for more info. ] [note This feature is experimental. Its API may change in subsequent releases. ] [heading Use cases] You should use pipelines for lightweight operations, dominated by round-trip time. Typical examples include: * Running connection setup code, involving operations like [refmemunq any_connection reset_connection], [refmemunq any_connection set_character_set] or preparing statements. [reflink connection_pool] uses pipelines to clean up connections for re-use. * Preparing several statements, in batch. * Executing and closing a statement in a single round-trip. You should [*avoid] pipelines for the following cases: * When you can achieve the same functionality using semicolon-separated queries (thus using [link mysql.multi_resultset.multi_queries multi-queries] and [link mysql.text_queries client-side SQL formatting]). Multi-queries will stop after the first error, which is usually what you want. See [link mysql.pipeline.pitfalls this section] for more info. * When running heavyweight queries, where the gains in round-trip time are not significant. * When there are dependencies between stages in the pipeline. Lack of protocol support makes this use case impossible. If you're not sure, don't use this feature. [heading Pipeline requests and responses] To run a pipeline, create a [reflink pipeline_request] object describing what should the pipeline do: [pipeline_request] We're using [refmemunq pipeline_request add_execute] and [refmemunq pipeline_request add_prepare_statement] to add stages to our pipeline. You can find all available stage types in the [link mysql.pipeline.reference reference section]. To actually run the pipeline, create a response object and call [refmem any_connection run_pipeline] or [refmemunq any_connection async_run_pipeline]: [pipeline_run] Finally, you can access the statements using [refmem stage_response as_statement]: [pipeline_results] If your pipeline contains an execution stage, it will generate a `results` object that can be accessed using [refmem stage_response as_results]. [heading:error Error handling] If any of the pipeline stages result in an error, the entire [refmemunq any_connection run_pipeline] operation is considered failed. This means that [*if `run_pipipeline` completed successfully, all stages succeeded]. Recall that [*all stages are always run, regardless of the outcome of previous stages]. If `run_pipipeline` fails, you can check which stages succeeded and failed by inspecting responses. [refmem stage_response error] and [refmem stage_response diag] will return error information about failed steps. For instance: [pipeline_errors] [heading:pitfalls Potential pitfalls] All requests in the pipeline are always run, regardless of the outcome of previous requests. As a result, some pipelines can behave non-intuitively: [pipeline_pitfalls_bad] Pipelines aren't the best fit here. Instead, you can express the same logic using semicolon-separated queries: [pipeline_pitfalls_good] Pipeline stages are run sequentially by the server. If any of the stages involves a heavyweight query, the server won't process subsequent stages until the query completes. [heading:reference Pipeline stage reference] In the table below, the following variables are assumed: * `req` is a [reflink pipeline_request]. * `stmt` is a valid [reflink statement]. * `result` is a [reflink results] object. * `conn` is an [reflink any_connection] object. [table:reference [ [Stage type] [Example] [When run, equivalent to...] [Response type] ] [ [ [*Execute]: behaves like [refmem any_connection execute][br][br] [refmem pipeline_request add_execute][br] [refmem pipeline_request add_execute_range] ] [[pipeline_reference_execute]] [[pipeline_reference_execute_equivalent]] [ [reflink results] or an error ] ] [ [ [*Prepare statement]: behaves like [refmem any_connection prepare_statement][br][br] [refmem pipeline_request add_prepare_statement] ] [[pipeline_reference_prepare_statement]] [[pipeline_reference_prepare_statement_equivalent]] [ [reflink statement] or an error ] ] [ [ [*Close statement]: behaves like [refmem any_connection close_statement][br][br] [refmem pipeline_request add_close_statement] ] [[pipeline_reference_close_statement]] [[pipeline_reference_close_statement_equivalent]] [ Possibly empty error ] ] [ [ [*Reset connection]: behaves like [refmem any_connection reset_connection][br][br] [refmem pipeline_request add_reset_connection] ] [[pipeline_reference_reset_connection]] [[pipeline_reference_reset_connection_equivalent]] [ Possibly empty error ] ] [ [ [*Set character set]: behaves like [refmem any_connection set_character_set][br][br] [refmem pipeline_request add_set_character_set] ] [[pipeline_reference_set_character_set]] [[pipeline_reference_set_character_set_equivalent]] [ Possibly empty error ] ] ] [endsect]