Skip to content

Commit 3cd724a

Browse files
committed
Bug#30030187: REDUCE DEPENDENCIES ON SQL_CLASS.H [noclose]
Move code that accesses data structures in sql_class.h from header files to .cc files. Patch 1. Change-Id: I28edb9dff035f5e239e3d84a77339e8e320e2582
1 parent 44e1252 commit 3cd724a

8 files changed

+1373
-1170
lines changed

sql/item_pfs_func.cc

+11-1
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,19 @@
2929

3030
#include "sql/item_pfs_func.h"
3131

32+
#include <stdio.h>
3233
#include <cmath>
3334

34-
#include "sql/derror.h" // ER_THD
35+
#include "m_ctype.h"
36+
#include "my_dbug.h"
37+
#include "my_psi_config.h"
38+
#include "my_sys.h"
39+
#include "mysql/components/services/psi_thread_bits.h"
40+
#include "mysqld_error.h"
41+
#include "pfs_thread_provider.h"
42+
#include "sql/field.h"
43+
#include "sql/item.h"
44+
#include "sql/sql_class.h"
3545
#include "sql/sql_lex.h"
3646

3747
extern bool pfs_enabled;

sql/item_pfs_func.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,14 @@
2525

2626
/* Function items used by mysql */
2727

28+
#include "my_inttypes.h"
2829
#include "sql/item_func.h"
2930
#include "sql/item_strfunc.h"
30-
#include "sql/sql_class.h"
31+
#include "sql/parse_tree_node_base.h"
32+
#include "sql_string.h"
33+
34+
class Item;
35+
class THD;
3136

3237
/** ps_current_thread_id() */
3338

sql/parse_tree_handler.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,13 @@ bool PT_handler_read_base::contextualize(Parse_context *pc) {
9898
!select->add_table_to_list(pc->thd, table, nullptr, 0))
9999
return true;
100100

101-
if (itemize_safe(pc, &m_opt_where_clause)) return true;
101+
if (m_opt_where_clause != nullptr &&
102+
m_opt_where_clause->itemize(pc, &m_opt_where_clause))
103+
return true;
102104
select->set_where_cond(m_opt_where_clause);
103105

104-
if (contextualize_safe(pc, m_opt_limit_clause)) return true;
106+
if (m_opt_limit_clause != nullptr && m_opt_limit_clause->contextualize(pc))
107+
return true;
105108

106109
lex->expr_allows_subselect = true;
107110

sql/parse_tree_items.cc

+278-4
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,35 @@
2222

2323
#include "sql/parse_tree_items.h"
2424

25+
#include <sys/types.h>
26+
27+
#include "m_string.h"
2528
#include "my_dbug.h"
2629
#include "my_sqlcommand.h"
30+
#include "my_sys.h"
31+
#include "my_time.h"
2732
#include "mysql/udf_registration_types.h"
2833
#include "mysql_com.h"
34+
#include "mysqld_error.h"
2935
#include "sql/auth/auth_acls.h"
3036
#include "sql/item_cmpfunc.h" // Item_func_eq
31-
#include "sql/mysqld.h" // using_udf_functions
37+
#include "sql/item_create.h"
38+
#include "sql/mysqld.h" // using_udf_functions
3239
#include "sql/parse_tree_nodes.h"
3340
#include "sql/protocol.h"
3441
#include "sql/sp.h"
42+
#include "sql/sp_head.h"
3543
#include "sql/sp_pcontext.h" // sp_pcontext
44+
#include "sql/sql_class.h"
45+
#include "sql/sql_error.h"
46+
#include "sql/sql_lex.h"
47+
#include "sql/sql_list.h"
3648
#include "sql/sql_udf.h"
49+
#include "sql/system_variables.h"
3750
#include "sql/table.h"
3851
#include "sql/trigger_def.h"
52+
#include "sql_string.h"
53+
#include "template_utils.h"
3954

