VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/6.2-query-execution-messages

⇱ Query Execution Messages | stefanak-michal/php-bolt-driver | DeepWiki


Loading...
Last indexed: 14 February 2026 (a283bd)
Menu

Query Execution Messages

This page documents the RUN message, which is the primary mechanism for executing Cypher queries in the Bolt protocol. The RUN message submits a query string with parameters and optional metadata to the database server for execution.

For information about retrieving query results after execution, see Result Streaming Messages. For transaction control messages (BEGIN, COMMIT, ROLLBACK), see Transaction Control Messages.

Purpose and Scope

The RUN message is used to:

  • Execute Cypher queries against the database
  • Submit parameterized queries with bound values
  • Specify query execution metadata (database selection, timeouts, transaction configuration)
  • Initiate result streams that are consumed by subsequent PULL or DISCARD messages

This page covers the message structure, parameter handling, and evolution across protocol versions V1 through V6.

Message Structure Evolution

The RUN message has evolved across protocol versions to support additional features while maintaining backward compatibility through trait composition.


Sources: src/protocol/v1/RunMessage.php1-24 src/protocol/v3/RunMessage.php1-43

V1/V2 Implementation

The V1 and V2 protocols implement RUN with two arguments:

FieldTypeDescription
queryStringCypher query text
parametersDictionaryQuery parameter bindings

Implementation: src/protocol/v1/RunMessage.php17-22

public function run(string $query, array $parameters = []): static
{
 $this->write($this->packer->pack(0x10, $query, (object)$parameters));
 $this->pipelinedMessages[] = Message::RUN;
 return $this;
}

The method:

  • Packs the RUN signature 0x10 with query string and parameters
  • Converts the $parameters array to an object for PackStream serialization
  • Appends Message::RUN to the pipeline queue
  • Returns the protocol instance for method chaining

Sources: src/protocol/v1/RunMessage.php17-22

V3-V6 Implementation

Starting with V3, the RUN message accepts an additional extra dictionary for metadata:

FieldTypeDescription
queryStringCypher query text
parametersDictionaryQuery parameter bindings
extraDictionaryExecution metadata (see below)

Implementation: src/protocol/v3/RunMessage.php18-28

public function run(string $query, array $parameters = [], array $extra = []): static
{
 $this->write($this->packer->pack(
 0x10,
 $query,
 (object)$parameters,
 (object)$extra
 ));
 $this->pipelinedMessages[] = Message::RUN;
 return $this;
}

Sources: src/protocol/v3/RunMessage.php18-28

Extra Metadata Dictionary

The extra dictionary introduced in V3 supports various execution metadata keys:

KeyTypeProtocolsDescription
bookmarksList[String]V3+Transaction bookmarks for causal consistency
tx_timeoutIntegerV3+Transaction timeout in milliseconds
tx_metadataDictionaryV3+User-defined transaction metadata
modeStringV3+Access mode: "r" (read) or "w" (write)
dbStringV4+Target database name (null for default)
imp_userStringV4.4+Impersonated user for query execution

The server may return additional metadata in the RUN response, such as:

  • qid (Query ID): Identifies the query stream for parameterized PULL/DISCARD in V4+
  • fields: Column names in the result set
  • t_first: Time to first record availability

Sources: src/protocol/v3/RunMessage.php18-28 tests/protocol/V4_4Test.php27-59

Response Handling

The RUN message response is handled differently based on protocol version capabilities:


Sources: src/protocol/v3/RunMessage.php35-41 tests/protocol/V1Test.php65-102

Response Processing

The _run() protected method processes RUN responses:

Implementation: src/protocol/v3/RunMessage.php35-41

protected function _run(): iterable
{
 $content = $this->read($signature);
 if (array_key_exists('qid', $content))
 $this->openStreams++;
 yield new Response(Message::RUN, $signature, $content);
}

Key behaviors:

  • Reads the response signature and content from the connection
  • Checks for qid field (Query ID) in V4+ protocols
  • Increments openStreams counter if qid is present
  • Yields a Response object containing the message type, signature, and content

Sources: src/protocol/v3/RunMessage.php35-41

State Transitions

The RUN message triggers specific state transitions in the protocol state machine:


State Transition Rules

