diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 32cdbe138b284..0f3124a6c2ae9 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6231,7 +6231,7 @@ ER_SLAVE_IGNORE_SERVER_IDS eng "The requested server id %d clashes with the slave startup option --replicate-same-server-id" ger "Die angeforderte Server-ID %d steht im Konflikt mit der Startoption --replicate-same-server-id für den Slave" ER_QUERY_CACHE_DISABLED - eng "Query cache is disabled; set query_cache_type to ON or DEMAND to enable it" + eng "Query cache is disabled; set query_cache_type to ON or DEMAND or DEMAND_NO_PRUNE to enable it" ER_SAME_NAME_PARTITION_FIELD eng "Duplicate partition field name '%-.192s'" ger "Partitionsfeld '%-.192s' ist ein Duplikat" diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index cf68ba369978e..d4be6aa8fd92a 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -766,6 +766,36 @@ void Query_cache::unlock(void) DBUG_VOID_RETURN; } +/** + Helper function for determine if a SELECT statement has a SQL_CACHE + directive. + + @param sql A pointer to the first white space character after SELECT + + @return + @retval TRUE The character string contains SQL_CACHE + @retval FALSE No directive found. +*/ + +static bool has_cache_directive(const char *sql) +{ + while (is_white_space(*sql)) + sql++; + + if (my_toupper(system_charset_info, sql[0]) == 'S' && + my_toupper(system_charset_info, sql[1]) == 'Q' && + my_toupper(system_charset_info, sql[2]) == 'L' && + my_toupper(system_charset_info, sql[3]) == '_' && + my_toupper(system_charset_info, sql[4]) == 'C' && + my_toupper(system_charset_info, sql[5]) == 'A' && + my_toupper(system_charset_info, sql[6]) == 'C' && + my_toupper(system_charset_info, sql[7]) == 'H' && + my_toupper(system_charset_info, sql[8]) == 'E' && + my_isspace(system_charset_info, sql[9])) + return TRUE; + + return FALSE; +} /** Helper function for determine if a SELECT statement has a SQL_NO_CACHE @@ -1817,14 +1847,28 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) goto err; } - if ((sql_end - sql) > 20 && has_no_cache_directive(sql+6)) + if ((sql_end - sql) > 20) { - /* - We do not increase 'refused' statistics here since it will be done - later when the query is parsed. - */ - DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive")); - goto err; + if (has_no_cache_directive(sql+6)) + { + /* + We do not increase 'refused' statistics here since it will be done + later when the query is parsed. + */ + DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive")); + goto err; + } + /* DEMAND, use DEMAND_NO_PUNE to avoid this check */ + if (thd->variables.query_cache_type==2 && !has_cache_directive(sql+6)) + { + /* + We do not increase 'refused' statistics here since it will be done + later when the query is parsed. + */ + DBUG_PRINT("qcache", + ("The statement don't have a SQL_CACHE directive when query_cache_type=DEMAND")); + goto err; + } } { /* @@ -4083,8 +4127,9 @@ Query_cache::is_cacheable(THD *thd, LEX *lex, if (thd->lex->safe_to_cache_query && (thd->variables.query_cache_type == 1 || - (thd->variables.query_cache_type == 2 && (lex->select_lex.options & - OPTION_TO_QUERY_CACHE))) && + ((thd->variables.query_cache_type == 2 || /* DEMAND */ + thd->variables.query_cache_type == 3) && /* DEMAND_NO_PRUNE */ + (lex->select_lex.options & OPTION_TO_QUERY_CACHE))) && qc_is_able_to_intercept_result(thd)) { DBUG_PRINT("qcache", ("options: %lx %lx type: %u", diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 0c68409dd2567..e7db96d3f4a0c 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2600,7 +2600,7 @@ static Sys_var_ulong Sys_query_cache_min_res_unit( BLOCK_SIZE(8), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_qcache_min_res_unit)); -static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", 0 }; +static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", "DEMAND_NO_PRUNE", 0 }; static bool check_query_cache_type(sys_var *self, THD *thd, set_var *var) { if (query_cache.is_disable_in_progress()) @@ -2639,7 +2639,8 @@ static Sys_var_enum Sys_query_cache_type( "query_cache_type", "OFF = Don't cache or retrieve results. ON = Cache all results " "except SELECT SQL_NO_CACHE ... queries. DEMAND = Cache only " - "SELECT SQL_CACHE ... queries", + "SELECT SQL_CACHE ... queries. DEMAND_NO_PRUNE = DEMAND , but allow " + "fetch query from cache previous inserted without SQL_CACHE", SESSION_VAR(query_cache_type), CMD_LINE(REQUIRED_ARG), query_cache_type_names, DEFAULT(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_query_cache_type),