4055
/**
4156
Apply a truth test to given expression. Either the expression can implement
@@ -150,7 +165,7 @@ bool PTI_table_wild::itemize(Parse_context *pc, Item **item) {
150165
if (super::itemize(pc, item)) return true;
151166

152167
schema = pc->thd->get_protocol()->has_client_capability(CLIENT_NO_SCHEMA)
153-
? NullS
168+
? nullptr
154169
: schema;
155170
*item = new (pc->mem_root) Item_field(POS(), schema, table, "*");
156171
if (*item == NULL || (*item)->itemize(pc, item)) return true;
@@ -395,7 +410,8 @@ bool PTI_simple_ident_q_3d::itemize(Parse_context *pc, Item **res) {
395410
} else {
396411
*res = new (pc->mem_root) Item_ref(POS(), schema, table, field);
397412
}
398-
return *res == nullptr || (*res)->itemize(pc, res);
413+
if (*res == nullptr) return true;
414+
return (*res)->itemize(pc, res);
399415
}
400416

401417
bool PTI_simple_ident_q_2d::itemize(Parse_context *pc, Item **res) {
@@ -449,9 +465,267 @@ bool PTI_simple_ident_q_2d::itemize(Parse_context *pc, Item **res) {
449465
return false;
450466
}
451467

468+
bool PTI_simple_ident_nospvar_ident::itemize(Parse_context *pc, Item **res) {
469+
if (super::itemize(pc, res)) return true;
470+
471+
if ((pc->select->parsing_place != CTX_HAVING) ||
472+
(pc->select->get_in_sum_expr() > 0)) {
473+
*res = new (pc->mem_root) Item_field(POS(), nullptr, nullptr, ident.str);
474+
} else {
475+
*res = new (pc->mem_root) Item_ref(POS(), nullptr, nullptr, ident.str);
476+
}
477+
if (*res == nullptr) return true;
478+
return (*res)->itemize(pc, res);
479+
}
480+
452481
bool PTI_truth_transform::itemize(Parse_context *pc, Item **res) {
453482
if (super::itemize(pc, res) || expr->itemize(pc, &expr)) return true;
454483

455484
*res = change_truth_value_of_condition(pc, expr, truth_test);
456-
return *res == NULL;
485+
return *res == nullptr;
486+
}
487+
488+
bool PTI_function_call_nonkeyword_now::itemize(Parse_context *pc, Item **res) {
489+
if (super::itemize(pc, res)) return true;
490+
491+
pc->thd->lex->safe_to_cache_query = false;
492+
return false;
493+
}
494+
495+
bool PTI_text_literal_text_string::itemize(Parse_context *pc, Item **res) {
496+
if (super::itemize(pc, res)) return true;
497+
498+
THD *thd = pc->thd;
499+
LEX_STRING tmp;
500+
const CHARSET_INFO *cs_con = thd->variables.collation_connection;
501+
const CHARSET_INFO *cs_cli = thd->variables.character_set_client;
502+
uint repertoire = is_7bit && my_charset_is_ascii_based(cs_cli)
503+
? MY_REPERTOIRE_ASCII
504+
: MY_REPERTOIRE_UNICODE30;
505+
if (thd->charset_is_collation_connection ||
506+
(repertoire == MY_REPERTOIRE_ASCII && my_charset_is_ascii_based(cs_con)))
507+
tmp = literal;
508+
else {
509+
if (thd->convert_string(&tmp, cs_con, literal.str, literal.length, cs_cli))
510+
return true;
511+
}
512+
init(tmp.str, tmp.length, cs_con, DERIVATION_COERCIBLE, repertoire);
513+
return false;
514+
}
515+
516+
bool PTI_text_literal_concat::itemize(Parse_context *pc, Item **res) {
517+
Item *tmp_head;
518+
if (super::itemize(pc, res) || head->itemize(pc, &tmp_head)) return true;
519+
520+
DBUG_ASSERT(tmp_head->type() == STRING_ITEM);
521+
Item_string *head_str = down_cast<Item_string *>(tmp_head);
522+
head_str->append(literal.str, literal.length);
523+
if ((head_str->collation.repertoire & MY_REPERTOIRE_EXTENDED) == 0) {
524+
// If the string has been pure ASCII so far, check the new part.
525+
const CHARSET_INFO *cs = pc->thd->variables.collation_connection;
526+
head_str->collation.repertoire |=
527+
my_string_repertoire(cs, literal.str, literal.length);
528+
}
529+
*res = head_str;
530+
return false;
531+
}
532+
533+
bool PTI_temporal_literal::itemize(Parse_context *pc, Item **res) {
534+
if (super::itemize(pc, res)) return true;
535+
536+
*res = create_temporal_literal(pc->thd, literal.str, literal.length, cs,
537+
field_type, true);
538+
return *res == nullptr;
539+
}
540+
541+
bool PTI_variable_aux_set_var::itemize(Parse_context *pc, Item **res) {
542+
if (super::itemize(pc, res)) return true;
543+
544+
LEX *lex = pc->thd->lex;
545+
if (!lex->parsing_options.allows_variable) {
546+
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
547+
return true;
548+
}
549+
lex->set_uncacheable(pc->select, UNCACHEABLE_RAND);
550+
return lex->set_var_list.push_back(this);
551+
}
552+
553+
bool PTI_variable_aux_ident_or_text::itemize(Parse_context *pc, Item **res) {
554+
if (super::itemize(pc, res)) return true;
555+
556+
LEX *lex = pc->thd->lex;
557+
if (!lex->parsing_options.allows_variable) {
558+
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
559+
return true;
560+
}
561+
lex->set_uncacheable(pc->select, UNCACHEABLE_RAND);
562+
return false;
563+
}
564+
565+
bool PTI_variable_aux_3d::itemize(Parse_context *pc, Item **res) {
566+
if (super::itemize(pc, res)) return true;
567+
568+
LEX *lex = pc->thd->lex;
569+
if (!lex->parsing_options.allows_variable) {
570+
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
571+
return true;
572+
}
573+
574+
/* disallow "SELECT @@global.global.variable" */
575+
if (ident1.str && ident2.str && check_reserved_words(ident1.str)) {
576+
error(pc, ident1_pos);
577+
return true;
578+
}
579+
580+
LEX_STRING *domain;
581+
LEX_STRING *variable;
582+
if (ident2.str && !is_key_cache_variable_suffix(ident2.str)) {
583+
LEX_STRING component_var;
584+
domain = &ident1;
585+
variable = &ident2;
586+
String tmp_name;
587+
if (tmp_name.reserve(domain->length + 1 + variable->length + 1) ||
588+
tmp_name.append(domain->str) || tmp_name.append('.') ||
589+
tmp_name.append(variable->str))
590+
return true; // OOM
591+
component_var.str = tmp_name.c_ptr();
592+
component_var.length = tmp_name.length();
593+
variable->str = nullptr;
594+
variable->length = 0;
595+
*res = get_system_var(pc, var_type, component_var, *variable);
596+
} else
597+
*res = get_system_var(pc, var_type, ident1, ident2);
598+
if (*res == nullptr) return true;
599+
if (is_identifier(ident1, "warning_count") ||
600+
is_identifier(ident1, "error_count")) {
601+
/*
602+
"Diagnostics variable" used in a non-diagnostics statement.
603+
Save the information we need for the former, but clear the
604+
rest of the diagnostics area on account of the latter.
605+
See reset_condition_info().
606+
*/
607+
lex->keep_diagnostics = DA_KEEP_COUNTS;
608+
}
609+
if (!down_cast<Item_func_get_system_var *>(*res)->is_written_to_binlog())
610+
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE);
611+
612+
return false;
613+
}
614+
615+
bool PTI_count_sym::itemize(Parse_context *pc, Item **res) {
616+
args[0] = new (pc->mem_root) Item_int(int32{0}, 1);
617+
if (args[0] == nullptr) return true;
618+
return super::itemize(pc, res);
619+
}
620+
621+
bool PTI_in_sum_expr::itemize(Parse_context *pc, Item **res) {
622+
pc->select->in_sum_expr++;
623+
if (super::itemize(pc, res) || expr->itemize(pc, &expr)) return true;
624+
pc->select->in_sum_expr--;
625+
*res = expr;
626+
return false;
627+
}
628+
629+
bool PTI_odbc_date::itemize(Parse_context *pc, Item **res) {
630+
if (super::itemize(pc, res) || expr->itemize(pc, &expr)) return true;
631+
632+
*res = nullptr;
633+
/*
634+
If "expr" is reasonably short pure ASCII string literal,
635+
try to parse known ODBC style date, time or timestamp literals,
636+
e.g:
637+
SELECT {d'2001-01-01'};
638+
SELECT {t'10:20:30'};
639+
SELECT {ts'2001-01-01 10:20:30'};
640+
*/
641+
if (expr->type() == Item::STRING_ITEM &&
642+
expr->collation.repertoire == MY_REPERTOIRE_ASCII) {
643+
String buf;
644+
String *tmp_str = expr->val_str(&buf);
645+
if (tmp_str->length() < MAX_DATE_STRING_REP_LENGTH * 4) {
646+
enum_field_types type = MYSQL_TYPE_STRING;
647+
ErrConvString str(tmp_str);
648+
LEX_STRING *ls = &ident;
649+
if (ls->length == 1) {
650+
if (ls->str[0] == 'd') /* {d'2001-01-01'} */
651+
type = MYSQL_TYPE_DATE;
652+
else if (ls->str[0] == 't') /* {t'10:20:30'} */
653+
type = MYSQL_TYPE_TIME;
654+
} else if (ls->length == 2) /* {ts'2001-01-01 10:20:30'} */
655+
{
656+
if (ls->str[0] == 't' && ls->str[1] == 's') type = MYSQL_TYPE_DATETIME;
657+
}
658+
if (type != MYSQL_TYPE_STRING)
659+
*res = create_temporal_literal(pc->thd, str.ptr(), str.length(),
660+
system_charset_info, type, false);
661+
}
662+
}
663+
if (*res == nullptr) *res = expr;
664+
return false;
665+
}
666+
667+
bool PTI_limit_option_ident::itemize(Parse_context *pc, Item **res) {
668+
if (super::itemize(pc, res)) return true;
669+
670+
LEX *lex = pc->thd->lex;
671+
sp_head *sp = lex->sphead;
672+
const char *query_start_ptr =
673+
sp ? sp->m_parser_data.get_current_stmt_start_ptr() : nullptr;
674+
675+
Item_splocal *v = create_item_for_sp_var(
676+
pc->thd, ident, nullptr, query_start_ptr, ident_loc.start, ident_loc.end);
677+
if (v == nullptr) return true;
678+
679+
lex->safe_to_cache_query = false;
680+
681+
if (v->type() != Item::INT_ITEM) {
682+
my_error(ER_WRONG_SPVAR_TYPE_IN_LIMIT, MYF(0));
683+
return true;
684+
}
685+
686+
v->limit_clause_param = true;
687+
*res = v;
688+
return false;
689+
}
690+
691+
bool PTI_limit_option_param_marker::itemize(Parse_context *pc, Item **res) {
692+
Item *tmp_param;
693+
if (super::itemize(pc, res) || param_marker->itemize(pc, &tmp_param))
694+
return true;
695+
696+
/*
697+
The Item_param::type() function may return various values, so we can't
698+
simply compare tmp_param->type() with some constant, cast tmp_param
699+
to Item_param* and assign the result back to param_marker.
700+
OTOH we ensure that Item_param::itemize() always substitute the output
701+
parameter with "this" pointer of Item_param object, so we can skip
702+
the check and the assignment.
703+
*/
704+
DBUG_ASSERT(tmp_param == param_marker);
705+
706+
param_marker->limit_clause_param = true;
707+
*res = param_marker;
708+
return false;
709+
}
710+
711+
bool PTI_context::itemize(Parse_context *pc, Item **res) {
712+
if (super::itemize(pc, res)) return true;
713+
714+
pc->select->parsing_place = m_parsing_place;
715+
716+
if (expr->itemize(pc, &expr)) return true;
717+
718+
if (!expr->is_bool_func()) {
719+
expr = make_condition(pc, expr);
720+
if (expr == nullptr) return true;
721+
}
722+
723+
// Ensure we're resetting parsing place of the right select
724+
DBUG_ASSERT(pc->select->parsing_place == m_parsing_place);
725+
pc->select->parsing_place = CTX_NONE;
726+
DBUG_ASSERT(expr != nullptr);
727+
expr->apply_is_true();
728+
729+
*res = expr;
730+
return false;
457731
}

0 commit comments

Comments
 (0)