summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-08-21 15:23:45 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-08-21 15:23:45 +0300
commit32ec5fb979760ba2db52d8afc39e8e090cf80a9c (patch)
tree354038721b2f99c9834c31c4a6f3a5fa23c21341 /sql
parente8de75db88acdf228237fbebad7f4c8f05e5cc1f (diff)
parent9de2e60d7491fcf3cd1f20a4be715ef0bedc316f (diff)
downloadmariadb-git-32ec5fb979760ba2db52d8afc39e8e090cf80a9c.tar.gz
Merge 10.2 into 10.3
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_parse.cc103
-rw-r--r--sql/sql_select.cc19
-rw-r--r--sql/sql_statistics.cc7
-rw-r--r--sql/tztime.cc64
-rw-r--r--sql/wsrep_sst.cc6
5 files changed, 150 insertions, 49 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 9bd2e6040f0..022c6519a8a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -8248,10 +8248,6 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
TABLE_LIST *head= join_list->head();
if (head->nested_join && head->nested_join->nest_type & REBALANCED_NEST)
{
- List_iterator<TABLE_LIST> li(*join_list);
- li++;
- while (li++)
- li.remove();
DBUG_RETURN(head);
}
if (unlikely(!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
@@ -8335,13 +8331,13 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
context and right-associative in another context.
In this query
- SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1)
+ SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1)
JOIN is left-associative and the query Q1 is interpreted as
- SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a.
+ SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a.
While in this query
- SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2)
+ SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2)
JOIN is right-associative and the query Q2 is interpreted as
- SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b
+ SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b
JOIN is right-associative if it is used with ON clause or with USING clause.
Otherwise it is left-associative.
@@ -8387,9 +8383,9 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
J LJ - ON
/ \ / \
- t1 LJ - ON (TQ3*) => J t2
- / \ / \
- t3 t2 t1 t3
+ t1 LJ - ON (TQ3*) => t3 J
+ / \ / \
+ t3 t2 t1 t2
With several left associative JOINs
SELECT * FROM t1 JOIN t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q4)
@@ -8397,15 +8393,15 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
J1 LJ - ON
/ \ / \
- t1 LJ - ON J2 t4
+ t1 J2 J2 t4
/ \ => / \
- J2 t4 J1 t3
- / \ / \
- t2 t3 t1 t2
+ t2 LJ - ON J1 t3
+ / \ / \
+ t3 t4 t1 t2
- Here's another example:
- SELECT *
- FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5)
+ Here's another example:
+ SELECT *
+ FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5)
J LJ - ON
/ \ / \
@@ -8415,15 +8411,58 @@ void st_select_lex::add_joined_table(TABLE_LIST *table)
/ \
t3 t4
- If the transformed nested join node node is a natural join node like in
- the following query
- SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6)
- the transformation additionally has to take care about setting proper
- references in the field natural_join for both operands of the natural
- join operation.
- The function also has to change the name resolution context for ON
- expressions used in the transformed join expression to take into
- account the tables of the left_op node.
+ If the transformed nested join node node is a natural join node like in
+ the following query
+ SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6)
+ the transformation additionally has to take care about setting proper
+ references in the field natural_join for both operands of the natural
+ join operation.
+
+ The queries that combine comma syntax for join operation with
+ JOIN expression require a special care. Consider the query
+ SELECT * FROM t1, t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q7)
+ This query is equivalent to the query
+ SELECT * FROM (t1, t2) JOIN t3 LEFT JOIN t4 ON t3.a=t4.a
+ The latter is transformed in the same way as query Q1
+
+ J LJ - ON
+ / \ / \
+ (t1,t2) LJ - ON => J t4
+ / \ / \
+ t3 t4 (t1,t2) t3
+
+ A transformation similar to the transformation for Q3 is done for
+ the following query with RIGHT JOIN
+ SELECT * FROM t1, t2 JOIN t3 RIGHT JOIN t4 ON t3.a=t4.a (Q8)
+
+ J LJ - ON
+ / \ / \
+ t3 LJ - ON => t4 J
+ / \ / \
+ t4 (t1,t2) (t1,t2) t3
+
+ The function also has to change the name resolution context for ON
+ expressions used in the transformed join expression to take into
+ account the tables of the left_op node.
+
+ TODO:
+ A more elegant solution would be to implement the transformation that
+ eliminates nests for cross join operations. For Q7 it would work like this:
+
+ J LJ - ON
+ / \ / \
+ (t1,t2) LJ - ON => (t1,t2,t3) t4
+ / \
+ t3 t4
+
+ For Q8 with RIGHT JOIN the transformation would work similarly:
+
+ J LJ - ON
+ / \ / \
+ t3 LJ - ON => t4 (t1,t2,t3)
+ / \
+ t4 (t1,t2)
+
*/
bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op,
@@ -8446,7 +8485,11 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op,
}
TABLE_LIST *tbl;
- List<TABLE_LIST> *jl= &right_op->nested_join->join_list;
+ List<TABLE_LIST> *right_op_jl= right_op->join_list;
+ TABLE_LIST *r_tbl= right_op_jl->pop();
+ DBUG_ASSERT(right_op == r_tbl);
+ TABLE_LIST *l_tbl= right_op_jl->pop();
+ DBUG_ASSERT(left_op == l_tbl);
TABLE_LIST *cj_nest;
/*
@@ -8463,6 +8506,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op,
List<TABLE_LIST> *cjl= &cj_nest->nested_join->join_list;
cjl->empty();
+ List<TABLE_LIST> *jl= &right_op->nested_join->join_list;
+ DBUG_ASSERT(jl->elements == 2);
/* Look for the left most node tbl of the right_op tree */
for ( ; ; )
{
@@ -8535,6 +8580,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op,
create a new top level nested join node.
*/
right_op->nested_join->nest_type|= REBALANCED_NEST;
+ if (unlikely(right_op_jl->push_front(right_op)))
+ DBUG_RETURN(true);
DBUG_RETURN(false);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2d6a843f7ad..7dcbafd4a88 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -8512,6 +8512,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
KEYUSE *keyuse= pos->key;
KEYUSE *prev_ref_keyuse= keyuse;
uint key= keyuse->key;
+ bool used_range_selectivity= false;
/*
Check if we have a prefix of key=const that matches a quick select.
@@ -8537,6 +8538,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
keyparts++;
}
sel /= (double)table->quick_rows[key] / (double) table->stat_records();
+ used_range_selectivity= true;
}
}
@@ -8572,13 +8574,14 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
if (keyparts > keyuse->keypart)
{
/* Ok this is the keyuse that will be used for ref access */
- uint fldno;
- if (is_hash_join_key_no(key))
- fldno= keyuse->keypart;
- else
- fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1;
- if (keyuse->val->const_item())
+ if (!used_range_selectivity && keyuse->val->const_item())
{
+ uint fldno;
+ if (is_hash_join_key_no(key))
+ fldno= keyuse->keypart;
+ else
+ fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1;
+
if (table->field[fldno]->cond_selectivity > 0)
{
sel /= table->field[fldno]->cond_selectivity;
@@ -16937,9 +16940,9 @@ static void create_tmp_field_from_item_finalize(THD *thd,
static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
Item ***copy_func, bool modify_item)
{
- Field *UNINIT_VAR(new_field);
DBUG_ASSERT(thd == table->in_use);
- if ((new_field= item->create_tmp_field(false, table)))
+ Field* new_field= item->create_tmp_field(false, table);
+ if (new_field)
create_tmp_field_from_item_finalize(thd, new_field, item,
copy_func, modify_item);
return new_field;
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 9242e3b423a..8d1342773f7 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2114,7 +2114,12 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
Histogram_type hist_type= (Histogram_type) (thd->variables.histogram_type);
uchar *histogram= NULL;
if (hist_size > 0)
- histogram= (uchar *) alloc_root(&table->mem_root, hist_size * columns);
+ {
+ if ((histogram= (uchar *) alloc_root(&table->mem_root,
+ hist_size * columns)))
+ bzero(histogram, hist_size * columns);
+
+ }
if (!table_stats || !column_stats || !index_stats || !idx_avg_frequency ||
(hist_size && !histogram))
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 09d775e7e51..3307f58818c 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -147,6 +147,7 @@ typedef struct st_time_zone_info
static my_bool prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage);
+my_bool opt_leap, opt_verbose, opt_skip_write_binlog;
#if defined(TZINFO2SQL) || defined(TESTTIME)
@@ -2428,6 +2429,14 @@ print_tz_leaps_as_sql(const TIME_ZONE_INFO *sp)
We are assuming that there are only one list of leap seconds
For all timezones.
*/
+ if (!opt_skip_write_binlog)
+ printf("\\d |\n"
+ "IF (select count(*) from information_schema.global_variables where\n"
+ "variable_name='wsrep_on') = 1 THEN\n"
+ "ALTER TABLE time_zone_leap_second ENGINE=InnoDB;\n"
+ "END IF|\n"
+ "\\d ;\n");
+
printf("TRUNCATE TABLE time_zone_leap_second;\n");
if (sp->leapcnt)
@@ -2440,6 +2449,14 @@ print_tz_leaps_as_sql(const TIME_ZONE_INFO *sp)
printf(";\n");
}
+ if (!opt_skip_write_binlog)
+ printf("\\d |\n"
+ "IF (select count(*) from information_schema.global_variables where\n"
+ "variable_name='wsrep_on') = 1 THEN\n"
+ "ALTER TABLE time_zone_leap_second ENGINE=MyISAM;\n"
+ "END IF|\n"
+ "\\d ;\n");
+
printf("ALTER TABLE time_zone_leap_second ORDER BY Transition_time;\n");
}
@@ -2597,8 +2614,6 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose)
}
-my_bool opt_leap, opt_verbose;
-
static const char *load_default_groups[]=
{ "mysql_tzinfo_to_sql", 0};
@@ -2619,6 +2634,8 @@ static struct my_option my_long_options[] =
&opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-write-binlog", 'S', "Do not replicate changes to time zone tables to other nodes in a Galera cluster",
+ &opt_skip_write_binlog,&opt_skip_write_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -2687,11 +2704,14 @@ main(int argc, char **argv)
return 1;
}
- // Replicate MyISAM DDL for this session, cf. lp:1161432
- // timezone info unfixable in XtraDB Cluster
- printf("set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?');\n"
- "prepare set_wsrep_myisam from @prep;\n"
- "set @toggle=1; execute set_wsrep_myisam using @toggle;\n");
+ if (opt_skip_write_binlog)
+ /* If skip_write_binlog is set and wsrep is compiled in we disable
+ sql_log_bin and wsrep_on to avoid Galera replicating below
+ truncate table clauses. This will allow user to set different
+ time zones to nodes in Galera cluster. */
+ printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?');\n"
+ "prepare set_wsrep_write_binlog from @prep1;\n"
+ "set @toggle=0; execute set_wsrep_write_binlog using @toggle;\n");
if (argc == 1 && !opt_leap)
{
@@ -2699,6 +2719,21 @@ main(int argc, char **argv)
root_name_end= strmake_buf(fullname, argv[0]);
+ if(!opt_skip_write_binlog)
+ {
+ // Alter time zone tables to InnoDB if wsrep_on is enabled
+ // to allow changes to them to replicate with Galera
+ printf("\\d |\n"
+ "IF (select count(*) from information_schema.global_variables where\n"
+ "variable_name='wsrep_on') = 1 THEN\n"
+ "ALTER TABLE time_zone ENGINE=InnoDB;\n"
+ "ALTER TABLE time_zone_name ENGINE=InnoDB;\n"
+ "ALTER TABLE time_zone_transition ENGINE=InnoDB;\n"
+ "ALTER TABLE time_zone_transition_type ENGINE=InnoDB;\n"
+ "END IF|\n"
+ "\\d ;\n");
+ }
+
printf("TRUNCATE TABLE time_zone;\n");
printf("TRUNCATE TABLE time_zone_name;\n");
printf("TRUNCATE TABLE time_zone_transition;\n");
@@ -2740,8 +2775,19 @@ main(int argc, char **argv)
free_root(&tz_storage, MYF(0));
}
- // Reset wsrep_replicate_myisam. lp:1161432
- printf("set @toggle=0; execute set_wsrep_myisam using @toggle;\n");
+ if(!opt_skip_write_binlog)
+ {
+ // Fall back to MyISAM
+ printf("\\d |\n"
+ "IF (select count(*) from information_schema.global_variables where\n"
+ "variable_name='wsrep_on') = 1 THEN\n"
+ "ALTER TABLE time_zone ENGINE=MyISAM;\n"
+ "ALTER TABLE time_zone_name ENGINE=MyISAM;\n"
+ "ALTER TABLE time_zone_transition ENGINE=MyISAM;\n"
+ "ALTER TABLE time_zone_transition_type ENGINE=MyISAM;\n"
+ "END IF|\n"
+ "\\d ;\n");
+ }
free_defaults(default_argv);
my_end(0);
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index bda79ed7406..8079ebaf563 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -756,7 +756,7 @@ static ssize_t sst_prepare_other (const char* method,
my_free(binlog_opt_val);
my_free(binlog_index_opt_val);
- if (ret < 0 || ret >= cmd_len)
+ if (ret < 0 || size_t(ret) >= cmd_len)
{
WSREP_ERROR("sst_prepare_other(): snprintf() failed: %d", ret);
return (ret < 0 ? ret : -EMSGSIZE);
@@ -1067,7 +1067,7 @@ static int sst_donate_mysqldump (const char* addr,
(long long)seqno, wsrep_gtid_domain_id,
bypass ? " " WSREP_SST_OPT_BYPASS : "");
- if (ret < 0 || ret >= cmd_len)
+ if (ret < 0 || size_t(ret) >= cmd_len)
{
WSREP_ERROR("sst_donate_mysqldump(): snprintf() failed: %d", ret);
return (ret < 0 ? ret : -EMSGSIZE);
@@ -1437,7 +1437,7 @@ static int sst_donate_other (const char* method,
bypass ? " " WSREP_SST_OPT_BYPASS : "");
my_free(binlog_opt_val);
- if (ret < 0 || ret >= cmd_len)
+ if (ret < 0 || size_t(ret) >= cmd_len)
{
WSREP_ERROR("sst_donate_other(): snprintf() failed: %d", ret);
return (ret < 0 ? ret : -EMSGSIZE);