diff --git a/reference/mysqlnd_qc/functions/mysqlnd-qc-get-cache-info.xml b/reference/mysqlnd_qc/functions/mysqlnd-qc-get-cache-info.xml
index a9f574f892..8517032680 100644
--- a/reference/mysqlnd_qc/functions/mysqlnd-qc-get-cache-info.xml
+++ b/reference/mysqlnd_qc/functions/mysqlnd-qc-get-cache-info.xml
@@ -415,8 +415,8 @@
-
+
&reftitle.examples;
@@ -503,7 +503,6 @@ array(4) {
]]>
-
diff --git a/reference/mysqlnd_qc/functions/mysqlnd-qc-set-is-select.xml b/reference/mysqlnd_qc/functions/mysqlnd-qc-set-is-select.xml
new file mode 100644
index 0000000000..516385c503
--- /dev/null
+++ b/reference/mysqlnd_qc/functions/mysqlnd-qc-set-is-select.xml
@@ -0,0 +1,163 @@
+
+
+
+
+
+ mysqlnd_qc_set_is_select
+ Installs a callback which decides whether a statement is cached
+
+
+
+ &reftitle.description;
+
+ mixed
+ mysqlnd_qc_set_is_select
+
+ string
+ callback
+
+
+
+ Installs a callback which decides whether a statement is cached.
+
+
+ There are several ways of hinting PELC/mysqlnd_qc to cache a query.
+ By default, PECL/mysqlnd_qc attempts to cache a if caching of all statements
+ is enabled or the query string begins with a certain SQL hint.
+ The plugin internally calls a function named is_select()
+ to find out. This internal function can be replaced with a user-defined callback.
+ Then, the user-defined callback is responsible to decide whether the plugin
+ attempts to cache a statement. Because the internal function is replaced
+ with the callback, the callback gains full control. The callback is free
+ to ignore the configuration setting mysqlnd_qc.cache_by_default
+ and SQL hints.
+
+
+ The callback is invoked for every statement inspected by the plugin.
+ It is given the statements string as a parameter. The callback returns
+ &false; if the statement shall not be cached. It returns &true; to
+ make the plugin attempt to cache the statements result set, if any.
+ A so-created cache entry is given the default TTL set with the
+ PHP configuration directive mysqlnd_qc.ttl.
+ If a different TTL shall be used, the callback returns a numeric
+ value to be used as the TTL.
+
+
+ The internal is_select function is part of the internal
+ cache storage handler interface. Thus, a user-defined storage handler
+ offers the same capabilities.
+
+
+
+
+ &reftitle.parameters;
+ &no.function.parameters;
+
+
+
+ &reftitle.returnvalues;
+
+ &return.success;
+
+
+
+
+ &reftitle.examples;
+
+
+
+
+
+ true,
+ /* 3 - use TTL = 3 seconds */
+ "@SELECT\s+.*\s+FROM\s+news@ismU" => 3
+ );
+ /* check if query does match pattern */
+ foreach ($patterns as $pattern => $ttl) {
+ if (preg_match($pattern, $query)) {
+ printf("is_select(%45s): cache\n", $query);
+ return $ttl;
+ }
+ }
+ printf("is_select(%45s): do not cache\n", $query);
+ return false;
+}
+mysqlnd_qc_set_is_select("is_select");
+
+/* Connect, create and populate test table */
+$mysqli = new mysqli("host", "user", "password", "schema");
+$mysqli->query("DROP TABLE IF EXISTS test");
+$mysqli->query("CREATE TABLE test(id INT)");
+$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");
+
+/* cache put */
+$mysqli->query("SELECT id FROM test WHERE id = 1");
+/* cache hit */
+$mysqli->query("SELECT id FROM test WHERE id = 1");
+/* cache put */
+$mysqli->query("SELECT * FROM test");
+?>
+]]>
+
+ &examples.outputs;
+
+
+
+
+
+
+
+ &reftitle.seealso;
+
+
+
+ Runtime configuration
+
+
+ mysqlnd_qc.ttl
+
+
+ mysqlnd_qc.cache_by_default
+
+
+ mysqlnd_qc_set_user_handlers
+
+
+
+
+
+
+
+
diff --git a/reference/mysqlnd_qc/quickstart.xml b/reference/mysqlnd_qc/quickstart.xml
index 81fa8c2ff7..8f3615c1a1 100644
--- a/reference/mysqlnd_qc/quickstart.xml
+++ b/reference/mysqlnd_qc/quickstart.xml
@@ -661,6 +661,110 @@ Script runtime : 3 seconds
+
+ Pattern based caching
+
+ An application has three options for telling PECL/mysqlnd_qc whether a particular
+ statement shall be used. The most basic approach is to cache all statements by
+ setting
+ mysqlnd_qc.cache_by_default = 1. This apporach is often of little
+ practical value. But it enables users to make a quick estimation about
+ the maximum performance gains from caching. An application designed to
+ use a cache may able to prefix selected statements with the appropriate SQL
+ hints. However, altering an applications source code may not always be possible
+ or desired, for example, to avoid problems with software updates. Therefore,
+ PECL/mysqlnd_qc allows setting a callback which decides if a query is to be
+ cached.
+
+
+ The callback is installed with the mysqlnd_qc_set_is_select
+ function. The callback is given the statement string of every statement
+ inspected by the plugin. Then, the callback can decide whether to cache
+ the function. The callback is supposed to return FALSE
+ if the statement shall not be cached. A return value of TRUE
+ makes the plugin try to add the statement into the cache. The cache entry
+ will be given the default TTL (
+ mysqlnd_qc.ttl). If the callback returns
+ a numberical value it is used as the TTL instead of the global default.
+
+
+
+
+
+
+
+ true,
+ /* 3 - use TTL = 3 seconds */
+ "@SELECT\s+.*\s+FROM\s+news@ismU" => 3
+ );
+
+ /* check if query does match pattern */
+ foreach ($patterns as $pattern => $ttl) {
+ if (preg_match($pattern, $query)) {
+ printf("is_select(%45s): cache\n", $query);
+ return $ttl;
+ }
+ }
+ printf("is_select(%45s): do not cache\n", $query);
+ return false;
+}
+/* install callback */
+mysqlnd_qc_set_is_select("is_select");
+
+/* Connect, create and populate test table */
+$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
+$mysqli->query("DROP TABLE IF EXISTS test");
+$mysqli->query("CREATE TABLE test(id INT)");
+$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)");
+
+/* cache put */
+$mysqli->query("SELECT id FROM test WHERE id = 1");
+/* cache hit */
+$mysqli->query("SELECT id FROM test WHERE id = 1");
+/* cache put */
+$mysqli->query("SELECT * FROM test");
+
+$stats = mysqlnd_qc_get_core_stats();
+printf("Cache put: %d\n", $stats['cache_put']);
+printf("Cache hit: %d\n", $stats['cache_hit']);
+?>
+]]>
+
+ &examples.outputs;
+
+
+
+
+
+
+ The examples callback tests if a statement string matches a pattern.
+ If this is the case, it either returns TRUE to cache
+ the statement using the global default TTL or an alternative TTL.
+
+
+ To minimize application changes the callback can put into and registered
+ in an auto prepend file.
+
+
+
Slam defense