Current StateResponseNew StateNotes
READYSUCCESSSTREAMINGQuery executing, awaiting result consumption
TX_READYSUCCESSTX_STREAMINGQuery executing within explicit transaction
READY / TX_READYFAILUREFAILEDQuery execution failed (syntax error, etc.)
INTERRUPTEDAnyINTERRUPTEDMessage ignored until RESET

Sources: tests/protocol/V1Test.php89-101 tests/protocol/V3Test.php97-109

Usage Patterns

Basic Query Execution (V1/V2)

Test Example: tests/protocol/V1Test.php65-102

// Successful query execution
$cls->serverState = ServerState::READY;
$cls->run('RETURN 1');
$response = $cls->getResponse();
// serverState transitions to STREAMING
// response->signature == Signature::SUCCESS

// Query with syntax error
$cls->serverState = ServerState::READY;
$cls->run('not a CQL');
$response = $cls->getResponse();
// serverState transitions to FAILED
// response->signature == Signature::FAILURE

Sources: tests/protocol/V1Test.php89-101

Query with Metadata (V3+)

Test Example: tests/protocol/V3Test.php70-110

// Query with parameters and extra metadata
$protocol->run(
 'MATCH (n:User {id: $userId}) RETURN n',
 ['userId' => 123],
 [
 'db' => 'myDatabase',
 'tx_timeout' => 30000,
 'mode' => 'r'
 ]
);

The extra dictionary allows:

  • Database selection via db key
  • Transaction timeout configuration
  • Read/write mode specification
  • Bookmark passing for causal consistency

Sources: src/protocol/v3/RunMessage.php18-28 tests/protocol/V3Test.php70-110

Message Encoding Examples

V1/V2 Encoding

From Test: tests/protocol/V1Test.php72-87

The test validates the binary encoding for run('RETURN 1'):

Hex bytes written:
0001b2 // Structure with 2 fields
000110 // Signature: 0x10 (RUN)
00098852455455524e2031 // String: "RETURN 1"
0001a0 // Empty dictionary (parameters)

Sources: tests/protocol/V1Test.php72-87

V3+ Encoding

From Test: tests/protocol/V3Test.php77-95

The test validates the binary encoding for run('RETURN 1', [], []):

Hex bytes written:
0001b3 // Structure with 3 fields
000110 // Signature: 0x10 (RUN)
00098852455455524e2031 // String: "RETURN 1"
0001a0 // Empty dictionary (parameters)
0001a0 // Empty dictionary (extra)

Sources: tests/protocol/V3Test.php77-95

Pipelining Behavior

The RUN message supports pipelining, allowing multiple messages to be sent before reading responses:


The pipelinedMessages array tracks outgoing messages, allowing the protocol layer to match responses to requests in order. This reduces network round-trips by batching writes.

Sources: src/protocol/v1/RunMessage.php20 src/protocol/v3/RunMessage.php26

Error Handling

RUN messages can fail for various reasons:

Error ConditionResponse SignatureServer State Transition
Syntax error in queryFAILUREREADYFAILED
Invalid parametersFAILUREREADYFAILED
Database not found (V4+)FAILUREREADYFAILED
Permission deniedFAILUREREADYFAILED
Connection interruptedIGNOREDINTERRUPTED (no change)

Test Reference: tests/protocol/V1Test.php94-101

When a RUN message fails:

  1. The server responds with a FAILURE message containing error details
  2. The server state transitions to FAILED
  3. The client must send ACK_FAILURE (V1/V2) or RESET (V3+) to recover
  4. No result stream is created

Sources: tests/protocol/V1Test.php94-101 tests/protocol/V3Test.php102-109

Protocol Version Comparison


Key Differences:

FeatureV1/V2V3+
Extra metadataNot supportedSupported via extra dictionary
Query ID trackingNot usedqid field for stream identification
Database selectionNot supporteddb key in extra metadata
Transaction metadataNot supportedtx_metadata in extra
ImpersonationNot supportedimp_user in V4.4+

Sources: src/protocol/v1/RunMessage.php1-24 src/protocol/v3/RunMessage.php1-43

Integration with Message Pipeline

The RUN message integrates with the protocol's message pipeline through the pipelinedMessages array:


This pipeline design allows:

  • Multiple messages to be queued before reading responses
  • Automatic matching of responses to request types
  • Efficient network utilization through batching

Sources: src/protocol/v1/RunMessage.php17-22 src/protocol/v3/RunMessage.php18-28