Skip to content

Commit 0c19bf6

Browse files
committed
prepared: docstring for PreparedStatement
1 parent 1fcadc9 commit 0c19bf6

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

scylla/src/statement/prepared_statement.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,68 @@ use crate::transport::execution_profile::ExecutionProfileHandle;
2222
use crate::transport::partitioner::{Partitioner, PartitionerHasher, PartitionerName};
2323

2424
/// Represents a statement prepared on the server.
25+
///
26+
/// To prepare a statement, simply execute [`Session::prepare`](crate::transport::session::Session::prepare).
27+
///
28+
/// If you plan on reusing the statement, or bounding some values to it during execution, always
29+
/// prefer using prepared statements over [`Session::query`](crate::transport::session::Session::query).
30+
///
31+
/// Benefits that prepared statements have to offer:
32+
/// * Performance - a prepared statement holds information about metadata
33+
/// that allows to carry out a statement execution in a type safe manner.
34+
/// When [`Session::query`](crate::transport::session::Session::query) is called with
35+
/// non-empty bound values, the driver has to prepare the statement before execution (to provide type safety).
36+
/// This implies 2 round trips per [`Session::query`](crate::transport::session::Session::query).
37+
/// On the other hand, the cost of [`Session::execute`](crate::transport::session::Session::execute) is only 1 round trip.
38+
/// * Increased type-safety - bound values' types are validated with
39+
/// the [`PreparedMetadata`] received from the server during the serialization.
40+
/// * Improved load balancing - thanks to statement metadata, the driver is able
41+
/// to compute a set of destined replicas for the statement execution. These replicas
42+
/// will be preferred when choosing the node (and shard) to send the request to.
43+
/// * Result deserialization optimization - see [`PreparedStatement::set_use_cached_result_metadata`].
44+
///
45+
/// # Clone implementation
46+
/// Cloning a prepared statement is a cheap operation. It only
47+
/// requires copying a couple of small fields and some [Arc] pointers.
48+
/// Always prefer cloning over executing [`Session::prepare`](crate::transport::session::Session::prepare)
49+
/// multiple times to save some roundtrips.
50+
///
51+
/// # Statement repreparation
52+
/// When schema is updated, the server is supposed to invalidate its
53+
/// prepared statement caches. Then, if client tries to execute a given statement,
54+
/// the server will respond with an error. Users should not worry about it, since
55+
/// the driver handles it properly and tries to reprepare the statement.
56+
/// However, there are some cases when client-side prepared statement should be dropped
57+
/// and prepared once again via [`Session::prepare`](crate::transport::session::Session::prepare) -
58+
/// see the mention about altering schema below.
59+
///
60+
/// # Altering schema
61+
/// If for some reason you decided to alter the part of schema that corresponds to given prepared
62+
/// statement, then the corresponding statement (and its copies obtained via [`PreparedStatement::clone`]) should
63+
/// be dropped. The statement should be prepared again.
64+
///
65+
/// There are two reasons for this:
66+
///
67+
/// ### CQL v4 protocol limitations
68+
/// The driver only supports CQL version 4.
69+
///
70+
/// In multi-client scenario, only the first client which reprepares the statement
71+
/// will receive the updated metadata from the server.
72+
/// The rest of the clients will still hold on the outdated metadata.
73+
/// In version 4 of CQL protocol there is currently no way for the server to notify other
74+
/// clients about prepared statement's metadata update.
75+
///
76+
/// ### Client-side metadata immutability
77+
/// The decision was made to keep client-side metadata immutable.
78+
/// Mainly because of the CQLv4 limitations mentioned above. This means
79+
/// that metadata is not updated during statement repreparation.
80+
/// This raises two issues:
81+
/// * bound values serialization errors - since [`PreparedMetadata`] is not updated
82+
/// * result deserialization errors - when [`PreparedStatement::set_use_cached_result_metadata`] is enabled,
83+
/// since [`ResultMetadata`] is not updated
84+
///
85+
/// So, to mitigate those issues, drop the outdated [`PreparedStatement`] manually
86+
/// and prepare it again against the new schema.
2587
#[derive(Debug)]
2688
pub struct PreparedStatement {
2789
pub(crate) config: StatementConfig,

scylla/src/transport/session.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,8 @@ impl Session {
839839
/// > must be sent as bound values
840840
/// > (see [performance section](https://rust-driver.docs.scylladb.com/stable/queries/prepared.html#performance))
841841
///
842-
/// See [the book](https://rust-driver.docs.scylladb.com/stable/queries/prepared.html) for more information
842+
/// See [the book](https://rust-driver.docs.scylladb.com/stable/queries/prepared.html) for more information.
843+
/// See the documentation of [`PreparedStatement`].
843844
///
844845
/// # Arguments
845846
/// * `query` - query to prepare, can be just a `&str` or the [Query] struct.

0 commit comments

Comments
 (0)