@@ -22,6 +22,68 @@ use crate::transport::execution_profile::ExecutionProfileHandle;
2222use 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 ) ]
2688pub struct PreparedStatement {
2789 pub ( crate ) config : StatementConfig ,
0 commit comments