diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-10-25 10:04:37 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-10-25 10:04:37 +0300 |
commit | 667d3fbbb51044b20d23150992adbbad1f04aad8 (patch) | |
tree | 6bf1006a9ea5e68f18387205bd224e7c5698278f /sql | |
parent | f19e8559aa3f46c0be427c9bd6534432bc08160c (diff) | |
parent | 34ff5ca8952ff58d99be5028a5920bfe5268f17a (diff) | |
download | mariadb-git-667d3fbbb51044b20d23150992adbbad1f04aad8.tar.gz |
Merge 10.3 into 10.4
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 16 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 13 | ||||
-rw-r--r-- | sql/sql_acl.cc | 14 | ||||
-rw-r--r-- | sql/sql_acl.h | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_explain.cc | 15 | ||||
-rw-r--r-- | sql/sql_insert.cc | 23 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 6 | ||||
-rw-r--r-- | sql/sql_show.cc | 13 | ||||
-rw-r--r-- | sql/sql_time.cc | 45 | ||||
-rw-r--r-- | sql/sql_view.cc | 24 | ||||
-rw-r--r-- | sql/sql_view.h | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 5 | ||||
-rw-r--r-- | sql/table.cc | 12 |
16 files changed, 130 insertions, 67 deletions
diff --git a/sql/item.cc b/sql/item.cc index f3eb7bcd741..73390e3d6e1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9773,6 +9773,8 @@ bool Item_trigger_field::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it) if (!item || fix_fields_if_needed(thd, NULL)) return true; + if (field->vers_sys_field()) + return false; // NOTE: field->table->copy_blobs should be false here, but let's // remember the value at runtime to avoid subtle bugs. @@ -10607,6 +10609,20 @@ void view_error_processor(THD *thd, void *data) ((TABLE_LIST *)data)->hide_view_error(thd); } +/** + Name resolution context with resolution in only one table +*/ + +Name_resolution_context::Name_resolution_context(TABLE_LIST *table): + outer_context(0), table_list(0), select_lex(0), + error_processor_data(0), + security_ctx(0) +{ + resolve_in_select_list= FALSE; + error_processor= &dummy_error_processor; + // resolve only in this table + first_name_resolution_table= last_name_resolution_table= table; +} st_select_lex *Item_ident::get_depended_from() const { diff --git a/sql/item.h b/sql/item.h index 05bfc47a2b4..9d41f72bf6a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -244,6 +244,8 @@ struct Name_resolution_context: Sql_alloc security_ctx(0) {} + Name_resolution_context(TABLE_LIST *table); + void init() { resolve_in_select_list= FALSE; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c7b83fae70d..b6509fa8b25 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -418,9 +418,18 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) if (args[0]->cmp_type() == STRING_RESULT && args[1]->cmp_type() == STRING_RESULT) { + Query_arena *arena, backup; + arena= thd->activate_stmt_arena_if_needed(&backup); + DTCollation tmp; - if (agg_arg_charsets_for_comparison(tmp, args, 2)) - return true; + bool ret= agg_arg_charsets_for_comparison(tmp, args, 2); + + if (arena) + thd->restore_active_arena(arena, &backup); + + if (ret) + return ret; + cmp->m_compare_collation= tmp.collation; } // Convert constants when compared to int/year field diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index dc69cb63618..2c9aeb04483 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3961,7 +3961,7 @@ bool change_password(THD *thd, LEX_USER *user) if (update_user_table_password(thd, tables.user_table(), *acl_user)) goto end; - acl_cache->clear(1); // Clear locked hostname cache + hostname_cache_refresh(); // Clear locked hostname cache mysql_mutex_unlock(&acl_cache->lock); result= acl_cache_is_locked= 0; if (mysql_bin_log.is_open()) @@ -4119,7 +4119,6 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, goto end; } - acl_cache->clear(1); mysql_mutex_unlock(&acl_cache->lock); result= 0; if (mysql_bin_log.is_open()) @@ -7590,7 +7589,10 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke) a role */ if (role_as_user) + { propagate_role_grants(role_as_user, PRIVS_TO_MERGE::ALL); + acl_cache->clear(1); + } } mysql_mutex_unlock(&acl_cache->lock); @@ -13736,11 +13738,11 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) if (global_system_variables.log_warnings) sql_print_information("X509 issuer mismatch: should be '%s' " "but is '%s'", acl_user->x509_issuer, ptr); - free(ptr); + OPENSSL_free(ptr); X509_free(cert); return 1; } - free(ptr); + OPENSSL_free(ptr); } /* X509 subject is specified, we check it .. */ if (acl_user->x509_subject[0]) @@ -13753,11 +13755,11 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) if (global_system_variables.log_warnings) sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", acl_user->x509_subject, ptr); - free(ptr); + OPENSSL_free(ptr); X509_free(cert); return 1; } - free(ptr); + OPENSSL_free(ptr); } X509_free(cert); return 0; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index dc8a085c96c..3d415051f28 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -103,7 +103,7 @@ */ #define TMP_TABLE_ACLS \ (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ - INDEX_ACL | ALTER_ACL) + INDEX_ACL | ALTER_ACL | REFERENCES_ACL) /* Defines to change the above bits to how things are stored in tables diff --git a/sql/sql_class.h b/sql/sql_class.h index 3479ed1a7bc..b390c909685 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5626,7 +5626,7 @@ class select_insert :public select_result_interceptor { int prepare(List<Item> &list, SELECT_LEX_UNIT *u); virtual int prepare2(JOIN *join); virtual int send_data(List<Item> &items); - virtual void store_values(List<Item> &values); + virtual bool store_values(List<Item> &values, bool ignore_errors); virtual bool can_rollback_data() { return 0; } bool prepare_eof(); bool send_ok_packet(); @@ -5668,7 +5668,7 @@ public: int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int binlog_show_create_table(TABLE **tables, uint count); - void store_values(List<Item> &values); + bool store_values(List<Item> &values, bool ignore_errors); bool send_eof(); virtual void abort_result_set(); virtual bool can_rollback_data() { return 1; } diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 860e840f34e..1681da63ac1 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -662,7 +662,11 @@ int Explain_node::print_explain_for_children(Explain_query *query, for (int i= 0; i < (int) children.elements(); i++) { Explain_node *node= query->get_node(children.at(i)); - if (node->print_explain(query, output, explain_flags, is_analyze)) + /* + Note: node may not be present because for certain kinds of subqueries, + the optimizer is not able to see that they were eliminated. + */ + if (node && node->print_explain(query, output, explain_flags, is_analyze)) return 1; } return 0; @@ -706,8 +710,15 @@ void Explain_node::print_explain_json_for_children(Explain_query *query, for (int i= 0; i < (int) children.elements(); i++) { Explain_node *node= query->get_node(children.at(i)); - /* Derived tables are printed inside Explain_table_access objects */ + /* + Note: node may not be present because for certain kinds of subqueries, + the optimizer is not able to see that they were eliminated. + */ + if (!node) + continue; + + /* Derived tables are printed inside Explain_table_access objects */ if (!is_connection_printable_in_json(node->connection_type)) continue; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 68d063720ed..aeb39871025 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3962,9 +3962,7 @@ int select_insert::send_data(List<Item> &values) DBUG_RETURN(0); thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields - store_values(values); - if (table->default_field && - unlikely(table->update_default_fields(info.ignore))) + if (store_values(values, info.ignore)) DBUG_RETURN(1); thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; if (unlikely(thd->is_error())) @@ -4022,18 +4020,19 @@ int select_insert::send_data(List<Item> &values) } -void select_insert::store_values(List<Item> &values) +bool select_insert::store_values(List<Item> &values, bool ignore_errors) { DBUG_ENTER("select_insert::store_values"); + bool error; if (fields->elements) - fill_record_n_invoke_before_triggers(thd, table, *fields, values, 1, - TRG_EVENT_INSERT); + error= fill_record_n_invoke_before_triggers(thd, table, *fields, values, + ignore_errors, TRG_EVENT_INSERT); else - fill_record_n_invoke_before_triggers(thd, table, table->field_to_fill(), - values, 1, TRG_EVENT_INSERT); + error= fill_record_n_invoke_before_triggers(thd, table, table->field_to_fill(), + values, ignore_errors, TRG_EVENT_INSERT); - DBUG_VOID_RETURN; + DBUG_RETURN(error); } bool select_insert::prepare_eof() @@ -4710,10 +4709,10 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) return result; } -void select_create::store_values(List<Item> &values) +bool select_create::store_values(List<Item> &values, bool ignore_errors) { - fill_record_n_invoke_before_triggers(thd, table, field, values, 1, - TRG_EVENT_INSERT); + return fill_record_n_invoke_before_triggers(thd, table, field, values, + ignore_errors, TRG_EVENT_INSERT); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 8922c6b541b..f31a128832b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2400,6 +2400,7 @@ void st_select_lex::init_query() item_list.empty(); min_max_opt_list.empty(); join= 0; + cur_pos_in_select_list= UNDEF_POS; having= prep_having= where= prep_where= 0; cond_pushed_into_where= cond_pushed_into_having= 0; attach_to_conds.empty(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 37d54b1165e..0261e7480f1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7007,13 +7007,13 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) @brief Check if the requested privileges exists in either User-, Host- or Db-tables. @param thd Thread context - @param want_access Privileges requested + @param requirements Privileges requested @param tables List of tables to be compared against - @param no_errors Don't report error to the client (using my_error() call). @param any_combination_of_privileges_will_do TRUE if any privileges on any column combination is enough. @param number Only the first 'number' tables in the linked list are relevant. + @param no_errors Don't report error to the client (using my_error() call). The suppled table list contains cached privileges. This functions calls the help functions check_access and check_grant to verify the first three steps @@ -7040,7 +7040,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, - bool any_combination_of_privileges_will_do, + bool any_combination_of_privileges_will_do, uint number, bool no_errors) { TABLE_LIST *org_tables= tables; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d290fde9d22..1fa0980977d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6071,6 +6071,15 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, show_table->use_all_columns(); // Required for default restore_record(show_table, s->default_values); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + check_access(thd, SELECT_ACL, db_name->str, + &tables->grant.privilege, 0, 0, MY_TEST(tables->schema_table)); + if (is_temporary_table(tables)) + { + tables->grant.privilege|= TMP_TABLE_ACLS; + } +#endif + for (; (field= *ptr) ; ptr++) { if(field->invisible > INVISIBLE_USER) @@ -6091,13 +6100,13 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access; - check_access(thd,SELECT_ACL, db_name->str, - &tables->grant.privilege, 0, 0, MY_TEST(tables->schema_table)); col_access= get_column_grant(thd, &tables->grant, db_name->str, table_name->str, field->field_name.str) & COL_ACLS; + if (!tables->schema_table && !col_access) continue; + char *end= tmp; for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) { diff --git a/sql/sql_time.cc b/sql/sql_time.cc index abc91907a55..7d288109439 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -68,62 +68,71 @@ int append_interval(String *str, interval_type int_type, const INTERVAL &interva size_t len; switch (int_type) { case INTERVAL_YEAR: - len= my_snprintf(buf,sizeof(buf),"%u", interval.year); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.year); break; case INTERVAL_QUARTER: case INTERVAL_MONTH: - len= my_snprintf(buf,sizeof(buf),"%u", interval.month); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.month); int_type=INTERVAL_MONTH; break; case INTERVAL_WEEK: case INTERVAL_DAY: - len= my_snprintf(buf,sizeof(buf),"%u", interval.day); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.day); int_type=INTERVAL_DAY; break; case INTERVAL_HOUR: - len= my_snprintf(buf,sizeof(buf),"%u", interval.hour); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.hour); break; case INTERVAL_MINUTE: - len= my_snprintf(buf,sizeof(buf),"%u", interval.minute); + len= my_snprintf(buf,sizeof(buf),"%llu", interval.minute); break; case INTERVAL_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u", interval.second); + len= my_snprintf(buf,sizeof(buf),"%llu", interval.second); break; case INTERVAL_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u", interval.second_part); + len= my_snprintf(buf,sizeof(buf),"%llu", interval.second_part); break; case INTERVAL_YEAR_MONTH: - len= my_snprintf(buf,sizeof(buf),"%u-%02u", interval.day, interval.month); + len= my_snprintf(buf,sizeof(buf),"'%lu-%02lu'", + interval.year, interval.month); break; case INTERVAL_DAY_HOUR: - len= my_snprintf(buf,sizeof(buf),"%u %u", interval.day, interval.hour); + len= my_snprintf(buf,sizeof(buf),"'%lu %lu'", interval.day, interval.hour); break; case INTERVAL_DAY_MINUTE: - len= my_snprintf(buf,sizeof(buf),"%u %u:%02u", interval.day, interval.hour, interval.minute); + len= my_snprintf(buf,sizeof(buf),"'%lu %lu:%02llu'", + interval.day, interval.hour, interval.minute); break; case INTERVAL_DAY_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u %u:%02u:%02u", interval.day, interval.hour, interval.minute, interval.second); + len= my_snprintf(buf,sizeof(buf),"'%lu %lu:%02llu:%02llu'", + interval.day, interval.hour, interval.minute, interval.second); break; case INTERVAL_HOUR_MINUTE: - len= my_snprintf(buf,sizeof(buf),"%u:%02u", interval.hour, interval.minute); + len= my_snprintf(buf,sizeof(buf),"'%lu:%02llu'", interval.hour, interval.minute); break; case INTERVAL_HOUR_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u:%02u", interval.hour, interval.minute, interval.second); + len= my_snprintf(buf,sizeof(buf),"'%lu:%02llu:%02llu'", + interval.hour, interval.minute, interval.second); break; case INTERVAL_MINUTE_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u", interval.minute, interval.second); + len= my_snprintf(buf,sizeof(buf),"'%llu:%02llu'", interval.minute, interval.second); break; case INTERVAL_DAY_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u %u:%02u:%02u.%06u", interval.day, interval.hour, interval.minute, interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"'%lu %lu:%02llu:%02llu.%06llu'", + interval.day, interval.hour, interval.minute, + interval.second, interval.second_part); break; case INTERVAL_HOUR_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u:%02u.%06u", interval.hour, interval.minute, interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"'%lu:%02llu:%02llu.%06llu'", + interval.hour, interval.minute, interval.second, + interval.second_part); break; case INTERVAL_MINUTE_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u.%06u", interval.minute, interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"'%llu:%02llu.%06llu'", + interval.minute, interval.second, interval.second_part); break; case INTERVAL_SECOND_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u.%06u", interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"%llu.%06llu", interval.second, interval.second_part); break; default: DBUG_ASSERT(0); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 248ac3c025e..1efbc68fb8a 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1177,19 +1177,26 @@ err: bool mariadb_view_version_get(TABLE_SHARE *share) { DBUG_ASSERT(share->is_view); + DBUG_ASSERT(share->tabledef_version.length == 0); if (!(share->tabledef_version.str= (uchar*) alloc_root(&share->mem_root, MICROSECOND_TIMESTAMP_BUFFER_SIZE))) return TRUE; - share->tabledef_version.length= 0; // safety if the drfinition file is brocken DBUG_ASSERT(share->view_def != NULL); if (share->view_def->parse((uchar *) &share->tabledef_version, NULL, view_timestamp_parameters, 1, &file_parser_dummy_hook)) + { + // safety if the definition file is brocken + share->tabledef_version.length= 0; + my_error(ER_TABLE_CORRUPT, MYF(0), + share->db.str, share->table_name.str); return TRUE; + } DBUG_ASSERT(share->tabledef_version.length == MICROSECOND_TIMESTAMP_BUFFER_SIZE-1); + return FALSE; } @@ -1254,10 +1261,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, mysql_handle_single_derived(thd->lex, table, DT_REINIT); DEBUG_SYNC(thd, "after_cached_view_opened"); - if (!share->tabledef_version.length) - { - mariadb_view_version_get(share); - } + DBUG_ASSERT(share->tabledef_version.length); DBUG_RETURN(0); } @@ -1311,15 +1315,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, required_view_parameters, &file_parser_dummy_hook))) goto end; - if (!share->tabledef_version.length) - { - share->tabledef_version.str= (const uchar *) - memdup_root(&share->mem_root, - (const void *) - table->hr_timestamp.str, - (share->tabledef_version.length= - table->hr_timestamp.length)); - } + DBUG_ASSERT(share->tabledef_version.length); if (!table->tabledef_version.length) { table->set_view_def_version(&table->hr_timestamp); diff --git a/sql/sql_view.h b/sql/sql_view.h index c1e5dc49da3..0713b951de7 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -64,4 +64,6 @@ extern const LEX_CSTRING view_type; void make_valid_column_names(List<Item> &item_list); +bool mariadb_view_version_get(TABLE_SHARE *share); + #endif /* SQL_VIEW_INCLUDED */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8a096b4808d..2682aef14d8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6088,10 +6088,11 @@ opt_part_option: opt_versioning_rotation: /* empty */ {} - | INTERVAL_SYM expr interval opt_versioning_interval_start + | { Lex->clause_that_disallows_subselect= "INTERVAL"; } + INTERVAL_SYM expr interval opt_versioning_interval_start { partition_info *part_info= Lex->part_info; - if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4))) + if (unlikely(part_info->vers_set_interval(thd, $3, $4, $5))) MYSQL_YYABORT; } | LIMIT ulonglong_num diff --git a/sql/table.cc b/sql/table.cc index 56d5b256971..b9260853381 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -652,7 +652,11 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) if (!share->view_def) share->error= OPEN_FRM_ERROR_ALREADY_ISSUED; else + { share->error= OPEN_FRM_OK; + if (mariadb_view_version_get(share)) + share->error= OPEN_FRM_ERROR_ALREADY_ISSUED; + } } else share->error= OPEN_FRM_NOT_A_TABLE; @@ -8629,7 +8633,7 @@ int TABLE::update_virtual_field(Field *vf, bool ignore_warnings) Counting_error_handler count_errors; Suppress_warnings_error_handler warning_handler; in_use->push_internal_handler(&count_errors); - bool abort_on_warning; + bool abort_on_warning= ignore_warnings; if (ignore_warnings) { abort_on_warning= in_use->abort_on_warning; @@ -9362,7 +9366,8 @@ bool TABLE_LIST::change_refs_to_fields() Item **materialized_items= (Item **)thd->calloc(sizeof(void *) * table->s->fields); - if (!materialized_items) + Name_resolution_context *ctx= new Name_resolution_context(this); + if (!materialized_items || !ctx) return TRUE; while ((ref= (Item_direct_ref*)li++)) @@ -9378,7 +9383,8 @@ bool TABLE_LIST::change_refs_to_fields() DBUG_ASSERT(!field_it.end_of_fields()); if (!materialized_items[idx]) { - materialized_items[idx]= new (thd->mem_root) Item_field(thd, table->field[idx]); + materialized_items[idx]= + new (thd->mem_root) Item_field(thd, ctx, table->field[idx]); if (!materialized_items[idx]) return TRUE; } |