From 4ec6fe10e56de0cf9b4dbc649b8552ae39c2c500 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:00:16 +0200 Subject: [PATCH 01/87] remove ULL() and LL(), because they're totally unnecessary and sometimes harmful (used with expressions) --- include/maria.h | 21 +++--- include/my_global.h | 18 +---- include/myisam.h | 21 +++--- mysys/ma_dyncol.c | 8 +- mysys/typelib.c | 3 +- mysys/waiting_threads.c | 5 +- sql-common/my_time.c | 31 ++++---- sql-common/pack.c | 6 +- sql/field.cc | 18 ++--- sql/handler.h | 86 +++++++++++----------- sql/item.cc | 8 +- sql/item.h | 2 +- sql/item_func.cc | 18 ++--- sql/item_strfunc.cc | 2 +- sql/item_sum.h | 6 +- sql/item_timefunc.cc | 4 +- sql/log_event.h | 3 +- sql/rpl_utility.cc | 5 +- sql/sql_bitmap.h | 5 +- sql/sql_class.h | 66 ++++++++--------- sql/sql_connect.cc | 4 +- sql/sql_lex.cc | 2 +- sql/sql_parse.cc | 4 +- sql/sql_partition.cc | 10 +-- sql/sql_priv.h | 8 +- sql/sql_repl.cc | 6 +- sql/sql_select.cc | 3 +- sql/sql_time.cc | 4 +- sql/sql_udf.h | 4 +- storage/maria/ma_bitmap.c | 15 ++-- storage/maria/ma_blockrec.c | 2 +- storage/maria/ma_create.c | 12 +-- storage/maria/ma_key.c | 2 +- storage/maria/ma_loghandler.c | 10 +-- storage/maria/ma_loghandler_lsn.h | 6 +- storage/maria/ma_pagecache.c | 12 +-- storage/maria/ma_recovery.c | 4 +- storage/maria/maria_def.h | 2 +- storage/maria/maria_pack.c | 2 +- storage/maria/trnman.h | 2 +- storage/maria/unittest/ma_control_file-t.c | 2 +- storage/maria/unittest/trnman-t.c | 2 +- storage/myisam/mi_create.c | 13 ++-- storage/myisam/myisampack.c | 3 +- strings/ctype-ucs2.c | 10 +-- strings/decimal.c | 4 +- strings/my_strtoll10.c | 10 +-- tests/mysql_client_test.c | 10 +-- 48 files changed, 248 insertions(+), 256 deletions(-) diff --git a/include/maria.h b/include/maria.h index cab296246b6..4dd007df74e 100644 --- a/include/maria.h +++ b/include/maria.h @@ -1,4 +1,5 @@ /* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -60,31 +61,31 @@ extern "C" { sets all high keys. */ #define MARIA_KEYMAP_BITS (8 * SIZEOF_LONG_LONG) -#define MARIA_KEYMAP_HIGH_MASK (ULL(1) << (MARIA_KEYMAP_BITS - 1)) +#define MARIA_KEYMAP_HIGH_MASK (1ULL << (MARIA_KEYMAP_BITS - 1)) #define maria_get_mask_all_keys_active(_keys_) \ (((_keys_) < MARIA_KEYMAP_BITS) ? \ - ((ULL(1) << (_keys_)) - ULL(1)) : \ - (~ ULL(0))) + ((1ULL << (_keys_)) - 1ULL) : \ + (~ 0ULL)) #if MARIA_MAX_KEY > MARIA_KEYMAP_BITS #define maria_is_key_active(_keymap_,_keyno_) \ (((_keyno_) < MARIA_KEYMAP_BITS) ? \ - test((_keymap_) & (ULL(1) << (_keyno_))) : \ + test((_keymap_) & (1ULL << (_keyno_))) : \ test((_keymap_) & MARIA_KEYMAP_HIGH_MASK)) #define maria_set_key_active(_keymap_,_keyno_) \ (_keymap_)|= (((_keyno_) < MARIA_KEYMAP_BITS) ? \ - (ULL(1) << (_keyno_)) : \ + (1ULL << (_keyno_)) : \ MARIA_KEYMAP_HIGH_MASK) #define maria_clear_key_active(_keymap_,_keyno_) \ (_keymap_)&= (((_keyno_) < MARIA_KEYMAP_BITS) ? \ - (~ (ULL(1) << (_keyno_))) : \ - (~ (ULL(0))) /*ignore*/ ) + (~ (1ULL << (_keyno_))) : \ + (~ (0ULL)) /*ignore*/ ) #else #define maria_is_key_active(_keymap_,_keyno_) \ - test((_keymap_) & (ULL(1) << (_keyno_))) + test((_keymap_) & (1ULL << (_keyno_))) #define maria_set_key_active(_keymap_,_keyno_) \ - (_keymap_)|= (ULL(1) << (_keyno_)) + (_keymap_)|= (1ULL << (_keyno_)) #define maria_clear_key_active(_keymap_,_keyno_) \ - (_keymap_)&= (~ (ULL(1) << (_keyno_))) + (_keymap_)&= (~ (1ULL << (_keyno_))) #endif #define maria_is_any_key_active(_keymap_) \ test((_keymap_)) diff --git a/include/my_global.h b/include/my_global.h index a99823b94d8..1aa806fb14d 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1,5 +1,6 @@ /* Copyright (c) 2001, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1006,25 +1007,8 @@ typedef struct st_mysql_lex_string LEX_STRING; typedef ulong myf; /* Type of MyFlags in my_funcs */ typedef char my_bool; /* Small bool */ -/* Macros for converting *constants* to the right type */ #define MYF(v) (myf) (v) -#ifndef LL -#ifdef HAVE_LONG_LONG -#define LL(A) A ## LL -#else -#define LL(A) A ## L -#endif -#endif - -#ifndef ULL -#ifdef HAVE_LONG_LONG -#define ULL(A) A ## ULL -#else -#define ULL(A) A ## UL -#endif -#endif - /* Defines to make it possible to prioritize register assignments. No longer that important with modern compilers. diff --git a/include/myisam.h b/include/myisam.h index eaa6b2dbd1f..d5484b1eac6 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -57,35 +58,35 @@ extern "C" { sets all high keys. */ #define MI_KEYMAP_BITS (8 * SIZEOF_LONG_LONG) -#define MI_KEYMAP_HIGH_MASK (ULL(1) << (MI_KEYMAP_BITS - 1)) +#define MI_KEYMAP_HIGH_MASK (1ULL << (MI_KEYMAP_BITS - 1)) #define mi_get_mask_all_keys_active(_keys_) \ (((_keys_) < MI_KEYMAP_BITS) ? \ - ((ULL(1) << (_keys_)) - ULL(1)) : \ - (~ ULL(0))) + ((1ULL << (_keys_)) - 1ULL) : \ + (~ 0ULL)) #if MI_MAX_KEY > MI_KEYMAP_BITS #define mi_is_key_active(_keymap_,_keyno_) \ (((_keyno_) < MI_KEYMAP_BITS) ? \ - test((_keymap_) & (ULL(1) << (_keyno_))) : \ + test((_keymap_) & (1ULL << (_keyno_))) : \ test((_keymap_) & MI_KEYMAP_HIGH_MASK)) #define mi_set_key_active(_keymap_,_keyno_) \ (_keymap_)|= (((_keyno_) < MI_KEYMAP_BITS) ? \ - (ULL(1) << (_keyno_)) : \ + (1ULL << (_keyno_)) : \ MI_KEYMAP_HIGH_MASK) #define mi_clear_key_active(_keymap_,_keyno_) \ (_keymap_)&= (((_keyno_) < MI_KEYMAP_BITS) ? \ - (~ (ULL(1) << (_keyno_))) : \ - (~ (ULL(0))) /*ignore*/ ) + (~ (1ULL << (_keyno_))) : \ + (~ (0ULL)) /*ignore*/ ) #else #define mi_is_key_active(_keymap_,_keyno_) \ - test((_keymap_) & (ULL(1) << (_keyno_))) + test((_keymap_) & (1ULL << (_keyno_))) #define mi_set_key_active(_keymap_,_keyno_) \ - (_keymap_)|= (ULL(1) << (_keyno_)) + (_keymap_)|= (1ULL << (_keyno_)) #define mi_clear_key_active(_keymap_,_keyno_) \ - (_keymap_)&= (~ (ULL(1) << (_keyno_))) + (_keymap_)&= (~ (1ULL << (_keyno_))) #endif diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index 8a224f1c5e8..71ceceaf162 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011,2012 Monty Program Ab; +/* Copyright (c) 2011,2013 Monty Program Ab; Copyright (c) 2011,2012 Oleksandr Byelkin Redistribution and use in source and binary forms, with or without @@ -866,7 +866,7 @@ dynamic_column_uint_read(DYNAMIC_COLUMN_VALUE *store_it_here, static size_t dynamic_column_sint_bytes(longlong val) { return dynamic_column_uint_bytes((val << 1) ^ - (val < 0 ? ULL(0xffffffffffffffff) : 0)); + (val < 0 ? 0xffffffffffffffffull : 0)); } @@ -884,7 +884,7 @@ dynamic_column_sint_store(DYNAMIC_COLUMN *str, longlong val) { return dynamic_column_uint_store(str, (val << 1) ^ - (val < 0 ? ULL(0xffffffffffffffff) : 0)); + (val < 0 ? 0xffffffffffffffffULL : 0)); } @@ -906,7 +906,7 @@ dynamic_column_sint_read(DYNAMIC_COLUMN_VALUE *store_it_here, dynamic_column_uint_read(store_it_here, data, length); val= store_it_here->x.ulong_value; if (val & 1) - val= (val >> 1) ^ ULL(0xffffffffffffffff); + val= (val >> 1) ^ 0xffffffffffffffffULL; else val>>= 1; store_it_here->x.long_value= (longlong) val; diff --git a/mysys/typelib.c b/mysys/typelib.c index 402d108e51c..a332adf6af5 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -1,4 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -218,7 +219,7 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err) x++; if ((find= find_type(i, lib, FIND_TYPE_COMMA_TERM) - 1) < 0) DBUG_RETURN(0); - result|= (ULL(1) << find); + result|= (1ULL << find); } *err= 0; DBUG_RETURN(result); diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c index 21b2a9ac78a..caeba9cfa12 100644 --- a/mysys/waiting_threads.c +++ b/mysys/waiting_threads.c @@ -1,4 +1,5 @@ /* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. + Copyright (c) 2011, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1068,7 +1069,7 @@ int wt_thd_cond_timedwait(WT_THD *thd, mysql_mutex_t *mutex) ret= WT_OK; rc_unlock(rc); - end_wait_time= starttime.val *1000 + (*thd->timeout_short)*ULL(1000000); + end_wait_time= starttime.val *1000 + (*thd->timeout_short)*1000000ULL; set_timespec_time_nsec(timeout, end_wait_time); if (ret == WT_TIMEOUT && !thd->killed) ret= mysql_cond_timedwait(&rc->cond, mutex, &timeout); @@ -1081,7 +1082,7 @@ int wt_thd_cond_timedwait(WT_THD *thd, mysql_mutex_t *mutex) ret= WT_DEADLOCK; else if (*thd->timeout_long > *thd->timeout_short) { - end_wait_time= starttime.val *1000 + (*thd->timeout_long)*ULL(1000000); + end_wait_time= starttime.val *1000 + (*thd->timeout_long)*1000000ULL; set_timespec_time_nsec(timeout, end_wait_time); if (!thd->killed) ret= mysql_cond_timedwait(&rc->cond, mutex, &timeout); diff --git a/sql-common/my_time.c b/sql-common/my_time.c index fbcf52dbf19..d4093bb4df9 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1,5 +1,6 @@ /* Copyright (c) 2004, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,10 +25,10 @@ ulonglong log_10_int[20]= { 1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL, - ULL(100000000), ULL(1000000000), ULL(10000000000), ULL(100000000000), - ULL(1000000000000), ULL(10000000000000), ULL(100000000000000), - ULL(1000000000000000), ULL(10000000000000000), ULL(100000000000000000), - ULL(1000000000000000000), ULL(10000000000000000000) + 100000000ULL, 1000000000ULL, 10000000000ULL, 100000000000ULL, + 1000000000000ULL, 10000000000000ULL, 100000000000000ULL, + 1000000000000000ULL, 10000000000000000ULL, 100000000000000000ULL, + 1000000000000000000ULL, 10000000000000000000ULL }; @@ -1170,19 +1171,19 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res, time_res->time_type=MYSQL_TIMESTAMP_DATETIME; - if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959)) + if (nr <= (YY_PART_YEAR-1)*10000000000LL+1231235959LL) { - nr= nr+LL(20000000000000); /* YYMMDDHHMMSS, 2000-2069 */ + nr= nr+20000000000000LL; /* YYMMDDHHMMSS, 2000-2069 */ goto ok; } - if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000)) + if (nr < YY_PART_YEAR*10000000000LL+ 101000000LL) goto err; - if (nr <= LL(991231235959)) - nr= nr+LL(19000000000000); /* YYMMDDHHMMSS, 1970-1999 */ + if (nr <= 991231235959LL) + nr= nr+19000000000000LL; /* YYMMDDHHMMSS, 1970-1999 */ ok: - part1=(long) (nr/LL(1000000)); - part2=(long) (nr - (longlong) part1*LL(1000000)); + part1=(long) (nr/1000000LL); + part2=(long) (nr - (longlong) part1*1000000LL); time_res->year= (int) (part1/10000L); part1%=10000L; time_res->month= (int) part1 / 100; time_res->day= (int) part1 % 100; @@ -1202,7 +1203,7 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res, /* Don't want to have was_cut get set if NO_ZERO_DATE was violated. */ if (nr || !(flags & TIME_NO_ZERO_DATE)) *was_cut= 1; - return LL(-1); + return -1; err: { @@ -1212,7 +1213,7 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res, time_res->time_type= save; /* Restore range */ *was_cut= 1; /* Found invalid date */ } - return LL(-1); + return -1; } /* @@ -1277,7 +1278,7 @@ ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *my_time) { return ((ulonglong) (my_time->year * 10000UL + my_time->month * 100UL + - my_time->day) * ULL(1000000) + + my_time->day) * 1000000ULL + (ulonglong) (my_time->hour * 10000UL + my_time->minute * 100UL + my_time->second)); @@ -1338,7 +1339,7 @@ ulonglong TIME_to_ulonglong(const MYSQL_TIME *my_time) return TIME_to_ulonglong_time(my_time); case MYSQL_TIMESTAMP_NONE: case MYSQL_TIMESTAMP_ERROR: - return ULL(0); + return 0; default: DBUG_ASSERT(0); } diff --git a/sql-common/pack.c b/sql-common/pack.c index 7ff89471b45..69ab7ac9e17 100644 --- a/sql-common/pack.c +++ b/sql-common/pack.c @@ -96,19 +96,19 @@ my_ulonglong net_field_length_ll(uchar **packet) uchar *net_store_length(uchar *packet, ulonglong length) { - if (length < (ulonglong) LL(251)) + if (length < (ulonglong) 251LL) { *packet=(uchar) length; return packet+1; } /* 251 is reserved for NULL */ - if (length < (ulonglong) LL(65536)) + if (length < (ulonglong) 65536LL) { *packet++=252; int2store(packet,(uint) length); return packet+2; } - if (length < (ulonglong) LL(16777216)) + if (length < (ulonglong) 16777216LL) { *packet++=253; int3store(packet,(ulong) length); diff --git a/sql/field.cc b/sql/field.cc index a0f46778092..0a45c32d811 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2011, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -68,7 +68,7 @@ const char field_separator=','; #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128 #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128 #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ -((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1))) +((ulong) ((1LL << min(arg, 4) * 8) - 1)) #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))) #define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED DBUG_ASSERT(is_stat_field || !table || (!table->write_set || bitmap_is_set(table->write_set, field_index) || bitmap_is_set(table->vcol_set, field_index))) @@ -3643,7 +3643,7 @@ int Field_long::store(longlong nr, bool unsigned_val) res=0; error= 1; } - else if ((ulonglong) nr >= (LL(1) << 32)) + else if ((ulonglong) nr >= (1LL << 32)) { res=(int32) (uint32) ~0L; error= 1; @@ -4577,7 +4577,7 @@ int Field_timestamp::store(longlong nr, bool unsigned_val) longlong tmp= number_to_datetime(nr, 0, &l_time, (thd->variables.sql_mode & MODE_NO_ZERO_DATE) | MODE_NO_ZERO_IN_DATE, &error); - return store_TIME_with_warning(thd, &l_time, &str, error, tmp != LL(-1)); + return store_TIME_with_warning(thd, &l_time, &str, error, tmp != -1); } @@ -5795,8 +5795,8 @@ String *Field_datetime::val_str(String *val_buffer, Avoid problem with slow longlong arithmetic and sprintf */ - part1=(long) (tmp/LL(1000000)); - part2=(long) (tmp - (ulonglong) part1*LL(1000000)); + part1=(long) (tmp/1000000LL); + part2=(long) (tmp - (ulonglong) part1*1000000LL); pos=(char*) val_buffer->ptr() + MAX_DATETIME_WIDTH; *pos--=0; @@ -5827,8 +5827,8 @@ bool Field_datetime::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { longlong tmp=Field_datetime::val_int(); uint32 part1,part2; - part1=(uint32) (tmp/LL(1000000)); - part2=(uint32) (tmp - (ulonglong) part1*LL(1000000)); + part1=(uint32) (tmp/1000000LL); + part2=(uint32) (tmp - (ulonglong) part1*1000000LL); ltime->time_type= MYSQL_TIMESTAMP_DATETIME; ltime->neg= 0; @@ -7909,7 +7909,7 @@ int Field_set::store(longlong nr, bool unsigned_val) if (sizeof(ulonglong)*8 <= typelib->count) max_nr= ULONGLONG_MAX; else - max_nr= (ULL(1) << typelib->count) - 1; + max_nr= (1ULL << typelib->count) - 1; if ((ulonglong) nr > max_nr) { diff --git a/sql/handler.h b/sql/handler.h index c38dec198b9..6241f1ee774 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2,7 +2,7 @@ #define HANDLER_INCLUDED /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2011 Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -59,9 +59,9 @@ /* Bits in table_flags() to show what database can do */ -#define HA_NO_TRANSACTIONS (1 << 0) /* Doesn't support transactions */ -#define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */ -#define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */ +#define HA_NO_TRANSACTIONS (1ULL << 0) /* Doesn't support transactions */ +#define HA_PARTIAL_COLUMN_READ (1ULL << 1) /* read may not return all columns */ +#define HA_TABLE_SCAN_ON_INDEX (1ULL << 2) /* No separate data/index file */ /* The following should be set if the following is not true when scanning a table with rnd_next() @@ -70,37 +70,37 @@ If this flag is not set, filesort will do a position() call for each matched row to be able to find the row later. */ -#define HA_REC_NOT_IN_SEQ (1 << 3) -#define HA_CAN_GEOMETRY (1 << 4) +#define HA_REC_NOT_IN_SEQ (1ULL << 3) +#define HA_CAN_GEOMETRY (1ULL << 4) /* Reading keys in random order is as fast as reading keys in sort order (Used in records.cc to decide if we should use a record cache and by filesort to decide if we should sort key + data or key + pointer-to-row */ -#define HA_FAST_KEY_READ (1 << 5) +#define HA_FAST_KEY_READ (1ULL << 5) /* Set the following flag if we on delete should force all key to be read and on update read all keys that changes */ -#define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6) -#define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */ -#define HA_DUPLICATE_POS (1 << 8) /* ha_position() gives dup row */ -#define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */ -#define HA_CAN_INDEX_BLOBS (1 << 10) -#define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */ -#define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */ -#define HA_STATS_RECORDS_IS_EXACT (1 << 13) /* stats.records is exact */ +#define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1ULL << 6) +#define HA_NULL_IN_KEY (1ULL << 7) /* One can have keys with NULL */ +#define HA_DUPLICATE_POS (1ULL << 8) /* ha_position() gives dup row */ +#define HA_NO_BLOBS (1ULL << 9) /* Doesn't support blobs */ +#define HA_CAN_INDEX_BLOBS (1ULL << 10) +#define HA_AUTO_PART_KEY (1ULL << 11) /* auto-increment in multi-part key */ +#define HA_REQUIRE_PRIMARY_KEY (1ULL << 12) /* .. and can't create a hidden one */ +#define HA_STATS_RECORDS_IS_EXACT (1ULL << 13) /* stats.records is exact */ /* INSERT_DELAYED only works with handlers that uses MySQL internal table level locks */ -#define HA_CAN_INSERT_DELAYED (1 << 14) +#define HA_CAN_INSERT_DELAYED (1ULL << 14) /* If we get the primary key columns for free when we do an index read It also implies that we have to retrive the primary key when using position() and rnd_pos(). */ -#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15) +#define HA_PRIMARY_KEY_IN_READ_INDEX (1ULL << 15) /* If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position() uses a primary key given by the record argument. @@ -108,36 +108,36 @@ If not set, the position is returned as the current rows position regardless of what argument is given. */ -#define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16) -#define HA_CAN_RTREEKEYS (1 << 17) -#define HA_NOT_DELETE_WITH_CACHE (1 << 18) +#define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1ULL << 16) +#define HA_CAN_RTREEKEYS (1ULL << 17) +#define HA_NOT_DELETE_WITH_CACHE (1ULL << 18) /* The following is we need to a primary key to delete (and update) a row. If there is no primary key, all columns needs to be read on update and delete */ -#define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19) -#define HA_NO_PREFIX_CHAR_KEYS (1 << 20) -#define HA_CAN_FULLTEXT (1 << 21) -#define HA_CAN_SQL_HANDLER (1 << 22) -#define HA_NO_AUTO_INCREMENT (1 << 23) +#define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1ULL << 19) +#define HA_NO_PREFIX_CHAR_KEYS (1ULL << 20) +#define HA_CAN_FULLTEXT (1ULL << 21) +#define HA_CAN_SQL_HANDLER (1ULL << 22) +#define HA_NO_AUTO_INCREMENT (1ULL << 23) /* Has automatic checksums and uses the old checksum format */ -#define HA_HAS_OLD_CHECKSUM (1 << 24) +#define HA_HAS_OLD_CHECKSUM (1ULL << 24) /* Table data are stored in separate files (for lower_case_table_names) */ -#define HA_FILE_BASED (1 << 26) -#define HA_NO_VARCHAR (1 << 27) -#define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */ -#define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */ -#define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30) -#define HA_NO_COPY_ON_ALTER (LL(1) << 31) -#define HA_HAS_RECORDS (LL(1) << 32) /* records() gives exact count*/ +#define HA_FILE_BASED (1ULL << 26) +#define HA_NO_VARCHAR (1ULL << 27) +#define HA_CAN_BIT_FIELD (1ULL << 28) /* supports bit fields */ +#define HA_NEED_READ_RANGE_BUFFER (1ULL << 29) /* for read_multi_range */ +#define HA_ANY_INDEX_MAY_BE_UNIQUE (1ULL << 30) +#define HA_NO_COPY_ON_ALTER (1ULL << 31) +#define HA_HAS_RECORDS (1ULL << 32) /* records() gives exact count*/ /* Has it's own method of binlog logging */ -#define HA_HAS_OWN_BINLOGGING (LL(1) << 33) +#define HA_HAS_OWN_BINLOGGING (1ULL << 33) /* Engine is capable of row-format and statement-format logging, respectively */ -#define HA_BINLOG_ROW_CAPABLE (LL(1) << 34) -#define HA_BINLOG_STMT_CAPABLE (LL(1) << 35) +#define HA_BINLOG_ROW_CAPABLE (1ULL << 34) +#define HA_BINLOG_STMT_CAPABLE (1ULL << 35) /* When a multiple key conflict happens in a REPLACE command mysql expects the conflicts to be reported in the ascending order of @@ -160,20 +160,20 @@ This flag helps the underlying SE to inform the server that the keys are not ordered. */ -#define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36) +#define HA_DUPLICATE_KEY_NOT_IN_ORDER (1ULL << 36) /* Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD. */ -#define HA_CAN_REPAIR (LL(1) << 37) +#define HA_CAN_REPAIR (1ULL << 37) /* Has automatic checksums and uses the new checksum format */ -#define HA_HAS_NEW_CHECKSUM (LL(1) << 38) -#define HA_CAN_VIRTUAL_COLUMNS (LL(1) << 39) -#define HA_MRR_CANT_SORT (LL(1) << 40) -#define HA_RECORD_MUST_BE_CLEAN_ON_WRITE (LL(1) << 41) +#define HA_HAS_NEW_CHECKSUM (1ULL << 38) +#define HA_CAN_VIRTUAL_COLUMNS (1ULL << 39) +#define HA_MRR_CANT_SORT (1ULL << 40) +#define HA_RECORD_MUST_BE_CLEAN_ON_WRITE (1ULL << 41) /* Table condition pushdown must be performed regardless of @@ -186,7 +186,7 @@ then the "query=..." condition must be always pushed down into storage engine. */ -#define HA_MUST_USE_TABLE_CONDITION_PUSHDOWN (LL(1) << 42) +#define HA_MUST_USE_TABLE_CONDITION_PUSHDOWN (1ULL << 42) /* Set of all binlog flags. Currently only contain the capabilities diff --git a/sql/item.cc b/sql/item.cc index a425b0cd4ce..fd6a11c319b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2012, Monty Program Ab + Copyright (c) 2010, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4012,8 +4012,8 @@ double Item_copy_string::val_real() longlong Item_copy_string::val_int() { int err; - return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(), - str_value.length(),10, (char**) 0, + return null_value ? 0 : my_strntoll(str_value.charset(),str_value.ptr(), + str_value.length(), 10, (char**) 0, &err); } @@ -4183,7 +4183,7 @@ double Item_copy_decimal::val_real() longlong Item_copy_decimal::val_int() { if (null_value) - return LL(0); + return 0; else { longlong result; diff --git a/sql/item.h b/sql/item.h index d72d2f1f80b..50d125f76de 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3592,7 +3592,7 @@ public: } virtual longlong val_int() { - return null_value ? LL(0) : cached_value; + return null_value ? 0 : cached_value; } virtual void copy(); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index b4c825b6222..108943541c9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2215,7 +2215,7 @@ longlong Item_func_shift_left::val_int() return 0; } null_value=0; - return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0)); + return (shift < sizeof(longlong)*8 ? (longlong) res : 0); } longlong Item_func_shift_right::val_int() @@ -2230,7 +2230,7 @@ longlong Item_func_shift_right::val_int() return 0; } null_value=0; - return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0)); + return (shift < sizeof(longlong)*8 ? (longlong) res : 0); } @@ -3163,7 +3163,7 @@ void Item_func_find_in_set::fix_length_and_dec() find->length(), 0); enum_bit=0; if (enum_value) - enum_bit=LL(1) << (enum_value-1); + enum_bit=1LL << (enum_value-1); } } } @@ -3244,7 +3244,7 @@ longlong Item_func_find_in_set::val_int() wc == (my_wc_t) separator) return (longlong) ++position; else - return LL(0); + return 0; } } return 0; @@ -3965,7 +3965,7 @@ class Interruptible_wait /** Time to wait before polling the connection status. */ -const ulonglong Interruptible_wait::m_interrupt_interval= 5 * ULL(1000000000); +const ulonglong Interruptible_wait::m_interrupt_interval= 5 * 1000000000ULL; /** @@ -4089,7 +4089,7 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &ull->cond; - timed_cond.set_timeout(timeout * ULL(1000000000)); + timed_cond.set_timeout(timeout * 1000000000ULL); error= 0; thd_wait_begin(thd, THD_WAIT_USER_LOCK); @@ -4669,7 +4669,7 @@ double user_var_entry::val_real(bool *null_value) longlong user_var_entry::val_int(bool *null_value) const { if ((*null_value= (value == 0))) - return LL(0); + return 0; switch (type) { case REAL_RESULT: @@ -4693,7 +4693,7 @@ longlong user_var_entry::val_int(bool *null_value) const DBUG_ASSERT(0); // Impossible break; } - return LL(0); // Impossible + return 0; // Impossible } @@ -5186,7 +5186,7 @@ longlong Item_func_get_user_var::val_int() { DBUG_ASSERT(fixed == 1); if (!var_entry) - return LL(0); // No such variable + return 0; // No such variable return (var_entry->val_int(&null_value)); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 462db3c24fd..a4ca4dbe5a0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3360,7 +3360,7 @@ String* Item_func_inet_ntoa::val_str(String* str) Also return null if n > 255.255.255.255 */ - if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295)))) + if ((null_value= (args[0]->null_value || n > 0xffffffff))) return 0; // Null value str->set_charset(collation.collation); diff --git a/sql/item_sum.h b/sql/item_sum.h index a954b0f65c1..6769c47a411 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1,7 +1,7 @@ #ifndef ITEM_SUM_INCLUDED #define ITEM_SUM_INCLUDED /* Copyright (c) 2000, 2011 Oracle and/or its affiliates. - Copyright (c) 2008-2011 Monty Program Ab + Copyright (c) 2008, 2013 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1120,7 +1120,7 @@ public: class Item_sum_or :public Item_sum_bit { public: - Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} + Item_sum_or(Item *item_par) :Item_sum_bit(item_par, 0) {} Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {} bool add(); const char *func_name() const { return "bit_or("; } @@ -1141,7 +1141,7 @@ class Item_sum_and :public Item_sum_bit class Item_sum_xor :public Item_sum_bit { public: - Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} + Item_sum_xor(Item *item_par) :Item_sum_bit(item_par, 0) {} Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {} bool add(); const char *func_name() const { return "bit_xor("; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 69a6dac5381..f43a4e79431 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -709,8 +709,8 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, { longlong value; const char *start= str; - for (value=0; str != end && my_isdigit(cs,*str) ; str++) - value= value*LL(10) + (longlong) (*str - '0'); + for (value=0; str != end && my_isdigit(cs, *str) ; str++) + value= value*10 + *str - '0'; msec_length= 6 - (str - start); values[i]= value; while (str != end && !my_isdigit(cs,*str)) diff --git a/sql/log_event.h b/sql/log_event.h index 24a08ae107c..be63304b529 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1,4 +1,5 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -551,7 +552,7 @@ struct sql_ex_info /* Shouldn't be defined before */ #define EXPECTED_OPTIONS \ - ((ULL(1) << 14) | (ULL(1) << 26) | (ULL(1) << 27) | (ULL(1) << 19)) + ((1ULL << 14) | (1ULL << 26) | (1ULL << 27) | (1ULL << 19)) #if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS #error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values! diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 8a1170cf4fa..1be97b34204 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2006, 2010, Oracle and/or its affiliates. + Copyright (c) 2011, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -521,9 +522,9 @@ bool is_conversion_ok(int order, Relay_log_info *rli) bool allow_non_lossy, allow_lossy; allow_non_lossy = slave_type_conversions_options & - (ULL(1) << SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY); + (1ULL << SLAVE_TYPE_CONVERSIONS_ALL_NON_LOSSY); allow_lossy= slave_type_conversions_options & - (ULL(1) << SLAVE_TYPE_CONVERSIONS_ALL_LOSSY); + (1ULL << SLAVE_TYPE_CONVERSIONS_ALL_LOSSY); DBUG_PRINT("enter", ("order: %d, flags:%s%s", order, allow_non_lossy ? " ALL_NON_LOSSY" : "", diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index db4c7110ac7..5e86a889053 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2003, 2010, Oracle and/or its affiliates + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -60,7 +61,7 @@ public: intersect(map2buff); if (map.n_bits > sizeof(ulonglong) * 8) bitmap_set_above(&map, sizeof(ulonglong), - test(map2buff & (LL(1) << (sizeof(ulonglong) * 8 - 1)))); + test(map2buff & (1LL << (sizeof(ulonglong) * 8 - 1)))); } void subtract(Bitmap& map2) { bitmap_subtract(&map, &map2.map); } void merge(Bitmap& map2) { bitmap_union(&map, &map2.map); } diff --git a/sql/sql_class.h b/sql/sql_class.h index a5bb12ae370..711bd035ba9 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2009, 2012, Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -75,38 +75,38 @@ enum enum_mark_columns enum enum_filetype { FILETYPE_CSV, FILETYPE_XML }; /* Bits for different SQL modes modes (including ANSI mode) */ -#define MODE_REAL_AS_FLOAT 1 -#define MODE_PIPES_AS_CONCAT 2 -#define MODE_ANSI_QUOTES 4 -#define MODE_IGNORE_SPACE 8 -#define MODE_IGNORE_BAD_TABLE_OPTIONS 16 -#define MODE_ONLY_FULL_GROUP_BY 32 -#define MODE_NO_UNSIGNED_SUBTRACTION 64 -#define MODE_NO_DIR_IN_CREATE 128 -#define MODE_POSTGRESQL 256 -#define MODE_ORACLE 512 -#define MODE_MSSQL 1024 -#define MODE_DB2 2048 -#define MODE_MAXDB 4096 -#define MODE_NO_KEY_OPTIONS 8192 -#define MODE_NO_TABLE_OPTIONS 16384 -#define MODE_NO_FIELD_OPTIONS 32768 -#define MODE_MYSQL323 65536L -#define MODE_MYSQL40 (MODE_MYSQL323*2) -#define MODE_ANSI (MODE_MYSQL40*2) -#define MODE_NO_AUTO_VALUE_ON_ZERO (MODE_ANSI*2) -#define MODE_NO_BACKSLASH_ESCAPES (MODE_NO_AUTO_VALUE_ON_ZERO*2) -#define MODE_STRICT_TRANS_TABLES (MODE_NO_BACKSLASH_ESCAPES*2) -#define MODE_STRICT_ALL_TABLES (MODE_STRICT_TRANS_TABLES*2) -#define MODE_NO_ZERO_IN_DATE (MODE_STRICT_ALL_TABLES*2) -#define MODE_NO_ZERO_DATE (MODE_NO_ZERO_IN_DATE*2) -#define MODE_INVALID_DATES (MODE_NO_ZERO_DATE*2) -#define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2) -#define MODE_TRADITIONAL (MODE_ERROR_FOR_DIVISION_BY_ZERO*2) -#define MODE_NO_AUTO_CREATE_USER (MODE_TRADITIONAL*2) -#define MODE_HIGH_NOT_PRECEDENCE (MODE_NO_AUTO_CREATE_USER*2) -#define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2) -#define MODE_PAD_CHAR_TO_FULL_LENGTH (ULL(1) << 31) +#define MODE_REAL_AS_FLOAT (1ULL << 0) +#define MODE_PIPES_AS_CONCAT (1ULL << 1) +#define MODE_ANSI_QUOTES (1ULL << 2) +#define MODE_IGNORE_SPACE (1ULL << 3) +#define MODE_IGNORE_BAD_TABLE_OPTIONS (1ULL << 4) +#define MODE_ONLY_FULL_GROUP_BY (1ULL << 5) +#define MODE_NO_UNSIGNED_SUBTRACTION (1ULL << 6) +#define MODE_NO_DIR_IN_CREATE (1ULL << 7) +#define MODE_POSTGRESQL (1ULL << 8) +#define MODE_ORACLE (1ULL << 9) +#define MODE_MSSQL (1ULL << 10) +#define MODE_DB2 (1ULL << 11) +#define MODE_MAXDB (1ULL << 12) +#define MODE_NO_KEY_OPTIONS (1ULL << 13) +#define MODE_NO_TABLE_OPTIONS (1ULL << 14) +#define MODE_NO_FIELD_OPTIONS (1ULL << 15) +#define MODE_MYSQL323 (1ULL << 16) +#define MODE_MYSQL40 (1ULL << 17) +#define MODE_ANSI (1ULL << 18) +#define MODE_NO_AUTO_VALUE_ON_ZERO (1ULL << 19) +#define MODE_NO_BACKSLASH_ESCAPES (1ULL << 20) +#define MODE_STRICT_TRANS_TABLES (1ULL << 21) +#define MODE_STRICT_ALL_TABLES (1ULL << 22) +#define MODE_NO_ZERO_IN_DATE (1ULL << 23) +#define MODE_NO_ZERO_DATE (1ULL << 24) +#define MODE_INVALID_DATES (1ULL << 25) +#define MODE_ERROR_FOR_DIVISION_BY_ZERO (1ULL << 26) +#define MODE_TRADITIONAL (1ULL << 27) +#define MODE_NO_AUTO_CREATE_USER (1ULL << 28) +#define MODE_HIGH_NOT_PRECEDENCE (1ULL << 29) +#define MODE_NO_ENGINE_SUBSTITUTION (1ULL << 30) +#define MODE_PAD_CHAR_TO_FULL_LENGTH (1ULL << 31) extern char internal_table_name[2]; extern char empty_c_string[1]; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 9f6185280cd..40bd59975f3 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2007, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2012, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -226,7 +226,7 @@ void time_out_user_resource_limits(THD *thd, USER_CONN *uc) DBUG_ENTER("time_out_user_resource_limits"); /* If more than a hour since last check, reset resource checking */ - if (check_time - uc->reset_utime >= LL(3600000000)) + if (check_time - uc->reset_utime >= 3600000000ULL) { uc->questions=0; uc->updates=0; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a6038031936..a56d9f4adc8 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2877,7 +2877,7 @@ void st_select_lex_unit::set_limit(st_select_lex *sl) val= fix_fields_successful ? item->val_uint() : 0; } else - val= ULL(0); + val= 0; offset_limit_cnt= (ha_rows)val; #ifndef BIG_TABLES diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ed4a68c8534..e866d2b74ef 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2012, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1379,7 +1379,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!(uptime= (ulong) (thd->start_time - server_start_time))) queries_per_second1000= 0; else - queries_per_second1000= thd->query_id * LL(1000) / uptime; + queries_per_second1000= thd->query_id * 1000 / uptime; length= my_snprintf(buff, buff_len - 1, "Uptime: %lu Threads: %d Questions: %lu " diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index f042f028450..ecd8315b80d 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2005, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2011, Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4717,8 +4717,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, } alt_part_info->part_type= tab_part_info->part_type; alt_part_info->subpart_type= tab_part_info->subpart_type; - if (alt_part_info->set_up_defaults_for_partitioning(new_table->file, - ULL(0), + if (alt_part_info->set_up_defaults_for_partitioning(new_table->file, 0, tab_part_info->num_parts)) { goto err; @@ -5134,8 +5133,7 @@ state of p1. alt_part_info->num_subparts= tab_part_info->num_subparts; DBUG_ASSERT(!alt_part_info->use_default_partitions); if (alt_part_info->set_up_defaults_for_partitioning(new_table->file, - ULL(0), - 0)) + 0, 0)) { goto err; } @@ -5268,7 +5266,7 @@ the generated partition syntax in a correct manner. tab_part_info->use_default_num_subpartitions= FALSE; } if (tab_part_info->check_partition_info(thd, (handlerton**)NULL, - new_table->file, ULL(0), TRUE)) + new_table->file, 0, TRUE)) { goto err; } diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 4e356b48497..7ff13bf06c3 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2010-2011 Monty Program Ab + Copyright (c) 2010, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -143,15 +143,15 @@ however, needs to rollback the effects of the succeeded statement to keep replication consistent. */ -#define OPTION_MASTER_SQL_ERROR (1ULL << 35) +#define OPTION_MASTER_SQL_ERROR (1ULL << 35) /* Dont report errors for individual rows, But just report error on commit (or read ofcourse) Note! Reserved for use in MySQL Cluster */ -#define OPTION_ALLOW_BATCH (ULL(1) << 36) // THD, intern (slave) -#define OPTION_SKIP_REPLICATION (ULL(1) << 37) // THD, user +#define OPTION_ALLOW_BATCH (1ULL << 36) // THD, intern (slave) +#define OPTION_SKIP_REPLICATION (1ULL << 37) // THD, user /* Check how many bytes are available on buffer. diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 631255e0d69..62336073b28 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2012, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -716,7 +716,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, *p_start_coord= &start_coord; LOG_POS_COORD coord_buf= { log_file_name, BIN_LOG_HEADER_SIZE }, *p_coord= &coord_buf; - if (heartbeat_period != LL(0)) + if (heartbeat_period != 0) { heartbeat_ts= &heartbeat_buf; set_timespec_nsec(*heartbeat_ts, 0); @@ -1827,7 +1827,7 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) else mi->heartbeat_period= (float) min(SLAVE_MAX_HEARTBEAT_PERIOD, (slave_net_timeout/2.0)); - mi->received_heartbeats= LL(0); // counter lives until master is CHANGEd + mi->received_heartbeats= 0; // counter lives until master is CHANGEd /* reset the last time server_id list if the current CHANGE MASTER is mentioning IGNORE_SERVER_IDS= (...) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ad4324fa7d1..41e09482e8e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2176,8 +2176,7 @@ JOIN::reinit() DBUG_ENTER("JOIN::reinit"); unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ? - select_lex->offset_limit->val_uint() : - ULL(0)); + select_lex->offset_limit->val_uint() : 0); first_record= 0; cleaned= false; diff --git a/sql/sql_time.cc b/sql/sql_time.cc index dadf579b2e7..89c2e3b7086 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -1017,13 +1017,13 @@ calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign, longlong *s (uint) l_time2->day); } - microseconds= ((longlong)days*LL(86400) + + microseconds= ((longlong)days*86400LL + (longlong)(l_time1->hour*3600L + l_time1->minute*60L + l_time1->second) - l_sign*(longlong)(l_time2->hour*3600L + l_time2->minute*60L + - l_time2->second)) * LL(1000000) + + l_time2->second)) * 1000000LL + (longlong)l_time1->second_part - l_sign*(longlong)l_time2->second_part; diff --git a/sql/sql_udf.h b/sql/sql_udf.h index cdb15b9e0f5..4aa055b9858 100644 --- a/sql/sql_udf.h +++ b/sql/sql_udf.h @@ -103,14 +103,14 @@ class udf_handler :public Sql_alloc if (get_arguments()) { *null_value=1; - return LL(0); + return 0; } Udf_func_longlong func= (Udf_func_longlong) u_d->func; longlong tmp=func(&initid, &f_args, &is_null, &error); if (is_null || error) { *null_value=1; - return LL(0); + return 0; } *null_value=0; return tmp; diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index e3668d3c8d3..09cf84f1fdb 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -1,4 +1,5 @@ /* Copyright (C) 2007 Michael Widenius + Copyright (c) 2010, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1256,7 +1257,7 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size, a full page or a tail page */ if ((!bits && best_data) || - ((bits & LL(04444444444444444)) == LL(04444444444444444))) + ((bits & 04444444444444444LL) == 04444444444444444LL)) continue; for (i= 0; i < 16 ; i++, bits >>= 3) { @@ -1344,8 +1345,8 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size, quite common case if we have blobs. */ - if ((!bits && best_data) || bits == LL(0xffffffffffff) || - bits == LL(04444444444444444)) + if ((!bits && best_data) || bits == 0xffffffffffffLL || + bits == 04444444444444444LL) continue; for (i= 0; i < 16; i++, bits >>= 3) { @@ -1470,14 +1471,14 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap, bits= prefix_bits= uint6korr(data_start - 6); DBUG_ASSERT(bits != 0); /* 111 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 */ - if (!(bits & LL(07000000000000000))) + if (!(bits & 07000000000000000LL)) { data_start-= 6; do { prefix_area_size++; bits<<= 3; - } while (!(bits & LL(07000000000000000))); + } while (!(bits & 07000000000000000LL)); area_size+= prefix_area_size; /* Calculate offset to page from data_start */ prefix_area_size= 16 - prefix_area_size; @@ -1526,11 +1527,11 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap, best_prefix_area_size= 16 - best_prefix_area_size; if (best_area_size < best_prefix_area_size) { - tmp= (LL(1) << best_area_size*3) - 1; + tmp= (1LL << best_area_size*3) - 1; best_area_size= best_prefix_area_size; /* for easy end test */ } else - tmp= (LL(1) << best_prefix_area_size*3) - 1; + tmp= (1LL << best_prefix_area_size*3) - 1; tmp<<= (16 - best_prefix_area_size) * 3; DBUG_ASSERT((best_prefix_bits & tmp) == 0); best_prefix_bits|= tmp; diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 55b9a137050..8b5da1dbefa 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -5454,7 +5454,7 @@ restart_bitmap_scan: { bits= uint6korr(data); /* Skip not allocated pages and blob / full tail pages */ - if (bits && bits != LL(07777777777777777)) + if (bits && bits != 07777777777777777LL) break; } bit_pos= 0; diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index 28c3491730f..4ed00598c2f 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -1215,19 +1215,19 @@ uint maria_get_pointer_length(ulonglong file_length, uint def) if (file_length) /* If not default */ { #ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS - if (file_length >= (ULL(1) << 56)) + if (file_length >= (1ULL << 56)) def=8; else #endif - if (file_length >= (ULL(1) << 48)) + if (file_length >= (1ULL << 48)) def=7; - else if (file_length >= (ULL(1) << 40)) + else if (file_length >= (1ULL << 40)) def=6; - else if (file_length >= (ULL(1) << 32)) + else if (file_length >= (1ULL << 32)) def=5; - else if (file_length >= (ULL(1) << 24)) + else if (file_length >= (1ULL << 24)) def=4; - else if (file_length >= (ULL(1) << 16)) + else if (file_length >= (1ULL << 16)) def=3; else def=2; diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c index f62ffcc49a0..a3553801eaa 100644 --- a/storage/maria/ma_key.c +++ b/storage/maria/ma_key.c @@ -99,7 +99,7 @@ uint transid_store_packed(MARIA_HA *info, uchar *to, ulonglong trid) uchar *start; uint length; uchar buff[8]; - DBUG_ASSERT(trid < (LL(1) << (MARIA_MAX_PACK_TRANSID_SIZE*8))); + DBUG_ASSERT(trid < (1LL << (MARIA_MAX_PACK_TRANSID_SIZE*8))); DBUG_ASSERT(trid >= info->s->state.create_trid); trid= (trid - info->s->state.create_trid) << 1; diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 56926c048d8..70d26b5ca49 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -3274,7 +3274,7 @@ static my_bool translog_get_last_page_addr(TRANSLOG_ADDRESS *addr, DBUG_PRINT("info", ("File size: %s", llstr(file_size, buff))); if (file_size == MY_FILEPOS_ERROR) DBUG_RETURN(1); - DBUG_ASSERT(file_size < ULL(0xffffffff)); + DBUG_ASSERT(file_size < 0xffffffffULL); if (((uint32)file_size) > TRANSLOG_PAGE_SIZE) { rec_offset= (((((uint32)file_size) / TRANSLOG_PAGE_SIZE) - 1) * @@ -3785,12 +3785,12 @@ my_bool translog_init_with_table(const char *directory, TRANSLOG_FILE *file= (TRANSLOG_FILE *)my_malloc(sizeof(TRANSLOG_FILE), MYF(0)); - compile_time_assert(MY_FILEPOS_ERROR > ULL(0xffffffff)); + compile_time_assert(MY_FILEPOS_ERROR > 0xffffffffULL); if (file == NULL || (file->handler.file= open_logfile_by_number_no_cache(i)) < 0 || mysql_file_seek(file->handler.file, 0, SEEK_END, MYF(0)) >= - ULL(0xffffffff)) + 0xffffffffULL) { int j; for (j= i - log_descriptor.min_file - 1; j > 0; j--) @@ -5247,7 +5247,7 @@ static uchar *translog_put_LSN_diff(LSN base_lsn, LSN lsn, uchar *dst) dst[0]= (uchar)(0x80 | (diff >> 24)); int3store(dst + 1, diff & 0xFFFFFFL); } - else if (diff <= LL(0x3FFFFFFFFF)) + else if (diff <= 0x3FFFFFFFFFLL) { dst-= 5; @@ -5344,7 +5344,7 @@ static uchar *translog_get_LSN_from_diff(LSN base_lsn, uchar *src, uchar *dst) { /* take 1 from file offset */ first_byte++; - base_offset+= LL(0x100000000); + base_offset+= 0x100000000LL; } file_no= LSN_FILE_NO(base_lsn) - first_byte; DBUG_ASSERT(base_offset - diff <= UINT_MAX); diff --git a/storage/maria/ma_loghandler_lsn.h b/storage/maria/ma_loghandler_lsn.h index 7fa53bc0a50..f618429f6f3 100644 --- a/storage/maria/ma_loghandler_lsn.h +++ b/storage/maria/ma_loghandler_lsn.h @@ -83,8 +83,8 @@ typedef TRANSLOG_ADDRESS LSN; other bytes are a LSN. */ typedef LSN LSN_WITH_FLAGS; -#define LSN_WITH_FLAGS_TO_LSN(x) (x & ULL(0x00FFFFFFFFFFFFFF)) -#define LSN_WITH_FLAGS_TO_FLAGS(x) (x & ULL(0xFF00000000000000)) +#define LSN_WITH_FLAGS_TO_LSN(x) (x & 0x00FFFFFFFFFFFFFFULL) +#define LSN_WITH_FLAGS_TO_FLAGS(x) (x & 0xFF00000000000000ULL) #define FILENO_IMPOSSIBLE 0 /**< log file's numbering starts at 1 */ #define LOG_OFFSET_IMPOSSIBLE 0 /**< log always has a header */ @@ -106,6 +106,6 @@ typedef LSN LSN_WITH_FLAGS; Unlike ULONGLONG_MAX, it can be safely used in comparison with valid LSNs (ULONGLONG_MAX is too big for correctness of cmp_translog_addr()). */ -#define LSN_MAX (LSN)ULL(0x00FFFFFFFFFFFFFF) +#define LSN_MAX (LSN)0x00FFFFFFFFFFFFFFULL #endif diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 6aaccea219f..4a3c3efd3fb 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -1650,7 +1650,7 @@ static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link) struct st_my_thread_var *thread; hash_link->file= first_page->file; - DBUG_ASSERT(first_page->pageno < ((ULL(1)) << 40)); + DBUG_ASSERT(first_page->pageno < ((1ULL) << 40)); hash_link->pageno= first_page->pageno; do { @@ -1813,7 +1813,7 @@ restart: goto restart; } hash_link->file= *file; - DBUG_ASSERT(pageno < ((ULL(1)) << 40)); + DBUG_ASSERT(pageno < ((1ULL) << 40)); hash_link->pageno= pageno; link_hash(start, hash_link); /* Register the request for the page */ @@ -3357,7 +3357,7 @@ uchar *pagecache_read(PAGECACHE *pagecache, page_cache_page_pin_str[unlock_pin])); DBUG_ASSERT(buff != 0 || (buff == 0 && (unlock_pin == PAGECACHE_PIN || unlock_pin == PAGECACHE_PIN_LEFT_PINNED))); - DBUG_ASSERT(pageno < ((ULL(1)) << 40)); + DBUG_ASSERT(pageno < ((1ULL) << 40)); #endif if (!page_link) @@ -3797,7 +3797,7 @@ my_bool pagecache_delete(PAGECACHE *pagecache, pin == PAGECACHE_PIN_LEFT_PINNED); restart: - DBUG_ASSERT(pageno < ((ULL(1)) << 40)); + DBUG_ASSERT(pageno < ((1ULL) << 40)); if (pagecache->can_be_used) { /* Key cache is used */ @@ -3977,7 +3977,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache, DBUG_ASSERT(lock != PAGECACHE_LOCK_LEFT_READLOCKED); DBUG_ASSERT(lock != PAGECACHE_LOCK_READ_UNLOCK); DBUG_ASSERT(offset + size <= pagecache->block_size); - DBUG_ASSERT(pageno < ((ULL(1)) << 40)); + DBUG_ASSERT(pageno < ((1ULL) << 40)); #endif if (!page_link) @@ -4974,7 +4974,7 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache, ptr+= 2; ptr[0]= (share->kfile.file == block->hash_link->file.file); ptr++; - DBUG_ASSERT(block->hash_link->pageno < ((ULL(1)) << 40)); + DBUG_ASSERT(block->hash_link->pageno < ((1ULL) << 40)); page_store(ptr, block->hash_link->pageno); ptr+= PAGE_STORE_SIZE; lsn_store(ptr, block->rec_lsn); diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 9ac42f885b5..aeeda26b791 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -1,5 +1,5 @@ /* Copyright (C) 2006, 2007 MySQL AB - Copyright (C) 2010-2011 Monty Program Ab + Copyright (C) 2010, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3683,7 +3683,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr) end_offset); if (initial_remainder == (ulonglong)(-1)) initial_remainder= local_remainder; - percentage_done= (uint) ((initial_remainder - local_remainder) * ULL(100) / + percentage_done= (uint) ((initial_remainder - local_remainder) * 100ULL / initial_remainder); if ((percentage_done - percentage_printed) >= 10) { diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index a5c448cf0f7..0dce9114f2a 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -855,7 +855,7 @@ struct st_maria_handler #define MARIA_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */ /* Marker for impossible delete link */ -#define IMPOSSIBLE_PAGE_NO LL(0xFFFFFFFFFF) +#define IMPOSSIBLE_PAGE_NO 0xFFFFFFFFFFLL /* The UNIQUE check is done with a hashed long key */ diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c index 40686995378..788bc5c2ad3 100644 --- a/storage/maria/maria_pack.c +++ b/storage/maria/maria_pack.c @@ -1905,7 +1905,7 @@ static int make_huff_decode_table(HUFF_TREE *huff_tree, uint trees) return 1; huff_tree->code_len=(uchar*) (huff_tree->code+elements); make_traverse_code_tree(huff_tree, huff_tree->root, - 8 * sizeof(ulonglong), LL(0)); + 8 * sizeof(ulonglong), 0); } } return 0; diff --git a/storage/maria/trnman.h b/storage/maria/trnman.h index f28345908f2..77e2916390a 100644 --- a/storage/maria/trnman.h +++ b/storage/maria/trnman.h @@ -56,7 +56,7 @@ struct st_ma_transaction uint16 flags; /**< Various flags */ }; -#define TRANSACTION_LOGGED_LONG_ID ULL(0x8000000000000000) +#define TRANSACTION_LOGGED_LONG_ID 0x8000000000000000ULL #define MAX_TRID (~(TrID)0) extern WT_RESOURCE_TYPE ma_rc_dup_unique; diff --git a/storage/maria/unittest/ma_control_file-t.c b/storage/maria/unittest/ma_control_file-t.c index b4e757788c2..1d52dee6ece 100644 --- a/storage/maria/unittest/ma_control_file-t.c +++ b/storage/maria/unittest/ma_control_file-t.c @@ -277,7 +277,7 @@ static int test_five_logs_and_max_trid(void) RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK); expect_logno= 100; - expect_max_trid= ULL(14111978111); + expect_max_trid= 14111978111ULL; for (i= 0; i<5; i++) { expect_logno*= 3; diff --git a/storage/maria/unittest/trnman-t.c b/storage/maria/unittest/trnman-t.c index c2bc993e2ff..78740eac9c1 100644 --- a/storage/maria/unittest/trnman-t.c +++ b/storage/maria/unittest/trnman-t.c @@ -45,7 +45,7 @@ pthread_handler_t test_trnman(void *arg) for (x= ((int)(intptr)(&m)); m > 0; ) { - y= x= (x*LL(3628273133) + LL(1500450271)) % LL(9576890767); /* three prime numbers */ + y= x= (x*3628273133LL + 1500450271LL) % 9576890767LL; /* three prime numbers */ m-= n= x % MAX_ITER; for (i= 0; i < n; i++) { diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index d4cc31368dd..b33bcced04d 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -863,19 +864,19 @@ uint mi_get_pointer_length(ulonglong file_length, uint def) if (file_length) /* If not default */ { #ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS - if (file_length >= ULL(1) << 56) + if (file_length >= 1ULL << 56) def=8; else #endif - if (file_length >= ULL(1) << 48) + if (file_length >= 1ULL << 48) def=7; - else if (file_length >= ULL(1) << 40) + else if (file_length >= 1ULL << 40) def=6; - else if (file_length >= ULL(1) << 32) + else if (file_length >= 1ULL << 32) def=5; - else if (file_length >= ULL(1) << 24) + else if (file_length >= 1ULL << 24) def=4; - else if (file_length >= ULL(1) << 16) + else if (file_length >= 1ULL << 16) def=3; else def=2; diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index 6ce88db87f5..1985a53acf8 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -1,4 +1,5 @@ /* Copyright (c) 2000, 2010, Oracle and/or its affiliates + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1931,7 +1932,7 @@ static int make_huff_decode_table(HUFF_TREE *huff_tree, uint trees) return 1; huff_tree->code_len=(uchar*) (huff_tree->code+elements); make_traverse_code_tree(huff_tree, huff_tree->root, - 8 * sizeof(ulonglong), LL(0)); + 8 * sizeof(ulonglong), 0); } } return 0; diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 6ebbae8fb5a..89df4ae0bc4 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1,5 +1,5 @@ /* Copyright (c) 2003, 2012, Oracle and/or its affiliates - Copyright (c) 2009, 2011, Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -40,11 +40,11 @@ #undef ULONGLONG_MAX #define ULONGLONG_MAX (~(ulonglong) 0) -#define MAX_NEGATIVE_NUMBER ((ulonglong) LL(0x8000000000000000)) +#define MAX_NEGATIVE_NUMBER ((ulonglong) 0x8000000000000000LL) #define INIT_CNT 9 -#define LFACTOR ULL(1000000000) -#define LFACTOR1 ULL(10000000000) -#define LFACTOR2 ULL(100000000000) +#define LFACTOR 1000000000ULL +#define LFACTOR1 10000000000ULL +#define LFACTOR2 100000000000ULL #if defined(HAVE_CHARSET_utf32) || defined(HAVE_CHARSET_mb2) static unsigned long lfactor[9]= diff --git a/strings/decimal.c b/strings/decimal.c index 3245f224b44..edcb4c52354 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004, 2011, Oracle and/or its affiliates. - Copyright (c) 2009, 2011, Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1032,7 +1032,7 @@ int decimal2ulonglong(const decimal_t *from, ulonglong *to) if (from->sign) { - *to=ULL(0); + *to= 0; return E_DEC_OVERFLOW; } diff --git a/strings/my_strtoll10.c b/strings/my_strtoll10.c index 48d548242a8..7130f6253a8 100644 --- a/strings/my_strtoll10.c +++ b/strings/my_strtoll10.c @@ -1,5 +1,5 @@ /* Copyright (c) 2003 TXT DataKonsult Ab - Copyright (c) 2009-2011, Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -29,11 +29,11 @@ #include "strings_def.h" #include /* Needed for MY_ERRNO_ERANGE */ -#define MAX_NEGATIVE_NUMBER ((ulonglong) LL(0x8000000000000000)) +#define MAX_NEGATIVE_NUMBER ((ulonglong) 0x8000000000000000ULL) #define INIT_CNT 9 -#define LFACTOR ULL(1000000000) -#define LFACTOR1 ULL(10000000000) -#define LFACTOR2 ULL(100000000000) +#define LFACTOR 1000000000ULL +#define LFACTOR1 10000000000ULL +#define LFACTOR2 100000000000ULL static unsigned long lfactor[9]= { diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index f348ec4515b..ec89e256579 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -1,5 +1,5 @@ /* Copyright (c) 2002, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2012, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9862,11 +9862,11 @@ static void test_bug3035() const uint32 uint32_max= 4294967295U; /* it might not work okay everyplace */ - const longlong int64_max= LL(9223372036854775807); + const longlong int64_max= 9223372036854775807LL; const longlong int64_min= -int64_max - 1; const ulonglong uint64_min= 0U; - const ulonglong uint64_max= ULL(18446744073709551615); + const ulonglong uint64_max= 18446744073709551615ULL; const char *stmt_text; @@ -12533,7 +12533,7 @@ static void test_truncation() /* double -> longlong, negative fp number to signed integer: no loss */ DIE_UNLESS(my_bind++ < bind_array + bind_count); - DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == LL(-12345678910)); + DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == -12345678910LL); /* big numeric string -> number */ DIE_UNLESS(my_bind++ < bind_array + bind_count); @@ -14535,7 +14535,7 @@ static void test_bug12925() { myheader("test_bug12925"); if (opt_getopt_ll_test) - DIE_UNLESS(opt_getopt_ll_test == LL(25600*1024*1024)); + DIE_UNLESS(opt_getopt_ll_test == 25600LL*1024*1024); } From e56cad4b152285219db19f542e4610c1307e3d92 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:03:43 +0200 Subject: [PATCH 02/87] small cleanup --- include/hash.h | 12 +++++------- mysql-test/suite/archive/archive.test | 1 - mysys/hash.c | 6 ++++-- sql/my_apc.cc | 3 +-- sql/my_apc.h | 8 ++++---- storage/archive/ha_archive.cc | 18 +----------------- 6 files changed, 15 insertions(+), 33 deletions(-) diff --git a/include/hash.h b/include/hash.h index 2ecfe0891d7..f014c44c7ec 100644 --- a/include/hash.h +++ b/include/hash.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. + Copyright (c) 2011, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -60,11 +61,8 @@ typedef struct st_hash { /* A search iterator state */ typedef uint HASH_SEARCH_STATE; -#define my_hash_init(A,B,C,D,E,F,G,H) \ - _my_hash_init(A,0,B,C,D,E,F,G,H) -#define my_hash_init2(A,B,C,D,E,F,G,H,I) \ - _my_hash_init(A,B,C,D,E,F,G,H,I) -my_bool _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset, +#define my_hash_init(A,B,C,D,E,F,G,H) my_hash_init2(A,0,B,C,D,E,F,G,H) +my_bool my_hash_init2(HASH *hash, uint growth_size, CHARSET_INFO *charset, ulong default_array_elements, size_t key_offset, size_t key_length, my_hash_get_key get_key, void (*free_element)(void*), @@ -98,7 +96,7 @@ my_bool my_hash_iterate(HASH *hash, my_hash_walk_action action, void *argument); #define my_hash_clear(H) bzero((char*) (H), sizeof(*(H))) #define my_hash_inited(H) ((H)->blength != 0) #define my_hash_init_opt(A,B,C,D,E,F,G,H) \ - (!my_hash_inited(A) && _my_hash_init(A,0,B,C,D,E,F,G,H)) + (!my_hash_inited(A) && my_hash_init(A,B,C,D,E,F,G,H)) #ifdef __cplusplus } diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 5dd85bf1aba..5bcefa3dcd5 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -3,7 +3,6 @@ # Taken FROM the select test # -- source include/have_archive.inc --- source include/have_binlog_format_mixed_or_statement.inc CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); call mtr.add_suppression("Table 't1' is marked as crashed and should be repaired"); diff --git a/mysys/hash.c b/mysys/hash.c index 0a830d8e3f4..aca6be4eb80 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. + Copyright (c) 2011, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,6 +60,7 @@ static my_hash_value_type calc_hash(const HASH *hash, as required during insertion. @param[in,out] hash The hash that is initialized + @param[in[ growth_size size incrememnt for the underlying dynarray @param[in] charset The charater set information @param[in] size The hash size @param[in] key_offest The key offset for the hash @@ -72,7 +74,7 @@ static my_hash_value_type calc_hash(const HASH *hash, @retval 1 failure */ my_bool -_my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset, +my_hash_init2(HASH *hash, uint growth_size, CHARSET_INFO *charset, ulong size, size_t key_offset, size_t key_length, my_hash_get_key get_key, void (*free_element)(void*), uint flags) diff --git a/sql/my_apc.cc b/sql/my_apc.cc index 4d0042510ae..3bad1331364 100644 --- a/sql/my_apc.cc +++ b/sql/my_apc.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2011 - 2012, Monty Program Ab + Copyright (c) 2011, 2013 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,6 @@ #ifndef MY_APC_STANDALONE -#include "sql_priv.h" #include "sql_class.h" #endif diff --git a/sql/my_apc.h b/sql/my_apc.h index 7f19809c082..c84074b2da5 100644 --- a/sql/my_apc.h +++ b/sql/my_apc.h @@ -1,7 +1,7 @@ -#ifndef INCLUDES_MY_APC_H -#define INCLUDES_MY_APC_H +#ifndef SQL_MY_APC_INCLUDED +#define SQL_MY_APC_INCLUDED /* - Copyright (c) 2011 - 2012, Monty Program Ab + Copyright (c) 2011, 2013 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -134,5 +134,5 @@ private: void init_show_explain_psi_keys(void); #endif -#endif //INCLUDES_MY_APC_H +#endif //SQL_MY_APC_INCLUDED diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 8d418cb571c..5ee7841d9b3 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2004, 2012, Oracle and/or its affiliates + Copyright (c) 2010, 2013 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -1812,23 +1813,6 @@ void ha_archive::destroy_record_buffer(archive_record_buffer *r) struct st_mysql_storage_engine archive_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; -mysql_declare_plugin(archive) -{ - MYSQL_STORAGE_ENGINE_PLUGIN, - &archive_storage_engine, - "ARCHIVE", - "Brian Aker, MySQL AB", - "Archive storage engine", - PLUGIN_LICENSE_GPL, - archive_db_init, /* Plugin Init */ - archive_db_done, /* Plugin Deinit */ - 0x0300 /* 3.0 */, - NULL, /* status variables */ - NULL, /* system variables */ - NULL, /* config options */ - 0, /* flags */ -} -mysql_declare_plugin_end; maria_declare_plugin(archive) { MYSQL_STORAGE_ENGINE_PLUGIN, From a6fa724b7f7826d238952713a10bc4e52df1237f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:36:53 +0200 Subject: [PATCH 03/87] split THD::make_lex_string() in two --- sql/sql_acl.cc | 10 ++++------ sql/sql_class.cc | 30 +++------------------------- sql/sql_class.h | 18 ++++++++++++++--- sql/sql_show.cc | 51 ++++++++++++++++++++++-------------------------- sql/sql_view.cc | 6 +++--- 5 files changed, 48 insertions(+), 67 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f6b3a7adeb7..56dec73bac5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7034,10 +7034,8 @@ bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name, tables->db= (char*)sp_db; tables->table_name= tables->alias= (char*)sp_name; - thd->make_lex_string(&combo->user, - combo->user.str, strlen(combo->user.str), 0); - thd->make_lex_string(&combo->host, - combo->host.str, strlen(combo->host.str), 0); + thd->make_lex_string(&combo->user, combo->user.str, strlen(combo->user.str)); + thd->make_lex_string(&combo->host, combo->host.str, strlen(combo->host.str)); combo->password= empty_lex_str; combo->plugin= empty_lex_str; @@ -8263,7 +8261,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) thd->user_connect= 0; strmake(sctx->priv_user, sctx->user, USERNAME_LENGTH); - if (thd->make_lex_string(&mpvio->db, db_buff, db_len, 0) == 0) + if (thd->make_lex_string(&mpvio->db, db_buff, db_len) == 0) DBUG_RETURN(1); /* The error is set by make_lex_string(). */ /* @@ -8489,7 +8487,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, Security_context *sctx= thd->security_ctx; - if (thd->make_lex_string(&mpvio->db, db, db_len, 0) == 0) + if (thd->make_lex_string(&mpvio->db, db, db_len) == 0) return packet_error; /* The error is set by make_lex_string(). */ my_free(sctx->user); if (!(sctx->user= my_strndup(user, user_len, MYF(MY_WME)))) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 6218ca60311..95aa4a00122 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2008, 2012, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1186,8 +1186,8 @@ LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str, const char *str, unsigned int size, int allocate_lex_string) { - return thd->make_lex_string(lex_str, str, size, - (bool) allocate_lex_string); + return allocate_lex_string ? thd->make_lex_string(str, size) + : thd->make_lex_string(lex_str, str, size); } extern "C" @@ -1900,30 +1900,6 @@ void THD::cleanup_after_query() } -/** - Create a LEX_STRING in this connection. - - @param lex_str pointer to LEX_STRING object to be initialized - @param str initializer to be copied into lex_str - @param length length of str, in bytes - @param allocate_lex_string if TRUE, allocate new LEX_STRING object, - instead of using lex_str value - @return NULL on failure, or pointer to the LEX_STRING object -*/ -LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str, - const char* str, uint length, - bool allocate_lex_string) -{ - if (allocate_lex_string) - if (!(lex_str= (LEX_STRING *)alloc_root(mem_root, sizeof(LEX_STRING)))) - return 0; - if (!(lex_str->str= strmake_root(mem_root, str, length))) - return 0; - lex_str->length= length; - return lex_str; -} - - /* Convert a string to another character set diff --git a/sql/sql_class.h b/sql/sql_class.h index 711bd035ba9..8ccb524f715 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2622,9 +2622,21 @@ public: return alloc_root(&transaction.mem_root,size); } - LEX_STRING *make_lex_string(LEX_STRING *lex_str, - const char* str, uint length, - bool allocate_lex_string); + LEX_STRING *make_lex_string(LEX_STRING *lex_str, const char* str, uint length) + { + if (!(lex_str->str= strmake_root(mem_root, str, length))) + return 0; + lex_str->length= length; + return lex_str; + } + + LEX_STRING *make_lex_string(const char* str, uint length) + { + LEX_STRING *lex_str; + if (!(lex_str= (LEX_STRING *)alloc_root(mem_root, sizeof(LEX_STRING)))) + return 0; + return make_lex_string(lex_str, str, length); + } bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, const char *from, uint from_length, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 269a99faadd..fb4db70abaa 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2009, 2012, Monty Program Ab + Copyright (c) 2009, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -829,8 +829,7 @@ find_files(THD *thd, List *files, const char *db, continue; } #endif - if (!(file_name= - thd->make_lex_string(file_name, uname, file_name_len, TRUE)) || + if (!(file_name= thd->make_lex_string(uname, file_name_len)) || files->push_back(file_name)) { my_dirend(dirp); @@ -3443,8 +3442,8 @@ bool get_lookup_value(THD *thd, Item_func *item_func, (uchar *) item_field->field_name, strlen(item_field->field_name), 0)) { - thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(), - tmp_str->length(), FALSE); + thd->make_lex_string(&lookup_field_vals->db_value, + tmp_str->ptr(), tmp_str->length()); } /* Lookup value is table name */ else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2, @@ -3452,8 +3451,8 @@ bool get_lookup_value(THD *thd, Item_func *item_func, (uchar *) item_field->field_name, strlen(item_field->field_name), 0)) { - thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(), - tmp_str->length(), FALSE); + thd->make_lex_string(&lookup_field_vals->table_value, + tmp_str->ptr(), tmp_str->length()); } } return 0; @@ -3638,8 +3637,7 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, case SQLCOM_SHOW_DATABASES: if (wild) { - thd->make_lex_string(&lookup_field_values->db_value, - wild, strlen(wild), 0); + thd->make_lex_string(&lookup_field_values->db_value, wild, strlen(wild)); lookup_field_values->wild_db_value= 1; } break; @@ -3648,11 +3646,11 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, case SQLCOM_SHOW_TRIGGERS: case SQLCOM_SHOW_EVENTS: thd->make_lex_string(&lookup_field_values->db_value, - lex->select_lex.db, strlen(lex->select_lex.db), 0); + lex->select_lex.db, strlen(lex->select_lex.db)); if (wild) { thd->make_lex_string(&lookup_field_values->table_value, - wild, strlen(wild), 0); + wild, strlen(wild)); lookup_field_values->wild_table_value= 1; } break; @@ -3711,9 +3709,8 @@ int make_db_list(THD *thd, List *files, bool *with_i_schema) { LEX_STRING *i_s_name_copy= 0; - i_s_name_copy= thd->make_lex_string(i_s_name_copy, - INFORMATION_SCHEMA_NAME.str, - INFORMATION_SCHEMA_NAME.length, TRUE); + i_s_name_copy= thd->make_lex_string(INFORMATION_SCHEMA_NAME.str, + INFORMATION_SCHEMA_NAME.length); *with_i_schema= 0; if (lookup_field_vals->wild_db_value) { @@ -3802,9 +3799,8 @@ static my_bool add_schema_table(THD *thd, plugin_ref plugin, DBUG_RETURN(0); } - if ((file_name= thd->make_lex_string(file_name, schema_table->table_name, - strlen(schema_table->table_name), - TRUE)) && + if ((file_name= thd->make_lex_string(schema_table->table_name, + strlen(schema_table->table_name))) && !file_list->push_back(file_name)) DBUG_RETURN(0); DBUG_RETURN(1); @@ -3835,8 +3831,8 @@ int schema_tables_add(THD *thd, List *files, const char *wild) continue; } if ((file_name= - thd->make_lex_string(file_name, tmp_schema_table->table_name, - strlen(tmp_schema_table->table_name), TRUE)) && + thd->make_lex_string(tmp_schema_table->table_name, + strlen(tmp_schema_table->table_name))) && !files->push_back(file_name)) continue; DBUG_RETURN(1); @@ -3888,9 +3884,8 @@ make_table_name_list(THD *thd, List *table_names, LEX *lex, find_schema_table(thd, lookup_field_vals->table_value.str); if (schema_table && !schema_table->hidden) { - if (!(name= - thd->make_lex_string(NULL, schema_table->table_name, - strlen(schema_table->table_name), TRUE)) || + if (!(name= thd->make_lex_string(schema_table->table_name, + strlen(schema_table->table_name))) || table_names->push_back(name)) return 1; } @@ -4015,10 +4010,10 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, These copies are used for make_table_list() while unaltered values are passed to process_table() functions. */ - if (!thd->make_lex_string(&db_name, orig_db_name->str, - orig_db_name->length, FALSE) || - !thd->make_lex_string(&table_name, orig_table_name->str, - orig_table_name->length, FALSE)) + if (!thd->make_lex_string(&db_name, + orig_db_name->str, orig_db_name->length) || + !thd->make_lex_string(&table_name, + orig_table_name->str, orig_table_name->length)) goto end; /* @@ -7860,9 +7855,9 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, because of lower_case_table_names */ thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str, - INFORMATION_SCHEMA_NAME.length, 0); + INFORMATION_SCHEMA_NAME.length); thd->make_lex_string(&table, schema_table->table_name, - strlen(schema_table->table_name), 0); + strlen(schema_table->table_name)); if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */ !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0), 0, 0, TL_READ, MDL_SHARED_READ)) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index bbc5c324573..8ce2c145d01 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2004, 2011, Oracle and/or its affiliates. - Copyright (c) 2011 Monty Program Ab + Copyright (c) 2011, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -871,7 +871,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->source= thd->lex->create_view_select; if (!thd->make_lex_string(&view->select_stmt, view_query.ptr(), - view_query.length(), false)) + view_query.length())) { my_error(ER_OUT_OF_RESOURCES, MYF(0)); error= -1; @@ -1004,7 +1004,7 @@ loop_out: view->view_creation_ctx->get_connection_cl()->name); if (!thd->make_lex_string(&view->view_body_utf8, is_query.ptr(), - is_query.length(), false)) + is_query.length())) { my_error(ER_OUT_OF_RESOURCES, MYF(0)); error= -1; From 37ad8d06e140e3b444643d8bbbb843fc56eb12a4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:40:45 +0200 Subject: [PATCH 04/87] cleanup --- sql/sql_show.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fb4db70abaa..fdfdea52a75 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3629,7 +3629,7 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, LOOKUP_FIELD_VALUES *lookup_field_values) { LEX *lex= thd->lex; - const char *wild= lex->wild ? lex->wild->ptr() : NullS; + String *wild= lex->wild; bool rc= 0; bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES)); @@ -3637,7 +3637,8 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, case SQLCOM_SHOW_DATABASES: if (wild) { - thd->make_lex_string(&lookup_field_values->db_value, wild, strlen(wild)); + thd->make_lex_string(&lookup_field_values->db_value, + wild->ptr(), wild->length()); lookup_field_values->wild_db_value= 1; } break; @@ -3650,7 +3651,7 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, if (wild) { thd->make_lex_string(&lookup_field_values->table_value, - wild, strlen(wild)); + wild->ptr(), wild->length()); lookup_field_values->wild_table_value= 1; } break; From daac5b511c7607cefed7579145d29c531e5257f3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:41:05 +0200 Subject: [PATCH 05/87] cleanup --- sql/sql_plugin.cc | 66 ++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 41 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 07b93818bb7..059fc197d22 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -509,7 +509,6 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, /* Determine interface version */ if (!sym) { - free_plugin_mem(plugin_dl); report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym); DBUG_RETURN(TRUE); } @@ -519,7 +518,6 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, if (plugin_dl->mysqlversion < min_plugin_interface_version || (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8)) { - free_plugin_mem(plugin_dl); report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, "plugin interface version mismatch"); DBUG_RETURN(TRUE); @@ -527,7 +525,6 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, /* Find plugin declarations */ if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym))) { - free_plugin_mem(plugin_dl); report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym); DBUG_RETURN(TRUE); } @@ -558,7 +555,6 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, MYF(MY_ZEROFILL|MY_WME)); if (!cur) { - free_plugin_mem(plugin_dl); report_error(report, ER_OUTOFMEMORY, static_cast(plugin_dl->dl.length)); DBUG_RETURN(TRUE); @@ -633,7 +629,6 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, Actually this branch impossible because in case of absence of maria version we try mysql version. */ - free_plugin_mem(plugin_dl); report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_interface_version_sym); DBUG_RETURN(TRUE); @@ -644,7 +639,6 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, if (plugin_dl->mariaversion < min_maria_plugin_interface_version || (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8)) { - free_plugin_mem(plugin_dl); report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, "plugin interface version mismatch"); DBUG_RETURN(TRUE); @@ -652,7 +646,6 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, /* Find plugin declarations */ if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym))) { - free_plugin_mem(plugin_dl); report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_declarations_sym); DBUG_RETURN(TRUE); } @@ -666,7 +659,6 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, sizeof_st_plugin= *(int *)sym; else { - free_plugin_mem(plugin_dl); report_error(report, ER_CANT_FIND_DL_ENTRY, maria_sizeof_st_plugin_sym); DBUG_RETURN(TRUE); } @@ -684,7 +676,6 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, MYF(MY_ZEROFILL|MY_WME)); if (!cur) { - free_plugin_mem(plugin_dl); report_error(report, ER_OUTOFMEMORY, static_cast(plugin_dl->dl.length)); DBUG_RETURN(TRUE); @@ -714,11 +705,12 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) #ifdef HAVE_DLOPEN char dlpath[FN_REFLEN]; uint plugin_dir_len, dummy_errors, dlpathlen, i; - struct st_plugin_dl *tmp, plugin_dl; + struct st_plugin_dl *tmp= 0, plugin_dl; void *sym; DBUG_ENTER("plugin_dl_add"); DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d", dl->str, (int) dl->length)); + mysql_mutex_assert_owner(&LOCK_plugin); plugin_dir_len= strlen(opt_plugin_dir); /* Ensure that the dll doesn't have a path. @@ -756,7 +748,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) if (*errmsg == ' ') errmsg++; } report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg); - DBUG_RETURN(0); + goto ret; } /* Checks which plugin interface present and reads info */ @@ -767,12 +759,12 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) plugin_interface_version_sym), dlpath, report)) - DBUG_RETURN(0); + goto ret; } else { if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report)) - DBUG_RETURN(0); + goto ret; } /* link the services in */ @@ -789,7 +781,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) "service '%s' interface version mismatch", list_of_services[i].name); report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0, buf); - DBUG_RETURN(0); + goto ret; } *(void**)sym= list_of_services[i].service; } @@ -799,10 +791,9 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1; if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0)))) { - free_plugin_mem(&plugin_dl); report_error(report, ER_OUTOFMEMORY, static_cast(plugin_dl.dl.length)); - DBUG_RETURN(0); + goto ret; } plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length, files_charset_info, dl->str, dl->length, system_charset_info, @@ -811,12 +802,17 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) /* Add this dll to array */ if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl))) { - free_plugin_mem(&plugin_dl); report_error(report, ER_OUTOFMEMORY, static_cast(sizeof(struct st_plugin_dl))); - DBUG_RETURN(0); + goto ret; } + +ret: + if (!tmp) + free_plugin_mem(&plugin_dl); + DBUG_RETURN(tmp); + #else DBUG_ENTER("plugin_dl_add"); report_error(report, ER_FEATURE_DISABLED, "plugin", "HAVE_DLOPEN"); @@ -825,34 +821,23 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) } -static void plugin_dl_del(const LEX_STRING *dl) +static void plugin_dl_del(struct st_plugin_dl *plugin_dl) { -#ifdef HAVE_DLOPEN - uint i; DBUG_ENTER("plugin_dl_del"); + if (!plugin_dl) + DBUG_VOID_RETURN; + mysql_mutex_assert_owner(&LOCK_plugin); - for (i= 0; i < plugin_dl_array.elements; i++) + /* Do not remove this element, unless no other plugin uses this dll. */ + if (! --plugin_dl->ref_count) { - struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i, - struct st_plugin_dl **); - if (tmp->ref_count && - ! my_strnncoll(files_charset_info, - (const uchar *)dl->str, dl->length, - (const uchar *)tmp->dl.str, tmp->dl.length)) - { - /* Do not remove this element, unless no other plugin uses this dll. */ - if (! --tmp->ref_count) - { - free_plugin_mem(tmp); - bzero(tmp, sizeof(struct st_plugin_dl)); - } - break; - } + free_plugin_mem(plugin_dl); + bzero(plugin_dl, sizeof(struct st_plugin_dl)); } + DBUG_VOID_RETURN; -#endif } @@ -1133,7 +1118,7 @@ err: if (errs == 0 && oks == 0) // no plugin was found report_error(report, ER_CANT_FIND_DL_ENTRY, name->str); - plugin_dl_del(dl); + plugin_dl_del(tmp.plugin_dl); DBUG_RETURN(errs > 0 || oks == 0); } @@ -1210,8 +1195,7 @@ static void plugin_del(struct st_plugin_int *plugin) restore_pluginvar_names(plugin->system_vars); plugin_vars_free_values(plugin->system_vars); my_hash_delete(&plugin_hash[plugin->plugin->type], (uchar*)plugin); - if (plugin->plugin_dl) - plugin_dl_del(&plugin->plugin_dl->dl); + plugin_dl_del(plugin->plugin_dl); plugin->state= PLUGIN_IS_FREED; plugin_array_version++; free_root(&plugin->mem_root, MYF(0)); From 78c0642073a196dbba2fd82ba903b64a9f35ba3f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:43:26 +0200 Subject: [PATCH 06/87] consistency in declaring service symbols --- libservices/HOWTO | 2 +- libservices/debug_sync_service.c | 2 +- libservices/progress_report_service.c | 2 +- libservices/thd_alloc_service.c | 2 +- libservices/thd_wait_service.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libservices/HOWTO b/libservices/HOWTO index 7dcfb6d9583..512cdb43c99 100644 --- a/libservices/HOWTO +++ b/libservices/HOWTO @@ -76,7 +76,7 @@ it should also declare all the accompanying data structures, as necessary ================================================================== /* GPL header */ #include - SERVICE_VERSION *foo_service= (void*)VERSION_foo; + SERVICE_VERSION foo_service= (void*)VERSION_foo; ================================================================== 7. add the new file to libservices/CMakeLists.txt (MYSQLSERVICES_SOURCES) diff --git a/libservices/debug_sync_service.c b/libservices/debug_sync_service.c index 8c7f109e95a..3afa088dee7 100644 --- a/libservices/debug_sync_service.c +++ b/libservices/debug_sync_service.c @@ -15,4 +15,4 @@ */ #include -SERVICE_VERSION *debug_sync_service= (void*)VERSION_debug_sync; +SERVICE_VERSION debug_sync_service= (void*)VERSION_debug_sync; diff --git a/libservices/progress_report_service.c b/libservices/progress_report_service.c index cd8db3eeacb..e55daf31e7d 100644 --- a/libservices/progress_report_service.c +++ b/libservices/progress_report_service.c @@ -14,4 +14,4 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -SERVICE_VERSION *progress_report_service= (void*)VERSION_progress_report; +SERVICE_VERSION progress_report_service= (void*)VERSION_progress_report; diff --git a/libservices/thd_alloc_service.c b/libservices/thd_alloc_service.c index 65e3fc490c8..54e498c6cd1 100644 --- a/libservices/thd_alloc_service.c +++ b/libservices/thd_alloc_service.c @@ -15,4 +15,4 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include -SERVICE_VERSION *thd_alloc_service= (void*)VERSION_thd_alloc; +SERVICE_VERSION thd_alloc_service= (void*)VERSION_thd_alloc; diff --git a/libservices/thd_wait_service.c b/libservices/thd_wait_service.c index 8cec4eecf77..1f8c19ac555 100644 --- a/libservices/thd_wait_service.c +++ b/libservices/thd_wait_service.c @@ -16,4 +16,4 @@ */ #include -SERVICE_VERSION *thd_wait_service= (void*)VERSION_thd_wait; +SERVICE_VERSION thd_wait_service= (void*)VERSION_thd_wait; From 48bb551328b004e91578d3d9e34f3837a3852f1e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:50:01 +0200 Subject: [PATCH 07/87] remove the service for installing the closed-source mysql thread pool plugin --- include/mysql/plugin_audit.h.pp | 8 --- include/mysql/plugin_auth.h.pp | 8 --- include/mysql/plugin_ftparser.h.pp | 8 --- include/mysql/service_thread_scheduler.h | 65 ----------------------- include/mysql/services.h | 4 +- include/service_versions.h | 4 +- libservices/CMakeLists.txt | 3 +- libservices/my_thread_scheduler_service.c | 20 ------- mysql-test/r/mysqld--help.result | 24 +++++++++ mysql-test/t/mysqld--help.test | 2 +- sql/scheduler.cc | 51 +----------------- sql/sql_plugin.cc | 4 +- sql/sql_plugin_services.h | 9 +--- 13 files changed, 35 insertions(+), 175 deletions(-) delete mode 100644 include/mysql/service_thread_scheduler.h delete mode 100644 libservices/my_thread_scheduler_service.c diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index fbd4ec2dd3f..2e74f8fd706 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -51,14 +51,6 @@ extern struct thd_wait_service_st { } *thd_wait_service; void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); -#include -struct scheduler_functions; -extern struct my_thread_scheduler_service { - int (*set)(struct scheduler_functions *scheduler); - int (*reset)(); -} *my_thread_scheduler_service; -int my_thread_scheduler_set(struct scheduler_functions *scheduler); -int my_thread_scheduler_reset(); #include extern struct progress_report_service_st { void (*thd_progress_init_func)(void* thd, unsigned int max_stage); diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 0f5dd26cfb3..6a877980c25 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -51,14 +51,6 @@ extern struct thd_wait_service_st { } *thd_wait_service; void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); -#include -struct scheduler_functions; -extern struct my_thread_scheduler_service { - int (*set)(struct scheduler_functions *scheduler); - int (*reset)(); -} *my_thread_scheduler_service; -int my_thread_scheduler_set(struct scheduler_functions *scheduler); -int my_thread_scheduler_reset(); #include extern struct progress_report_service_st { void (*thd_progress_init_func)(void* thd, unsigned int max_stage); diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 49cf7e5b931..ab15c9d176d 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -51,14 +51,6 @@ extern struct thd_wait_service_st { } *thd_wait_service; void thd_wait_begin(void* thd, int wait_type); void thd_wait_end(void* thd); -#include -struct scheduler_functions; -extern struct my_thread_scheduler_service { - int (*set)(struct scheduler_functions *scheduler); - int (*reset)(); -} *my_thread_scheduler_service; -int my_thread_scheduler_set(struct scheduler_functions *scheduler); -int my_thread_scheduler_reset(); #include extern struct progress_report_service_st { void (*thd_progress_init_func)(void* thd, unsigned int max_stage); diff --git a/include/mysql/service_thread_scheduler.h b/include/mysql/service_thread_scheduler.h deleted file mode 100644 index 5a5e0e2f520..00000000000 --- a/include/mysql/service_thread_scheduler.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SERVICE_THREAD_SCHEDULER_INCLUDED -#define SERVICE_THREAD_SCHEDULER_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -struct scheduler_functions; - -extern struct my_thread_scheduler_service { - int (*set)(struct scheduler_functions *scheduler); - int (*reset)(); -} *my_thread_scheduler_service; - -#ifdef MYSQL_DYNAMIC_PLUGIN - -#define my_thread_scheduler_set(F) my_thread_scheduler_service->set((F)) -#define my_thread_scheduler_reset() my_thread_scheduler_service->reset() - -#else - -/** - Set the thread scheduler to use for the server. - - @param scheduler Pointer to scheduler callbacks to use. - @retval 0 Scheduler installed correctly. - @retval 1 Invalid value (NULL) used for scheduler. -*/ -int my_thread_scheduler_set(struct scheduler_functions *scheduler); - -/** - Restore the previous thread scheduler. - - @note If no thread scheduler was installed previously with - thd_set_thread_scheduler, this function will report an error. - - @retval 0 Scheduler installed correctly. - @retval 1 No scheduler installed. -*/ -int my_thread_scheduler_reset(); - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* SERVICE_THREAD_SCHEDULER_INCLUDED */ diff --git a/include/mysql/services.h b/include/mysql/services.h index b5b331d4923..e14523f4fa1 100644 --- a/include/mysql/services.h +++ b/include/mysql/services.h @@ -1,5 +1,6 @@ #ifndef MYSQL_SERVICES_INCLUDED -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. + Copyright (c) 2012, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +22,6 @@ extern "C" { #include #include #include -#include #include #include #include diff --git a/include/service_versions.h b/include/service_versions.h index 9b41da7440e..e0a717fea9e 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. + Copyright (c) 2012, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,7 +23,6 @@ #define VERSION_my_snprintf 0x0100 #define VERSION_thd_alloc 0x0100 #define VERSION_thd_wait 0x0100 -#define VERSION_my_thread_scheduler 0x0100 #define VERSION_progress_report 0x0100 #define VERSION_debug_sync 0x1000 #define VERSION_kill_statement 0x1000 diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt index 1583d1ff792..86ed3493993 100644 --- a/libservices/CMakeLists.txt +++ b/libservices/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2006 MySQL AB, 2010 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006 MySQL AB, 2010 Oracle and/or its affiliates. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,7 +19,6 @@ SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c thd_wait_service.c - my_thread_scheduler_service.c progress_report_service.c debug_sync_service.c kill_statement_service.c) diff --git a/libservices/my_thread_scheduler_service.c b/libservices/my_thread_scheduler_service.c deleted file mode 100644 index 0bbad39dd0a..00000000000 --- a/libservices/my_thread_scheduler_service.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -SERVICE_VERSION my_thread_scheduler_service= - (void*)VERSION_my_thread_scheduler; diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index d29631eabc0..e5edb963ca9 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -817,6 +817,25 @@ The following options may be given as the first argument: values are COMMIT or ROLLBACK. --thread-cache-size=# How many threads we should keep in a cache for reuse + --thread-pool-idle-timeout=# + Timeout in seconds for an idle thread in the thread + pool.Worker thread will be shut down after timeout + --thread-pool-max-threads=# + Maximum allowed number of worker threads in the thread + pool + --thread-pool-oversubscribe=# + How many additional active worker threads in a group are + allowed. + --thread-pool-size=# + Number of thread groups in the pool. This parameter is + roughly equivalent to maximum number of concurrently + executing threads (threads in a waiting state do not + count as executing). + --thread-pool-stall-limit=# + Maximum query execution time in milliseconds,before an + executing non-yielding thread is considered stalled.If a + worker thread is stalled, additional worker thread may be + created to handle remaining clients. --thread-stack=# The stack size for each thread --time-format=name The TIME format (ignored) --timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are @@ -1090,6 +1109,11 @@ table-definition-cache 400 table-open-cache 400 tc-heuristic-recover COMMIT thread-cache-size 0 +thread-pool-idle-timeout 60 +thread-pool-max-threads 500 +thread-pool-oversubscribe 3 +thread-pool-size 4 +thread-pool-stall-limit 500 thread-stack 294912 time-format %H:%i:%s timed-mutexes FALSE diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index 4b5572c2bbe..84d1fe85ec8 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -27,7 +27,7 @@ perl; feedback debug temp-pool ssl des-key-file xtradb thread-concurrency super-large-pages mutex-deadlock-detector null-audit maria aria pbxt oqgraph - sphinx thread-handling thread-pool query-cache-info/; + sphinx thread-handling query-cache-info/; # And substitute the content some environment variables with their # names: diff --git a/sql/scheduler.cc b/sql/scheduler.cc index 54653557b16..e690f06af2e 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. - Copyright (c) 2012, Monty Program Ab + Copyright (c) 2012, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -139,52 +139,3 @@ void one_thread_scheduler(scheduler_functions *func) func->end_thread= no_threads_end; } - - -/* - no pluggable schedulers in mariadb. - when we'll want it, we'll do it properly -*/ -#if 0 - -static scheduler_functions *saved_thread_scheduler; -static uint saved_thread_handling; - -extern "C" -int my_thread_scheduler_set(scheduler_functions *scheduler) -{ - DBUG_ASSERT(scheduler != 0); - - if (scheduler == NULL) - return 1; - - saved_thread_scheduler= thread_scheduler; - saved_thread_handling= thread_handling; - thread_scheduler= scheduler; - // Scheduler loaded dynamically - thread_handling= SCHEDULER_TYPES_COUNT; - return 0; -} - - -extern "C" -int my_thread_scheduler_reset() -{ - DBUG_ASSERT(saved_thread_scheduler != NULL); - - if (saved_thread_scheduler == NULL) - return 1; - - thread_scheduler= saved_thread_scheduler; - thread_handling= saved_thread_handling; - saved_thread_scheduler= 0; - return 0; -} -#else -extern "C" int my_thread_scheduler_set(scheduler_functions *scheduler) -{ return 1; } - -extern "C" int my_thread_scheduler_reset() -{ return 1; } -#endif - diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 059fc197d22..78e5b5b3833 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1516,8 +1516,8 @@ int plugin_init(int *argc, char **argv, int flags) } /* prepare debug_sync service */ - DBUG_ASSERT(strcmp(list_of_services[5].name, "debug_sync_service") == 0); - list_of_services[5].service= *(void**)&debug_sync_C_callback_ptr; + DBUG_ASSERT(strcmp(list_of_services[4].name, "debug_sync_service") == 0); + list_of_services[4].service= *(void**)&debug_sync_C_callback_ptr; mysql_mutex_lock(&LOCK_plugin); diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h index e3ef338eaad..d2f60a6e08c 100644 --- a/sql/sql_plugin_services.h +++ b/sql/sql_plugin_services.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. + Copyright (c) 2012, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,11 +42,6 @@ static struct thd_wait_service_st thd_wait_handler= { thd_wait_end }; -static struct my_thread_scheduler_service my_thread_scheduler_handler= { - my_thread_scheduler_set, - my_thread_scheduler_reset, -}; - static struct progress_report_service_st progress_report_handler= { thd_progress_init, thd_progress_report, @@ -63,7 +59,6 @@ static struct st_service_ref list_of_services[]= { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler }, { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }, { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler }, - { "my_thread_scheduler_service", VERSION_my_thread_scheduler, &my_thread_scheduler_handler }, { "progress_report_service", VERSION_progress_report, &progress_report_handler }, { "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init() { "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler } From e7036ec1a287b2b2bac0cbf309ae0baf73320fb0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:51:16 +0200 Subject: [PATCH 08/87] mtr bug: files outside of both the suite dir and the overlay dir, were treated as coming from the overlay. (example: archive suite, test_sql_discovery overlay, mysql-test/include/have_archive.inc) --- mysql-test/lib/mtr_cases.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 32ec24da492..a82e3ee10b7 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -968,6 +968,8 @@ sub get_tags_from_file($$) { } elsif ($over and $file =~ m@^$pdir/(.*)$@) { $suffix = $1; @prefix = map { "$_/" } $sdir, $pdir; + } else { + $over = 0; # file neither in $sdir nor in $pdir } while (my $line= <$F>) From fdcaa6cb3201ef432574946976cbc981bcffac61 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 14:54:43 +0200 Subject: [PATCH 09/87] clarify CREATE grammar --- sql/sql_yacc.yy | 64 ++++++++++++++++--------------------------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f4e03ac3d14..68319da9cf2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1461,7 +1461,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type table_ident table_ident_nodb references xid - table_ident_opt_wild + table_ident_opt_wild create_like %type remember_name remember_end opt_db text_or_password @@ -2115,7 +2115,7 @@ create: lex->name.length= 0; lex->create_last_non_select_table= lex->last_table(); } - create2 + create_body { LEX *lex= YYTHD->lex; lex->current_select= &lex->select_lex; @@ -4290,36 +4290,23 @@ size_number: End tablespace part */ -create2: - '(' create2a {} - | opt_create_table_options - opt_create_partitioning - create3 {} - | LIKE table_ident +create_body: + '(' create_field_list ')' + { Lex->create_info.option_list= NULL; } + opt_create_table_options opt_create_partitioning opt_create_select {} + | opt_create_table_options opt_create_partitioning opt_create_select {} + /* + the following rule is redundant, but there's a shift/reduce + conflict that prevents the rule above from parsing a syntax like + CREATE TABLE t1 (SELECT 1); + */ + | '(' create_select ')' { Select->set_braces(1);} union_opt {} + | create_like { - THD *thd= YYTHD; - TABLE_LIST *src_table; - LEX *lex= thd->lex; - lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; - src_table= lex->select_lex.add_table_to_list(thd, $2, NULL, 0, - TL_READ, - MDL_SHARED_READ); - if (! src_table) - MYSQL_YYABORT; - /* CREATE TABLE ... LIKE is not allowed for views. */ - src_table->required_type= FRMTYPE_TABLE; - } - | '(' LIKE table_ident ')' - { - THD *thd= YYTHD; - TABLE_LIST *src_table; - LEX *lex= thd->lex; - - lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; - src_table= lex->select_lex.add_table_to_list(thd, $3, NULL, 0, - TL_READ, - MDL_SHARED_READ); + Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; + TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(YYTHD, + $1, NULL, 0, TL_READ, MDL_SHARED_READ); if (! src_table) MYSQL_YYABORT; /* CREATE TABLE ... LIKE is not allowed for views. */ @@ -4327,21 +4314,12 @@ create2: } ; -create2a: - create_field_list ')' - { - Lex->create_info.option_list= NULL; - } - opt_create_table_options - opt_create_partitioning - create3 {} - | opt_create_partitioning - create_select ')' - { Select->set_braces(1);} - union_opt {} +create_like: + LIKE table_ident { $$= $2; } + | '(' LIKE table_ident ')' { $$= $3; } ; -create3: +opt_create_select: /* empty */ {} | opt_duplicate opt_as create_select { Select->set_braces(0);} From bbbd7cedf522e7ea9883b881370fceb91ed3d746 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:19:45 +0200 Subject: [PATCH 10/87] my_dir() cleanup * replace pointer acrobatics with a struct * make sorting explicit: MY_DONT_SORT -> MY_WANT_SORT (if you want something to be done - say it. fixes all places where my_dir() was used without thinking) * typo s/number_off_files/number_of_files/ * directory_file_name() doesn't need to be extern * remove #ifdef __BORLANDC__ * ignore '.' and '..' entries --- client/mysqltest.cc | 12 +- include/my_dir.h | 5 +- include/my_sys.h | 1 - mysys/default.c | 2 +- mysys/my_lib.c | 248 +++++++----------- sql/log.cc | 2 +- sql/log_event.cc | 2 +- sql/sql_base.cc | 7 +- sql/sql_db.cc | 32 +-- sql/sql_show.cc | 16 +- sql/tztime.cc | 2 +- storage/maria/ma_init.c | 2 +- storage/maria/ma_loghandler.c | 2 +- storage/maria/unittest/ma_maria_log_cleanup.c | 2 +- 14 files changed, 125 insertions(+), 210 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 2cca53f4e74..222ecbdba6c 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -3633,7 +3633,6 @@ void do_remove_files_wildcard(struct st_command *command) fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME); DBUG_PRINT("info", ("listing directory: %s", dirname)); - /* Note that my_dir sorts the list if not given any flags */ if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT | MY_WME)))) { error= 1; @@ -3648,7 +3647,7 @@ void do_remove_files_wildcard(struct st_command *command) /* Set default wild chars for wild_compare, is changed in embedded mode */ set_wild_chars(1); - for (i= 0; i < (uint) dir_info->number_off_files; i++) + for (i= 0; i < (uint) dir_info->number_of_files; i++) { file= dir_info->dir_entry + i; /* Remove only regular files, i.e. no directories etc. */ @@ -3911,17 +3910,12 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname, DBUG_ENTER("get_list_files"); DBUG_PRINT("info", ("listing directory: %s", ds_dirname->str)); - /* Note that my_dir sorts the list if not given any flags */ - if (!(dir_info= my_dir(ds_dirname->str, MYF(0)))) + if (!(dir_info= my_dir(ds_dirname->str, MYF(MY_WANT_SORT)))) DBUG_RETURN(1); set_wild_chars(1); - for (i= 0; i < (uint) dir_info->number_off_files; i++) + for (i= 0; i < (uint) dir_info->number_of_files; i++) { file= dir_info->dir_entry + i; - if (file->name[0] == '.' && - (file->name[1] == '\0' || - (file->name[1] == '.' && file->name[2] == '\0'))) - continue; /* . or .. */ if (ds_wild && ds_wild->length && wild_compare(file->name, ds_wild->str, 0)) continue; diff --git a/include/my_dir.h b/include/my_dir.h index 6a941b37d79..be988ae790c 100644 --- a/include/my_dir.h +++ b/include/my_dir.h @@ -46,8 +46,9 @@ extern "C" { #define MY_S_ISFIFO(m) (((m) & MY_S_IFMT) == MY_S_IFIFO) /* Ensure these dosn't clash with anything in my_sys.h */ -#define MY_DONT_SORT 8192 /* my_lib; Don't sort files */ +#define MY_WANT_SORT 8192 /* my_lib; sort files */ #define MY_WANT_STAT 16384 /* my_lib; stat files */ +#define MY_DONT_SORT 0 /* typedefs for my_dir & my_stat */ @@ -94,7 +95,7 @@ typedef struct st_my_dir /* Struct returned from my_dir */ we don't want to change code that uses my_dir. */ struct fileinfo *dir_entry; - uint number_off_files; + uint number_of_files; } MY_DIR; extern MY_DIR *my_dir(const char *path,myf MyFlags); diff --git a/include/my_sys.h b/include/my_sys.h index 13e4d463515..40061a33636 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -708,7 +708,6 @@ extern size_t cleanup_dirname(char * to,const char *from); extern size_t system_filename(char * to,const char *from); extern size_t unpack_filename(char * to,const char *from); extern char * intern_filename(char * to,const char *from); -extern char * directory_file_name(char * dst, const char *src); extern int pack_filename(char * to, const char *name, size_t max_length); extern char * my_path(char * to,const char *progname, const char *own_pathname_part); diff --git a/mysys/default.c b/mysys/default.c index a90f428eca5..9e23eb6b261 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -846,7 +846,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler, if (!(search_dir= my_dir(ptr, MYF(MY_WME)))) goto err; - for (i= 0; i < (uint) search_dir->number_off_files; i++) + for (i= 0; i < (uint) search_dir->number_of_files; i++) { search_file= search_dir->dir_entry + i; ext= fn_ext(search_file->name); diff --git a/mysys/my_lib.c b/mysys/my_lib.c index f11ea97d328..e8a81b19e22 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -22,10 +22,8 @@ #include "mysys_err.h" #if defined(HAVE_DIRENT_H) # include -# define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen # if defined(HAVE_SYS_NDIR_H) # include # endif @@ -60,25 +58,29 @@ static int comp_names(struct fileinfo *a,struct fileinfo *b); +typedef struct { + MY_DIR dir; + DYNAMIC_ARRAY array; + MEM_ROOT root; +} MY_DIR_HANDLE; - /* We need this because program don't know with malloc we used */ +/* We need this because the caller doesn't know which malloc we've used */ -void my_dirend(MY_DIR *buffer) +void my_dirend(MY_DIR *dir) { + MY_DIR_HANDLE *dirh= (MY_DIR_HANDLE*) dir; DBUG_ENTER("my_dirend"); - if (buffer) + if (dirh) { - delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer + - ALIGN_SIZE(sizeof(MY_DIR)))); - free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) + - ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0)); - my_free(buffer); + delete_dynamic(&dirh->array); + free_root(&dirh->root, MYF(0)); + my_free(dirh); } DBUG_VOID_RETURN; } /* my_dirend */ - /* Compare in sort of filenames */ + /* Compare in sort of filenames */ static int comp_names(struct fileinfo *a, struct fileinfo *b) { @@ -88,13 +90,27 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b) #if !defined(_WIN32) +static char *directory_file_name (char * dst, const char *src) +{ + /* Process as Unix format: just remove test the final slash. */ + char *end; + DBUG_ASSERT(strlen(src) < (FN_REFLEN + 1)); + + if (src[0] == 0) + src= (char*) "."; /* Use empty as current */ + end=strmov(dst, src); + if (end[-1] != FN_LIBCHAR + 1) + { + *end++= FN_LIBCHAR; /* Add last '/' */ + *end='\0'; + } + return end; +} + MY_DIR *my_dir(const char *path, myf MyFlags) { - char *buffer; - MY_DIR *result= 0; + MY_DIR_HANDLE *dirh= 0; FILEINFO finfo; - DYNAMIC_ARRAY *dir_entries_storage; - MEM_ROOT *names_storage; DIR *dirp; struct dirent *dp; char tmp_path[FN_REFLEN + 2], *tmp_file; @@ -107,59 +123,53 @@ MY_DIR *my_dir(const char *path, myf MyFlags) mysql_mutex_lock(&THR_LOCK_open); #endif - dirp = opendir(directory_file_name(tmp_path,(char *) path)); -#if defined(__amiga__) - if ((dirp->dd_fd) < 0) /* Directory doesn't exists */ - goto error; -#endif - if (dirp == NULL || - ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + - ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + - sizeof(MEM_ROOT), MyFlags))) + tmp_file= directory_file_name(tmp_path, path); + + if (!(dirp= opendir(tmp_path))) goto error; - dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); - names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + - ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); + if (!(dirh= my_malloc(sizeof(*dirh), MyFlags | MY_ZEROFILL))) + goto error; - if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + if (my_init_dynamic_array(&dirh->array, sizeof(FILEINFO), ENTRIES_START_SIZE, ENTRIES_INCREMENT, MYF(MyFlags))) - { - my_free(buffer); goto error; - } - init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE, - MYF(MyFlags)); - /* MY_DIR structure is allocated and completly initialized at this point */ - result= (MY_DIR*)buffer; - - tmp_file=strend(tmp_path); + init_alloc_root(&dirh->root, NAMES_START_SIZE, NAMES_START_SIZE, + MYF(MyFlags)); dp= (struct dirent*) dirent_tmp; while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp))) { - if (!(finfo.name= strdup_root(names_storage, dp->d_name))) - goto error; + MY_STAT statbuf, *mystat= 0; + if (dp->d_name[0] == '.' && + (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + continue; /* . or .. */ + if (MyFlags & MY_WANT_STAT) { - if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, - sizeof(MY_STAT)))) - goto error; - - bzero(finfo.mystat, sizeof(MY_STAT)); - (void) strmov(tmp_file,dp->d_name); - (void) my_stat(tmp_path, finfo.mystat, MyFlags); - if (!(finfo.mystat->st_mode & MY_S_IREAD)) + mystat= &statbuf; + bzero(mystat, sizeof(*mystat)); + (void) strmov(tmp_file, dp->d_name); + (void) my_stat(tmp_path, mystat, MyFlags); + if (!(mystat->st_mode & MY_S_IREAD)) continue; } - else - finfo.mystat= NULL; - if (push_dynamic(dir_entries_storage, (uchar*)&finfo)) + if (!(finfo.name= strdup_root(&dirh->root, dp->d_name))) + goto error; + + if (mystat && + !((mystat= memdup_root(&dirh->root, mystat, sizeof(*mystat))))) + goto error; + + finfo.mystat= mystat; + + if (push_dynamic(&dirh->array, (uchar*)&finfo)) goto error; } @@ -167,13 +177,14 @@ MY_DIR *my_dir(const char *path, myf MyFlags) #if !defined(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif - result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; - result->number_off_files= dir_entries_storage->elements; - if (!(MyFlags & MY_DONT_SORT)) - my_qsort((void *) result->dir_entry, result->number_off_files, - sizeof(FILEINFO), (qsort_cmp) comp_names); - DBUG_RETURN(result); + if (MyFlags & MY_WANT_SORT) + sort_dynamic(&dirh->array, (qsort_cmp) comp_names); + + dirh->dir.dir_entry= dynamic_element(&dirh->array, 0, FILEINFO *); + dirh->dir.number_of_files= dirh->array.elements; + + DBUG_RETURN(&dirh->dir); error: #if !defined(HAVE_READDIR_R) @@ -182,37 +193,13 @@ MY_DIR *my_dir(const char *path, myf MyFlags) my_errno=errno; if (dirp) (void) closedir(dirp); - my_dirend(result); + my_dirend(&dirh->dir); if (MyFlags & (MY_FAE | MY_WME)) - my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno); - DBUG_RETURN((MY_DIR *) NULL); + my_error(EE_DIR, MYF(ME_BELL | ME_WAITTANG), path, my_errno); + DBUG_RETURN(NULL); } /* my_dir */ -/* - * Convert from directory name to filename. - * On UNIX, it's simple: just make sure there is a terminating / - - * Returns pointer to dst; - */ - -char * directory_file_name (char * dst, const char *src) -{ - /* Process as Unix format: just remove test the final slash. */ - char *end; - DBUG_ASSERT(strlen(src) < (FN_REFLEN + 1)); - - if (src[0] == 0) - src= (char*) "."; /* Use empty as current */ - end= strnmov(dst, src, FN_REFLEN + 1); - if (end[-1] != FN_LIBCHAR) - { - end[0]=FN_LIBCHAR; /* Add last '/' */ - end[1]='\0'; - } - return dst; -} - #else /* @@ -223,18 +210,11 @@ char * directory_file_name (char * dst, const char *src) MY_DIR *my_dir(const char *path, myf MyFlags) { - char *buffer; - MY_DIR *result= 0; + MY_DIR_HANDLE *dirh= 0; FILEINFO finfo; - DYNAMIC_ARRAY *dir_entries_storage; - MEM_ROOT *names_storage; -#ifdef __BORLANDC__ - struct ffblk find; -#else struct _finddata_t find; -#endif ushort mode; - char tmp_path[FN_REFLEN],*tmp_file,attrib; + char tmp_path[FN_REFLEN], *tmp_file,attrib; #ifdef _WIN64 __int64 handle; #else @@ -257,32 +237,18 @@ MY_DIR *my_dir(const char *path, myf MyFlags) tmp_file[2]='*'; tmp_file[3]='\0'; - if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + - ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + - sizeof(MEM_ROOT), MyFlags))) + if (!(dirh= my_malloc(sizeof(*dirh), MyFlags | MY_ZEROFILL))) goto error; - - dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); - names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + - ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); - if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + if (my_init_dynamic_array(&dirh->array, sizeof(FILEINFO), ENTRIES_START_SIZE, ENTRIES_INCREMENT, MYF(MyFlags))) - { - my_free(buffer); goto error; - } - init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE, MYF(MyFlags)); - - /* MY_DIR structure is allocated and completly initialized at this point */ - result= (MY_DIR*)buffer; -#ifdef __BORLANDC__ - if ((handle= findfirst(tmp_path,&find,0)) == -1L) -#else + init_alloc_root(&dirh->root, NAMES_START_SIZE, NAMES_START_SIZE, + MYF(MyFlags)); + if ((handle=_findfirst(tmp_path,&find)) == -1L) -#endif { DBUG_PRINT("info", ("findfirst returned error, errno: %d", errno)); if (errno != EINVAL) @@ -295,12 +261,8 @@ MY_DIR *my_dir(const char *path, myf MyFlags) } else { - do { -#ifdef __BORLANDC__ - attrib= find.ff_attrib; -#else attrib= find.attrib; /* Do not show hidden and system files which Windows sometimes create. @@ -309,71 +271,55 @@ MY_DIR *my_dir(const char *path, myf MyFlags) */ if (attrib & (_A_HIDDEN | _A_SYSTEM)) continue; -#endif -#ifdef __BORLANDC__ - if (!(finfo.name= strdup_root(names_storage, find.ff_name))) + + if (find.name[0] == '.' && + (find.name[1] == '\0' || + (find.name[1] == '.' && find.name[2] == '\0'))) + continue; /* . or .. */ + + if (!(finfo.name= strdup_root(&dirh->root, find.name))) goto error; -#else - if (!(finfo.name= strdup_root(names_storage, find.name))) - goto error; -#endif if (MyFlags & MY_WANT_STAT) { - if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, - sizeof(MY_STAT)))) + if (!(finfo.mystat= (MY_STAT*)alloc_root(&dirh->root, sizeof(MY_STAT)))) goto error; bzero(finfo.mystat, sizeof(MY_STAT)); -#ifdef __BORLANDC__ - finfo.mystat->st_size=find.ff_fsize; -#else finfo.mystat->st_size=find.size; -#endif mode= MY_S_IREAD; if (!(attrib & _A_RDONLY)) mode|= MY_S_IWRITE; if (attrib & _A_SUBDIR) mode|= MY_S_IFDIR; finfo.mystat->st_mode= mode; -#ifdef __BORLANDC__ - finfo.mystat->st_mtime= ((uint32) find.ff_ftime); -#else finfo.mystat->st_mtime= ((uint32) find.time_write); -#endif } else finfo.mystat= NULL; - if (push_dynamic(dir_entries_storage, (uchar*)&finfo)) + if (push_dynamic(&dirh->array, (uchar*)&finfo)) goto error; } -#ifdef __BORLANDC__ - while (findnext(&find) == 0); -#else while (_findnext(handle,&find) == 0); - _findclose(handle); -#endif } - result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; - result->number_off_files= dir_entries_storage->elements; + if (MyFlags & MY_WANT_SORT) + sort_dynamic(&dirh->array, (qsort_cmp) comp_names); - if (!(MyFlags & MY_DONT_SORT)) - my_qsort((void *) result->dir_entry, result->number_off_files, - sizeof(FILEINFO), (qsort_cmp) comp_names); - DBUG_PRINT("exit", ("found %d files", result->number_off_files)); - DBUG_RETURN(result); + dirh->dir.dir_entry= dynamic_element(&dirh->array, 0, FILEINFO *); + dirh->dir.number_of_files= dirh->array.elements; + + DBUG_PRINT("exit", ("found %d files", dirh->dir.number_of_files)); + DBUG_RETURN(&dirh->dir); error: my_errno=errno; -#ifndef __BORLANDC__ if (handle != -1) _findclose(handle); -#endif - my_dirend(result); - if (MyFlags & MY_FAE+MY_WME) - my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno); - DBUG_RETURN((MY_DIR *) NULL); + my_dirend(&dirh->dir); + if (MyFlags & (MY_FAE | MY_WME)) + my_error(EE_DIR,MYF(ME_BELL | ME_WAITTANG), path, errno); + DBUG_RETURN(NULL); } /* my_dir */ #endif /* _WIN32 */ diff --git a/sql/log.cc b/sql/log.cc index 0c273453751..5ddfab6f805 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2277,7 +2277,7 @@ static int find_uniq_filename(char *name) DBUG_RETURN(1); } file_info= dir_info->dir_entry; - for (i= dir_info->number_off_files ; i-- ; file_info++) + for (i= dir_info->number_of_files ; i-- ; file_info++) { if (memcmp(file_info->name, start, length) == 0 && test_if_number(file_info->name+length, &number,0)) diff --git a/sql/log_event.cc b/sql/log_event.cc index 55b95996515..19bc79babb1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -577,7 +577,7 @@ static void cleanup_load_tmpdir() *(p++)= '-'; *p= 0; - for (i=0 ; i < (uint)dirp->number_off_files; i++) + for (i=0 ; i < (uint)dirp->number_of_files; i++) { file=dirp->dir_entry+i; if (is_prefix(file->name, prefbuf)) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d32f39cae2f..0d31ba06e12 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9230,15 +9230,10 @@ my_bool mysql_rm_tmp_tables(void) /* Remove all SQLxxx tables from directory */ - for (idx=0 ; idx < (uint) dirp->number_off_files ; idx++) + for (idx=0 ; idx < (uint) dirp->number_of_files ; idx++) { file=dirp->dir_entry+idx; - /* skiping . and .. */ - if (file->name[0] == '.' && (!file->name[1] || - (file->name[1] == '.' && !file->name[2]))) - continue; - if (!memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length)) { diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 87650e643f2..b287aad49ef 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -52,11 +52,9 @@ const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; -static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, - const char *db, - const char *path, - TABLE_LIST **tables, - bool *found_other_files); +static bool find_db_tables_and_rm_known_files(THD *, MY_DIR *, const char *, + const char *, TABLE_LIST **, + bool *); long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path); static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error); @@ -1010,18 +1008,13 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, tot_list_next_local= tot_list_next_global= &tot_list; for (uint idx=0 ; - idx < (uint) dirp->number_off_files && !thd->killed ; + idx < (uint) dirp->number_of_files && !thd->killed ; idx++) { FILEINFO *file=dirp->dir_entry+idx; char *extension; DBUG_PRINT("info",("Examining: %s", file->name)); - /* skiping . and .. */ - if (file->name[0] == '.' && (!file->name[1] || - (file->name[1] == '.' && !file->name[2]))) - continue; - if (file->name[0] == 'a' && file->name[1] == 'r' && file->name[2] == 'c' && file->name[3] == '\0') { @@ -1189,18 +1182,13 @@ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) DBUG_PRINT("enter", ("path: %s", org_path)); for (uint idx=0 ; - idx < (uint) dirp->number_off_files && !thd->killed ; + idx < (uint) dirp->number_of_files && !thd->killed ; idx++) { FILEINFO *file=dirp->dir_entry+idx; char *extension, *revision; DBUG_PRINT("info",("Examining: %s", file->name)); - /* skiping . and .. */ - if (file->name[0] == '.' && (!file->name[1] || - (file->name[1] == '.' && !file->name[2]))) - continue; - extension= fn_ext(file->name); if (extension[0] != '.' || extension[1] != 'f' || extension[2] != 'r' || @@ -1687,7 +1675,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) /* Step2: Move tables to the new database */ if ((dirp = my_dir(path,MYF(MY_DONT_SORT)))) { - uint nfiles= (uint) dirp->number_off_files; + uint nfiles= (uint) dirp->number_of_files; for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++) { FILEINFO *file= dirp->dir_entry + idx; @@ -1778,17 +1766,15 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) if ((dirp = my_dir(path,MYF(MY_DONT_SORT)))) { - uint nfiles= (uint) dirp->number_off_files; + uint nfiles= (uint) dirp->number_of_files; for (uint idx=0 ; idx < nfiles ; idx++) { FILEINFO *file= dirp->dir_entry + idx; char oldname[FN_REFLEN + 1], newname[FN_REFLEN + 1]; DBUG_PRINT("info",("Examining: %s", file->name)); - /* skiping . and .. and MY_DB_OPT_FILE */ - if ((file->name[0] == '.' && - (!file->name[1] || (file->name[1] == '.' && !file->name[2]))) || - !my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE)) + /* skiping MY_DB_OPT_FILE */ + if (!my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE)) continue; /* pass empty file name, and file->name as extension to avoid encoding */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fdfdea52a75..a9c40a44997 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -60,8 +60,6 @@ #include "datadict.h" // dd_frm_type() #include "keycaches.h" -#define STR_OR_NIL(S) ((S) ? (S) : "") - #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" #endif @@ -737,7 +735,7 @@ find_files(THD *thd, List *files, const char *db, bzero((char*) &table_list,sizeof(table_list)); - if (!(dirp = my_dir(path,MYF((dir ? MY_WANT_STAT : 0) | + if (!(dirp = my_dir(path, MYF((dir ? MY_WANT_STAT : 0) | MY_WANT_SORT | MY_THREAD_SPECIFIC)))) { if (my_errno == ENOENT) @@ -747,16 +745,12 @@ find_files(THD *thd, List *files, const char *db, DBUG_RETURN(FIND_FILES_DIR); } - for (i=0 ; i < (uint) dirp->number_off_files ; i++) + for (i=0 ; i < (uint) dirp->number_of_files ; i++) { char uname[SAFE_NAME_LEN + 1]; /* Unencoded name */ file=dirp->dir_entry+i; if (dir) { /* Return databases */ - if ((file->name[0] == '.' && - ((file->name[1] == '.' && file->name[2] == '\0') || - file->name[1] == '\0'))) - continue; /* . or .. */ #ifdef USE_SYMDIR char *ext; char buff[FN_REFLEN]; @@ -4626,9 +4620,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } - DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'", - STR_OR_NIL(lookup_field_vals.db_value.str), - STR_OR_NIL(lookup_field_vals.table_value.str))); + DBUG_PRINT("info",("db_name='%s', table_name='%s'", + lookup_field_vals.db_value.str, + lookup_field_vals.table_value.str)); if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value) { diff --git a/sql/tztime.cc b/sql/tztime.cc index 000e3ac0518..5e1e8bec7b3 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2505,7 +2505,7 @@ scan_tz_dir(char * name_end) name_end= strmake(name_end, "/", FN_REFLEN - (name_end - fullname)); - for (i= 0; i < cur_dir->number_off_files; i++) + for (i= 0; i < cur_dir->number_of_files; i++) { if (cur_dir->dir_entry[i].name[0] != '.') { diff --git a/storage/maria/ma_init.c b/storage/maria/ma_init.c index 78ca7ed9bf8..962405552f0 100644 --- a/storage/maria/ma_init.c +++ b/storage/maria/ma_init.c @@ -148,7 +148,7 @@ my_bool maria_upgrade() "Converting them to Aria names", MYF(ME_JUST_INFO)); - for (i= 0; i < dir->number_off_files; i++) + for (i= 0; i < dir->number_of_files; i++) { const char *file= dir->dir_entry[i].name; if (strncmp(file, "maria_log.", 10) == 0 && diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 70d26b5ca49..5233e57594c 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -3479,7 +3479,7 @@ my_bool translog_walk_filenames(const char *directory, if (!(dirp = my_dir(directory, MYF(MY_DONT_SORT)))) return FALSE; - for (i= 0; i < dirp->number_off_files; i++) + for (i= 0; i < dirp->number_of_files; i++) { char *file= dirp->dir_entry[i].name; if (strncmp(file, "aria_log.", 10) == 0 && diff --git a/storage/maria/unittest/ma_maria_log_cleanup.c b/storage/maria/unittest/ma_maria_log_cleanup.c index 60e4fdb02fd..3e4bc755832 100644 --- a/storage/maria/unittest/ma_maria_log_cleanup.c +++ b/storage/maria/unittest/ma_maria_log_cleanup.c @@ -38,7 +38,7 @@ my_bool maria_log_remove(const char *testdir) if (!(dirp = my_dir(maria_data_root, MYF(MY_DONT_SORT)))) return 1; - for (i= 0; i < dirp->number_off_files; i++) + for (i= 0; i < dirp->number_of_files; i++) { char *file= dirp->dir_entry[i].name; if (strncmp(file, "aria_log.", 9) == 0 && From 0614af18a6589d94b483a779ad34de93086f96f8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:20:58 +0200 Subject: [PATCH 11/87] macro do {} while(0) safety --- include/my_global.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/my_global.h b/include/my_global.h index 1aa806fb14d..c82ac911fc2 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -476,7 +476,7 @@ typedef unsigned int uint; typedef unsigned short ushort; #endif -#define swap_variables(t, a, b) { t dummy; dummy= a; a= b; b= dummy; } +#define swap_variables(t, a, b) do { t dummy; dummy= a; a= b; b= dummy; } while(0) #define test(a) ((a) ? 1 : 0) #define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0) #define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0) From 8b4d967798299399d4b81b1cd949080edbafdc5b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:26:58 +0200 Subject: [PATCH 12/87] bugfix: MYSQL_THDVAR_STR plugins with PLUGIN_VAR_MEMALLOC didn't work (PLUGIN_VAR_MEMALLOC ix 0x8000 and cannot be saved in a char as such) --- sql/sql_plugin.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 78e5b5b3833..4b631636db6 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2354,8 +2354,14 @@ err: #undef MYSQL_SYSVAR_NAME #define MYSQL_SYSVAR_NAME(name) name -#define PLUGIN_VAR_TYPEMASK 0x007f -#define PLUGIN_VAR_BOOKMARK_KEY (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_MEMALLOC) +#define PLUGIN_VAR_TYPEMASK 0x7f +#define BOOKMARK_MEMALLOC 0x80 + +static inline char plugin_var_bookmark_key(uint flags) +{ + return (flags & PLUGIN_VAR_TYPEMASK) | + (flags & PLUGIN_VAR_MEMALLOC ? BOOKMARK_MEMALLOC : 0); +} #define EXTRA_OPTIONS 3 /* options for: 'foo', 'plugin-foo' and NULL */ @@ -2709,7 +2715,7 @@ static st_bookmark *find_bookmark(const char *plugin, const char *name, else memcpy(varname + 1, name, namelen + 1); - varname[0]= flags & PLUGIN_VAR_BOOKMARK_KEY; + varname[0]= plugin_var_bookmark_key(flags); result= (st_bookmark*) my_hash_search(&bookmark_hash, (const uchar*) varname, length - 1); @@ -2767,7 +2773,7 @@ static st_bookmark *register_var(const char *plugin, const char *name, { result= (st_bookmark*) alloc_root(&plugin_mem_root, sizeof(struct st_bookmark) + length-1); - varname[0]= flags & PLUGIN_VAR_BOOKMARK_KEY; + varname[0]= plugin_var_bookmark_key(flags); memcpy(result->key, varname, length); result->name_len= length - 2; result->offset= -1; @@ -2889,7 +2895,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock) if (!(var= intern_find_sys_var(v->key + 1, v->name_len)) || !(pi= var->cast_pluginvar()) || - v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_BOOKMARK_KEY)) + v->key[0] != plugin_var_bookmark_key(pi->plugin_var->flags)) continue; /* Here we do anything special that may be required of the data types */ @@ -3021,7 +3027,7 @@ static void cleanup_variables(THD *thd, struct system_variables *vars) DBUG_ASSERT((uint)v->offset <= vars->dynamic_variables_head); if ((v->key[0] & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR && - v->key[0] & PLUGIN_VAR_MEMALLOC) + v->key[0] & BOOKMARK_MEMALLOC) { char **ptr= (char**)(vars->dynamic_variables_ptr + v->offset); my_free(*ptr); From e727741614b5361465de9cc8c292e7c3fb9cdfec Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:27:35 +0200 Subject: [PATCH 13/87] typo fixed --- sql/table.cc | 8 ++++---- sql/table.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index 06e424b2cfb..8bc0f7b6b12 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4817,7 +4817,7 @@ void TABLE_LIST::register_want_access(ulong want_access) Load security context information for this view SYNOPSIS - TABLE_LIST::prepare_view_securety_context() + TABLE_LIST::prepare_view_security_context() thd [in] thread handler RETURN @@ -4826,9 +4826,9 @@ void TABLE_LIST::register_want_access(ulong want_access) */ #ifndef NO_EMBEDDED_ACCESS_CHECKS -bool TABLE_LIST::prepare_view_securety_context(THD *thd) +bool TABLE_LIST::prepare_view_security_context(THD *thd) { - DBUG_ENTER("TABLE_LIST::prepare_view_securety_context"); + DBUG_ENTER("TABLE_LIST::prepare_view_security_context"); DBUG_PRINT("enter", ("table: %s", alias)); DBUG_ASSERT(!prelocking_placeholder && view); @@ -4935,7 +4935,7 @@ bool TABLE_LIST::prepare_security(THD *thd) Security_context *save_security_ctx= thd->security_ctx; DBUG_ASSERT(!prelocking_placeholder); - if (prepare_view_securety_context(thd)) + if (prepare_view_security_context(thd)) DBUG_RETURN(TRUE); thd->security_ctx= find_view_security_context(thd); while ((tbl= tb++)) diff --git a/sql/table.h b/sql/table.h index 9aa68b05cf2..50ddb0a096b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2034,7 +2034,7 @@ struct TABLE_LIST bool prepare_security(THD *thd); #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *find_view_security_context(THD *thd); - bool prepare_view_securety_context(THD *thd); + bool prepare_view_security_context(THD *thd); #endif /* Cleanup for re-execution in a prepared statement or a stored From ccc9238335daaa1ca269b651bf25845afa7cf166 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:35:39 +0200 Subject: [PATCH 14/87] s/st_ha_create_information/HA_CREATE_INFO/ --- sql/handler.h | 4 ++-- sql/sql_db.h | 1 - sql/sql_partition.h | 1 - sql/sql_show.h | 2 -- sql/sql_table.h | 2 +- sql/unireg.h | 2 -- storage/myisam/ha_myisam.h | 3 --- 7 files changed, 3 insertions(+), 12 deletions(-) diff --git a/sql/handler.h b/sql/handler.h index 6241f1ee774..7c8cc98b37c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1284,7 +1284,7 @@ struct st_partition_iter; enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES }; -typedef struct st_ha_create_information +struct HA_CREATE_INFO { CHARSET_INFO *table_charset, *default_table_charset; LEX_STRING connect_string; @@ -1324,7 +1324,7 @@ typedef struct st_ha_create_information ha_table_option_struct *option_struct; ///< structure with parsed table options ha_field_option_struct **fields_option_struct; ///< array of field option structures ha_index_option_struct **indexes_option_struct; ///< array of index option structures -} HA_CREATE_INFO; +}; typedef struct st_key_create_information diff --git a/sql/sql_db.h b/sql/sql_db.h index 1f447c11a52..62d379c515d 100644 --- a/sql/sql_db.h +++ b/sql/sql_db.h @@ -19,7 +19,6 @@ #include "hash.h" /* HASH */ class THD; -typedef struct st_ha_create_information HA_CREATE_INFO; int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); diff --git a/sql/sql_partition.h b/sql/sql_partition.h index 2fd9b4c3d75..8db07f836b0 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -32,7 +32,6 @@ class partition_info; struct TABLE; struct TABLE_LIST; typedef struct st_bitmap MY_BITMAP; -typedef struct st_ha_create_information HA_CREATE_INFO; typedef struct st_key KEY; typedef struct st_key_range key_range; diff --git a/sql/sql_show.h b/sql/sql_show.h index 03d8af3aabd..09e0a80fd4f 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -27,9 +27,7 @@ class String; class THD; class sp_name; struct TABLE_LIST; -struct st_ha_create_information; typedef class st_select_lex SELECT_LEX; -typedef st_ha_create_information HA_CREATE_INFO; struct LEX; typedef struct st_mysql_show_var SHOW_VAR; typedef struct st_schema_table ST_SCHEMA_TABLE; diff --git a/sql/sql_table.h b/sql/sql_table.h index 9d5e768a5a3..7826c540487 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -26,7 +26,7 @@ class THD; struct TABLE; struct handlerton; typedef struct st_ha_check_opt HA_CHECK_OPT; -typedef struct st_ha_create_information HA_CREATE_INFO; +struct HA_CREATE_INFO; typedef struct st_key KEY; typedef struct st_key_cache KEY_CACHE; typedef struct st_lock_param_type ALTER_PARTITION_PARAM_TYPE; diff --git a/sql/unireg.h b/sql/unireg.h index da510bb4e6d..f4e88b0d8d7 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -23,8 +23,6 @@ /* Extra functions used by unireg library */ -typedef struct st_ha_create_information HA_CREATE_INFO; - #ifndef NO_ALARM_LOOP #define NO_ALARM_LOOP /* lib5 and popen can't use alarm */ #endif diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 3c0d10fae8c..11871479342 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -26,9 +26,6 @@ #include "handler.h" /* handler */ #include "table.h" /* TABLE_SHARE */ -struct TABLE_SHARE; -typedef struct st_ha_create_information HA_CREATE_INFO; - #define HA_RECOVER_DEFAULT 1 /* Automatic recover active */ #define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */ #define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */ From 028ce66c9eb4d680c838ea2e33aefe29f0efb97b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:36:37 +0200 Subject: [PATCH 15/87] simplify test case --- mysql-test/r/partition_debug_sync.result | 7 ++----- mysql-test/t/partition_debug_sync.test | 11 ++++------- sql/sql_table.cc | 2 -- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/partition_debug_sync.result b/mysql-test/r/partition_debug_sync.result index ad0f6df5ff2..826bca019d5 100644 --- a/mysql-test/r/partition_debug_sync.result +++ b/mysql-test/r/partition_debug_sync.result @@ -42,21 +42,18 @@ CREATE TABLE t2 b INTEGER NOT NULL, KEY (b)) ENGINE = MYISAM -/*!50100 PARTITION BY RANGE (a) -(PARTITION p0 VALUES LESS THAN (2), +PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (2), PARTITION p1 VALUES LESS THAN (20), PARTITION p2 VALUES LESS THAN (100), -PARTITION p3 VALUES LESS THAN MAXVALUE ) */; +PARTITION p3 VALUES LESS THAN MAXVALUE); SET DEBUG_SYNC= 'alter_table_before_open_tables SIGNAL removing_partitions WAIT_FOR waiting_for_alter'; SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done'; ALTER TABLE t2 REMOVE PARTITIONING; # Con default -SET SESSION debug_dbug= "+d,sleep_before_no_locks_delete_table"; SET DEBUG_SYNC= 'now WAIT_FOR removing_partitions'; SET DEBUG_SYNC= 'rm_table_no_locks_before_delete_table SIGNAL waiting_for_alter'; SET DEBUG_SYNC= 'rm_table_no_locks_before_binlog SIGNAL delete_done'; DROP TABLE IF EXISTS t2; -SET SESSION debug_dbug= "-d,sleep_before_no_locks_delete_table"; # Con 1 ERROR 42S02: Table 'test.t2' doesn't exist SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/t/partition_debug_sync.test b/mysql-test/t/partition_debug_sync.test index 027a4bd19a7..f8c00abafab 100644 --- a/mysql-test/t/partition_debug_sync.test +++ b/mysql-test/t/partition_debug_sync.test @@ -60,22 +60,19 @@ CREATE TABLE t2 b INTEGER NOT NULL, KEY (b)) ENGINE = MYISAM -/*!50100 PARTITION BY RANGE (a) -(PARTITION p0 VALUES LESS THAN (2), - PARTITION p1 VALUES LESS THAN (20), - PARTITION p2 VALUES LESS THAN (100), - PARTITION p3 VALUES LESS THAN MAXVALUE ) */; +PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (2), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (100), + PARTITION p3 VALUES LESS THAN MAXVALUE); SET DEBUG_SYNC= 'alter_table_before_open_tables SIGNAL removing_partitions WAIT_FOR waiting_for_alter'; SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done'; --send ALTER TABLE t2 REMOVE PARTITIONING connection default; --echo # Con default -SET SESSION debug_dbug= "+d,sleep_before_no_locks_delete_table"; SET DEBUG_SYNC= 'now WAIT_FOR removing_partitions'; SET DEBUG_SYNC= 'rm_table_no_locks_before_delete_table SIGNAL waiting_for_alter'; SET DEBUG_SYNC= 'rm_table_no_locks_before_binlog SIGNAL delete_done'; DROP TABLE IF EXISTS t2; -SET SESSION debug_dbug= "-d,sleep_before_no_locks_delete_table"; --echo # Con 1 connection con1; --error ER_NO_SUCH_TABLE diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a379b581539..bd2d8573951 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2278,8 +2278,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); - DBUG_EXECUTE_IF("sleep_before_no_locks_delete_table", - my_sleep(100000);); error= 0; if (drop_temporary || ((access(path, F_OK) && From 73f79ac83f827a1b5227482b2184afc188c707ae Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:37:47 +0200 Subject: [PATCH 16/87] simpler fix for mysql bug #56085, no need to write an error interceptor, when the function has a dedicated flag for this very use case. --- include/my_global.h | 8 +++++--- sql/sql_plugin.cc | 20 ++++---------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index c82ac911fc2..859c06c6818 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -90,13 +90,15 @@ #define IF_WIN(A,B) B #endif -#ifndef EMBEDDED_LIBRARY +#ifdef EMBEDDED_LIBRARY +#define IF_EMBEDDED(A,B) A +#else +#define IF_EMBEDDED(A,B) B + #ifdef WITH_NDB_BINLOG #define HAVE_NDB_BINLOG 1 #endif -#endif /* !EMBEDDED_LIBRARY */ -#ifndef EMBEDDED_LIBRARY #define HAVE_REPLICATION #define HAVE_EXTERNAL_CLIENT #endif diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 4b631636db6..60474bbfd5b 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1707,9 +1707,6 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) int error; THD *new_thd= new THD; bool result; -#ifdef EMBEDDED_LIBRARY - No_such_table_error_handler error_handler; -#endif /* EMBEDDED_LIBRARY */ DBUG_ENTER("plugin_load"); new_thd->thread_stack= (char*) &tables; @@ -1718,22 +1715,13 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) new_thd->db_length= 5; bzero((char*) &new_thd->net, sizeof(new_thd->net)); tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_READ); - -#ifdef EMBEDDED_LIBRARY - /* - When building an embedded library, if the mysql.plugin table - does not exist, we silently ignore the missing table - */ - new_thd->push_internal_handler(&error_handler); -#endif /* EMBEDDED_LIBRARY */ + tables.open_strategy= TABLE_LIST:: IF_EMBEDDED(OPEN_IF_EXISTS, OPEN_NORMAL); result= open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT); -#ifdef EMBEDDED_LIBRARY - new_thd->pop_internal_handler(); - if (error_handler.safely_trapped_errors()) + table= tables.table; + if (IF_EMBEDDED(!table, false)) goto end; -#endif /* EMBEDDED_LIBRARY */ if (result) { @@ -1745,7 +1733,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) sql_print_warning("Could not open mysql.plugin table. Some options may be missing from the help text"); goto end; } - table= tables.table; + if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE)) { sql_print_error("Could not initialize init_read_record; Plugins not " From 0d405ed02f264945426fab12d50b34976350db35 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:40:59 +0200 Subject: [PATCH 17/87] remove long time obsolete xyz_ci() copies of xyz() macros --- sql/sql_plugin.cc | 12 +++++------- sql/sql_plugin.h | 2 -- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 60474bbfd5b..0406f8190a8 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -310,8 +310,6 @@ static void plugin_vars_free_values(sys_var *vars); static void restore_pluginvar_names(sys_var *first); static void plugin_opt_set_limits(struct my_option *, const struct st_mysql_sys_var *); -#define my_intern_plugin_lock(A,B) intern_plugin_lock(A,B) -#define my_intern_plugin_lock_ci(A,B) intern_plugin_lock(A,B) static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin); static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void reap_plugins(void); @@ -973,7 +971,7 @@ plugin_ref plugin_lock(THD *thd, plugin_ref ptr) #endif mysql_mutex_lock(&LOCK_plugin); plugin_ref_to_int(ptr)->locks_total++; - rc= my_intern_plugin_lock_ci(lex, ptr); + rc= intern_plugin_lock(lex, ptr); mysql_mutex_unlock(&LOCK_plugin); DBUG_RETURN(rc); } @@ -987,7 +985,7 @@ plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name, int type) DBUG_ENTER("plugin_lock_by_name"); mysql_mutex_lock(&LOCK_plugin); if ((plugin= plugin_find_internal(name, type))) - rc= my_intern_plugin_lock_ci(lex, plugin_int_to_ref(plugin)); + rc= intern_plugin_lock(lex, plugin_int_to_ref(plugin)); mysql_mutex_unlock(&LOCK_plugin); DBUG_RETURN(rc); } @@ -1597,7 +1595,7 @@ int plugin_init(int *argc, char **argv, int flags) { DBUG_ASSERT(!global_system_variables.table_plugin); global_system_variables.table_plugin= - my_intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr)); + intern_plugin_lock(NULL, plugin_int_to_ref(plugin_ptr)); DBUG_ASSERT(plugin_ptr->ref_count == 1); } } @@ -2652,7 +2650,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length) { mysql_rwlock_unlock(&LOCK_system_variables_hash); LEX *lex= thd ? thd->lex : 0; - if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin)))) + if (!(plugin= intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin)))) var= NULL; /* failed to lock it, it must be uninstalling */ else if (!(plugin_state(plugin) & PLUGIN_IS_READY)) @@ -2976,7 +2974,7 @@ void plugin_thdvar_init(THD *thd) mysql_mutex_lock(&LOCK_plugin); thd->variables.table_plugin= - my_intern_plugin_lock(NULL, global_system_variables.table_plugin); + intern_plugin_lock(NULL, global_system_variables.table_plugin); intern_plugin_unlock(NULL, old_table_plugin); mysql_mutex_unlock(&LOCK_plugin); DBUG_VOID_RETURN; diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index be1cfcdcc4f..d3c41a1e17b 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -150,9 +150,7 @@ extern void plugin_shutdown(void); void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root); extern bool plugin_is_ready(const LEX_STRING *name, int type); #define my_plugin_lock_by_name(A,B,C) plugin_lock_by_name(A,B,C) -#define my_plugin_lock_by_name_ci(A,B,C) plugin_lock_by_name(A,B,C) #define my_plugin_lock(A,B) plugin_lock(A,B) -#define my_plugin_lock_ci(A,B) plugin_lock(A,B) extern plugin_ref plugin_lock(THD *thd, plugin_ref ptr); extern plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name, int type); From 94753d8b946aa8b04cc713377fdcd50f952f3231 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:44:19 +0200 Subject: [PATCH 18/87] small cleanup - remove prehistoric DB_TYPE_xxx values --- sql/handler.cc | 7 ------- sql/handler.h | 36 +++++++++++++++++------------------- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 150bbee39a9..ee505bfd5ff 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -232,13 +232,6 @@ handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type, RUN_HOOK(transaction, after_rollback, (thd, FALSE)); - switch (database_type) { - case DB_TYPE_MRG_ISAM: - return ha_resolve_by_legacy_type(thd, DB_TYPE_MRG_MYISAM); - default: - break; - } - return ha_default_handlerton(thd); } /* ha_checktype */ diff --git a/sql/handler.h b/sql/handler.h index 7c8cc98b37c..2acec83d3ca 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -336,25 +336,23 @@ enum legacy_db_type { - DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1, - DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM, - DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM, - DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM, - DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, - DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER, - DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB, - DB_TYPE_FEDERATED_DB, - DB_TYPE_BLACKHOLE_DB, - DB_TYPE_PARTITION_DB, - DB_TYPE_BINLOG, - DB_TYPE_SOLID, - DB_TYPE_PBXT, - DB_TYPE_TABLE_FUNCTION, - DB_TYPE_MEMCACHE, - DB_TYPE_FALCON, - DB_TYPE_MARIA, - /** Performance schema engine. */ - DB_TYPE_PERFORMANCE_SCHEMA, + /* note these numerical values are fixed and can *not* be changed */ + DB_TYPE_UNKNOWN=0, + DB_TYPE_HEAP=6, + DB_TYPE_MYISAM=9, + DB_TYPE_MRG_MYISAM=10, + DB_TYPE_INNODB=12, + DB_TYPE_NDBCLUSTER=14, + DB_TYPE_EXAMPLE_DB=15, + DB_TYPE_ARCHIVE_DB=16, + DB_TYPE_CSV_DB=17, + DB_TYPE_FEDERATED_DB=18, + DB_TYPE_BLACKHOLE_DB=19, + DB_TYPE_PARTITION_DB=20, + DB_TYPE_BINLOG=21, + DB_TYPE_PBXT=23, + DB_TYPE_MARIA=27, + DB_TYPE_PERFORMANCE_SCHEMA=28, DB_TYPE_FIRST_DYNAMIC=42, DB_TYPE_DEFAULT=127 // Must be last }; From 09ece94fac5fc160e11e6bd46208e6c0be86e7e6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 15:57:38 +0200 Subject: [PATCH 19/87] remove handlerton::find_files (new implementation is coming), and handlerton::table_exists_in_engine (new implementation is coming), and handlerton::license (redundant) --- sql/handler.cc | 90 ------------------------------------------------ sql/handler.h | 11 ------ sql/sql_show.cc | 9 ----- sql/sql_table.cc | 24 ++++--------- 4 files changed, 7 insertions(+), 127 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index ee505bfd5ff..4214e7f9108 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4371,96 +4371,6 @@ int ha_discover(THD *thd, const char *db, const char *name, } -/** - Call this function in order to give the handler the possiblity - to ask engine if there are any new tables that should be written to disk - or any dropped tables that need to be removed from disk -*/ -struct st_find_files_args -{ - const char *db; - const char *path; - const char *wild; - bool dir; - List *files; -}; - -static my_bool find_files_handlerton(THD *thd, plugin_ref plugin, - void *arg) -{ - st_find_files_args *vargs= (st_find_files_args *)arg; - handlerton *hton= plugin_data(plugin, handlerton *); - - - if (hton->state == SHOW_OPTION_YES && hton->find_files) - if (hton->find_files(hton, thd, vargs->db, vargs->path, vargs->wild, - vargs->dir, vargs->files)) - return TRUE; - - return FALSE; -} - -int -ha_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir, List *files) -{ - int error= 0; - DBUG_ENTER("ha_find_files"); - DBUG_PRINT("enter", ("db: '%s' path: '%s' wild: '%s' dir: %d", - db, path, wild, dir)); - st_find_files_args args= {db, path, wild, dir, files}; - - plugin_foreach(thd, find_files_handlerton, - MYSQL_STORAGE_ENGINE_PLUGIN, &args); - /* The return value is not currently used */ - DBUG_RETURN(error); -} - -/** - Ask handler if the table exists in engine. - @retval - HA_ERR_NO_SUCH_TABLE Table does not exist - @retval - HA_ERR_TABLE_EXIST Table exists - @retval - \# Error code -*/ -struct st_table_exists_in_engine_args -{ - const char *db; - const char *name; - int err; -}; - -static my_bool table_exists_in_engine_handlerton(THD *thd, plugin_ref plugin, - void *arg) -{ - st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg; - handlerton *hton= plugin_data(plugin, handlerton *); - - int err= HA_ERR_NO_SUCH_TABLE; - - if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine) - err = hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name); - - vargs->err = err; - if (vargs->err == HA_ERR_TABLE_EXIST) - return TRUE; - - return FALSE; -} - -int ha_table_exists_in_engine(THD* thd, const char* db, const char* name) -{ - DBUG_ENTER("ha_table_exists_in_engine"); - DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); - st_table_exists_in_engine_args args= {db, name, HA_ERR_NO_SUCH_TABLE}; - plugin_foreach(thd, table_exists_in_engine_handlerton, - MYSQL_STORAGE_ENGINE_PLUGIN, &args); - DBUG_PRINT("exit", ("error: %d", args.err)); - DBUG_RETURN(args.err); -} - #ifdef HAVE_NDB_BINLOG /* TODO: change this into a dynamic struct diff --git a/sql/handler.h b/sql/handler.h index 2acec83d3ca..f6a10a84646 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1079,14 +1079,6 @@ struct handlerton const char *name, uchar **frmblob, size_t *frmlen); - int (*find_files)(handlerton *hton, THD *thd, - const char *db, - const char *path, - const char *wild, bool dir, List *files); - int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db, - const char *name); - - uint32 license; /* Flag for Engine License */ /* Optional clauses in the CREATE/ALTER TABLE */ @@ -3041,9 +3033,6 @@ bool ha_check_if_table_exists(THD* thd, const char *db, const char *name, bool *exists); int ha_discover(THD* thd, const char* dbname, const char* name, uchar** frmblob, size_t* frmlen); -int ha_find_files(THD *thd,const char *db,const char *path, - const char *wild, bool dir, List* files); -int ha_table_exists_in_engine(THD* thd, const char* db, const char* name); /* key cache */ extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache, void *); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a9c40a44997..c251678f42c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -833,8 +833,6 @@ find_files(THD *thd, List *files, const char *db, DBUG_PRINT("info",("found: %d files", files->elements)); my_dirend(dirp); - (void) ha_find_files(thd, db, path, wild, dir, files); - DBUG_RETURN(FIND_FILES_OK); } @@ -3889,13 +3887,6 @@ make_table_name_list(THD *thd, List *table_names, LEX *lex, { if (table_names->push_back(&lookup_field_vals->table_value)) return 1; - /* - Check that table is relevant in current transaction. - (used for ndb engine, see ndbcluster_find_files(), ha_ndbcluster.cc) - */ - (void) ha_find_files(thd, db_name->str, path, - lookup_field_vals->table_value.str, 0, - table_names); } return 0; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bd2d8573951..455fef094af 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4421,24 +4421,14 @@ bool mysql_create_table_no_lock(THD *thd, { bool create_if_not_exists = create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS; - int retcode = ha_table_exists_in_engine(thd, db, table_name); - DBUG_PRINT("info", ("exists_in_engine: %u",retcode)); - switch (retcode) + bool exists_in_engine; + ha_check_if_table_exists(thd, db, table_name, &exists_in_engine); + if (exists_in_engine) { - case HA_ERR_NO_SUCH_TABLE: - /* Normal case, no table exists. we can go and create it */ - break; - case HA_ERR_TABLE_EXIST: - DBUG_PRINT("info", ("Table existed in handler")); - - if (create_if_not_exists) - goto warn; - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); - goto err; - default: - DBUG_PRINT("info", ("error: %u from storage engine", retcode)); - my_error(retcode, MYF(0),table_name); - goto err; + if (create_if_not_exists) + goto warn; + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); + goto err; } } From 58e62d701e9d1c0a5ebb88f8a8779011c59ee735 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 17:08:49 +0200 Subject: [PATCH 20/87] * move bas_ext from the handler to the handlerton * provide a default bas_ext value of the empty list --- sql/ha_partition.cc | 27 +++++++--------- sql/ha_partition.h | 4 --- sql/handler.cc | 30 ++++++++---------- sql/handler.h | 6 +++- sql/table.cc | 14 ++------- storage/archive/ha_archive.cc | 23 ++++++-------- storage/archive/ha_archive.h | 1 - storage/blackhole/ha_blackhole.cc | 9 ------ storage/blackhole/ha_blackhole.h | 1 - storage/cassandra/ha_cassandra.cc | 10 ------ storage/cassandra/ha_cassandra.h | 5 --- storage/csv/ha_tina.cc | 43 +++++++------------------ storage/csv/ha_tina.h | 1 - storage/example/ha_example.cc | 49 +++++++++++++---------------- storage/example/ha_example.h | 5 --- storage/federated/ha_federated.cc | 15 --------- storage/federated/ha_federated.h | 1 - storage/federatedx/ha_federatedx.cc | 16 ---------- storage/federatedx/ha_federatedx.h | 1 - storage/heap/ha_heap.cc | 10 ------ storage/heap/ha_heap.h | 1 - storage/maria/ha_maria.cc | 7 +---- storage/maria/ha_maria.h | 1 - storage/myisam/ha_myisam.cc | 7 +---- storage/myisam/ha_myisam.h | 1 - storage/myisammrg/ha_myisammrg.cc | 7 +---- storage/myisammrg/ha_myisammrg.h | 1 - storage/perfschema/ha_perfschema.cc | 9 ------ storage/perfschema/ha_perfschema.h | 2 -- storage/sphinx/ha_sphinx.cc | 13 -------- storage/sphinx/ha_sphinx.h | 1 - storage/xtradb/handler/ha_innodb.cc | 26 +++++---------- storage/xtradb/handler/ha_innodb.h | 1 - 33 files changed, 86 insertions(+), 262 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 5f67a89cb9c..5f7851b8e25 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -78,6 +78,17 @@ static handler *partition_create_handler(handlerton *hton, static uint partition_flags(); static uint alter_table_flags(uint flags); +/* + If frm_error() is called then we will use this to to find out what file + extensions exist for the storage engine. This is also used by the default + rename_table and delete_table method in handler.cc. +*/ + +static const char *ha_partition_ext[]= +{ + ha_par_ext, NullS +}; + static int partition_initialize(void *p) { @@ -93,6 +104,7 @@ static int partition_initialize(void *p) partition_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN | HTON_TEMPORARY_NOT_SUPPORTED; + partition_hton->tablefile_extensions= ha_partition_ext; return 0; } @@ -7311,21 +7323,6 @@ int ha_partition::final_drop_index(TABLE *table_arg) } -/* - If frm_error() is called then we will use this to to find out what file - extensions exist for the storage engine. This is also used by the default - rename_table and delete_table method in handler.cc. -*/ - -static const char *ha_partition_ext[]= -{ - ha_par_ext, NullS -}; - -const char **ha_partition::bas_ext() const -{ return ha_partition_ext; } - - uint ha_partition::min_of_the_max_uint( uint (handler::*operator_func)(void) const) const { diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 53f0c4f2484..9e1c5b0bf5f 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -882,10 +882,6 @@ public: the ha_partition_hton cannot know all its capabilities */ virtual uint alter_table_flags(uint flags); - /* - extensions of table handler files - */ - virtual const char **bas_ext() const; /* unireg.cc will call the following to make sure that the storage engine can handle the data it is about to send. diff --git a/sql/handler.cc b/sql/handler.cc index 4214e7f9108..56e9ec35ad8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -443,11 +443,13 @@ int ha_finalize_handlerton(st_plugin_int *plugin) int ha_initialize_handlerton(st_plugin_int *plugin) { handlerton *hton; + static const char *no_exts[]= { 0 }; DBUG_ENTER("ha_initialize_handlerton"); DBUG_PRINT("plugin", ("initialize plugin: '%s'", plugin->name.str)); hton= (handlerton *)my_malloc(sizeof(handlerton), MYF(MY_WME | MY_ZEROFILL)); + hton->tablefile_extensions= no_exts; if (hton == NULL) { @@ -4719,26 +4721,20 @@ static my_bool exts_handlerton(THD *unused, plugin_ref plugin, { List *found_exts= (List *) arg; handlerton *hton= plugin_data(plugin, handlerton *); - handler *file; - if (hton->state == SHOW_OPTION_YES && hton->create && - (file= hton->create(hton, (TABLE_SHARE*) 0, current_thd->mem_root))) + List_iterator_fast it(*found_exts); + const char **ext, *old_ext; + + for (ext= hton->tablefile_extensions; *ext; ext++) { - List_iterator_fast it(*found_exts); - const char **ext, *old_ext; - - for (ext= file->bas_ext(); *ext; ext++) + while ((old_ext= it++)) { - while ((old_ext= it++)) - { - if (!strcmp(old_ext, *ext)) - break; - } - if (!old_ext) - found_exts->push_back((char *) *ext); - - it.rewind(); + if (!strcmp(old_ext, *ext)) + break; } - delete file; + if (!old_ext) + found_exts->push_back((char *) *ext); + + it.rewind(); } return FALSE; } diff --git a/sql/handler.h b/sql/handler.h index f6a10a84646..43c5246c156 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1086,6 +1086,7 @@ struct handlerton ha_create_table_option *field_options; // these are specified per field ha_create_table_option *index_options; // these are specified per index + const char **tablefile_extensions; }; @@ -2416,7 +2417,10 @@ public: element - data file extention. This order is assumed by prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. */ - virtual const char **bas_ext() const =0; + const char **bas_ext() const + { + return ht->tablefile_extensions; + } virtual int get_default_no_partitions(HA_CREATE_INFO *create_info) { return 1;} diff --git a/sql/table.cc b/sql/table.cc index 8bc0f7b6b12..cdee7405c7e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2987,23 +2987,15 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) break; case 2: { - handler *file= 0; const char *datext= ""; - if (share->db_type() != NULL) - { - if ((file= get_new_handler(share, current_thd->mem_root, - share->db_type()))) - { - if (!(datext= *file->bas_ext())) - datext= ""; - } - } + if (share->db_type() && share->db_type()->tablefile_extensions[0]) + datext= share->db_type()->tablefile_extensions[0]; + err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ? ER_FILE_USED : ER_CANT_OPEN_FILE; strxmov(buff, share->normalized_path.str, datext, NullS); my_error(err_no,errortype, buff, db_errno); - delete file; break; } case 5: diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 5ee7841d9b3..02813ff8dc7 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -199,6 +199,14 @@ static void init_archive_psi_keys(void) TRUE Error */ +/* + We just implement one additional file extension. +*/ +static const char *ha_archive_exts[] = { + ARZ, + NullS +}; + int archive_db_init(void *p) { DBUG_ENTER("archive_db_init"); @@ -214,6 +222,7 @@ int archive_db_init(void *p) archive_hton->create= archive_create_handler; archive_hton->flags= HTON_NO_FLAGS; archive_hton->discover= archive_discover; + archive_hton->tablefile_extensions= ha_archive_exts; if (mysql_mutex_init(az_key_mutex_archive_mutex, &archive_mutex, MY_MUTEX_INIT_FAST)) @@ -530,20 +539,6 @@ int ha_archive::init_archive_reader() } -/* - We just implement one additional file extension. -*/ -static const char *ha_archive_exts[] = { - ARZ, - NullS -}; - -const char **ha_archive::bas_ext() const -{ - return ha_archive_exts; -} - - /* When opening a file we: Create/get our shared structure. diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index 627267c7306..25e520f56dd 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -83,7 +83,6 @@ public: { } const char *index_type(uint inx) { return "NONE"; } - const char **bas_ext() const; ulonglong table_flags() const { return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_BIT_FIELD | diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 812623314bf..91a2c70cb9f 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -52,15 +52,6 @@ ha_blackhole::ha_blackhole(handlerton *hton, {} -static const char *ha_blackhole_exts[] = { - NullS -}; - -const char **ha_blackhole::bas_ext() const -{ - return ha_blackhole_exts; -} - int ha_blackhole::open(const char *name, int mode, uint test_if_locked) { DBUG_ENTER("ha_blackhole::open"); diff --git a/storage/blackhole/ha_blackhole.h b/storage/blackhole/ha_blackhole.h index 51857f3bb2a..b70320848d7 100644 --- a/storage/blackhole/ha_blackhole.h +++ b/storage/blackhole/ha_blackhole.h @@ -51,7 +51,6 @@ public: don't implement this method unless you really have indexes */ const char *index_type(uint key_number); - const char **bas_ext() const; ulonglong table_flags() const { return(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 3934f288085..968d23c94b5 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -369,16 +369,6 @@ ha_cassandra::ha_cassandra(handlerton *hton, TABLE_SHARE *table_arg) {} -static const char *ha_cassandra_exts[] = { - NullS -}; - -const char **ha_cassandra::bas_ext() const -{ - return ha_cassandra_exts; -} - - int ha_cassandra::connect_and_check_options(TABLE *table_arg) { ha_table_option_struct *options= table_arg->s->option_struct; diff --git a/storage/cassandra/ha_cassandra.h b/storage/cassandra/ha_cassandra.h index a57a754979c..3fd9d542885 100644 --- a/storage/cassandra/ha_cassandra.h +++ b/storage/cassandra/ha_cassandra.h @@ -131,11 +131,6 @@ public: */ const char *index_type(uint inx) { return "HASH"; } - /** @brief - The file extensions. - */ - const char **bas_ext() const; - /** @brief This is a list of flags that indicate what functionality the storage engine implements. The current table flags are documented in handler.h diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 50e639881c5..ab2e2c118f8 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -144,6 +144,16 @@ static void init_tina_psi_keys(void) } #endif /* HAVE_PSI_INTERFACE */ +/* + If frm_error() is called in table.cc this is called to find out what file + extensions exist for this handler. +*/ +static const char *ha_tina_exts[] = { + CSV_EXT, + CSM_EXT, + NullS +}; + static int tina_init_func(void *p) { handlerton *tina_hton; @@ -161,6 +171,7 @@ static int tina_init_func(void *p) tina_hton->create= tina_create_handler; tina_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES | HTON_NO_PARTITION); + tina_hton->tablefile_extensions= ha_tina_exts; return 0; } @@ -832,21 +843,6 @@ err: DBUG_RETURN(error); } -/* - If frm_error() is called in table.cc this is called to find out what file - extensions exist for this handler. -*/ -static const char *ha_tina_exts[] = { - CSV_EXT, - CSM_EXT, - NullS -}; - -const char **ha_tina::bas_ext() const -{ - return ha_tina_exts; -} - /* Three functions below are needed to enable concurrent insert functionality for CSV engine. For more details see mysys/thr_lock.c @@ -1771,23 +1767,6 @@ bool ha_tina::check_if_incompatible_data(HA_CREATE_INFO *info, struct st_mysql_storage_engine csv_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; -mysql_declare_plugin(csv) -{ - MYSQL_STORAGE_ENGINE_PLUGIN, - &csv_storage_engine, - "CSV", - "Brian Aker, MySQL AB", - "CSV storage engine", - PLUGIN_LICENSE_GPL, - tina_init_func, /* Plugin Init */ - tina_done_func, /* Plugin Deinit */ - 0x0100 /* 1.0 */, - NULL, /* status variables */ - NULL, /* system variables */ - NULL, /* config options */ - 0, /* flags */ -} -mysql_declare_plugin_end; maria_declare_plugin(csv) { MYSQL_STORAGE_ENGINE_PLUGIN, diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h index 26404b3a9e7..ebf62fbed65 100644 --- a/storage/csv/ha_tina.h +++ b/storage/csv/ha_tina.h @@ -103,7 +103,6 @@ public: free_root(&blobroot, MYF(0)); } const char *index_type(uint inx) { return "NONE"; } - const char **bas_ext() const; ulonglong table_flags() const { return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT | diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 81f6cbe707f..dac1ff81c10 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -229,6 +229,27 @@ static void init_example_psi_keys() #endif +/** + @brief + If frm_error() is called then we will use this to determine + the file extensions that exist for the storage engine. This is also + used by the default rename_table and delete_table method in + handler.cc and by the default discover_many method. + + For engines that have two file name extentions (separate meta/index file + and data file), the order of elements is relevant. First element of engine + file name extentions array should be meta/index file extention. Second + element - data file extention. This order is assumed by + prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. + + @see + rename_table method in handler.cc and + delete_table method in handler.cc +*/ + +static const char *ha_example_exts[] = { + NullS +}; static int example_init_func(void *p) { DBUG_ENTER("example_init_func"); @@ -247,6 +268,7 @@ static int example_init_func(void *p) example_hton->flags= HTON_CAN_RECREATE; example_hton->table_options= example_table_option_list; example_hton->field_options= example_field_option_list; + example_hton->tablefile_extensions= ha_example_exts; DBUG_RETURN(0); } @@ -353,33 +375,6 @@ ha_example::ha_example(handlerton *hton, TABLE_SHARE *table_arg) {} -/** - @brief - If frm_error() is called then we will use this to determine - the file extensions that exist for the storage engine. This is also - used by the default rename_table and delete_table method in - handler.cc. - - For engines that have two file name extentions (separate meta/index file - and data file), the order of elements is relevant. First element of engine - file name extentions array should be meta/index file extention. Second - element - data file extention. This order is assumed by - prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. - - @see - rename_table method in handler.cc and - delete_table method in handler.cc -*/ - -static const char *ha_example_exts[] = { - NullS -}; - -const char **ha_example::bas_ext() const -{ - return ha_example_exts; -} - /** @brief Used for opening tables. The name will be the name of the file. diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h index 9be370edfe3..d3d31893781 100644 --- a/storage/example/ha_example.h +++ b/storage/example/ha_example.h @@ -72,11 +72,6 @@ public: */ const char *index_type(uint inx) { return "HASH"; } - /** @brief - The file extensions. - */ - const char **bas_ext() const; - /** @brief This is a list of flags that indicate what functionality the storage engine implements. The current table flags are documented in handler.h diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index b554c344f62..872eecff9cd 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1615,21 +1615,6 @@ ha_rows ha_federated::records_in_range(uint inx, key_range *start_key, DBUG_ENTER("ha_federated::records_in_range"); DBUG_RETURN(FEDERATED_RECORDS_IN_RANGE); } -/* - If frm_error() is called then we will use this to to find out - what file extentions exist for the storage engine. This is - also used by the default rename_table and delete_table method - in handler.cc. -*/ - -const char **ha_federated::bas_ext() const -{ - static const char *ext[]= - { - NullS - }; - return ext; -} /* diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index fc2c4740cc0..31f33f5f789 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -134,7 +134,6 @@ public: */ // perhaps get index type const char *index_type(uint inx) { return "REMOTE"; } - const char **bas_ext() const; /* This is a list of flags that says what the storage engine implements. The current table flags are documented in diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index e1c2a38964a..1d298cf283d 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1719,22 +1719,6 @@ ha_rows ha_federatedx::records_in_range(uint inx, key_range *start_key, DBUG_ENTER("ha_federatedx::records_in_range"); DBUG_RETURN(FEDERATEDX_RECORDS_IN_RANGE); } -/* - If frm_error() is called then we will use this to to find out - what file extentions exist for the storage engine. This is - also used by the default rename_table and delete_table method - in handler.cc. -*/ - -const char **ha_federatedx::bas_ext() const -{ - static const char *ext[]= - { - NullS - }; - return ext; -} - federatedx_txn *ha_federatedx::get_txn(THD *thd, bool no_create) { diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index dcbbe534262..66eb4061ec3 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -317,7 +317,6 @@ public: */ // perhaps get index type const char *index_type(uint inx) { return "REMOTE"; } - const char **bas_ext() const; /* This is a list of flags that says what the storage engine implements. The current table flags are documented in diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 8e63799680b..916abaa60ea 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -75,16 +75,6 @@ ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg) internal_table(0) {} - -static const char *ha_heap_exts[] = { - NullS -}; - -const char **ha_heap::bas_ext() const -{ - return ha_heap_exts; -} - /* Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index 30ad06e2c06..74824b66c42 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -45,7 +45,6 @@ public: } /* Rows also use a fixed-size format */ enum row_type get_row_type() const { return ROW_TYPE_FIXED; } - const char **bas_ext() const; ulonglong table_flags() const { return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY | diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 6264a342d7a..6ea1dccc40b 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -996,12 +996,6 @@ static const char *ha_maria_exts[]= }; -const char **ha_maria::bas_ext() const -{ - return ha_maria_exts; -} - - const char *ha_maria::index_type(uint key_number) { return ((table->key_info[key_number].flags & HA_FULLTEXT) ? @@ -3487,6 +3481,7 @@ static int ha_maria_init(void *p) maria_hton->db_type= DB_TYPE_UNKNOWN; maria_hton->create= maria_create_handler; maria_hton->panic= maria_hton_panic; + maria_hton->tablefile_extensions= ha_maria_exts; maria_hton->commit= maria_commit; maria_hton->rollback= maria_rollback; maria_hton->checkpoint_state= maria_checkpoint_state; diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index 6240895ee97..9dcac73158b 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -59,7 +59,6 @@ public: ~ha_maria() {} handler *clone(const char *name, MEM_ROOT *mem_root); const char *index_type(uint key_number); - const char **bas_ext() const; ulonglong table_flags() const { return int_table_flags; } ulong index_flags(uint inx, uint part, bool all_parts) const; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index c0221989891..e5fed8731dd 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -677,12 +677,6 @@ static const char *ha_myisam_exts[] = { NullS }; -const char **ha_myisam::bas_ext() const -{ - return ha_myisam_exts; -} - - const char *ha_myisam::index_type(uint key_number) { return ((table->key_info[key_number].flags & HA_FULLTEXT) ? @@ -2209,6 +2203,7 @@ static int myisam_init(void *p) myisam_hton->create= myisam_create_handler; myisam_hton->panic= myisam_panic; myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES; + myisam_hton->tablefile_extensions= ha_myisam_exts; mi_killed= mi_killed_in_mariadb; return 0; diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 11871479342..5589bd3e1e1 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -54,7 +54,6 @@ class ha_myisam: public handler ~ha_myisam() {} handler *clone(const char *name, MEM_ROOT *mem_root); const char *index_type(uint key_number); - const char **bas_ext() const; ulonglong table_flags() const { return int_table_flags; } int index_init(uint idx, bool sorted); int index_end(); diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 8cb74c5df44..5d9b5b5808b 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -171,12 +171,6 @@ extern "C" void myrg_print_wrong_table(const char *table_name) } -const char **ha_myisammrg::bas_ext() const -{ - return ha_myisammrg_exts; -} - - const char *ha_myisammrg::index_type(uint key_number) { return ((table->key_info[key_number].flags & HA_FULLTEXT) ? @@ -1724,6 +1718,7 @@ static int myisammrg_init(void *p) myisammrg_hton->create= myisammrg_create_handler; myisammrg_hton->panic= myisammrg_panic; myisammrg_hton->flags= HTON_NO_PARTITION; + myisammrg_hton->tablefile_extensions= ha_myisammrg_exts; return 0; } diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 8007e7d04e8..455819c5526 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -82,7 +82,6 @@ public: ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg); ~ha_myisammrg(); - const char **bas_ext() const; const char *index_type(uint key_number); ulonglong table_flags() const { diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index 0fb86cfe5cd..4bb90bcf652 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -196,15 +196,6 @@ ha_perfschema::ha_perfschema(handlerton *hton, TABLE_SHARE *share) ha_perfschema::~ha_perfschema() {} -static const char *ha_pfs_exts[]= { - NullS -}; - -const char **ha_perfschema::bas_ext() const -{ - return ha_pfs_exts; -} - int ha_perfschema::open(const char *name, int mode, uint test_if_locked) { DBUG_ENTER("ha_perfschema::open"); diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h index 35670339599..a21a3d13a16 100644 --- a/storage/perfschema/ha_perfschema.h +++ b/storage/perfschema/ha_perfschema.h @@ -44,8 +44,6 @@ public: const char *index_type(uint) { return ""; } - const char **bas_ext(void) const; - /** Capabilities of the performance schema tables. */ ulonglong table_flags(void) const { diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index 3305875c124..afb6cea0a40 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -2005,9 +2005,6 @@ int CSphSEQuery::BuildRequest ( char ** ppBuffer ) // SPHINX HANDLER ////////////////////////////////////////////////////////////////////////////// -static const char * ha_sphinx_exts[] = { NullS }; - - #if MYSQL_VERSION_ID<50100 ha_sphinx::ha_sphinx ( TABLE_ARG * table ) : handler ( &sphinx_hton, table ) @@ -2047,16 +2044,6 @@ ha_sphinx::~ha_sphinx() } } - -// If frm_error() is called then we will use this to to find out what file extentions -// exist for the storage engine. This is also used by the default rename_table and -// delete_table method in handler.cc. -const char ** ha_sphinx::bas_ext() const -{ - return ha_sphinx_exts; -} - - // Used for opening tables. The name will be the name of the file. // A table is opened when it needs to be opened. For instance // when a request comes in for a select on the table (tables are not diff --git a/storage/sphinx/ha_sphinx.h b/storage/sphinx/ha_sphinx.h index f2aa726791b..f650e1641da 100644 --- a/storage/sphinx/ha_sphinx.h +++ b/storage/sphinx/ha_sphinx.h @@ -57,7 +57,6 @@ public: const char * table_type () const { return "SPHINX"; } ///< SE name for display purposes const char * index_type ( uint ) { return "HASH"; } ///< index type name for display purposes - const char ** bas_ext () const; ///< my file extensions #if MYSQL_VERSION_ID>50100 ulonglong table_flags () const { return HA_CAN_INDEX_BLOBS | diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index dde5b8fd965..5ba58fe439b 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -2560,6 +2560,13 @@ skip_overwrite: } +/****************************************************************//** +Gives the file extension of an InnoDB single-table tablespace. */ +static const char* ha_innobase_exts[] = { + ".ibd", + NullS +}; + /*********************************************************************//** Opens an InnoDB database. @return 0 on success, error code on failure */ @@ -2608,6 +2615,7 @@ innobase_init( innobase_hton->release_temporary_latches=innobase_release_temporary_latches; innobase_hton->alter_table_flags = innobase_alter_table_flags; innobase_hton->kill_query = innobase_kill_query; + innobase_hton->tablefile_extensions = ha_innobase_exts; ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR); @@ -4032,13 +4040,6 @@ ha_innobase::table_flags() const return int_table_flags | HA_BINLOG_STMT_CAPABLE; } -/****************************************************************//** -Gives the file extension of an InnoDB single-table tablespace. */ -static const char* ha_innobase_exts[] = { - ".ibd", - NullS -}; - /****************************************************************//** Returns the index type. */ UNIV_INTERN @@ -4051,17 +4052,6 @@ ha_innobase::index_type( return("BTREE"); } -/****************************************************************//** -Returns the table file name extension. -@return file extension string */ -UNIV_INTERN -const char** -ha_innobase::bas_ext() const -/*========================*/ -{ - return(ha_innobase_exts); -} - /****************************************************************//** Returns the operations supported for indexes. @return flags of supported operations */ diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 607f9ecfb36..439be10fddb 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -125,7 +125,6 @@ class ha_innobase: public handler enum row_type get_row_type() const; const char* index_type(uint key_number); - const char** bas_ext() const; Table_flags table_flags() const; ulong index_flags(uint idx, uint part, bool all_parts) const; uint max_supported_keys() const; From 69ba585a1e8a0ea52c3bced2a40311d75009e5d0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 17:09:05 +0200 Subject: [PATCH 21/87] remove #if MYSQL_VERSION_ID there is no "upstream" OQGraph version that needs to stay compatible with different MariaDB releases. --- storage/oqgraph/ha_oqgraph.cc | 206 +++++++++------------------------- storage/oqgraph/ha_oqgraph.h | 1 - 2 files changed, 50 insertions(+), 157 deletions(-) diff --git a/storage/oqgraph/ha_oqgraph.cc b/storage/oqgraph/ha_oqgraph.cc index 0352fee8293..bab748937c2 100644 --- a/storage/oqgraph/ha_oqgraph.cc +++ b/storage/oqgraph/ha_oqgraph.cc @@ -61,54 +61,11 @@ static const char oqgraph_description[]= "Open Query Graph Computation Engine, stored in memory " "(http://openquery.com/graph)"; -#if MYSQL_VERSION_ID < 50100 -static bool oqgraph_init(); - -handlerton oqgraph_hton= { - "OQGRAPH", - SHOW_OPTION_YES, - oqgraph_description, - DB_TYPE_OQGRAPH, - oqgraph_init, - 0, /* slot */ - 0, /* savepoint size. */ - NULL, /* close_connection */ - NULL, /* savepoint */ - NULL, /* rollback to savepoint */ - NULL, /* release savepoint */ - NULL, /* commit */ - NULL, /* rollback */ - NULL, /* prepare */ - NULL, /* recover */ - NULL, /* commit_by_xid */ - NULL, /* rollback_by_xid */ - NULL, /* create_cursor_read_view */ - NULL, /* set_cursor_read_view */ - NULL, /* close_cursor_read_view */ - HTON_NO_FLAGS -}; - -#define STATISTIC_INCREMENT(X) \ -statistic_increment(table->in_use->status_var.X, &LOCK_status) -#define MOVE(X) move_field(X) -#define RECORDS records -#else -#define STATISTIC_INCREMENT(X) /* nothing */ -#define MOVE(X) move_field_offset(X) -#define RECORDS stats.records -#endif - static HASH oqgraph_open_tables; static pthread_mutex_t LOCK_oqgraph; static bool oqgraph_init_done= 0; -#if MYSQL_VERSION_ID >= 50130 -#define HASH_KEY_LENGTH size_t -#else -#define HASH_KEY_LENGTH uint -#endif - -static uchar* get_key(const uchar *ptr, HASH_KEY_LENGTH *length, +static uchar* get_key(const uchar *ptr, size_t *length, my_bool) { const OQGRAPH_INFO *share= (const OQGRAPH_INFO*) ptr; @@ -116,7 +73,6 @@ static uchar* get_key(const uchar *ptr, HASH_KEY_LENGTH *length, return (uchar*) share->name; } -#if MYSQL_VERSION_ID >= 50100 static handler* oqgraph_create_handler(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root) { @@ -125,12 +81,6 @@ static handler* oqgraph_create_handler(handlerton *hton, TABLE_SHARE *table, static int oqgraph_init(handlerton *hton) { -#else -static bool oqgraph_init() -{ - if (have_oqgraph == SHOW_OPTION_DISABLED) - return 1; -#endif if (pthread_mutex_init(&LOCK_oqgraph, MY_MUTEX_INIT_FAST)) goto error; if (my_hash_init(&oqgraph_open_tables, &my_charset_bin, 32, 0, 0, @@ -139,22 +89,16 @@ static bool oqgraph_init() pthread_mutex_destroy(&LOCK_oqgraph); goto error; } -#if MYSQL_VERSION_ID >= 50100 hton->state= SHOW_OPTION_YES; hton->db_type= DB_TYPE_AUTOASSIGN; hton->create= oqgraph_create_handler; hton->flags= HTON_NO_FLAGS; -#endif oqgraph_init_done= TRUE; return 0; error: -#if MYSQL_VERSION_ID < 50100 - have_oqgraph= SHOW_OPTION_DISABLED; -#endif return 1; } -#if MYSQL_VERSION_ID >= 50100 static int oqgraph_fini(void *) { my_hash_free(&oqgraph_open_tables); @@ -162,7 +106,6 @@ static int oqgraph_fini(void *) oqgraph_init_done= FALSE; return 0; } -#endif static OQGRAPH_INFO *get_share(const char *name, TABLE *table=0) { @@ -331,32 +274,13 @@ static int oqgraph_check_table_structure (TABLE *table_arg) ** OQGRAPH tables *****************************************************************************/ -#if MYSQL_VERSION_ID >= 50100 ha_oqgraph::ha_oqgraph(handlerton *hton, TABLE_SHARE *table_arg) : handler(hton, table_arg), -#else -ha_oqgraph::ha_oqgraph(TABLE *table_arg) - : handler(&oqgraph_hton, table_arg), -#endif share(0), graph(0), records_changed(0), key_stat_version(0) { } -static const char *ha_oqgraph_exts[] = -{ - NullS -}; - -const char **ha_oqgraph::bas_ext() const -{ - return ha_oqgraph_exts; -} - -#if MYSQL_VERSION_ID >= 50100 ulonglong ha_oqgraph::table_flags() const -#else -ulong ha_oqgraph::table_flags() const -#endif { return (HA_NO_BLOBS | HA_NULL_IN_KEY | HA_REC_NOT_IN_SEQ | HA_CAN_INSERT_DELAYED | @@ -439,18 +363,15 @@ int ha_oqgraph::write_row(byte * buf) { int res= oqgraph::MISC_FAIL; Field ** const field= table->field; - STATISTIC_INCREMENT(ha_write_count); -#if MYSQL_VERSION_ID >= 50100 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); -#endif my_ptrdiff_t ptrdiff= buf - table->record[0]; if (ptrdiff) { - field[1]->MOVE(ptrdiff); - field[2]->MOVE(ptrdiff); - field[3]->MOVE(ptrdiff); + field[1]->move_field_offset(ptrdiff); + field[2]->move_field_offset(ptrdiff); + field[3]->move_field_offset(ptrdiff); } if (!field[1]->is_null() && !field[2]->is_null()) @@ -473,13 +394,11 @@ int ha_oqgraph::write_row(byte * buf) if (ptrdiff) { - field[1]->MOVE(-ptrdiff); - field[2]->MOVE(-ptrdiff); - field[3]->MOVE(-ptrdiff); + field[1]->move_field_offset(-ptrdiff); + field[2]->move_field_offset(-ptrdiff); + field[3]->move_field_offset(-ptrdiff); } -#if MYSQL_VERSION_ID >= 50100 dbug_tmp_restore_column_map(table->read_set, old_map); -#endif if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records) { @@ -499,19 +418,16 @@ int ha_oqgraph::update_row(const byte * old, byte * buf) VertexID orig_id, dest_id; EdgeWeight weight= 1; Field **field= table->field; - STATISTIC_INCREMENT(ha_update_count); -#if MYSQL_VERSION_ID >= 50100 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); -#endif my_ptrdiff_t ptrdiff= buf - table->record[0]; if (ptrdiff) { - field[0]->MOVE(ptrdiff); - field[1]->MOVE(ptrdiff); - field[2]->MOVE(ptrdiff); - field[3]->MOVE(ptrdiff); + field[0]->move_field_offset(ptrdiff); + field[1]->move_field_offset(ptrdiff); + field[2]->move_field_offset(ptrdiff); + field[3]->move_field_offset(ptrdiff); } if (inited == INDEX || inited == RND) @@ -527,10 +443,10 @@ int ha_oqgraph::update_row(const byte * old, byte * buf) my_ptrdiff_t ptrdiff2= old - buf; - field[0]->MOVE(ptrdiff2); - field[1]->MOVE(ptrdiff2); - field[2]->MOVE(ptrdiff2); - field[3]->MOVE(ptrdiff2); + field[0]->move_field_offset(ptrdiff2); + field[1]->move_field_offset(ptrdiff2); + field[2]->move_field_offset(ptrdiff2); + field[3]->move_field_offset(ptrdiff2); if (field[0]->is_null()) { @@ -551,22 +467,20 @@ int ha_oqgraph::update_row(const byte * old, byte * buf) res= oqgraph::OK; } - field[0]->MOVE(-ptrdiff2); - field[1]->MOVE(-ptrdiff2); - field[2]->MOVE(-ptrdiff2); - field[3]->MOVE(-ptrdiff2); + field[0]->move_field_offset(-ptrdiff2); + field[1]->move_field_offset(-ptrdiff2); + field[2]->move_field_offset(-ptrdiff2); + field[3]->move_field_offset(-ptrdiff2); } if (ptrdiff) { - field[0]->MOVE(-ptrdiff); - field[1]->MOVE(-ptrdiff); - field[2]->MOVE(-ptrdiff); - field[3]->MOVE(-ptrdiff); + field[0]->move_field_offset(-ptrdiff); + field[1]->move_field_offset(-ptrdiff); + field[2]->move_field_offset(-ptrdiff); + field[3]->move_field_offset(-ptrdiff); } -#if MYSQL_VERSION_ID >= 50100 dbug_tmp_restore_column_map(table->read_set, old_map); -#endif if (!res && records_changed*OQGRAPH_STATS_UPDATE_THRESHOLD > share->records) { @@ -583,7 +497,6 @@ int ha_oqgraph::delete_row(const byte * buf) { int res= oqgraph::EDGE_NOT_FOUND; Field **field= table->field; - STATISTIC_INCREMENT(ha_delete_count); if (inited == INDEX || inited == RND) { @@ -595,16 +508,14 @@ int ha_oqgraph::delete_row(const byte * buf) } if (res != oqgraph::OK) { -#if MYSQL_VERSION_ID >= 50100 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); -#endif my_ptrdiff_t ptrdiff= buf - table->record[0]; if (ptrdiff) { - field[0]->MOVE(ptrdiff); - field[1]->MOVE(ptrdiff); - field[2]->MOVE(ptrdiff); + field[0]->move_field_offset(ptrdiff); + field[1]->move_field_offset(ptrdiff); + field[2]->move_field_offset(ptrdiff); } if (field[0]->is_null() && !field[1]->is_null() && !field[2]->is_null()) @@ -621,13 +532,11 @@ int ha_oqgraph::delete_row(const byte * buf) if (ptrdiff) { - field[0]->MOVE(-ptrdiff); - field[1]->MOVE(-ptrdiff); - field[2]->MOVE(-ptrdiff); + field[0]->move_field_offset(-ptrdiff); + field[1]->move_field_offset(-ptrdiff); + field[2]->move_field_offset(-ptrdiff); } -#if MYSQL_VERSION_ID >= 50100 dbug_tmp_restore_column_map(table->read_set, old_map); -#endif } if (!res && table->s->tmp_table == NO_TMP_TABLE && @@ -654,7 +563,6 @@ int ha_oqgraph::index_next_same(byte *buf, const byte *key, uint key_len) int res; open_query::row row; DBUG_ASSERT(inited==INDEX); - STATISTIC_INCREMENT(ha_read_key_count); if (!(res= graph->fetch_row(row))) res= fill_record(buf, row); table->status= res ? STATUS_NOT_FOUND : 0; @@ -672,21 +580,18 @@ int ha_oqgraph::index_read_idx(byte * buf, uint index, const byte * key, VertexID *orig_idp=0, *dest_idp=0; int *latchp=0; open_query::row row; - STATISTIC_INCREMENT(ha_read_key_count); bmove_align(buf, table->s->default_values, table->s->reclength); key_restore(buf, (byte*) key, key_info, key_len); -#if MYSQL_VERSION_ID >= 50100 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set); -#endif my_ptrdiff_t ptrdiff= buf - table->record[0]; if (ptrdiff) { - field[0]->MOVE(ptrdiff); - field[1]->MOVE(ptrdiff); - field[2]->MOVE(ptrdiff); + field[0]->move_field_offset(ptrdiff); + field[1]->move_field_offset(ptrdiff); + field[2]->move_field_offset(ptrdiff); } if (!field[0]->is_null()) @@ -709,13 +614,11 @@ int ha_oqgraph::index_read_idx(byte * buf, uint index, const byte * key, if (ptrdiff) { - field[0]->MOVE(-ptrdiff); - field[1]->MOVE(-ptrdiff); - field[2]->MOVE(-ptrdiff); + field[0]->move_field_offset(-ptrdiff); + field[1]->move_field_offset(-ptrdiff); + field[2]->move_field_offset(-ptrdiff); } -#if MYSQL_VERSION_ID >= 50100 dbug_tmp_restore_column_map(table->read_set, old_map); -#endif res= graph->search(latchp, orig_idp, dest_idp); @@ -731,19 +634,17 @@ int ha_oqgraph::fill_record(byte *record, const open_query::row &row) bmove_align(record, table->s->default_values, table->s->reclength); -#if MYSQL_VERSION_ID >= 50100 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); -#endif my_ptrdiff_t ptrdiff= record - table->record[0]; if (ptrdiff) { - field[0]->MOVE(ptrdiff); - field[1]->MOVE(ptrdiff); - field[2]->MOVE(ptrdiff); - field[3]->MOVE(ptrdiff); - field[4]->MOVE(ptrdiff); - field[5]->MOVE(ptrdiff); + field[0]->move_field_offset(ptrdiff); + field[1]->move_field_offset(ptrdiff); + field[2]->move_field_offset(ptrdiff); + field[3]->move_field_offset(ptrdiff); + field[4]->move_field_offset(ptrdiff); + field[5]->move_field_offset(ptrdiff); } // just each field specifically, no sense iterating @@ -785,16 +686,14 @@ int ha_oqgraph::fill_record(byte *record, const open_query::row &row) if (ptrdiff) { - field[0]->MOVE(-ptrdiff); - field[1]->MOVE(-ptrdiff); - field[2]->MOVE(-ptrdiff); - field[3]->MOVE(-ptrdiff); - field[4]->MOVE(-ptrdiff); - field[5]->MOVE(-ptrdiff); + field[0]->move_field_offset(-ptrdiff); + field[1]->move_field_offset(-ptrdiff); + field[2]->move_field_offset(-ptrdiff); + field[3]->move_field_offset(-ptrdiff); + field[4]->move_field_offset(-ptrdiff); + field[5]->move_field_offset(-ptrdiff); } -#if MYSQL_VERSION_ID >= 50100 dbug_tmp_restore_column_map(table->write_set, old_map); -#endif return 0; } @@ -808,7 +707,6 @@ int ha_oqgraph::rnd_next(byte *buf) { int res; open_query::row row; - STATISTIC_INCREMENT(ha_read_rnd_next_count); if (!(res= graph->fetch_row(row))) res= fill_record(buf, row); table->status= res ? STATUS_NOT_FOUND: 0; @@ -819,7 +717,6 @@ int ha_oqgraph::rnd_pos(byte * buf, byte *pos) { int res; open_query::row row; - STATISTIC_INCREMENT(ha_read_rnd_count); if (!(res= graph->fetch_row(row, pos))) res= fill_record(buf, row); table->status=res ? STATUS_NOT_FOUND: 0; @@ -838,7 +735,7 @@ int ha_oqgraph::cmp_ref(const byte *ref1, const byte *ref2) int ha_oqgraph::info(uint flag) { - RECORDS= graph->vertices_count() + graph->edges_count(); + stats.records= graph->vertices_count() + graph->edges_count(); #if 0 records= hp_info.records; deleted= hp_info.deleted; @@ -976,8 +873,8 @@ ha_rows ha_oqgraph::records_in_range(uint inx, key_range *min_key, return HA_POS_ERROR; // Can only use exact keys } - if (RECORDS <= 1) - return RECORDS; + if (stats.records <= 1) + return stats.records; /* Assert that info() did run. We need current statistics here. */ DBUG_ASSERT(key_stat_version == share->key_stat_version); @@ -1018,7 +915,6 @@ void ha_oqgraph::update_create_info(HA_CREATE_INFO *create_info) // create_info->auto_increment_value= auto_increment_value; } -#if MYSQL_VERSION_ID >= 50100 struct st_mysql_storage_engine oqgraph_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; @@ -1041,5 +937,3 @@ maria_declare_plugin(oqgraph) maria_declare_plugin_end; #endif - -#endif diff --git a/storage/oqgraph/ha_oqgraph.h b/storage/oqgraph/ha_oqgraph.h index ee88e38c526..9f55fb233d8 100644 --- a/storage/oqgraph/ha_oqgraph.h +++ b/storage/oqgraph/ha_oqgraph.h @@ -68,7 +68,6 @@ public: } /* Rows also use a fixed-size format */ enum row_type get_row_type() const { return ROW_TYPE_FIXED; } - const char **bas_ext() const; ulong index_flags(uint inx, uint part, bool all_parts) const; uint max_supported_keys() const { return MAX_KEY; } uint max_supported_key_part_length() const { return MAX_KEY_LENGTH; } From 8980e67693c8f011200bc3924f5a8fc914aecc51 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 17:11:19 +0200 Subject: [PATCH 22/87] * use Dynamic_array<> instead of List<> for the list of found tables in sql_show.cc * make find_files static --- sql/sql_array.h | 5 ++++ sql/sql_show.cc | 68 ++++++++++++++++++++++++++----------------------- sql/sql_show.h | 9 ------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/sql/sql_array.h b/sql/sql_array.h index f07126bc0ef..f788b71a785 100644 --- a/sql/sql_array.h +++ b/sql/sql_array.h @@ -124,6 +124,11 @@ public: return (insert_dynamic(&array, (uchar*)&el)); } + bool append_val(Elem el) + { + return (insert_dynamic(&array, (uchar*)&el)); + } + int elements() { return array.elements; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c251678f42c..200ab98cd3e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -687,6 +687,11 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL; } +enum find_files_result { + FIND_FILES_OK, + FIND_FILES_OOM, + FIND_FILES_DIR +}; /* find_files() - find files in a given directory. @@ -708,8 +713,8 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) */ -find_files_result -find_files(THD *thd, List *files, const char *db, +static find_files_result +find_files(THD *thd, Dynamic_array *files, const char *db, const char *path, const char *wild, bool dir) { uint i; @@ -739,9 +744,9 @@ find_files(THD *thd, List *files, const char *db, MY_THREAD_SPECIFIC)))) { if (my_errno == ENOENT) - my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db); + my_error(ER_BAD_DB_ERROR, MYF(ME_BELL | ME_WAITTANG), db); else - my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno); + my_error(ER_CANT_READ_DIR, MYF(ME_BELL | ME_WAITTANG), path, my_errno); DBUG_RETURN(FIND_FILES_DIR); } @@ -824,13 +829,13 @@ find_files(THD *thd, List *files, const char *db, } #endif if (!(file_name= thd->make_lex_string(uname, file_name_len)) || - files->push_back(file_name)) + files->append(file_name)) { my_dirend(dirp); DBUG_RETURN(FIND_FILES_OOM); } } - DBUG_PRINT("info",("found: %d files", files->elements)); + DBUG_PRINT("info",("found: %d files", files->elements())); my_dirend(dirp); DBUG_RETURN(FIND_FILES_OK); @@ -3697,7 +3702,7 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) non-zero error */ -int make_db_list(THD *thd, List *files, +int make_db_list(THD *thd, Dynamic_array *files, LOOKUP_FIELD_VALUES *lookup_field_vals, bool *with_i_schema) { @@ -3718,7 +3723,7 @@ int make_db_list(THD *thd, List *files, lookup_field_vals->db_value.str)) { *with_i_schema= 1; - if (files->push_back(i_s_name_copy)) + if (files->append(i_s_name_copy)) return 1; } return (find_files(thd, files, NullS, mysql_data_home, @@ -3739,11 +3744,11 @@ int make_db_list(THD *thd, List *files, lookup_field_vals->db_value.length)) { *with_i_schema= 1; - if (files->push_back(i_s_name_copy)) + if (files->append(i_s_name_copy)) return 1; return 0; } - if (files->push_back(&lookup_field_vals->db_value)) + if (files->append_val(&lookup_field_vals->db_value)) return 1; return 0; } @@ -3752,7 +3757,7 @@ int make_db_list(THD *thd, List *files, Create list of existing databases. It is used in case of select from information schema table */ - if (files->push_back(i_s_name_copy)) + if (files->append(i_s_name_copy)) return 1; *with_i_schema= 1; return (find_files(thd, files, NullS, @@ -3762,7 +3767,7 @@ int make_db_list(THD *thd, List *files, struct st_add_schema_table { - List *files; + Dynamic_array *files; const char *wild; }; @@ -3772,7 +3777,7 @@ static my_bool add_schema_table(THD *thd, plugin_ref plugin, { LEX_STRING *file_name= 0; st_add_schema_table *data= (st_add_schema_table *)p_data; - List *file_list= data->files; + Dynamic_array *file_list= data->files; const char *wild= data->wild; ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *); DBUG_ENTER("add_schema_table"); @@ -3794,13 +3799,14 @@ static my_bool add_schema_table(THD *thd, plugin_ref plugin, if ((file_name= thd->make_lex_string(schema_table->table_name, strlen(schema_table->table_name))) && - !file_list->push_back(file_name)) + !file_list->append(file_name)) DBUG_RETURN(0); DBUG_RETURN(1); } -int schema_tables_add(THD *thd, List *files, const char *wild) +int schema_tables_add(THD *thd, Dynamic_array *files, + const char *wild) { LEX_STRING *file_name= 0; ST_SCHEMA_TABLE *tmp_schema_table= schema_tables; @@ -3826,7 +3832,7 @@ int schema_tables_add(THD *thd, List *files, const char *wild) if ((file_name= thd->make_lex_string(tmp_schema_table->table_name, strlen(tmp_schema_table->table_name))) && - !files->push_back(file_name)) + !files->append(file_name)) continue; DBUG_RETURN(1); } @@ -3861,8 +3867,8 @@ int schema_tables_add(THD *thd, List *files, const char *wild) */ static int -make_table_name_list(THD *thd, List *table_names, LEX *lex, - LOOKUP_FIELD_VALUES *lookup_field_vals, +make_table_name_list(THD *thd, Dynamic_array *table_names, + LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals, bool with_i_schema, LEX_STRING *db_name) { char path[FN_REFLEN + 1]; @@ -3879,13 +3885,13 @@ make_table_name_list(THD *thd, List *table_names, LEX *lex, { if (!(name= thd->make_lex_string(schema_table->table_name, strlen(schema_table->table_name))) || - table_names->push_back(name)) + table_names->append(name)) return 1; } } else { - if (table_names->push_back(&lookup_field_vals->table_value)) + if (table_names->append_val(&lookup_field_vals->table_value)) return 1; } return 0; @@ -4544,11 +4550,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; LOOKUP_FIELD_VALUES lookup_field_vals; - LEX_STRING *db_name, *table_name; + LEX_STRING *db_name; bool with_i_schema; enum enum_schema_tables schema_table_idx; - List db_names; - List_iterator_fast it(db_names); + Dynamic_array db_names; COND *partial_cond= 0; int error= 1; Open_tables_backup open_tables_state_backup; @@ -4652,9 +4657,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema)) goto err; - it.rewind(); /* To get access to new elements in basis list */ - while ((db_name= it++)) + for (int i=0; i < db_names.elements(); i++) { + db_name= db_names.at(i); #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(check_access(thd, SELECT_ACL, db_name->str, &thd->col_access, NULL, 0, 1) || @@ -4663,7 +4668,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0)) #endif { - List table_names; + Dynamic_array table_names; int res= make_table_name_list(thd, &table_names, lex, &lookup_field_vals, with_i_schema, db_name); @@ -4672,9 +4677,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (res) goto err; - List_iterator_fast it_files(table_names); - while ((table_name= it_files++)) + for (int i=0; i < table_names.elements(); i++) { + LEX_STRING *table_name= table_names.at(i); restore_record(table, s->default_values); table->field[schema_table->idx_field1]-> store(db_name->str, db_name->length, system_charset_info); @@ -4779,8 +4784,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) */ LOOKUP_FIELD_VALUES lookup_field_vals; - List db_names; - LEX_STRING *db_name; + Dynamic_array db_names; bool with_i_schema; HA_CREATE_INFO create; TABLE *table= tables->table; @@ -4816,9 +4820,9 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(0); } - List_iterator_fast it(db_names); - while ((db_name=it++)) + for (int i=0; i < db_names.elements(); i++) { + LEX_STRING *db_name= db_names.at(i); if (with_i_schema) // information schema name is always first in list { if (store_schema_shemata(thd, table, db_name, diff --git a/sql/sql_show.h b/sql/sql_show.h index 09e0a80fd4f..ec4d6a2b7c9 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -34,12 +34,6 @@ typedef struct st_schema_table ST_SCHEMA_TABLE; struct TABLE; typedef struct system_status_var STATUS_VAR; -enum find_files_result { - FIND_FILES_OK, - FIND_FILES_OOM, - FIND_FILES_DIR -}; - /* Used by handlers to store things in schema tables */ #define IS_FILES_FILE_ID 0 #define IS_FILES_FILE_NAME 1 @@ -80,9 +74,6 @@ enum find_files_result { #define IS_FILES_STATUS 36 #define IS_FILES_EXTRA 37 -find_files_result find_files(THD *thd, List *files, const char *db, - const char *path, const char *wild, bool dir); - int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, HA_CREATE_INFO *create_info_arg, bool show_database); int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff); From 2a9662b401405ee8f8f0849f7f90faac1081e26e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Apr 2013 17:17:25 +0200 Subject: [PATCH 23/87] find_files(): don't sort files in my_dir(), sort table names after all engines have discovered their tables side effect: correct alphabetical sorting as in ORDER BY ... COLLATE utf8_bin, information_schema is no longer the first after find_files(), tables like #mysql50#zzz are sorted first (as per table name), not last (as per file name zzz). --- mysql-test/r/drop.result | 2 +- mysql-test/r/mysqlcheck.result | 4 +- mysql-test/r/mysqlslap.result | 2 +- mysql-test/r/schema.result | 2 +- mysql-test/r/upgrade.result | 4 +- .../suite/jp/r/jp_create_db_sjis.result | 6 +- .../suite/jp/r/jp_create_db_ucs2.result | 6 +- .../suite/jp/r/jp_create_db_ujis.result | 6 +- .../suite/jp/r/jp_create_db_utf8.result | 6 +- .../sys_vars/r/ignore_db_dirs_basic.result | 4 +- sql/sql_show.cc | 72 ++++++++----------- 11 files changed, 50 insertions(+), 64 deletions(-) diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index db3aa770499..55309e54fb3 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -142,9 +142,9 @@ create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ERROR 42000: Incorrect table name '#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12345' show tables; Tables_in_mysqltestbug26703 +#mysql50#abc`def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1234 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -#mysql50#abc`def use test; drop database mysqltestbug26703; End of 5.1 tests diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 034913a72e6..14ade969b25 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -176,15 +176,15 @@ t1 v1 show tables; Tables_in_test -t1 #mysql50#v-1 +t1 v1 test.t1 OK show tables; Tables_in_test t1 -v1 v-1 +v1 drop view v1, `v-1`; drop table t1; SET NAMES utf8; diff --git a/mysql-test/r/mysqlslap.result b/mysql-test/r/mysqlslap.result index 069c9182de2..38a7b0a694e 100644 --- a/mysql-test/r/mysqlslap.result +++ b/mysql-test/r/mysqlslap.result @@ -234,8 +234,8 @@ test # 'bug58090' database should be present. SHOW DATABASES; Database -information_schema bug58090 +information_schema mtr mysql performance_schema diff --git a/mysql-test/r/schema.result b/mysql-test/r/schema.result index 809d652053e..bb6dbd65f84 100644 --- a/mysql-test/r/schema.result +++ b/mysql-test/r/schema.result @@ -5,8 +5,8 @@ Database Create Database foo CREATE DATABASE `foo` /*!40100 DEFAULT CHARACTER SET latin1 */ show schemas; Database -information_schema foo +information_schema mtr mysql performance_schema diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index ec63cc0d98c..4f52fd1e246 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -33,12 +33,12 @@ show create database `#mysql50#mysqltest-1`; ERROR 42000: Unknown database '#mysql50#mysqltest-1' show tables in `mysqltest1`; Tables_in_mysqltest1 -t1 t-1 +t1 show tables in `mysqltest-1`; Tables_in_mysqltest-1 -t1 t-1 +t1 drop database `mysqltest1`; drop database `mysqltest-1`; drop table if exists `txu@0023p@0023p1`; diff --git a/mysql-test/suite/jp/r/jp_create_db_sjis.result b/mysql-test/suite/jp/r/jp_create_db_sjis.result index b7c09fbfbe9..93524e1c443 100644 --- a/mysql-test/suite/jp/r/jp_create_db_sjis.result +++ b/mysql-test/suite/jp/r/jp_create_db_sjis.result @@ -9,12 +9,12 @@ CREATE DATABASE ` SELECT schema_name from information_schema.schemata where schema_name <> 'mtr'; schema_name information_schema -ƒ\\•\ -“ú–{Œê -ÆÎÝºÞ mysql performance_schema test +ƒ\\•\ +“ú–{Œê +ÆÎÝºÞ USE `ÆÎݺÞ`; USE `“ú–{Œê`; USE `ƒ\\•\`; diff --git a/mysql-test/suite/jp/r/jp_create_db_ucs2.result b/mysql-test/suite/jp/r/jp_create_db_ucs2.result index 3832ff5a0c7..c6a2ff78b4f 100644 --- a/mysql-test/suite/jp/r/jp_create_db_ucs2.result +++ b/mysql-test/suite/jp/r/jp_create_db_ucs2.result @@ -10,12 +10,12 @@ CREATE DATABASE ` SELECT schema_name from information_schema.schemata where schema_name <> 'mtr'; schema_name information_schema -ÆüËܸì -íÜíÝíÞ -ŽÆŽÎŽÝŽºŽÞ mysql performance_schema test +ÆüËܸì +íÜíÝíÞ +ŽÆŽÎŽÝŽºŽÞ USE `ŽÆŽÎŽÝŽºŽÞ`; USE `ÆüËܸì`; USE `íÜíÝíÞ`; diff --git a/mysql-test/suite/jp/r/jp_create_db_ujis.result b/mysql-test/suite/jp/r/jp_create_db_ujis.result index d6bf31336fd..e5e0c2f1ad8 100644 --- a/mysql-test/suite/jp/r/jp_create_db_ujis.result +++ b/mysql-test/suite/jp/r/jp_create_db_ujis.result @@ -9,12 +9,12 @@ CREATE DATABASE ` SELECT schema_name from information_schema.schemata where schema_name <> 'mtr'; schema_name information_schema -ÆüËܸì -íÜíÝíÞ -ŽÆŽÎŽÝŽºŽÞ mysql performance_schema test +ÆüËܸì +íÜíÝíÞ +ŽÆŽÎŽÝŽºŽÞ USE `ŽÆŽÎŽÝŽºŽÞ`; USE `ÆüËܸì`; USE `íÜíÝíÞ`; diff --git a/mysql-test/suite/jp/r/jp_create_db_utf8.result b/mysql-test/suite/jp/r/jp_create_db_utf8.result index 62202d43df0..f07a36fd7c7 100644 --- a/mysql-test/suite/jp/r/jp_create_db_utf8.result +++ b/mysql-test/suite/jp/r/jp_create_db_utf8.result @@ -9,12 +9,12 @@ CREATE DATABASE `龔龖龗`; SELECT schema_name from information_schema.schemata where schema_name <> 'mtr'; schema_name information_schema -日本語 -龔龖龗 -ニホï¾ï½ºï¾ž mysql performance_schema test +日本語 +龔龖龗 +ニホï¾ï½ºï¾ž USE `ニホï¾ï½ºï¾ž`; USE `日本語`; USE `龔龖龗`; diff --git a/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result b/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result index 55d61800a39..5802c71d280 100644 --- a/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result +++ b/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result @@ -6,8 +6,8 @@ e,lost+found,.mysqlgui,ignored_db # with '.' SHOW DATABASES; Database -information_schema #mysql50#.otherdir +information_schema mtr mysql performance_schema @@ -33,8 +33,8 @@ id 2 SHOW DATABASES; Database -information_schema #mysql50#.otherdir +information_schema lost+found mtr mysql diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 200ab98cd3e..92be469becc 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -687,6 +687,15 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL; } +extern "C" { +static int cmp_table_names(LEX_STRING * const *a, LEX_STRING * const *b) +{ + return my_strnncoll(&my_charset_bin, + (const uchar*)((*a)->str), (*a)->length, + (const uchar*)((*b)->str), (*b)->length); +} +} + enum find_files_result { FIND_FILES_OK, FIND_FILES_OOM, @@ -740,7 +749,7 @@ find_files(THD *thd, Dynamic_array *files, const char *db, bzero((char*) &table_list,sizeof(table_list)); - if (!(dirp = my_dir(path, MYF((dir ? MY_WANT_STAT : 0) | MY_WANT_SORT | + if (!(dirp = my_dir(path, MYF((dir ? MY_WANT_STAT : 0) | MY_THREAD_SPECIFIC)))) { if (my_errno == ENOENT) @@ -838,6 +847,8 @@ find_files(THD *thd, Dynamic_array *files, const char *db, DBUG_PRINT("info",("found: %d files", files->elements())); my_dirend(dirp); + files->sort(cmp_table_names); + DBUG_RETURN(FIND_FILES_OK); } @@ -3694,8 +3705,6 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) wild wild string idx_field_vals idx_field_vals->db_name contains db name or wild string - with_i_schema returns 1 if we added 'IS' name to list - otherwise returns 0 RETURN zero success @@ -3703,13 +3712,8 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) */ int make_db_list(THD *thd, Dynamic_array *files, - LOOKUP_FIELD_VALUES *lookup_field_vals, - bool *with_i_schema) + LOOKUP_FIELD_VALUES *lookup_field_vals) { - LEX_STRING *i_s_name_copy= 0; - i_s_name_copy= thd->make_lex_string(INFORMATION_SCHEMA_NAME.str, - INFORMATION_SCHEMA_NAME.length); - *with_i_schema= 0; if (lookup_field_vals->wild_db_value) { /* @@ -3722,8 +3726,7 @@ int make_db_list(THD *thd, Dynamic_array *files, INFORMATION_SCHEMA_NAME.str, lookup_field_vals->db_value.str)) { - *with_i_schema= 1; - if (files->append(i_s_name_copy)) + if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; } return (find_files(thd, files, NullS, mysql_data_home, @@ -3743,8 +3746,7 @@ int make_db_list(THD *thd, Dynamic_array *files, if (is_infoschema_db(lookup_field_vals->db_value.str, lookup_field_vals->db_value.length)) { - *with_i_schema= 1; - if (files->append(i_s_name_copy)) + if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; return 0; } @@ -3757,9 +3759,8 @@ int make_db_list(THD *thd, Dynamic_array *files, Create list of existing databases. It is used in case of select from information schema table */ - if (files->append(i_s_name_copy)) + if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; - *with_i_schema= 1; return (find_files(thd, files, NullS, mysql_data_home, NullS, 1) != FIND_FILES_OK); } @@ -3857,7 +3858,6 @@ int schema_tables_add(THD *thd, Dynamic_array *files, @param[in] table_names List of table names in database @param[in] lex pointer to LEX struct @param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct - @param[in] with_i_schema TRUE means that we add I_S tables to list @param[in] db_name database name @return Operation status @@ -3869,14 +3869,14 @@ int schema_tables_add(THD *thd, Dynamic_array *files, static int make_table_name_list(THD *thd, Dynamic_array *table_names, LEX *lex, LOOKUP_FIELD_VALUES *lookup_field_vals, - bool with_i_schema, LEX_STRING *db_name) + LEX_STRING *db_name) { char path[FN_REFLEN + 1]; build_table_filename(path, sizeof(path) - 1, db_name->str, "", "", 0); if (!lookup_field_vals->wild_table_value && lookup_field_vals->table_value.str) { - if (with_i_schema) + if (db_name == &INFORMATION_SCHEMA_NAME) { LEX_STRING *name; ST_SCHEMA_TABLE *schema_table= @@ -3901,7 +3901,7 @@ make_table_name_list(THD *thd, Dynamic_array *table_names, This call will add all matching the wildcards (if specified) IS tables to the list */ - if (with_i_schema) + if (db_name == &INFORMATION_SCHEMA_NAME) return (schema_tables_add(thd, table_names, lookup_field_vals->table_value.str)); @@ -4129,7 +4129,6 @@ end: @param[in] table TABLE struct for I_S table @param[in] db_name database name @param[in] table_name table name - @param[in] with_i_schema I_S table if TRUE @return Operation status @retval 0 success @@ -4137,11 +4136,10 @@ end: */ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, - LEX_STRING *db_name, LEX_STRING *table_name, - bool with_i_schema) + LEX_STRING *db_name, LEX_STRING *table_name) { TABLE *table= tables->table; - if (with_i_schema) + if (db_name == &INFORMATION_SCHEMA_NAME) { table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), system_charset_info); @@ -4550,8 +4548,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; LOOKUP_FIELD_VALUES lookup_field_vals; - LEX_STRING *db_name; - bool with_i_schema; enum enum_schema_tables schema_table_idx; Dynamic_array db_names; COND *partial_cond= 0; @@ -4655,11 +4651,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } - if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema)) + if (make_db_list(thd, &db_names, &lookup_field_vals)) goto err; for (int i=0; i < db_names.elements(); i++) { - db_name= db_names.at(i); + LEX_STRING *db_name= db_names.at(i); #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(check_access(thd, SELECT_ACL, db_name->str, &thd->col_access, NULL, 0, 1) || @@ -4670,8 +4666,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { Dynamic_array table_names; int res= make_table_name_list(thd, &table_names, lex, - &lookup_field_vals, - with_i_schema, db_name); + &lookup_field_vals, db_name); if (res == 2) /* Not fatal error, continue */ continue; if (res) @@ -4707,14 +4702,13 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) /* SHOW TABLE NAMES command */ if (schema_table_idx == SCH_TABLE_NAMES) { - if (fill_schema_table_names(thd, tables, db_name, - table_name, with_i_schema)) + if (fill_schema_table_names(thd, tables, db_name, table_name)) continue; } else { if (!(table_open_method & ~OPEN_FRM_ONLY) && - !with_i_schema) + db_name != &INFORMATION_SCHEMA_NAME) { /* Here we need to filter out warnings, which can happen @@ -4748,11 +4742,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) } } } - /* - If we have information schema its always the first table and only - the first table. Reset for other tables. - */ - with_i_schema= 0; } } @@ -4785,7 +4774,6 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) LOOKUP_FIELD_VALUES lookup_field_vals; Dynamic_array db_names; - bool with_i_schema; HA_CREATE_INFO create; TABLE *table= tables->table; #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -4798,15 +4786,14 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_PRINT("INDEX VALUES",("db_name: %s table_name: %s", lookup_field_vals.db_value.str, lookup_field_vals.table_value.str)); - if (make_db_list(thd, &db_names, &lookup_field_vals, - &with_i_schema)) + if (make_db_list(thd, &db_names, &lookup_field_vals)) DBUG_RETURN(1); /* If we have lookup db value we should check that the database exists */ if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value && - !with_i_schema) + db_names.at(0) != &INFORMATION_SCHEMA_NAME) { char path[FN_REFLEN+16]; uint path_len; @@ -4823,12 +4810,11 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) for (int i=0; i < db_names.elements(); i++) { LEX_STRING *db_name= db_names.at(i); - if (with_i_schema) // information schema name is always first in list + if (db_name == &INFORMATION_SCHEMA_NAME) { if (store_schema_shemata(thd, table, db_name, system_charset_info)) DBUG_RETURN(1); - with_i_schema= 0; continue; } #ifndef NO_EMBEDDED_ACCESS_CHECKS From 03dfb2c1210f75e234b5571a40a9aa92cb1afa45 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:31:29 +0200 Subject: [PATCH 24/87] file-based table discovery for discovering storage engines also: * move few tests from archive/archive.test to archive/discover.test * fix (unintentionally) bug#34104, updated result files --- mysql-test/r/grant4.result | 2 +- mysql-test/suite/archive/archive.result | 32 ---- mysql-test/suite/archive/archive.test | 28 ---- mysql-test/suite/archive/discover.result | 70 ++++++++ mysql-test/suite/archive/discover.test | 56 +++++++ mysql-test/t/grant4.test | 4 +- sql/discover.cc | 124 ++++++++++++++ sql/discover.h | 8 + sql/handler.cc | 69 +++++++- sql/handler.h | 74 +++++++-- sql/sql_show.cc | 197 ++++++++++++----------- storage/archive/ha_archive.cc | 1 - 12 files changed, 483 insertions(+), 182 deletions(-) create mode 100644 mysql-test/suite/archive/discover.result create mode 100644 mysql-test/suite/archive/discover.test diff --git a/mysql-test/r/grant4.result b/mysql-test/r/grant4.result index d0b6627cd0b..65ab92c1afd 100644 --- a/mysql-test/r/grant4.result +++ b/mysql-test/r/grant4.result @@ -86,9 +86,9 @@ GRANT SHOW VIEW, SELECT ON v3 to mysqltest_u1@localhost; use mysqltest_db1; ** Connect as restricted user mysqltest_u1. ** SELECT FROM INFORMATION_SCHEMA.STATISTICS will succeed because any privileges will do (authentication is enough). +** but will return no rows SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='t5'; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT -def mysqltest_db1 t5 1 mysqltest_db1 i 1 s1 A NULL NULL NULL YES BTREE ** SHOW INDEX FROM t5 will fail because we don't have any privileges on any column combination. SHOW INDEX FROM t5; ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't5' diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 98608a95f37..618433fe5e0 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12785,38 +12785,6 @@ a 2 DROP TABLE t1; # -# Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE -# -DROP TABLE IF EXISTS t1; -CREATE TABLE t1 (a int) ENGINE=ARCHIVE; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 -INSERT INTO t1 VALUES (1); -OPTIMIZE TABLE t1; -Table Op Msg_type Msg_text -test.t1 optimize status OK -FLUSH TABLES; -INSERT INTO t1 VALUES (2); -SELECT * FROM t1 ORDER BY a; -a -1 -2 -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 -DROP TABLE t1; -# -# BUG#58205 - Valgrind failure in fn_format when called from -# archive_discover -# -CREATE TABLE `a/../`(a INT) ENGINE=ARCHIVE; -DROP TABLE `a/../`; -# # BUG#57162 - valgrind errors, random data when returning # ordered data from archive tables # diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 5bcefa3dcd5..92868158ed4 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1711,34 +1711,6 @@ REPAIR TABLE t1 EXTENDED; SELECT * FROM t1; DROP TABLE t1; ---echo # ---echo # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE ---echo # - ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - -CREATE TABLE t1 (a int) ENGINE=ARCHIVE; -SHOW CREATE TABLE t1; -INSERT INTO t1 VALUES (1); -OPTIMIZE TABLE t1; -let $MYSQLD_DATADIR= `select @@datadir`; -remove_file $MYSQLD_DATADIR/test/t1.frm; -FLUSH TABLES; -INSERT INTO t1 VALUES (2); -SELECT * FROM t1 ORDER BY a; -SHOW CREATE TABLE t1; -DROP TABLE t1; - ---echo # ---echo # BUG#58205 - Valgrind failure in fn_format when called from ---echo # archive_discover ---echo # -CREATE TABLE `a/../`(a INT) ENGINE=ARCHIVE; -remove_file $MYSQLD_DATADIR/test/a@002f@002e@002e@002f.frm; -DROP TABLE `a/../`; - --echo # --echo # BUG#57162 - valgrind errors, random data when returning --echo # ordered data from archive tables diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result new file mode 100644 index 00000000000..51f66ee701b --- /dev/null +++ b/mysql-test/suite/archive/discover.result @@ -0,0 +1,70 @@ +create table t1 (a int) engine=archive; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +insert t1 values (1); +show tables; +Tables_in_test +t1 +# +# simple discover on use +# +flush tables; +insert t1 values (2); +select * from t1; +a +1 +2 +# +# list tables +# +create table t0 (a int) engine=archive; +flush tables; +show tables; +Tables_in_test +t0 +t1 +select * from t1; +a +1 +2 +# +# discover on drop +# +flush tables; +drop table t0, t1; +show tables; +Tables_in_test +# +# Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE +# +create table t1 (a int) engine=archive; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +insert into t1 values (1); +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +flush tables; +insert into t1 values (2); +select * from t1 order by a; +a +1 +2 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +drop table t1; +# +# BUG#58205 - Valgrind failure in fn_format when called from +# archive_discover +# +create table `a/../`(a int) engine=archive; +drop table `a/../`; diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test new file mode 100644 index 00000000000..843cb0caf63 --- /dev/null +++ b/mysql-test/suite/archive/discover.test @@ -0,0 +1,56 @@ +-- source include/have_archive.inc +let $mysqld_datadir= `select @@datadir`; + +create table t1 (a int) engine=archive; +show create table t1; +insert t1 values (1); +show tables; + +--echo # +--echo # simple discover on use +--echo # +remove_file $mysqld_datadir/test/t1.frm; +flush tables; +insert t1 values (2); +select * from t1; + +--echo # +--echo # list tables +--echo # +create table t0 (a int) engine=archive; +remove_file $mysqld_datadir/test/t1.frm; +flush tables; +show tables; +select * from t1; + +--echo # +--echo # discover on drop +--echo # +remove_file $mysqld_datadir/test/t1.frm; +flush tables; +drop table t0, t1; +show tables; + +--echo # +--echo # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE +--echo # + +create table t1 (a int) engine=archive; +show create table t1; +insert into t1 values (1); +optimize table t1; +remove_file $mysqld_datadir/test/t1.frm; +flush tables; +insert into t1 values (2); +select * from t1 order by a; +show create table t1; +drop table t1; + +--echo # +--echo # BUG#58205 - Valgrind failure in fn_format when called from +--echo # archive_discover +--echo # +create table `a/../`(a int) engine=archive; +remove_file $mysqld_datadir/test/a@002f@002e@002e@002f.frm; +drop table `a/../`; + diff --git a/mysql-test/t/grant4.test b/mysql-test/t/grant4.test index f3e551cd623..c30e0c28f31 100644 --- a/mysql-test/t/grant4.test +++ b/mysql-test/t/grant4.test @@ -104,9 +104,7 @@ connection con1; use mysqltest_db1; --echo ** Connect as restricted user mysqltest_u1. --echo ** SELECT FROM INFORMATION_SCHEMA.STATISTICS will succeed because any privileges will do (authentication is enough). -# -# this result is wrong. reported as bug#34104 -# +--echo ** but will return no rows SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='t5'; # # Bug27145 EXTRA_ACL trouble diff --git a/sql/discover.cc b/sql/discover.cc index b9dba92a780..72b88c8780b 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -128,7 +128,131 @@ int writefrm(const char *name, const uchar *frmdata, size_t len) DBUG_RETURN(error); } /* writefrm */ +static inline void advance(FILEINFO* &from, FILEINFO* &to, + FILEINFO* cur, bool &skip) +{ + if (skip) // if not copying + from= cur; // just advance the start pointer + else // if copying + if (to == from) // but to the same place (not shifting the data) + from= to= cur; // advance both pointers + else // otherwise + while (from < cur) // have to copy [from...cur) to [to...) + *to++ = *from++; + skip= false; +} +/** + Go through the directory listing looking for files with a specified + extension and add them to the result list + @details + This function may be called many times on the same directory listing + but with different extensions. To avoid discovering the same table twice, + whenever a table file is discovered, all files with the same name + (independently from the extensions) are removed from the list. + Example: the list contained + { "db.opt", "t1.MYD", "t1.MYI", "t1.frm", "t2.ARZ", "t3.ARZ", "t3.frm" } + on discovering all ".frm" files, tables "t1" and "t3" will be found, + and list will become + { "db.opt", "t2.ARZ" } + and now ".ARZ" discovery can discover the table "t2" + + @note + This function assumes that the directory listing is sorted alphabetically. + + @note Partitioning makes this more complicated. A partitioned table t1 might + have files, like t1.frm, t1#P#part1.ibd, t1#P#foo.ibd, etc. + That means we need to compare file names only up to the first '#' or '.' + whichever comes first. +*/ +int extension_based_table_discovery(MY_DIR *dirp, const char *ext_meta, + handlerton::discovered_list *result) +{ + CHARSET_INFO *cs= character_set_filesystem; + size_t ext_meta_len= strlen(ext_meta); + FILEINFO *from, *to, *cur, *end; + bool skip= false; + + from= to= cur= dirp->dir_entry; + end= cur + dirp->number_of_files; + while (cur < end) + { + char *octothorp= strrchr(cur->name, '#'); + char *ext= strchr(octothorp ? octothorp : cur->name, FN_EXTCHAR); + + if (ext && octothorp != cur->name) + { + size_t len= (octothorp ? octothorp : ext) - cur->name; + if (from != cur && + (my_strnncoll(cs, (uchar*)from->name, len, (uchar*)cur->name, len) || + (from->name[len] != FN_EXTCHAR && from->name[len] != '#'))) + advance(from, to, cur, skip); + + if (my_strnncoll(cs, (uchar*)ext, strlen(ext), + (uchar*)ext_meta, ext_meta_len) == 0) + { + *ext = 0; + if (result->add_file(cur->name)) + return 1; + *ext = FN_EXTCHAR; + skip= true; // table discovered, skip all files with the same name + } + } + else + { + advance(from, to, cur, skip); + from++; + } + + cur++; + } + advance(from, to, cur, skip); + dirp->number_of_files= to - dirp->dir_entry; + return 0; +} + +/** + Simple, not reusable file-based table discovery + + @details + simplified version of extension_based_table_discovery(), that does not + modify the list of files. It cannot be called many times for the same + directory listing, otherwise it'll produce duplicate results. + + @note + For backward compatibility reasons, this will find tables with names, + starting from '#', as long as they don't start from '#sql-'. + These names are invalid since 5.0, and the compex discovery function + will ignore them. Anyone still having these files, should disable + discovering engines, and rename these invalid table files. +*/ +int ext_table_discovery_simple(MY_DIR *dirp, const char *ext_meta, + handlerton::discovered_list *result) +{ + CHARSET_INFO *cs= character_set_filesystem; + size_t ext_meta_len= strlen(ext_meta); + FILEINFO *cur, *end; + + cur= dirp->dir_entry; + end= cur + dirp->number_of_files; + while (cur < end) + { + char *ext= strrchr(cur->name, FN_EXTCHAR); + + if (ext && !is_prefix(cur->name, tmp_file_prefix)) + { + if (my_strnncoll(cs, (uchar*)ext, strlen(ext), + (uchar*)ext_meta, ext_meta_len) == 0) + { + *ext = 0; + if (result->add_file(cur->name)) + return 1; + } + } + cur++; + } + return 0; +} diff --git a/sql/discover.h b/sql/discover.h index a663e44128d..d7f94240fa6 100644 --- a/sql/discover.h +++ b/sql/discover.h @@ -21,4 +21,12 @@ int readfrm(const char *name, uchar **data, size_t *length); int writefrm(const char* name, const uchar* data, size_t len); +int extension_based_table_discovery(MY_DIR *dirp, const char *ext, + handlerton::discovered_list *tl); + +#ifdef MYSQL_SERVER +int ext_table_discovery_simple(MY_DIR *dirp, const char *ext_meta, + handlerton::discovered_list *result); +#endif + #endif /* DISCOVER_INCLUDED */ diff --git a/sql/handler.cc b/sql/handler.cc index 56e9ec35ad8..8dd0a5d6995 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -433,6 +433,9 @@ int ha_finalize_handlerton(st_plugin_int *plugin) hton2plugin[hton->slot]= NULL; } + if (hton->discover_table_names) + my_atomic_add32(&engines_with_discover_table_names, -1); + my_free(hton); end: @@ -440,6 +443,13 @@ int ha_finalize_handlerton(st_plugin_int *plugin) } +static int hton_ext_based_table_discovery(handlerton *hton, LEX_STRING *db, + MY_DIR *dir, handlerton::discovered_list *result) +{ + return extension_based_table_discovery(dir, hton->tablefile_extensions[0], + result); +} + int ha_initialize_handlerton(st_plugin_int *plugin) { handlerton *hton; @@ -449,8 +459,6 @@ int ha_initialize_handlerton(st_plugin_int *plugin) hton= (handlerton *)my_malloc(sizeof(handlerton), MYF(MY_WME | MY_ZEROFILL)); - hton->tablefile_extensions= no_exts; - if (hton == NULL) { sql_print_error("Unable to allocate memory for plugin '%s' handlerton.", @@ -468,6 +476,16 @@ int ha_initialize_handlerton(st_plugin_int *plugin) goto err; } + // default list file extensions: empty + if (!hton->tablefile_extensions) + hton->tablefile_extensions= no_exts; + + // if the enfine can discover a single table and it is file-based + // then it can use a default file-based table names discovery + if (!hton->discover_table_names && + hton->discover && hton->tablefile_extensions[0]) + hton->discover_table_names= hton_ext_based_table_discovery; + /* the switch below and hton->state should be removed when command-line options for plugins will be implemented @@ -557,6 +575,9 @@ int ha_initialize_handlerton(st_plugin_int *plugin) break; }; + if (hton->discover_table_names) + my_atomic_add32(&engines_with_discover_table_names, 1); + DBUG_RETURN(0); err_deinit: @@ -4373,6 +4394,50 @@ int ha_discover(THD *thd, const char *db, const char *name, } +/** + Discover all table names in a given database +*/ +volatile int32 engines_with_discover_table_names= 0; + +struct st_discover_names_args +{ + LEX_STRING *db; + MY_DIR *dirp; + handlerton::discovered_list *result; +}; + +static my_bool discover_names(THD *thd, plugin_ref plugin, + void *arg) +{ + st_discover_names_args *args= (st_discover_names_args *)arg; + handlerton *ht= plugin_data(plugin, handlerton *); + if (ht->state == SHOW_OPTION_YES && ht->discover_table_names && + ht->discover_table_names(ht, args->db, args->dirp, args->result)) + return 1; + + return 0; +} + +int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, + handlerton::discovered_list *result) +{ + int error; + DBUG_ENTER("ha_discover_table_names"); + st_discover_names_args args= {db, dirp, result}; + + if (engines_with_discover_table_names == 0) + DBUG_RETURN(ext_table_discovery_simple(dirp, reg_ext, result)); + + error= extension_based_table_discovery(dirp, reg_ext, result); + + if (!error) + error= plugin_foreach(thd, discover_names, MYSQL_STORAGE_ENGINE_PLUGIN, + &args); + + DBUG_RETURN(error); +} + + #ifdef HAVE_NDB_BINLOG /* TODO: change this into a dynamic struct diff --git a/sql/handler.h b/sql/handler.h index 43c5246c156..93edfb2296e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1086,11 +1086,60 @@ struct handlerton ha_create_table_option *field_options; // these are specified per field ha_create_table_option *index_options; // these are specified per index - const char **tablefile_extensions; + /** + The list of extensions of files created for a single table in the + database directory (datadir/db_name/). + + Used by open_table_error(), by the default rename_table and delete_table + handler methods, and by the default discovery implementation. + + For engines that have more than one file name extentions (separate + metadata, index, and/or data files), the order of elements is relevant. + First element of engine file name extentions array should be metadata + file extention. This is implied by the open_table_error() + and the default discovery implementation. + + Second element - data file extention. This is implied + assumed by REPAIR TABLE ... USE_FRM implementation. + */ + const char **tablefile_extensions; // by default - empty list + + /********************************************************************* + Table discovery API. + It allows the server to "discover" tables that exist in the storage + engine, without user issuing an explicit CREATE TABLE statement. + **********************************************************************/ + + /* + The discover_table_names method tells the server + about all tables in the specified database that the engine + knows about. Tables (or file names of tables) are added to + the provided discovered_list collector object using + add_table() or add_file() methods. + */ + class discovered_list + { + public: + virtual bool add_table(const char *tname, size_t tlen) = 0; + virtual bool add_file(const char *fname) = 0; + protected: virtual ~discovered_list() {} + }; + + /* + By default (if not implemented by the engine, but the discovery_table() is + implemented) it will perform a file-based discovery: + + - if tablefile_extensions[0] is not null, this will discovers all tables + with the tablefile_extensions[0] extension. + + Returns 0 on success and 1 on error. + */ + int (*discover_table_names)(handlerton *hton, LEX_STRING *db, MY_DIR *dir, + discovered_list *result); }; -inline LEX_STRING *hton_name(const handlerton *hton) +static inline LEX_STRING *hton_name(const handlerton *hton) { return &(hton2plugin[hton->slot]->name); } @@ -2406,21 +2455,7 @@ public: virtual void free_foreign_key_create_info(char* str) {} /** The following can be called without an open handler */ const char *table_type() const { return hton_name(ht)->str; } - /** - If frm_error() is called then we will use this to find out what file - extentions exist for the storage engine. This is also used by the default - rename_table and delete_table method in handler.cc. - - For engines that have two file name extentions (separate meta/index file - and data file), the order of elements is relevant. First element of engine - file name extentions array should be meta/index file extention. Second - element - data file extention. This order is assumed by - prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. - */ - const char **bas_ext() const - { - return ht->tablefile_extensions; - } + const char **bas_ext() const { return ht->tablefile_extensions; } virtual int get_default_no_partitions(HA_CREATE_INFO *create_info) { return 1;} @@ -3037,6 +3072,11 @@ bool ha_check_if_table_exists(THD* thd, const char *db, const char *name, bool *exists); int ha_discover(THD* thd, const char* dbname, const char* name, uchar** frmblob, size_t* frmlen); +int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, + handlerton::discovered_list *result); +#ifdef MYSQL_SERVER +extern volatile int32 engines_with_discover_table_names; +#endif /* key cache */ extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache, void *); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 92be469becc..44736cd375a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -687,6 +687,50 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL; } +class Discovered_table_list: public handlerton::discovered_list +{ + THD *thd; + const char *wild; + size_t wild_length; + Dynamic_array *tables; + +public: + Discovered_table_list(THD *thd_arg, Dynamic_array *tables_arg, + const char *wild_arg) + { + thd= thd_arg; + tables= tables_arg; + if (wild_arg && wild_arg[0]) + { + wild= wild_arg; + wild_length= strlen(wild_arg); + } + else + wild= 0; + } + ~Discovered_table_list() {} + + bool add_table(const char *tname, size_t tlen) + { + if (wild && my_wildcmp(files_charset_info, tname, tname + tlen, + wild, wild + wild_length, + wild_prefix, wild_one, wild_many)) + return 0; + + LEX_STRING *name= thd->make_lex_string(tname, tlen); + if (!name || tables->append(name)) + return 1; + return 0; + } + + bool add_file(const char *fname) + { + char tname[SAFE_NAME_LEN + 1]; + size_t tlen= filename_to_tablename(fname, tname, sizeof(tname)); + return add_table(tname, tlen); + } +}; + extern "C" { static int cmp_table_names(LEX_STRING * const *a, LEX_STRING * const *b) { @@ -709,11 +753,10 @@ enum find_files_result { find_files() thd thread handler files put found files in this list - db database name to set in TABLE_LIST structure + db database name to search tables in + or NULL to search for databases path path to database wild filter for found files - dir read databases in path if TRUE, read .frm files in - database otherwise RETURN FIND_FILES_OK success @@ -723,60 +766,46 @@ enum find_files_result { static find_files_result -find_files(THD *thd, Dynamic_array *files, const char *db, - const char *path, const char *wild, bool dir) +find_files(THD *thd, Dynamic_array *files, LEX_STRING *db, + const char *path, const char *wild) { - uint i; - char *ext; MY_DIR *dirp; - FILEINFO *file; - LEX_STRING *file_name= 0; - uint file_name_len; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - uint col_access=thd->col_access; -#endif - uint wild_length= 0; - TABLE_LIST table_list; + myf my_dir_flags= MY_THREAD_SPECIFIC; + Discovered_table_list tl(thd, files, wild); DBUG_ENTER("find_files"); - if (wild) - { - if (!wild[0]) - wild= 0; - else - wild_length= strlen(wild); - } + if (!db) + my_dir_flags|= MY_WANT_STAT; - bzero((char*) &table_list,sizeof(table_list)); + if (engines_with_discover_table_names) + my_dir_flags|= MY_WANT_SORT; - if (!(dirp = my_dir(path, MYF((dir ? MY_WANT_STAT : 0) | - MY_THREAD_SPECIFIC)))) + if (!(dirp = my_dir(path, my_dir_flags))) { if (my_errno == ENOENT) - my_error(ER_BAD_DB_ERROR, MYF(ME_BELL | ME_WAITTANG), db); + my_error(ER_BAD_DB_ERROR, MYF(ME_BELL | ME_WAITTANG), db->str); else my_error(ER_CANT_READ_DIR, MYF(ME_BELL | ME_WAITTANG), path, my_errno); DBUG_RETURN(FIND_FILES_DIR); } - for (i=0 ; i < (uint) dirp->number_of_files ; i++) + if (!db) /* Return databases */ { - char uname[SAFE_NAME_LEN + 1]; /* Unencoded name */ - file=dirp->dir_entry+i; - if (dir) - { /* Return databases */ + for (uint i=0; i < (uint) dirp->number_of_files; i++) + { + FILEINFO *file= dirp->dir_entry+i; #ifdef USE_SYMDIR char *ext; char buff[FN_REFLEN]; if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym")) { - /* Only show the sym file if it points to a directory */ - char *end; + /* Only show the sym file if it points to a directory */ + char *end; *ext=0; /* Remove extension */ - unpack_dirname(buff, file->name); - end= strend(buff); - if (end != buff && end[-1] == FN_LIBCHAR) - end[-1]= 0; // Remove end FN_LIBCHAR + unpack_dirname(buff, file->name); + end= strend(buff); + if (end != buff && end[-1] == FN_LIBCHAR) + end[-1]= 0; // Remove end FN_LIBCHAR if (!mysql_file_stat(key_file_misc, buff, file->mystat, MYF(0))) continue; } @@ -787,69 +816,26 @@ find_files(THD *thd, Dynamic_array *files, const char *db, if (is_in_ignore_db_dirs_list(file->name)) continue; - file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); - if (wild) - { - if (lower_case_table_names) - { - if (my_wildcmp(files_charset_info, - uname, uname + file_name_len, - wild, wild + wild_length, - wild_prefix, wild_one, wild_many)) - continue; - } - else if (wild_compare(uname, wild, 0)) - continue; - } - } - else - { - // Return only .frm files which aren't temp files. - if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) || - is_prefix(file->name, tmp_file_prefix)) - continue; - *ext=0; - file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); - if (wild) - { - if (lower_case_table_names) - { - if (my_wildcmp(files_charset_info, - uname, uname + file_name_len, - wild, wild + wild_length, - wild_prefix, wild_one,wild_many)) - continue; - } - else if (wild_compare(uname, wild, 0)) - continue; - } - } -#ifndef NO_EMBEDDED_ACCESS_CHECKS - /* Don't show tables where we don't have any privileges */ - if (db && !(col_access & TABLE_ACLS)) - { - table_list.db= (char*) db; - table_list.db_length= strlen(db); - table_list.table_name= uname; - table_list.table_name_length= file_name_len; - table_list.grant.privilege=col_access; - if (check_grant(thd, TABLE_ACLS, &table_list, TRUE, 1, TRUE)) - continue; - } -#endif - if (!(file_name= thd->make_lex_string(uname, file_name_len)) || - files->append(file_name)) - { - my_dirend(dirp); - DBUG_RETURN(FIND_FILES_OOM); + if (tl.add_file(file->name)) + goto err; } } + else + { + if (ha_discover_table_names(thd, db, dirp, &tl)) + goto err; + } + DBUG_PRINT("info",("found: %d files", files->elements())); my_dirend(dirp); files->sort(cmp_table_names); DBUG_RETURN(FIND_FILES_OK); + +err: + my_dirend(dirp); + DBUG_RETURN(FIND_FILES_OOM); } @@ -3729,8 +3715,8 @@ int make_db_list(THD *thd, Dynamic_array *files, if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; } - return (find_files(thd, files, NullS, mysql_data_home, - lookup_field_vals->db_value.str, 1) != FIND_FILES_OK); + return find_files(thd, files, 0, mysql_data_home, + lookup_field_vals->db_value.str); } @@ -3761,8 +3747,7 @@ int make_db_list(THD *thd, Dynamic_array *files, */ if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; - return (find_files(thd, files, NullS, - mysql_data_home, NullS, 1) != FIND_FILES_OK); + return find_files(thd, files, 0, mysql_data_home, NullS); } @@ -3905,8 +3890,8 @@ make_table_name_list(THD *thd, Dynamic_array *table_names, return (schema_tables_add(thd, table_names, lookup_field_vals->table_value.str)); - find_files_result res= find_files(thd, table_names, db_name->str, path, - lookup_field_vals->table_value.str, 0); + find_files_result res= find_files(thd, table_names, db_name, path, + lookup_field_vals->table_value.str); if (res != FIND_FILES_OK) { /* @@ -4545,6 +4530,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { LEX *lex= thd->lex; TABLE *table= tables->table; + TABLE_LIST table_acl_check; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; LOOKUP_FIELD_VALUES lookup_field_vals; @@ -4651,6 +4637,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; } + bzero((char*) &table_acl_check, sizeof(table_acl_check)); + if (make_db_list(thd, &db_names, &lookup_field_vals)) goto err; for (int i=0; i < db_names.elements(); i++) @@ -4675,6 +4663,19 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) for (int i=0; i < table_names.elements(); i++) { LEX_STRING *table_name= table_names.at(i); + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (!(thd->col_access & TABLE_ACLS)) + { + table_acl_check.db= db_name->str; + table_acl_check.db_length= db_name->length; + table_acl_check.table_name= table_name->str; + table_acl_check.table_name_length= table_name->length; + table_acl_check.grant.privilege= thd->col_access; + if (check_grant(thd, TABLE_ACLS, &table_acl_check, TRUE, 1, TRUE)) + continue; + } +#endif restore_record(table, s->default_values); table->field[schema_table->idx_field1]-> store(db_name->str, db_name->length, system_charset_info); diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 02813ff8dc7..57d6fc947f8 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -105,7 +105,6 @@ static HASH archive_open_tables; /* The file extension */ #define ARZ ".ARZ" // The data file #define ARN ".ARN" // Files used during an optimize call -#define ARM ".ARM" // Meta file (deprecated) /* uchar + uchar From 0d1a59587566fb6ee27205fa64949a4cf4288dd1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:33:49 +0200 Subject: [PATCH 25/87] make the open_table_def to read the whole frm in memory and let open_binary_frm to parse it from the buffer, not a file. this avoids jumping back in forth in the frm file, and doing intermediate buffer mallocs. --- sql/table.cc | 197 ++++++++++++++++++++------------------------------- 1 file changed, 78 insertions(+), 119 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index cdee7405c7e..fb726f8b9f0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -65,18 +65,13 @@ LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") }; /* Functions defined in this file */ -void open_table_error(TABLE_SHARE *share, int error, int db_errno, - myf errortype, int errarg); -static int open_binary_frm(THD *thd, TABLE_SHARE *share, - uchar *head, File file); +static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *buf); static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, char **names); static uint find_field(Field **fields, uchar *record, uint start, uint length); inline bool is_system_table_name(const char *name, uint length); -static ulong get_form_pos(File file, uchar *head); - /************************************************************************** Object_creation_ctx implementation. **************************************************************************/ @@ -691,7 +686,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) } error= 4; - if (mysql_file_read(file, head, 64, MYF(MY_NABP))) + if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP))) goto err; if (head[0] == (uchar) 254 && head[1] == 1) @@ -730,12 +725,32 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) /* No handling of text based files yet */ if (table_type == 1) { + MY_STAT stats; + uchar *buf; + + if (my_fstat(file, &stats, MYF(0))) + goto err; + + if (!(buf= (uchar*)my_malloc(stats.st_size, MYF(MY_THREAD_SPECIFIC|MY_WME)))) + goto err; + + memcpy(buf, head, sizeof(head)); + + if (mysql_file_read(file, buf + sizeof(head), + stats.st_size - sizeof(head), MYF(MY_NABP))) + { + my_free(buf); + goto err; + } + mysql_file_close(file, MYF(MY_WME)); + root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); old_root= *root_ptr; *root_ptr= &share->mem_root; - error= open_binary_frm(thd, share, head, file); + error= open_binary_frm(thd, share, buf); *root_ptr= old_root; error_given= 1; + my_free(buf); } share->table_category= get_table_category(& share->db, & share->table_name); @@ -743,6 +758,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) if (!error) thd->status_var.opened_shares++; + DBUG_RETURN(error); + err: mysql_file_close(file, MYF(MY_WME)); @@ -757,23 +774,30 @@ err_not_open: } -/* - Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE +/** + Read data from a binary .frm file image into a TABLE_SHARE + + @note + frm bytes at the following offsets are unused in MariaDB 10.0: + + 8..9 (used to be the number of "form names") + 28..29 (used to be key_info_length) + + They're still set, for compatibility reasons, but never read. */ -static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, - File file) +static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) { int error, errarg= 0; uint new_frm_ver, field_pack_length, new_field_pack_flag; uint interval_count, interval_parts, read_length, int_length; uint db_create_options, keys, key_parts, n_length; - uint key_info_length, com_length, null_bit_pos; + uint com_length, null_bit_pos; uint extra_rec_buf_length; uint i,j; bool use_hash; char *keynames, *names, *comment_pos; - uchar forminfo[288]; + uchar *forminfo; uchar *record; uchar *disk_buff, *strpos, *null_flags, *null_pos; ulong pos, record_offset; @@ -791,7 +815,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, uint vcol_screen_length, UNINIT_VAR(options_len); char *vcol_screen_pos; uchar *UNINIT_VAR(options); - uchar *extra_segment_buff= 0; KEY first_keyinfo; uint len; KEY_PART_INFO *first_key_part= NULL; @@ -801,37 +824,36 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, share->ext_key_parts= 0; DBUG_ENTER("open_binary_frm"); - new_field_pack_flag= head[27]; - new_frm_ver= (head[2] - FRM_VER); + new_field_pack_flag= frm_image[27]; + new_frm_ver= (frm_image[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; - disk_buff= 0; error= 3; - /* Position of the form in the form file. */ - if (!(pos= get_form_pos(file, head))) - goto err; /* purecov: inspected */ - mysql_file_seek(file,pos,MY_SEEK_SET,MYF(0)); - if (mysql_file_read(file, forminfo,288,MYF(MY_NABP))) + /* Position of the form in the form file. */ + len = uint2korr(frm_image+4); + if (!(pos= uint4korr(frm_image + 64 + len))) goto err; - share->frm_version= head[2]; + + forminfo= frm_image + pos; + share->frm_version= frm_image[2]; /* Check if .frm file created by MySQL 5.0. In this case we want to display CHAR fields as CHAR and not as VARCHAR. We do it this way as we want to keep the old frm version to enable MySQL 4.1 to read these files. */ - if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5) + if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && frm_image[33] == 5) share->frm_version= FRM_VER_TRUE_VARCHAR; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (*(head+61) && + if (*(frm_image+61) && !(share->default_part_db_type= - ha_checktype(thd, (enum legacy_db_type) (uint) *(head+61), 1, 0))) + ha_checktype(thd, (enum legacy_db_type) (uint) *(frm_image+61), 1, 0))) goto err; - DBUG_PRINT("info", ("default_part_db_type = %u", head[61])); + DBUG_PRINT("info", ("default_part_db_type = %u", frm_image[61])); #endif - legacy_db_type= (enum legacy_db_type) (uint) *(head+3); + legacy_db_type= (enum legacy_db_type) (uint) *(frm_image+3); DBUG_ASSERT(share->db_plugin == NULL); /* if the storage engine is dynamic, no point in resolving it by its @@ -841,23 +863,23 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, legacy_db_type < DB_TYPE_FIRST_DYNAMIC) share->db_plugin= ha_lock_engine(NULL, ha_checktype(thd, legacy_db_type, 0, 0)); - share->db_create_options= db_create_options= uint2korr(head+30); + share->db_create_options= db_create_options= uint2korr(frm_image+30); share->db_options_in_use= share->db_create_options; - share->mysql_version= uint4korr(head+51); + share->mysql_version= uint4korr(frm_image+51); share->null_field_first= 0; - if (!head[32]) // New frm file in 3.23 + if (!frm_image[32]) // New frm file in 3.23 { - share->avg_row_length= uint4korr(head+34); - share->transactional= (ha_choice) (head[39] & 3); - share->page_checksum= (ha_choice) ((head[39] >> 2) & 3); - share->row_type= (row_type) head[40]; - share->table_charset= get_charset((((uint) head[41]) << 8) + - (uint) head[38],MYF(0)); + share->avg_row_length= uint4korr(frm_image+34); + share->transactional= (ha_choice) (frm_image[39] & 3); + share->page_checksum= (ha_choice) ((frm_image[39] >> 2) & 3); + share->row_type= (row_type) frm_image[40]; + share->table_charset= get_charset((((uint) frm_image[41]) << 8) + + (uint) frm_image[38],MYF(0)); share->null_field_first= 1; } if (!share->table_charset) { - /* unknown charset in head[38] or pre-3.23 frm */ + /* unknown charset in frm_image[38] or pre-3.23 frm */ if (use_mb(default_charset_info)) { /* Warn that we may be changing the size of character columns */ @@ -872,14 +894,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if (db_create_options & HA_OPTION_LONG_BLOB_PTR) share->blob_ptr_size= portable_sizeof_char_ptr; error=4; - share->max_rows= uint4korr(head+18); - share->min_rows= uint4korr(head+22); + share->max_rows= uint4korr(frm_image+18); + share->min_rows= uint4korr(frm_image+22); /* Read keyinformation */ - key_info_length= (uint) uint2korr(head+28); - mysql_file_seek(file, (ulong) uint2korr(head+6), MY_SEEK_SET, MYF(0)); - if (read_string(file,(uchar**) &disk_buff,key_info_length)) - goto err; /* purecov: inspected */ + disk_buff= frm_image + uint2korr(frm_image+6); if (disk_buff[0] & 0x80) { share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f); @@ -1047,36 +1066,29 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, (keyinfo->comment.length > 0)); } - share->reclength = uint2korr((head+16)); + share->reclength = uint2korr((frm_image+16)); share->stored_rec_length= share->reclength; - if (*(head+26) == 1) + if (*(frm_image+26) == 1) share->system= 1; /* one-record-database */ #ifdef HAVE_CRYPTED_FRM - else if (*(head+26) == 2) + else if (*(frm_image+26) == 2) { crypted= get_crypt_for_frm(); share->crypted= 1; } #endif - record_offset= (ulong) (uint2korr(head+6)+ - ((uint2korr(head+14) == 0xffff ? - uint4korr(head+47) : uint2korr(head+14)))); + record_offset= (ulong) (uint2korr(frm_image+6)+ + ((uint2korr(frm_image+14) == 0xffff ? + uint4korr(frm_image+47) : uint2korr(frm_image+14)))); - if ((n_length= uint4korr(head+55))) + if ((n_length= uint4korr(frm_image+55))) { /* Read extra data segment */ uchar *next_chunk, *buff_end; DBUG_PRINT("info", ("extra segment size is %u bytes", n_length)); - if (!(extra_segment_buff= (uchar*) my_malloc(n_length + 1, MYF(MY_WME)))) - goto err; - next_chunk= extra_segment_buff; - if (mysql_file_pread(file, extra_segment_buff, - n_length, record_offset + share->reclength, - MYF(MY_NABP))) - { - goto err; - } + next_chunk= frm_image + record_offset + share->reclength; + buff_end= next_chunk + n_length; share->connect_string.length= uint2korr(next_chunk); if (!(share->connect_string.str= strmake_root(&share->mem_root, (char*) next_chunk + 2, @@ -1086,7 +1098,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, goto err; } next_chunk+= share->connect_string.length + 2; - buff_end= extra_segment_buff + n_length; if (next_chunk + 2 < buff_end) { uint str_db_type_length= uint2korr(next_chunk); @@ -1240,21 +1251,20 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } DBUG_ASSERT(next_chunk <= buff_end); } - share->key_block_size= uint2korr(head+62); + share->key_block_size= uint2korr(frm_image+62); error=4; - extra_rec_buf_length= uint2korr(head+59); + extra_rec_buf_length= uint2korr(frm_image+59); rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length); share->rec_buff_length= rec_buff_length; if (!(record= (uchar *) alloc_root(&share->mem_root, rec_buff_length))) goto err; /* purecov: inspected */ share->default_values= record; - if (mysql_file_pread(file, record, (size_t) share->reclength, - record_offset, MYF(MY_NABP))) - goto err; /* purecov: inspected */ + memcpy(record, frm_image + record_offset, share->reclength); + + disk_buff= frm_image + pos + 288; - mysql_file_seek(file, pos+288, MY_SEEK_SET, MYF(0)); #ifdef HAVE_CRYPTED_FRM if (crypted) { @@ -1300,8 +1310,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, read_length=(uint) (share->fields * field_pack_length + pos+ (uint) (n_length+int_length+com_length+ vcol_screen_length)); - if (read_string(file,(uchar**) &disk_buff,read_length)) - goto err; /* purecov: inspected */ #ifdef HAVE_CRYPTED_FRM if (crypted) { @@ -1923,8 +1931,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } else share->primary_key= MAX_KEY; - my_free(disk_buff); - disk_buff=0; if (new_field_pack_flag <= 1) { /* Old file format with default as not null */ @@ -2000,15 +2006,12 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if (use_hash) (void) my_hash_check(&share->name_hash); #endif - my_free(extra_segment_buff); DBUG_RETURN (0); err: share->error= error; share->open_errno= my_errno; share->errarg= errarg; - my_free(disk_buff); - my_free(extra_segment_buff); delete crypted; delete handler_file; my_hash_free(&share->name_hash); @@ -2820,50 +2823,6 @@ void free_field_buffers_larger_than(TABLE *table, uint32 size) } } -/** - Find where a form starts. - - @param head The start of the form file. - - @remark If formname is NULL then only formnames is read. - - @retval The form position. -*/ - -static ulong get_form_pos(File file, uchar *head) -{ - uchar *pos, *buf; - uint names, length; - ulong ret_value=0; - DBUG_ENTER("get_form_pos"); - - names= uint2korr(head+8); - - if (!(names= uint2korr(head+8))) - DBUG_RETURN(0); - - length= uint2korr(head+4); - - mysql_file_seek(file, 64L, MY_SEEK_SET, MYF(0)); - - if (!(buf= (uchar*) my_malloc(length+names*4, MYF(MY_WME)))) - DBUG_RETURN(0); - - if (mysql_file_read(file, buf, length+names*4, MYF(MY_NABP))) - { - my_free(buf); - DBUG_RETURN(0); - } - - pos= buf+length; - ret_value= uint4korr(pos); - - my_free(buf); - - DBUG_RETURN(ret_value); -} - - /* Read string from a file with malloc From cda52b2cb28091c4372880a2b68a9174f21bd885 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:33:58 +0200 Subject: [PATCH 26/87] remove dead HAVE_CRYPTED_FRM code and now-unused read_string() function --- sql/discover.cc | 8 ++++++-- sql/frm_crypt.cc | 37 ----------------------------------- sql/frm_crypt.h | 23 ---------------------- sql/table.cc | 51 ------------------------------------------------ sql/table.h | 1 - sql/unireg.cc | 22 --------------------- 6 files changed, 6 insertions(+), 136 deletions(-) delete mode 100644 sql/frm_crypt.cc delete mode 100644 sql/frm_crypt.h diff --git a/sql/discover.cc b/sql/discover.cc index 72b88c8780b..82dc8d97d65 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -74,9 +74,13 @@ int readfrm(const char *name, uchar **frmdata, size_t *len) // Read whole frm file error= 3; - read_data= 0; // Nothing to free - if (read_string(file, &read_data, read_len)) + if (!(read_data= (uchar*)my_malloc(read_len, MYF(MY_WME)))) goto err; + if (mysql_file_read(file, read_data, read_len, MYF(MY_NABP))) + { + my_free(read_data); + goto err; + } // Setup return data *frmdata= (uchar*) read_data; diff --git a/sql/frm_crypt.cc b/sql/frm_crypt.cc deleted file mode 100644 index 5612908aea5..00000000000 --- a/sql/frm_crypt.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -/* -** change the following to the output of password('our password') -** split into 2 parts of 8 characters each. -** This is done to make it impossible to search after a text string in the -** mysql binary. -*/ - -#include "sql_priv.h" -#include "frm_crypt.h" - -#ifdef HAVE_CRYPTED_FRM - -/* password('test') */ -ulong password_seed[2]={0x378b243e, 0x220ca493}; - -SQL_CRYPT *get_crypt_for_frm(void) -{ - return new SQL_CRYPT(password_seed); -} - -#endif diff --git a/sql/frm_crypt.h b/sql/frm_crypt.h deleted file mode 100644 index 0605644b3e0..00000000000 --- a/sql/frm_crypt.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#ifndef FRM_CRYPT_INCLUDED -#define FRM_CRYPT_INCLUDED - -class SQL_CRYPT; - -SQL_CRYPT *get_crypt_for_frm(void); - -#endif /* FRM_CRYPT_INCLUDED */ diff --git a/sql/table.cc b/sql/table.cc index fb726f8b9f0..46ac6578076 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -22,7 +22,6 @@ #include "sql_priv.h" #include "unireg.h" // REQUIRED: for other includes #include "table.h" -#include "frm_crypt.h" // get_crypt_for_frm #include "key.h" // find_ref_key #include "sql_table.h" // build_table_filename, // primary_key_name @@ -806,7 +805,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) handler *handler_file= 0; KEY *keyinfo; KEY_PART_INFO *key_part= NULL; - SQL_CRYPT *crypted=0; Field **field_ptr, *reg_field; const char **interval_array; enum legacy_db_type legacy_db_type; @@ -1070,13 +1068,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) share->stored_rec_length= share->reclength; if (*(frm_image+26) == 1) share->system= 1; /* one-record-database */ -#ifdef HAVE_CRYPTED_FRM - else if (*(frm_image+26) == 2) - { - crypted= get_crypt_for_frm(); - share->crypted= 1; - } -#endif record_offset= (ulong) (uint2korr(frm_image+6)+ ((uint2korr(frm_image+14) == 0xffff ? @@ -1265,15 +1256,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) disk_buff= frm_image + pos + 288; -#ifdef HAVE_CRYPTED_FRM - if (crypted) - { - crypted->decode((char*) forminfo+256,288-256); - if (sint2korr(forminfo+284) != 0) // Should be 0 - goto err; // Wrong password - } -#endif - share->fields= uint2korr(forminfo+258); pos= uint2korr(forminfo+260); /* Length of all screens */ n_length= uint2korr(forminfo+268); @@ -1310,14 +1292,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) read_length=(uint) (share->fields * field_pack_length + pos+ (uint) (n_length+int_length+com_length+ vcol_screen_length)); -#ifdef HAVE_CRYPTED_FRM - if (crypted) - { - crypted->decode((char*) disk_buff,read_length); - delete crypted; - crypted=0; - } -#endif strpos= disk_buff+pos; share->intervals= (TYPELIB*) (field_ptr+share->fields+1); @@ -2012,7 +1986,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) share->error= error; share->open_errno= my_errno; share->errarg= errarg; - delete crypted; delete handler_file; my_hash_free(&share->name_hash); if (share->ha_data_destroy) @@ -2823,30 +2796,6 @@ void free_field_buffers_larger_than(TABLE *table, uint32 size) } } -/* - Read string from a file with malloc - - NOTES: - We add an \0 at end of the read string to make reading of C strings easier -*/ - -int read_string(File file, uchar**to, size_t length) -{ - DBUG_ENTER("read_string"); - - my_free(*to); - if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) || - mysql_file_read(file, *to, length, MYF(MY_NABP))) - { - my_free(*to); /* purecov: inspected */ - *to= 0; /* purecov: inspected */ - DBUG_RETURN(1); /* purecov: inspected */ - } - *((char*) *to+length)= '\0'; - DBUG_RETURN (0); -} /* read_string */ - - /* Add a new form to a form file */ ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames, diff --git a/sql/table.h b/sql/table.h index 50ddb0a096b..90907230f78 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2463,7 +2463,6 @@ char *get_field(MEM_ROOT *mem, Field *field); bool get_field(MEM_ROOT *mem, Field *field, class String *res); int closefrm(TABLE *table, bool free_share); -int read_string(File file, uchar* *to, size_t length); void free_blobs(TABLE *table); void free_field_buffers_larger_than(TABLE *table, uint32 size); int set_zone(int nr,int min_zone,int max_zone); diff --git a/sql/unireg.cc b/sql/unireg.cc index 20d101be1a3..90039c478be 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -396,28 +396,6 @@ bool mysql_create_frm(THD *thd, const char *file_name, pack_fields(file, create_fields, data_offset)) goto err; -#ifdef HAVE_CRYPTED_FRM - if (create_info->password) - { - char tmp=2,*disk_buff=0; - SQL_CRYPT *crypted=new SQL_CRYPT(create_info->password); - if (!crypted || mysql_file_pwrite(file, &tmp, 1, 26, MYF_RW))// Mark crypted - goto err; - uint read_length=uint2korr(forminfo)-256; - mysql_file_seek(file, filepos+256, MY_SEEK_SET, MYF(0)); - if (read_string(file,(uchar**) &disk_buff,read_length)) - goto err; - crypted->encode(disk_buff,read_length); - delete crypted; - if (mysql_file_pwrite(file, disk_buff, read_length, filepos+256, MYF_RW)) - { - my_free(disk_buff); - goto err; - } - my_free(disk_buff); - } -#endif - my_free(screen_buff); my_free(keybuff); From 5ad68a0d2f66b2d36f0a509c443829d58477caa2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:34:09 +0200 Subject: [PATCH 27/87] don't use I_S constants for open_table_def and get_table_share, have a specially defined enum with clearly named values --- sql/handler.cc | 4 ++-- sql/sql_admin.cc | 4 ++-- sql/sql_base.cc | 32 ++++++++++++++------------------ sql/sql_base.h | 2 +- sql/sql_show.cc | 4 ++-- sql/sql_table.cc | 2 +- sql/table.cc | 12 +++--------- sql/table.h | 8 ++++++-- 8 files changed, 31 insertions(+), 37 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 8dd0a5d6995..0091c765042 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4104,7 +4104,7 @@ int ha_create_table(THD *thd, const char *path, DBUG_ENTER("ha_create_table"); init_tmp_table_share(thd, &share, db, 0, table_name, path); - if (open_table_def(thd, &share, 0) || + if (open_table_def(thd, &share) || open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table, TRUE)) goto err; @@ -4171,7 +4171,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name) DBUG_RETURN(2); init_tmp_table_share(thd, &share, db, 0, name, path); - if (open_table_def(thd, &share, 0)) + if (open_table_def(thd, &share)) { DBUG_RETURN(3); } diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 10636fd7296..43500211e1b 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -128,8 +128,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); mysql_mutex_lock(&LOCK_open); - share= get_table_share(thd, table_list, key, key_length, 0, - &error, hash_value); + share= get_table_share(thd, table_list, key, key_length, + FRM_READ_TABLE_ONLY, &error, hash_value); mysql_mutex_unlock(&LOCK_open); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0d31ba06e12..9b9411c63a1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -575,7 +575,7 @@ static void table_def_unuse_table(TABLE *table) */ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, uint db_flags, int *error, + uint key_length, enum read_frm_op op, int *error, my_hash_value_type hash_value) { TABLE_SHARE *share; @@ -622,7 +622,7 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, free_table_share(share); DBUG_RETURN(0); // return error } - if (open_table_def(thd, share, db_flags)) + if (open_table_def(thd, share, op)) { *error= share->error; (void) my_hash_delete(&table_def_cache, (uchar*) share); @@ -644,7 +644,7 @@ found: open_table_error(share, share->error, share->open_errno, share->errarg); DBUG_RETURN(0); } - if (share->is_view && !(db_flags & OPEN_VIEW)) + if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW) { open_table_error(share, 1, ENOENT, 0); DBUG_RETURN(0); @@ -685,7 +685,7 @@ found: static TABLE_SHARE * get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, char *key, uint key_length, - uint db_flags, int *error, + enum read_frm_op op, int *error, my_hash_value_type hash_value) { @@ -693,7 +693,7 @@ get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, bool exists; DBUG_ENTER("get_table_share_with_discover"); - share= get_table_share(thd, table_list, key, key_length, db_flags, error, + share= get_table_share(thd, table_list, key, key_length, op, error, hash_value); /* If share is not NULL, we found an existing share. @@ -3014,10 +3014,9 @@ retry_share: mysql_mutex_lock(&LOCK_open); - if (!(share= get_table_share_with_discover(thd, table_list, key, - key_length, OPEN_VIEW, - &error, - hash_value))) + if (!(share= get_table_share_with_discover(thd, table_list, key, key_length, + FRM_READ_NO_ERROR_FOR_VIEW, + &error, hash_value))) { mysql_mutex_unlock(&LOCK_open); /* @@ -3856,10 +3855,8 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, cache_key_length); mysql_mutex_lock(&LOCK_open); - if (!(share= get_table_share(thd, table_list, cache_key, - cache_key_length, - OPEN_VIEW, &error, - hash_value))) + if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, + FRM_READ_NO_ERROR_FOR_VIEW, &error, hash_value))) goto err; if (share->is_view && @@ -3949,9 +3946,8 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) cache_key_length); mysql_mutex_lock(&LOCK_open); - if (!(share= get_table_share(thd, table_list, cache_key, - cache_key_length, - OPEN_VIEW, ¬_used, + if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, + FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, hash_value))) goto end_unlock; @@ -6117,7 +6113,7 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db, init_tmp_table_share(thd, share, saved_cache_key, key_length, strend(saved_cache_key)+1, tmp_path); - if (open_table_def(thd, share, 0) || + if (open_table_def(thd, share) || open_table_from_share(thd, share, table_name, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX), @@ -9249,7 +9245,7 @@ my_bool mysql_rm_tmp_tables(void) memcpy(filePathCopy, filePath, filePath_len - ext_len); filePathCopy[filePath_len - ext_len]= 0; init_tmp_table_share(thd, &share, "", 0, "", filePathCopy); - if (!open_table_def(thd, &share, 0) && + if (!open_table_def(thd, &share) && ((handler_file= get_new_handler(&share, thd->mem_root, share.db_type())))) { diff --git a/sql/sql_base.h b/sql/sql_base.h index 7d1797e2883..1cd36160309 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -108,7 +108,7 @@ create_table_def_key(char *key, const char *db, const char *table_name) } TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, uint db_flags, int *error, + uint key_length, enum read_frm_op op, int *error, my_hash_value_type hash_value); void release_table_share(TABLE_SHARE *share); TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 44736cd375a..d63e8221654 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4383,8 +4383,8 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, key_length= create_table_def_key(thd, key, &table_list, 0); hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); mysql_mutex_lock(&LOCK_open); - share= get_table_share(thd, &table_list, key, - key_length, OPEN_VIEW, ¬_used, hash_value); + share= get_table_share(thd, &table_list, key, key_length, + FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, hash_value); if (!share) { res= 0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 455fef094af..7072cb38138 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4023,7 +4023,7 @@ static bool check_if_created_table_can_be_opened(THD *thd, init_tmp_table_share(thd, &share, db, 0, table_name, path); - result= (open_table_def(thd, &share, 0) || + result= (open_table_def(thd, &share) || open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table, TRUE)); if (! result) diff --git a/sql/table.cc b/sql/table.cc index 46ac6578076..a0012e2e0d0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -619,7 +619,7 @@ static bool has_disabled_path_chars(const char *str) 6 Unknown .frm version */ -int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) +int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) { int error, table_type; bool error_given; @@ -693,17 +693,11 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) if (head[2] == FRM_VER || head[2] == FRM_VER+1 || (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)) { - /* Open view only */ - if (db_flags & OPEN_VIEW_ONLY) - { - error_given= 1; - goto err; - } table_type= 1; } else { - error= 6; // Unkown .frm version + error= 6; // Unknown .frm version goto err; } } @@ -713,7 +707,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) if (memcmp(head+5,"VIEW",4) == 0) { share->is_view= 1; - if (db_flags & OPEN_VIEW) + if (op == FRM_READ_NO_ERROR_FOR_VIEW) error= 0; } goto err; diff --git a/sql/table.h b/sql/table.h index 90907230f78..18ed635aae8 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2433,10 +2433,13 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, #endif } +enum read_frm_op { + FRM_READ_TABLE_ONLY, + FRM_READ_NO_ERROR_FOR_VIEW +}; size_t max_row_length(TABLE *table, const uchar *data); - void init_mdl_requests(TABLE_LIST *table_list); int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, @@ -2451,7 +2454,8 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, uint key_length, const char *table_name, const char *path); void free_table_share(TABLE_SHARE *share); -int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags); +int open_table_def(THD *thd, TABLE_SHARE *share, + enum read_frm_op op = FRM_READ_TABLE_ONLY); void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg); void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); bool check_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase); From 163882665eed8c065953bdce05aaa152b6b5df0f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:34:17 +0200 Subject: [PATCH 28/87] * don't use 1-8 numbers for open_table_error codes, use an enum. * print "table doesn't exist in engine" when a table doesn't exist in the engine, instead of "file not found" (if no file was involved) * print a complete filename that cannot be found ('t1.MYI', not 't1') * it's not an error for a DROP if a table doesn't exist in the engine (or some table files cannot be found) - if the DROP succeeded regardless --- include/my_base.h | 2 +- mysql-test/include/mix1.inc | 5 +- mysql-test/r/myisam-system.result | 12 +- mysql-test/r/mysql_client_test.result | 1 + .../r/mysql_client_test_nonblock.result | 1 + mysql-test/r/mysqlcheck.result | 1 + mysql-test/r/partition_myisam.result | 1 - mysql-test/suite/archive/archive.result | 5 +- mysql-test/suite/archive/archive.test | 1 - .../federated/federated_bug_35333.result | 10 +- .../suite/federated/federated_bug_35333.test | 4 - mysql-test/suite/innodb/r/innodb_mysql.result | 2 +- mysql-test/suite/rpl/r/rpl_EE_err.result | 2 +- mysql-test/t/myisam-system.test | 6 +- mysql-test/t/mysql_client_test.test | 2 + mysql-test/t/mysql_client_test_nonblock.test | 1 + mysql-test/t/mysqlcheck.test | 1 + sql/datadict.cc | 5 + sql/handler.cc | 15 +- sql/share/errmsg-utf8.txt | 2 +- sql/sql_admin.cc | 3 +- sql/sql_base.cc | 30 +-- sql/sql_base.h | 3 +- sql/sql_show.cc | 2 +- sql/sql_table.cc | 4 +- sql/table.cc | 244 +++++++----------- sql/table.h | 26 +- storage/innobase/handler/ha_innodb.cc | 17 +- storage/xtradb/handler/ha_innodb.cc | 4 +- 29 files changed, 196 insertions(+), 216 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index 4cbcb00425b..0c12057b2ab 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -405,7 +405,7 @@ enum ha_base_keytype { #define HA_ERR_WRONG_INDEX 124 /* Wrong index given to function */ #define HA_ERR_CRASHED 126 /* Indexfile is crashed */ #define HA_ERR_WRONG_IN_RECORD 127 /* Record-file is crashed */ -#define HA_ERR_OUT_OF_MEM 128 /* Record-file is crashed */ +#define HA_ERR_OUT_OF_MEM 128 /* Out of memory */ #define HA_ERR_NOT_A_TABLE 130 /* not a MYI file - no signature */ #define HA_ERR_WRONG_COMMAND 131 /* Command not supported */ #define HA_ERR_OLD_FILE 132 /* old databasfile */ diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 87d6698865a..e7ea8b3d25a 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -627,16 +627,17 @@ DROP TABLE t1,t2,t3; create table t1 (a int) engine=innodb; let $MYSQLD_DATADIR= `select @@datadir`; copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/bug29807.frm; ---error 1146 +--error ER_NO_SUCH_TABLE_IN_ENGINE select * from bug29807; drop table t1; ---error 1051 +--error ER_BAD_TABLE_ERROR drop table bug29807; create table bug29807 (a int); drop table bug29807; --disable_query_log call mtr.add_suppression("InnoDB: Error: table .test...bug29807. does not exist in the InnoDB internal"); call mtr.add_suppression("Cannot find or open table test\/bug29807 from"); +call mtr.add_suppression("Table 'test.bug29807' doesn't exist in engine"); --enable_query_log diff --git a/mysql-test/r/myisam-system.result b/mysql-test/r/myisam-system.result index 924e7885814..9d5a59459ec 100644 --- a/mysql-test/r/myisam-system.result +++ b/mysql-test/r/myisam-system.result @@ -2,12 +2,18 @@ drop table if exists t1,t2; create table t1 (a int) engine=myisam; drop table if exists t1; Warnings: -Warning 2 Can't find file: 't1' (errno: 2 "No such file or directory") +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") create table t1 (a int) engine=myisam; +select * from t1; +ERROR HY000: Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") drop table t1; -Got one of the listed errors +Warnings: +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") create table t1 (a int) engine=myisam; +select * from t1; +ERROR HY000: File './test/t1.MYD' not found (Errcode: 2 "No such file or directory") drop table t1; -Got one of the listed errors +Warnings: +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") drop table t1; ERROR 42S02: Unknown table 't1' diff --git a/mysql-test/r/mysql_client_test.result b/mysql-test/r/mysql_client_test.result index 7875464ebe2..4ad07b20ab5 100644 --- a/mysql-test/r/mysql_client_test.result +++ b/mysql-test/r/mysql_client_test.result @@ -1,5 +1,6 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); ok # cat MYSQL_TMP_DIR/test_wl4435.out.log diff --git a/mysql-test/r/mysql_client_test_nonblock.result b/mysql-test/r/mysql_client_test_nonblock.result index edda7980e97..e37e2132b0c 100644 --- a/mysql-test/r/mysql_client_test_nonblock.result +++ b/mysql-test/r/mysql_client_test_nonblock.result @@ -1,5 +1,6 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); ok SET @@global.general_log= @old_general_log; SET @@global.slow_query_log= @old_slow_query_log; diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 14ade969b25..c195bc6e3b3 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -160,6 +160,7 @@ Table Op Msg_type Msg_text test.v1 check status OK information_schema.routines check note The storage engine for the table doesn't support check drop view v1; +call mtr.add_suppression("Error reading file './test/t1.frm'"); CREATE TABLE t1(a INT) engine=myisam; CREATE TABLE t2(a INT) engine=myisam; test.t1 diff --git a/mysql-test/r/partition_myisam.result b/mysql-test/r/partition_myisam.result index f0844c0b407..10586ddc548 100644 --- a/mysql-test/r/partition_myisam.result +++ b/mysql-test/r/partition_myisam.result @@ -102,7 +102,6 @@ FLUSH TABLES; CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check Error Failed to read from the .par file -test.t1 check Error Incorrect information in file: './test/t1.frm' test.t1 check error Corrupt SELECT * FROM t1; ERROR HY000: Failed to read from the .par file diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 618433fe5e0..df0db73244a 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12754,9 +12754,10 @@ DROP TABLE t1; CREATE TABLE t1(a INT) ENGINE=ARCHIVE; FLUSH TABLE t1; SELECT * FROM t1; -ERROR HY000: Can't find file: 't1' (errno: 2 "No such file or directory") +ERROR HY000: Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory") DROP TABLE t1; -ERROR 42S02: Unknown table 't1' +Warnings: +Warning 2 Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory") # # Ensure that TRUNCATE fails for non-empty archive tables. # diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 92868158ed4..0dfdc969162 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1676,7 +1676,6 @@ FLUSH TABLE t1; --remove_file $MYSQLD_DATADIR/test/t1.ARZ --error ER_FILE_NOT_FOUND SELECT * FROM t1; ---error ER_BAD_TABLE_ERROR DROP TABLE t1; --echo # diff --git a/mysql-test/suite/federated/federated_bug_35333.result b/mysql-test/suite/federated/federated_bug_35333.result index 74f6f6e8f02..05e4bab8ec5 100644 --- a/mysql-test/suite/federated/federated_bug_35333.result +++ b/mysql-test/suite/federated/federated_bug_35333.result @@ -24,14 +24,12 @@ CREATE TABLE t1 (c1 int) ENGINE=MYISAM; SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE ROW_FORMAT TABLE_ROWS DATA_LENGTH TABLE_COMMENT -test t1 BASE TABLE NULL NULL NULL NULL Can't find file: 't1' (errno: 2 "No such file or directory") +test t1 BASE TABLE NULL NULL NULL NULL Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") Warnings: -Warning 1017 Can't find file: 't1' (errno: 2 "No such file or directory") -SHOW WARNINGS; -Level Code Message -Warning 1017 Can't find file: 't1' (errno: 2 "No such file or directory") +Warning 1017 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") DROP TABLE t1; -ERROR 42S02: Unknown table 't1' +Warnings: +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") # # Cleanup # diff --git a/mysql-test/suite/federated/federated_bug_35333.test b/mysql-test/suite/federated/federated_bug_35333.test index 6487e10e018..47feefd75a1 100644 --- a/mysql-test/suite/federated/federated_bug_35333.test +++ b/mysql-test/suite/federated/federated_bug_35333.test @@ -64,11 +64,7 @@ let $MYSQLD_DATADIR= `SELECT @@datadir`; SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; -SHOW WARNINGS; ---disable_warnings ---error 1051 DROP TABLE t1; ---enable_warnings --echo # --echo # Cleanup diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index b2df98bbfa6..d963c4cc89b 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -630,7 +630,7 @@ a DROP TABLE t1,t2,t3; create table t1 (a int) engine=innodb; select * from bug29807; -ERROR 42S02: Table 'test.bug29807' doesn't exist +ERROR 42S02: Table 'test.bug29807' doesn't exist in engine drop table t1; drop table bug29807; ERROR 42S02: Unknown table 'bug29807' diff --git a/mysql-test/suite/rpl/r/rpl_EE_err.result b/mysql-test/suite/rpl/r/rpl_EE_err.result index 5b3f1872c4e..f61ca063b77 100644 --- a/mysql-test/suite/rpl/r/rpl_EE_err.result +++ b/mysql-test/suite/rpl/r/rpl_EE_err.result @@ -4,5 +4,5 @@ create table t1 (a int) engine=myisam; flush tables; drop table if exists t1; Warnings: -Warning 2 Can't find file: 't1' (errno: 2 "No such file or directory") +Warning 2 Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory") include/rpl_end.inc diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test index d908e639a4e..ef1bc03434d 100644 --- a/mysql-test/t/myisam-system.test +++ b/mysql-test/t/myisam-system.test @@ -12,11 +12,13 @@ let $MYSQLD_DATADIR= `select @@datadir`; drop table if exists t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYI ---error ER_BAD_TABLE_ERROR,6 +--error ER_FILE_NOT_FOUND +select * from t1; drop table t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYD ---error ER_BAD_TABLE_ERROR,6,29 +--error 29 +select * from t1; drop table t1; --error ER_BAD_TABLE_ERROR drop table t1; diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index 90da022fb38..bf5331ca4f9 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -6,6 +6,8 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); + # We run with different binaries for normal and --embedded-server # # If this test fails with "command "$MYSQL_CLIENT_TEST" failed", diff --git a/mysql-test/t/mysql_client_test_nonblock.test b/mysql-test/t/mysql_client_test_nonblock.test index fc2e0b1d01b..51263854e58 100644 --- a/mysql-test/t/mysql_client_test_nonblock.test +++ b/mysql-test/t/mysql_client_test_nonblock.test @@ -5,6 +5,7 @@ SET @old_general_log= @@global.general_log; SET @old_slow_query_log= @@global.slow_query_log; +call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); # We run with different binaries for normal and --embedded-server # diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index c0025f9e742..06d702495c2 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -93,6 +93,7 @@ drop view v1; # Bug#37527: mysqlcheck fails to report entire database # when frm file corruption # +call mtr.add_suppression("Error reading file './test/t1.frm'"); CREATE TABLE t1(a INT) engine=myisam; CREATE TABLE t2(a INT) engine=myisam; # backup then null t1.frm diff --git a/sql/datadict.cc b/sql/datadict.cc index e3f679cc7ec..4aa024b3b44 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -60,6 +60,11 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) (header[2] < FRM_VER+3 || header[2] > FRM_VER+4))) DBUG_RETURN(FRMTYPE_TABLE); + /* + XXX this is a bug. + if header[3] is > DB_TYPE_FIRST_DYNAMIC, then the complete + storage engine name must be read from the frm + */ *dbt= (enum legacy_db_type) (uint) *(header + 3); /* Probably a table. */ diff --git a/sql/handler.cc b/sql/handler.cc index 0091c765042..58e8524dd8d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2189,7 +2189,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */ if (table_type == NULL || ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) - DBUG_RETURN(ENOENT); + DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); path= get_canonical_filename(file, path, tmp_path); if ((error= file->ha_delete_table(path)) && generate_warning) @@ -2205,6 +2205,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, /* Fill up strucutures that print_error may need */ dummy_share.path.str= (char*) path; dummy_share.path.length= strlen(path); + dummy_share.normalized_path= dummy_share.path; dummy_share.db.str= (char*) db; dummy_share.db.length= strlen(db); dummy_share.table_name.str= (char*) alias; @@ -3208,7 +3209,17 @@ void handler::print_error(int error, myf errflag) errflag|= ME_NOREFRESH; } } - my_error(textno, errflag, table_share->table_name.str, error); + + /* if we got an OS error from a file-based engine, specify a path of error */ + if (error < HA_ERR_FIRST && bas_ext()[0]) + { + char buff[FN_REFLEN]; + strxnmov(buff, sizeof(buff), + table_share->normalized_path.str, bas_ext()[0], NULL); + my_error(textno, errflag, buff, error); + } + else + my_error(textno, errflag, table_share->table_name.str, error); DBUG_VOID_RETURN; } diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 8c7a8000695..e7f60987cc1 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6599,4 +6599,4 @@ ER_CANT_START_STOP_SLAVE ER_SLAVE_STARTED eng "SLAVE '%.*s' started" ER_SLAVE_STOPPED - eng "SLAVE '%.*s' stopped" \ No newline at end of file + eng "SLAVE '%.*s' stopped" diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 43500211e1b..849a00a7df7 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -81,6 +81,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, HA_CHECK_OPT *check_opt) { int error= 0; + enum open_frm_error not_used; TABLE tmp_table, *table; TABLE_LIST *pos_in_locked_tables= 0; TABLE_SHARE *share; @@ -129,7 +130,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, table_list, key, key_length, - FRM_READ_TABLE_ONLY, &error, hash_value); + FRM_READ_TABLE_ONLY, ¬_used, hash_value); mysql_mutex_unlock(&LOCK_open); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9b9411c63a1..03728fcd372 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -575,13 +575,14 @@ static void table_def_unuse_table(TABLE *table) */ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, enum read_frm_op op, int *error, + uint key_length, enum read_frm_op op, + enum open_frm_error *error, my_hash_value_type hash_value) { TABLE_SHARE *share; DBUG_ENTER("get_table_share"); - *error= 0; + *error= OPEN_FRM_OK; /* To be able perform any operation on table we should own @@ -641,12 +642,12 @@ found: if (share->error) { /* Table definition contained an error */ - open_table_error(share, share->error, share->open_errno, share->errarg); + open_table_error(share, share->error, share->open_errno); DBUG_RETURN(0); } if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW) { - open_table_error(share, 1, ENOENT, 0); + open_table_error(share, OPEN_FRM_NO_VIEWS, ENOENT); DBUG_RETURN(0); } @@ -685,7 +686,7 @@ found: static TABLE_SHARE * get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, char *key, uint key_length, - enum read_frm_op op, int *error, + enum read_frm_op op, enum open_frm_error *error, my_hash_value_type hash_value) { @@ -724,7 +725,7 @@ get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE)) DBUG_RETURN(share); - *error= 0; + *error= OPEN_FRM_OK; /* Table didn't exist. Check if some engine can provide it */ if (ha_check_if_table_exists(thd, table_list->db, table_list->table_name, @@ -762,7 +763,7 @@ get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, else { thd->clear_error(); - *error= 7; /* Run auto-discover. */ + *error= OPEN_FRM_DISCOVER; /* Run auto-discover. */ } DBUG_RETURN(NULL); } @@ -2735,7 +2736,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, char *alias= table_list->alias; uint flags= ot_ctx->get_flags(); MDL_ticket *mdl_ticket; - int error; + enum open_frm_error error; TABLE_SHARE *share; my_hash_value_type hash_value; DBUG_ENTER("open_table"); @@ -3020,12 +3021,11 @@ retry_share: { mysql_mutex_unlock(&LOCK_open); /* - If thd->is_error() is not set, we either need discover - (error == 7), or the error was silenced by the prelocking - handler (error == 0), in which case we should skip this + If thd->is_error() is not set, we either need discover or the error was + silenced by the prelocking handler, in which case we should skip this table. */ - if (error == 7 && !thd->is_error()) + if (error == OPEN_FRM_DISCOVER && !thd->is_error()) { (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, table_list); @@ -3172,7 +3172,7 @@ retry_share: { my_free(table); - if (error == 7) + if (error == OPEN_FRM_DISCOVER) (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, table_list); else if (share->crashed) @@ -3847,7 +3847,7 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, MEM_ROOT *mem_root, uint flags) { TABLE not_used; - int error; + enum open_frm_error error; my_hash_value_type hash_value; TABLE_SHARE *share; @@ -3934,7 +3934,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) uint cache_key_length; TABLE_SHARE *share; TABLE *entry; - int not_used; + enum open_frm_error not_used; bool result= TRUE; my_hash_value_type hash_value; diff --git a/sql/sql_base.h b/sql/sql_base.h index 1cd36160309..e0612397361 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -108,7 +108,8 @@ create_table_def_key(char *key, const char *db, const char *table_name) } TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, enum read_frm_op op, int *error, + uint key_length, enum read_frm_op op, + enum open_frm_error *error, my_hash_value_type hash_value); void release_table_share(TABLE_SHARE *share); TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d63e8221654..7afbd3a7f9c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4305,7 +4305,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, TABLE tbl; TABLE_LIST table_list; uint res= 0; - int not_used; + enum open_frm_error not_used; my_hash_value_type hash_value; char key[MAX_DBKEY_LENGTH]; uint key_length; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7072cb38138..ad30b26908a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2323,8 +2323,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, !dont_log_query); /* No error if non existent table and 'IF EXIST' clause or view */ - if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && - (if_exists || table_type == NULL)) + if (error == ENOENT || (error == HA_ERR_NO_SUCH_TABLE && + (if_exists || table_type == NULL))) { error= 0; thd->clear_error(); diff --git a/sql/table.cc b/sql/table.cc index a0012e2e0d0..661d448b743 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -64,7 +64,7 @@ LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") }; /* Functions defined in this file */ -static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *buf); +static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image); static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, char **names); static uint find_field(Field **fields, uchar *record, uint start, uint length); @@ -608,20 +608,13 @@ static bool has_disabled_path_chars(const char *str) table_def_cache The data is returned in 'share', which is alloced by alloc_table_share().. The code assumes that share is initialized. - - RETURN VALUES - 0 ok - 1 Error (see open_table_error) - 2 Error (see open_table_error) - 3 Wrong data in .frm file - 4 Error (see open_table_error) - 5 Error (see open_table_error: charset unavailable) - 6 Unknown .frm version */ -int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) +enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, + enum read_frm_op op) { - int error, table_type; + enum open_frm_error error; + bool is_binary_frm= false; bool error_given; File file; uchar head[64]; @@ -631,7 +624,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, share->table_name.str, share->normalized_path.str)); - error= 1; + error= OPEN_FRM_OPEN_ERROR; error_given= 0; strxmov(path, share->normalized_path.str, reg_ext, NullS); @@ -684,31 +677,38 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) share->normalized_path.length= length; } - error= 4; if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP))) + { + error = my_errno == HA_ERR_FILE_TOO_SHORT + ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR; goto err; + } if (head[0] == (uchar) 254 && head[1] == 1) { if (head[2] == FRM_VER || head[2] == FRM_VER+1 || (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)) { - table_type= 1; + is_binary_frm= true; } else { - error= 6; // Unknown .frm version + my_printf_error(ER_NOT_FORM_FILE, + "Table '%-.64s' was created with a different version " + "of MySQL and cannot be read", + MYF(0), path); + error= OPEN_FRM_ERROR_ALREADY_ISSUED; goto err; } } else if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0) { - error= 5; + error= OPEN_FRM_NO_VIEWS; if (memcmp(head+5,"VIEW",4) == 0) { share->is_view= 1; if (op == FRM_READ_NO_ERROR_FOR_VIEW) - error= 0; + error= OPEN_FRM_OK; } goto err; } @@ -716,7 +716,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) goto err; /* No handling of text based files yet */ - if (table_type == 1) + if (is_binary_frm) { MY_STAT stats; uchar *buf; @@ -740,7 +740,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); old_root= *root_ptr; *root_ptr= &share->mem_root; - error= open_binary_frm(thd, share, buf); + error= open_binary_frm(thd, share, buf) ? OPEN_FRM_CORRUPTED : OPEN_FRM_OK; *root_ptr= old_root; error_given= 1; my_free(buf); @@ -760,7 +760,8 @@ err_not_open: if (error && !error_given) { share->error= error; - open_table_error(share, error, (share->open_errno= my_errno), 0); + share->open_errno= my_errno; + open_table_error(share, error, share->open_errno); } DBUG_RETURN(error); @@ -779,9 +780,8 @@ err_not_open: They're still set, for compatibility reasons, but never read. */ -static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) +static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) { - int error, errarg= 0; uint new_frm_ver, field_pack_length, new_field_pack_flag; uint interval_count, interval_parts, read_length, int_length; uint db_create_options, keys, key_parts, n_length; @@ -820,8 +820,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) new_frm_ver= (frm_image[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; - error= 3; - /* Position of the form in the form file. */ len = uint2korr(frm_image+4); if (!(pos= uint4korr(frm_image + 64 + len))) @@ -885,7 +883,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) share->db_record_offset= 1; if (db_create_options & HA_OPTION_LONG_BLOB_PTR) share->blob_ptr_size= portable_sizeof_char_ptr; - error=4; share->max_rows= uint4korr(frm_image+18); share->min_rows= uint4korr(frm_image+22); @@ -1125,7 +1122,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) /* Check if the partitioning engine is ready */ if (!plugin_is_ready(&name, MYSQL_STORAGE_ENGINE_PLUGIN)) { - error= 8; my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-partition"); goto err; @@ -1140,7 +1136,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) else if (!tmp_plugin) { /* purecov: begin inspected */ - error= 8; name.str[name.length]=0; my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str); goto err; @@ -1238,7 +1233,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) } share->key_block_size= uint2korr(frm_image+62); - error=4; extra_rec_buf_length= uint2korr(frm_image+59); rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length); share->rec_buff_length= rec_buff_length; @@ -1396,7 +1390,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) geom_type= (Field::geometry_type) strpos[14]; charset= &my_charset_bin; #else - error= 4; // unsupported field type goto err; #endif } @@ -1407,8 +1400,16 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) charset= &my_charset_bin; else if (!(charset= get_charset(csid, MYF(0)))) { - error= 5; // Unknown or unavailable charset - errarg= (int) csid; + const char *csname= get_charset_name((uint) csid); + char tmp[10]; + if (!csname || csname[0] =='?') + { + my_snprintf(tmp, sizeof(tmp), "#%d", csid); + csname= tmp; + } + my_printf_error(ER_UNKNOWN_COLLATION, + "Unknown collation '%s' in table '%-.64s' definition", + MYF(0), csname, share->table_name.str); goto err; } } @@ -1452,10 +1453,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if (opt_interval_id) interval_nr= (uint)vcol_screen_pos[3]; else if ((uint)vcol_screen_pos[0] != 1) - { - error= 4; goto err; - } + fld_stored_in_db= (bool) (uint) vcol_screen_pos[2]; vcol_expr_length= vcol_info_length - (uint)(FRM_VCOL_HEADER_SIZE(opt_interval_id)); @@ -1554,10 +1553,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) (TYPELIB*) 0), share->fieldnames.type_names[i]); if (!reg_field) // Not supported field type - { - error= 4; - goto err; /* purecov: inspected */ - } + goto err; + reg_field->field_index= i; reg_field->comment=comment; @@ -1583,20 +1580,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if (reg_field->unireg_check == Field::NEXT_NUMBER) share->found_next_number_field= field_ptr; - if (use_hash) - { - if (my_hash_insert(&share->name_hash, - (uchar*) field_ptr)) - { - /* - Set return code 8 here to indicate that an error has - occurred but that the error message already has been - sent (OOM). - */ - error= 8; - goto err; - } - } + if (use_hash && my_hash_insert(&share->name_hash, (uchar*) field_ptr)) + goto err; if (!reg_field->stored_in_db) { share->stored_fields--; @@ -1748,10 +1733,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) (uint) key_part->offset, (uint) key_part->length); if (!key_part->fieldnr) - { - error= 4; // Wrong file goto err; - } + field= key_part->field= share->field[key_part->fieldnr-1]; key_part->type= field->key_type(); if (field->null_ptr) @@ -1924,11 +1907,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) share->default_values, reg_field, &share->next_number_key_offset, &share->next_number_keypart)) < 0) - { - /* Wrong field definition */ - error= 4; - goto err; - } + goto err; // Wrong field definition else reg_field->flags |= AUTO_INCREMENT_FLAG; } @@ -1974,12 +1953,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if (use_hash) (void) my_hash_check(&share->name_hash); #endif - DBUG_RETURN (0); + DBUG_RETURN(0); err: - share->error= error; + share->error= OPEN_FRM_CORRUPTED; share->open_errno= my_errno; - share->errarg= errarg; delete handler_file; my_hash_free(&share->name_hash); if (share->ha_data_destroy) @@ -1995,8 +1973,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) } #endif /* WITH_PARTITION_STORAGE_ENGINE */ - open_table_error(share, error, share->open_errno, errarg); - DBUG_RETURN(error); + if (!thd->is_error()) + open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno); + + DBUG_RETURN(1); } /* open_binary_frm */ /* @@ -2306,11 +2286,12 @@ end: 7 Table definition has changed in engine */ -int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, - uint db_stat, uint prgflag, uint ha_open_flags, - TABLE *outparam, bool is_create_table) +enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, + const char *alias, uint db_stat, uint prgflag, + uint ha_open_flags, TABLE *outparam, + bool is_create_table) { - int error; + enum open_frm_error error; uint records, i, bitmap_size; bool error_reported= FALSE; uchar *record, *bitmaps; @@ -2322,7 +2303,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_VIEW; // not a view - error= 1; + error= OPEN_FRM_ERROR_ALREADY_ISSUED; // for OOM errors below bzero((char*) outparam, sizeof(*outparam)); outparam->in_use= thd; outparam->s= share; @@ -2351,7 +2332,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, DBUG_ASSERT(!db_stat); } - error= 4; outparam->reginfo.lock_type= TL_UNLOCK; outparam->current_lock= F_UNLCK; records=0; @@ -2504,7 +2484,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, &(*field_ptr)->vcol_info->expr_str, &error_reported)) { - error= 4; // in case no error is reported + error= OPEN_FRM_CORRUPTED; goto err; } *(vfield_ptr++)= *field_ptr; @@ -2615,53 +2595,32 @@ partititon_err: outparam->default_column_bitmaps(); /* The table struct is now initialized; Open the table */ - error= 2; if (db_stat) { - int ha_err; - if ((ha_err= (outparam->file-> - ha_open(outparam, share->normalized_path.str, - (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), - (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : - ((db_stat & HA_WAIT_IF_LOCKED) || - (specialflag & SPECIAL_WAIT_IF_LOCKED)) ? - HA_OPEN_WAIT_IF_LOCKED : - (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ? - HA_OPEN_ABORT_IF_LOCKED : - HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags)))) + if (db_stat & HA_OPEN_TEMPORARY) + ha_open_flags|= HA_OPEN_TMP_TABLE; + else if ((db_stat & HA_WAIT_IF_LOCKED) || + (specialflag & SPECIAL_WAIT_IF_LOCKED)) + ha_open_flags|= HA_OPEN_WAIT_IF_LOCKED; + else if (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) + ha_open_flags|= HA_OPEN_ABORT_IF_LOCKED; + else + ha_open_flags|= HA_OPEN_IGNORE_IF_LOCKED; + + int ha_err= outparam->file->ha_open(outparam, share->normalized_path.str, + (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR), + ha_open_flags); + if (ha_err) { + share->open_errno= ha_err; /* Set a flag if the table is crashed and it can be auto. repaired */ share->crashed= (outparam->file->auto_repair(ha_err) && !(ha_open_flags & HA_OPEN_FOR_REPAIR)); - - switch (ha_err) - { - case HA_ERR_NO_SUCH_TABLE: - /* - The table did not exists in storage engine, use same error message - as if the .frm file didn't exist - */ - error= 1; - my_errno= ENOENT; - break; - case EMFILE: - /* - Too many files opened, use same error message as if the .frm - file can't open - */ - DBUG_PRINT("error", ("open file: %s failed, too many files opened (errno: %d)", - share->normalized_path.str, ha_err)); - error= 1; - my_errno= EMFILE; - break; - default: - outparam->file->print_error(ha_err, MYF(0)); - error_reported= TRUE; - if (ha_err == HA_ERR_TABLE_DEF_CHANGED) - error= 7; - break; - } - goto err; /* purecov: inspected */ + outparam->file->print_error(ha_err, MYF(0)); + error_reported= TRUE; + if (ha_err == HA_ERR_TABLE_DEF_CHANGED) + error= OPEN_FRM_DISCOVER; + goto err; } } @@ -2675,11 +2634,11 @@ partititon_err: thd->status_var.opened_tables++; thd->lex->context_analysis_only= save_context_analysis_only; - DBUG_RETURN (0); + DBUG_RETURN (OPEN_FRM_OK); err: if (! error_reported) - open_table_error(share, error, my_errno, 0); + open_table_error(share, error, my_errno); delete outparam->file; #ifdef WITH_PARTITION_STORAGE_ENGINE if (outparam->part_info) @@ -2864,16 +2823,15 @@ ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames, /* error message when opening a form file */ -void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) +void open_table_error(TABLE_SHARE *share, enum open_frm_error error, + int db_errno) { - int err_no; char buff[FN_REFLEN]; myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log DBUG_ENTER("open_table_error"); switch (error) { - case 7: - case 1: + case OPEN_FRM_OPEN_ERROR: /* Test if file didn't exists. We have to also test for EINVAL as this may happen on windows when opening a file with a not legal file name @@ -2887,47 +2845,23 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) errortype, buff, db_errno); } break; - case 2: - { - const char *datext= ""; - - if (share->db_type() && share->db_type()->tablefile_extensions[0]) - datext= share->db_type()->tablefile_extensions[0]; - - err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ? - ER_FILE_USED : ER_CANT_OPEN_FILE; - strxmov(buff, share->normalized_path.str, datext, NullS); - my_error(err_no,errortype, buff, db_errno); + case OPEN_FRM_OK: + DBUG_ASSERT(0); // open_table_error() is never called for this one break; - } - case 5: - { - const char *csname= get_charset_name((uint) errarg); - char tmp[10]; - if (!csname || csname[0] =='?') - { - my_snprintf(tmp, sizeof(tmp), "#%d", errarg); - csname= tmp; - } - my_printf_error(ER_UNKNOWN_COLLATION, - "Unknown collation '%s' in table '%-.64s' definition", - MYF(0), csname, share->table_name.str); + case OPEN_FRM_ERROR_ALREADY_ISSUED: break; - } - case 6: - strxmov(buff, share->normalized_path.str, reg_ext, NullS); - my_printf_error(ER_NOT_FORM_FILE, - "Table '%-.64s' was created with a different version " - "of MySQL and cannot be read", - MYF(0), buff); + case OPEN_FRM_DISCOVER: + case OPEN_FRM_NO_VIEWS: + DBUG_ASSERT(0); // open_table_error() is never called for this one break; - case 8: - break; - default: /* Better wrong error than none */ - case 4: + case OPEN_FRM_CORRUPTED: strxmov(buff, share->normalized_path.str, reg_ext, NullS); my_error(ER_NOT_FORM_FILE, errortype, buff); break; + case OPEN_FRM_READ_ERROR: + strxmov(buff, share->normalized_path.str, reg_ext, NullS); + my_error(ER_ERROR_ON_READ, errortype, buff, db_errno); + break; } DBUG_VOID_RETURN; } /* open_table_error */ diff --git a/sql/table.h b/sql/table.h index 18ed635aae8..737afc38300 100644 --- a/sql/table.h +++ b/sql/table.h @@ -562,6 +562,16 @@ typedef I_P_List alter_table_flags = innobase_alter_table_flags; innobase_hton->kill_query = innobase_kill_query; + if (srv_file_per_table) + innobase_hton->tablefile_extensions = ha_innobase_exts; + ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR); #ifndef DBUG_OFF @@ -3349,13 +3359,6 @@ ha_innobase::table_flags() const return int_table_flags | HA_BINLOG_STMT_CAPABLE; } -/****************************************************************//** -Gives the file extension of an InnoDB single-table tablespace. */ -static const char* ha_innobase_exts[] = { - ".ibd", - NullS -}; - /****************************************************************//** Returns the table type (storage engine name). @return table type */ diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 5ba58fe439b..e90b62aa3db 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -2615,7 +2615,9 @@ innobase_init( innobase_hton->release_temporary_latches=innobase_release_temporary_latches; innobase_hton->alter_table_flags = innobase_alter_table_flags; innobase_hton->kill_query = innobase_kill_query; - innobase_hton->tablefile_extensions = ha_innobase_exts; + + if (srv_file_per_table) + innobase_hton->tablefile_extensions = ha_innobase_exts; ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR); From d71b75c90d86f6a654a7e93ac383b4000533ffbc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:34:27 +0200 Subject: [PATCH 29/87] moving LOCK_open into get_table_share() --- sql/sql_admin.cc | 2 - sql/sql_base.cc | 185 +++++++++++++++++++++++++---------------------- sql/sql_show.cc | 9 +-- sql/sql_view.cc | 5 +- sql/table.h | 4 +- 5 files changed, 107 insertions(+), 98 deletions(-) diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 849a00a7df7..0410d72bafc 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -128,10 +128,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, has_mdl_lock= TRUE; hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, table_list, key, key_length, FRM_READ_TABLE_ONLY, ¬_used, hash_value); - mysql_mutex_unlock(&LOCK_open); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 03728fcd372..f58e121a511 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -167,6 +167,24 @@ Repair_mrg_table_error_handler::handle_condition(THD *, Protects table_def_hash, used and unused lists in the TABLE_SHARE object, LRU lists of used TABLEs and used TABLE_SHAREs, refresh_version and the table id counter. + In particular: + + end_of_unused_share + last_table_id + oldest_unused_share + refresh_version + table_cache_count + table_def_cache + table_def_shutdown_in_progress + unused_tables + TABLE::next + TABLE::prev + TABLE_SHARE::free_tables + TABLE_SHARE::m_flush_tickets + TABLE_SHARE::next + TABLE_SHARE::prev + TABLE_SHARE::ref_count + TABLE_SHARE::used_tables */ mysql_mutex_t LOCK_open; @@ -584,6 +602,8 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, *error= OPEN_FRM_OK; + mysql_mutex_lock(&LOCK_open); + /* To be able perform any operation on table we should own some kind of metadata lock on it. @@ -594,47 +614,46 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, MDL_SHARED)); /* Read table definition from cache */ - if ((share= (TABLE_SHARE*) my_hash_search_using_hash_value(&table_def_cache, - hash_value, (uchar*) key, key_length))) - goto found; - - if (!(share= alloc_table_share(table_list, key, key_length))) + share= (TABLE_SHARE*) my_hash_search_using_hash_value(&table_def_cache, + hash_value, (uchar*) key, key_length); + if (!share) { - DBUG_RETURN(0); + if (!(share= alloc_table_share(table_list, key, key_length))) + goto err; + + /* + We assign a new table id under the protection of LOCK_open. + We do this instead of creating a new mutex + and using it for the sole purpose of serializing accesses to a + static variable, we assign the table id here. We assign it to the + share before inserting it into the table_def_cache to be really + sure that it cannot be read from the cache without having a table + id assigned. + + CAVEAT. This means that the table cannot be used for + binlogging/replication purposes, unless get_table_share() has been + called directly or indirectly. + */ + assign_new_table_id(share); + + if (my_hash_insert(&table_def_cache, (uchar*) share)) + { + free_table_share(share); + goto err; + } + if (open_table_def(thd, share, op)) + { + *error= share->error; + (void) my_hash_delete(&table_def_cache, (uchar*) share); + goto err; + } + share->ref_count++; // Mark in use + DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", + (ulong) share, share->ref_count)); + + goto end; } - /* - We assign a new table id under the protection of LOCK_open. - We do this instead of creating a new mutex - and using it for the sole purpose of serializing accesses to a - static variable, we assign the table id here. We assign it to the - share before inserting it into the table_def_cache to be really - sure that it cannot be read from the cache without having a table - id assigned. - - CAVEAT. This means that the table cannot be used for - binlogging/replication purposes, unless get_table_share() has been - called directly or indirectly. - */ - assign_new_table_id(share); - - if (my_hash_insert(&table_def_cache, (uchar*) share)) - { - free_table_share(share); - DBUG_RETURN(0); // return error - } - if (open_table_def(thd, share, op)) - { - *error= share->error; - (void) my_hash_delete(&table_def_cache, (uchar*) share); - DBUG_RETURN(0); - } - share->ref_count++; // Mark in use - DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", - (ulong) share, share->ref_count)); - DBUG_RETURN(share); - -found: /* We found an existing table definition. Return it if we didn't get an error when reading the table definition from file. @@ -643,12 +662,13 @@ found: { /* Table definition contained an error */ open_table_error(share, share->error, share->open_errno); - DBUG_RETURN(0); + goto err; } + if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW) { open_table_error(share, OPEN_FRM_NO_VIEWS, ENOENT); - DBUG_RETURN(0); + goto err; } ++share->ref_count; @@ -673,6 +693,12 @@ found: DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", (ulong) share, share->ref_count)); + goto end; + +err: + share= 0; +end: + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(share); } @@ -3013,13 +3039,10 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, retry_share: - mysql_mutex_lock(&LOCK_open); - if (!(share= get_table_share_with_discover(thd, table_list, key, key_length, FRM_READ_NO_ERROR_FOR_VIEW, &error, hash_value))) { - mysql_mutex_unlock(&LOCK_open); /* If thd->is_error() is not set, we either need discover or the error was silenced by the prelocking handler, in which case we should skip this @@ -3042,7 +3065,7 @@ retry_share: if (table_list->parent_l) { my_error(ER_WRONG_MRG_TABLE, MYF(0)); - goto err_unlock; + goto err_lock; } /* @@ -3050,12 +3073,12 @@ retry_share: that it was a view when the statement was prepared. */ if (check_and_update_table_version(thd, table_list, share)) - goto err_unlock; + goto err_lock; if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->table_name); - goto err_unlock; + goto err_lock; } /* Open view */ @@ -3065,7 +3088,9 @@ retry_share: READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, thd->open_options, 0, table_list, mem_root)) - goto err_unlock; + goto err_lock; + + mysql_mutex_lock(&LOCK_open); /* TODO: Don't free this */ release_table_share(share); @@ -3087,12 +3112,12 @@ retry_share: { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->table_name); - goto err_unlock; + goto err_lock; } + mysql_mutex_lock(&LOCK_open); if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) || - (share->protected_against_usage() && - !(flags & MYSQL_OPEN_FOR_REPAIR))) + (share->protected_against_usage() && !(flags & MYSQL_OPEN_FOR_REPAIR))) { if (share->has_old_version()) { @@ -3144,12 +3169,12 @@ retry_share: { table= share->free_tables.front(); table_def_use_table(thd, table); - /* We need to release share as we have EXTRA reference to it in our hands. */ + /* Release the share as we hold an extra reference to it */ release_table_share(share); } else { - /* We have too many TABLE instances around let us try to get rid of them. */ + /* If we have too many TABLE instances around, try to get rid of them */ while (table_cache_count > table_cache_size && unused_tables) free_cache_entry(unused_tables); @@ -3218,7 +3243,6 @@ retry_share: err_lock: mysql_mutex_lock(&LOCK_open); -err_unlock: release_table_share(share); mysql_mutex_unlock(&LOCK_open); @@ -3853,30 +3877,26 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key, cache_key_length); - mysql_mutex_lock(&LOCK_open); - if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, FRM_READ_NO_ERROR_FOR_VIEW, &error, hash_value))) - goto err; + return TRUE; - if (share->is_view && - !open_new_frm(thd, share, alias, - (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | - HA_GET_INDEX | HA_TRY_READ_ONLY), - READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | - flags, thd->open_options, ¬_used, table_list, - mem_root)) - { - release_table_share(share); - mysql_mutex_unlock(&LOCK_open); - return FALSE; - } + bool err= !share->is_view || + open_new_frm(thd, share, alias, + (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | + HA_GET_INDEX | HA_TRY_READ_ONLY), + READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | flags, + thd->open_options, ¬_used, table_list, mem_root); - my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str, "VIEW"); + mysql_mutex_lock(&LOCK_open); release_table_share(share); -err: mysql_mutex_unlock(&LOCK_open); - return TRUE; + + if (err) + my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, + table_list->table_name, "VIEW"); + + return err; } @@ -3942,27 +3962,19 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) thd->clear_error(); + if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) + return result; + hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key, cache_key_length); - mysql_mutex_lock(&LOCK_open); if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, hash_value))) - goto end_unlock; + goto end_free; if (share->is_view) - { - release_table_share(share); - goto end_unlock; - } - - if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) - { - release_table_share(share); - goto end_unlock; - } - mysql_mutex_unlock(&LOCK_open); + goto end_release; if (open_table_from_share(thd, share, table_list->alias, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | @@ -3987,16 +3999,17 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) closefrm(entry, 0); result= FALSE; } - my_free(entry); +end_release: mysql_mutex_lock(&LOCK_open); release_table_share(share); /* Remove the repaired share from the table cache. */ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db, table_list->table_name, TRUE); -end_unlock: mysql_mutex_unlock(&LOCK_open); +end_free: + my_free(entry); return result; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7afbd3a7f9c..45c3318987c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4382,13 +4382,12 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, key_length= create_table_def_key(thd, key, &table_list, 0); hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, &table_list, key, key_length, FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, hash_value); if (!share) { res= 0; - goto end_unlock; + goto end; } if (share->is_view) @@ -4437,10 +4436,10 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, free_root(&tbl.mem_root, MYF(0)); } -end_share: - release_table_share(share); -end_unlock: +end_share: + mysql_mutex_lock(&LOCK_open); + release_table_share(share); mysql_mutex_unlock(&LOCK_open); end: diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 8ce2c145d01..67004dc538d 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1707,9 +1707,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) some_views_deleted= TRUE; /* - For a view, there is a TABLE_SHARE object, but its - ref_count never goes above 1. Remove it from the table - definition cache, in case the view was cached. + For a view, there is a TABLE_SHARE object. + Remove it from the table definition cache, in case the view was cached. */ tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name, FALSE); diff --git a/sql/table.h b/sql/table.h index 737afc38300..520d5a2f2b5 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2188,9 +2188,9 @@ private: #else inline void set_check_merged() {} #endif - /** See comments for set_metadata_id() */ + /** See comments for set_table_ref_id() */ enum enum_table_ref_type m_table_ref_type; - /** See comments for set_metadata_id() */ + /** See comments for set_table_ref_id() */ ulong m_table_ref_version; }; From 474e5ecd1f4e39e57f7677e5d9dc2bd44da4768f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:34:49 +0200 Subject: [PATCH 30/87] Don't hold LOCK_open over open_table_def/open_binary_frm call --- sql/sql_base.cc | 28 ++++++++++++++++++++++------ sql/table.cc | 5 +++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f58e121a511..cbcd8045348 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -597,6 +597,7 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, enum open_frm_error *error, my_hash_value_type hash_value) { + bool open_failed; TABLE_SHARE *share; DBUG_ENTER("get_table_share"); @@ -641,19 +642,33 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, free_table_share(share); goto err; } - if (open_table_def(thd, share, op)) + share->ref_count++; // Mark in use + share->error= OPEN_FRM_OPEN_ERROR; + mysql_mutex_lock(&share->LOCK_ha_data); + mysql_mutex_unlock(&LOCK_open); + + open_failed= open_table_def(thd, share, op); + + mysql_mutex_unlock(&share->LOCK_ha_data); + mysql_mutex_lock(&LOCK_open); + + if (open_failed) { *error= share->error; + share->ref_count--; (void) my_hash_delete(&table_def_cache, (uchar*) share); goto err; } - share->ref_count++; // Mark in use DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", (ulong) share, share->ref_count)); goto end; } + /* make sure that open_table_def() for this share is not running */ + mysql_mutex_lock(&share->LOCK_ha_data); + mysql_mutex_unlock(&share->LOCK_ha_data); + /* We found an existing table definition. Return it if we didn't get an error when reading the table definition from file. @@ -863,8 +878,9 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) mysql_mutex_assert_owner(&LOCK_open); key_length= create_table_def_key(key, db, table_name); - return (TABLE_SHARE*) my_hash_search(&table_def_cache, - (uchar*) key, key_length); + TABLE_SHARE* share= (TABLE_SHARE*)my_hash_search(&table_def_cache, + (uchar*) key, key_length); + return !share || share->error ? 0 : share; } @@ -2954,12 +2970,12 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, global read lock until end of this statement in order to have this statement blocked by active FLUSH TABLES WITH READ LOCK. - We don't block acquire this protection under LOCK TABLES as + We don't need to acquire this protection under LOCK TABLES as such protection already acquired at LOCK TABLES time and not released until UNLOCK TABLES. We don't block statements which modify only temporary tables - as these tables are not preserved by backup by any form of + as these tables are not preserved by any form of backup which uses FLUSH TABLES WITH READ LOCK. TODO: The fact that we sometimes acquire protection against diff --git a/sql/table.cc b/sql/table.cc index 661d448b743..6c6dea48bfd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -751,15 +751,16 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, if (!error) thd->status_var.opened_shares++; - DBUG_RETURN(error); + goto err_not_open; err: mysql_file_close(file, MYF(MY_WME)); err_not_open: + share->error= error; + if (error && !error_given) { - share->error= error; share->open_errno= my_errno; open_table_error(share, error, share->open_errno); } From b9f42f4b7a08d4f6d46ecaba3595b38af0a6525d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:34:58 +0200 Subject: [PATCH 31/87] rename open_binary_frm() to TABLE_SHARE::init_from_binary_frm_image() simplify open_table_def() --- sql/datadict.cc | 4 +- sql/table.cc | 132 +++++++++++++++++++----------------------------- sql/table.h | 2 + sql/unireg.h | 9 ++++ 4 files changed, 65 insertions(+), 82 deletions(-) diff --git a/sql/datadict.cc b/sql/datadict.cc index 4aa024b3b44..3b125d47235 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -55,9 +55,7 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) if the following test is true (arg #3). This should not have effect on return value from this function (default FRMTYPE_TABLE) */ - if (header[0] != (uchar) 254 || header[1] != 1 || - (header[2] != FRM_VER && header[2] != FRM_VER+1 && - (header[2] < FRM_VER+3 || header[2] > FRM_VER+4))) + if (!is_binary_frm_header(header)) DBUG_RETURN(FRMTYPE_TABLE); /* diff --git a/sql/table.cc b/sql/table.cc index 6c6dea48bfd..cd933e0e4a6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -64,7 +64,6 @@ LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") }; /* Functions defined in this file */ -static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image); static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, char **names); static uint find_field(Field **fields, uchar *record, uint start, uint length); @@ -317,7 +316,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key, strmov(share->path.str, path); share->normalized_path.str= share->path.str; share->normalized_path.length= path_length; - + share->table_category= get_table_category(& share->db, & share->table_name); share->set_refresh_version(); /* @@ -613,10 +612,10 @@ static bool has_disabled_path_chars(const char *str) enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, enum read_frm_op op) { - enum open_frm_error error; - bool is_binary_frm= false; - bool error_given; + bool error_given= false; File file; + MY_STAT stats; + uchar *buf; uchar head[64]; char path[FN_REFLEN]; MEM_ROOT **root_ptr, *old_root; @@ -624,8 +623,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, share->table_name.str, share->normalized_path.str)); - error= OPEN_FRM_OPEN_ERROR; - error_given= 0; + share->error= OPEN_FRM_OPEN_ERROR; strxmov(path, share->normalized_path.str, reg_ext, NullS); if ((file= mysql_file_open(key_file_frm, @@ -679,76 +677,52 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP))) { - error = my_errno == HA_ERR_FILE_TOO_SHORT - ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR; + share->error = my_errno == HA_ERR_FILE_TOO_SHORT + ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR; goto err; } - if (head[0] == (uchar) 254 && head[1] == 1) + if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0) { - if (head[2] == FRM_VER || head[2] == FRM_VER+1 || - (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)) - { - is_binary_frm= true; - } - else - { - my_printf_error(ER_NOT_FORM_FILE, - "Table '%-.64s' was created with a different version " - "of MySQL and cannot be read", - MYF(0), path); - error= OPEN_FRM_ERROR_ALREADY_ISSUED; - goto err; - } - } - else if (memcmp(head, STRING_WITH_LEN("TYPE=")) == 0) - { - error= OPEN_FRM_NO_VIEWS; - if (memcmp(head+5,"VIEW",4) == 0) - { - share->is_view= 1; - if (op == FRM_READ_NO_ERROR_FOR_VIEW) - error= OPEN_FRM_OK; - } + share->is_view= 1; + share->error= op == FRM_READ_NO_ERROR_FOR_VIEW + ? OPEN_FRM_OK : OPEN_FRM_NO_VIEWS; goto err; } - else + if (!is_binary_frm_header(head)) + { + /* No handling of text based files yet */ + share->error = OPEN_FRM_CORRUPTED; + goto err; + } + + if (my_fstat(file, &stats, MYF(0))) goto err; - /* No handling of text based files yet */ - if (is_binary_frm) + if (!(buf= (uchar*)my_malloc(stats.st_size, MYF(MY_THREAD_SPECIFIC|MY_WME)))) + goto err; + + memcpy(buf, head, sizeof(head)); + + if (mysql_file_read(file, buf + sizeof(head), + stats.st_size - sizeof(head), MYF(MY_NABP))) { - MY_STAT stats; - uchar *buf; - - if (my_fstat(file, &stats, MYF(0))) - goto err; - - if (!(buf= (uchar*)my_malloc(stats.st_size, MYF(MY_THREAD_SPECIFIC|MY_WME)))) - goto err; - - memcpy(buf, head, sizeof(head)); - - if (mysql_file_read(file, buf + sizeof(head), - stats.st_size - sizeof(head), MYF(MY_NABP))) - { - my_free(buf); - goto err; - } - mysql_file_close(file, MYF(MY_WME)); - - root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); - old_root= *root_ptr; - *root_ptr= &share->mem_root; - error= open_binary_frm(thd, share, buf) ? OPEN_FRM_CORRUPTED : OPEN_FRM_OK; - *root_ptr= old_root; - error_given= 1; + share->error = my_errno == HA_ERR_FILE_TOO_SHORT + ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR; my_free(buf); + goto err; } + mysql_file_close(file, MYF(MY_WME)); - share->table_category= get_table_category(& share->db, & share->table_name); + root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); + old_root= *root_ptr; + *root_ptr= &share->mem_root; + share->init_from_binary_frm_image(thd, buf); + error_given= true; + *root_ptr= old_root; + my_free(buf); - if (!error) + if (!share->error) thd->status_var.opened_shares++; goto err_not_open; @@ -757,15 +731,13 @@ err: mysql_file_close(file, MYF(MY_WME)); err_not_open: - share->error= error; - - if (error && !error_given) + if (share->error && !error_given) { share->open_errno= my_errno; - open_table_error(share, error, share->open_errno); + open_table_error(share, share->error, share->open_errno); } - DBUG_RETURN(error); + DBUG_RETURN(share->error); } @@ -781,8 +753,9 @@ err_not_open: They're still set, for compatibility reasons, but never read. */ -static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) +bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const uchar *frm_image) { + TABLE_SHARE *share= this; uint new_frm_ver, field_pack_length, new_field_pack_flag; uint interval_count, interval_parts, read_length, int_length; uint db_create_options, keys, key_parts, n_length; @@ -791,9 +764,9 @@ static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) uint i,j; bool use_hash; char *keynames, *names, *comment_pos; - uchar *forminfo; - uchar *record; - uchar *disk_buff, *strpos, *null_flags, *null_pos; + const uchar *forminfo; + uchar *record, *null_flags, *null_pos; + const uchar *disk_buff, *strpos; ulong pos, record_offset; ulong *rec_per_key= NULL; ulong rec_buff_length; @@ -807,7 +780,7 @@ static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) bool null_bits_are_used; uint vcol_screen_length, UNINIT_VAR(options_len); char *vcol_screen_pos; - uchar *UNINIT_VAR(options); + const uchar *UNINIT_VAR(options); KEY first_keyinfo; uint len; KEY_PART_INFO *first_key_part= NULL; @@ -863,7 +836,7 @@ static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) share->avg_row_length= uint4korr(frm_image+34); share->transactional= (ha_choice) (frm_image[39] & 3); share->page_checksum= (ha_choice) ((frm_image[39] >> 2) & 3); - share->row_type= (row_type) frm_image[40]; + share->row_type= (enum row_type) frm_image[40]; share->table_charset= get_charset((((uint) frm_image[41]) << 8) + (uint) frm_image[38],MYF(0)); share->null_field_first= 1; @@ -1068,7 +1041,7 @@ static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if ((n_length= uint4korr(frm_image+55))) { /* Read extra data segment */ - uchar *next_chunk, *buff_end; + const uchar *next_chunk, *buff_end; DBUG_PRINT("info", ("extra segment size is %u bytes", n_length)); next_chunk= frm_image + record_offset + share->reclength; buff_end= next_chunk + n_length; @@ -1335,7 +1308,7 @@ static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) null_bits_are_used= share->null_fields != 0; if (share->null_field_first) { - null_flags= null_pos= (uchar*) record+1; + null_flags= null_pos= record+1; null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1; /* null_bytes below is only correct under the condition that @@ -1348,8 +1321,7 @@ static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) else { share->null_bytes= (share->null_fields+7)/8; - null_flags= null_pos= (uchar*) (record + 1 +share->reclength - - share->null_bytes); + null_flags= null_pos= record + 1 + share->reclength - share->null_bytes; null_bit_pos= 0; } #endif @@ -1954,6 +1926,8 @@ static bool open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *frm_image) if (use_hash) (void) my_hash_check(&share->name_hash); #endif + + share->error= OPEN_FRM_OK; DBUG_RETURN(0); err: diff --git a/sql/table.h b/sql/table.h index 520d5a2f2b5..af359377e61 100644 --- a/sql/table.h +++ b/sql/table.h @@ -985,6 +985,8 @@ struct TABLE_SHARE } uint actual_n_key_parts(THD *thd); + + bool init_from_binary_frm_image(THD *thd, const uchar *frm_image); }; diff --git a/sql/unireg.h b/sql/unireg.h index f4e88b0d8d7..702637b0736 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -178,4 +178,13 @@ int rea_create_table(THD *thd, const char *path, List &create_field, uint key_count,KEY *key_info, handler *file); + +static inline bool is_binary_frm_header(uchar *head) +{ + return head[0] == 254 + && head[1] == 1 + && head[2] >= FRM_VER + && head[2] <= FRM_VER+4; +} + #endif From 87a9d60ec625c8f1e8563de648105b36add9e940 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:35:07 +0200 Subject: [PATCH 32/87] revert " revision-id: sanja@askmonty.org-20110511110948-4kdevwzomvk56y1w committer: sanja@askmonty.org branch nick: work-maria-5.1-CREATE-merge timestamp: Wed 2011-05-11 14:09:48 +0300 Bugfix: New table creation/renaming block added if old encoded table present " the old behavior was less inconsistent than the new one. In the new one the error message was sometimes different (under LOCK TABLES e.g.), and there were race conditions (if this CREATE happened when a concurrent ALTER has renamed the old table away but haven't put the new table in place) The old one was like "(when using old table names) for DML #mysql50# prefix is optional, for DDL it's required". --- mysql-test/r/create.result | 35 ++++++++++++------ mysql-test/r/upgrade.result | 8 ++-- mysql-test/t/create.test | 29 +++++++-------- mysql-test/t/upgrade.test | 7 +--- sql/sql_rename.cc | 16 ++++---- sql/sql_table.cc | 74 ++----------------------------------- sql/sql_table.h | 3 -- 7 files changed, 55 insertions(+), 117 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 7c556354d2e..bb3b672858a 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1899,25 +1899,36 @@ create table t3 (a int) row_format=page; drop table t1,t2,t3; # -- End of Bug#45829 -# new table creation/renaming blocked if old encoded table present -create table `t-1` (a int) engine=myisam; -insert into `t-1` values (1); -show tables; -Tables_in_test -t-1 -flush tables; -convert table files in mysql 5.0 file name encoding +create table `#mysql50#t-1` (a int) engine=myisam; +insert into `#mysql50#t-1` values (1); show tables; Tables_in_test #mysql50#t-1 create table `t-1` (a int); -ERROR 42S01: Table '#mysql50#t-1' already exists +show tables; +Tables_in_test +#mysql50#t-1 +t-1 +select * from `t-1`; +a +select * from `#mysql50#t-1`; +a +1 +drop table `t-1`; create table t1 (a int); alter table t1 rename `t-1`; -ERROR 42S01: Table '#mysql50#t-1' already exists +show tables; +Tables_in_test +#mysql50#t-1 +t-1 +drop table `t-1`; +create table t1 (a int); rename table t1 to `t-1`; -ERROR 42S01: Table '#mysql50#t-1' already exists -drop table `#mysql50#t-1`, t1; +show tables; +Tables_in_test +#mysql50#t-1 +t-1 +drop table `#mysql50#t-1`, `t-1`; End of 5.1 tests diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index 4f52fd1e246..d565bb2dbd6 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -41,18 +41,20 @@ t-1 t1 drop database `mysqltest1`; drop database `mysqltest-1`; -drop table if exists `txu@0023p@0023p1`; -drop table if exists `txu#p#p1`; create table `txu#p#p1` (s1 int); insert into `txu#p#p1` values (1); select * from `txu@0023p@0023p1`; ERROR 42S02: Table 'test.txu@0023p@0023p1' doesn't exist create table `txu@0023p@0023p1` (s1 int); -ERROR 42S01: Table '#mysql50#txu@0023p@0023p1' already exists +show tables; +Tables_in_test +txu#p#p1 +txu@0023p@0023p1 select * from `txu#p#p1`; s1 1 drop table `txu#p#p1`; +drop table `txu@0023p@0023p1`; # # Bug#37631 Incorrect key file for table after upgrading from 5.0 to 5.1 # diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index a61f89539cb..f82d859243a 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1559,29 +1559,26 @@ drop table t1,t2,t3; --echo # -- End of Bug#45829 # ---echo # new table creation/renaming blocked if old encoded table present +# new table creation/renaming is NOT blocked if old encoded table present # let $MYSQLD_DATADIR= `select @@datadir`; -create table `t-1` (a int) engine=myisam; -insert into `t-1` values (1); +create table `#mysql50#t-1` (a int) engine=myisam; +insert into `#mysql50#t-1` values (1); show tables; -flush tables; ---echo convert table files in mysql 5.0 file name encoding ---copy_file $MYSQLD_DATADIR/test/t@002d1.MYD $MYSQLD_DATADIR/test/t-1.MYD ---copy_file $MYSQLD_DATADIR/test/t@002d1.MYI $MYSQLD_DATADIR/test/t-1.MYI ---copy_file $MYSQLD_DATADIR/test/t@002d1.frm $MYSQLD_DATADIR/test/t-1.frm ---remove_file $MYSQLD_DATADIR/test/t@002d1.MYD ---remove_file $MYSQLD_DATADIR/test/t@002d1.MYI ---remove_file $MYSQLD_DATADIR/test/t@002d1.frm -show tables; ---error ER_TABLE_EXISTS_ERROR create table `t-1` (a int); +show tables; +# selects can distinguish between the two tables +select * from `t-1`; +select * from `#mysql50#t-1`; +drop table `t-1`; create table t1 (a int); ---error ER_TABLE_EXISTS_ERROR alter table t1 rename `t-1`; ---error ER_TABLE_EXISTS_ERROR +show tables; +drop table `t-1`; +create table t1 (a int); rename table t1 to `t-1`; -drop table `#mysql50#t-1`, t1; +show tables; +drop table `#mysql50#t-1`, `t-1`; --echo --echo End of 5.1 tests diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index a8c875ef764..c6d01a16f49 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -33,18 +33,15 @@ drop database `mysqltest-1`; # # Bug#17142: Crash if create with encoded name # ---disable_warnings -drop table if exists `txu@0023p@0023p1`; -drop table if exists `txu#p#p1`; ---enable_warnings create table `txu#p#p1` (s1 int); insert into `txu#p#p1` values (1); --error 1146 select * from `txu@0023p@0023p1`; ---error ER_TABLE_EXISTS_ERROR create table `txu@0023p@0023p1` (s1 int); +show tables; select * from `txu#p#p1`; drop table `txu#p#p1`; +drop table `txu@0023p@0023p1`; --echo # --echo # Bug#37631 Incorrect key file for table after upgrading from 5.0 to 5.1 diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index c91623cee6e..cf9810db445 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -241,7 +241,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, char *new_table_alias, bool skip_error) { int rc= 1; - char new_name[FN_REFLEN + 1], old_name[FN_REFLEN + 1]; + char name[FN_REFLEN + 1]; const char *new_alias, *old_alias; frm_type_enum frm_type; enum legacy_db_type table_type; @@ -260,17 +260,17 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, } DBUG_ASSERT(new_alias); - build_table_filename(new_name, sizeof(new_name) - 1, + build_table_filename(name, sizeof(name) - 1, new_db, new_alias, reg_ext, 0); - build_table_filename(old_name, sizeof(old_name) - 1, - ren_table->db, old_alias, reg_ext, 0); - if (check_table_file_presence(old_name, - new_name, new_db, new_alias, new_alias, TRUE)) + if (!access(name,F_OK)) { + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(1); // This can't be skipped } + build_table_filename(name, sizeof(name) - 1, + ren_table->db, old_alias, reg_ext, 0); - frm_type= dd_frm_type(thd, old_name, &table_type); + frm_type= dd_frm_type(thd, name, &table_type); switch (frm_type) { case FRMTYPE_TABLE: @@ -322,7 +322,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, default: DBUG_ASSERT(0); // should never happen case FRMTYPE_ERROR: - my_error(ER_FILE_NOT_FOUND, MYF(0), old_name, my_errno); + my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); break; } if (rc && !skip_error) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ad30b26908a..4ab7fc28381 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4036,68 +4036,6 @@ static bool check_if_created_table_can_be_opened(THD *thd, #endif -/** - Check that there is no frm file for given table - - @param old_path path to the old frm file - @param path path to the frm file in new encoding - @param db database name - @param table_name table name - @param alias table name for error message (for new encoding) - @param issue_error should we issue error messages - - @retval FALSE there is no frm file - @retval TRUE there is frm file -*/ - -bool check_table_file_presence(char *old_path, - char *path, - const char *db, - const char *table_name, - const char *alias, - bool issue_error) -{ - if (!access(path,F_OK)) - { - if (issue_error) - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),alias); - return TRUE; - } - { - /* - Check if file of the table in 5.0 file name encoding exists. - - Except case when it is the same table. - */ - char tbl50[FN_REFLEN]; -#ifdef _WIN32 - if (check_if_legal_tablename(table_name) != 0) - { - /* - Check for reserved device names for which access() returns 0 - (CON, AUX etc). - */ - return FALSE; - } -#endif - strxmov(tbl50, mysql_data_home, "/", db, "/", table_name, NullS); - fn_format(tbl50, tbl50, "", reg_ext, MY_UNPACK_FILENAME); - if (!access(tbl50, F_OK) && - (old_path == NULL || - strcmp(old_path, tbl50) != 0)) - { - if (issue_error) - { - strxmov(tbl50, MYSQL50_TABLE_NAME_PREFIX, table_name, NullS); - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), tbl50); - } - return TRUE; - } - } - return FALSE; -} - - /* Create a table @@ -4382,12 +4320,11 @@ bool mysql_create_table_no_lock(THD *thd, if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - if (check_table_file_presence(NULL, path, db, table_name, table_name, - !(create_info->options & - HA_LEX_CREATE_IF_NOT_EXISTS))) + if (!access(path,F_OK)) { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) goto warn; + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); goto err; } /* @@ -6066,7 +6003,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, MDL_request target_mdl_request; int error= 0; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1]; - char old_name_buff[FN_REFLEN + 1]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; char path[FN_REFLEN + 1]; @@ -6273,12 +6209,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, */ build_table_filename(new_name_buff, sizeof(new_name_buff) - 1, new_db, new_name_buff, reg_ext, 0); - build_table_filename(old_name_buff, sizeof(old_name_buff) - 1, - db, table_name, reg_ext, 0); - if (check_table_file_presence(old_name_buff, new_name_buff, new_db, - new_name, new_alias, TRUE)) + if (!access(new_name_buff, F_OK)) { /* Table will be closed in do_command() */ + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); goto err; } } diff --git a/sql/sql_table.h b/sql/sql_table.h index 7826c540487..4dc28aa4933 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -131,9 +131,6 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db, const char *table, const char *ext, uint flags); uint build_table_shadow_filename(char *buff, size_t bufflen, ALTER_PARTITION_PARAM_TYPE *lpt); -bool check_table_file_presence(char *old_path, char *path, const char *db, - const char *table_name, const char *alias, - bool issue_error); bool mysql_create_table(THD *thd, TABLE_LIST *create_table, HA_CREATE_INFO *create_info, Alter_info *alter_info); From b0a5dd73fa7d9f239661cc1683422f14e69c53eb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:35:15 +0200 Subject: [PATCH 33/87] * remove ha_check_if_table_exists() and get_table_share_with_discover(). * rename check_if_table_exists() -> table_exists() and remove unneeded arguments --- sql/handler.cc | 27 ----- sql/handler.h | 2 - sql/sql_base.cc | 285 ++++++++++++++--------------------------------- sql/sql_base.h | 11 +- sql/sql_db.cc | 8 +- sql/sql_show.cc | 11 +- sql/sql_table.cc | 49 +------- sql/table.cc | 20 +++- sql/table.h | 6 +- 9 files changed, 119 insertions(+), 300 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 58e8524dd8d..8da997c2df2 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4203,33 +4203,6 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name) } -/** - Try to find a table in a storage engine. - - @param db Normalized table schema name - @param name Normalized table name. - @param[out] exists Only valid if the function succeeded. - - @retval TRUE An error is found - @retval FALSE Success, check *exists -*/ - -bool -ha_check_if_table_exists(THD* thd, const char *db, const char *name, - bool *exists) -{ - uchar *frmblob= NULL; - size_t frmlen; - DBUG_ENTER("ha_check_if_table_exists"); - - *exists= ! ha_discover(thd, db, name, &frmblob, &frmlen); - if (*exists) - my_free(frmblob); - - DBUG_RETURN(FALSE); -} - - void st_ha_check_opt::init() { flags= sql_flags= 0; diff --git a/sql/handler.h b/sql/handler.h index 93edfb2296e..79e757c5649 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3068,8 +3068,6 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); /* discovery */ int ha_create_table_from_engine(THD* thd, const char *db, const char *name); -bool ha_check_if_table_exists(THD* thd, const char *db, const char *name, - bool *exists); int ha_discover(THD* thd, const char* dbname, const char* name, uchar** frmblob, size_t* frmlen); int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index cbcd8045348..6f393f3329c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -575,18 +575,13 @@ static void table_def_unuse_table(TABLE *table) table_list Table that should be opened key Table cache key key_length Length of key - db_flags Flags to open_table_def(): - OPEN_VIEW + op operation: what to open table or view error out: Error code from open_table_def() IMPLEMENTATION Get a table definition from the table definition cache. If it doesn't exist, create a new from the table definition file. - NOTES - We must have wrlock on LOCK_open when we come here - (To be changed later) - RETURN 0 Error # Share for table @@ -673,6 +668,17 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, We found an existing table definition. Return it if we didn't get an error when reading the table definition from file. */ + if (share->is_view && op == FRM_READ_TABLE_ONLY) + { + open_table_error(share, OPEN_FRM_NOT_A_TABLE, ENOENT); + goto err; + } + if (!share->is_view && op == FRM_READ_VIEW_ONLY) + { + open_table_error(share, OPEN_FRM_NOT_A_VIEW, ENOENT); + goto err; + } + if (share->error) { /* Table definition contained an error */ @@ -680,12 +686,6 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, goto err; } - if (share->is_view && op != FRM_READ_NO_ERROR_FOR_VIEW) - { - open_table_error(share, OPEN_FRM_NO_VIEWS, ENOENT); - goto err; - } - ++share->ref_count; if (share->ref_count == 1 && share->prev) @@ -718,98 +718,6 @@ end: } -/** - Get a table share. If it didn't exist, try creating it from engine - - For arguments and return values, see get_table_share() -*/ - -static TABLE_SHARE * -get_table_share_with_discover(THD *thd, TABLE_LIST *table_list, - char *key, uint key_length, - enum read_frm_op op, enum open_frm_error *error, - my_hash_value_type hash_value) - -{ - TABLE_SHARE *share; - bool exists; - DBUG_ENTER("get_table_share_with_discover"); - - share= get_table_share(thd, table_list, key, key_length, op, error, - hash_value); - /* - If share is not NULL, we found an existing share. - - If share is NULL, and there is no error, we're inside - pre-locking, which silences 'ER_NO_SUCH_TABLE' errors - with the intention to silently drop non-existing tables - from the pre-locking list. In this case we still need to try - auto-discover before returning a NULL share. - - Or, we're inside SHOW CREATE VIEW, which - also installs a silencer for ER_NO_SUCH_TABLE error. - - If share is NULL and the error is ER_NO_SUCH_TABLE, this is - the same as above, only that the error was not silenced by - pre-locking or SHOW CREATE VIEW. - - In both these cases it won't harm to try to discover the - table. - - Finally, if share is still NULL, it's a real error and we need - to abort. - - @todo Rework alternative ways to deal with ER_NO_SUCH TABLE. - */ - if (share || - (thd->is_error() && thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE && - thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE)) - DBUG_RETURN(share); - - *error= OPEN_FRM_OK; - - /* Table didn't exist. Check if some engine can provide it */ - if (ha_check_if_table_exists(thd, table_list->db, table_list->table_name, - &exists)) - { - thd->clear_error(); - /* Conventionally, the storage engine API does not report errors. */ - my_error(ER_OUT_OF_RESOURCES, MYF(0)); - } - else if (! exists) - { - /* - No such table in any engine. - Hide "Table doesn't exist" errors if the table belongs to a view. - The check for thd->is_error() is necessary to not push an - unwanted error in case the error was already silenced. - @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE. - */ - if (thd->is_error()) - { - if (table_list->parent_l) - { - thd->clear_error(); - my_error(ER_WRONG_MRG_TABLE, MYF(0)); - } - else if (table_list->belong_to_view) - { - TABLE_LIST *view= table_list->belong_to_view; - thd->clear_error(); - my_error(ER_VIEW_INVALID, MYF(0), - view->view_db.str, view->view_name.str); - } - } - } - else - { - thd->clear_error(); - *error= OPEN_FRM_DISCOVER; /* Run auto-discover. */ - } - DBUG_RETURN(NULL); -} - - /** Mark that we are not using table share anymore. @@ -871,7 +779,7 @@ void release_table_share(TABLE_SHARE *share) # TABLE_SHARE for table */ -TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) +static TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) { char key[SAFE_NAME_LEN*2+2]; uint key_length; @@ -2445,10 +2353,9 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, or in some storage engine. @param thd Thread context - @param table Table list element - @param fast_check Check only if share or .frm file exists - @param[out] exists Out parameter which is set to TRUE if table - exists and to FALSE otherwise. + @param db database name + @param table_name table name + @param path (optional) path to the frm file @note This function acquires LOCK_open internally. @@ -2460,48 +2367,36 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, @retval FALSE No error. 'exists' out parameter set accordingly. */ -bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool fast_check, - bool *exists) +bool table_exists(THD *thd, const char *db, const char *table_name, + const char *path) { - char path[FN_REFLEN + 1]; + char path_buf[FN_REFLEN + 1]; TABLE_SHARE *share; - DBUG_ENTER("check_if_table_exists"); - - *exists= TRUE; - - DBUG_ASSERT(fast_check || - thd->mdl_context. - is_lock_owner(MDL_key::TABLE, table->db, - table->table_name, MDL_SHARED)); + DBUG_ENTER("table_exists"); mysql_mutex_lock(&LOCK_open); - share= get_cached_table_share(table->db, table->table_name); + share= get_cached_table_share(db, table_name); mysql_mutex_unlock(&LOCK_open); if (share) - goto end; + DBUG_RETURN(TRUE); - build_table_filename(path, sizeof(path) - 1, table->db, table->table_name, - reg_ext, 0); + if (!path) + { + build_table_filename(path_buf, sizeof(path_buf) - 1, + db, table_name, reg_ext, 0); + path= path_buf; + } if (!access(path, F_OK)) - goto end; - - if (fast_check) - { - *exists= FALSE; - goto end; - } - - /* .FRM file doesn't exist. Check if some engine can provide it. */ - if (ha_check_if_table_exists(thd, table->db, table->table_name, exists)) - { - my_printf_error(ER_OUT_OF_RESOURCES, "Failed to open '%-.64s', error while " - "unpacking from engine", MYF(0), table->table_name); DBUG_RETURN(TRUE); - } -end: - DBUG_RETURN(FALSE); + + /* .FRM file doesn't exist. Try to discover it */ + uchar *frmblob= NULL; + size_t frmlen; + bool exists= ! ha_discover(thd, db, table_name, &frmblob, &frmlen); + my_free(frmblob); + DBUG_RETURN(exists); } @@ -2781,6 +2676,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, enum open_frm_error error; TABLE_SHARE *share; my_hash_value_type hash_value; + enum read_frm_op read_op; DBUG_ENTER("open_table"); /* an open table operation needs a lot of the stack space */ @@ -3040,12 +2936,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS) { - bool exists; - - if (check_if_table_exists(thd, table_list, 0, &exists)) - DBUG_RETURN(TRUE); - - if (!exists) + if (!table_exists(thd, table_list)) DBUG_RETURN(FALSE); /* Table exists. Let us try to open it. */ @@ -3053,21 +2944,41 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, else if (table_list->open_strategy == TABLE_LIST::OPEN_STUB) DBUG_RETURN(FALSE); + if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) + read_op = FRM_READ_TABLE_ONLY; + else + if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) + read_op = FRM_READ_VIEW_ONLY; + else + read_op = FRM_READ_TABLE_OR_VIEW; + retry_share: - if (!(share= get_table_share_with_discover(thd, table_list, key, key_length, - FRM_READ_NO_ERROR_FOR_VIEW, - &error, hash_value))) + share= get_table_share(thd, table_list, key, key_length, + read_op, &error, hash_value); + + if (!share) { /* - If thd->is_error() is not set, we either need discover or the error was - silenced by the prelocking handler, in which case we should skip this - table. + Hide "Table doesn't exist" errors if the table belongs to a view. + The check for thd->is_error() is necessary to not push an + unwanted error in case the error was already silenced. + @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE. */ - if (error == OPEN_FRM_DISCOVER && !thd->is_error()) + if (thd->is_error()) { - (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, - table_list); + if (table_list->parent_l) + { + thd->clear_error(); + my_error(ER_WRONG_MRG_TABLE, MYF(0)); + } + else if (table_list->belong_to_view) + { + TABLE_LIST *view= table_list->belong_to_view; + thd->clear_error(); + my_error(ER_VIEW_INVALID, MYF(0), + view->view_db.str, view->view_name.str); + } } DBUG_RETURN(TRUE); } @@ -3090,12 +3001,6 @@ retry_share: */ if (check_and_update_table_version(thd, table_list, share)) goto err_lock; - if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) - { - my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, - table_list->table_name); - goto err_lock; - } /* Open view */ if (open_new_frm(thd, share, alias, @@ -3117,20 +3022,6 @@ retry_share: DBUG_RETURN(FALSE); } - /* - Note that situation when we are trying to open a table for what - was a view during previous execution of PS will be handled in by - the caller. Here we should simply open our table even if - TABLE_LIST::view is true. - */ - - if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) - { - my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, - table_list->table_name); - goto err_lock; - } - mysql_mutex_lock(&LOCK_open); if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) || (share->protected_against_usage() && !(flags & MYSQL_OPEN_FOR_REPAIR))) @@ -3894,11 +3785,12 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key, cache_key_length); if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, - FRM_READ_NO_ERROR_FOR_VIEW, &error, hash_value))) + FRM_READ_VIEW_ONLY, &error, hash_value))) return TRUE; - bool err= !share->is_view || - open_new_frm(thd, share, alias, + DBUG_ASSERT(share->is_view); + + bool err= open_new_frm(thd, share, alias, (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | HA_TRY_READ_ONLY), READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | flags, @@ -3908,10 +3800,6 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, release_table_share(share); mysql_mutex_unlock(&LOCK_open); - if (err) - my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, - table_list->table_name, "VIEW"); - return err; } @@ -3985,12 +3873,11 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) cache_key_length); if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, - FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, + FRM_READ_TABLE_ONLY, ¬_used, hash_value))) goto end_free; - if (share->is_view) - goto end_release; + DBUG_ASSERT(! share->is_view); if (open_table_from_share(thd, share, table_list->alias, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | @@ -4016,7 +3903,6 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) result= FALSE; } -end_release: mysql_mutex_lock(&LOCK_open); release_table_share(share); /* Remove the repaired share from the table cache. */ @@ -4786,7 +4672,7 @@ lock_table_names(THD *thd, if (mdl_requests.is_empty()) DBUG_RETURN(FALSE); - /* Check if CREATE TABLE IF NOT EXISTS was used */ + /* Check if CREATE TABLE was used */ create_table= (tables_start && tables_start->open_strategy == TABLE_LIST::OPEN_IF_EXISTS); @@ -4825,12 +4711,9 @@ lock_table_names(THD *thd, for (;;) { - bool exists= TRUE; - bool res; - if (create_table) thd->push_internal_handler(&error_handler); // Avoid warnings & errors - res= thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout); + bool res= thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout); if (create_table) thd->pop_internal_handler(); if (!res) @@ -4840,13 +4723,10 @@ lock_table_names(THD *thd, DBUG_RETURN(TRUE); // Return original error /* - We come here in the case of lock timeout when executing - CREATE TABLE IF NOT EXISTS. - Verify that table really exists (it should as we got a lock conflict) + We come here in the case of lock timeout when executing CREATE TABLE. + Verify that table does exist (it usually does, as we got a lock conflict) */ - if (check_if_table_exists(thd, tables_start, 1, &exists)) - DBUG_RETURN(TRUE); // Should never happen - if (exists) + if (table_exists(thd, tables_start)) { if (thd->lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS) { @@ -4858,17 +4738,16 @@ lock_table_names(THD *thd, my_error(ER_TABLE_EXISTS_ERROR, MYF(0), tables_start->table_name); DBUG_RETURN(TRUE); } - /* purecov: begin inspected */ /* - We got error from acquire_locks but table didn't exists. - In theory this should never happen, except maybe in - CREATE or DROP DATABASE scenario. + We got error from acquire_locks, but the table didn't exists. + This could happen if another connection runs a statement + involving this non-existent table, and this statement took the mdl, + but didn't error out with ER_NO_SUCH_TABLE yet (yes, a race condition). We play safe and restart the original acquire_locks with the - original timeout + original timeout. */ create_table= 0; lock_wait_timeout= org_lock_wait_timeout; - /* purecov: end */ } } diff --git a/sql/sql_base.h b/sql/sql_base.h index e0612397361..8bcbbff556e 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -112,7 +112,6 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, enum open_frm_error *error, my_hash_value_type hash_value); void release_table_share(TABLE_SHARE *share); -TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update, uint lock_flags); @@ -333,8 +332,14 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, const char *table_name, bool no_error); void mark_tmp_table_for_reuse(TABLE *table); -bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool fast_check, - bool *exists); + +bool table_exists(THD *thd, const char *db, const char *table_name, + const char *path); +static inline bool table_exists(THD *thd, TABLE_LIST *table) +{ + return table_exists(thd, table->db, table->table_name, NULL); +} + int update_virtual_fields(THD *thd, TABLE *table, enum enum_vcol_update_mode vcol_update_mode= VCOL_UPDATE_FOR_READ); int dynamic_column_error_message(enum_dyncol_func_result rc); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index b287aad49ef..359f74155db 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -934,16 +934,10 @@ update_binlog: for (tbl= tables; tbl; tbl= tbl->next_local) { uint tbl_name_len; - bool exists; char quoted_name[FN_REFLEN+3]; // Only write drop table to the binlog for tables that no longer exist. - if (check_if_table_exists(thd, tbl, 0, &exists)) - { - error= true; - goto exit; - } - if (exists) + if (table_exists(thd, tbl)) continue; my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 45c3318987c..c99c345f13f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4057,12 +4057,14 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, of backward compatibility. */ if (!is_show_fields_or_keys && result && thd->is_error() && - thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) + (thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE || + thd->stmt_da->sql_errno() == ER_WRONG_OBJECT)) { /* Hide error for a non-existing table. For example, this error can occur when we use a where condition - with a db name and table, but the table does not exist. + with a db name and table, but the table does not exist or + there is a view with the same name. */ result= false; thd->clear_error(); @@ -4383,7 +4385,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, key_length= create_table_def_key(thd, key, &table_list, 0); hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); share= get_table_share(thd, &table_list, key, key_length, - FRM_READ_NO_ERROR_FOR_VIEW, ¬_used, hash_value); + FRM_READ_TABLE_OR_VIEW, ¬_used, hash_value); if (!share) { res= 0; @@ -4407,10 +4409,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, res= 1; goto end_share; } - } - if (share->is_view) - { if (open_new_frm(thd, share, table_name->str, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | HA_TRY_READ_ONLY), diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4ab7fc28381..ea1b7b3398b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2279,11 +2279,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); error= 0; - if (drop_temporary || - ((access(path, F_OK) && - ha_create_table_from_engine(thd, db, alias)) || - (!drop_view && - dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))) + if (drop_temporary || !table_exists(thd, db, alias, path) || + (!drop_view && dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)) { /* One of the following cases happened: @@ -4320,50 +4317,10 @@ bool mysql_create_table_no_lock(THD *thd, if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - if (!access(path,F_OK)) + if (table_exists(thd, db, table_name, path)) { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) goto warn; - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); - goto err; - } - /* - We don't assert here, but check the result, because the table could be - in the table definition cache and in the same time the .frm could be - missing from the disk, in case of manual intervention which deletes - the .frm file. The user has to use FLUSH TABLES; to clear the cache. - Then she could create the table. This case is pretty obscure and - therefore we don't introduce a new error message only for it. - */ - mysql_mutex_lock(&LOCK_open); - if (get_cached_table_share(db, table_name)) - { - mysql_mutex_unlock(&LOCK_open); - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); - goto err; - } - mysql_mutex_unlock(&LOCK_open); - } - - /* - Check that table with given name does not already - exist in any storage engine. In such a case it should - be discovered and the error ER_TABLE_EXISTS_ERROR be returned - unless user specified CREATE TABLE IF EXISTS - An exclusive metadata lock ensures that no - one else is attempting to discover the table. Since - it's not on disk as a frm file, no one could be using it! - */ - if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) - { - bool create_if_not_exists = - create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS; - bool exists_in_engine; - ha_check_if_table_exists(thd, db, table_name, &exists_in_engine); - if (exists_in_engine) - { - if (create_if_not_exists) - goto warn; my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); goto err; } diff --git a/sql/table.cc b/sql/table.cc index cd933e0e4a6..ca92909b9a7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -685,8 +685,8 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0) { share->is_view= 1; - share->error= op == FRM_READ_NO_ERROR_FOR_VIEW - ? OPEN_FRM_OK : OPEN_FRM_NO_VIEWS; + share->error= op == FRM_READ_TABLE_ONLY + ? OPEN_FRM_NOT_A_TABLE : OPEN_FRM_OK; goto err; } if (!is_binary_frm_header(head)) @@ -695,6 +695,11 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, share->error = OPEN_FRM_CORRUPTED; goto err; } + if (op == FRM_READ_VIEW_ONLY) + { + share->error = OPEN_FRM_NOT_A_VIEW; + goto err; + } if (my_fstat(file, &stats, MYF(0))) goto err; @@ -2802,7 +2807,7 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error, int db_errno) { char buff[FN_REFLEN]; - myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log + const myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log DBUG_ENTER("open_table_error"); switch (error) { @@ -2825,8 +2830,15 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error, break; case OPEN_FRM_ERROR_ALREADY_ISSUED: break; + case OPEN_FRM_NOT_A_VIEW: + my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, + share->table_name.str, "VIEW"); + break; + case OPEN_FRM_NOT_A_TABLE: + my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, + share->table_name.str, "TABLE"); + break; case OPEN_FRM_DISCOVER: - case OPEN_FRM_NO_VIEWS: DBUG_ASSERT(0); // open_table_error() is never called for this one break; case OPEN_FRM_CORRUPTED: diff --git a/sql/table.h b/sql/table.h index af359377e61..1ac3dcba0ba 100644 --- a/sql/table.h +++ b/sql/table.h @@ -569,7 +569,8 @@ enum open_frm_error { OPEN_FRM_CORRUPTED, OPEN_FRM_DISCOVER, OPEN_FRM_ERROR_ALREADY_ISSUED, - OPEN_FRM_NO_VIEWS, + OPEN_FRM_NOT_A_VIEW, + OPEN_FRM_NOT_A_TABLE }; /** @@ -2448,7 +2449,8 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, enum read_frm_op { FRM_READ_TABLE_ONLY, - FRM_READ_NO_ERROR_FOR_VIEW + FRM_READ_VIEW_ONLY, + FRM_READ_TABLE_OR_VIEW }; size_t max_row_length(TABLE *table, const uchar *data); From 934115184b52a28a30d576a8a47d0ec66b1b0712 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:35:24 +0200 Subject: [PATCH 34/87] convenience helpers for get_table_share() and tdc_open_view(). Pass db and table_name into a function instead of the table_list, when only db and table name are needed. --- sql/sql_admin.cc | 9 ++---- sql/sql_base.cc | 80 +++++++++++++++++------------------------------- sql/sql_base.h | 47 ++++++++++++++++++++++++---- sql/sql_show.cc | 9 ++---- sql/sql_view.cc | 8 ++--- sql/table.cc | 10 +++--- sql/table.h | 6 ++-- 7 files changed, 82 insertions(+), 87 deletions(-) diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 0410d72bafc..e900353337a 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -100,8 +100,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, if (!(table= table_list->table)) { - char key[MAX_DBKEY_LENGTH]; - uint key_length; /* If the table didn't exist, we have a shared metadata lock on it that is left from mysql_admin_table()'s attempt to @@ -114,9 +112,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, Attempt to do full-blown table open in mysql_admin_table() has failed. Let us try to open at least a .FRM for this table. */ - my_hash_value_type hash_value; - key_length= create_table_def_key(thd, key, table_list, 0); table_list->mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name, MDL_EXCLUSIVE, MDL_TRANSACTION); @@ -127,9 +123,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, DBUG_RETURN(0); has_mdl_lock= TRUE; - hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - share= get_table_share(thd, table_list, key, key_length, - FRM_READ_TABLE_ONLY, ¬_used, hash_value); + share= get_table_share(thd, table_list->db, table_list->table_name, + FRM_READ_TABLE_ONLY, ¬_used); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6f393f3329c..14389e840e9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -320,18 +320,18 @@ static void check_unused(THD *thd) Create a table cache key SYNOPSIS - create_table_def_key() + create_tmp_table_def_key() thd Thread handler key Create key here (must be of size MAX_DBKEY_LENGTH) - table_list Table definition - tmp_table Set if table is a tmp table + db Database name. + table_name Table name. IMPLEMENTATION The table cache_key is created from: db_name + \0 table_name + \0 - if the table is a tmp table, we add the following to make each tmp table + additionally we add the following to make each tmp table unique on the slave: 4 bytes for master thread id @@ -341,19 +341,13 @@ static void check_unused(THD *thd) Length of key */ -uint create_table_def_key(THD *thd, char *key, - const TABLE_LIST *table_list, - bool tmp_table) +uint create_tmp_table_def_key(THD *thd, char *key, + const char *db, const char *table_name) { - uint key_length= create_table_def_key(key, table_list->db, - table_list->table_name); - - if (tmp_table) - { - int4store(key + key_length, thd->server_id); - int4store(key + key_length + 4, thd->variables.pseudo_thread_id); - key_length+= TMP_TABLE_KEY_EXTRA; - } + uint key_length= create_table_def_key(key, db, table_name); + int4store(key + key_length, thd->server_id); + int4store(key + key_length + 4, thd->variables.pseudo_thread_id); + key_length+= TMP_TABLE_KEY_EXTRA; return key_length; } @@ -587,9 +581,9 @@ static void table_def_unuse_table(TABLE *table) # Share for table */ -TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, enum read_frm_op op, - enum open_frm_error *error, +TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, + char *key, uint key_length, + enum read_frm_op op, enum open_frm_error *error, my_hash_value_type hash_value) { bool open_failed; @@ -604,9 +598,7 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, To be able perform any operation on table we should own some kind of metadata lock on it. */ - DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, - table_list->db, - table_list->table_name, + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, MDL_SHARED)); /* Read table definition from cache */ @@ -614,7 +606,7 @@ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, hash_value, (uchar*) key, key_length); if (!share) { - if (!(share= alloc_table_share(table_list, key, key_length))) + if (!(share= alloc_table_share(db, table_name, key, key_length))) goto err; /* @@ -2071,7 +2063,7 @@ TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name) TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl) { char key[MAX_DBKEY_LENGTH]; - uint key_length= create_table_def_key(thd, key, tl, 1); + uint key_length= create_tmp_table_def_key(thd, key, tl->db, tl->table_name); return find_temporary_table(thd, key, key_length); } @@ -2251,15 +2243,12 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db, char *key; uint key_length; TABLE_SHARE *share= table->s; - TABLE_LIST table_list; DBUG_ENTER("rename_temporary_table"); if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH))) DBUG_RETURN(1); /* purecov: inspected */ - table_list.db= (char*) db; - table_list.table_name= (char*) table_name; - key_length= create_table_def_key(thd, key, &table_list, 1); + key_length= create_tmp_table_def_key(thd, key, db, table_name); share->set_table_cache_key(key, key_length); DBUG_RETURN(0); } @@ -2686,8 +2675,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (thd->killed) DBUG_RETURN(TRUE); - key_length= (create_table_def_key(thd, key, table_list, 1) - - TMP_TABLE_KEY_EXTRA); + key_length= create_tmp_table_def_key(thd, key, table_list->db, + table_list->table_name) - + TMP_TABLE_KEY_EXTRA; /* Unless requested otherwise, try to resolve this table in the list @@ -2954,8 +2944,8 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, retry_share: - share= get_table_share(thd, table_list, key, key_length, - read_op, &error, hash_value); + share= get_table_share(thd, table_list->db, table_list->table_name, + key, key_length, read_op, &error, hash_value); if (!share) { @@ -3779,13 +3769,11 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, { TABLE not_used; enum open_frm_error error; - my_hash_value_type hash_value; TABLE_SHARE *share; - hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key, - cache_key_length); - if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, - FRM_READ_VIEW_ONLY, &error, hash_value))) + if (!(share= get_table_share(thd, table_list->db, table_list->table_name, + cache_key, cache_key_length, + FRM_READ_VIEW_ONLY, &error))) return TRUE; DBUG_ASSERT(share->is_view); @@ -3854,27 +3842,18 @@ static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry) static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) { - char cache_key[MAX_DBKEY_LENGTH]; - uint cache_key_length; TABLE_SHARE *share; TABLE *entry; enum open_frm_error not_used; bool result= TRUE; - my_hash_value_type hash_value; - - cache_key_length= create_table_def_key(thd, cache_key, table_list, 0); thd->clear_error(); if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) return result; - hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key, - cache_key_length); - - if (!(share= get_table_share(thd, table_list, cache_key, cache_key_length, - FRM_READ_TABLE_ONLY, ¬_used, - hash_value))) + if (!(share= get_table_share(thd, table_list->db, table_list->table_name, + FRM_READ_TABLE_ONLY, ¬_used))) goto end_free; DBUG_ASSERT(! share->is_view); @@ -5995,7 +5974,6 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db, TABLE_SHARE *share; char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path; uint key_length; - TABLE_LIST table_list; DBUG_ENTER("open_table_uncached"); DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s' server_id: %u " @@ -6003,10 +5981,8 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db, db, table_name, path, (uint) thd->server_id, (ulong) thd->variables.pseudo_thread_id)); - table_list.db= (char*) db; - table_list.table_name= (char*) table_name; /* Create the cache_key for temporary tables */ - key_length= create_table_def_key(thd, cache_key, &table_list, 1); + key_length= create_tmp_table_def_key(thd, cache_key, db, table_name); if (!(tmp_table= (TABLE*) my_malloc(sizeof(*tmp_table) + sizeof(*share) + strlen(path)+1 + key_length, diff --git a/sql/sql_base.h b/sql/sql_base.h index 8bcbbff556e..e0ced3992eb 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -69,6 +69,8 @@ enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN, #define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002 #define RTFC_CHECK_KILLED_FLAG 0x0004 +extern HASH table_def_cache; + bool check_dup(const char *db, const char *name, TABLE_LIST *tables); extern mysql_mutex_t LOCK_open; bool table_cache_init(void); @@ -79,9 +81,6 @@ void table_def_start_shutdown(void); void assign_new_table_id(TABLE_SHARE *share); uint cached_open_tables(void); uint cached_table_definitions(void); -uint create_table_def_key(THD *thd, char *key, - const TABLE_LIST *table_list, - bool tmp_table); /** Create a table cache key for non-temporary table. @@ -107,12 +106,38 @@ create_table_def_key(char *key, const char *db, const char *table_name) NAME_LEN) - key + 1); } -TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, - uint key_length, enum read_frm_op op, +uint create_tmp_table_def_key(THD *thd, char *key, const char *db, + const char *table_name); +TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, + char *key, uint key_length, enum read_frm_op op, enum open_frm_error *error, my_hash_value_type hash_value); void release_table_share(TABLE_SHARE *share); + +// convenience helper: call get_table_share() without precomputed hash_value +static inline TABLE_SHARE *get_table_share(THD *thd, const char *db, + const char *table_name, + char *key, uint key_length, + enum read_frm_op op, + enum open_frm_error *error) +{ + return get_table_share(thd, db, table_name, key, key_length, op, error, + my_calc_hash(&table_def_cache, (uchar*) key, key_length)); +} + +// convenience helper: call get_table_share() without precomputed cache key +static inline TABLE_SHARE *get_table_share(THD *thd, const char *db, + const char *table_name, + enum read_frm_op op, + enum open_frm_error *error) +{ + char key[MAX_DBKEY_LENGTH]; + uint key_length; + key_length= create_table_def_key(key, db, table_name); + return get_table_share(thd, db, table_name, key, key_length, op, error); +} + TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update, uint lock_flags); @@ -327,6 +352,17 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type, bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, char *cache_key, uint cache_key_length, MEM_ROOT *mem_root, uint flags); + +static inline bool tdc_open_view(THD *thd, TABLE_LIST *table_list, + const char *alias, MEM_ROOT *mem_root, + uint flags) +{ + char key[MAX_DBKEY_LENGTH]; + uint key_length; + key_length= create_table_def_key(key, table_list->db, table_list->table_name); + return tdc_open_view(thd, table_list, alias, key, key_length, mem_root, flags); +} + void tdc_flush_unused_tables(); TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, const char *table_name, @@ -356,7 +392,6 @@ extern TABLE *unused_tables; extern Item **not_found_item; extern Field *not_found_field; extern Field *view_ref_found; -extern HASH table_def_cache; /** clean/setup table fields and map. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c99c345f13f..0f18ba69711 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4308,9 +4308,6 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, TABLE_LIST table_list; uint res= 0; enum open_frm_error not_used; - my_hash_value_type hash_value; - char key[MAX_DBKEY_LENGTH]; - uint key_length; char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1]; bzero((char*) &table_list, sizeof(TABLE_LIST)); @@ -4382,10 +4379,8 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, goto end; } - key_length= create_table_def_key(thd, key, &table_list, 0); - hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length); - share= get_table_share(thd, &table_list, key, key_length, - FRM_READ_TABLE_OR_VIEW, ¬_used, hash_value); + share= get_table_share(thd, table_list.db, table_list.table_name, + FRM_READ_TABLE_OR_VIEW, ¬_used); if (!share) { res= 0; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 67004dc538d..7c033f74fb2 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -211,16 +211,12 @@ static void make_valid_column_names(List &item_list) static bool fill_defined_view_parts (THD *thd, TABLE_LIST *view) { - char key[MAX_DBKEY_LENGTH]; - uint key_length; LEX *lex= thd->lex; TABLE_LIST decoy; memcpy (&decoy, view, sizeof (TABLE_LIST)); - key_length= create_table_def_key(thd, key, view, 0); - - if (tdc_open_view(thd, &decoy, decoy.alias, key, key_length, - thd->mem_root, OPEN_VIEW_NO_PARSE)) + if (tdc_open_view(thd, &decoy, decoy.alias, thd->mem_root, + OPEN_VIEW_NO_PARSE)) return TRUE; if (!lex->definer) diff --git a/sql/table.cc b/sql/table.cc index ca92909b9a7..451caf0bed4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -285,8 +285,8 @@ TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name) # Share */ -TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key, - uint key_length) +TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, + char *key, uint key_length) { MEM_ROOT mem_root; TABLE_SHARE *share; @@ -294,12 +294,10 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key, char path[FN_REFLEN]; uint path_length; DBUG_ENTER("alloc_table_share"); - DBUG_PRINT("enter", ("table: '%s'.'%s'", - table_list->db, table_list->table_name)); + DBUG_PRINT("enter", ("table: '%s'.'%s'", db, table_name)); path_length= build_table_filename(path, sizeof(path) - 1, - table_list->db, - table_list->table_name, "", 0); + db, table_name, "", 0); init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); if (multi_alloc_root(&mem_root, &share, sizeof(*share), diff --git a/sql/table.h b/sql/table.h index 1ac3dcba0ba..816567f1496 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1624,7 +1624,7 @@ struct TABLE_LIST /** Prepare TABLE_LIST that consists of one table instance to use in - simple_open_and_lock_tables + open_and_lock_tables */ inline void init_one_table(const char *db_name_arg, size_t db_length_arg, @@ -2464,8 +2464,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, bool unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, TABLE *table, Field *field, LEX_STRING *vcol_expr, bool *error_reported); -TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key, - uint key_length); +TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, + char *key, uint key_length); void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, uint key_length, const char *table_name, const char *path); From 6a839ff40d1be946b4391eb7a316b0404e1cd82b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:35:57 +0200 Subject: [PATCH 35/87] handlerton::discover_table_existence() method --- sql/handler.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ sql/handler.h | 23 ++++++++++++ sql/sql_base.cc | 58 ++--------------------------- sql/sql_base.h | 9 +---- sql/sql_db.cc | 2 +- sql/sql_table.cc | 11 ++++-- 6 files changed, 133 insertions(+), 67 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 8da997c2df2..f4987b9b36f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -383,6 +383,11 @@ static int ha_finish_errors(void) return 0; } +volatile int32 need_full_discover_for_existence= 0; +static int full_discover_for_existence(handlerton *, const char *, const char *) +{ return 1; } +static int ext_based_existence(handlerton *, const char *, const char *) +{ return 1; } int ha_finalize_handlerton(st_plugin_int *plugin) { @@ -433,6 +438,9 @@ int ha_finalize_handlerton(st_plugin_int *plugin) hton2plugin[hton->slot]= NULL; } + if (hton->discover_table_existence == full_discover_for_existence) + my_atomic_add32(&need_full_discover_for_existence, -1); + if (hton->discover_table_names) my_atomic_add32(&engines_with_discover_table_names, -1); @@ -486,6 +494,18 @@ int ha_initialize_handlerton(st_plugin_int *plugin) hton->discover && hton->tablefile_extensions[0]) hton->discover_table_names= hton_ext_based_table_discovery; + // default discover_table_existence implementation + if (!hton->discover_table_existence && hton->discover) + { + if (hton->tablefile_extensions[0]) + hton->discover_table_existence= ext_based_existence; + else + { + hton->discover_table_existence= full_discover_for_existence; + my_atomic_add32(&need_full_discover_for_existence, 1); + } + } + /* the switch below and hton->state should be removed when command-line options for plugins will be implemented @@ -4377,6 +4397,83 @@ int ha_discover(THD *thd, const char *db, const char *name, DBUG_RETURN(error); } +/** + Check if a given table exists, without doing a full discover, if possible +*/ + +static my_bool file_ext_exists(char *path, size_t path_len, const char *ext) +{ + strmake(path + path_len, ext, FN_REFLEN - path_len); + return !access(path, F_OK); +} + +struct st_discover_existence_args +{ + char *path; + size_t path_len; + const char *db, *table_name; +}; + +static my_bool discover_existence(THD *thd, plugin_ref plugin, + void *arg) +{ + st_discover_existence_args *args= (st_discover_existence_args*)arg; + handlerton *ht= plugin_data(plugin, handlerton *); + if (ht->state != SHOW_OPTION_YES || !ht->discover_table_existence) + return FALSE; + + if (ht->discover_table_existence == ext_based_existence) + return file_ext_exists(args->path, args->path_len, + ht->tablefile_extensions[0]); + + return ht->discover_table_existence(ht, args->db, args->table_name); +} + +bool ha_table_exists(THD *thd, const char *db, const char *table_name) +{ + DBUG_ENTER("ha_discover_table_existence"); + + if (need_full_discover_for_existence) + { + enum open_frm_error err; + TABLE_LIST table; + + DBUG_ASSERT(0); + TABLE_SHARE *share= get_table_share(thd, db, table_name, + FRM_READ_TABLE_ONLY, &err); + + if (share) + { + mysql_mutex_lock(&LOCK_open); + release_table_share(share); + mysql_mutex_unlock(&LOCK_open); + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); + } + + mysql_mutex_lock(&LOCK_open); + TABLE_SHARE *share= get_cached_table_share(db, table_name); + mysql_mutex_unlock(&LOCK_open); + + if (share) + DBUG_RETURN(TRUE); + + char path[FN_REFLEN + 1]; + size_t path_len = build_table_filename(path, sizeof(path) - 1, + db, table_name, "", 0); + + if (file_ext_exists(path, path_len, reg_ext)) + DBUG_RETURN(TRUE); + + st_discover_existence_args args= {path, path_len, db, table_name}; + + if (plugin_foreach(thd, discover_existence, MYSQL_STORAGE_ENGINE_PLUGIN, + &args)) + DBUG_RETURN(TRUE); + + DBUG_RETURN(FALSE); +} /** Discover all table names in a given database diff --git a/sql/handler.h b/sql/handler.h index 79e757c5649..ee1d54c3253 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1136,6 +1136,27 @@ struct handlerton */ int (*discover_table_names)(handlerton *hton, LEX_STRING *db, MY_DIR *dir, discovered_list *result); + + /* + This is a method that allows to server to check if a table exists without + an overhead of the complete discovery. + + By default (if not implemented by the engine, but the discovery_table() is + implemented) it will try to perform a file-based discovery: + + - if tablefile_extensions[0] is not null this will look for a file name + with the tablefile_extensions[0] extension. + + - if tablefile_extensions[0] is null, this will resort to discover_table(). + + Note that resorting to discover_table() is slow and the engine + should probably implement its own discover_table_existence() method, + if its tablefile_extensions[0] is null. + + Returns 1 if the table exists and 0 if it does not. + */ + int (*discover_table_existence)(handlerton *hton, const char *db, + const char *table_name); }; @@ -3072,6 +3093,8 @@ int ha_discover(THD* thd, const char* dbname, const char* name, uchar** frmblob, size_t* frmlen); int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, handlerton::discovered_list *result); +bool ha_table_exists(THD *thd, const char *db, const char *table_name); + #ifdef MYSQL_SERVER extern volatile int32 engines_with_discover_table_names; #endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 14389e840e9..d1feba264f1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -771,7 +771,7 @@ void release_table_share(TABLE_SHARE *share) # TABLE_SHARE for table */ -static TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) +TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) { char key[SAFE_NAME_LEN*2+2]; uint key_length; @@ -2337,58 +2337,6 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, } -/** - Check that table exists in table definition cache, on disk - or in some storage engine. - - @param thd Thread context - @param db database name - @param table_name table name - @param path (optional) path to the frm file - - @note This function acquires LOCK_open internally. - - @note If there is no .FRM file for the table but it exists in one - of engines (e.g. it was created on another node of NDB cluster) - this function will fetch and create proper .FRM file for it. - - @retval TRUE Some error occurred - @retval FALSE No error. 'exists' out parameter set accordingly. -*/ - -bool table_exists(THD *thd, const char *db, const char *table_name, - const char *path) -{ - char path_buf[FN_REFLEN + 1]; - TABLE_SHARE *share; - DBUG_ENTER("table_exists"); - - mysql_mutex_lock(&LOCK_open); - share= get_cached_table_share(db, table_name); - mysql_mutex_unlock(&LOCK_open); - - if (share) - DBUG_RETURN(TRUE); - - if (!path) - { - build_table_filename(path_buf, sizeof(path_buf) - 1, - db, table_name, reg_ext, 0); - path= path_buf; - } - - if (!access(path, F_OK)) - DBUG_RETURN(TRUE); - - /* .FRM file doesn't exist. Try to discover it */ - uchar *frmblob= NULL; - size_t frmlen; - bool exists= ! ha_discover(thd, db, table_name, &frmblob, &frmlen); - my_free(frmblob); - DBUG_RETURN(exists); -} - - /** An error handler which converts, if possible, ER_LOCK_DEADLOCK error that can occur when we are trying to acquire a metadata lock to @@ -2926,7 +2874,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS) { - if (!table_exists(thd, table_list)) + if (!ha_table_exists(thd, table_list->db, table_list->table_name)) DBUG_RETURN(FALSE); /* Table exists. Let us try to open it. */ @@ -4705,7 +4653,7 @@ lock_table_names(THD *thd, We come here in the case of lock timeout when executing CREATE TABLE. Verify that table does exist (it usually does, as we got a lock conflict) */ - if (table_exists(thd, tables_start)) + if (ha_table_exists(thd, tables_start->db, tables_start->table_name)) { if (thd->lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS) { diff --git a/sql/sql_base.h b/sql/sql_base.h index e0ced3992eb..1880b4f4321 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -113,7 +113,7 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, enum open_frm_error *error, my_hash_value_type hash_value); void release_table_share(TABLE_SHARE *share); - +TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); // convenience helper: call get_table_share() without precomputed hash_value static inline TABLE_SHARE *get_table_share(THD *thd, const char *db, @@ -369,13 +369,6 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, bool no_error); void mark_tmp_table_for_reuse(TABLE *table); -bool table_exists(THD *thd, const char *db, const char *table_name, - const char *path); -static inline bool table_exists(THD *thd, TABLE_LIST *table) -{ - return table_exists(thd, table->db, table->table_name, NULL); -} - int update_virtual_fields(THD *thd, TABLE *table, enum enum_vcol_update_mode vcol_update_mode= VCOL_UPDATE_FOR_READ); int dynamic_column_error_message(enum_dyncol_func_result rc); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 359f74155db..6dee6b4bcc5 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -937,7 +937,7 @@ update_binlog: char quoted_name[FN_REFLEN+3]; // Only write drop table to the binlog for tables that no longer exist. - if (table_exists(thd, tbl)) + if (ha_table_exists(thd, tbl->db, tbl->table_name)) continue; my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ea1b7b3398b..b19e179f022 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2279,8 +2279,9 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); error= 0; - if (drop_temporary || !table_exists(thd, db, alias, path) || - (!drop_view && dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)) + if (!table->internal_tmp_table && + (drop_temporary || !ha_table_exists(thd, db, alias) || + (!drop_view && dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))) { /* One of the following cases happened: @@ -2288,6 +2289,10 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, . "DROP" but table was not found on disk and table can't be created from engine. . ./sql/datadict.cc +32 /Alfranio - TODO: We need to test this. + + Table->internal_tmp_table is set when one of the #sql-xxx files + was left in the datadir after a crash during ALTER TABLE. + See Bug#30152. */ if (if_exists) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -4317,7 +4322,7 @@ bool mysql_create_table_no_lock(THD *thd, if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - if (table_exists(thd, db, table_name, path)) + if (ha_table_exists(thd, db, table_name)) { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) goto warn; From f532653c2920490ac15ad70db0f2f1aaaacb92fe Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:41:57 +0200 Subject: [PATCH 36/87] remove ha_create_table_from_engine() replace enum read_frm_op with a bitmap flags. remove always-unused 'error' argument of get_table_share --- include/my_base.h | 2 +- sql/handler.cc | 79 ++--------------------------------------------- sql/handler.h | 1 - sql/sql_admin.cc | 3 +- sql/sql_base.cc | 74 +++++++++++++++++++++++++------------------- sql/sql_base.h | 14 +++------ sql/sql_show.cc | 3 +- sql/table.cc | 8 ++--- sql/table.h | 11 ++++--- 9 files changed, 61 insertions(+), 134 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index 0c12057b2ab..f1b6825319c 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -313,7 +313,7 @@ enum ha_base_keytype { #define HA_OPTION_CHECKSUM 32 #define HA_OPTION_DELAY_KEY_WRITE 64 #define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */ -#define HA_OPTION_CREATE_FROM_ENGINE 256 +/* unused 256 */ #define HA_OPTION_RELIES_ON_SQL_LAYER 512 #define HA_OPTION_NULL_FIELDS 1024 #define HA_OPTION_PAGE_CHECKSUM 2048 diff --git a/sql/handler.cc b/sql/handler.cc index f4987b9b36f..32d78e78ba3 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4157,72 +4157,6 @@ err: DBUG_RETURN(error != 0); } -/** - Try to discover table from engine. - - @note - If found, write the frm file to disk. - - @retval - -1 Table did not exists - @retval - 0 Table created ok - @retval - > 0 Error, table existed but could not be created -*/ -int ha_create_table_from_engine(THD* thd, const char *db, const char *name) -{ - int error; - uchar *frmblob; - size_t frmlen; - char path[FN_REFLEN + 1]; - HA_CREATE_INFO create_info; - TABLE table; - TABLE_SHARE share; - DBUG_ENTER("ha_create_table_from_engine"); - DBUG_PRINT("enter", ("name '%s'.'%s'", db, name)); - - bzero((uchar*) &create_info,sizeof(create_info)); - if ((error= ha_discover(thd, db, name, &frmblob, &frmlen))) - { - /* Table could not be discovered and thus not created */ - DBUG_RETURN(error); - } - - /* - Table exists in handler and could be discovered - frmblob and frmlen are set, write the frm to disk - */ - - build_table_filename(path, sizeof(path) - 1, db, name, "", 0); - // Save the frm file - error= writefrm(path, frmblob, frmlen); - my_free(frmblob); - if (error) - DBUG_RETURN(2); - - init_tmp_table_share(thd, &share, db, 0, name, path); - if (open_table_def(thd, &share)) - { - DBUG_RETURN(3); - } - if (open_table_from_share(thd, &share, "" ,0, 0, 0, &table, FALSE)) - { - free_table_share(&share); - DBUG_RETURN(3); - } - - update_create_info_from_table(&create_info, &table); - create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE; - - get_canonical_filename(table.file, path, path); - error=table.file->ha_create(path, &table, &create_info); - (void) closefrm(&table, 1); - - DBUG_RETURN(error != 0); -} - - void st_ha_check_opt::init() { flags= sql_flags= 0; @@ -4435,21 +4369,12 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name) if (need_full_discover_for_existence) { - enum open_frm_error err; TABLE_LIST table; DBUG_ASSERT(0); TABLE_SHARE *share= get_table_share(thd, db, table_name, - FRM_READ_TABLE_ONLY, &err); - - if (share) - { - mysql_mutex_lock(&LOCK_open); - release_table_share(share); - mysql_mutex_unlock(&LOCK_open); - DBUG_RETURN(TRUE); - } - DBUG_RETURN(FALSE); + GTS_TABLE | GTS_NOLOCK); + DBUG_RETURN(share != 0); } mysql_mutex_lock(&LOCK_open); diff --git a/sql/handler.h b/sql/handler.h index ee1d54c3253..2f899fdaa19 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3088,7 +3088,6 @@ int ha_delete_table(THD *thd, handlerton *db_type, const char *path, bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); /* discovery */ -int ha_create_table_from_engine(THD* thd, const char *db, const char *name); int ha_discover(THD* thd, const char* dbname, const char* name, uchar** frmblob, size_t* frmlen); int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index e900353337a..9e3ea46f526 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -81,7 +81,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, HA_CHECK_OPT *check_opt) { int error= 0; - enum open_frm_error not_used; TABLE tmp_table, *table; TABLE_LIST *pos_in_locked_tables= 0; TABLE_SHARE *share; @@ -124,7 +123,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, has_mdl_lock= TRUE; share= get_table_share(thd, table_list->db, table_list->table_name, - FRM_READ_TABLE_ONLY, ¬_used); + GTS_TABLE); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d1feba264f1..03f6db3a498 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -569,8 +569,8 @@ static void table_def_unuse_table(TABLE *table) table_list Table that should be opened key Table cache key key_length Length of key - op operation: what to open table or view - error out: Error code from open_table_def() + flags operation: what to open table or view + hash_value = my_calc_hash(&table_def_cache, key, key_length) IMPLEMENTATION Get a table definition from the table definition cache. @@ -582,15 +582,14 @@ static void table_def_unuse_table(TABLE *table) */ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, - char *key, uint key_length, - enum read_frm_op op, enum open_frm_error *error, + char *key, uint key_length, uint flags, my_hash_value_type hash_value) { bool open_failed; TABLE_SHARE *share; DBUG_ENTER("get_table_share"); - *error= OPEN_FRM_OK; + DBUG_ASSERT(!(flags & GTS_FORCE_DISCOVERY)); // FIXME not implemented mysql_mutex_lock(&LOCK_open); @@ -634,14 +633,13 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, mysql_mutex_lock(&share->LOCK_ha_data); mysql_mutex_unlock(&LOCK_open); - open_failed= open_table_def(thd, share, op); + open_failed= open_table_def(thd, share, flags); mysql_mutex_unlock(&share->LOCK_ha_data); mysql_mutex_lock(&LOCK_open); if (open_failed) { - *error= share->error; share->ref_count--; (void) my_hash_delete(&table_def_cache, (uchar*) share); goto err; @@ -660,24 +658,23 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, We found an existing table definition. Return it if we didn't get an error when reading the table definition from file. */ - if (share->is_view && op == FRM_READ_TABLE_ONLY) + if (share->error) + { + open_table_error(share, share->error, share->open_errno); + goto err; + } + + if (share->is_view && !(flags & GTS_VIEW)) { open_table_error(share, OPEN_FRM_NOT_A_TABLE, ENOENT); goto err; } - if (!share->is_view && op == FRM_READ_VIEW_ONLY) + if (!share->is_view && !(flags & GTS_TABLE)) { open_table_error(share, OPEN_FRM_NOT_A_VIEW, ENOENT); goto err; } - if (share->error) - { - /* Table definition contained an error */ - open_table_error(share, share->error, share->open_errno); - goto err; - } - ++share->ref_count; if (share->ref_count == 1 && share->prev) @@ -703,8 +700,23 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, goto end; err: - share= 0; + mysql_mutex_unlock(&LOCK_open); + DBUG_RETURN(0); + end: + if (flags & GTS_NOLOCK) + { + share->ref_count--; + /* + if GTS_NOLOCK is requested, the returned share pointer cannot be used, + the share it points to may go away any moment. + But perhaps the caller is only interested to know whether a share or + table existed? + Let's return an invalid pointer here to catch dereferencing attempts. + */ + share= (TABLE_SHARE*) 1; + } + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(share); } @@ -2610,10 +2622,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, char *alias= table_list->alias; uint flags= ot_ctx->get_flags(); MDL_ticket *mdl_ticket; - enum open_frm_error error; TABLE_SHARE *share; my_hash_value_type hash_value; - enum read_frm_op read_op; + uint gts_flags; DBUG_ENTER("open_table"); /* an open table operation needs a lot of the stack space */ @@ -2883,17 +2894,16 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, DBUG_RETURN(FALSE); if (table_list->i_s_requested_object & OPEN_TABLE_ONLY) - read_op = FRM_READ_TABLE_ONLY; + gts_flags= GTS_TABLE; + else if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) + gts_flags= GTS_VIEW; else - if (table_list->i_s_requested_object & OPEN_VIEW_ONLY) - read_op = FRM_READ_VIEW_ONLY; - else - read_op = FRM_READ_TABLE_OR_VIEW; + gts_flags= GTS_TABLE | GTS_VIEW; retry_share: share= get_table_share(thd, table_list->db, table_list->table_name, - key, key_length, read_op, &error, hash_value); + key, key_length, gts_flags, hash_value); if (!share) { @@ -3019,6 +3029,8 @@ retry_share: } else { + enum open_frm_error error; + /* If we have too many TABLE instances around, try to get rid of them */ while (table_cache_count > table_cache_size && unused_tables) free_cache_entry(unused_tables); @@ -3716,12 +3728,10 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, MEM_ROOT *mem_root, uint flags) { TABLE not_used; - enum open_frm_error error; TABLE_SHARE *share; if (!(share= get_table_share(thd, table_list->db, table_list->table_name, - cache_key, cache_key_length, - FRM_READ_VIEW_ONLY, &error))) + cache_key, cache_key_length, GTS_VIEW))) return TRUE; DBUG_ASSERT(share->is_view); @@ -3792,7 +3802,6 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) { TABLE_SHARE *share; TABLE *entry; - enum open_frm_error not_used; bool result= TRUE; thd->clear_error(); @@ -3801,7 +3810,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) return result; if (!(share= get_table_share(thd, table_list->db, table_list->table_name, - FRM_READ_TABLE_ONLY, ¬_used))) + GTS_TABLE))) goto end_free; DBUG_ASSERT(! share->is_view); @@ -3979,8 +3988,9 @@ recover_from_failed_open(THD *thd) tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db, m_failed_table->table_name, FALSE); - ha_create_table_from_engine(thd, m_failed_table->db, - m_failed_table->table_name); + get_table_share(thd, m_failed_table->db, + m_failed_table->table_name, + GTS_TABLE | GTS_FORCE_DISCOVERY | GTS_NOLOCK); thd->warning_info->clear_warning_info(thd->query_id); thd->clear_error(); // Clear error message diff --git a/sql/sql_base.h b/sql/sql_base.h index 1880b4f4321..fc95ecb0119 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -109,8 +109,7 @@ create_table_def_key(char *key, const char *db, const char *table_name) uint create_tmp_table_def_key(THD *thd, char *key, const char *db, const char *table_name); TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, - char *key, uint key_length, enum read_frm_op op, - enum open_frm_error *error, + char *key, uint key_length, uint flags, my_hash_value_type hash_value); void release_table_share(TABLE_SHARE *share); TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); @@ -119,23 +118,20 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name); static inline TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, char *key, uint key_length, - enum read_frm_op op, - enum open_frm_error *error) + uint flags) { - return get_table_share(thd, db, table_name, key, key_length, op, error, + return get_table_share(thd, db, table_name, key, key_length, flags, my_calc_hash(&table_def_cache, (uchar*) key, key_length)); } // convenience helper: call get_table_share() without precomputed cache key static inline TABLE_SHARE *get_table_share(THD *thd, const char *db, - const char *table_name, - enum read_frm_op op, - enum open_frm_error *error) + const char *table_name, uint flags) { char key[MAX_DBKEY_LENGTH]; uint key_length; key_length= create_table_def_key(key, db, table_name); - return get_table_share(thd, db, table_name, key, key_length, op, error); + return get_table_share(thd, db, table_name, key, key_length, flags); } TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0f18ba69711..ff81aff530c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4307,7 +4307,6 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, TABLE tbl; TABLE_LIST table_list; uint res= 0; - enum open_frm_error not_used; char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1]; bzero((char*) &table_list, sizeof(TABLE_LIST)); @@ -4380,7 +4379,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, } share= get_table_share(thd, table_list.db, table_list.table_name, - FRM_READ_TABLE_OR_VIEW, ¬_used); + GTS_TABLE | GTS_VIEW); if (!share) { res= 0; diff --git a/sql/table.cc b/sql/table.cc index 451caf0bed4..8a74c1c0b60 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -607,8 +607,7 @@ static bool has_disabled_path_chars(const char *str) alloc_table_share().. The code assumes that share is initialized. */ -enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, - enum read_frm_op op) +enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) { bool error_given= false; File file; @@ -683,8 +682,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, if (memcmp(head, STRING_WITH_LEN("TYPE=VIEW\n")) == 0) { share->is_view= 1; - share->error= op == FRM_READ_TABLE_ONLY - ? OPEN_FRM_NOT_A_TABLE : OPEN_FRM_OK; + share->error= flags & GTS_VIEW ? OPEN_FRM_OK : OPEN_FRM_NOT_A_TABLE; goto err; } if (!is_binary_frm_header(head)) @@ -693,7 +691,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, share->error = OPEN_FRM_CORRUPTED; goto err; } - if (op == FRM_READ_VIEW_ONLY) + if (!(flags & GTS_TABLE)) { share->error = OPEN_FRM_NOT_A_VIEW; goto err; diff --git a/sql/table.h b/sql/table.h index 816567f1496..cd967824a04 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2447,10 +2447,11 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, #endif } -enum read_frm_op { - FRM_READ_TABLE_ONLY, - FRM_READ_VIEW_ONLY, - FRM_READ_TABLE_OR_VIEW +enum get_table_share_flags { + GTS_TABLE = 1, + GTS_VIEW = 2, + GTS_NOLOCK = 4, // don't increase share->ref_count + GTS_FORCE_DISCOVERY = 8 // don't use the .frm file }; size_t max_row_length(TABLE *table, const uchar *data); @@ -2471,7 +2472,7 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, const char *table_name, const char *path); void free_table_share(TABLE_SHARE *share); enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, - enum read_frm_op op = FRM_READ_TABLE_ONLY); + uint flags = GTS_TABLE); void open_table_error(TABLE_SHARE *share, enum open_frm_error error, int db_errno); From e5a323e107767ceb5106b85d077d4ac9d2d37778 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:45:31 +0200 Subject: [PATCH 37/87] single table discovery: handlerton::discover_table() method. fixes for need_full_discover_for_existence mode --- mysql-test/t/partition_disabled.test | 2 + mysql-test/t/show_check.test | 2 + sql/handler.cc | 120 +++++++++++++++++---------- sql/handler.h | 22 +++-- sql/sql_base.cc | 32 ++++--- sql/sql_db.cc | 4 - sql/sql_table.cc | 43 +++++----- sql/table.cc | 111 ++++++++++++------------- sql/table.h | 4 +- storage/archive/azio.c | 8 +- storage/archive/azlib.h | 4 +- storage/archive/ha_archive.cc | 42 +++++----- 12 files changed, 219 insertions(+), 175 deletions(-) diff --git a/mysql-test/t/partition_disabled.test b/mysql-test/t/partition_disabled.test index 320d6238502..798fb0aa59e 100644 --- a/mysql-test/t/partition_disabled.test +++ b/mysql-test/t/partition_disabled.test @@ -29,7 +29,9 @@ ALTER TABLE t1 ANALYZE PARTITION ALL; ALTER TABLE t1 REBUILD PARTITION ALL; ALTER TABLE t1 ENGINE Memory; ALTER TABLE t1 ADD (new INT); +--disable_warnings DROP TABLE t1; +--enable_warnings --error ER_OPTION_PREVENTS_STATEMENT CREATE TABLE t1 ( diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index c2edef87d41..32bf5417a0a 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -429,7 +429,9 @@ system echo "this is a junk file for test" >> $MYSQLD_DATADIR/test/t1.frm ; SHOW TABLE STATUS like 't1'; --error ER_NOT_FORM_FILE show create table t1; +--disable_warnings drop table if exists t1; +--enable_warnings --error 1,0 --remove_file $MYSQLD_DATADIR/test/t1.frm diff --git a/sql/handler.cc b/sql/handler.cc index 32d78e78ba3..a9a2214a91d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -491,11 +491,11 @@ int ha_initialize_handlerton(st_plugin_int *plugin) // if the enfine can discover a single table and it is file-based // then it can use a default file-based table names discovery if (!hton->discover_table_names && - hton->discover && hton->tablefile_extensions[0]) + hton->discover_table && hton->tablefile_extensions[0]) hton->discover_table_names= hton_ext_based_table_discovery; // default discover_table_existence implementation - if (!hton->discover_table_existence && hton->discover) + if (!hton->discover_table_existence && hton->discover_table) { if (hton->tablefile_extensions[0]) hton->discover_table_existence= ext_based_existence; @@ -4279,56 +4279,44 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache, } -/** - Try to discover one table from handler(s). - - @retval - -1 Table did not exists - @retval - 0 OK. In this case *frmblob and *frmlen are set - @retval - >0 error. frmblob and frmlen may not be set -*/ -struct st_discover_args -{ - const char *db; - const char *name; - uchar **frmblob; - size_t *frmlen; -}; - static my_bool discover_handlerton(THD *thd, plugin_ref plugin, void *arg) { - st_discover_args *vargs= (st_discover_args *)arg; + TABLE_SHARE *share= (TABLE_SHARE *)arg; handlerton *hton= plugin_data(plugin, handlerton *); - if (hton->state == SHOW_OPTION_YES && hton->discover && - (!(hton->discover(hton, thd, vargs->db, vargs->name, - vargs->frmblob, - vargs->frmlen)))) - return TRUE; + if (hton->state == SHOW_OPTION_YES && hton->discover_table) + { + int error= hton->discover_table(hton, thd, share); + if (error != HA_ERR_NO_SUCH_TABLE) + { + if (error) + { + DBUG_ASSERT(share->error); // MUST be always set for get_cached_table_share to work + my_error(ER_GET_ERRNO, MYF(0), error); + } + else + share->error= OPEN_FRM_OK; - return FALSE; + status_var_increment(thd->status_var.ha_discover_count); + return TRUE; // abort the search + } + } + + DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); + return FALSE; // continue with the next engine } -int ha_discover(THD *thd, const char *db, const char *name, - uchar **frmblob, size_t *frmlen) +int ha_discover_table(THD *thd, TABLE_SHARE *share) { - int error= -1; // Table does not exist in any handler - DBUG_ENTER("ha_discover"); - DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); - st_discover_args args= {db, name, frmblob, frmlen}; + DBUG_ENTER("ha_discover_table"); - if (is_prefix(name,tmp_file_prefix)) /* skip temporary tables */ - DBUG_RETURN(error); + DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet - if (plugin_foreach(thd, discover_handlerton, - MYSQL_STORAGE_ENGINE_PLUGIN, &args)) - error= 0; + if (!plugin_foreach(thd, discover_handlerton, + MYSQL_STORAGE_ENGINE_PLUGIN, share)) + open_table_error(share, OPEN_FRM_OPEN_ERROR, ENOENT); // not found - if (!error) - status_var_increment(thd->status_var.ha_discover_count); - DBUG_RETURN(error); + DBUG_RETURN(share->error != OPEN_FRM_OK); } /** @@ -4363,6 +4351,45 @@ static my_bool discover_existence(THD *thd, plugin_ref plugin, return ht->discover_table_existence(ht, args->db, args->table_name); } +class Table_exists_error_handler : public Internal_error_handler +{ +public: + Table_exists_error_handler() + : m_handled_errors(0), m_unhandled_errors(0) + {} + + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) + { + *cond_hdl= NULL; + if (sql_errno == ER_NO_SUCH_TABLE || + sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE || + sql_errno == ER_WRONG_OBJECT || + sql_errno == ER_OPTION_PREVENTS_STATEMENT) // partition_disabled.test + { + m_handled_errors++; + return TRUE; + } + + if (level == MYSQL_ERROR::WARN_LEVEL_ERROR) + m_unhandled_errors++; + return FALSE; + } + + bool safely_trapped_errors() + { + return ((m_handled_errors > 0) && (m_unhandled_errors == 0)); + } + +private: + int m_handled_errors; + int m_unhandled_errors; +}; + bool ha_table_exists(THD *thd, const char *db, const char *table_name) { DBUG_ENTER("ha_discover_table_existence"); @@ -4371,10 +4398,13 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name) { TABLE_LIST table; - DBUG_ASSERT(0); - TABLE_SHARE *share= get_table_share(thd, db, table_name, - GTS_TABLE | GTS_NOLOCK); - DBUG_RETURN(share != 0); + Table_exists_error_handler no_such_table_handler; + thd->push_internal_handler(&no_such_table_handler); + get_table_share(thd, db, table_name, GTS_TABLE | GTS_VIEW | GTS_NOLOCK); + thd->pop_internal_handler(); + + // the table doesn't exist if we've caught ER_NO_SUCH_TABLE and nothing else + DBUG_RETURN(!no_such_table_handler.safely_trapped_errors()); } mysql_mutex_lock(&LOCK_open); diff --git a/sql/handler.h b/sql/handler.h index 2f899fdaa19..2093a3d1605 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1075,10 +1075,6 @@ struct handlerton enum handler_create_iterator_result (*create_iterator)(handlerton *hton, enum handler_iterator_type type, struct handler_iterator *fill_this_in); - int (*discover)(handlerton *hton, THD* thd, const char *db, - const char *name, - uchar **frmblob, - size_t *frmlen); /* Optional clauses in the CREATE/ALTER TABLE */ @@ -1110,6 +1106,20 @@ struct handlerton engine, without user issuing an explicit CREATE TABLE statement. **********************************************************************/ + /* + This method is required for any engine that supports automatic table + discovery, there is no default implementation. + + Given a TABLE_SHARE discover_table() fills it in with a correct table + structure using one of the TABLE_SHARE::init_from_* methods. + + Returns HA_ERR_NO_SUCH_TABLE if the table did not exist in the engine, + zero if the table was discovered successfully, or any other + HA_ERR_* error code as appropriate if the table existed, but the + discovery failed. + */ + int (*discover_table)(handlerton *hton, THD* thd, TABLE_SHARE *share); + /* The discover_table_names method tells the server about all tables in the specified database that the engine @@ -1157,6 +1167,7 @@ struct handlerton */ int (*discover_table_existence)(handlerton *hton, const char *db, const char *table_name); + }; @@ -3088,8 +3099,7 @@ int ha_delete_table(THD *thd, handlerton *db_type, const char *path, bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); /* discovery */ -int ha_discover(THD* thd, const char* dbname, const char* name, - uchar** frmblob, size_t* frmlen); +int ha_discover_table(THD *thd, TABLE_SHARE *share); int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, handlerton::discovered_list *result); bool ha_table_exists(THD *thd, const char *db, const char *table_name); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 03f6db3a498..d93c412dd60 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -585,24 +585,15 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, char *key, uint key_length, uint flags, my_hash_value_type hash_value) { - bool open_failed; TABLE_SHARE *share; DBUG_ENTER("get_table_share"); - DBUG_ASSERT(!(flags & GTS_FORCE_DISCOVERY)); // FIXME not implemented - mysql_mutex_lock(&LOCK_open); - /* - To be able perform any operation on table we should own - some kind of metadata lock on it. - */ - DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, - MDL_SHARED)); - /* Read table definition from cache */ share= (TABLE_SHARE*) my_hash_search_using_hash_value(&table_def_cache, hash_value, (uchar*) key, key_length); + if (!share) { if (!(share= alloc_table_share(db, table_name, key, key_length))) @@ -633,12 +624,15 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, mysql_mutex_lock(&share->LOCK_ha_data); mysql_mutex_unlock(&LOCK_open); - open_failed= open_table_def(thd, share, flags); + if (flags & GTS_FORCE_DISCOVERY) + ha_discover_table(thd, share); // don't read the frm at all + else + open_table_def(thd, share, flags | GTS_FORCE_DISCOVERY); // frm or discover mysql_mutex_unlock(&share->LOCK_ha_data); mysql_mutex_lock(&LOCK_open); - if (open_failed) + if (share->error) { share->ref_count--; (void) my_hash_delete(&table_def_cache, (uchar*) share); @@ -650,6 +644,9 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, goto end; } + /* cannot force discovery of a cached share */ + DBUG_ASSERT(!(flags & GTS_FORCE_DISCOVERY)); + /* make sure that open_table_def() for this share is not running */ mysql_mutex_lock(&share->LOCK_ha_data); mysql_mutex_unlock(&share->LOCK_ha_data); @@ -706,7 +703,7 @@ err: end: if (flags & GTS_NOLOCK) { - share->ref_count--; + release_table_share(share); /* if GTS_NOLOCK is requested, the returned share pointer cannot be used, the share it points to may go away any moment. @@ -716,6 +713,15 @@ end: */ share= (TABLE_SHARE*) 1; } + else + { + /* + To be able perform any operation on table we should own + some kind of metadata lock on it. + */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, + MDL_SHARED)); + } mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(share); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 6dee6b4bcc5..d4f8431beec 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -832,11 +832,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) mysql_ha_rm_tables(thd, tables); for (table= tables; table; table= table->next_local) - { - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, - false); deleted_tables++; - } thd->push_internal_handler(&err_handler); if (!thd->killed && diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b19e179f022..830c57438a3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1928,10 +1928,6 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, MYSQL_OPEN_SKIP_TEMPORARY)) DBUG_RETURN(true); - for (table= tables; table; table= table->next_local) - - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, - false); } else { @@ -2222,23 +2218,9 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, { non_temp_tables_count++; - if (thd->locked_tables_mode) - { - if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED, - TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) - { - error= -1; - goto err; - } - close_all_tables_for_name(thd, table->table->s, - HA_EXTRA_PREPARE_FOR_DROP); - table->table= 0; - } - - /* Check that we have an exclusive lock on the table to be dropped. */ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db, table->table_name, - MDL_EXCLUSIVE)); + MDL_SHARED)); alias= (lower_case_table_names == 2) ? table->alias : table->table_name; /* remove .frm file and engine files */ @@ -2307,6 +2289,28 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, else { char *end; + + if (thd->locked_tables_mode) + { + if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED, + TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) + { + error= -1; + goto err; + } + close_all_tables_for_name(thd, table->table->s, + HA_EXTRA_PREPARE_FOR_DROP); + table->table= 0; + } + else + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, + false); + + /* Check that we have an exclusive lock on the table to be dropped. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db, + table->table_name, + MDL_EXCLUSIVE)); + /* Cannot use the db_type from the table, since that might have changed while waiting for the exclusive name lock. @@ -2372,6 +2376,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, err: if (wrong_tables.length()) { + thd->clear_error(); if (!foreign_key_error) my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), wrong_tables.c_ptr_safe()); diff --git a/sql/table.cc b/sql/table.cc index 8a74c1c0b60..d9dab7fe170 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -316,6 +316,7 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, share->normalized_path.length= path_length; share->table_category= get_table_category(& share->db, & share->table_name); share->set_refresh_version(); + share->open_errno= ENOENT; /* Since alloc_table_share() can be called without any locking (for @@ -570,24 +571,21 @@ inline bool is_system_table_name(const char *name, uint length) } -/** - Check if a string contains path elements -*/ - +/* + We don't try to open 5.0 unencoded name, if + - non-encoded name contains '@' signs, + because '@' can be misinterpreted. + It is not clear if '@' is escape character in 5.1, + or a normal character in 5.0. + + - non-encoded db or table name contain "#mysql50#" prefix. + This kind of tables must have been opened only by the + mysql_file_open() above. +*/ static bool has_disabled_path_chars(const char *str) { - for (; *str; str++) - { - switch (*str) { - case FN_EXTCHAR: - case '/': - case '\\': - case '~': - case '@': - return TRUE; - } - } - return FALSE; + return strpbrk(str, "/\\~@.") != 0 || + strncmp(str, STRING_WITH_LEN(MYSQL50_TABLE_NAME_PREFIX)) == 0; } @@ -626,50 +624,45 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0) { - /* - We don't try to open 5.0 unencoded name, if - - non-encoded name contains '@' signs, - because '@' can be misinterpreted. - It is not clear if '@' is escape character in 5.1, - or a normal character in 5.0. - - - non-encoded db or table name contain "#mysql50#" prefix. - This kind of tables must have been opened only by the - mysql_file_open() above. - */ - if (has_disabled_path_chars(share->table_name.str) || - has_disabled_path_chars(share->db.str) || - !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX, - MYSQL50_TABLE_NAME_PREFIX_LENGTH) || - !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX, - MYSQL50_TABLE_NAME_PREFIX_LENGTH)) + if (!has_disabled_path_chars(share->table_name.str) && + !has_disabled_path_chars(share->db.str)) + { + /* Try unencoded 5.0 name */ + uint length; + strxnmov(path, sizeof(path)-1, + mysql_data_home, "/", share->db.str, "/", + share->table_name.str, reg_ext, NullS); + length= unpack_filename(path, path) - reg_ext_length; + /* + The following is a safety test and should never fail + as the old file name should never be longer than the new one. + */ + DBUG_ASSERT(length <= share->normalized_path.length); + /* + If the old and the new names have the same length, + then table name does not have tricky characters, + so no need to check the old file name. + */ + if (length != share->normalized_path.length && + (file= mysql_file_open(key_file_frm, + path, O_RDONLY | O_SHARE, MYF(0))) >= 0) + { + /* Unencoded 5.0 table name found */ + path[length]= '\0'; // Remove .frm extension + strmov(share->normalized_path.str, path); + share->normalized_path.length= length; + } + } + /* still no luck? try to discover the table */ + if (file < 0) + { + if (flags & GTS_TABLE && flags & GTS_FORCE_DISCOVERY) + { + ha_discover_table(thd, share); + error_given= true; + } goto err_not_open; - - /* Try unencoded 5.0 name */ - uint length; - strxnmov(path, sizeof(path)-1, - mysql_data_home, "/", share->db.str, "/", - share->table_name.str, reg_ext, NullS); - length= unpack_filename(path, path) - reg_ext_length; - /* - The following is a safety test and should never fail - as the old file name should never be longer than the new one. - */ - DBUG_ASSERT(length <= share->normalized_path.length); - /* - If the old and the new names have the same length, - then table name does not have tricky characters, - so no need to check the old file name. - */ - if (length == share->normalized_path.length || - ((file= mysql_file_open(key_file_frm, - path, O_RDONLY | O_SHARE, MYF(0))) < 0)) - goto err_not_open; - - /* Unencoded 5.0 table name found */ - path[length]= '\0'; // Remove .frm extension - strmov(share->normalized_path.str, path); - share->normalized_path.length= length; + } } if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP))) diff --git a/sql/table.h b/sql/table.h index cd967824a04..e4e5b839a85 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2450,8 +2450,8 @@ static inline void dbug_tmp_restore_column_maps(MY_BITMAP *read_set, enum get_table_share_flags { GTS_TABLE = 1, GTS_VIEW = 2, - GTS_NOLOCK = 4, // don't increase share->ref_count - GTS_FORCE_DISCOVERY = 8 // don't use the .frm file + GTS_NOLOCK = 4, + GTS_FORCE_DISCOVERY = 8 }; size_t max_row_length(TABLE *table, const uchar *data); diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 92d7ad70344..43c418e516d 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -855,7 +855,7 @@ int azclose (azio_stream *s) Though this was added to support MySQL's FRM file, anything can be stored in this location. */ -int azwrite_frm(azio_stream *s, char *blob, unsigned int length) +int azwrite_frm(azio_stream *s, uchar *blob, unsigned int length) { if (s->mode == 'r') return 1; @@ -867,7 +867,7 @@ int azwrite_frm(azio_stream *s, char *blob, unsigned int length) s->frm_length= length; s->start+= length; - if (my_pwrite(s->file, (uchar*) blob, s->frm_length, + if (my_pwrite(s->file, blob, s->frm_length, s->frm_start_pos, MYF(MY_NABP)) || write_header(s) || (my_seek(s->file, 0, MY_SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)) @@ -876,9 +876,9 @@ int azwrite_frm(azio_stream *s, char *blob, unsigned int length) return 0; } -int azread_frm(azio_stream *s, char *blob) +int azread_frm(azio_stream *s, uchar *blob) { - return my_pread(s->file, (uchar*) blob, s->frm_length, + return my_pread(s->file, blob, s->frm_length, s->frm_start_pos, MYF(MY_NABP)) ? 1 : 0; } diff --git a/storage/archive/azlib.h b/storage/archive/azlib.h index 29a6329fb0a..05fc299e581 100644 --- a/storage/archive/azlib.h +++ b/storage/archive/azlib.h @@ -331,8 +331,8 @@ extern int azclose(azio_stream *file); error number (see function gzerror below). */ -extern int azwrite_frm (azio_stream *s, char *blob, unsigned int length); -extern int azread_frm (azio_stream *s, char *blob); +extern int azwrite_frm (azio_stream *s, uchar *blob, unsigned int length); +extern int azread_frm (azio_stream *s, uchar *blob); extern int azwrite_comment (azio_stream *s, char *blob, unsigned int length); extern int azread_comment (azio_stream *s, char *blob); diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 57d6fc947f8..37b1273b65d 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -26,6 +26,7 @@ #include // T_EXTEND #include "ha_archive.h" +#include "discover.h" #include #include @@ -120,10 +121,7 @@ extern "C" PSI_file_key arch_key_file_data; static handler *archive_create_handler(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root); -int archive_discover(handlerton *hton, THD* thd, const char *db, - const char *name, - uchar **frmblob, - size_t *frmlen); +int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share); /* Number of rows that will force a bulk insert. @@ -220,7 +218,7 @@ int archive_db_init(void *p) archive_hton->db_type= DB_TYPE_ARCHIVE_DB; archive_hton->create= archive_create_handler; archive_hton->flags= HTON_NO_FLAGS; - archive_hton->discover= archive_discover; + archive_hton->discover_table= archive_discover; archive_hton->tablefile_extensions= ha_archive_exts; if (mysql_mutex_init(az_key_mutex_archive_mutex, @@ -270,19 +268,17 @@ ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg) archive_reader_open= FALSE; } -int archive_discover(handlerton *hton, THD* thd, const char *db, - const char *name, - uchar **frmblob, - size_t *frmlen) +int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) { DBUG_ENTER("archive_discover"); - DBUG_PRINT("archive_discover", ("db: %s, name: %s", db, name)); + DBUG_PRINT("archive_discover", ("db: '%s' name: '%s'", share->db.str, + share->table_name.str)); azio_stream frm_stream; char az_file[FN_REFLEN]; - char *frm_ptr; + uchar *frm_ptr; MY_STAT file_stat; - build_table_filename(az_file, sizeof(az_file) - 1, db, name, ARZ, 0); + strxmov(az_file, share->normalized_path.str, ARZ, NullS); if (!(mysql_file_stat(/* arch_key_file_data */ 0, az_file, &file_stat, MYF(0)))) goto err; @@ -295,19 +291,23 @@ int archive_discover(handlerton *hton, THD* thd, const char *db, } if (frm_stream.frm_length == 0) - goto err; + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); - frm_ptr= (char *)my_malloc(sizeof(char) * frm_stream.frm_length, MYF(0)); + frm_ptr= (uchar *)my_malloc(sizeof(char) * frm_stream.frm_length, MYF(0)); azread_frm(&frm_stream, frm_ptr); azclose(&frm_stream); - *frmlen= frm_stream.frm_length; - *frmblob= (uchar*) frm_ptr; + // don't go through the discovery again + if (writefrm(share->normalized_path.str, frm_ptr, frm_stream.frm_length)) + DBUG_RETURN(my_errno); + + share->init_from_binary_frm_image(thd, frm_ptr); + + my_free(frm_ptr); DBUG_RETURN(0); err: - my_errno= 0; - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } /* @@ -650,9 +650,9 @@ int ha_archive::close(void) int ha_archive::frm_copy(azio_stream *src, azio_stream *dst) { int rc= 0; - char *frm_ptr; + uchar *frm_ptr; - if (!(frm_ptr= (char *) my_malloc(src->frm_length, MYF(0)))) + if (!(frm_ptr= (uchar *) my_malloc(src->frm_length, MYF(0)))) return HA_ERR_OUT_OF_MEM; /* Write file offset is set to the end of the file. */ @@ -758,7 +758,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, if (frm_ptr) { mysql_file_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0)); - azwrite_frm(&create_stream, (char *)frm_ptr, (size_t)file_stat.st_size); + azwrite_frm(&create_stream, frm_ptr, (size_t)file_stat.st_size); my_free(frm_ptr); } } From a489ae89b9ffe427963745f13c44e1e4d67494f4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:47:25 +0200 Subject: [PATCH 38/87] fix mysql_rm_table_no_locks() not to use dd_frm_type, because the frm file may not exist (the table exists only in the engine). --- mysql-test/include/mix1.inc | 6 -- mysql-test/r/plugin.result | 8 ++- mysql-test/suite/innodb/r/innodb_mysql.result | 7 +- mysql-test/t/plugin.test | 21 +++++- sql/handler.cc | 67 +++++++++++++++---- sql/handler.h | 5 +- sql/sql_plugin.cc | 3 +- sql/sql_table.cc | 66 +++++++++--------- sql/table.h | 5 +- 9 files changed, 127 insertions(+), 61 deletions(-) diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index e7ea8b3d25a..75ba0e43221 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -630,15 +630,9 @@ copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/bug29807.frm; --error ER_NO_SUCH_TABLE_IN_ENGINE select * from bug29807; drop table t1; ---error ER_BAD_TABLE_ERROR drop table bug29807; -create table bug29807 (a int); -drop table bug29807; ---disable_query_log call mtr.add_suppression("InnoDB: Error: table .test...bug29807. does not exist in the InnoDB internal"); call mtr.add_suppression("Cannot find or open table test\/bug29807 from"); -call mtr.add_suppression("Table 'test.bug29807' doesn't exist in engine"); ---enable_query_log # diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 62864d0f16d..ac2ba843131 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -35,7 +35,9 @@ PLUGIN_LICENSE GPL LOAD_OPTION ON PLUGIN_MATURITY Experimental PLUGIN_AUTH_VERSION 3.14.15.926 -CREATE TABLE t1(a int) ENGINE=EXAMPLE; +CREATE TABLE t1 (a int) ENGINE=EXAMPLE; +CREATE TABLE t2 (a int) ENGINE=EXAMPLE; +FLUSH TABLES; SELECT * FROM t1; a set global example_ulong_var=500; @@ -65,6 +67,10 @@ LOAD_OPTION ON PLUGIN_MATURITY Experimental PLUGIN_AUTH_VERSION 0.1 DROP TABLE t1; +select * from information_schema.plugins where plugin_library like 'ha_example%'; +SELECT * FROM t2; +ERROR 42000: Unknown storage engine 'EXAMPLE' +DROP TABLE t2; UNINSTALL PLUGIN EXAMPLE; ERROR 42000: PLUGIN EXAMPLE does not exist UNINSTALL PLUGIN non_exist; diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index d963c4cc89b..7247b26e86b 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -633,9 +633,10 @@ select * from bug29807; ERROR 42S02: Table 'test.bug29807' doesn't exist in engine drop table t1; drop table bug29807; -ERROR 42S02: Unknown table 'bug29807' -create table bug29807 (a int); -drop table bug29807; +Warnings: +Warning 155 Table 'test.bug29807' doesn't exist in engine +call mtr.add_suppression("InnoDB: Error: table .test...bug29807. does not exist in the InnoDB internal"); +call mtr.add_suppression("Cannot find or open table test\/bug29807 from"); CREATE TABLE t1 (a INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT) ENGINE=InnoDB; switch to connection c1 diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index 4412383f837..71ca860e269 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -16,12 +16,13 @@ INSTALL SONAME 'ha_example'; --replace_regex /\.dll/.so/ --query_vertical select * from information_schema.plugins where plugin_library like 'ha_example%' -CREATE TABLE t1(a int) ENGINE=EXAMPLE; +CREATE TABLE t1 (a int) ENGINE=EXAMPLE; +CREATE TABLE t2 (a int) ENGINE=EXAMPLE; +FLUSH TABLES; # Let's do some advanced ops with the example engine :) SELECT * FROM t1; - # a couple of tests for variables set global example_ulong_var=500; set global example_enum_var= e1; @@ -29,12 +30,26 @@ show status like 'example%'; show variables like 'example%'; UNINSTALL SONAME 'ha_example'; + +# the engine is NOT uninstalled yet, +# because the table `t1` is open, sitting in the table defintion cache + --replace_column 5 # --replace_regex /\.dll/.so/ --query_vertical select * from information_schema.plugins where plugin_library like 'ha_example%' - DROP TABLE t1; +# now the engine IS unloaded +# and the table `t2` belongs to an unknown engine + +--replace_column 5 # +--replace_regex /\.dll/.so/ +--query_vertical select * from information_schema.plugins where plugin_library like 'ha_example%' +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t2; +DROP TABLE t2; + + --error 1305 UNINSTALL PLUGIN EXAMPLE; diff --git a/sql/handler.cc b/sql/handler.cc index a9a2214a91d..c164a2e2b83 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2202,15 +2202,15 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, TABLE_SHARE dummy_share; DBUG_ENTER("ha_delete_table"); + /* table_type is NULL in ALTER TABLE when renaming only .frm files */ + if (table_type == NULL || table_type == view_pseudo_hton || + ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) + DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); + bzero((char*) &dummy_table, sizeof(dummy_table)); bzero((char*) &dummy_share, sizeof(dummy_share)); dummy_table.s= &dummy_share; - /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */ - if (table_type == NULL || - ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type))) - DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); - path= get_canonical_filename(file, path, tmp_path); if ((error= file->ha_delete_table(path)) && generate_warning) { @@ -4319,10 +4319,6 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share) DBUG_RETURN(share->error != OPEN_FRM_OK); } -/** - Check if a given table exists, without doing a full discover, if possible -*/ - static my_bool file_ext_exists(char *path, size_t path_len, const char *ext) { strmake(path + path_len, ext, FN_REFLEN - path_len); @@ -4334,6 +4330,7 @@ struct st_discover_existence_args char *path; size_t path_len; const char *db, *table_name; + handlerton *hton; }; static my_bool discover_existence(THD *thd, plugin_ref plugin, @@ -4344,6 +4341,8 @@ static my_bool discover_existence(THD *thd, plugin_ref plugin, if (ht->state != SHOW_OPTION_YES || !ht->discover_table_existence) return FALSE; + args->hton= ht; + if (ht->discover_table_existence == ext_based_existence) return file_ext_exists(args->path, args->path_len, ht->tablefile_extensions[0]); @@ -4390,25 +4389,53 @@ private: int m_unhandled_errors; }; -bool ha_table_exists(THD *thd, const char *db, const char *table_name) +/** + Check if a given table exists, without doing a full discover, if possible + + If the 'hton' is not NULL, it's set to the handlerton of the storage engine + of this table, or to view_pseudo_hton if the frm belongs to a view. + + + @retval true Table exists (even if the error occurred, like bad frm) + @retval false Table does not exist (one can do CREATE TABLE table_name) +*/ +bool ha_table_exists(THD *thd, const char *db, const char *table_name, + handlerton **hton) { - DBUG_ENTER("ha_discover_table_existence"); + DBUG_ENTER("ha_table_exists"); + + if (hton) + *hton= 0; if (need_full_discover_for_existence) { TABLE_LIST table; + uint flags = GTS_TABLE | GTS_VIEW; + + if (!hton) + flags|= GTS_NOLOCK; Table_exists_error_handler no_such_table_handler; thd->push_internal_handler(&no_such_table_handler); - get_table_share(thd, db, table_name, GTS_TABLE | GTS_VIEW | GTS_NOLOCK); + TABLE_SHARE *share= get_table_share(thd, db, table_name, flags); thd->pop_internal_handler(); + if (hton && share) + { + *hton= share->db_type(); + mysql_mutex_lock(&LOCK_open); + release_table_share(share); + mysql_mutex_unlock(&LOCK_open); + } + // the table doesn't exist if we've caught ER_NO_SUCH_TABLE and nothing else DBUG_RETURN(!no_such_table_handler.safely_trapped_errors()); } mysql_mutex_lock(&LOCK_open); TABLE_SHARE *share= get_cached_table_share(db, table_name); + if (hton && share) + *hton= share->db_type(); mysql_mutex_unlock(&LOCK_open); if (share) @@ -4419,13 +4446,27 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name) db, table_name, "", 0); if (file_ext_exists(path, path_len, reg_ext)) + { + if (hton) + { + enum legacy_db_type db_type; + if (dd_frm_type(thd, path, &db_type) != FRMTYPE_VIEW) + *hton= ha_resolve_by_legacy_type(thd, db_type); + else + *hton= view_pseudo_hton; + } DBUG_RETURN(TRUE); + } - st_discover_existence_args args= {path, path_len, db, table_name}; + st_discover_existence_args args= {path, path_len, db, table_name, 0}; if (plugin_foreach(thd, discover_existence, MYSQL_STORAGE_ENGINE_PLUGIN, &args)) + { + if (hton) + *hton= args.hton; DBUG_RETURN(TRUE); + } DBUG_RETURN(FALSE); } diff --git a/sql/handler.h b/sql/handler.h index 2093a3d1605..02e273204e2 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3073,6 +3073,8 @@ static inline bool ha_storage_engine_is_enabled(const handlerton *db_type) (db_type->state == SHOW_OPTION_YES) : FALSE; } +#define view_pseudo_hton ((handlerton *)1) + /* basic stuff */ int ha_init_errors(void); int ha_init(void); @@ -3102,7 +3104,8 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); int ha_discover_table(THD *thd, TABLE_SHARE *share); int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, handlerton::discovered_list *result); -bool ha_table_exists(THD *thd, const char *db, const char *table_name); +bool ha_table_exists(THD *thd, const char *db, const char *table_name, + handlerton **hton= 0); #ifdef MYSQL_SERVER extern volatile int32 engines_with_discover_table_names; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 0406f8190a8..d6a64b38446 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -906,7 +906,8 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc) mysql_mutex_assert_owner(&LOCK_plugin); - if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED)) + if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED | + PLUGIN_IS_DELETED)) { plugin_ref plugin; #ifdef DBUG_OFF diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 830c57438a3..a59ecbead8d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -54,7 +54,6 @@ #include "sql_parse.h" #include "sql_show.h" #include "transaction.h" -#include "datadict.h" // dd_frm_type() #ifdef __WIN__ #include @@ -2137,8 +2136,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool is_trans; char *db=table->db; size_t db_length= table->db_length; - handlerton *table_type; - enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN; + handlerton *table_type= 0; DBUG_PRINT("table", ("table_l: '%s'.'%s' table: 0x%lx s: 0x%lx", table->db, table->table_name, (long) table->table, @@ -2262,8 +2260,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); error= 0; if (!table->internal_tmp_table && - (drop_temporary || !ha_table_exists(thd, db, alias) || - (!drop_view && dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))) + (drop_temporary || !ha_table_exists(thd, db, alias, &table_type) || + (!drop_view && table_type == view_pseudo_hton))) { /* One of the following cases happened: @@ -2290,6 +2288,19 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, { char *end; + /* + It could happen that table's share in the table_def_cache + is the only thing that keeps the engine plugin loaded + (if it is uninstalled and waits for the ref counter to drop to 0). + + In this case, the tdc_remove_table() below will release and unload + the plugin. And ha_delete_table() will get a dangling pointer. + + Let's lock the plugin till the end of the statement. + */ + if (table_type && table_type != view_pseudo_hton) + plugin_lock(thd, plugin_int_to_ref(hton2plugin[table_type->slot])); + if (thd->locked_tables_mode) { if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED, @@ -2298,6 +2309,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, error= -1; goto err; } + /* the following internally does TDC_RT_REMOVE_ALL */ close_all_tables_for_name(thd, table->table->s, HA_EXTRA_PREPARE_FOR_DROP); table->table= 0; @@ -2311,30 +2323,12 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, table->table_name, MDL_EXCLUSIVE)); - /* - Cannot use the db_type from the table, since that might have changed - while waiting for the exclusive name lock. - */ - if (frm_db_type == DB_TYPE_UNKNOWN) - { - dd_frm_type(thd, path, &frm_db_type); - DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path)); - } - table_type= ha_resolve_by_legacy_type(thd, frm_db_type); // Remove extension for delete *(end= path + path_length - reg_ext_length)= '\0'; - DBUG_PRINT("info", ("deleting table of type %d", - (table_type ? table_type->db_type : 0))); + error= ha_delete_table(thd, table_type, path, db, table->table_name, !dont_log_query); - /* No error if non existent table and 'IF EXIST' clause or view */ - if (error == ENOENT || (error == HA_ERR_NO_SUCH_TABLE && - (if_exists || table_type == NULL))) - { - error= 0; - thd->clear_error(); - } if (error == HA_ERR_ROW_IS_REFERENCED) { /* the table is referenced by a foreign key constraint */ @@ -2342,18 +2336,29 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) { - int new_error; + int frm_delete_error, trigger_drop_error= 0; /* Delete the table definition file */ strmov(end,reg_ext); - if (!(new_error= mysql_file_delete(key_file_frm, path, MYF(MY_WME)))) + frm_delete_error= mysql_file_delete(key_file_frm, path, MYF(MY_WME)); + if (frm_delete_error) + frm_delete_error= my_errno; + else { non_tmp_table_deleted= TRUE; - new_error= Table_triggers_list::drop_all_triggers(thd, db, - table->table_name); + trigger_drop_error= + Table_triggers_list::drop_all_triggers(thd, db, table->table_name); + } + + if (trigger_drop_error || + (frm_delete_error && frm_delete_error != ENOENT)) + error= 1; + else if (!frm_delete_error || !error || if_exists) + { + error= 0; + thd->clear_error(); } - error|= new_error; } - non_tmp_error= error ? TRUE : non_tmp_error; + non_tmp_error= error ? TRUE : non_tmp_error; } if (error) { @@ -2376,7 +2381,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, err: if (wrong_tables.length()) { - thd->clear_error(); if (!foreign_key_error) my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), wrong_tables.c_ptr_safe()); diff --git a/sql/table.h b/sql/table.h index e4e5b839a85..3fe7ef53f4e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -665,8 +665,9 @@ struct TABLE_SHARE plugin_ref db_plugin; /* storage engine plugin */ inline handlerton *db_type() const /* table_type for handler */ { - // DBUG_ASSERT(db_plugin); - return db_plugin ? plugin_data(db_plugin, handlerton*) : NULL; + return is_view ? view_pseudo_hton : + db_plugin ? plugin_data(db_plugin, handlerton*) + : NULL; } enum row_type row_type; /* How rows are stored */ enum tmp_table_type tmp_table; From 5d364e53cb8545790e1b5f37489a2180b78a43cc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:49:00 +0200 Subject: [PATCH 39/87] handlerton::discover_table_names() can not discover only "unknown" tables. Duplicates are possible - deal with them. --- sql/discover.cc | 5 +- sql/discover.h | 2 +- sql/handler.cc | 184 ++++++++++++++++++++++++++++-------- sql/handler.h | 25 ++++- sql/item_subselect.cc | 2 +- sql/sql_array.h | 9 +- sql/sql_show.cc | 81 ++-------------- storage/sphinx/ha_sphinx.cc | 8 +- 8 files changed, 191 insertions(+), 125 deletions(-) diff --git a/sql/discover.cc b/sql/discover.cc index 82dc8d97d65..e2e84824f4d 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -232,11 +232,10 @@ int extension_based_table_discovery(MY_DIR *dirp, const char *ext_meta, will ignore them. Anyone still having these files, should disable discovering engines, and rename these invalid table files. */ -int ext_table_discovery_simple(MY_DIR *dirp, const char *ext_meta, +int ext_table_discovery_simple(MY_DIR *dirp, handlerton::discovered_list *result) { CHARSET_INFO *cs= character_set_filesystem; - size_t ext_meta_len= strlen(ext_meta); FILEINFO *cur, *end; cur= dirp->dir_entry; @@ -248,7 +247,7 @@ int ext_table_discovery_simple(MY_DIR *dirp, const char *ext_meta, if (ext && !is_prefix(cur->name, tmp_file_prefix)) { if (my_strnncoll(cs, (uchar*)ext, strlen(ext), - (uchar*)ext_meta, ext_meta_len) == 0) + (uchar*)reg_ext, reg_ext_length) == 0) { *ext = 0; if (result->add_file(cur->name)) diff --git a/sql/discover.h b/sql/discover.h index d7f94240fa6..a5d98d270e6 100644 --- a/sql/discover.h +++ b/sql/discover.h @@ -25,7 +25,7 @@ int extension_based_table_discovery(MY_DIR *dirp, const char *ext, handlerton::discovered_list *tl); #ifdef MYSQL_SERVER -int ext_table_discovery_simple(MY_DIR *dirp, const char *ext_meta, +int ext_table_discovery_simple(MY_DIR *dirp, handlerton::discovered_list *result); #endif diff --git a/sql/handler.cc b/sql/handler.cc index c164a2e2b83..fa837195f88 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -383,12 +383,36 @@ static int ha_finish_errors(void) return 0; } -volatile int32 need_full_discover_for_existence= 0; +static volatile int32 need_full_discover_for_existence= 0; +static volatile int32 engines_with_discover_table_names= 0; + + static int full_discover_for_existence(handlerton *, const char *, const char *) { return 1; } + static int ext_based_existence(handlerton *, const char *, const char *) { return 1; } +static int hton_ext_based_table_discovery(handlerton *hton, LEX_STRING *db, + MY_DIR *dir, handlerton::discovered_list *result) +{ + /* + tablefile_extensions[0] is the metadata file, see + the comment above tablefile_extensions declaration + */ + return extension_based_table_discovery(dir, hton->tablefile_extensions[0], + result); +} + +static void update_discovery_counters(handlerton *hton, int val) +{ + if (hton->discover_table_existence == full_discover_for_existence) + my_atomic_add32(&need_full_discover_for_existence, val); + + if (hton->discover_table_names) + my_atomic_add32(&engines_with_discover_table_names, val); +} + int ha_finalize_handlerton(st_plugin_int *plugin) { handlerton *hton= (handlerton *)plugin->data; @@ -438,11 +462,7 @@ int ha_finalize_handlerton(st_plugin_int *plugin) hton2plugin[hton->slot]= NULL; } - if (hton->discover_table_existence == full_discover_for_existence) - my_atomic_add32(&need_full_discover_for_existence, -1); - - if (hton->discover_table_names) - my_atomic_add32(&engines_with_discover_table_names, -1); + update_discovery_counters(hton, -1); my_free(hton); @@ -451,13 +471,6 @@ int ha_finalize_handlerton(st_plugin_int *plugin) } -static int hton_ext_based_table_discovery(handlerton *hton, LEX_STRING *db, - MY_DIR *dir, handlerton::discovered_list *result) -{ - return extension_based_table_discovery(dir, hton->tablefile_extensions[0], - result); -} - int ha_initialize_handlerton(st_plugin_int *plugin) { handlerton *hton; @@ -474,6 +487,9 @@ int ha_initialize_handlerton(st_plugin_int *plugin) goto err_no_hton_memory; } + hton->tablefile_extensions= no_exts; + hton->discover_table_names= hton_ext_based_table_discovery; + hton->slot= HA_SLOT_UNDEF; /* Historical Requirement */ plugin->data= hton; // shortcut for the future @@ -484,15 +500,11 @@ int ha_initialize_handlerton(st_plugin_int *plugin) goto err; } - // default list file extensions: empty - if (!hton->tablefile_extensions) - hton->tablefile_extensions= no_exts; - - // if the enfine can discover a single table and it is file-based - // then it can use a default file-based table names discovery - if (!hton->discover_table_names && - hton->discover_table && hton->tablefile_extensions[0]) - hton->discover_table_names= hton_ext_based_table_discovery; + // hton_ext_based_table_discovery() works only when discovery + // is supported and the engine if file-based. + if (hton->discover_table_names == hton_ext_based_table_discovery && + (!hton->discover_table || !hton->tablefile_extensions[0])) + hton->discover_table_names= NULL; // default discover_table_existence implementation if (!hton->discover_table_existence && hton->discover_table) @@ -500,10 +512,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin) if (hton->tablefile_extensions[0]) hton->discover_table_existence= ext_based_existence; else - { hton->discover_table_existence= full_discover_for_existence; - my_atomic_add32(&need_full_discover_for_existence, 1); - } } /* @@ -595,8 +604,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin) break; }; - if (hton->discover_table_names) - my_atomic_add32(&engines_with_discover_table_names, 1); + update_discovery_counters(hton, 1); DBUG_RETURN(0); @@ -4474,13 +4482,88 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, /** Discover all table names in a given database */ -volatile int32 engines_with_discover_table_names= 0; +extern "C" { + +static int cmp_file_names(const void *a, const void *b) +{ + CHARSET_INFO *cs= character_set_filesystem; + char *aa= ((FILEINFO *)a)->name; + char *bb= ((FILEINFO *)b)->name; + return my_strnncoll(cs, (uchar*)aa, strlen(aa), (uchar*)bb, strlen(bb)); +} + +static int cmp_table_names(LEX_STRING * const *a, LEX_STRING * const *b) +{ + return my_strnncoll(&my_charset_bin, (uchar*)((*a)->str), (*a)->length, + (uchar*)((*b)->str), (*b)->length); +} + +} + +Discovered_table_list::Discovered_table_list(THD *thd_arg, + Dynamic_array *tables_arg, + const LEX_STRING *wild_arg) +{ + thd= thd_arg; + tables= tables_arg; + if (wild_arg->str && wild_arg->str[0]) + { + wild= wild_arg->str; + wend= wild + wild_arg->length; + } + else + wild= 0; +} + +bool Discovered_table_list::add_table(const char *tname, size_t tlen) +{ + if (wild && my_wildcmp(files_charset_info, tname, tname + tlen, wild, wend, + wild_prefix, wild_one, wild_many)) + return 0; + + LEX_STRING *name= thd->make_lex_string(tname, tlen); + if (!name || tables->append(name)) + return 1; + return 0; +} + +bool Discovered_table_list::add_file(const char *fname) +{ + char tname[SAFE_NAME_LEN + 1]; + size_t tlen= filename_to_tablename(fname, tname, sizeof(tname)); + return add_table(tname, tlen); +} + + +void Discovered_table_list::sort() +{ + tables->sort(cmp_table_names); +} + +void Discovered_table_list::remove_duplicates() +{ + LEX_STRING **src= tables->front(); + LEX_STRING **dst= src; + while (++dst < tables->back()) + { + LEX_STRING *s= *src, *d= *dst; + DBUG_ASSERT(strncmp(s->str, d->str, min(s->length, d->length)) <= 0); + if ((s->length != d->length || strncmp(s->str, d->str, d->length))) + { + src++; + if (src != dst) + *src= *dst; + } + } + tables->set_elements(src - tables->front() + 1); +} struct st_discover_names_args { LEX_STRING *db; MY_DIR *dirp; - handlerton::discovered_list *result; + Discovered_table_list *result; + uint possible_duplicates; }; static my_bool discover_names(THD *thd, plugin_ref plugin, @@ -4488,28 +4571,51 @@ static my_bool discover_names(THD *thd, plugin_ref plugin, { st_discover_names_args *args= (st_discover_names_args *)arg; handlerton *ht= plugin_data(plugin, handlerton *); - if (ht->state == SHOW_OPTION_YES && ht->discover_table_names && - ht->discover_table_names(ht, args->db, args->dirp, args->result)) - return 1; + + if (ht->state == SHOW_OPTION_YES && ht->discover_table_names) + { + uint old_elements= args->result->tables->elements(); + if (ht->discover_table_names(ht, args->db, args->dirp, args->result)) + return 1; + + /* + hton_ext_based_table_discovery never discovers a table that has + a corresponding .frm file; but custom engine discover methods might + */ + if (ht->discover_table_names != hton_ext_based_table_discovery) + args->possible_duplicates+= args->result->tables->elements() - old_elements; + } return 0; } int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, - handlerton::discovered_list *result) + Discovered_table_list *result) { int error; DBUG_ENTER("ha_discover_table_names"); - st_discover_names_args args= {db, dirp, result}; if (engines_with_discover_table_names == 0) - DBUG_RETURN(ext_table_discovery_simple(dirp, reg_ext, result)); + { + error= ext_table_discovery_simple(dirp, result); + result->sort(); + } + else + { + st_discover_names_args args= {db, dirp, result, 0}; - error= extension_based_table_discovery(dirp, reg_ext, result); + /* extension_based_table_discovery relies on dirp being sorted */ + my_qsort(dirp->dir_entry, dirp->number_of_files, + sizeof(FILEINFO), cmp_file_names); - if (!error) - error= plugin_foreach(thd, discover_names, MYSQL_STORAGE_ENGINE_PLUGIN, - &args); + error= extension_based_table_discovery(dirp, reg_ext, result) || + plugin_foreach(thd, discover_names, + MYSQL_STORAGE_ENGINE_PLUGIN, &args); + result->sort(); + + if (args.possible_duplicates > 0) + result->remove_duplicates(); + } DBUG_RETURN(error); } diff --git a/sql/handler.h b/sql/handler.h index 02e273204e2..7b3be833b33 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -31,6 +31,7 @@ #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA */ #include "sql_cache.h" #include "structs.h" /* SHOW_COMP_OPTION */ +#include "sql_array.h" /* Dynamic_array<> */ #include #include @@ -3101,14 +3102,30 @@ int ha_delete_table(THD *thd, handlerton *db_type, const char *path, bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); /* discovery */ +#ifdef MYSQL_SERVER +class Discovered_table_list: public handlerton::discovered_list +{ + THD *thd; + const char *wild, *wend; +public: + Dynamic_array *tables; + + Discovered_table_list(THD *thd_arg, Dynamic_array *tables_arg, + const LEX_STRING *wild_arg); + ~Discovered_table_list() {} + + bool add_table(const char *tname, size_t tlen); + bool add_file(const char *fname); + + void sort(); + void remove_duplicates(); // assumes that the list is sorted +}; + int ha_discover_table(THD *thd, TABLE_SHARE *share); int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp, - handlerton::discovered_list *result); + Discovered_table_list *result); bool ha_table_exists(THD *thd, const char *db, const char *table_name, handlerton **hton= 0); - -#ifdef MYSQL_SERVER -extern volatile int32 engines_with_discover_table_names; #endif /* key cache */ diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 0544dceb9a0..d373b017db7 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2935,7 +2935,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg) res= TRUE; goto out; } - for (int i= 0; i < eqs.elements(); i++) + for (size_t i= 0; i < eqs.elements(); i++) { if (optimizer->arguments()[0]->maybe_null) { diff --git a/sql/sql_array.h b/sql/sql_array.h index f788b71a785..43ca4ef4219 100644 --- a/sql/sql_array.h +++ b/sql/sql_array.h @@ -104,7 +104,7 @@ public: MYF(MY_THREAD_SPECIFIC)); } - Elem& at(int idx) + Elem& at(size_t idx) { return *(((Elem*)array.buffer) + idx); } @@ -129,11 +129,16 @@ public: return (insert_dynamic(&array, (uchar*)&el)); } - int elements() + size_t elements() { return array.elements; } + void set_elements(size_t n) + { + array.elements= n; + } + ~Dynamic_array() { delete_dynamic(&array); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ff81aff530c..5c92d7db8f2 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -687,59 +687,6 @@ db_name_is_in_ignore_db_dirs_list(const char *directory) return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL; } -class Discovered_table_list: public handlerton::discovered_list -{ - THD *thd; - const char *wild; - size_t wild_length; - Dynamic_array *tables; - -public: - Discovered_table_list(THD *thd_arg, Dynamic_array *tables_arg, - const char *wild_arg) - { - thd= thd_arg; - tables= tables_arg; - if (wild_arg && wild_arg[0]) - { - wild= wild_arg; - wild_length= strlen(wild_arg); - } - else - wild= 0; - } - ~Discovered_table_list() {} - - bool add_table(const char *tname, size_t tlen) - { - if (wild && my_wildcmp(files_charset_info, tname, tname + tlen, - wild, wild + wild_length, - wild_prefix, wild_one, wild_many)) - return 0; - - LEX_STRING *name= thd->make_lex_string(tname, tlen); - if (!name || tables->append(name)) - return 1; - return 0; - } - - bool add_file(const char *fname) - { - char tname[SAFE_NAME_LEN + 1]; - size_t tlen= filename_to_tablename(fname, tname, sizeof(tname)); - return add_table(tname, tlen); - } -}; - -extern "C" { -static int cmp_table_names(LEX_STRING * const *a, LEX_STRING * const *b) -{ - return my_strnncoll(&my_charset_bin, - (const uchar*)((*a)->str), (*a)->length, - (const uchar*)((*b)->str), (*b)->length); -} -} - enum find_files_result { FIND_FILES_OK, FIND_FILES_OOM, @@ -767,20 +714,13 @@ enum find_files_result { static find_files_result find_files(THD *thd, Dynamic_array *files, LEX_STRING *db, - const char *path, const char *wild) + const char *path, const LEX_STRING *wild) { MY_DIR *dirp; - myf my_dir_flags= MY_THREAD_SPECIFIC; Discovered_table_list tl(thd, files, wild); DBUG_ENTER("find_files"); - if (!db) - my_dir_flags|= MY_WANT_STAT; - - if (engines_with_discover_table_names) - my_dir_flags|= MY_WANT_SORT; - - if (!(dirp = my_dir(path, my_dir_flags))) + if (!(dirp = my_dir(path, MY_THREAD_SPECIFIC | (db ? 0 : MY_WANT_STAT)))) { if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR, MYF(ME_BELL | ME_WAITTANG), db->str); @@ -819,6 +759,7 @@ find_files(THD *thd, Dynamic_array *files, LEX_STRING *db, if (tl.add_file(file->name)) goto err; } + tl.sort(); } else { @@ -826,11 +767,9 @@ find_files(THD *thd, Dynamic_array *files, LEX_STRING *db, goto err; } - DBUG_PRINT("info",("found: %d files", files->elements())); + DBUG_PRINT("info",("found: %zu files", files->elements())); my_dirend(dirp); - files->sort(cmp_table_names); - DBUG_RETURN(FIND_FILES_OK); err: @@ -3716,7 +3655,7 @@ int make_db_list(THD *thd, Dynamic_array *files, return 1; } return find_files(thd, files, 0, mysql_data_home, - lookup_field_vals->db_value.str); + &lookup_field_vals->db_value); } @@ -3747,7 +3686,7 @@ int make_db_list(THD *thd, Dynamic_array *files, */ if (files->append_val(&INFORMATION_SCHEMA_NAME)) return 1; - return find_files(thd, files, 0, mysql_data_home, NullS); + return find_files(thd, files, 0, mysql_data_home, &null_lex_str); } @@ -3891,7 +3830,7 @@ make_table_name_list(THD *thd, Dynamic_array *table_names, lookup_field_vals->table_value.str)); find_files_result res= find_files(thd, table_names, db_name, path, - lookup_field_vals->table_value.str); + &lookup_field_vals->table_value); if (res != FIND_FILES_OK) { /* @@ -4633,7 +4572,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (make_db_list(thd, &db_names, &lookup_field_vals)) goto err; - for (int i=0; i < db_names.elements(); i++) + for (size_t i=0; i < db_names.elements(); i++) { LEX_STRING *db_name= db_names.at(i); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -4652,7 +4591,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (res) goto err; - for (int i=0; i < table_names.elements(); i++) + for (size_t i=0; i < table_names.elements(); i++) { LEX_STRING *table_name= table_names.at(i); @@ -4800,7 +4739,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(0); } - for (int i=0; i < db_names.elements(); i++) + for (size_t i=0; i < db_names.elements(); i++) { LEX_STRING *db_name= db_names.at(i); if (db_name == &INFORMATION_SCHEMA_NAME) diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index afb6cea0a40..94940e0b82f 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -1285,7 +1285,7 @@ CSphSEQuery::~CSphSEQuery () SafeDeleteArray ( m_sQueryBuffer ); SafeDeleteArray ( m_pWeights ); SafeDeleteArray ( m_pBuf ); - for ( int i=0; im_iType==SPH_ATTR_BIGINT ? 16 : 12; // id64 + value @@ -1972,13 +1972,13 @@ int CSphSEQuery::BuildRequest ( char ** ppBuffer ) // overrides SendInt ( m_dOverrides.elements() ); - for ( int i=0; im_sName ); SendDword ( pOverride->m_iType ); SendInt ( pOverride->m_dIds.elements() ); - for ( int j=0; jm_dIds.elements(); j++ ) + for ( size_t j=0; jm_dIds.elements(); j++ ) { SendUint64 ( pOverride->m_dIds.at(j) ); if ( pOverride->m_iType==SPH_ATTR_FLOAT ) From 07b252391811d20a6ddd49bac9492257048e8ed6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:49:13 +0200 Subject: [PATCH 40/87] rename a handler method to more precisely reflect what kind of a hack it does --- sql/ha_partition.cc | 8 ++++---- sql/ha_partition.h | 4 ++-- sql/handler.cc | 6 +++--- sql/handler.h | 4 ++-- sql/sql_table.cc | 12 ++++++------ sql/unireg.cc | 4 ++-- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 5f7851b8e25..efb3ceae51f 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -511,7 +511,7 @@ int ha_partition::rename_table(const char *from, const char *to) Create the handler file (.par-file) SYNOPSIS - create_handler_files() + create_partitioning_metadata() name Full path of table name create_info Create info generated for CREATE TABLE @@ -520,19 +520,19 @@ int ha_partition::rename_table(const char *from, const char *to) 0 Success DESCRIPTION - create_handler_files is called to create any handler specific files + create_partitioning_metadata is called to create any handler specific files before opening the file with openfrm to later call ::create on the file object. In the partition handler this is used to store the names of partitions and types of engines in the partitions. */ -int ha_partition::create_handler_files(const char *path, +int ha_partition::create_partitioning_metadata(const char *path, const char *old_path, int action_flag, HA_CREATE_INFO *create_info) { - DBUG_ENTER("ha_partition::create_handler_files()"); + DBUG_ENTER("ha_partition::create_partitioning_metadata()"); /* We need to update total number of parts since we might write the handler diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 9e1c5b0bf5f..4f753cf5a9e 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -229,7 +229,7 @@ public: chance for the handler to add any interesting comments to the table comments not provided by the users comment. - create_handler_files is called before opening a new handler object + create_partitioning_metadata is called before opening a new handler object with openfrm to call create. It is used to create any local handler object needed in opening the object in openfrm ------------------------------------------------------------------------- @@ -238,7 +238,7 @@ public: virtual int rename_table(const char *from, const char *to); virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); - virtual int create_handler_files(const char *name, + virtual int create_partitioning_metadata(const char *name, const char *old_name, int action_flag, HA_CREATE_INFO *create_info); virtual void update_create_info(HA_CREATE_INFO *create_info); diff --git a/sql/handler.cc b/sql/handler.cc index fa837195f88..a1c4ba89035 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3835,16 +3835,16 @@ handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info) /** Create handler files for CREATE TABLE: public interface. - @sa handler::create_handler_files() + @sa handler::create_partitioning_metadata() */ int -handler::ha_create_handler_files(const char *name, const char *old_name, +handler::ha_create_partitioning_metadata(const char *name, const char *old_name, int action_flag, HA_CREATE_INFO *info) { mark_trx_read_write(); - return create_handler_files(name, old_name, action_flag, info); + return create_partitioning_metadata(name, old_name, action_flag, info); } diff --git a/sql/handler.h b/sql/handler.h index 7b3be833b33..ea928afa9ed 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2063,7 +2063,7 @@ public: int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info); - int ha_create_handler_files(const char *name, const char *old_name, + int ha_create_partitioning_metadata(const char *name, const char *old_name, int action_flag, HA_CREATE_INFO *info); int ha_change_partitions(HA_CREATE_INFO *create_info, @@ -3003,7 +3003,7 @@ private: virtual void drop_table(const char *name); virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0; - virtual int create_handler_files(const char *name, const char *old_name, + virtual int create_partitioning_metadata(const char *name, const char *old_name, int action_flag, HA_CREATE_INFO *info) { return FALSE; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a59ecbead8d..6fc5d9c0fc1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1707,7 +1707,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) lpt->table_name, lpt->create_info, lpt->alter_info->create_list, lpt->key_count, lpt->key_info_buffer, lpt->table->file)) || - lpt->table->file->ha_create_handler_files(shadow_path, NULL, + lpt->table->file->ha_create_partitioning_metadata(shadow_path, NULL, CHF_CREATE_FLAG, lpt->create_info)) { @@ -1760,13 +1760,13 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) */ if (mysql_file_delete(key_file_frm, frm_name, MYF(MY_WME)) || #ifdef WITH_PARTITION_STORAGE_ENGINE - lpt->table->file->ha_create_handler_files(path, shadow_path, + lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, CHF_DELETE_FLAG, NULL) || deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) || (sync_ddl_log(), FALSE) || mysql_file_rename(key_file_frm, shadow_frm_name, frm_name, MYF(MY_WME)) || - lpt->table->file->ha_create_handler_files(path, shadow_path, + lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, CHF_RENAME_FLAG, NULL)) #else mysql_file_rename(key_file_frm, @@ -4029,7 +4029,7 @@ static bool check_if_created_table_can_be_opened(THD *thd, /* It is impossible to open definition of partitioned table without .par file. */ - if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info)) + if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, create_info)) return TRUE; init_tmp_table_share(thd, &share, db, 0, table_name, path); @@ -4041,7 +4041,7 @@ static bool check_if_created_table_can_be_opened(THD *thd, (void) closefrm(&table, 0); free_table_share(&share); - (void) file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info); + (void) file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, create_info); return result; } #endif @@ -7197,7 +7197,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* Tell the handler that a new frm file is in place. */ - error= t_table_list->table->file->ha_create_handler_files(path, NULL, + error= t_table_list->table->file->ha_create_partitioning_metadata(path, NULL, CHF_INDEX_FLAG, create_info); diff --git a/sql/unireg.cc b/sql/unireg.cc index 90039c478be..e2381e34fc7 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -476,14 +476,14 @@ int rea_create_table(THD *thd, const char *path, if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; if (!create_info->frm_only && - (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, + (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, create_info) || ha_create_table(thd, path, db, table_name, create_info, 0))) goto err_handler; DBUG_RETURN(0); err_handler: - (void) file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info); + (void) file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, create_info); mysql_file_delete(key_file_frm, frm_name, MYF(0)); DBUG_RETURN(1); } /* rea_create_table */ From 2481db063f5262860a8c98635167b55b2ea73e20 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:49:21 +0200 Subject: [PATCH 41/87] move writing of the frm into init_from_binary_frm_image() --- sql/table.cc | 23 ++++++++++++++++------- sql/table.h | 3 ++- storage/archive/ha_archive.cc | 26 ++++++++++++++------------ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index d9dab7fe170..34292f5ad10 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -39,6 +39,7 @@ #include "sql_select.h" #include "sql_derived.h" #include "sql_statistics.h" +#include "discover.h" #include "mdl.h" // MDL_wait_for_graph_visitor /* INFORMATION_SCHEMA name */ @@ -613,7 +614,6 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) uchar *buf; uchar head[64]; char path[FN_REFLEN]; - MEM_ROOT **root_ptr, *old_root; DBUG_ENTER("open_table_def"); DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, share->table_name.str, share->normalized_path.str)); @@ -708,12 +708,8 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) } mysql_file_close(file, MYF(MY_WME)); - root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); - old_root= *root_ptr; - *root_ptr= &share->mem_root; - share->init_from_binary_frm_image(thd, buf); + share->init_from_binary_frm_image(thd, NULL, buf, stats.st_size); error_given= true; - *root_ptr= old_root; my_free(buf); if (!share->error) @@ -745,9 +741,12 @@ err_not_open: 28..29 (used to be key_info_length) They're still set, for compatibility reasons, but never read. + + TODO verify that we never read data from beyond frm_length! */ -bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const uchar *frm_image) +bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, + const uchar *frm_image, size_t frm_length) { TABLE_SHARE *share= this; uint new_frm_ver, field_pack_length, new_field_pack_flag; @@ -782,8 +781,16 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const uchar *frm_image) uint first_key_parts= 0; keyinfo= &first_keyinfo; share->ext_key_parts= 0; + MEM_ROOT **root_ptr, *old_root; DBUG_ENTER("open_binary_frm"); + root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); + old_root= *root_ptr; + *root_ptr= &share->mem_root; + + if (path && writefrm(path, frm_image, frm_length)) + goto err; + new_field_pack_flag= frm_image[27]; new_frm_ver= (frm_image[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; @@ -1922,6 +1929,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const uchar *frm_image) #endif share->error= OPEN_FRM_OK; + *root_ptr= old_root; DBUG_RETURN(0); err: @@ -1945,6 +1953,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const uchar *frm_image) if (!thd->is_error()) open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno); + *root_ptr= old_root; DBUG_RETURN(1); } /* open_binary_frm */ diff --git a/sql/table.h b/sql/table.h index 3fe7ef53f4e..0922286070d 100644 --- a/sql/table.h +++ b/sql/table.h @@ -988,7 +988,8 @@ struct TABLE_SHARE uint actual_n_key_parts(THD *thd); - bool init_from_binary_frm_image(THD *thd, const uchar *frm_image); + bool init_from_binary_frm_image(THD *thd, const char *path, + const uchar *frm_image, size_t frm_length); }; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 37b1273b65d..0de26f37796 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -281,7 +281,7 @@ int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) strxmov(az_file, share->normalized_path.str, ARZ, NullS); if (!(mysql_file_stat(/* arch_key_file_data */ 0, az_file, &file_stat, MYF(0)))) - goto err; + DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); if (!(azopen(&frm_stream, az_file, O_RDONLY|O_BINARY))) { @@ -293,21 +293,23 @@ int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) if (frm_stream.frm_length == 0) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); - frm_ptr= (uchar *)my_malloc(sizeof(char) * frm_stream.frm_length, MYF(0)); - azread_frm(&frm_stream, frm_ptr); + frm_ptr= (uchar *)my_malloc(sizeof(char) * frm_stream.frm_length, + MYF(MY_THREAD_SPECIFIC | MY_WME)); + if (!frm_ptr) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + if (azread_frm(&frm_stream, frm_ptr)) + goto ret; + azclose(&frm_stream); - // don't go through the discovery again - if (writefrm(share->normalized_path.str, frm_ptr, frm_stream.frm_length)) - DBUG_RETURN(my_errno); - - share->init_from_binary_frm_image(thd, frm_ptr); + if (!share->init_from_binary_frm_image(thd, share->normalized_path.str, + frm_ptr, frm_stream.frm_length)) + my_errno= 0; +ret: my_free(frm_ptr); - - DBUG_RETURN(0); -err: - DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); + DBUG_RETURN(my_errno); } /* From 556f5684930fdd44093b1918ac32976dfbdf55ba Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:49:30 +0200 Subject: [PATCH 42/87] init_from_binary_frm_image: verify that we don't read beyond the image buffer --- sql/table.cc | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index 34292f5ad10..b8a631f6b18 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -709,7 +709,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) mysql_file_close(file, MYF(MY_WME)); share->init_from_binary_frm_image(thd, NULL, buf, stats.st_size); - error_given= true; + error_given= true; // init_from_binary_frm_image has already called my_error() my_free(buf); if (!share->error) @@ -741,8 +741,6 @@ err_not_open: 28..29 (used to be key_info_length) They're still set, for compatibility reasons, but never read. - - TODO verify that we never read data from beyond frm_length! */ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, @@ -758,6 +756,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, bool use_hash; char *keynames, *names, *comment_pos; const uchar *forminfo; + const uchar *frm_image_end = frm_image + frm_length; uchar *record, *null_flags, *null_pos; const uchar *disk_buff, *strpos; ulong pos, record_offset; @@ -791,16 +790,22 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, if (path && writefrm(path, frm_image, frm_length)) goto err; + if (frm_length < 64 + 288) + goto err; + new_field_pack_flag= frm_image[27]; new_frm_ver= (frm_image[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; /* Position of the form in the form file. */ len = uint2korr(frm_image+4); - if (!(pos= uint4korr(frm_image + 64 + len))) + if (frm_length < 64 + len || !(pos= uint4korr(frm_image + 64 + len))) goto err; forminfo= frm_image + pos; + if (forminfo + 288 >= frm_image_end) + goto err; + share->frm_version= frm_image[2]; /* Check if .frm file created by MySQL 5.0. In this case we want to @@ -863,6 +868,10 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, /* Read keyinformation */ disk_buff= frm_image + uint2korr(frm_image+6); + + if (disk_buff + 6 >= frm_image_end) + goto err; + if (disk_buff[0] & 0x80) { share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f); @@ -912,6 +921,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, { if (new_frm_ver >= 3) { + if (strpos + 8 >= frm_image_end) + goto err; keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; keyinfo->key_length= (uint) uint2korr(strpos+2); keyinfo->key_parts= (uint) strpos[4]; @@ -921,6 +932,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, } else { + if (strpos + 4 >= frm_image_end) + goto err; keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; keyinfo->key_length= (uint) uint2korr(strpos+1); keyinfo->key_parts= (uint) strpos[3]; @@ -958,6 +971,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, keyinfo->rec_per_key= rec_per_key; for (j=keyinfo->key_parts ; j-- ; key_part++) { + if (strpos + (new_frm_ver >= 1 ? 9 : 7) >= frm_image_end) + goto err; *rec_per_key++=0; key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK); key_part->offset= (uint) uint2korr(strpos+2)-1; @@ -1014,17 +1029,25 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, share->ext_key_parts+= keyinfo->ext_key_parts; } keynames=(char*) key_part; - strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; + strpos+= strnmov(keynames, (char *) strpos, frm_image_end - strpos) - keynames; + if (*strpos++) // key names are \0-terminated + goto err; //reading index comments for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++) { if (keyinfo->flags & HA_USES_COMMENT) { + if (strpos + 2 >= frm_image_end) + goto err; keyinfo->comment.length= uint2korr(strpos); - keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2, + strpos+= 2; + + if (strpos + keyinfo->comment.length >= frm_image_end) + goto err; + keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos, keyinfo->comment.length); - strpos+= 2 + keyinfo->comment.length; + strpos+= keyinfo->comment.length; } DBUG_ASSERT(test(keyinfo->flags & HA_USES_COMMENT) == (keyinfo->comment.length > 0)); @@ -1038,6 +1061,9 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, record_offset= (ulong) (uint2korr(frm_image+6)+ ((uint2korr(frm_image+14) == 0xffff ? uint4korr(frm_image+47) : uint2korr(frm_image+14)))); + + if (record_offset + share->reclength >= frm_length) + goto err; if ((n_length= uint4korr(frm_image+55))) { @@ -1046,6 +1072,10 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, DBUG_PRINT("info", ("extra segment size is %u bytes", n_length)); next_chunk= frm_image + record_offset + share->reclength; buff_end= next_chunk + n_length; + + if (buff_end >= frm_image_end) + goto err; + share->connect_string.length= uint2korr(next_chunk); if (!(share->connect_string.str= strmake_root(&share->mem_root, (char*) next_chunk + 2, @@ -1882,8 +1912,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, &share->next_number_key_offset, &share->next_number_keypart)) < 0) goto err; // Wrong field definition - else - reg_field->flags |= AUTO_INCREMENT_FLAG; + reg_field->flags |= AUTO_INCREMENT_FLAG; } if (share->blob_fields) From 5f69c8a59480569eb275169630f91763fceacc0f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:49:39 +0200 Subject: [PATCH 43/87] ha_create_table: remove unused argument --- sql/datadict.cc | 2 +- sql/handler.cc | 6 ++---- sql/handler.h | 3 +-- sql/sql_truncate.cc | 2 +- sql/unireg.cc | 2 +- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/sql/datadict.cc b/sql/datadict.cc index 3b125d47235..c228784d578 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -180,7 +180,7 @@ bool dd_recreate_table(THD *thd, const char *db, const char *table_name) build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); /* Attempt to reconstruct the table. */ - error= ha_create_table(thd, path, db, table_name, &create_info, TRUE); + error= ha_create_table(thd, path, db, table_name, &create_info); DBUG_RETURN(error); } diff --git a/sql/handler.cc b/sql/handler.cc index a1c4ba89035..b8ad8678b87 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4132,8 +4132,7 @@ end: */ int ha_create_table(THD *thd, const char *path, const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - bool update_create_info) + HA_CREATE_INFO *create_info) { int error= 1; TABLE table; @@ -4148,8 +4147,7 @@ int ha_create_table(THD *thd, const char *path, TRUE)) goto err; - if (update_create_info) - update_create_info_from_table(create_info, &table); + update_create_info_from_table(create_info, &table); name= get_canonical_filename(table.file, share.path.str, name_buff); diff --git a/sql/handler.h b/sql/handler.h index ea928afa9ed..11221fa3b10 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3093,8 +3093,7 @@ void ha_checkpoint_state(bool disable); void ha_commit_checkpoint_request(void *cookie, void (*pre_hook)(void *)); int ha_create_table(THD *thd, const char *path, const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - bool update_create_info); + HA_CREATE_INFO *create_info); int ha_delete_table(THD *thd, handlerton *db_type, const char *path, const char *db, const char *alias, bool generate_warning); diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index d47fb24eaba..041bc178a0d 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -276,7 +276,7 @@ static bool recreate_temporary_table(THD *thd, TABLE *table) on table and schema names. */ ha_create_table(thd, share->normalized_path.str, share->db.str, - share->table_name.str, &create_info, 1); + share->table_name.str, &create_info); if (open_table_uncached(thd, share->path.str, share->db.str, share->table_name.str, TRUE)) diff --git a/sql/unireg.cc b/sql/unireg.cc index e2381e34fc7..60d419808ef 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -478,7 +478,7 @@ int rea_create_table(THD *thd, const char *path, if (!create_info->frm_only && (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, create_info) || - ha_create_table(thd, path, db, table_name, create_info, 0))) + ha_create_table(thd, path, db, table_name, create_info))) goto err_handler; DBUG_RETURN(0); From 9594107fb8ce4c691c0cbb5891eef5add6ee105f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:49:48 +0200 Subject: [PATCH 44/87] cleanups --- sql/datadict.cc | 25 +++++++++++++++++-------- sql/datadict.h | 3 ++- sql/sql_truncate.cc | 13 ++----------- sql/unireg.cc | 22 ++++++++-------------- sql/unireg.h | 2 +- 5 files changed, 30 insertions(+), 35 deletions(-) diff --git a/sql/datadict.cc b/sql/datadict.cc index c228784d578..15419c4f577 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -158,26 +158,35 @@ bool dd_check_storage_engine_flag(THD *thd, @param thd Thread context. @param db Name of the database to which the table belongs to. @param name Table name. + @param path For temporary tables only - path to table files. + Otherwise NULL (the path is calculated from db and table names). @retval FALSE Success. @retval TRUE Error. */ -bool dd_recreate_table(THD *thd, const char *db, const char *table_name) +bool dd_recreate_table(THD *thd, const char *db, const char *table_name, + const char *path) { bool error= TRUE; HA_CREATE_INFO create_info; - char path[FN_REFLEN + 1]; + char path_buf[FN_REFLEN + 1]; DBUG_ENTER("dd_recreate_table"); - /* There should be a exclusive metadata lock on the table. */ - DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, - MDL_EXCLUSIVE)); - memset(&create_info, 0, sizeof(create_info)); - /* Create a path to the table, but without a extension. */ - build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); + if (path) + create_info.options|= HA_LEX_CREATE_TMP_TABLE; + else + { + build_table_filename(path_buf, sizeof(path_buf) - 1, + db, table_name, "", 0); + path= path_buf; + + /* There should be a exclusive metadata lock on the table. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, + MDL_EXCLUSIVE)); + } /* Attempt to reconstruct the table. */ error= ha_create_table(thd, path, db, table_name, &create_info); diff --git a/sql/datadict.h b/sql/datadict.h index f852b02f52c..9c625e6434c 100644 --- a/sql/datadict.h +++ b/sql/datadict.h @@ -36,6 +36,7 @@ bool dd_check_storage_engine_flag(THD *thd, const char *db, const char *table_name, uint32 flag, bool *yes_no); -bool dd_recreate_table(THD *thd, const char *db, const char *table_name); +bool dd_recreate_table(THD *thd, const char *db, const char *table_name, + const char *path = NULL); #endif // DATADICT_INCLUDED diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 041bc178a0d..0e97de5a6aa 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -258,25 +258,16 @@ static bool recreate_temporary_table(THD *thd, TABLE *table) { bool error= TRUE; TABLE_SHARE *share= table->s; - HA_CREATE_INFO create_info; handlerton *table_type= table->s->db_type(); DBUG_ENTER("recreate_temporary_table"); - memset(&create_info, 0, sizeof(create_info)); - create_info.options|= HA_LEX_CREATE_TMP_TABLE; - table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); /* Don't free share. */ close_temporary_table(thd, table, FALSE, FALSE); - /* - We must use share->normalized_path.str since for temporary tables it - differs from what dd_recreate_table() would generate based - on table and schema names. - */ - ha_create_table(thd, share->normalized_path.str, share->db.str, - share->table_name.str, &create_info); + dd_recreate_table(thd, share->db.str, share->table_name.str, + share->normalized_path.str); if (open_table_uncached(thd, share->path.str, share->db.str, share->table_name.str, TRUE)) diff --git a/sql/unireg.cc b/sql/unireg.cc index 60d419808ef..eeaa8fc747f 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -49,11 +49,9 @@ static bool pack_header(uchar *forminfo,enum legacy_db_type table_type, static uint get_interval_id(uint *,List &, Create_field *); static bool pack_fields(File file, List &create_fields, ulong data_offset); -static bool make_empty_rec(THD *thd, int file, enum legacy_db_type table_type, - uint table_options, +static bool make_empty_rec(THD *thd, int file, uint table_options, List &create_fields, - uint reclength, ulong data_offset, - handler *handler); + uint reclength, ulong data_offset); /** An interceptor to hijack ER_TOO_MANY_FIELDS error from @@ -102,8 +100,8 @@ handle_condition(THD *, create_fields Fields to create keys number of keys to create key_info Keys to create - db_file Handler to use. May be zero, in which case we use - create_info->db_type + db_file Handler to use. + RETURN false ok true error @@ -317,9 +315,8 @@ bool mysql_create_frm(THD *thd, const char *file_name, mysql_file_seek(file, (ulong) uint2korr(fileinfo+6) + (ulong) key_buff_length, MY_SEEK_SET, MYF(0)); - if (make_empty_rec(thd,file,ha_legacy_type(create_info->db_type), - create_info->table_options, - create_fields,reclength, data_offset, db_file)) + if (make_empty_rec(thd, file, create_info->table_options, + create_fields, reclength, data_offset)) goto err; int2store(buff, create_info->connect_string.length); @@ -1064,12 +1061,9 @@ static bool pack_fields(File file, List &create_fields, /* save an empty record on start of formfile */ -static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type, - uint table_options, +static bool make_empty_rec(THD *thd, File file, uint table_options, List &create_fields, - uint reclength, - ulong data_offset, - handler *handler) + uint reclength, ulong data_offset) { int error= 0; Field::utype type; diff --git a/sql/unireg.h b/sql/unireg.h index 702637b0736..46ff166a2b3 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -86,7 +86,7 @@ #define READ_ALL 1 /* openfrm: Read all parameters */ #define CHANGE_FRM 2 /* openfrm: open .frm as O_RDWR */ #define READ_KEYINFO 4 /* L{s nyckeldata fr}n filen */ -#define EXTRA_RECORD 8 /* Reservera plats f|r extra record */ +#define EXTRA_RECORD 8 /* Reserve space for an extra record */ #define DONT_OPEN_TABLES 8 /* Don't open database-files (frd) */ #define DONT_OPEN_MASTER_REG 16 /* Don't open first reg-file (prt) */ #define EXTRA_LONG_RECORD 16 /* Plats f|r dubbel s|k-record */ From 15c936e4b3d151346c027bd4b51b44c826b095b6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:49:59 +0200 Subject: [PATCH 45/87] open_table_def() no longer probes for the old pre-5.1 table file names. SELECT * FROM `t-1` will no longer read "t-1.frm" file, use `#mysql50#t-1` for this. --- sql/table.cc | 45 ++++++--------------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index b8a631f6b18..647e8d3ee5a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -621,48 +621,15 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) share->error= OPEN_FRM_OPEN_ERROR; strxmov(path, share->normalized_path.str, reg_ext, NullS); - if ((file= mysql_file_open(key_file_frm, - path, O_RDONLY | O_SHARE, MYF(0))) < 0) + file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0)); + if (file < 0) { - if (!has_disabled_path_chars(share->table_name.str) && - !has_disabled_path_chars(share->db.str)) + if ((flags & GTS_TABLE) && (flags & GTS_FORCE_DISCOVERY)) { - /* Try unencoded 5.0 name */ - uint length; - strxnmov(path, sizeof(path)-1, - mysql_data_home, "/", share->db.str, "/", - share->table_name.str, reg_ext, NullS); - length= unpack_filename(path, path) - reg_ext_length; - /* - The following is a safety test and should never fail - as the old file name should never be longer than the new one. - */ - DBUG_ASSERT(length <= share->normalized_path.length); - /* - If the old and the new names have the same length, - then table name does not have tricky characters, - so no need to check the old file name. - */ - if (length != share->normalized_path.length && - (file= mysql_file_open(key_file_frm, - path, O_RDONLY | O_SHARE, MYF(0))) >= 0) - { - /* Unencoded 5.0 table name found */ - path[length]= '\0'; // Remove .frm extension - strmov(share->normalized_path.str, path); - share->normalized_path.length= length; - } - } - /* still no luck? try to discover the table */ - if (file < 0) - { - if (flags & GTS_TABLE && flags & GTS_FORCE_DISCOVERY) - { - ha_discover_table(thd, share); - error_given= true; - } - goto err_not_open; + ha_discover_table(thd, share); + error_given= true; } + goto err_not_open; } if (mysql_file_read(file, head, sizeof(head), MYF(MY_NABP))) From cdc01e29d3a9f6d98aaa482363af81003485e256 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:50:30 +0200 Subject: [PATCH 46/87] remove dd_frm_type(), dd_frm_storage_engine(), dd_check_storage_engine_flag() from everywhere - now RENAME, SHOW FULL TABLES, and TRUNCATE work with discovery. improve error messages in truncate --- mysql-test/r/mdl_sync.result | 2 +- mysql-test/r/ps_1general.result | 2 +- mysql-test/r/rename.result | 10 +-- mysql-test/r/truncate_badse.result | 13 ++++ mysql-test/suite/archive/archive.result | 10 --- mysql-test/suite/archive/archive.test | 10 --- mysql-test/suite/archive/discover.result | 37 +++++++++- mysql-test/suite/archive/discover.test | 29 +++++++- mysql-test/t/mdl_sync.test | 2 +- mysql-test/t/myisam-system.test | 5 ++ mysql-test/t/ps_1general.test | 5 +- mysql-test/t/rename.test | 10 +-- mysql-test/t/truncate_badse.test | 15 ++++ sql/datadict.cc | 82 --------------------- sql/datadict.h | 19 +++-- sql/handler.cc | 4 +- sql/sql_base.cc | 5 +- sql/sql_rename.cc | 93 +++++++++++------------- sql/sql_show.cc | 31 +++----- sql/sql_table.cc | 8 +- sql/sql_truncate.cc | 22 +++++- sql/sql_view.cc | 22 +++--- sql/table.cc | 20 +---- 23 files changed, 213 insertions(+), 243 deletions(-) create mode 100644 mysql-test/r/truncate_badse.result create mode 100644 mysql-test/t/truncate_badse.test diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index b2e71faf741..1c94f867a54 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -2850,7 +2850,7 @@ SET DEBUG_SYNC= 'now SIGNAL blocked'; # Reaping: DROP DATABASE db1 # Connection con2 # Reaping: RENAME TABLE db1.t1 TO test.t1 -Got one of the listed errors +ERROR 42S02: Table 'db1.t1' doesn't exist # Connection default CREATE DATABASE db1; CREATE TABLE test.t2 (a INT); diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 3ca0cf8554f..0a8aea94e8a 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -533,7 +533,7 @@ drop table t2; prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ; create table t5 (a int) ; execute stmt1 ; -ERROR HY000: Can't find file: './test/t7' (errno: 2 "No such file or directory") +ERROR 42S02: Table 'test.t7' doesn't exist create table t7 (a int) ; execute stmt1 ; execute stmt1 ; diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result index edf05d0c5d3..7433ab8a0c9 100644 --- a/mysql-test/r/rename.result +++ b/mysql-test/r/rename.result @@ -14,20 +14,20 @@ select * from t1; 1 table 1 1 table 1 rename table t1 to t2; -Got one of the listed errors +ERROR 42S01: Table 't2' already exists rename table t1 to t1; -Got one of the listed errors +ERROR 42S01: Table 't1' already exists rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2; -Got one of the listed errors +ERROR 42S01: Table 't2' already exists show tables like "t_"; Tables_in_test (t_) t1 t2 t3 rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1; -Got one of the listed errors +ERROR 42S01: Table 't1' already exists rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1; -Got one of the listed errors +ERROR 42S02: Table 'test.t5' doesn't exist select * from t1; 1 table 1 1 table 1 diff --git a/mysql-test/r/truncate_badse.result b/mysql-test/r/truncate_badse.result new file mode 100644 index 00000000000..16f44f180ed --- /dev/null +++ b/mysql-test/r/truncate_badse.result @@ -0,0 +1,13 @@ +install plugin example soname 'ha_example'; +create table t1 (a int) engine=example; +select 1; +1 +1 +uninstall plugin example; +flush tables; +select count(*) from information_schema.plugins where plugin_name='example'; +count(*) +0 +truncate table t1; +ERROR 42000: Unknown storage engine 'EXAMPLE' +drop table t1; diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index df0db73244a..f5c97cb4dde 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12749,16 +12749,6 @@ SELECT * FROM t1; col1 col2 DROP TABLE t1; # -# BUG#48757 - missing .ARZ file causes server crash -# -CREATE TABLE t1(a INT) ENGINE=ARCHIVE; -FLUSH TABLE t1; -SELECT * FROM t1; -ERROR HY000: Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory") -DROP TABLE t1; -Warnings: -Warning 2 Can't find file: './test/t1.ARZ' (errno: 2 "No such file or directory") -# # Ensure that TRUNCATE fails for non-empty archive tables. # CREATE TABLE t1 (a INT) ENGINE=ARCHIVE; diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 0dfdc969162..70e32254062 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1668,16 +1668,6 @@ SELECT * FROM t1; DROP TABLE t1; remove_file $MYSQLD_DATADIR/test/t1.ARM; ---echo # ---echo # BUG#48757 - missing .ARZ file causes server crash ---echo # -CREATE TABLE t1(a INT) ENGINE=ARCHIVE; -FLUSH TABLE t1; ---remove_file $MYSQLD_DATADIR/test/t1.ARZ ---error ER_FILE_NOT_FOUND -SELECT * FROM t1; -DROP TABLE t1; - --echo # --echo # Ensure that TRUNCATE fails for non-empty archive tables. --echo # diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index 51f66ee701b..ae8b69d56b6 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -18,19 +18,50 @@ a 1 2 # -# list tables +# show tables # -create table t0 (a int) engine=archive; +create table t2 (a int) engine=archive; flush tables; show tables; Tables_in_test -t0 t1 +t2 select * from t1; a 1 2 # +# show full tables +# +flush tables; +show full tables; +Tables_in_test Table_type +t1 BASE TABLE +t2 BASE TABLE +select * from t1; +a +1 +2 +# +# discover on truncate +# +flush tables; +truncate table t1; +ERROR HY000: Table storage engine for 't1' doesn't have this option +show tables; +Tables_in_test +t1 +t2 +# +# discover on rename +# +flush tables; +rename table t2 to t0; +show tables; +Tables_in_test +t0 +t1 +# # discover on drop # flush tables; diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 843cb0caf63..4be90f50a50 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -15,14 +15,39 @@ insert t1 values (2); select * from t1; --echo # ---echo # list tables +--echo # show tables --echo # -create table t0 (a int) engine=archive; +create table t2 (a int) engine=archive; remove_file $mysqld_datadir/test/t1.frm; flush tables; show tables; select * from t1; +--echo # +--echo # show full tables +--echo # +remove_file $mysqld_datadir/test/t1.frm; +flush tables; +show full tables; +select * from t1; + +--echo # +--echo # discover on truncate +--echo # +remove_file $mysqld_datadir/test/t1.frm; +flush tables; +--error ER_ILLEGAL_HA +truncate table t1; +show tables; + +--echo # +--echo # discover on rename +--echo # +remove_file $mysqld_datadir/test/t2.frm; +flush tables; +rename table t2 to t0; +show tables; + --echo # --echo # discover on drop --echo # diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index 197cad536e4..fef8a9848ca 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -4382,7 +4382,7 @@ connection default; --echo # Connection con2 connection con2; --echo # Reaping: RENAME TABLE db1.t1 TO test.t1 ---error ER_FILE_NOT_FOUND, ER_FILE_NOT_FOUND +--error ER_NO_SUCH_TABLE --reap --echo # Connection default diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test index ef1bc03434d..cece33bb00b 100644 --- a/mysql-test/t/myisam-system.test +++ b/mysql-test/t/myisam-system.test @@ -9,16 +9,21 @@ drop table if exists t1,t2; create table t1 (a int) engine=myisam; let $MYSQLD_DATADIR= `select @@datadir`; --remove_file $MYSQLD_DATADIR/test/t1.MYI +--replace_result $MYSQLD_DATADIR ./ drop table if exists t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYI +--replace_result $MYSQLD_DATADIR ./ --error ER_FILE_NOT_FOUND select * from t1; +--replace_result $MYSQLD_DATADIR ./ drop table t1; create table t1 (a int) engine=myisam; --remove_file $MYSQLD_DATADIR/test/t1.MYD +--replace_result $MYSQLD_DATADIR ./ --error 29 select * from t1; +--replace_result $MYSQLD_DATADIR ./ drop table t1; --error ER_BAD_TABLE_ERROR drop table t1; diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 812b1b5ff94..22cad56a8e4 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -582,10 +582,7 @@ drop table t2; # cases derived from client_test.c: test_rename() prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ; create table t5 (a int) ; -# rename must fail, t7 does not exist -# Clean up the filename here because embedded server reports whole path ---replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' t7.frm t7 ---error ER_FILE_NOT_FOUND +--error ER_NO_SUCH_TABLE execute stmt1 ; create table t7 (a int) ; # rename, t5 -> t6 and t7 -> t8 diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test index bb90cbafd74..a55bc845acc 100644 --- a/mysql-test/t/rename.test +++ b/mysql-test/t/rename.test @@ -21,16 +21,16 @@ rename table t3 to t4, t2 to t3, t1 to t2, t4 to t1; select * from t1; # The following should give errors ---error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR +--error ER_TABLE_EXISTS_ERROR rename table t1 to t2; ---error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR +--error ER_TABLE_EXISTS_ERROR rename table t1 to t1; ---error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR +--error ER_TABLE_EXISTS_ERROR rename table t3 to t4, t2 to t3, t1 to t2, t4 to t2; show tables like "t_"; ---error ER_TABLE_EXISTS_ERROR,ER_TABLE_EXISTS_ERROR +--error ER_TABLE_EXISTS_ERROR rename table t3 to t1, t2 to t3, t1 to t2, t4 to t1; ---error ER_FILE_NOT_FOUND,ER_FILE_NOT_FOUND +--error ER_NO_SUCH_TABLE rename table t3 to t4, t5 to t3, t1 to t2, t4 to t1; select * from t1; diff --git a/mysql-test/t/truncate_badse.test b/mysql-test/t/truncate_badse.test new file mode 100644 index 00000000000..71545cab11a --- /dev/null +++ b/mysql-test/t/truncate_badse.test @@ -0,0 +1,15 @@ +# +# test what TRUNCATE TABLE does, if the table was created in +# now-unknown storage engine. +# +--source include/have_example_plugin.inc +install plugin example soname 'ha_example'; +create table t1 (a int) engine=example; +select 1; +uninstall plugin example; +flush tables; +select count(*) from information_schema.plugins where plugin_name='example'; +--error ER_UNKNOWN_STORAGE_ENGINE +truncate table t1; +drop table t1; + diff --git a/sql/datadict.cc b/sql/datadict.cc index 15419c4f577..55ffd8eaee3 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -70,88 +70,6 @@ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt) } -/** - Given a table name, check type of .frm and legacy table type. - - @param[in] thd The current session. - @param[in] db Table schema. - @param[in] table_name Table database. - @param[out] table_type handlerton of the table if FRMTYPE_TABLE, - otherwise undefined. - - @return FALSE if FRMTYPE_TABLE and storage engine found. TRUE otherwise. -*/ - -bool dd_frm_storage_engine(THD *thd, const char *db, const char *table_name, - handlerton **table_type) -{ - char path[FN_REFLEN + 1]; - enum legacy_db_type db_type; - LEX_STRING db_name = {(char *) db, strlen(db)}; - - /* There should be at least some lock on the table. */ - DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, - table_name, MDL_SHARED)); - - if (check_db_name(&db_name)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str); - return TRUE; - } - - if (check_table_name(table_name, strlen(table_name), FALSE)) - { - my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name); - return TRUE; - } - - (void) build_table_filename(path, sizeof(path) - 1, db, - table_name, reg_ext, 0); - - dd_frm_type(thd, path, &db_type); - - /* Type is unknown if the object is not found or is not a table. */ - if (db_type == DB_TYPE_UNKNOWN || - !(*table_type= ha_resolve_by_legacy_type(thd, db_type))) - { - my_error(ER_NO_SUCH_TABLE, MYF(0), db, table_name); - return TRUE; - } - - return FALSE; -} - - -/** - Given a table name, check if the storage engine for the - table referred by this name supports an option 'flag'. - Return an error if the table does not exist or is not a - base table. - - @pre Any metadata lock on the table. - - @param[in] thd The current session. - @param[in] db Table schema. - @param[in] table_name Table database. - @param[in] flag The option to check. - @param[out] yes_no The result. Undefined if error. -*/ - -bool dd_check_storage_engine_flag(THD *thd, - const char *db, const char *table_name, - uint32 flag, bool *yes_no) -{ - handlerton *table_type; - - if (dd_frm_storage_engine(thd, db, table_name, &table_type)) - return TRUE; - - *yes_no= ha_check_storage_engine_flag(table_type, flag); - - return FALSE; -} - - /* Regenerate a metadata locked table. diff --git a/sql/datadict.h b/sql/datadict.h index 9c625e6434c..dd80942daca 100644 --- a/sql/datadict.h +++ b/sql/datadict.h @@ -28,14 +28,21 @@ enum frm_type_enum FRMTYPE_VIEW }; +/* + Take extra care when using dd_frm_type() - it only checks the .frm file, + and it won't work for any engine that supports discovery. + + Prefer to use ha_table_exists() instead. + To check whether it's an frm of a view, use dd_frm_is_view(). +*/ frm_type_enum dd_frm_type(THD *thd, char *path, enum legacy_db_type *dbt); -bool dd_frm_storage_engine(THD *thd, const char *db, const char *table_name, - handlerton **table_type); -bool dd_check_storage_engine_flag(THD *thd, - const char *db, const char *table_name, - uint32 flag, - bool *yes_no); +static inline bool dd_frm_is_view(THD *thd, char *path) +{ + enum legacy_db_type not_used; + return dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW; +} + bool dd_recreate_table(THD *thd, const char *db, const char *table_name, const char *path = NULL); diff --git a/sql/handler.cc b/sql/handler.cc index b8ad8678b87..57282102a1a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -386,7 +386,6 @@ static int ha_finish_errors(void) static volatile int32 need_full_discover_for_existence= 0; static volatile int32 engines_with_discover_table_names= 0; - static int full_discover_for_existence(handlerton *, const char *, const char *) { return 1; } @@ -4373,8 +4372,7 @@ public: *cond_hdl= NULL; if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE || - sql_errno == ER_WRONG_OBJECT || - sql_errno == ER_OPTION_PREVENTS_STATEMENT) // partition_disabled.test + sql_errno == ER_WRONG_OBJECT) { m_handled_errors++; return TRUE; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d93c412dd60..c4e510fd451 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -55,7 +55,7 @@ #include #include "rpl_filter.h" #include "sql_table.h" // build_table_filename -#include "datadict.h" // dd_frm_type() +#include "datadict.h" // dd_frm_is_view() #include "sql_hset.h" // Hash_set #ifdef __WIN__ #include @@ -2774,7 +2774,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, MDL_SHARED)) { char path[FN_REFLEN + 1]; - enum legacy_db_type not_used; build_table_filename(path, sizeof(path) - 1, table_list->db, table_list->table_name, reg_ext, 0); /* @@ -2784,7 +2783,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, during prelocking process (in this case in theory we still should hold shared metadata lock on it). */ - if (dd_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW) + if (dd_frm_is_view(thd, path)) { if (!tdc_open_view(thd, table_list, alias, key, key_length, mem_root, 0)) diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index cf9810db445..2c75de6e8a6 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -29,7 +29,6 @@ #include "sql_base.h" // tdc_remove_table, lock_table_names, #include "sql_handler.h" // mysql_ha_rm_tables #include "sql_statistics.h" -#include "datadict.h" static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error); @@ -241,11 +240,9 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, char *new_table_alias, bool skip_error) { int rc= 1; - char name[FN_REFLEN + 1]; + handlerton *hton; + bool new_exists, old_exists; const char *new_alias, *old_alias; - frm_type_enum frm_type; - enum legacy_db_type table_type; - DBUG_ENTER("do_rename"); if (lower_case_table_names == 2) @@ -260,53 +257,48 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, } DBUG_ASSERT(new_alias); - build_table_filename(name, sizeof(name) - 1, - new_db, new_alias, reg_ext, 0); - if (!access(name,F_OK)) + new_exists= ha_table_exists(thd, new_db, new_alias); + + if (new_exists) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); - DBUG_RETURN(1); // This can't be skipped + DBUG_RETURN(1); // This can't be skipped } - build_table_filename(name, sizeof(name) - 1, - ren_table->db, old_alias, reg_ext, 0); - frm_type= dd_frm_type(thd, name, &table_type); - switch (frm_type) + old_exists= ha_table_exists(thd, ren_table->db, old_alias, &hton); + + if (old_exists) { - case FRMTYPE_TABLE: + if (hton != view_pseudo_hton) + { + if (!(rc= mysql_rename_table(hton, ren_table->db, old_alias, + new_db, new_alias, 0))) { - if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd, - table_type), - ren_table->db, old_alias, - new_db, new_alias, 0))) + LEX_STRING db_name= { ren_table->db, ren_table->db_length }; + LEX_STRING table_name= { ren_table->table_name, + ren_table->table_name_length }; + LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) }; + (void) rename_table_in_stat_tables(thd, &db_name, &table_name, + &db_name, &new_table); + if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db, + old_alias, + ren_table->table_name, + new_db, + new_alias))) { - LEX_STRING db_name= { ren_table->db, ren_table->db_length }; - LEX_STRING table_name= { ren_table->table_name, - ren_table->table_name_length }; - LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) }; - (void) rename_table_in_stat_tables(thd, &db_name, &table_name, - &db_name, &new_table); - if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db, - old_alias, - ren_table->table_name, - new_db, - new_alias))) - { - /* - We've succeeded in renaming table's .frm and in updating - corresponding handler data, but have failed to update table's - triggers appropriately. So let us revert operations on .frm - and handler's data and report about failure to rename table. - */ - (void) mysql_rename_table(ha_resolve_by_legacy_type(thd, - table_type), - new_db, new_alias, - ren_table->db, old_alias, 0); - } + /* + We've succeeded in renaming table's .frm and in updating + corresponding handler data, but have failed to update table's + triggers appropriately. So let us revert operations on .frm + and handler's data and report about failure to rename table. + */ + (void) mysql_rename_table(hton, new_db, new_alias, + ren_table->db, old_alias, 0); } } - break; - case FRMTYPE_VIEW: + } + else + { /* change of schema is not allowed except of ALTER ...UPGRADE DATA DIRECTORY NAME command @@ -314,22 +306,19 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, */ if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE && strcmp(ren_table->db, new_db)) - my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, - new_db); + my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db); else rc= mysql_rename_view(thd, new_db, new_alias, ren_table); - break; - default: - DBUG_ASSERT(0); // should never happen - case FRMTYPE_ERROR: - my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); - break; + } + } + else + { + my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias); } if (rc && !skip_error) DBUG_RETURN(1); DBUG_RETURN(0); - } /* Rename all tables in list; Return pointer to wrong entry if something goes diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5c92d7db8f2..a0fa9807b29 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -57,7 +57,6 @@ #include #include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH #include "debug_sync.h" -#include "datadict.h" // dd_frm_type() #include "keycaches.h" #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -4072,26 +4071,18 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, } else if (tables->table_open_method != SKIP_OPEN_TABLE) { - enum legacy_db_type not_used; - char path[FN_REFLEN + 1]; - (void) build_table_filename(path, sizeof(path) - 1, db_name->str, - table_name->str, reg_ext, 0); - switch (dd_frm_type(thd, path, ¬_used)) { - case FRMTYPE_ERROR: - table->field[3]->store(STRING_WITH_LEN("ERROR"), - system_charset_info); - break; - case FRMTYPE_TABLE: - table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), - system_charset_info); - break; - case FRMTYPE_VIEW: - table->field[3]->store(STRING_WITH_LEN("VIEW"), - system_charset_info); - break; - default: - DBUG_ASSERT(0); + CHARSET_INFO *cs= system_charset_info; + handlerton *hton; + if (ha_table_exists(thd, db_name->str, table_name->str, &hton)) + { + if (hton == view_pseudo_hton) + table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); + else + table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); } + else + table->field[3]->store(STRING_WITH_LEN("ERROR"), cs); + if (thd->is_error() && thd->stmt_da->sql_errno() == ER_NO_SUCH_TABLE) { thd->clear_error(); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6fc5d9c0fc1..7d5f2d870ec 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4637,9 +4637,13 @@ mysql_rename_table(handlerton *base, const char *old_db, if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext)) { error=my_errno; - /* Restore old file name */ if (file) - file->ha_rename_table(to_base, from_base); + { + if (error == ENOENT) + error= 0; // this is ok if file->ha_rename_table() succeeded + else + file->ha_rename_table(to_base, from_base); // Restore old file name + } } } delete file; diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 0e97de5a6aa..92c4d150433 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -341,9 +341,27 @@ bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref, MYSQL_OPEN_SKIP_TEMPORARY)) DBUG_RETURN(TRUE); - if (dd_check_storage_engine_flag(thd, table_ref->db, table_ref->table_name, - HTON_CAN_RECREATE, hton_can_recreate)) + handlerton *hton; + if (!ha_table_exists(thd, table_ref->db, table_ref->table_name, &hton) || + hton == view_pseudo_hton) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_ref->db, table_ref->table_name); DBUG_RETURN(TRUE); + } + + if (!hton) + { + /* + The table exists, but its storage engine is unknown, perhaps not + loaded at the moment. We need to open and parse the frm to know the + storage engine in question, so let's proceed with the truncation and + try to open the table. This will produce the correct error message + about unknown engine. + */ + *hton_can_recreate= false; + } + else + *hton_can_recreate= hton->flags & HTON_CAN_RECREATE; } /* diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 7c033f74fb2..0a84dd996ce 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -33,7 +33,7 @@ #include "sp_head.h" #include "sp.h" #include "sp_cache.h" -#include "datadict.h" // dd_frm_type() +#include "datadict.h" // dd_frm_is_view() #define MD5_BUFF_LENGTH 33 @@ -1642,7 +1642,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) String non_existant_views; char *wrong_object_db= NULL, *wrong_object_name= NULL; bool error= FALSE; - enum legacy_db_type not_used; bool some_views_deleted= FALSE; bool something_wrong= FALSE; DBUG_ENTER("mysql_drop_view"); @@ -1665,12 +1664,11 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) for (view= views; view; view= view->next_local) { - frm_type_enum type= FRMTYPE_ERROR; + bool not_exist; build_table_filename(path, sizeof(path) - 1, view->db, view->table_name, reg_ext, 0); - if (access(path, F_OK) || - FRMTYPE_VIEW != (type= dd_frm_type(thd, path, ¬_used))) + if ((not_exist= my_access(path, F_OK)) || !dd_frm_is_view(thd, path)) { char name[FN_REFLEN]; my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name); @@ -1681,7 +1679,13 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) name); continue; } - if (type == FRMTYPE_TABLE) + if (not_exist) + { + if (non_existant_views.length()) + non_existant_views.append(','); + non_existant_views.append(String(view->table_name,system_charset_info)); + } + else { if (!wrong_object_name) { @@ -1689,12 +1693,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) wrong_object_name= view->table_name; } } - else - { - if (non_existant_views.length()) - non_existant_views.append(','); - non_existant_views.append(String(view->table_name,system_charset_info)); - } continue; } if (mysql_file_delete(key_file_frm, path, MYF(MY_WME))) diff --git a/sql/table.cc b/sql/table.cc index 647e8d3ee5a..0eaae05af77 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -572,24 +572,6 @@ inline bool is_system_table_name(const char *name, uint length) } -/* - We don't try to open 5.0 unencoded name, if - - non-encoded name contains '@' signs, - because '@' can be misinterpreted. - It is not clear if '@' is escape character in 5.1, - or a normal character in 5.0. - - - non-encoded db or table name contain "#mysql50#" prefix. - This kind of tables must have been opened only by the - mysql_file_open() above. -*/ -static bool has_disabled_path_chars(const char *str) -{ - return strpbrk(str, "/\\~@.") != 0 || - strncmp(str, STRING_WITH_LEN(MYSQL50_TABLE_NAME_PREFIX)) == 0; -} - - /* Read table definition from a binary / text based .frm file @@ -3176,7 +3158,7 @@ rename_file_ext(const char * from,const char * to,const char * ext) char from_b[FN_REFLEN],to_b[FN_REFLEN]; (void) strxmov(from_b,from,ext,NullS); (void) strxmov(to_b,to,ext,NullS); - return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(MY_WME))); + return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(0))); } From f597a6a694391f9c48c60fd79bdb2972b99b9fc6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:50:55 +0200 Subject: [PATCH 47/87] HA_ERR_TABLE_DEF_CHANGED support in ha_archive --- mysql-test/suite/archive/archive.result | 5 +- mysql-test/suite/archive/archive.test | 2 +- mysql-test/suite/archive/discover.result | 9 ++ mysql-test/suite/archive/discover.test | 8 ++ storage/archive/ha_archive.cc | 149 +++++++++++++---------- storage/archive/ha_archive.h | 3 +- 6 files changed, 106 insertions(+), 70 deletions(-) diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index f5c97cb4dde..e914aeb89be 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12815,9 +12815,8 @@ DROP TABLE t1; # create table t1 (a int, b char(50)) engine=archive; select * from t1; -ERROR HY000: Table 't1' is marked as crashed and should be repaired +a b +1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa show warnings; Level Code Message -Warning 127 Got error 127 when reading table `test`.`t1` -Error 1194 Table 't1' is marked as crashed and should be repaired drop table t1; diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 70e32254062..01873de1e93 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1736,7 +1736,7 @@ DROP TABLE t1; create table t1 (a int, b char(50)) engine=archive; --remove_file $MYSQLD_DATADIR/test/t1.ARZ copy_file std_data/t917689.ARZ $MYSQLD_DATADIR/test/t1.ARZ; ---error 1194 +# --error 1194 select * from t1; show warnings; drop table t1; diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index ae8b69d56b6..db8c3259f46 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -62,6 +62,15 @@ Tables_in_test t0 t1 # +# discover on HA_ERR_TABLE_DEF_CHANGED +# +alter table t1 modify a int default 5; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +# # discover on drop # flush tables; diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 4be90f50a50..6c1f563dfa8 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -48,6 +48,14 @@ flush tables; rename table t2 to t0; show tables; +--echo # +--echo # discover on HA_ERR_TABLE_DEF_CHANGED +--echo # +copy_file $mysqld_datadir/test/t1.ARZ $MYSQL_TMP_DIR/t1.ARZ; +alter table t1 modify a int default 5; +move_file $MYSQL_TMP_DIR/t1.ARZ $mysqld_datadir/test/t1.ARZ; +show create table t1; + --echo # --echo # discover on drop --echo # diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 0de26f37796..2d2ab5f285c 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -159,12 +159,11 @@ static PSI_mutex_info all_archive_mutexes[]= { &az_key_mutex_ARCHIVE_SHARE_mutex, "ARCHIVE_SHARE::mutex", 0} }; -PSI_file_key arch_key_file_metadata, arch_key_file_data, arch_key_file_frm; +PSI_file_key arch_key_file_metadata, arch_key_file_data; static PSI_file_info all_archive_files[]= { { &arch_key_file_metadata, "metadata", 0}, - { &arch_key_file_data, "data", 0}, - { &arch_key_file_frm, "FRM", 0} + { &arch_key_file_data, "data", 0} }; static void init_archive_psi_keys(void) @@ -438,6 +437,9 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc) */ if (archive_tmp.version < ARCHIVE_VERSION) *rc= HA_ERR_TABLE_NEEDS_UPGRADE; + else if (frm_compare(&archive_tmp, table_name)) + *rc= HA_ERR_TABLE_DEF_CHANGED; + azclose(&archive_tmp); (void) my_hash_insert(&archive_open_tables, (uchar*) share); @@ -566,14 +568,8 @@ int ha_archive::open(const char *name, int mode, uint open_options) { case 0: break; + case HA_ERR_TABLE_DEF_CHANGED: case HA_ERR_CRASHED_ON_USAGE: - DBUG_PRINT("ha_archive", ("archive table was crashed")); - if (open_options & HA_OPEN_FOR_REPAIR) - { - rc= 0; - break; - } - /* fall through */ case HA_ERR_TABLE_NEEDS_UPGRADE: if (open_options & HA_OPEN_FOR_REPAIR) { @@ -654,7 +650,8 @@ int ha_archive::frm_copy(azio_stream *src, azio_stream *dst) int rc= 0; uchar *frm_ptr; - if (!(frm_ptr= (uchar *) my_malloc(src->frm_length, MYF(0)))) + if (!(frm_ptr= (uchar *) my_malloc(src->frm_length, + MYF(MY_THREAD_SPECIFIC | MY_WME)))) return HA_ERR_OUT_OF_MEM; /* Write file offset is set to the end of the file. */ @@ -668,6 +665,46 @@ int ha_archive::frm_copy(azio_stream *src, azio_stream *dst) } +/** + Compare frm blob with the on-disk frm file + + @param s The azio stream. + @param path A path for readfrm() + + @return Zero if equal, non-zero otherwise. +*/ + +int ha_archive::frm_compare(azio_stream *s, const char *path) +{ + int rc= 0; + uchar *frm_ptr= 0, *azfrm_ptr= 0; + size_t frm_len; + + /* no frm = no discovery. perhaps it's a partitioned table */ + if (readfrm(path, &frm_ptr, &frm_len)) + goto err; + + if (!(azfrm_ptr= (uchar *) my_malloc(s->frm_length, + MYF(MY_THREAD_SPECIFIC | MY_WME)))) + goto err; + + rc= 1; + + if (frm_len != s->frm_length) + goto err; + + if (azread_frm(s, azfrm_ptr)) + goto err; + + rc= memcmp(frm_ptr, azfrm_ptr, frm_len); + +err: + my_free(frm_ptr); + my_free(azfrm_ptr); + return rc; +} + + /* We create our data file here. The format is pretty simple. You can read about the format of the data file above. @@ -684,9 +721,8 @@ int ha_archive::create(const char *name, TABLE *table_arg, char linkname[FN_REFLEN]; int error; azio_stream create_stream; /* Archive file we are working with */ - File frm_file; /* File handler for readers */ - MY_STAT file_stat; // Stat information for the data file uchar *frm_ptr; + size_t frm_len; DBUG_ENTER("ha_archive::create"); @@ -735,56 +771,41 @@ int ha_archive::create(const char *name, TABLE *table_arg, There is a chance that the file was "discovered". In this case just use whatever file is there. */ - if (!(mysql_file_stat(/* arch_key_file_data */ 0, name_buff, &file_stat, MYF(0)))) + my_errno= 0; + if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR|O_BINARY))) { - my_errno= 0; - if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR|O_BINARY))) - { - error= errno; - goto error2; - } - - if (linkname[0]) - my_symlink(name_buff, linkname, MYF(0)); - fn_format(name_buff, name, "", ".frm", - MY_REPLACE_EXT | MY_UNPACK_FILENAME); - - /* - Here is where we open up the frm and pass it to archive to store - */ - if ((frm_file= mysql_file_open(arch_key_file_frm, name_buff, O_RDONLY, MYF(0))) >= 0) - { - if (!mysql_file_fstat(frm_file, &file_stat, MYF(MY_WME))) - { - frm_ptr= (uchar *)my_malloc(sizeof(uchar) * (size_t)file_stat.st_size, MYF(0)); - if (frm_ptr) - { - mysql_file_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0)); - azwrite_frm(&create_stream, frm_ptr, (size_t)file_stat.st_size); - my_free(frm_ptr); - } - } - mysql_file_close(frm_file, MYF(0)); - } - - if (create_info->comment.str) - azwrite_comment(&create_stream, create_info->comment.str, - create_info->comment.length); - - /* - Yes you need to do this, because the starting value - for the autoincrement may not be zero. - */ - create_stream.auto_increment= stats.auto_increment_value ? - stats.auto_increment_value - 1 : 0; - if (azclose(&create_stream)) - { - error= errno; - goto error2; - } + error= errno; + goto error2; + } + + if (linkname[0]) + my_symlink(name_buff, linkname, MYF(0)); + + /* + Here is where we open up the frm and pass it to archive to store + */ + readfrm(name, &frm_ptr, &frm_len); + if (frm_ptr) + { + azwrite_frm(&create_stream, frm_ptr, frm_len); + my_free(frm_ptr); + } + + if (create_info->comment.str) + azwrite_comment(&create_stream, create_info->comment.str, + create_info->comment.length); + + /* + Yes you need to do this, because the starting value + for the autoincrement may not be zero. + */ + create_stream.auto_increment= stats.auto_increment_value ? + stats.auto_increment_value - 1 : 0; + if (azclose(&create_stream)) + { + error= errno; + goto error2; } - else - my_errno= 0; DBUG_PRINT("ha_archive", ("Creating File %s", name_buff)); DBUG_PRINT("ha_archive", ("Creating Link %s", linkname)); @@ -901,7 +922,6 @@ int ha_archive::write_row(uchar *buf) if (share->crashed) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); - ha_statistic_increment(&SSV::ha_write_count); mysql_mutex_lock(&share->mutex); if (!share->archive_write_open && init_archive_writer()) @@ -938,7 +958,8 @@ int ha_archive::write_row(uchar *buf) First we create a buffer that we can use for reading rows, and can pass to get_row(). */ - if (!(read_buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME)))) + if (!(read_buf= (uchar*) my_malloc(table->s->reclength, + MYF(MY_THREAD_SPECIFIC | MY_WME)))) { rc= HA_ERR_OUT_OF_MEM; goto error; @@ -1325,7 +1346,6 @@ int ha_archive::rnd_next(uchar *buf) } scan_rows--; - ha_statistic_increment(&SSV::ha_read_rnd_next_count); current_position= aztell(&archive); rc= get_row(&archive, buf); @@ -1361,7 +1381,6 @@ int ha_archive::rnd_pos(uchar * buf, uchar *pos) { int rc; DBUG_ENTER("ha_archive::rnd_pos"); - ha_statistic_increment(&SSV::ha_read_rnd_next_count); current_position= (my_off_t)my_get_ptr(pos, ref_length); if (azseek(&archive, current_position, SEEK_SET) == (my_off_t)(-1L)) { diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index 25e520f56dd..0723ee9bfc9 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -51,7 +51,7 @@ typedef struct st_archive_share { Version for file format. 1 - Initial Version (Never Released) 2 - Stream Compression, seperate blobs, no packing - 3 - One steam (row and blobs), with packing + 3 - One stream (row and blobs), with packing */ #define ARCHIVE_VERSION 3 @@ -76,6 +76,7 @@ class ha_archive: public handler archive_record_buffer *create_record_buffer(unsigned int length); void destroy_record_buffer(archive_record_buffer *r); int frm_copy(azio_stream *src, azio_stream *dst); + int frm_compare(azio_stream *src, const char *path); public: ha_archive(handlerton *hton, TABLE_SHARE *table_arg); From 84b882172d6ff772148da808531f67baa4e89283 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:51:04 +0200 Subject: [PATCH 48/87] if discovery in recover_from_failed_open fails, don't bother to reopen --- sql/sql_base.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c4e510fd451..7c249df8061 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3993,9 +3993,12 @@ recover_from_failed_open(THD *thd) tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db, m_failed_table->table_name, FALSE); - get_table_share(thd, m_failed_table->db, - m_failed_table->table_name, - GTS_TABLE | GTS_FORCE_DISCOVERY | GTS_NOLOCK); + if ((result= + !get_table_share(thd, m_failed_table->db, + m_failed_table->table_name, + GTS_TABLE | GTS_FORCE_DISCOVERY | GTS_NOLOCK))) + break; + thd->warning_info->clear_warning_info(thd->query_id); thd->clear_error(); // Clear error message From 9ec326a8b1fd0d83d9baaaf64f021be10564409d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:56:28 +0200 Subject: [PATCH 49/87] cleanup frm creation: * comments * cosmetic changes, *(ptr+5) -> ptr[5] * a couple of trivial functions -> inline * remove unused argument from pack_header() * create_frm() no longer creates frm file (the function used to prepare and fill a memory buffer and call my_create at the end. Now it only prepares a memory buffer). Renamed accordingly. * don't call pack_screen twice, go for a smaller screen area in the first attempt * remove useless calls to check_duplicate_warning() * don't write unireg screens to .frm files * remove make_new_entry(), it's basically dead code, always calculating and writing into frm the same string value. replace the function call with the constant string. --- mysql-test/suite/archive/archive.result | 4 +- .../suite/archive/partition_archive.result | 4 +- sql/field.h | 2 +- sql/table.cc | 300 ++++++------------ sql/table.h | 25 +- sql/unireg.cc | 240 +++----------- sql/unireg.h | 3 + 7 files changed, 163 insertions(+), 415 deletions(-) diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index e914aeb89be..4babfdae220 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12701,12 +12701,12 @@ CREATE TABLE t1(a INT, b BLOB) ENGINE=archive; SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DATA_LENGTH AVG_ROW_LENGTH -8666 15 +8608 15 INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2'); SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DATA_LENGTH AVG_ROW_LENGTH -8700 4350 +8642 4321 DROP TABLE t1; SET @save_join_buffer_size= @@join_buffer_size; SET @@join_buffer_size= 8192; diff --git a/mysql-test/suite/archive/partition_archive.result b/mysql-test/suite/archive/partition_archive.result index 186a7930251..9ea6f00015e 100644 --- a/mysql-test/suite/archive/partition_archive.result +++ b/mysql-test/suite/archive/partition_archive.result @@ -15,10 +15,10 @@ ENGINE = ARCHIVE; INSERT INTO t1 VALUES(CURRENT_DATE); SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; DATA_LENGTH INDEX_LENGTH -8658 0 +8604 0 SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; DATA_LENGTH INDEX_LENGTH -8658 0 +8604 0 DROP TABLE t1; drop database if exists db99; drop table if exists t1; diff --git a/sql/field.h b/sql/field.h index 92a01b9421c..6e880e78c6e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -2383,7 +2383,7 @@ public: /** structure with parsed options (for comparing fields in ALTER TABLE) */ ha_field_option_struct *option_struct; - uint8 row,col,sc_length,interval_id; // For rea_create_table + uint8 interval_id; // For rea_create_table uint offset,pack_flag; /* diff --git a/sql/table.cc b/sql/table.cc index 0eaae05af77..f37c6c70c6b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -594,7 +594,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) File file; MY_STAT stats; uchar *buf; - uchar head[64]; + uchar head[FRM_HEADER_SIZE]; char path[FN_REFLEN]; DBUG_ENTER("open_table_def"); DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, @@ -690,6 +690,10 @@ err_not_open: 28..29 (used to be key_info_length) They're still set, for compatibility reasons, but never read. + + 42..46 are unused since 5.0 (were for RAID support) + Also, there're few unused bytes in forminfo. + */ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, @@ -739,7 +743,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, if (path && writefrm(path, frm_image, frm_length)) goto err; - if (frm_length < 64 + 288) + if (frm_length < FRM_HEADER_SIZE + FRM_FORMINFO_SIZE) goto err; new_field_pack_flag= frm_image[27]; @@ -748,11 +752,12 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, /* Position of the form in the form file. */ len = uint2korr(frm_image+4); - if (frm_length < 64 + len || !(pos= uint4korr(frm_image + 64 + len))) + if (frm_length < FRM_HEADER_SIZE + len || + !(pos= uint4korr(frm_image + FRM_HEADER_SIZE + len))) goto err; forminfo= frm_image + pos; - if (forminfo + 288 >= frm_image_end) + if (forminfo + FRM_FORMINFO_SIZE >= frm_image_end) goto err; share->frm_version= frm_image[2]; @@ -766,13 +771,13 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, share->frm_version= FRM_VER_TRUE_VARCHAR; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (*(frm_image+61) && + if (frm_image[61] && !(share->default_part_db_type= - ha_checktype(thd, (enum legacy_db_type) (uint) *(frm_image+61), 1, 0))) + ha_checktype(thd, (enum legacy_db_type) (uint) frm_image[61], 1, 0))) goto err; DBUG_PRINT("info", ("default_part_db_type = %u", frm_image[61])); #endif - legacy_db_type= (enum legacy_db_type) (uint) *(frm_image+3); + legacy_db_type= (enum legacy_db_type) (uint) frm_image[3]; DBUG_ASSERT(share->db_plugin == NULL); /* if the storage engine is dynamic, no point in resolving it by its @@ -1004,7 +1009,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, share->reclength = uint2korr((frm_image+16)); share->stored_rec_length= share->reclength; - if (*(frm_image+26) == 1) + if (frm_image[26] == 1) share->system= 1; /* one-record-database */ record_offset= (ulong) (uint2korr(frm_image+6)+ @@ -1196,7 +1201,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, share->default_values= record; memcpy(record, frm_image + record_offset, share->reclength); - disk_buff= frm_image + pos + 288; + disk_buff= frm_image + pos + FRM_FORMINFO_SIZE; share->fields= uint2korr(forminfo+258); pos= uint2korr(forminfo+260); /* Length of all screens */ @@ -2705,79 +2710,7 @@ void free_field_buffers_larger_than(TABLE *table, uint32 size) } } - /* Add a new form to a form file */ - -ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames, - const char *newname) -{ - uint i,bufflength,maxlength,n_length,length,names; - ulong endpos,newpos; - uchar buff[IO_SIZE]; - uchar *pos; - DBUG_ENTER("make_new_entry"); - - length=(uint) strlen(newname)+1; - n_length=uint2korr(fileinfo+4); - maxlength=uint2korr(fileinfo+6); - names=uint2korr(fileinfo+8); - newpos=uint4korr(fileinfo+10); - - if (64+length+n_length+(names+1)*4 > maxlength) - { /* Expand file */ - newpos+=IO_SIZE; - int4store(fileinfo+10,newpos); - /* Copy from file-end */ - endpos= (ulong) mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0)); - bufflength= (uint) (endpos & (IO_SIZE-1)); /* IO_SIZE is a power of 2 */ - - while (endpos > maxlength) - { - mysql_file_seek(file, (ulong) (endpos-bufflength), MY_SEEK_SET, MYF(0)); - if (mysql_file_read(file, buff, bufflength, MYF(MY_NABP+MY_WME))) - DBUG_RETURN(0L); - mysql_file_seek(file, (ulong) (endpos-bufflength+IO_SIZE), MY_SEEK_SET, - MYF(0)); - if ((mysql_file_write(file, buff, bufflength, MYF(MY_NABP+MY_WME)))) - DBUG_RETURN(0); - endpos-=bufflength; bufflength=IO_SIZE; - } - bzero(buff,IO_SIZE); /* Null new block */ - mysql_file_seek(file, (ulong) maxlength, MY_SEEK_SET, MYF(0)); - if (mysql_file_write(file, buff, bufflength, MYF(MY_NABP+MY_WME))) - DBUG_RETURN(0L); - maxlength+=IO_SIZE; /* Fix old ref */ - int2store(fileinfo+6,maxlength); - for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ; - pos+=4) - { - endpos=uint4korr(pos)+IO_SIZE; - int4store(pos,endpos); - } - } - - if (n_length == 1 ) - { /* First name */ - length++; - (void) strxmov((char*) buff,"/",newname,"/",NullS); - } - else - (void) strxmov((char*) buff,newname,"/",NullS); /* purecov: inspected */ - mysql_file_seek(file, 63L+(ulong) n_length, MY_SEEK_SET, MYF(0)); - if (mysql_file_write(file, buff, (size_t) length+1, MYF(MY_NABP+MY_WME)) || - (names && mysql_file_write(file, - (uchar*) (*formnames->type_names+n_length-1), - names*4, MYF(MY_NABP+MY_WME))) || - mysql_file_write(file, fileinfo+10, 4, MYF(MY_NABP+MY_WME))) - DBUG_RETURN(0L); /* purecov: inspected */ - - int2store(fileinfo+8,names+1); - int2store(fileinfo+4,n_length+length); - (void) mysql_file_chsize(file, newpos, 0, MYF(MY_WME));/* Append file with '\0' */ - DBUG_RETURN(newpos); -} /* make_new_entry */ - - - /* error message when opening a form file */ +/* error message when opening a form file */ void open_table_error(TABLE_SHARE *share, enum open_frm_error error, int db_errno) @@ -2928,28 +2861,6 @@ static uint find_field(Field **fields, uchar *record, uint start, uint length) } - /* Check that the integer is in the internal */ - -int set_zone(register int nr, int min_zone, int max_zone) -{ - if (nr<=min_zone) - return (min_zone); - if (nr>=max_zone) - return (max_zone); - return (nr); -} /* set_zone */ - - /* Adjust number to next larger disk buffer */ - -ulong next_io_size(register ulong pos) -{ - reg2 ulong offset; - if ((offset= pos & (IO_SIZE-1))) - return pos-offset+IO_SIZE; - return pos; -} /* next_io_size */ - - /* Store an SQL quoted string. @@ -3012,22 +2923,13 @@ void append_unescaped(String *res, const char *pos, uint length) } - /* Create a .frm file */ - -File create_frm(THD *thd, const char *name, const char *db, - const char *table, uint reclength, uchar *fileinfo, - HA_CREATE_INFO *create_info, uint keys, KEY *key_info) +void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, + HA_CREATE_INFO *create_info, uint keys, KEY *key_info) { - register File file; ulong length; - uchar fill[IO_SIZE]; - int create_flags= O_RDWR | O_TRUNC; ulong key_comment_total_bytes= 0; uint i; - DBUG_ENTER("create_frm"); - - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) - create_flags|= O_EXCL | O_NOFOLLOW; + DBUG_ENTER("prepare_frm_header"); /* Fix this when we have new .frm files; Current limit is 4G rows (TODO) */ if (create_info->max_rows > UINT_MAX32) @@ -3035,101 +2937,81 @@ File create_frm(THD *thd, const char *name, const char *db, if (create_info->min_rows > UINT_MAX32) create_info->min_rows= UINT_MAX32; - if ((file= mysql_file_create(key_file_frm, - name, CREATE_MODE, create_flags, MYF(0))) >= 0) + uint key_length, tmp_key_length, tmp, csid; + bzero((char*) fileinfo, FRM_HEADER_SIZE); + /* header */ + fileinfo[0]=(uchar) 254; + fileinfo[1]= 1; + fileinfo[2]= FRM_VER+3+ test(create_info->varchar); + + fileinfo[3]= (uchar) ha_legacy_type( + ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0)); + int2store(fileinfo+4,3); + int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ + /* + Keep in sync with pack_keys() in unireg.cc + For each key: + 8 bytes for the key header + 9 bytes for each key-part (MAX_REF_PARTS) + NAME_LEN bytes for the name + 1 byte for the NAMES_SEP_CHAR (before the name) + For all keys: + 6 bytes for the header + 1 byte for the NAMES_SEP_CHAR (after the last name) + 9 extra bytes (padding for safety? alignment?) + */ + for (i= 0; i < keys; i++) { - uint key_length, tmp_key_length, tmp, csid; - bzero((char*) fileinfo,64); - /* header */ - fileinfo[0]=(uchar) 254; - fileinfo[1]= 1; - fileinfo[2]= FRM_VER+3+ test(create_info->varchar); - - fileinfo[3]= (uchar) ha_legacy_type( - ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0)); - fileinfo[4]=1; - int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ - /* - Keep in sync with pack_keys() in unireg.cc - For each key: - 8 bytes for the key header - 9 bytes for each key-part (MAX_REF_PARTS) - NAME_LEN bytes for the name - 1 byte for the NAMES_SEP_CHAR (before the name) - For all keys: - 6 bytes for the header - 1 byte for the NAMES_SEP_CHAR (after the last name) - 9 extra bytes (padding for safety? alignment?) - */ - for (i= 0; i < keys; i++) - { - DBUG_ASSERT(test(key_info[i].flags & HA_USES_COMMENT) == - (key_info[i].comment.length > 0)); - if (key_info[i].flags & HA_USES_COMMENT) - key_comment_total_bytes += 2 + key_info[i].comment.length; - } - - key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 - + key_comment_total_bytes; - - length= next_io_size((ulong) (IO_SIZE+key_length+reclength+ - create_info->extra_size)); - int4store(fileinfo+10,length); - tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff; - int2store(fileinfo+14,tmp_key_length); - int2store(fileinfo+16,reclength); - int4store(fileinfo+18,create_info->max_rows); - int4store(fileinfo+22,create_info->min_rows); - /* fileinfo[26] is set in mysql_create_frm() */ - fileinfo[27]=2; // Use long pack-fields - /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */ - create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers - int2store(fileinfo+30,create_info->table_options); - fileinfo[32]=0; // No filename anymore - fileinfo[33]=5; // Mark for 5.0 frm file - int4store(fileinfo+34,create_info->avg_row_length); - csid= (create_info->default_table_charset ? - create_info->default_table_charset->number : 0); - fileinfo[38]= (uchar) csid; - fileinfo[39]= (uchar) ((uint) create_info->transactional | - ((uint) create_info->page_checksum << 2)); - fileinfo[40]= (uchar) create_info->row_type; - /* Next few bytes where for RAID support */ - fileinfo[41]= (uchar) (csid >> 8); - fileinfo[42]= 0; - fileinfo[43]= 0; - fileinfo[44]= 0; - fileinfo[45]= 0; - fileinfo[46]= 0; - int4store(fileinfo+47, key_length); - tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store - int4store(fileinfo+51, tmp); - int4store(fileinfo+55, create_info->extra_size); - /* - 59-60 is reserved for extra_rec_buf_length, - 61 for default_part_db_type - */ - int2store(fileinfo+62, create_info->key_block_size); - bzero(fill,IO_SIZE); - for (; length > IO_SIZE ; length-= IO_SIZE) - { - if (mysql_file_write(file, fill, IO_SIZE, MYF(MY_WME | MY_NABP))) - { - (void) mysql_file_close(file, MYF(0)); - (void) mysql_file_delete(key_file_frm, name, MYF(0)); - return(-1); - } - } + DBUG_ASSERT(test(key_info[i].flags & HA_USES_COMMENT) == + (key_info[i].comment.length > 0)); + if (key_info[i].flags & HA_USES_COMMENT) + key_comment_total_bytes += 2 + key_info[i].comment.length; } - else - { - if (my_errno == ENOENT) - my_error(ER_BAD_DB_ERROR,MYF(0),db); - else - my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); - } - DBUG_RETURN(file); -} /* create_frm */ + + key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 + + key_comment_total_bytes; + + length= next_io_size((ulong) (IO_SIZE+key_length+reclength+ + create_info->extra_size)); + int2store(fileinfo+8,1); + int4store(fileinfo+10,length); + tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff; + int2store(fileinfo+14,tmp_key_length); + int2store(fileinfo+16,reclength); + int4store(fileinfo+18,create_info->max_rows); + int4store(fileinfo+22,create_info->min_rows); + /* fileinfo[26] is set in mysql_create_frm() */ + fileinfo[27]=2; // Use long pack-fields + /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */ + create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers + int2store(fileinfo+30,create_info->table_options); + fileinfo[32]=0; // No filename anymore + fileinfo[33]=5; // Mark for 5.0 frm file + int4store(fileinfo+34,create_info->avg_row_length); + csid= (create_info->default_table_charset ? + create_info->default_table_charset->number : 0); + fileinfo[38]= (uchar) csid; + fileinfo[39]= (uchar) ((uint) create_info->transactional | + ((uint) create_info->page_checksum << 2)); + fileinfo[40]= (uchar) create_info->row_type; + /* Next few bytes where for RAID support */ + fileinfo[41]= (uchar) (csid >> 8); + fileinfo[42]= 0; + fileinfo[43]= 0; + fileinfo[44]= 0; + fileinfo[45]= 0; + fileinfo[46]= 0; + int4store(fileinfo+47, key_length); + tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store + int4store(fileinfo+51, tmp); + int4store(fileinfo+55, create_info->extra_size); + /* + 59-60 is reserved for extra_rec_buf_length, + 61 for default_part_db_type + */ + int2store(fileinfo+62, create_info->key_block_size); + DBUG_VOID_RETURN; +} /* prepare_fileinfo */ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) diff --git a/sql/table.h b/sql/table.h index 0922286070d..04a86aa1884 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2490,17 +2490,28 @@ bool get_field(MEM_ROOT *mem, Field *field, class String *res); int closefrm(TABLE *table, bool free_share); void free_blobs(TABLE *table); void free_field_buffers_larger_than(TABLE *table, uint32 size); -int set_zone(int nr,int min_zone,int max_zone); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); -ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, - const char *newname); -ulong next_io_size(ulong pos); void append_unescaped(String *res, const char *pos, uint length); -File create_frm(THD *thd, const char *name, const char *db, - const char *table, uint reclength, uchar *fileinfo, - HA_CREATE_INFO *create_info, uint keys, KEY *key_info); +void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, + HA_CREATE_INFO *create_info, uint keys, KEY *key_info); char *fn_rext(char *name); +/* Check that the integer is in the internal */ +static inline int set_zone(int nr,int min_zone,int max_zone) +{ + if (nr <= min_zone) + return min_zone; + if (nr >= max_zone) + return max_zone; + return nr; +} + +/* Adjust number to next larger disk buffer */ +static inline ulong next_io_size(ulong pos) +{ + return MY_ALIGN(pos, IO_SIZE); +} + /* performance schema */ extern LEX_STRING PERFORMANCE_SCHEMA_DB_NAME; diff --git a/sql/unireg.cc b/sql/unireg.cc index eeaa8fc747f..5841b693aec 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -27,7 +27,6 @@ #include "sql_priv.h" #include "unireg.h" #include "sql_partition.h" // struct partition_info -#include "sql_table.h" // check_duplicate_warning #include "sql_class.h" // THD, Internal_error_handler #include "create_options.h" #include @@ -38,54 +37,11 @@ /* threshold for safe_alloca */ #define ALLOCA_THRESHOLD 2048 -static uchar * pack_screens(List &create_fields, - uint *info_length, uint *screens, bool small_file); -static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info, - ulong data_offset); -static bool pack_header(uchar *forminfo,enum legacy_db_type table_type, - List &create_fields, - uint info_length, uint screens, uint table_options, - ulong data_offset, handler *file); +static uint pack_keys(uchar *,uint, KEY *, ulong); +static bool pack_header(uchar *, List &, uint, ulong, handler *); static uint get_interval_id(uint *,List &, Create_field *); -static bool pack_fields(File file, List &create_fields, - ulong data_offset); -static bool make_empty_rec(THD *thd, int file, uint table_options, - List &create_fields, - uint reclength, ulong data_offset); - -/** - An interceptor to hijack ER_TOO_MANY_FIELDS error from - pack_screens and retry again without UNIREG screens. - - XXX: what is a UNIREG screen? -*/ - -struct Pack_header_error_handler: public Internal_error_handler -{ - virtual bool handle_condition(THD *thd, - uint sql_errno, - const char* sqlstate, - MYSQL_ERROR::enum_warning_level level, - const char* msg, - MYSQL_ERROR ** cond_hdl); - bool is_handled; - Pack_header_error_handler() :is_handled(FALSE) {} -}; - - -bool -Pack_header_error_handler:: -handle_condition(THD *, - uint sql_errno, - const char*, - MYSQL_ERROR::enum_warning_level, - const char*, - MYSQL_ERROR ** cond_hdl) -{ - *cond_hdl= NULL; - is_handled= (sql_errno == ER_TOO_MANY_FIELDS); - return is_handled; -} +static bool pack_fields(File, List &, ulong); +static bool make_empty_rec(THD *, int, uint, List &, uint, ulong); /* Create a frm (table definition) file @@ -115,25 +71,20 @@ bool mysql_create_frm(THD *thd, const char *file_name, handler *db_file) { LEX_STRING str_db_type; - uint reclength, info_length, screens, key_info_length, maxlength, tmp_len, i; + uint reclength, key_info_length, maxlength, tmp_len, i; ulong key_buff_length; File file; ulong filepos, data_offset; uint options_len; - uchar fileinfo[64],forminfo[288],*keybuff; - uchar *screen_buff; + uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE],*keybuff; char buff[128]; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info= thd->work_part_info; #endif - Pack_header_error_handler pack_header_error_handler; int error; DBUG_ENTER("mysql_create_frm"); DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension - - if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0))) - DBUG_RETURN(1); DBUG_ASSERT(db_file != NULL); /* If fixed row records, we need one bit to check for deleted rows */ @@ -141,32 +92,12 @@ bool mysql_create_frm(THD *thd, const char *file_name, create_info->null_bits++; data_offset= (create_info->null_bits + 7) / 8; - thd->push_internal_handler(&pack_header_error_handler); - - error= pack_header(forminfo, ha_legacy_type(create_info->db_type), - create_fields,info_length, - screens, create_info->table_options, + error= pack_header(forminfo, create_fields, create_info->table_options, data_offset, db_file); - thd->pop_internal_handler(); - if (error) - { - my_free(screen_buff); - if (! pack_header_error_handler.is_handled) - DBUG_RETURN(1); + DBUG_RETURN(1); - // Try again without UNIREG screens (to get more columns) - if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1))) - DBUG_RETURN(1); - if (pack_header(forminfo, ha_legacy_type(create_info->db_type), - create_fields,info_length, - screens, create_info->table_options, data_offset, db_file)) - { - my_free(screen_buff); - DBUG_RETURN(1); - } - } reclength=uint2korr(forminfo+266); /* Calculate extra data segment length */ @@ -244,16 +175,13 @@ bool mysql_create_frm(THD *thd, const char *file_name, { my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), real_table_name, static_cast(TABLE_COMMENT_MAXLEN)); - my_free(screen_buff); DBUG_RETURN(1); } char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_TABLE_COMMENT), real_table_name, static_cast(TABLE_COMMENT_MAXLEN)); - /* do not push duplicate warnings */ - if (!check_duplicate_warning(current_thd, warn_buff, strlen(warn_buff))) - push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_TABLE_COMMENT, warn_buff); + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TOO_LONG_TABLE_COMMENT, warn_buff); create_info->comment.length= tmp_len; } /* @@ -266,32 +194,43 @@ bool mysql_create_frm(THD *thd, const char *file_name, forminfo[46]=255; create_info->extra_size+= 2 + create_info->comment.length; } - else{ + else + { strmake((char*) forminfo+47, create_info->comment.str ? create_info->comment.str : "", create_info->comment.length); forminfo[46]=(uchar) create_info->comment.length; } - if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo, - create_info, keys, key_info)) < 0) - { - my_free(screen_buff); - DBUG_RETURN(1); - } + prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info); key_buff_length= uint4korr(fileinfo+47); keybuff=(uchar*) my_malloc(key_buff_length, MYF(MY_THREAD_SPECIFIC)); key_info_length= pack_keys(keybuff, keys, key_info, data_offset); - /* - Ensure that there are no forms in this newly created form file. - Even if the form file exists, create_frm must truncate it to - ensure one form per form file. - */ - DBUG_ASSERT(uint2korr(fileinfo+8) == 0); + int create_flags= O_RDWR | O_TRUNC; + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) + create_flags|= O_EXCL | O_NOFOLLOW; - if (!(filepos= make_new_entry(file, fileinfo, NULL, ""))) + file= mysql_file_create(key_file_frm, file_name, + CREATE_MODE, create_flags, MYF(0)); + if (file < 0) + { + if (my_errno == ENOENT) + my_error(ER_BAD_DB_ERROR,MYF(0),db); + else + my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); + my_free(keybuff); + DBUG_RETURN(1); + } + + //======================== + filepos= uint4korr(fileinfo+10); + mysql_file_seek(file, FRM_HEADER_SIZE, MY_SEEK_SET, MYF(0)); + if (mysql_file_write(file, (uchar*)"//", 3, MYF(MY_NABP+MY_WME)) || + mysql_file_write(file, fileinfo+10, 4, MYF(MY_NABP+MY_WME))) goto err; + //======================== + maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); int2store(forminfo+2,maxlength); int4store(fileinfo+10,(ulong) (filepos+maxlength)); @@ -308,7 +247,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, #endif int2store(fileinfo+59,db_file->extra_rec_buf_length()); - if (mysql_file_pwrite(file, fileinfo, 64, 0L, MYF_RW) || + if (mysql_file_pwrite(file, fileinfo, FRM_HEADER_SIZE, 0L, MYF_RW) || mysql_file_pwrite(file, keybuff, key_info_length, (ulong) uint2korr(fileinfo+6), MYF_RW)) goto err; @@ -388,12 +327,10 @@ bool mysql_create_frm(THD *thd, const char *file_name, } mysql_file_seek(file, filepos, MY_SEEK_SET, MYF(0)); - if (mysql_file_write(file, forminfo, 288, MYF_RW) || - mysql_file_write(file, screen_buff, info_length, MYF_RW) || + if (mysql_file_write(file, forminfo, FRM_FORMINFO_SIZE, MYF_RW) || pack_fields(file, create_fields, data_offset)) goto err; - my_free(screen_buff); my_free(keybuff); if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) && @@ -423,7 +360,6 @@ bool mysql_create_frm(THD *thd, const char *file_name, DBUG_RETURN(0); err: - my_free(screen_buff); my_free(keybuff); err2: (void) mysql_file_close(file, MYF(MY_WME)); @@ -486,82 +422,6 @@ err_handler: } /* rea_create_table */ - /* Pack screens to a screen for save in a form-file */ - -static uchar *pack_screens(List &create_fields, - uint *info_length, uint *screens, - bool small_file) -{ - reg1 uint i; - uint row,start_row,end_row,fields_on_screen; - uint length,cols; - uchar *info,*pos,*start_screen; - uint fields=create_fields.elements; - List_iterator it(create_fields); - DBUG_ENTER("pack_screens"); - - start_row=4; end_row=22; cols=80; fields_on_screen=end_row+1-start_row; - - *screens=(fields-1)/fields_on_screen+1; - length= (*screens) * (SC_INFO_LENGTH+ (cols>> 1)+4); - - Create_field *field; - while ((field=it++)) - length+=(uint) strlen(field->field_name)+1+TE_INFO_LENGTH+cols/2; - - if (!(info=(uchar*) my_malloc(length,MYF(MY_WME | MY_THREAD_SPECIFIC)))) - DBUG_RETURN(0); - - start_screen=0; - row=end_row; - pos=info; - it.rewind(); - for (i=0 ; i < fields ; i++) - { - Create_field *cfield=it++; - if (row++ == end_row) - { - if (i) - { - length=(uint) (pos-start_screen); - int2store(start_screen,length); - start_screen[2]=(uchar) (fields_on_screen+1); - start_screen[3]=(uchar) (fields_on_screen); - } - row=start_row; - start_screen=pos; - pos+=4; - pos[0]= (uchar) start_row-2; /* Header string */ - pos[1]= (uchar) (cols >> 2); - pos[2]= (uchar) (cols >> 1) +1; - strfill((char *) pos+3,(uint) (cols >> 1),' '); - pos+=(cols >> 1)+4; - } - length=(uint) strlen(cfield->field_name); - if (length > cols-3) - length=cols-3; - - if (!small_file) - { - pos[0]=(uchar) row; - pos[1]=0; - pos[2]=(uchar) (length+1); - pos=(uchar*) strmake((char*) pos+3,cfield->field_name,length)+1; - } - cfield->row=(uint8) row; - cfield->col=(uint8) (length+1); - cfield->sc_length=(uint8) min(cfield->length,cols-(length+2)); - } - length=(uint) (pos-start_screen); - int2store(start_screen,length); - start_screen[2]=(uchar) (row-start_row+2); - start_screen[3]=(uchar) (row-start_row+1); - - *info_length=(uint) (pos-info); - DBUG_RETURN(info); -} /* pack_screens */ - - /* Pack keyinfo and keynames to keybuff for save in form-file. */ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, @@ -647,10 +507,8 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, /* Make formheader */ -static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, - List &create_fields, - uint info_length, uint screens, uint table_options, - ulong data_offset, handler *file) +static bool pack_header(uchar *forminfo, List &create_fields, + uint table_options, ulong data_offset, handler *file) { uint length,int_count,int_length,no_empty, int_parts; uint time_stamp_pos,null_fields; @@ -693,10 +551,8 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_FIELD_COMMENT), field->field_name, static_cast(COLUMN_COMMENT_MAXLEN)); - /* do not push duplicate warnings */ - if (!check_duplicate_warning(current_thd, warn_buff, strlen(warn_buff))) - push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_FIELD_COMMENT, warn_buff); + push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TOO_LONG_FIELD_COMMENT, warn_buff); field->comment.length= tmp_len; } if (field->vcol_info) @@ -808,7 +664,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, } /* Hack to avoid bugs with small static rows in MySQL */ reclength=max(file->min_record_length(table_options),reclength); - if (info_length+(ulong) create_fields.elements*FCOMP+288+ + if ((ulong) create_fields.elements*FCOMP+FRM_FORMINFO_SIZE+ n_length+int_length+com_length+vcol_info_length > 65535L || int_count > 255) { @@ -816,13 +672,13 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, DBUG_RETURN(1); } - bzero((char*)forminfo,288); - length=(info_length+create_fields.elements*FCOMP+288+n_length+int_length+ + bzero((char*)forminfo,FRM_FORMINFO_SIZE); + length=(create_fields.elements*FCOMP+FRM_FORMINFO_SIZE+n_length+int_length+ com_length+vcol_info_length); int2store(forminfo,length); - forminfo[256] = (uint8) screens; + forminfo[256] = 0; int2store(forminfo+258,create_fields.elements); - int2store(forminfo+260,info_length); + int2store(forminfo+260,0); int2store(forminfo+262,totlength); int2store(forminfo+264,no_empty); int2store(forminfo+266,reclength); @@ -836,7 +692,6 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, int2store(forminfo+282,null_fields); int2store(forminfo+284,com_length); int2store(forminfo+286,vcol_info_length); - /* forminfo+288 is free to use for additional information */ DBUG_RETURN(0); } /* pack_header */ @@ -889,9 +744,6 @@ static bool pack_fields(File file, List &create_fields, { uint recpos; uint cur_vcol_expr_len= 0; - buff[0]= (uchar) field->row; - buff[1]= (uchar) field->col; - buff[2]= (uchar) field->sc_length; int2store(buff+3, field->length); /* The +1 is here becasue the col offset in .frm file have offset 1 */ recpos= field->offset+1 + (uint) data_offset; diff --git a/sql/unireg.h b/sql/unireg.h index 46ff166a2b3..6972f90c1db 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -179,6 +179,9 @@ int rea_create_table(THD *thd, const char *path, uint key_count,KEY *key_info, handler *file); +#define FRM_HEADER_SIZE 64 +#define FRM_FORMINFO_SIZE 288 + static inline bool is_binary_frm_header(uchar *head) { return head[0] == 254 From e671cba9ede179a8c631e572450198dbad17aaa0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:56:43 +0200 Subject: [PATCH 50/87] Instead of creating and writing frm into a file peacewise (allocating and freeing buffers on the way), allocate one frm buffer, prepare the frm image completely in memory, and then write it down. --- sql/unireg.cc | 301 ++++++++++++++++++++++++++------------------------ 1 file changed, 155 insertions(+), 146 deletions(-) diff --git a/sql/unireg.cc b/sql/unireg.cc index 5841b693aec..f72658edf7f 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -40,8 +40,9 @@ static uint pack_keys(uchar *,uint, KEY *, ulong); static bool pack_header(uchar *, List &, uint, ulong, handler *); static uint get_interval_id(uint *,List &, Create_field *); -static bool pack_fields(File, List &, ulong); -static bool make_empty_rec(THD *, int, uint, List &, uint, ulong); +static bool pack_fields(uchar *, List &, ulong); +static size_t packed_fields_length(List &); +static bool make_empty_rec(THD *, uchar *, uint, List &, uint, ulong); /* Create a frm (table definition) file @@ -76,12 +77,13 @@ bool mysql_create_frm(THD *thd, const char *file_name, File file; ulong filepos, data_offset; uint options_len; - uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE],*keybuff; - char buff[128]; + uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE]; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info= thd->work_part_info; #endif int error; + size_t frm_length; + uchar *frm_ptr, *pos; DBUG_ENTER("mysql_create_frm"); DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension @@ -204,32 +206,35 @@ bool mysql_create_frm(THD *thd, const char *file_name, prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info); key_buff_length= uint4korr(fileinfo+47); - keybuff=(uchar*) my_malloc(key_buff_length, MYF(MY_THREAD_SPECIFIC)); - key_info_length= pack_keys(keybuff, keys, key_info, data_offset); - - int create_flags= O_RDWR | O_TRUNC; - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) - create_flags|= O_EXCL | O_NOFOLLOW; - - file= mysql_file_create(key_file_frm, file_name, - CREATE_MODE, create_flags, MYF(0)); - if (file < 0) - { - if (my_errno == ENOENT) - my_error(ER_BAD_DB_ERROR,MYF(0),db); - else - my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); - my_free(keybuff); - DBUG_RETURN(1); - } - - //======================== filepos= uint4korr(fileinfo+10); - mysql_file_seek(file, FRM_HEADER_SIZE, MY_SEEK_SET, MYF(0)); - if (mysql_file_write(file, (uchar*)"//", 3, MYF(MY_NABP+MY_WME)) || - mysql_file_write(file, fileinfo+10, 4, MYF(MY_NABP+MY_WME))) - goto err; - //======================== + + { + size_t len1, len2, len3; + len1= FRM_HEADER_SIZE; // fileinfo + len1+= 7; // "form entry" + + len2= uint2korr(fileinfo+6); // 4096 + len2+= key_buff_length; + len2+= reclength; + len2+= create_info->extra_size; + + len3= filepos; + len3+= FRM_FORMINFO_SIZE; //forminfo + len3+= packed_fields_length(create_fields); + + frm_length= len3; + } + + frm_ptr= (uchar*) my_malloc(frm_length, MYF(MY_ZEROFILL | MY_THREAD_SPECIFIC)); + if (!frm_ptr) + DBUG_RETURN(1); + + pos = frm_ptr + uint2korr(fileinfo+6); + key_info_length= pack_keys(pos, keys, key_info, data_offset); + //frm_length-= key_buff_length-key_info_length; + + memcpy(frm_ptr + FRM_HEADER_SIZE, "//", 3); + int4store(frm_ptr + 67, filepos); maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); int2store(forminfo+2,maxlength); @@ -247,99 +252,99 @@ bool mysql_create_frm(THD *thd, const char *file_name, #endif int2store(fileinfo+59,db_file->extra_rec_buf_length()); - if (mysql_file_pwrite(file, fileinfo, FRM_HEADER_SIZE, 0L, MYF_RW) || - mysql_file_pwrite(file, keybuff, key_info_length, - (ulong) uint2korr(fileinfo+6), MYF_RW)) - goto err; - mysql_file_seek(file, - (ulong) uint2korr(fileinfo+6) + (ulong) key_buff_length, - MY_SEEK_SET, MYF(0)); - if (make_empty_rec(thd, file, create_info->table_options, - create_fields, reclength, data_offset)) + memcpy(frm_ptr, fileinfo, FRM_HEADER_SIZE); + + pos+= key_buff_length; + if (make_empty_rec(thd, pos, create_info->table_options, create_fields, + reclength, data_offset)) goto err; - int2store(buff, create_info->connect_string.length); - if (mysql_file_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) || - mysql_file_write(file, (const uchar*)create_info->connect_string.str, - create_info->connect_string.length, MYF(MY_NABP))) - goto err; - - int2store(buff, str_db_type.length); - if (mysql_file_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) || - mysql_file_write(file, (const uchar*)str_db_type.str, - str_db_type.length, MYF(MY_NABP))) - goto err; + pos+= reclength; + int2store(pos, create_info->connect_string.length); + pos+= 2; + memcpy(pos, create_info->connect_string.str, create_info->connect_string.length); + pos+= create_info->connect_string.length; + int2store(pos, str_db_type.length); + pos+= 2; + memcpy(pos, str_db_type.str, str_db_type.length); + pos+= str_db_type.length; #ifdef WITH_PARTITION_STORAGE_ENGINE if (part_info) { char auto_partitioned= part_info->is_auto_partitioned ? 1 : 0; - int4store(buff, part_info->part_info_len); - if (mysql_file_write(file, (const uchar*)buff, 4, MYF_RW) || - mysql_file_write(file, (const uchar*)part_info->part_info_string, - part_info->part_info_len + 1, MYF_RW) || - mysql_file_write(file, (const uchar*)&auto_partitioned, 1, MYF_RW)) - goto err; + int4store(pos, part_info->part_info_len); + pos+= 4; + memcpy(pos, part_info->part_info_string, part_info->part_info_len + 1); + pos+= part_info->part_info_len + 1; + *pos++= auto_partitioned; } else #endif { - bzero((uchar*) buff, 6); - if (mysql_file_write(file, (uchar*) buff, 6, MYF_RW)) - goto err; + pos+= 6; } for (i= 0; i < keys; i++) { if (key_info[i].parser_name) { - if (mysql_file_write(file, (const uchar*)key_info[i].parser_name->str, - key_info[i].parser_name->length + 1, MYF(MY_NABP))) - goto err; + memcpy(pos, key_info[i].parser_name->str, key_info[i].parser_name->length + 1); + pos+= key_info[i].parser_name->length + 1; } } if (forminfo[46] == (uchar)255) { - uchar comment_length_buff[2]; - int2store(comment_length_buff,create_info->comment.length); - if (mysql_file_write(file, comment_length_buff, 2, MYF(MY_NABP)) || - mysql_file_write(file, (uchar*) create_info->comment.str, - create_info->comment.length, MYF(MY_NABP))) - goto err; + int2store(pos, create_info->comment.length); + pos+=2; + memcpy(pos, create_info->comment.str, create_info->comment.length); + pos+= create_info->comment.length; } if (options_len) { - uchar *optbuff= (uchar *)my_safe_alloca(options_len + 4, ALLOCA_THRESHOLD); - my_bool error; - DBUG_PRINT("info", ("Create options length: %u", options_len)); - if (!optbuff) - goto err; - int4store(optbuff, options_len); - engine_table_options_frm_image(optbuff + 4, + int4store(pos, options_len); + pos+= 4; + engine_table_options_frm_image(pos, create_info->option_list, create_fields, keys, key_info); - error= my_write(file, optbuff, options_len + 4, MYF_RW); - my_safe_afree(optbuff, options_len + 4, ALLOCA_THRESHOLD); - if (error) - goto err; + pos+= options_len; } - mysql_file_seek(file, filepos, MY_SEEK_SET, MYF(0)); - if (mysql_file_write(file, forminfo, FRM_FORMINFO_SIZE, MYF_RW) || - pack_fields(file, create_fields, data_offset)) + memcpy(frm_ptr + filepos, forminfo, FRM_FORMINFO_SIZE); + if (pack_fields(frm_ptr + filepos + FRM_FORMINFO_SIZE, create_fields, data_offset)) goto err; - my_free(keybuff); + //========================================== + { + int create_flags= O_RDWR | O_TRUNC; + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) + create_flags|= O_EXCL | O_NOFOLLOW; + file= mysql_file_create(key_file_frm, file_name, + CREATE_MODE, create_flags, MYF(0)); + } + if (file < 0) + { + if (my_errno == ENOENT) + my_error(ER_BAD_DB_ERROR,MYF(0),db); + else + my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); + goto err; + } + + if (mysql_file_write(file, frm_ptr, frm_length, MYF_RW)) + goto err2; if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) && (mysql_file_sync(file, MYF(MY_WME)) || my_sync_dir_by_file(file_name, MYF(MY_WME)))) goto err2; if (mysql_file_close(file, MYF(MY_WME))) - goto err3; + goto err1; + + my_free(frm_ptr); { /* @@ -357,14 +362,15 @@ bool mysql_create_frm(THD *thd, const char *file_name, } } } + DBUG_RETURN(0); -err: - my_free(keybuff); err2: - (void) mysql_file_close(file, MYF(MY_WME)); -err3: + mysql_file_close(file, MYF(MY_WME)); +err1: mysql_file_delete(key_file_frm, file_name, MYF(0)); +err: + my_free(frm_ptr); DBUG_RETURN(1); } /* mysql_create_frm */ @@ -724,14 +730,47 @@ static uint get_interval_id(uint *int_count,List &create_fields, } +static size_t packed_fields_length(List &create_fields) +{ + Create_field *field; + size_t length= 0; + DBUG_ENTER("packed_fields_length"); + + List_iterator it(create_fields); + uint int_count=0; + while ((field=it++)) + { + if (field->interval_id > int_count) + { + int_count= field->interval_id; + length++; + for (int i=0; field->interval->type_names[i]; i++) + { + length+= field->interval->type_lengths[i]; + length++; + } + length++; + } + if (field->vcol_info) + { + length+= field->vcol_info->expr_str.length + + FRM_VCOL_HEADER_SIZE(field->interval); + } + length+= FCOMP; + length+= strlen(field->field_name)+1; + length+= field->comment.length; + } + length++; + length++; + DBUG_RETURN(length); +} + /* Save fields, fieldnames and intervals */ -static bool pack_fields(File file, List &create_fields, +static bool pack_fields(uchar *buff, List &create_fields, ulong data_offset) { - reg2 uint i; uint int_count, comment_length= 0, vcol_info_length=0; - uchar buff[MAX_FIELD_WIDTH]; Create_field *field; DBUG_ENTER("pack_fields"); @@ -777,40 +816,29 @@ static bool pack_fields(File file, List &create_fields, the additional data saved for the virtual field */ buff[12]= cur_vcol_expr_len= field->vcol_info->expr_str.length + - FRM_VCOL_HEADER_SIZE(field->interval!=NULL); - vcol_info_length+= cur_vcol_expr_len + - FRM_VCOL_HEADER_SIZE(field->interval!=NULL); + FRM_VCOL_HEADER_SIZE(field->interval); + vcol_info_length+= cur_vcol_expr_len; buff[13]= (uchar) MYSQL_TYPE_VIRTUAL; } int2store(buff+15, field->comment.length); comment_length+= field->comment.length; set_if_bigger(int_count,field->interval_id); - if (mysql_file_write(file, buff, FCOMP, MYF_RW)) - DBUG_RETURN(1); + buff+= FCOMP; } - /* Write fieldnames */ - buff[0]=(uchar) NAMES_SEP_CHAR; - if (mysql_file_write(file, buff, 1, MYF_RW)) - DBUG_RETURN(1); - i=0; + /* Write fieldnames */ + *buff++= NAMES_SEP_CHAR; it.rewind(); while ((field=it++)) { - char *pos= strmov((char*) buff,field->field_name); - *pos++=NAMES_SEP_CHAR; - if (i == create_fields.elements-1) - *pos++=0; - if (mysql_file_write(file, buff, (size_t) (pos-(char*) buff), MYF_RW)) - DBUG_RETURN(1); - i++; + buff= (uchar*)strmov((char*) buff, field->field_name); + *buff++=NAMES_SEP_CHAR; } + *buff++= 0; - /* Write intervals */ + /* Write intervals */ if (int_count) { - String tmp((char*) buff,sizeof(buff), &my_charset_bin); - tmp.length(0); it.rewind(); int_count=0; while ((field=it++)) @@ -852,34 +880,30 @@ static bool pack_fields(File file, List &create_fields, } int_count= field->interval_id; - tmp.append(sep); - for (const char **pos=field->interval->type_names ; *pos ; pos++) + *buff++= sep; + for (int i=0; field->interval->type_names[i]; i++) { - tmp.append(*pos); - tmp.append(sep); + memcpy(buff, field->interval->type_names[i], field->interval->type_lengths[i]); + buff+= field->interval->type_lengths[i]; + *buff++= sep; } - tmp.append('\0'); // End of intervall + *buff++= 0; + } } - if (mysql_file_write(file, (uchar*) tmp.ptr(), tmp.length(), MYF_RW)) - DBUG_RETURN(1); } if (comment_length) { it.rewind(); - int_count=0; while ((field=it++)) { - if (field->comment.length) - if (mysql_file_write(file, (uchar*) field->comment.str, - field->comment.length, MYF_RW)) - DBUG_RETURN(1); + memcpy(buff, field->comment.str, field->comment.length); + buff+= field->comment.length; } } if (vcol_info_length) { it.rewind(); - int_count=0; while ((field=it++)) { /* @@ -892,18 +916,13 @@ static bool pack_fields(File file, List &create_fields, */ if (field->vcol_info && field->vcol_info->expr_str.length) { - buff[0]= (uchar)(1 + test(field->interval_id)); - buff[1]= (uchar) field->sql_type; - buff[2]= (uchar) field->stored_in_db; + *buff++= (uchar)(1 + test(field->interval_id)); + *buff++= (uchar) field->sql_type; + *buff++= (uchar) field->stored_in_db; if (field->interval_id) - buff[3]= (uchar) field->interval_id; - if (my_write(file, buff, 3 + test(field->interval_id), MYF_RW)) - DBUG_RETURN(1); - if (my_write(file, - (uchar*) field->vcol_info->expr_str.str, - field->vcol_info->expr_str.length, - MYF_RW)) - DBUG_RETURN(1); + *buff++= (uchar) field->interval_id; + memcpy(buff, field->vcol_info->expr_str.str, field->vcol_info->expr_str.length); + buff+= field->vcol_info->expr_str.length; } } } @@ -913,14 +932,14 @@ static bool pack_fields(File file, List &create_fields, /* save an empty record on start of formfile */ -static bool make_empty_rec(THD *thd, File file, uint table_options, +static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, List &create_fields, uint reclength, ulong data_offset) { int error= 0; Field::utype type; uint null_count; - uchar *buff,*null_pos; + uchar *null_pos; TABLE table; TABLE_SHARE share; Create_field *field; @@ -932,13 +951,6 @@ static bool make_empty_rec(THD *thd, File file, uint table_options, bzero((char*) &share, sizeof(share)); table.s= &share; - if (!(buff=(uchar*) my_malloc((size_t) reclength, - MYF(MY_WME | MY_ZEROFILL | - MY_THREAD_SPECIFIC)))) - { - DBUG_RETURN(1); - } - table.in_use= thd; table.s->blob_ptr_size= portable_sizeof_char_ptr; @@ -1024,10 +1036,7 @@ static bool make_empty_rec(THD *thd, File file, uint table_options, if (null_count & 7) *(null_pos + null_count / 8)|= ~(((uchar) 1 << (null_count & 7)) - 1); - error= mysql_file_write(file, buff, (size_t) reclength, MYF_RW) != 0; - err: - my_free(buff); thd->count_cuted_fields= old_count_cuted_fields; DBUG_RETURN(error); } /* make_empty_rec */ From cb5473cb2f0cea5eeace0fec17e0840fcba8f37a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:56:52 +0200 Subject: [PATCH 51/87] write frm pieces contiguously, don't align them on a 4K boundary (in partition_archive.test frm size goes down 16 times :) --- mysql-test/suite/archive/archive.result | 4 ++-- .../suite/archive/partition_archive.result | 4 ++-- sql/table.cc | 5 ---- sql/unireg.cc | 24 +++++++------------ 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 4babfdae220..9208b987df0 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12701,12 +12701,12 @@ CREATE TABLE t1(a INT, b BLOB) ENGINE=archive; SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DATA_LENGTH AVG_ROW_LENGTH -8608 15 +535 15 INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2'); SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DATA_LENGTH AVG_ROW_LENGTH -8642 4321 +569 284 DROP TABLE t1; SET @save_join_buffer_size= @@join_buffer_size; SET @@join_buffer_size= 8192; diff --git a/mysql-test/suite/archive/partition_archive.result b/mysql-test/suite/archive/partition_archive.result index 9ea6f00015e..27ec5edb429 100644 --- a/mysql-test/suite/archive/partition_archive.result +++ b/mysql-test/suite/archive/partition_archive.result @@ -15,10 +15,10 @@ ENGINE = ARCHIVE; INSERT INTO t1 VALUES(CURRENT_DATE); SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; DATA_LENGTH INDEX_LENGTH -8604 0 +520 0 SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; DATA_LENGTH INDEX_LENGTH -8604 0 +520 0 DROP TABLE t1; drop database if exists db99; drop table if exists t1; diff --git a/sql/table.cc b/sql/table.cc index f37c6c70c6b..a23eaa52c0b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2926,7 +2926,6 @@ void append_unescaped(String *res, const char *pos, uint length) void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, HA_CREATE_INFO *create_info, uint keys, KEY *key_info) { - ulong length; ulong key_comment_total_bytes= 0; uint i; DBUG_ENTER("prepare_frm_header"); @@ -2947,7 +2946,6 @@ void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, fileinfo[3]= (uchar) ha_legacy_type( ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0)); int2store(fileinfo+4,3); - int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ /* Keep in sync with pack_keys() in unireg.cc For each key: @@ -2971,10 +2969,7 @@ void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, key_length= keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 + key_comment_total_bytes; - length= next_io_size((ulong) (IO_SIZE+key_length+reclength+ - create_info->extra_size)); int2store(fileinfo+8,1); - int4store(fileinfo+10,length); tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff; int2store(fileinfo+14,tmp_key_length); int2store(fileinfo+16,reclength); diff --git a/sql/unireg.cc b/sql/unireg.cc index f72658edf7f..bffe3ab7a41 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -206,24 +206,18 @@ bool mysql_create_frm(THD *thd, const char *file_name, prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info); key_buff_length= uint4korr(fileinfo+47); - filepos= uint4korr(fileinfo+10); - { - size_t len1, len2, len3; - len1= FRM_HEADER_SIZE; // fileinfo - len1+= 7; // "form entry" + frm_length= FRM_HEADER_SIZE; // fileinfo; + frm_length+= 7; // "form entry" - len2= uint2korr(fileinfo+6); // 4096 - len2+= key_buff_length; - len2+= reclength; - len2+= create_info->extra_size; + int2store(fileinfo+6, frm_length); + frm_length+= key_buff_length; + frm_length+= reclength; // row with default values + frm_length+= create_info->extra_size; - len3= filepos; - len3+= FRM_FORMINFO_SIZE; //forminfo - len3+= packed_fields_length(create_fields); - - frm_length= len3; - } + filepos= frm_length; + frm_length+= FRM_FORMINFO_SIZE; // forminfo + frm_length+= packed_fields_length(create_fields); frm_ptr= (uchar*) my_malloc(frm_length, MYF(MY_ZEROFILL | MY_THREAD_SPECIFIC)); if (!frm_ptr) From b3e70c4ae713abeddd47b3987f898ed763fa4eca Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:56:59 +0200 Subject: [PATCH 52/87] split mysql_create_frm() in create_frm_image() and writefrm() --- sql/discover.cc | 39 ++++++++++------- sql/discover.h | 3 +- sql/sql_table.cc | 2 +- sql/table.cc | 11 +++-- sql/table.h | 2 +- sql/unireg.cc | 107 ++++++++++++++++++++--------------------------- 6 files changed, 81 insertions(+), 83 deletions(-) diff --git a/sql/discover.cc b/sql/discover.cc index e2e84824f4d..a7681a3c2ba 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -100,7 +100,7 @@ int readfrm(const char *name, uchar **frmdata, size_t *len) Write the content of a frm data pointer to a frm file. - @param name path to table-file "db/name" + @param path path to table-file "db/name" @param frmdata frm data @param len length of the frmdata @@ -110,24 +110,35 @@ int readfrm(const char *name, uchar **frmdata, size_t *len) 2 Could not write file */ -int writefrm(const char *name, const uchar *frmdata, size_t len) +int writefrm(const char *path, const char *db, const char *table, + bool need_sync, const uchar *frmdata, size_t len) { - File file; - char index_file[FN_REFLEN]; + char file_name[FN_REFLEN+1]; int error; DBUG_ENTER("writefrm"); - DBUG_PRINT("enter",("name: '%s' len: %lu ",name, (ulong) len)); + DBUG_PRINT("enter",("name: '%s' len: %lu ",path, (ulong) len)); - error= 0; - if ((file= mysql_file_create(key_file_frm, - fn_format(index_file, name, "", reg_ext, - MY_UNPACK_FILENAME | MY_APPEND_EXT), - CREATE_MODE, O_RDWR | O_TRUNC, - MYF(MY_WME))) >= 0) + strxnmov(file_name, sizeof(file_name)-1, path, reg_ext, NullS); + + File file= mysql_file_create(key_file_frm, file_name, + CREATE_MODE, O_RDWR | O_TRUNC, MYF(0)); + + if ((error= file < 0)) { - if (mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP))) - error= 2; - (void) mysql_file_close(file, MYF(0)); + if (my_errno == ENOENT) + my_error(ER_BAD_DB_ERROR, MYF(0), db); + else + my_error(ER_CANT_CREATE_TABLE, MYF(0), table, my_errno); + } + else + { + error= mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP)); + + if (!error && need_sync) + error= mysql_file_sync(file, MYF(MY_WME)) || + my_sync_dir_by_file(file_name, MYF(MY_WME)); + + error|= mysql_file_close(file, MYF(MY_WME)); } DBUG_RETURN(error); } /* writefrm */ diff --git a/sql/discover.h b/sql/discover.h index a5d98d270e6..28d35b73152 100644 --- a/sql/discover.h +++ b/sql/discover.h @@ -19,7 +19,8 @@ #include "my_global.h" /* uchar */ int readfrm(const char *name, uchar **data, size_t *length); -int writefrm(const char* name, const uchar* data, size_t len); +int writefrm(const char *path, const char *db, const char *table, + bool need_sync, const uchar *frmdata, size_t len); int extension_based_table_discovery(MY_DIR *dirp, const char *ext, handlerton::discovered_list *tl); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7d5f2d870ec..739a1141992 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1703,7 +1703,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) #endif /* Write shadow frm file */ lpt->create_info->table_options= lpt->db_options; - if ((mysql_create_frm(lpt->thd, shadow_frm_name, lpt->db, + if ((mysql_create_frm(lpt->thd, shadow_path, lpt->db, lpt->table_name, lpt->create_info, lpt->alter_info->create_list, lpt->key_count, lpt->key_info_buffer, lpt->table->file)) || diff --git a/sql/table.cc b/sql/table.cc index a23eaa52c0b..b30ed15ba8e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -657,7 +657,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) } mysql_file_close(file, MYF(MY_WME)); - share->init_from_binary_frm_image(thd, NULL, buf, stats.st_size); + share->init_from_binary_frm_image(thd, false, buf, stats.st_size); error_given= true; // init_from_binary_frm_image has already called my_error() my_free(buf); @@ -696,8 +696,9 @@ err_not_open: */ -bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, - const uchar *frm_image, size_t frm_length) +bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, + const uchar *frm_image, + size_t frm_length) { TABLE_SHARE *share= this; uint new_frm_ver, field_pack_length, new_field_pack_flag; @@ -740,7 +741,9 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path, old_root= *root_ptr; *root_ptr= &share->mem_root; - if (path && writefrm(path, frm_image, frm_length)) + if (write && writefrm(share->normalized_path.str, + share->db.str, share->table_name.str, MY_SYNC, + frm_image, frm_length)) goto err; if (frm_length < FRM_HEADER_SIZE + FRM_FORMINFO_SIZE) diff --git a/sql/table.h b/sql/table.h index 04a86aa1884..e419f5d1240 100644 --- a/sql/table.h +++ b/sql/table.h @@ -988,7 +988,7 @@ struct TABLE_SHARE uint actual_n_key_parts(THD *thd); - bool init_from_binary_frm_image(THD *thd, const char *path, + bool init_from_binary_frm_image(THD *thd, bool write, const uchar *frm_image, size_t frm_length); }; diff --git a/sql/unireg.cc b/sql/unireg.cc index bffe3ab7a41..fdc4628bace 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -29,6 +29,7 @@ #include "sql_partition.h" // struct partition_info #include "sql_class.h" // THD, Internal_error_handler #include "create_options.h" +#include "discover.h" #include #include @@ -43,6 +44,8 @@ static uint get_interval_id(uint *,List &, Create_field *); static bool pack_fields(uchar *, List &, ulong); static size_t packed_fields_length(List &); static bool make_empty_rec(THD *, uchar *, uint, List &, uint, ulong); +static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *, + List &, uint, KEY *, handler *); /* Create a frm (table definition) file @@ -70,11 +73,29 @@ bool mysql_create_frm(THD *thd, const char *file_name, List &create_fields, uint keys, KEY *key_info, handler *db_file) +{ + DBUG_ENTER("mysql_create_frm"); + LEX_CUSTRING frm= create_frm_image(thd, table, create_info, + create_fields, keys, key_info, db_file); + if (!frm.str) + DBUG_RETURN(1); + + bool need_sync= opt_sync_frm && + !(create_info->options & HA_LEX_CREATE_TMP_TABLE); + int error= writefrm(file_name, db, table, need_sync, frm.str, frm.length); + + my_free(const_cast(frm.str)); + DBUG_RETURN(error); +} + +LEX_CUSTRING create_frm_image(THD *thd, const char *table, + HA_CREATE_INFO *create_info, + List &create_fields, + uint keys, KEY *key_info, handler *db_file) { LEX_STRING str_db_type; uint reclength, key_info_length, maxlength, tmp_len, i; ulong key_buff_length; - File file; ulong filepos, data_offset; uint options_len; uchar fileinfo[FRM_HEADER_SIZE],forminfo[FRM_FORMINFO_SIZE]; @@ -82,12 +103,9 @@ bool mysql_create_frm(THD *thd, const char *file_name, partition_info *part_info= thd->work_part_info; #endif int error; - size_t frm_length; uchar *frm_ptr, *pos; - DBUG_ENTER("mysql_create_frm"); - - DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension - DBUG_ASSERT(db_file != NULL); + LEX_CUSTRING frm= {0,0}; + DBUG_ENTER("create_frm_image"); /* If fixed row records, we need one bit to check for deleted rows */ if (!(create_info->table_options & HA_OPTION_PACK_RECORD)) @@ -98,7 +116,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, data_offset, db_file); if (error) - DBUG_RETURN(1); + DBUG_RETURN(frm); reclength=uint2korr(forminfo+266); @@ -177,7 +195,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, { my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), real_table_name, static_cast(TABLE_COMMENT_MAXLEN)); - DBUG_RETURN(1); + DBUG_RETURN(frm); } char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_TABLE_COMMENT), @@ -207,25 +225,25 @@ bool mysql_create_frm(THD *thd, const char *file_name, key_buff_length= uint4korr(fileinfo+47); - frm_length= FRM_HEADER_SIZE; // fileinfo; - frm_length+= 7; // "form entry" + frm.length= FRM_HEADER_SIZE; // fileinfo; + frm.length+= 7; // "form entry" - int2store(fileinfo+6, frm_length); - frm_length+= key_buff_length; - frm_length+= reclength; // row with default values - frm_length+= create_info->extra_size; + int2store(fileinfo+6, frm.length); + frm.length+= key_buff_length; + frm.length+= reclength; // row with default values + frm.length+= create_info->extra_size; - filepos= frm_length; - frm_length+= FRM_FORMINFO_SIZE; // forminfo - frm_length+= packed_fields_length(create_fields); + filepos= frm.length; + frm.length+= FRM_FORMINFO_SIZE; // forminfo + frm.length+= packed_fields_length(create_fields); - frm_ptr= (uchar*) my_malloc(frm_length, MYF(MY_ZEROFILL | MY_THREAD_SPECIFIC)); + frm_ptr= (uchar*) my_malloc(frm.length, MYF(MY_WME | MY_ZEROFILL | + MY_THREAD_SPECIFIC)); if (!frm_ptr) - DBUG_RETURN(1); + DBUG_RETURN(frm); pos = frm_ptr + uint2korr(fileinfo+6); key_info_length= pack_keys(pos, keys, key_info, data_offset); - //frm_length-= key_buff_length-key_info_length; memcpy(frm_ptr + FRM_HEADER_SIZE, "//", 3); int4store(frm_ptr + 67, filepos); @@ -310,36 +328,6 @@ bool mysql_create_frm(THD *thd, const char *file_name, if (pack_fields(frm_ptr + filepos + FRM_FORMINFO_SIZE, create_fields, data_offset)) goto err; - //========================================== - { - int create_flags= O_RDWR | O_TRUNC; - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) - create_flags|= O_EXCL | O_NOFOLLOW; - - file= mysql_file_create(key_file_frm, file_name, - CREATE_MODE, create_flags, MYF(0)); - } - if (file < 0) - { - if (my_errno == ENOENT) - my_error(ER_BAD_DB_ERROR,MYF(0),db); - else - my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno); - goto err; - } - - if (mysql_file_write(file, frm_ptr, frm_length, MYF_RW)) - goto err2; - if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) && - (mysql_file_sync(file, MYF(MY_WME)) || - my_sync_dir_by_file(file_name, MYF(MY_WME)))) - goto err2; - - if (mysql_file_close(file, MYF(MY_WME))) - goto err1; - - my_free(frm_ptr); - { /* Restore all UCS2 intervals. @@ -357,16 +345,13 @@ bool mysql_create_frm(THD *thd, const char *file_name, } } - DBUG_RETURN(0); + frm.str= frm_ptr; + DBUG_RETURN(frm); -err2: - mysql_file_close(file, MYF(MY_WME)); -err1: - mysql_file_delete(key_file_frm, file_name, MYF(0)); err: my_free(frm_ptr); - DBUG_RETURN(1); -} /* mysql_create_frm */ + DBUG_RETURN(frm); +} /* @@ -397,15 +382,11 @@ int rea_create_table(THD *thd, const char *path, { DBUG_ENTER("rea_create_table"); - char frm_name[FN_REFLEN]; - strxmov(frm_name, path, reg_ext, NullS); - if (mysql_create_frm(thd, frm_name, db, table_name, create_info, + if (mysql_create_frm(thd, path, db, table_name, create_info, create_fields, keys, key_info, file)) DBUG_RETURN(1); - // Make sure mysql_create_frm din't remove extension - DBUG_ASSERT(*fn_rext(frm_name)); if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; if (!create_info->frm_only && @@ -417,6 +398,8 @@ int rea_create_table(THD *thd, const char *path, err_handler: (void) file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, create_info); + char frm_name[FN_REFLEN]; + strxmov(frm_name, path, reg_ext, NullS); mysql_file_delete(key_file_frm, frm_name, MYF(0)); DBUG_RETURN(1); } /* rea_create_table */ From e06cb31719ce31fb1cd7944d1de86d4de9e3eca6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 15:57:09 +0200 Subject: [PATCH 53/87] CREATE TABLE and frm-less discovering engines. Now CREATE TABLE does not write the frm file on disk, if the engine can discover it --- include/my_sys.h | 2 +- mysql-test/suite/archive/archive.result | 28 +++++++++++ mysql-test/suite/archive/archive.test | 17 ++++++- mysql-test/suite/archive/discover.result | 5 ++ mysql-test/suite/archive/discover.test | 2 + mysys/my_compress.c | 2 +- sql/datadict.cc | 2 +- sql/discover.cc | 4 +- sql/discover.h | 8 +-- sql/handler.cc | 31 ++++++++++-- sql/handler.h | 4 +- sql/sql_base.cc | 2 +- sql/sql_table.cc | 23 ++++----- sql/table.cc | 35 ++++++++++--- sql/table.h | 3 ++ sql/unireg.cc | 63 ++++++++++++++---------- storage/archive/azio.c | 2 +- storage/archive/azlib.h | 2 +- storage/archive/ha_archive.cc | 22 ++++----- storage/archive/ha_archive.h | 2 +- 20 files changed, 185 insertions(+), 74 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 40061a33636..f2d31405687 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -877,7 +877,7 @@ extern void *my_az_allocator(void *dummy, unsigned int items, unsigned int size) extern void my_az_free(void *dummy, void *address); extern int my_compress_buffer(uchar *dest, size_t *destLen, const uchar *source, size_t sourceLen); -extern int packfrm(uchar *, size_t, uchar **, size_t *); +extern int packfrm(const uchar *, size_t, uchar **, size_t *); extern int unpackfrm(uchar **, size_t *, const uchar *); extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem, diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 9208b987df0..23636021d2a 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12816,7 +12816,35 @@ DROP TABLE t1; create table t1 (a int, b char(50)) engine=archive; select * from t1; a b +flush tables; +select * from t1; +a b 1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa show warnings; Level Code Message drop table t1; +create temporary table t1 (a int) engine=archive; +insert t1 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +show create table t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +alter table t1 add column b varchar(10); +select * from t1; +a b +1 NULL +2 NULL +3 NULL +show create table t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(10) DEFAULT NULL +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 01873de1e93..2acf8b9e6b5 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1734,9 +1734,24 @@ DROP TABLE t1; --echo # BUG#917689 Using wrong archive table causes crash --echo # create table t1 (a int, b char(50)) engine=archive; +select * from t1; # open the table to create the frm +flush tables; # and close the table again --remove_file $MYSQLD_DATADIR/test/t1.ARZ copy_file std_data/t917689.ARZ $MYSQLD_DATADIR/test/t1.ARZ; -# --error 1194 +#--error ER_CRASHED_ON_USAGE select * from t1; show warnings; drop table t1; + +# +# temporary archive +# +create temporary table t1 (a int) engine=archive; +insert t1 values (1),(2),(3); +select * from t1; +show create table t1; +alter table t1 add column b varchar(10); +select * from t1; +show create table t1; +drop table t1; + diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index db8c3259f46..dc6d124d345 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -21,6 +21,8 @@ a # show tables # create table t2 (a int) engine=archive; +select * from t2; +a flush tables; show tables; Tables_in_test @@ -107,4 +109,7 @@ drop table t1; # archive_discover # create table `a/../`(a int) engine=archive; +select * from `a/../`; +a +flush tables; drop table `a/../`; diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 6c1f563dfa8..8175511929f 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -18,6 +18,7 @@ select * from t1; --echo # show tables --echo # create table t2 (a int) engine=archive; +select * from t2; remove_file $mysqld_datadir/test/t1.frm; flush tables; show tables; @@ -84,6 +85,7 @@ drop table t1; --echo # archive_discover --echo # create table `a/../`(a int) engine=archive; +select * from `a/../`; flush tables; remove_file $mysqld_datadir/test/a@002f@002e@002e@002f.frm; drop table `a/../`; diff --git a/mysys/my_compress.c b/mysys/my_compress.c index ea56900db05..10c1903c163 100644 --- a/mysys/my_compress.c +++ b/mysys/my_compress.c @@ -234,7 +234,7 @@ my_bool my_uncompress(uchar *packet, size_t len, size_t *complen) >0 Failure */ -int packfrm(uchar *data, size_t len, +int packfrm(const uchar *data, size_t len, uchar **pack_data, size_t *pack_len) { int error; diff --git a/sql/datadict.cc b/sql/datadict.cc index 55ffd8eaee3..4bc74af7bdb 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -107,7 +107,7 @@ bool dd_recreate_table(THD *thd, const char *db, const char *table_name, } /* Attempt to reconstruct the table. */ - error= ha_create_table(thd, path, db, table_name, &create_info); + error= ha_create_table(thd, path, db, table_name, &create_info, NULL); DBUG_RETURN(error); } diff --git a/sql/discover.cc b/sql/discover.cc index a7681a3c2ba..a499e234a8f 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -45,7 +45,7 @@ 3 Could not allocate data for read. Could not read file */ -int readfrm(const char *name, uchar **frmdata, size_t *len) +int readfrm(const char *name, const uchar **frmdata, size_t *len) { int error; char index_file[FN_REFLEN]; @@ -134,7 +134,7 @@ int writefrm(const char *path, const char *db, const char *table, { error= mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP)); - if (!error && need_sync) + if (!error && need_sync && opt_sync_frm) error= mysql_file_sync(file, MYF(MY_WME)) || my_sync_dir_by_file(file_name, MYF(MY_WME)); diff --git a/sql/discover.h b/sql/discover.h index 28d35b73152..aad8bb734ec 100644 --- a/sql/discover.h +++ b/sql/discover.h @@ -18,14 +18,14 @@ #include "my_global.h" /* uchar */ -int readfrm(const char *name, uchar **data, size_t *length); -int writefrm(const char *path, const char *db, const char *table, - bool need_sync, const uchar *frmdata, size_t len); - int extension_based_table_discovery(MY_DIR *dirp, const char *ext, handlerton::discovered_list *tl); #ifdef MYSQL_SERVER +int readfrm(const char *name, const uchar **data, size_t *length); +int writefrm(const char *path, const char *db, const char *table, + bool need_sync, const uchar *frmdata, size_t len); + int ext_table_discovery_simple(MY_DIR *dirp, handlerton::discovered_list *result); #endif diff --git a/sql/handler.cc b/sql/handler.cc index 57282102a1a..00ed78f335d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -34,7 +34,7 @@ #include "sql_parse.h" // check_stack_overrun #include "sql_acl.h" // SUPER_ACL #include "sql_base.h" // free_io_cache -#include "discover.h" // writefrm +#include "discover.h" // extension_based_table_discovery, etc #include "log_event.h" // *_rows_log_event #include "create_options.h" #include "rpl_filter.h" @@ -4131,7 +4131,7 @@ end: */ int ha_create_table(THD *thd, const char *path, const char *db, const char *table_name, - HA_CREATE_INFO *create_info) + HA_CREATE_INFO *create_info, LEX_CUSTRING *frm) { int error= 1; TABLE table; @@ -4141,9 +4141,28 @@ int ha_create_table(THD *thd, const char *path, DBUG_ENTER("ha_create_table"); init_tmp_table_share(thd, &share, db, 0, table_name, path); - if (open_table_def(thd, &share) || - open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, 0, &table, - TRUE)) + + if (frm) + { + bool write_frm_now= !create_info->db_type->discover_table && + !create_info->tmp_table(); + + share.frm_image= frm; + + // open an frm image + if (share.init_from_binary_frm_image(thd, write_frm_now, + frm->str, frm->length)) + goto err; + } + else + { + // open an frm file + if (open_table_def(thd, &share)) + goto err; + } + + + if (open_table_from_share(thd, &share, "", 0, READ_ALL, 0, &table, true)) goto err; update_create_info_from_table(create_info, &table); @@ -4151,7 +4170,9 @@ int ha_create_table(THD *thd, const char *path, name= get_canonical_filename(table.file, share.path.str, name_buff); error= table.file->ha_create(name, &table, create_info); + (void) closefrm(&table, 0); + if (error) { strxmov(name_buff, db, ".", table_name, NullS); diff --git a/sql/handler.h b/sql/handler.h index 11221fa3b10..8e4d59e7f7f 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1397,6 +1397,8 @@ struct HA_CREATE_INFO ha_table_option_struct *option_struct; ///< structure with parsed table options ha_field_option_struct **fields_option_struct; ///< array of field option structures ha_index_option_struct **indexes_option_struct; ///< array of index option structures + + bool tmp_table() { return options & HA_LEX_CREATE_TMP_TABLE; } }; @@ -3093,7 +3095,7 @@ void ha_checkpoint_state(bool disable); void ha_commit_checkpoint_request(void *cookie, void (*pre_hook)(void *)); int ha_create_table(THD *thd, const char *path, const char *db, const char *table_name, - HA_CREATE_INFO *create_info); + HA_CREATE_INFO *create_info, LEX_CUSTRING *frm); int ha_delete_table(THD *thd, handlerton *db_type, const char *path, const char *db, const char *alias, bool generate_warning); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 7c249df8061..f88a3ef05f9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5963,7 +5963,7 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db, init_tmp_table_share(thd, share, saved_cache_key, key_length, strend(saved_cache_key)+1, tmp_path); - if (open_table_def(thd, share) || + if (open_table_def(thd, share, GTS_TABLE | GTS_FORCE_DISCOVERY) || open_table_from_share(thd, share, table_name, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX), diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 739a1141992..f6a5cc3448a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1724,12 +1724,12 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) handlers that have the main version of the frm file stored in the handler. */ - uchar *data; + const uchar *data; size_t length; if (readfrm(shadow_path, &data, &length) || packfrm(data, length, &lpt->pack_frm_data, &lpt->pack_frm_len)) { - my_free(data); + my_free(const_cast(data)); my_free(lpt->pack_frm_data); mem_alloc_error(length); error= 1; @@ -5981,7 +5981,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; char path[FN_REFLEN + 1]; - char reg_path[FN_REFLEN+1]; ha_rows copied,deleted; handlerton *old_db_type, *new_db_type, *save_old_db_type; enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY; @@ -6051,7 +6050,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* - Assign variables table_name, new_name, db, new_db, path, reg_path + Assign variables table_name, new_name, db, new_db, path, to simplify further comparisions: we want to see if it's a RENAME later just by comparing the pointers, avoiding the need for strcmp. */ @@ -6061,7 +6060,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, db=table_list->db; if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) new_db= db; - build_table_filename(reg_path, sizeof(reg_path) - 1, db, table_name, reg_ext, 0); build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); mysql_ha_rm_tables(thd, table_list); @@ -6644,13 +6642,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, need_copy_table, need_lock_for_indexes)); } - /* - better have a negative test here, instead of positive, like - alter_info->flags & ALTER_ADD_COLUMN|ALTER_ADD_INDEX|... - so that ALTER TABLE won't break when somebody will add new flag - */ if (need_copy_table == ALTER_TABLE_METADATA_ONLY) - create_info->frm_only= 1; + { + char frm_name[FN_REFLEN+1]; + strxmov(frm_name, path, reg_ext, NullS); + /* + frm_only can only be used if old frm exists. + discovering frm-less engines cannot enjoy this optimization. + */ + create_info->frm_only= !my_access(frm_name, F_OK); + } #ifdef WITH_PARTITION_STORAGE_ENGINE if (table_for_fast_alter_partition) diff --git a/sql/table.cc b/sql/table.cc index b30ed15ba8e..e47c07f3a7e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -661,9 +661,6 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) error_given= true; // init_from_binary_frm_image has already called my_error() my_free(buf); - if (!share->error) - thd->status_var.opened_shares++; - goto err_not_open; err: @@ -741,9 +738,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, old_root= *root_ptr; *root_ptr= &share->mem_root; - if (write && writefrm(share->normalized_path.str, - share->db.str, share->table_name.str, MY_SYNC, - frm_image, frm_length)) + if (write && write_frm_image(frm_image, frm_length)) goto err; if (frm_length < FRM_HEADER_SIZE + FRM_FORMINFO_SIZE) @@ -1915,6 +1910,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, #endif share->error= OPEN_FRM_OK; + thd->status_var.opened_shares++; *root_ptr= old_root; DBUG_RETURN(0); @@ -1943,6 +1939,33 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, DBUG_RETURN(1); } /* open_binary_frm */ + +bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len) +{ + return writefrm(normalized_path.str, db.str, table_name.str, 1, frm, len); +} + + +bool TABLE_SHARE::read_frm_image(const uchar **frm, size_t *len) +{ + if (partition_info_str) // cannot discover a partition + { + DBUG_ASSERT(db_type()->discover_table == 0); + return 1; + } + + if (frm_image) + { + *frm= frm_image->str; + *len= frm_image->length; + frm_image->str= 0; // pass the ownership to the caller + frm_image= 0; + return 0; + } + return readfrm(normalized_path.str, frm, len); +} + + /* @brief Clear GET_FIXED_FIELDS_FLAG in all fields of a table diff --git a/sql/table.h b/sql/table.h index e419f5d1240..562a49bfdae 100644 --- a/sql/table.h +++ b/sql/table.h @@ -988,8 +988,11 @@ struct TABLE_SHARE uint actual_n_key_parts(THD *thd); + LEX_CUSTRING *frm_image; ///< only during CREATE TABLE (@sa ha_create_table) bool init_from_binary_frm_image(THD *thd, bool write, const uchar *frm_image, size_t frm_length); + bool write_frm_image(const uchar *frm_image, size_t frm_length); + bool read_frm_image(const uchar **frm_image, size_t *frm_length); }; diff --git a/sql/unireg.cc b/sql/unireg.cc index fdc4628bace..a50ac99ed20 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -80,9 +80,8 @@ bool mysql_create_frm(THD *thd, const char *file_name, if (!frm.str) DBUG_RETURN(1); - bool need_sync= opt_sync_frm && - !(create_info->options & HA_LEX_CREATE_TMP_TABLE); - int error= writefrm(file_name, db, table, need_sync, frm.str, frm.length); + int error= writefrm(file_name, db, table, !create_info->tmp_table(), + frm.str, frm.length); my_free(const_cast(frm.str)); DBUG_RETURN(error); @@ -382,30 +381,49 @@ int rea_create_table(THD *thd, const char *path, { DBUG_ENTER("rea_create_table"); - if (mysql_create_frm(thd, path, db, table_name, create_info, - create_fields, keys, key_info, file)) - + LEX_CUSTRING frm= create_frm_image(thd, table_name, create_info, + create_fields, keys, key_info, file); + if (!frm.str) DBUG_RETURN(1); if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; - if (!create_info->frm_only && - (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, - create_info) || - ha_create_table(thd, path, db, table_name, create_info))) - goto err_handler; + + if (create_info->frm_only) + { + if (writefrm(path, db, table_name, 1, frm.str, frm.length)) + goto err_handler; + } + else + { + // TODO don't write frm for temp tables + if (create_info->tmp_table() && + writefrm(path, db, table_name, 0, frm.str, frm.length)) + goto err_handler; + + if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, + create_info) || + ha_create_table(thd, path, db, table_name, create_info, &frm)) + { + file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, + create_info); + goto err_handler; + } + } + + my_free(const_cast(frm.str)); DBUG_RETURN(0); err_handler: - (void) file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, create_info); char frm_name[FN_REFLEN]; strxmov(frm_name, path, reg_ext, NullS); mysql_file_delete(key_file_frm, frm_name, MYF(0)); + my_free(const_cast(frm.str)); DBUG_RETURN(1); } /* rea_create_table */ - /* Pack keyinfo and keynames to keybuff for save in form-file. */ +/* Pack keyinfo and keynames to keybuff for save in form-file. */ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, ulong data_offset) @@ -488,7 +506,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, } /* pack_keys */ - /* Make formheader */ +/* Make formheader */ static bool pack_header(uchar *forminfo, List &create_fields, uint table_options, ulong data_offset, handler *file) @@ -510,8 +528,7 @@ static bool pack_header(uchar *forminfo, List &create_fields, com_length=vcol_info_length=0; n_length=2L; - /* Check fields */ - + /* Check fields */ List_iterator it(create_fields); Create_field *field; while ((field=it++)) @@ -638,8 +655,7 @@ static bool pack_header(uchar *forminfo, List &create_fields, } int_length+=int_count*2; // 255 prefix + 0 suffix - /* Save values in forminfo */ - + /* Save values in forminfo */ if (reclength > (ulong) file->max_record_length()) { my_error(ER_TOO_BIG_ROWSIZE, MYF(0), static_cast(file->max_record_length())); @@ -679,8 +695,7 @@ static bool pack_header(uchar *forminfo, List &create_fields, } /* pack_header */ - /* get each unique interval each own id */ - +/* get each unique interval each own id */ static uint get_interval_id(uint *int_count,List &create_fields, Create_field *last_field) { @@ -742,7 +757,7 @@ static size_t packed_fields_length(List &create_fields) DBUG_RETURN(length); } - /* Save fields, fieldnames and intervals */ +/* Save fields, fieldnames and intervals */ static bool pack_fields(uchar *buff, List &create_fields, ulong data_offset) @@ -751,10 +766,8 @@ static bool pack_fields(uchar *buff, List &create_fields, Create_field *field; DBUG_ENTER("pack_fields"); - /* Write field info */ - + /* Write field info */ List_iterator it(create_fields); - int_count=0; while ((field=it++)) { @@ -907,7 +920,7 @@ static bool pack_fields(uchar *buff, List &create_fields, } - /* save an empty record on start of formfile */ +/* save an empty record on start of formfile */ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, List &create_fields, diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 43c418e516d..c6058af2e3d 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -855,7 +855,7 @@ int azclose (azio_stream *s) Though this was added to support MySQL's FRM file, anything can be stored in this location. */ -int azwrite_frm(azio_stream *s, uchar *blob, unsigned int length) +int azwrite_frm(azio_stream *s, const uchar *blob, unsigned int length) { if (s->mode == 'r') return 1; diff --git a/storage/archive/azlib.h b/storage/archive/azlib.h index 05fc299e581..09f61afcd28 100644 --- a/storage/archive/azlib.h +++ b/storage/archive/azlib.h @@ -331,7 +331,7 @@ extern int azclose(azio_stream *file); error number (see function gzerror below). */ -extern int azwrite_frm (azio_stream *s, uchar *blob, unsigned int length); +extern int azwrite_frm (azio_stream *s, const uchar *blob, unsigned int length); extern int azread_frm (azio_stream *s, uchar *blob); extern int azwrite_comment (azio_stream *s, char *blob, unsigned int length); extern int azread_comment (azio_stream *s, char *blob); diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 2d2ab5f285c..616af00bcc8 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -302,8 +302,7 @@ int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) azclose(&frm_stream); - if (!share->init_from_binary_frm_image(thd, share->normalized_path.str, - frm_ptr, frm_stream.frm_length)) + if (!share->init_from_binary_frm_image(thd, 1, frm_ptr, frm_stream.frm_length)) my_errno= 0; ret: @@ -437,7 +436,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc) */ if (archive_tmp.version < ARCHIVE_VERSION) *rc= HA_ERR_TABLE_NEEDS_UPGRADE; - else if (frm_compare(&archive_tmp, table_name)) + else if (frm_compare(&archive_tmp)) *rc= HA_ERR_TABLE_DEF_CHANGED; azclose(&archive_tmp); @@ -669,19 +668,19 @@ int ha_archive::frm_copy(azio_stream *src, azio_stream *dst) Compare frm blob with the on-disk frm file @param s The azio stream. - @param path A path for readfrm() @return Zero if equal, non-zero otherwise. */ -int ha_archive::frm_compare(azio_stream *s, const char *path) +int ha_archive::frm_compare(azio_stream *s) { int rc= 0; - uchar *frm_ptr= 0, *azfrm_ptr= 0; + const uchar *frm_ptr= 0; + uchar *azfrm_ptr= 0; size_t frm_len; /* no frm = no discovery. perhaps it's a partitioned table */ - if (readfrm(path, &frm_ptr, &frm_len)) + if (table->s->read_frm_image(&frm_ptr, &frm_len)) goto err; if (!(azfrm_ptr= (uchar *) my_malloc(s->frm_length, @@ -699,7 +698,7 @@ int ha_archive::frm_compare(azio_stream *s, const char *path) rc= memcmp(frm_ptr, azfrm_ptr, frm_len); err: - my_free(frm_ptr); + my_free(const_cast(frm_ptr)); my_free(azfrm_ptr); return rc; } @@ -721,7 +720,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, char linkname[FN_REFLEN]; int error; azio_stream create_stream; /* Archive file we are working with */ - uchar *frm_ptr; + const uchar *frm_ptr; size_t frm_len; DBUG_ENTER("ha_archive::create"); @@ -784,11 +783,10 @@ int ha_archive::create(const char *name, TABLE *table_arg, /* Here is where we open up the frm and pass it to archive to store */ - readfrm(name, &frm_ptr, &frm_len); - if (frm_ptr) + if (!table_arg->s->read_frm_image(&frm_ptr, &frm_len)) { azwrite_frm(&create_stream, frm_ptr, frm_len); - my_free(frm_ptr); + my_free(const_cast(frm_ptr)); } if (create_info->comment.str) diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index 0723ee9bfc9..7e8d5cee47b 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -76,7 +76,7 @@ class ha_archive: public handler archive_record_buffer *create_record_buffer(unsigned int length); void destroy_record_buffer(archive_record_buffer *r); int frm_copy(azio_stream *src, azio_stream *dst); - int frm_compare(azio_stream *src, const char *path); + int frm_compare(azio_stream *src); public: ha_archive(handlerton *hton, TABLE_SHARE *table_arg); From 474f45b3dc684b14c3b5ab86303c8aa890d2dce5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:06:54 +0200 Subject: [PATCH 54/87] discover of table non-existance on drop --- mysql-test/suite/archive/discover.result | 12 +++++++++++- mysql-test/suite/archive/discover.test | 12 +++++++++++- sql/handler.cc | 7 ++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index dc6d124d345..8cae289733b 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -76,9 +76,19 @@ t1 CREATE TABLE `t1` ( # discover on drop # flush tables; -drop table t0, t1; +drop table t1; show tables; Tables_in_test +t0 +# +# discover of table non-existance on drop +# +select * from t0; +a +flush tables; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +drop table t0; # # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE # diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 8175511929f..7a588d4654d 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -62,9 +62,19 @@ show create table t1; --echo # remove_file $mysqld_datadir/test/t1.frm; flush tables; -drop table t0, t1; +drop table t1; show tables; +--echo # +--echo # discover of table non-existance on drop +--echo # +select * from t0; +remove_file $mysqld_datadir/test/t0.ARZ; +flush tables; +--error ER_NO_SUCH_TABLE +select * from t1; +drop table t0; + --echo # --echo # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE --echo # diff --git a/sql/handler.cc b/sql/handler.cc index 00ed78f335d..d58040abaa8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3448,9 +3448,14 @@ int handler::delete_table(const char *name) { int saved_error= 0; int error= 0; - int enoent_or_zero= ENOENT; // Error if no file was deleted + int enoent_or_zero; char buff[FN_REFLEN]; + if (ht->discover_table) + enoent_or_zero= 0; // the table may not exist in the engine, it's ok + else + enoent_or_zero= ENOENT; // the first file of bas_ext() *must* exist + for (const char **ext=bas_ext(); *ext ; ext++) { fn_format(buff, name, "", *ext, MY_UNPACK_FILENAME|MY_APPEND_EXT); From 4853c7192ded76ede690746cde9eaabbc448479b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:07:17 +0200 Subject: [PATCH 55/87] discovery using sql CREATE TABLE statement --- mysql-test/r/alter_table.result | 6 +- mysql-test/r/merge.result | 24 +- mysql-test/r/show_check.result | 2 +- mysql-test/suite/archive/archive.result | 2 +- sql/handler.cc | 4 + sql/share/errmsg-utf8.txt | 3 + sql/sql_table.cc | 279 +++++++++++++----------- sql/sql_table.h | 7 + sql/table.cc | 161 ++++++++++++-- sql/table.h | 6 +- sql/unireg.cc | 47 +--- sql/unireg.h | 18 +- storage/archive/ha_archive.cc | 5 +- 13 files changed, 345 insertions(+), 219 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index b2cfd079ff5..6b2f064d209 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -978,7 +978,7 @@ SHOW CREATE TABLE `tt+2`; Table Create Table tt+2 CREATE TEMPORARY TABLE `tt+2` ( `c1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 DROP TABLE `tt+1`, `tt+2`; CREATE TABLE `#sql1` (c1 INT); CREATE TABLE `@0023sql2` (c1 INT); @@ -1015,12 +1015,12 @@ SHOW CREATE TABLE `#sql2`; Table Create Table #sql2 CREATE TEMPORARY TABLE `#sql2` ( `c1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 SHOW CREATE TABLE `@0023sql1`; Table Create Table @0023sql1 CREATE TEMPORARY TABLE `@0023sql1` ( `c1` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 DROP TABLE `#sql2`, `@0023sql1`; DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index de376dc187d..83a4caac919 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2883,7 +2883,7 @@ Table Create Table m2 CREATE TEMPORARY TABLE `m2` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) SELECT * FROM m2; c1 c2 111 121 @@ -2900,7 +2900,7 @@ Table Create Table m1 CREATE TEMPORARY TABLE `m1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) SELECT * FROM m1; c1 c2 111 121 @@ -2989,7 +2989,7 @@ Table Create Table m1 CREATE TEMPORARY TABLE `m1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT INTO m1 VALUES (511, 521); SELECT * FROM m1; c1 c2 @@ -3040,7 +3040,7 @@ Table Create Table m1 CREATE TEMPORARY TABLE `m1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) # CREATE TABLE m2 SELECT * FROM m1; SHOW CREATE TABLE m2; @@ -3092,7 +3092,7 @@ Table Create Table m2 CREATE TABLE `m2` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) SELECT * FROM m2; c1 c2 111 121 @@ -3118,7 +3118,7 @@ Table Create Table m2 CREATE TEMPORARY TABLE `m2` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) SELECT * FROM m2; c1 c2 111 121 @@ -3288,7 +3288,7 @@ Table Create Table m2 CREATE TEMPORARY TABLE `m2` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) SELECT * FROM m2; c1 c2 111 121 @@ -3305,7 +3305,7 @@ Table Create Table m1 CREATE TEMPORARY TABLE `m1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) SELECT * FROM m1; c1 c2 111 121 @@ -3396,7 +3396,7 @@ Table Create Table m1 CREATE TEMPORARY TABLE `m1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT INTO m1 VALUES (511, 521); SELECT * FROM m1; c1 c2 @@ -3447,7 +3447,7 @@ Table Create Table m1 CREATE TEMPORARY TABLE `m1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) CREATE TABLE m2 SELECT * FROM m1; ERROR HY000: Table 'm2' was not locked with LOCK TABLES # @@ -3492,14 +3492,14 @@ Table Create Table m2 CREATE TEMPORARY TABLE `m2` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) LOCK TABLE m1 WRITE, m2 WRITE; SHOW CREATE TABLE m2; Table Create Table m2 CREATE TEMPORARY TABLE `m2` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL -) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`t1`,`t2`) SELECT * FROM m2; c1 c2 111 121 diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 1818713d443..2b7439b09e0 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -198,7 +198,7 @@ show create table t2; Table Create Table t2 CREATE TEMPORARY TABLE `t2` ( `a` int(11) NOT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 drop table t2; create table t1 ( test_set set( 'val1', 'val2', 'val3' ) not null default '', diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 23636021d2a..287c2991c1d 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12846,5 +12846,5 @@ Table Create Table t1 CREATE TEMPORARY TABLE `t1` ( `a` int(11) DEFAULT NULL, `b` varchar(10) DEFAULT NULL -) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 +) ENGINE=ARCHIVE DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 drop table t1; diff --git a/sql/handler.cc b/sql/handler.cc index d58040abaa8..735c2b012e6 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4317,6 +4317,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, handlerton *hton= plugin_data(plugin, handlerton *); if (hton->state == SHOW_OPTION_YES && hton->discover_table) { + share->db_plugin= plugin; int error= hton->discover_table(hton, thd, share); if (error != HA_ERR_NO_SUCH_TABLE) { @@ -4324,6 +4325,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, { DBUG_ASSERT(share->error); // MUST be always set for get_cached_table_share to work my_error(ER_GET_ERRNO, MYF(0), error); + share->db_plugin= 0; } else share->error= OPEN_FRM_OK; @@ -4331,6 +4333,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, status_var_increment(thd->status_var.ha_discover_count); return TRUE; // abort the search } + share->db_plugin= 0; } DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); @@ -4342,6 +4345,7 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share) DBUG_ENTER("ha_discover_table"); DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet + DBUG_ASSERT(!share->db_plugin); if (!plugin_foreach(thd, discover_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, share)) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index e7f60987cc1..fd74af7d56d 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6600,3 +6600,6 @@ ER_SLAVE_STARTED eng "SLAVE '%.*s' started" ER_SLAVE_STOPPED eng "SLAVE '%.*s' stopped" +ER_SQL_DISCOVER_ERROR + eng "Engine %s failed to discover table %`-.192s.%`-.192s with '%s'" + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f6a5cc3448a..0a02e674c07 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1703,13 +1703,23 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) #endif /* Write shadow frm file */ lpt->create_info->table_options= lpt->db_options; - if ((mysql_create_frm(lpt->thd, shadow_path, lpt->db, - lpt->table_name, lpt->create_info, - lpt->alter_info->create_list, lpt->key_count, - lpt->key_info_buffer, lpt->table->file)) || - lpt->table->file->ha_create_partitioning_metadata(shadow_path, NULL, - CHF_CREATE_FLAG, - lpt->create_info)) + LEX_CUSTRING frm= build_frm_image(lpt->thd, lpt->table_name, + lpt->create_info, + lpt->alter_info->create_list, + lpt->key_count, lpt->key_info_buffer, + lpt->table->file); + if (!frm.str) + { + error= 1; + goto end; + } + + int error= writefrm(shadow_path, lpt->db, lpt->table_name, + !lpt->create_info->tmp_table(), frm.str, frm.length); + my_free(const_cast(frm.str)); + + if (error || lpt->table->file->ha_create_partitioning_metadata(shadow_path, + NULL, CHF_CREATE_FLAG, lpt->create_info)) { mysql_file_delete(key_file_frm, shadow_frm_name, MYF(0)); error= 1; @@ -3857,6 +3867,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } + if (create_info->tmp_table()) + create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE; + + /* Give warnings for not supported table options */ +#if defined(WITH_ARIA_STORAGE_ENGINE) + extern handlerton *maria_hton; + if (file->ht != maria_hton) +#endif + if (create_info->transactional) + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + ER(ER_ILLEGAL_HA_CREATE_OPTION), + file->engine_name()->str, + "TRANSACTIONAL=1"); + if (parse_option_list(thd, &create_info->option_struct, create_info->option_list, file->partition_ht()->table_options, FALSE, @@ -4047,70 +4072,27 @@ static bool check_if_created_table_can_be_opened(THD *thd, #endif -/* - Create a table - - SYNOPSIS - mysql_create_table_no_lock() - thd Thread object - db Database - table_name Table name - create_info Create information (like MAX_ROWS) - fields List of fields to create - keys List of keys to create - internal_tmp_table Set to 1 if this is an internal temporary table - (From ALTER TABLE) - select_field_count - is_trans identifies the type of engine where the table - was created: either trans or non-trans. - - DESCRIPTION - If one creates a temporary table, this is automatically opened - - Note that this function assumes that caller already have taken - exclusive metadata lock on table being created or used some other - way to ensure that concurrent operations won't intervene. - mysql_create_table() is a wrapper that can be used for this. - - no_log is needed for the case of CREATE ... SELECT, - as the logging will be done later in sql_insert.cc - select_field_count is also used for CREATE ... SELECT, - and must be zero for standard create of table. - - RETURN VALUES - FALSE OK - TRUE error -*/ - -bool mysql_create_table_no_lock(THD *thd, +handler *mysql_create_frm_image(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, Alter_info *alter_info, bool internal_tmp_table, - uint select_field_count, - bool *is_trans) + uint select_field_count, LEX_CUSTRING *frm) { - char path[FN_REFLEN + 1]; - uint path_length; - const char *alias; uint db_options, key_count; KEY *key_info_buffer; - handler *file; - bool error= TRUE; - DBUG_ENTER("mysql_create_table_no_lock"); - DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", - db, table_name, internal_tmp_table)); - + handler *file; + DBUG_ENTER("mysql_create_frm_image"); /* Check for duplicate fields and check type of table to create */ if (!alter_info->create_list.elements) { my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS), MYF(0)); - DBUG_RETURN(TRUE); + DBUG_RETURN(NULL); } if (check_engine(thd, db, table_name, create_info)) - DBUG_RETURN(TRUE); + DBUG_RETURN(NULL); set_table_default_charset(thd, create_info, (char*) db); @@ -4119,12 +4101,11 @@ bool mysql_create_table_no_lock(THD *thd, create_info->row_type != ROW_TYPE_FIXED && create_info->row_type != ROW_TYPE_DEFAULT) db_options|= HA_OPTION_PACK_RECORD; - alias= table_case_name(create_info, table_name); if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, create_info->db_type))) { mem_alloc_error(sizeof(handler)); - DBUG_RETURN(TRUE); + DBUG_RETURN(NULL); } #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info= thd->work_part_info; @@ -4141,7 +4122,7 @@ bool mysql_create_table_no_lock(THD *thd, if (!part_info) { mem_alloc_error(sizeof(partition_info)); - DBUG_RETURN(TRUE); + goto err; } file->set_auto_partitions(part_info); part_info->default_engine_type= create_info->db_type; @@ -4166,7 +4147,7 @@ bool mysql_create_table_no_lock(THD *thd, char *part_syntax_buf; uint syntax_len; handlerton *engine_type; - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) + if (create_info->tmp_table()) { my_error(ER_PARTITION_NO_TEMPORARY, MYF(0)); goto err; @@ -4238,9 +4219,8 @@ bool mysql_create_table_no_lock(THD *thd, delete file; create_info->db_type= partition_hton; if (!(file= get_ha_partition(part_info))) - { - DBUG_RETURN(TRUE); - } + DBUG_RETURN(NULL); + /* If we have default number of partitions or subpartitions we might require to set-up the part_info object such that it @@ -4282,65 +4262,90 @@ bool mysql_create_table_no_lock(THD *thd, engine_type))) { mem_alloc_error(sizeof(handler)); - DBUG_RETURN(TRUE); + DBUG_RETURN(NULL); } } } #endif if (mysql_prepare_create_table(thd, create_info, alter_info, - internal_tmp_table, - &db_options, file, + internal_tmp_table, &db_options, file, &key_info_buffer, &key_count, select_field_count)) goto err; + create_info->table_options=db_options; - /* Check if table exists */ - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) - { - path_length= build_tmptable_filename(thd, path, sizeof(path)); - create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE; - } - else - { - path_length= build_table_filename(path, sizeof(path) - 1, db, alias, reg_ext, - internal_tmp_table ? FN_IS_TMP : 0); - } + *frm= build_frm_image(thd, table_name, create_info, + alter_info->create_list, key_count, + key_info_buffer, file); - /* Check if table already exists */ - if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && - find_temporary_table(thd, db, table_name)) - { - if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) - goto warn; - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); + if (frm->str) + DBUG_RETURN(file); + +err: + delete file; + DBUG_RETURN(NULL); +} + + +/* + Create a table + + SYNOPSIS + mysql_create_table_no_lock() + thd Thread object + db Database + table_name Table name + create_info Create information (like MAX_ROWS) + fields List of fields to create + keys List of keys to create + internal_tmp_table Set to 1 if this is an internal temporary table + (From ALTER TABLE) + select_field_count + is_trans identifies the type of engine where the table + was created: either trans or non-trans. + + DESCRIPTION + If one creates a temporary table, this is automatically opened + + Note that this function assumes that caller already have taken + exclusive metadata lock on table being created or used some other + way to ensure that concurrent operations won't intervene. + mysql_create_table() is a wrapper that can be used for this. + + select_field_count is also used for CREATE ... SELECT, + and must be zero for standard create of table. + + RETURN VALUES + FALSE OK + TRUE error +*/ + +bool mysql_create_table_no_lock(THD *thd, + const char *db, const char *table_name, + HA_CREATE_INFO *create_info, + Alter_info *alter_info, + bool internal_tmp_table, + uint select_field_count, + bool *is_trans) +{ + char path[FN_REFLEN + 1]; + uint path_length; + const char *alias; + handler *file; + LEX_CUSTRING frm= {0,0}; + bool error= TRUE; + DBUG_ENTER("mysql_create_table_no_lock"); + DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", + db, table_name, internal_tmp_table)); + + alias= table_case_name(create_info, table_name); + + file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info, + internal_tmp_table, select_field_count, &frm); + + if (!file) goto err; - } - - /* Give warnings for not supported table options */ -#if defined(WITH_ARIA_STORAGE_ENGINE) - extern handlerton *maria_hton; - if (file->ht != maria_hton) -#endif - if (create_info->transactional) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - ER(ER_ILLEGAL_HA_CREATE_OPTION), - file->engine_name()->str, - "TRANSACTIONAL=1"); - - if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) - { - if (ha_table_exists(thd, db, table_name)) - { - if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) - goto warn; - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); - goto err; - } - } - - thd_proc_info(thd, "creating table"); #ifdef HAVE_READLINK { @@ -4402,15 +4407,41 @@ bool mysql_create_table_no_lock(THD *thd, "INDEX DIRECTORY"); create_info->data_file_name= create_info->index_file_name= 0; } - create_info->table_options=db_options; - path[path_length - reg_ext_length]= '\0'; // Remove .frm extension - if (rea_create_table(thd, path, db, table_name, - create_info, alter_info->create_list, - key_count, key_info_buffer, file)) + /* Check if table exists */ + if (create_info->tmp_table()) + { + path_length= build_tmptable_filename(thd, path, sizeof(path)); + path[path_length - reg_ext_length]= '\0'; // Remove .frm extension + + if (find_temporary_table(thd, db, table_name)) + { + if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + goto warn; + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); + goto err; + } + } + else + { + path_length= build_table_filename(path, sizeof(path) - 1, db, alias, "", + internal_tmp_table ? FN_IS_TMP : 0); + + if (!internal_tmp_table && ha_table_exists(thd, db, table_name)) + { + if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + goto warn; + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); + goto err; + } + } + + thd_proc_info(thd, "creating table"); + + if (rea_create_table(thd, &frm, path, db, table_name, create_info, file)) goto err; - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) + if (create_info->tmp_table()) { /* Open a table (skipping table cache) and add it into @@ -4431,7 +4462,7 @@ bool mysql_create_table_no_lock(THD *thd, thd->thread_specific_used= TRUE; } #ifdef WITH_PARTITION_STORAGE_ENGINE - else if (part_info && create_info->frm_only) + else if (thd->work_part_info && create_info->frm_only) { /* For partitioned tables we can't find some problems with table @@ -4457,6 +4488,7 @@ bool mysql_create_table_no_lock(THD *thd, error= FALSE; err: thd_proc_info(thd, "After create"); + my_free(const_cast(frm.str)); delete file; DBUG_RETURN(error); @@ -4468,7 +4500,6 @@ warn: goto err; } - /** Implementation of SQLCOM_CREATE_TABLE. @@ -4514,7 +4545,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, if (!result && (!thd->is_current_stmt_binlog_format_row() || (thd->is_current_stmt_binlog_format_row() && - !(create_info->options & HA_LEX_CREATE_TMP_TABLE)))) + !(create_info->tmp_table())))) result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans); end: @@ -4727,7 +4758,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, local_create_info.options|= create_info->options&HA_LEX_CREATE_IF_NOT_EXISTS; /* Replace type of source table with one specified in the statement. */ local_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE; - local_create_info.options|= create_info->options & HA_LEX_CREATE_TMP_TABLE; + local_create_info.options|= create_info->tmp_table(); /* Reset auto-increment counter for the new table. */ local_create_info.auto_increment_value= 0; /* @@ -4745,7 +4776,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, Ensure that we have an exclusive lock on target table if we are creating non-temporary table. */ - DBUG_ASSERT((create_info->options & HA_LEX_CREATE_TMP_TABLE) || + DBUG_ASSERT((create_info->tmp_table()) || thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db, table->table_name, MDL_EXCLUSIVE)); @@ -4772,7 +4803,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, 4 temporary temporary Nothing ==== ========= ========= ============================== */ - if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) + if (!(create_info->tmp_table())) { if (src_table->table->s->tmp_table) // Case 2 { @@ -7227,7 +7258,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, DBUG_ASSERT(!(mysql_bin_log.is_open() && thd->is_current_stmt_binlog_format_row() && - (create_info->options & HA_LEX_CREATE_TMP_TABLE))); + (create_info->tmp_table()))); if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) DBUG_RETURN(TRUE); @@ -7852,7 +7883,7 @@ static bool check_engine(THD *thd, const char *db_name, ha_resolve_storage_engine_name(*new_engine), table_name); } - if (create_info->options & HA_LEX_CREATE_TMP_TABLE && + if (create_info->tmp_table() && ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED)) { if (create_info->used_fields & HA_CREATE_USED_ENGINE) diff --git a/sql/sql_table.h b/sql/sql_table.h index 4dc28aa4933..016260b6b26 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -25,6 +25,7 @@ struct TABLE_LIST; class THD; struct TABLE; struct handlerton; +class handler; typedef struct st_ha_check_opt HA_CHECK_OPT; struct HA_CREATE_INFO; typedef struct st_key KEY; @@ -140,6 +141,12 @@ bool mysql_create_table_no_lock(THD *thd, const char *db, Alter_info *alter_info, bool tmp_table, uint select_field_count, bool *is_trans); +handler *mysql_create_frm_image(THD *thd, + const char *db, const char *table_name, + HA_CREATE_INFO *create_info, + Alter_info *alter_info, + bool internal_tmp_table, + uint select_field_count, LEX_CUSTRING *frm); bool mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); diff --git a/sql/table.cc b/sql/table.cc index e47c07f3a7e..d6b109a880a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -693,9 +693,9 @@ err_not_open: */ -bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, - const uchar *frm_image, - size_t frm_length) +int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, + const uchar *frm_image, + size_t frm_length) { TABLE_SHARE *share= this; uint new_frm_ver, field_pack_length, new_field_pack_flag; @@ -729,10 +729,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, KEY_PART_INFO *first_key_part= NULL; uint ext_key_parts= 0; uint first_key_parts= 0; + plugin_ref se_plugin= 0; keyinfo= &first_keyinfo; share->ext_key_parts= 0; MEM_ROOT **root_ptr, *old_root; - DBUG_ENTER("open_binary_frm"); + DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image"); root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); old_root= *root_ptr; @@ -776,15 +777,13 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, DBUG_PRINT("info", ("default_part_db_type = %u", frm_image[61])); #endif legacy_db_type= (enum legacy_db_type) (uint) frm_image[3]; - DBUG_ASSERT(share->db_plugin == NULL); /* if the storage engine is dynamic, no point in resolving it by its dynamically allocated legacy_db_type. We will resolve it later by name. */ if (legacy_db_type > DB_TYPE_UNKNOWN && legacy_db_type < DB_TYPE_FIRST_DYNAMIC) - share->db_plugin= ha_lock_engine(NULL, - ha_checktype(thd, legacy_db_type, 0, 0)); + se_plugin= ha_lock_engine(NULL, ha_checktype(thd, legacy_db_type, 0, 0)); share->db_create_options= db_create_options= uint2korr(frm_image+30); share->db_options_in_use= share->db_create_options; share->mysql_version= uint4korr(frm_image+51); @@ -1045,7 +1044,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, name.length= str_db_type_length; plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name); - if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin)) + if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, se_plugin)) { if (legacy_db_type > DB_TYPE_UNKNOWN && legacy_db_type < DB_TYPE_FIRST_DYNAMIC && @@ -1057,14 +1056,11 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } /* tmp_plugin is locked with a local lock. - we unlock the old value of share->db_plugin before + we unlock the old value of se_plugin before replacing it with a globally locked version of tmp_plugin */ - plugin_unlock(NULL, share->db_plugin); - share->db_plugin= my_plugin_lock(NULL, tmp_plugin); - DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", - str_db_type_length, next_chunk + 2, - ha_legacy_type(share->db_type()))); + plugin_unlock(NULL, se_plugin); + se_plugin= plugin_lock(NULL, tmp_plugin); } #ifdef WITH_PARTITION_STORAGE_ENGINE else if (str_db_type_length == 9 && @@ -1073,7 +1069,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, /* Use partition handler tmp_plugin is locked with a local lock. - we unlock the old value of share->db_plugin before + we unlock the old value of se_plugin before replacing it with a globally locked version of tmp_plugin */ /* Check if the partitioning engine is ready */ @@ -1083,11 +1079,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, "--skip-partition"); goto err; } - plugin_unlock(NULL, share->db_plugin); - share->db_plugin= ha_lock_engine(NULL, partition_hton); - DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", - str_db_type_length, next_chunk + 2, - ha_legacy_type(share->db_type()))); + plugin_unlock(NULL, se_plugin); + se_plugin= ha_lock_engine(NULL, partition_hton); } #endif else if (!tmp_plugin) @@ -1284,7 +1277,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, /* Allocate handler */ if (!(handler_file= get_new_handler(share, thd->mem_root, - share->db_type()))) + plugin_data(se_plugin, handlerton *)))) goto err; record= share->default_values-1; /* Fieldstart = 1 */ @@ -1909,6 +1902,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, (void) my_hash_check(&share->name_hash); #endif + DBUG_ASSERT(!share->db_plugin || plugin_equals(share->db_plugin, se_plugin)); + share->db_plugin= se_plugin; share->error= OPEN_FRM_OK; thd->status_var.opened_shares++; *root_ptr= old_root; @@ -1918,6 +1913,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->error= OPEN_FRM_CORRUPTED; share->open_errno= my_errno; delete handler_file; + plugin_unlock(0, se_plugin); my_hash_free(&share->name_hash); if (share->ha_data_destroy) { @@ -1936,10 +1932,129 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno); *root_ptr= old_root; - DBUG_RETURN(1); -} /* open_binary_frm */ + DBUG_RETURN(HA_ERR_NOT_A_TABLE); +} +static bool sql_unusable_for_discovery(THD *thd, const char *sql) +{ + LEX *lex= thd->lex; + HA_CREATE_INFO *create_info= &lex->create_info; + + // ... not CREATE TABLE + if (lex->sql_command != SQLCOM_CREATE_TABLE) + return 1; + // ... create like + if (create_info->options & HA_LEX_CREATE_TABLE_LIKE) + return 1; + // ... create select + if (lex->select_lex.item_list.elements) + return 1; + // ... temporary + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) + return 1; + // ... if exists + if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + return 1; + + // XXX error out or rather ignore the following: + // ... partitioning + if (lex->part_info) + return 1; + // ... union + if (create_info->used_fields & HA_CREATE_USED_UNION) + return 1; + // ... index/data directory + if (create_info->data_file_name || create_info->index_file_name) + return 1; + // ... engine + if (create_info->used_fields & HA_CREATE_USED_ENGINE) + return 1; + + return 0; +} + +int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, + const char *sql, size_t sql_length) +{ + ulonglong saved_mode= thd->variables.sql_mode; + CHARSET_INFO *old_cs= thd->variables.character_set_client; + Parser_state parser_state; + bool error; + char *sql_copy; + handler *file; + LEX *old_lex; + Query_arena *arena, backup; + LEX tmp_lex; + LEX_CUSTRING frm= {0,0}; + + DBUG_ENTER("TABLE_SHARE::init_from_sql_statement_string"); + + /* + Ouch. Parser may *change* the string it's working on. + Currently (2013-02-26) it is used to permanently disable + conditional comments. + Anyway, let's copy the caller's string... + */ + if (!(sql_copy= thd->strmake(sql, sql_length))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + if (parser_state.init(thd, sql_copy, sql_length)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + thd->variables.sql_mode= MODE_NO_ENGINE_SUBSTITUTION | MODE_NO_DIR_IN_CREATE; + thd->variables.character_set_client= system_charset_info; + tmp_disable_binlog(thd); + old_lex= thd->lex; + thd->lex= &tmp_lex; + + arena= thd->stmt_arena; + if (arena->is_conventional()) + arena= 0; + else + thd->set_n_backup_active_arena(arena, &backup); + + lex_start(thd); + + if ((error= parse_sql(thd, & parser_state, NULL))) + goto ret; + + if (sql_unusable_for_discovery(thd, sql_copy)) + { + my_error(ER_SQL_DISCOVER_ERROR, MYF(0), plugin_name(db_plugin)->str, + db.str, table_name.str, sql_copy); + goto ret; + } + + thd->lex->create_info.db_type= plugin_data(db_plugin, handlerton *); + + file= mysql_create_frm_image(thd, db.str, table_name.str, + &thd->lex->create_info, &thd->lex->alter_info, + 0, 0, &frm); + error|= file == 0; + delete file; + + if (frm.str) + error= init_from_binary_frm_image(thd, write, frm.str, frm.length); + +ret: + my_free(const_cast(frm.str)); + lex_end(thd->lex); + thd->lex= old_lex; + if (arena) + thd->restore_active_arena(arena, &backup); + reenable_binlog(thd); + thd->variables.sql_mode= saved_mode; + thd->variables.character_set_client= old_cs; + if (thd->is_error() || error) + { + thd->clear_error(); + my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str); + DBUG_RETURN(HA_ERR_NOT_A_TABLE); + } + DBUG_RETURN(0); +} + bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len) { return writefrm(normalized_path.str, db.str, table_name.str, 1, frm, len); diff --git a/sql/table.h b/sql/table.h index 562a49bfdae..a10617cc938 100644 --- a/sql/table.h +++ b/sql/table.h @@ -989,8 +989,10 @@ struct TABLE_SHARE uint actual_n_key_parts(THD *thd); LEX_CUSTRING *frm_image; ///< only during CREATE TABLE (@sa ha_create_table) - bool init_from_binary_frm_image(THD *thd, bool write, - const uchar *frm_image, size_t frm_length); + int init_from_binary_frm_image(THD *thd, bool write, + const uchar *frm_image, size_t frm_length); + int init_from_sql_statement_string(THD *thd, bool write, + const char *sql, size_t sql_length); bool write_frm_image(const uchar *frm_image, size_t frm_length); bool read_frm_image(const uchar **frm_image, size_t *frm_length); }; diff --git a/sql/unireg.cc b/sql/unireg.cc index a50ac99ed20..aa60a9e49c8 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -44,8 +44,6 @@ static uint get_interval_id(uint *,List &, Create_field *); static bool pack_fields(uchar *, List &, ulong); static size_t packed_fields_length(List &); static bool make_empty_rec(THD *, uchar *, uint, List &, uint, ulong); -static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *, - List &, uint, KEY *, handler *); /* Create a frm (table definition) file @@ -67,27 +65,7 @@ static LEX_CUSTRING create_frm_image(THD *, const char *, HA_CREATE_INFO *, true error */ -bool mysql_create_frm(THD *thd, const char *file_name, - const char *db, const char *table, - HA_CREATE_INFO *create_info, - List &create_fields, - uint keys, KEY *key_info, - handler *db_file) -{ - DBUG_ENTER("mysql_create_frm"); - LEX_CUSTRING frm= create_frm_image(thd, table, create_info, - create_fields, keys, key_info, db_file); - if (!frm.str) - DBUG_RETURN(1); - - int error= writefrm(file_name, db, table, !create_info->tmp_table(), - frm.str, frm.length); - - my_free(const_cast(frm.str)); - DBUG_RETURN(error); -} - -LEX_CUSTRING create_frm_image(THD *thd, const char *table, +LEX_CUSTRING build_frm_image(THD *thd, const char *table, HA_CREATE_INFO *create_info, List &create_fields, uint keys, KEY *key_info, handler *db_file) @@ -104,7 +82,7 @@ LEX_CUSTRING create_frm_image(THD *thd, const char *table, int error; uchar *frm_ptr, *pos; LEX_CUSTRING frm= {0,0}; - DBUG_ENTER("create_frm_image"); + DBUG_ENTER("build_frm_image"); /* If fixed row records, we need one bit to check for deleted rows */ if (!(create_info->table_options & HA_OPTION_PACK_RECORD)) @@ -373,37 +351,30 @@ err: 1 error */ -int rea_create_table(THD *thd, const char *path, - const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List &create_fields, - uint keys, KEY *key_info, handler *file) +int rea_create_table(THD *thd, LEX_CUSTRING *frm, + const char *path, const char *db, const char *table_name, + HA_CREATE_INFO *create_info, handler *file) { DBUG_ENTER("rea_create_table"); - LEX_CUSTRING frm= create_frm_image(thd, table_name, create_info, - create_fields, keys, key_info, file); - if (!frm.str) - DBUG_RETURN(1); - if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; if (create_info->frm_only) { - if (writefrm(path, db, table_name, 1, frm.str, frm.length)) + if (writefrm(path, db, table_name, 1, frm->str, frm->length)) goto err_handler; } else { // TODO don't write frm for temp tables if (create_info->tmp_table() && - writefrm(path, db, table_name, 0, frm.str, frm.length)) + writefrm(path, db, table_name, 0, frm->str, frm->length)) goto err_handler; if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, create_info) || - ha_create_table(thd, path, db, table_name, create_info, &frm)) + ha_create_table(thd, path, db, table_name, create_info, frm)) { file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, create_info); @@ -411,14 +382,12 @@ int rea_create_table(THD *thd, const char *path, } } - my_free(const_cast(frm.str)); DBUG_RETURN(0); err_handler: char frm_name[FN_REFLEN]; strxmov(frm_name, path, reg_ext, NullS); mysql_file_delete(key_file_frm, frm_name, MYF(0)); - my_free(const_cast(frm.str)); DBUG_RETURN(1); } /* rea_create_table */ diff --git a/sql/unireg.h b/sql/unireg.h index 6972f90c1db..89dae6b2e97 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -167,17 +167,13 @@ #include "sql_list.h" /* List<> */ #include "field.h" /* Create_field */ -bool mysql_create_frm(THD *thd, const char *file_name, - const char *db, const char *table, - HA_CREATE_INFO *create_info, - List &create_field, - uint key_count,KEY *key_info,handler *db_type); -int rea_create_table(THD *thd, const char *path, - const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List &create_field, - uint key_count,KEY *key_info, - handler *file); +int rea_create_table(THD *thd, LEX_CUSTRING *frm, + const char *path, const char *db, const char *table_name, + HA_CREATE_INFO *create_info, handler *file); +LEX_CUSTRING build_frm_image(THD *thd, const char *table, + HA_CREATE_INFO *create_info, + List &create_fields, + uint keys, KEY *key_info, handler *db_file); #define FRM_HEADER_SIZE 64 #define FRM_FORMINFO_SIZE 288 diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 616af00bcc8..515ebf8cf3d 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -302,9 +302,8 @@ int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) azclose(&frm_stream); - if (!share->init_from_binary_frm_image(thd, 1, frm_ptr, frm_stream.frm_length)) - my_errno= 0; - + my_errno= share->init_from_binary_frm_image(thd, 1, + frm_ptr, frm_stream.frm_length); ret: my_free(frm_ptr); DBUG_RETURN(my_errno); From 2d788ff5ca24d88853d3e201253a724392135f06 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:07:35 +0200 Subject: [PATCH 56/87] test_sql_discovery storage engine use it to test main test cases with need_full_discover_for_existence > 0 --- sql/sql_base.cc | 9 - sql/sql_rename.cc | 13 +- sql/sql_rename.h | 3 - sql/sql_table.cc | 1 - storage/test_sql_discovery/CMakeLists.txt | 2 + .../mysql-test/archive/discover.test | 3 + .../main/r/partition_disabled.rdiff | 11 + .../mysql-test/main/r/plugin.rdiff | 11 + .../mysql-test/main/t/create.test | 3 + .../mysql-test/main/t/drop.test | 3 + .../mysql-test/main/t/mdl_sync.test | 3 + .../mysql-test/main/t/partition_disabled.test | 3 + .../mysql-test/main/t/plugin.test | 3 + .../mysql-test/main/t/rename.test | 3 + .../mysql-test/sql_discovery/inc.inc | 4 + .../mysql-test/sql_discovery/inc.opt | 1 + .../mysql-test/sql_discovery/simple.result | 199 ++++++++++++++++++ .../mysql-test/sql_discovery/simple.test | 133 ++++++++++++ .../test_sql_discovery/test_sql_discovery.cc | 175 +++++++++++++++ 19 files changed, 565 insertions(+), 18 deletions(-) create mode 100644 storage/test_sql_discovery/CMakeLists.txt create mode 100644 storage/test_sql_discovery/mysql-test/archive/discover.test create mode 100644 storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff create mode 100644 storage/test_sql_discovery/mysql-test/main/r/plugin.rdiff create mode 100644 storage/test_sql_discovery/mysql-test/main/t/create.test create mode 100644 storage/test_sql_discovery/mysql-test/main/t/drop.test create mode 100644 storage/test_sql_discovery/mysql-test/main/t/mdl_sync.test create mode 100644 storage/test_sql_discovery/mysql-test/main/t/partition_disabled.test create mode 100644 storage/test_sql_discovery/mysql-test/main/t/plugin.test create mode 100644 storage/test_sql_discovery/mysql-test/main/t/rename.test create mode 100644 storage/test_sql_discovery/mysql-test/sql_discovery/inc.inc create mode 100644 storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt create mode 100644 storage/test_sql_discovery/mysql-test/sql_discovery/simple.result create mode 100644 storage/test_sql_discovery/mysql-test/sql_discovery/simple.test create mode 100644 storage/test_sql_discovery/test_sql_discovery.cc diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f88a3ef05f9..15eab7f32df 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -713,15 +713,6 @@ end: */ share= (TABLE_SHARE*) 1; } - else - { - /* - To be able perform any operation on table we should own - some kind of metadata lock on it. - */ - DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, - MDL_SHARED)); - } mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(share); diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 2c75de6e8a6..c957076ac4f 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -32,6 +32,9 @@ static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error); +static bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, + char *new_table_name, char *new_table_alias, + bool skip_error); static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list); @@ -144,10 +147,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) MYSQL_OPEN_SKIP_TEMPORARY)) goto err; - for (ren_table= table_list; ren_table; ren_table= ren_table->next_local) - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, ren_table->db, - ren_table->table_name, FALSE); - error=0; /* An exclusive lock on table names is satisfactory to ensure @@ -235,7 +234,7 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list) true rename failed */ -bool +static bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, char *new_table_alias, bool skip_error) { @@ -269,6 +268,10 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name, if (old_exists) { + DBUG_ASSERT(!thd->locked_tables_mode); + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, + ren_table->db, ren_table->table_name, false); + if (hton != view_pseudo_hton) { if (!(rc= mysql_rename_table(hton, ren_table->db, old_alias, diff --git a/sql/sql_rename.h b/sql/sql_rename.h index 039a3b8b4a1..aaf09a8d030 100644 --- a/sql/sql_rename.h +++ b/sql/sql_rename.h @@ -20,8 +20,5 @@ class THD; struct TABLE_LIST; bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent); -bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, - char *new_table_name, char *new_table_alias, - bool skip_error); #endif /* SQL_RENAME_INCLUDED */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0a02e674c07..8f2320b9b30 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -22,7 +22,6 @@ #include "unireg.h" #include "debug_sync.h" #include "sql_table.h" -#include "sql_rename.h" // do_rename #include "sql_parse.h" // test_if_data_home_dir #include "sql_cache.h" // query_cache_* #include "sql_base.h" // open_table_uncached, lock_table_names diff --git a/storage/test_sql_discovery/CMakeLists.txt b/storage/test_sql_discovery/CMakeLists.txt new file mode 100644 index 00000000000..2039b08123c --- /dev/null +++ b/storage/test_sql_discovery/CMakeLists.txt @@ -0,0 +1,2 @@ +MYSQL_ADD_PLUGIN(test_sql_discovery test_sql_discovery.cc STORAGE_ENGINE + COMPONENT Test) diff --git a/storage/test_sql_discovery/mysql-test/archive/discover.test b/storage/test_sql_discovery/mysql-test/archive/discover.test new file mode 100644 index 00000000000..6d7414280c5 --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/archive/discover.test @@ -0,0 +1,3 @@ +# run the normal test file with need_full_discover_for_existence>0 +--source ../sql_discovery/inc.inc +--source discover.test diff --git a/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff b/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff new file mode 100644 index 00000000000..3bb52b39d29 --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff @@ -0,0 +1,11 @@ +--- r/partition_disabled.result 2013-04-07 12:36:57.000000000 +0200 ++++ /usr/home/serg/Abk/mysql/10.0-serg/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.reject 2013-04-07 23:19:14.000000000 +0200 +@@ -3,7 +3,7 @@ + SELECT * FROM t1; + ERROR HY000: The MariaDB server is running with the --skip-partition option so it cannot execute this statement + TRUNCATE TABLE t1; +-ERROR 42S02: Table 'test.t1' doesn't exist ++ERROR HY000: The MariaDB server is running with the --skip-partition option so it cannot execute this statement + ANALYZE TABLE t1; + Table Op Msg_type Msg_text + test.t1 analyze Error The MariaDB server is running with the --skip-partition option so it cannot execute this statement diff --git a/storage/test_sql_discovery/mysql-test/main/r/plugin.rdiff b/storage/test_sql_discovery/mysql-test/main/r/plugin.rdiff new file mode 100644 index 00000000000..b9288d70f4b --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/r/plugin.rdiff @@ -0,0 +1,11 @@ +--- r/plugin.result 2013-02-21 19:46:59.000000000 +0100 ++++ r/plugin.reject 2013-02-27 11:13:22.000000000 +0100 +@@ -71,6 +71,8 @@ + SELECT * FROM t2; + ERROR 42000: Unknown storage engine 'EXAMPLE' + DROP TABLE t2; ++Warnings: ++Error 1286 Unknown storage engine 'EXAMPLE' + UNINSTALL PLUGIN EXAMPLE; + ERROR 42000: PLUGIN EXAMPLE does not exist + UNINSTALL PLUGIN non_exist; diff --git a/storage/test_sql_discovery/mysql-test/main/t/create.test b/storage/test_sql_discovery/mysql-test/main/t/create.test new file mode 100644 index 00000000000..4b3dd16c0a2 --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/t/create.test @@ -0,0 +1,3 @@ +# run the normal test file with need_full_discover_for_existence>0 +--source ../sql_discovery/inc.inc +--source create.test diff --git a/storage/test_sql_discovery/mysql-test/main/t/drop.test b/storage/test_sql_discovery/mysql-test/main/t/drop.test new file mode 100644 index 00000000000..2b3f864ec6b --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/t/drop.test @@ -0,0 +1,3 @@ +# run the normal test file with need_full_discover_for_existence>0 +--source ../sql_discovery/inc.inc +--source drop.test diff --git a/storage/test_sql_discovery/mysql-test/main/t/mdl_sync.test b/storage/test_sql_discovery/mysql-test/main/t/mdl_sync.test new file mode 100644 index 00000000000..9c052839d93 --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/t/mdl_sync.test @@ -0,0 +1,3 @@ +# run the normal test file with need_full_discover_for_existence>0 +--source ../sql_discovery/inc.inc +--source mdl_sync.test diff --git a/storage/test_sql_discovery/mysql-test/main/t/partition_disabled.test b/storage/test_sql_discovery/mysql-test/main/t/partition_disabled.test new file mode 100644 index 00000000000..7fccc33fdbd --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/t/partition_disabled.test @@ -0,0 +1,3 @@ +# run the normal test file with need_full_discover_for_existence>0 +--source ../sql_discovery/inc.inc +--source partition_disabled.test diff --git a/storage/test_sql_discovery/mysql-test/main/t/plugin.test b/storage/test_sql_discovery/mysql-test/main/t/plugin.test new file mode 100644 index 00000000000..52315af0645 --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/t/plugin.test @@ -0,0 +1,3 @@ +# run the normal test file with need_full_discover_for_existence>0 +--source ../sql_discovery/inc.inc +--source plugin.test diff --git a/storage/test_sql_discovery/mysql-test/main/t/rename.test b/storage/test_sql_discovery/mysql-test/main/t/rename.test new file mode 100644 index 00000000000..ba645131401 --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/main/t/rename.test @@ -0,0 +1,3 @@ +# run the normal test file with need_full_discover_for_existence>0 +--source ../sql_discovery/inc.inc +--source rename.test diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/inc.inc b/storage/test_sql_discovery/mysql-test/sql_discovery/inc.inc new file mode 100644 index 00000000000..b13cbd7d12b --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/sql_discovery/inc.inc @@ -0,0 +1,4 @@ +if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'test_sql_discovery' AND support='YES'`) +{ + --skip Test requires test_sql_discovery engine +} diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt b/storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt new file mode 100644 index 00000000000..32a5e3a294e --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt @@ -0,0 +1 @@ +--plugin-load=$HA_TEST_SQL_DISCOVERY_SO diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result new file mode 100644 index 00000000000..c2b9160f7c3 --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result @@ -0,0 +1,199 @@ +show variables like 'test_sql_discovery%'; +Variable_name Value +test_sql_discovery_statement +test_sql_discovery_write_frm ON +set sql_quote_show_create=0; +create table t1 (a int) engine=test_sql_discovery; +ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +set @@test_sql_discovery_statement='t1:foobar bwa-ha-ha'; +select * from t0; +ERROR 42S02: Table 'test.t0' doesn't exist +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'foobar bwa-ha-ha' at line 1 +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:select 1'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'select 1' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 (a int primary key) partition by hash(id) partitions 2'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1290 The MariaDB server is running with the --skip-partition option so it cannot execute this statement +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 (a int) union=(t3,t4)'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) union=(t3,t4)' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 like t2'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 like t2' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 select * from t2'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 select * from t2' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 (a int) index directory="/tmp"'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) index directory="/tmp"' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 (a int) data directory="/tmp"'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) data directory="/tmp"' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 (a int) engine=myisam'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) engine=myisam' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create temporary table t1 (a int)'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create temporary table t1 (a int)' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table if not exists t1 (a int)'; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist +show warnings; +Level Code Message +Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table if not exists t1 (a int)' +Error 1146 Table 'test.t1' doesn't exist +Error 1030 Got error 130 "Incorrect file format" from storage engine +set @@test_sql_discovery_statement='t1:create table t1 (a int)'; +select * from t1; +a +show create table t1; +Table Create Table +t1 CREATE TABLE t1 ( + a int(11) DEFAULT NULL +) ENGINE=TEST_SQL_DISCOVERY DEFAULT CHARSET=latin1 +drop table t1; +set @@test_sql_discovery_statement='t1:create table t2 (a int)'; +select * from t1; +a +select * from t2; +ERROR 42S02: Table 'test.t2' doesn't exist +drop table t1; +set @@test_sql_discovery_statement='t1: +create table t1 ( + a int not null default 5 primary key, + b timestamp, + c tinyblob, + d decimal(5,2), + e varchar(30) character set ascii, + f geometry not null, + index (d,b), + unique index (c(10)), + fulltext (e), + spatial (f) +) comment="abc" default character set utf8 max_rows=100 min_rows=10 checksum=1'; +show status like 'handler_discover'; +Variable_name Value +Handler_discover 13 +show create table t1; +Table Create Table +t1 CREATE TABLE t1 ( + a int(11) NOT NULL DEFAULT '5', + b timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + c tinyblob, + d decimal(5,2) DEFAULT NULL, + e varchar(30) CHARACTER SET ascii DEFAULT NULL, + f geometry NOT NULL, + PRIMARY KEY (a), + UNIQUE KEY c (c(10)), + KEY d (d,b), + SPATIAL KEY f (f), + FULLTEXT KEY e (e) +) ENGINE=TEST_SQL_DISCOVERY DEFAULT CHARSET=utf8 MIN_ROWS=10 MAX_ROWS=100 CHECKSUM=1 COMMENT='abc' +show status like 'handler_discover'; +Variable_name Value +Handler_discover 14 +---- +t1.frm +---- +show open tables from test; +Database Table In_use Name_locked +test t1 0 0 +select * from t1; +a b c d e f +show status like 'handler_discover'; +Variable_name Value +Handler_discover 14 +flush tables; +select * from t1; +a b c d e f +show status like 'handler_discover'; +Variable_name Value +Handler_discover 14 +drop table t1; +set @@test_sql_discovery_write_frm=0; +set @@test_sql_discovery_statement='t1:create table t1 (a int)'; +show status like 'handler_discover'; +Variable_name Value +Handler_discover 14 +show create table t1; +Table Create Table +t1 CREATE TABLE t1 ( + a int(11) DEFAULT NULL +) ENGINE=TEST_SQL_DISCOVERY DEFAULT CHARSET=latin1 +show status like 'handler_discover'; +Variable_name Value +Handler_discover 15 +---- +---- +show open tables from test; +Database Table In_use Name_locked +test t1 0 0 +select * from t1; +a +show status like 'handler_discover'; +Variable_name Value +Handler_discover 15 +flush tables; +select * from t1; +a +show status like 'handler_discover'; +Variable_name Value +Handler_discover 16 +drop table t1; +show status like 'handler_discover'; +Variable_name Value +Handler_discover 16 diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.test b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.test new file mode 100644 index 00000000000..4aa5ac2864e --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.test @@ -0,0 +1,133 @@ +--source inc.inc + +show variables like 'test_sql_discovery%'; +set sql_quote_show_create=0; +let $mysqld_datadir= `select @@datadir`; + +--error ER_CANT_CREATE_TABLE +create table t1 (a int) engine=test_sql_discovery; + +--error ER_NO_SUCH_TABLE +select * from t1; + +set @@test_sql_discovery_statement='t1:foobar bwa-ha-ha'; +--error ER_NO_SUCH_TABLE +select * from t0; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +# +# test different invalid discovering statements +# + +set @@test_sql_discovery_statement='t1:select 1'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table t1 (a int primary key) partition by hash(id) partitions 2'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table t1 (a int) union=(t3,t4)'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table t1 like t2'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table t1 select * from t2'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table t1 (a int) index directory="/tmp"'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table t1 (a int) data directory="/tmp"'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table t1 (a int) engine=myisam'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create temporary table t1 (a int)'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +set @@test_sql_discovery_statement='t1:create table if not exists t1 (a int)'; +--error ER_NO_SUCH_TABLE +select * from t1; +show warnings; + +# +# this should work: +# +set @@test_sql_discovery_statement='t1:create table t1 (a int)'; +select * from t1; +show create table t1; +drop table t1; + +# table name in the create table statement is ignored +set @@test_sql_discovery_statement='t1:create table t2 (a int)'; +select * from t1; +--error ER_NO_SUCH_TABLE +select * from t2; +drop table t1; + +# and something more complex +set @@test_sql_discovery_statement='t1: +create table t1 ( + a int not null default 5 primary key, + b timestamp, + c tinyblob, + d decimal(5,2), + e varchar(30) character set ascii, + f geometry not null, + index (d,b), + unique index (c(10)), + fulltext (e), + spatial (f) +) comment="abc" default character set utf8 max_rows=100 min_rows=10 checksum=1'; +show status like 'handler_discover'; +show create table t1; +show status like 'handler_discover'; +--echo ---- +--list_files $mysqld_datadir/test t* +--echo ---- +show open tables from test; +select * from t1; +show status like 'handler_discover'; +flush tables; +select * from t1; +show status like 'handler_discover'; +drop table t1; + +set @@test_sql_discovery_write_frm=0; +set @@test_sql_discovery_statement='t1:create table t1 (a int)'; +show status like 'handler_discover'; +show create table t1; +show status like 'handler_discover'; +--echo ---- +--list_files $mysqld_datadir/test t* +--echo ---- +show open tables from test; +select * from t1; +show status like 'handler_discover'; +flush tables; +select * from t1; +show status like 'handler_discover'; +drop table t1; +show status like 'handler_discover'; + diff --git a/storage/test_sql_discovery/test_sql_discovery.cc b/storage/test_sql_discovery/test_sql_discovery.cc new file mode 100644 index 00000000000..00d488e4ad6 --- /dev/null +++ b/storage/test_sql_discovery/test_sql_discovery.cc @@ -0,0 +1,175 @@ +/* + Copyright (c) 2013 Monty Program Ab + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + a really minimal engine to test table discovery via sql statements. + See the archive engine if you're interested in real-life usable engine that + uses discovery via frm shipping. +*/ + +#include +#include +#include + +static MYSQL_THDVAR_STR(statement, PLUGIN_VAR_MEMALLOC, + "The table name and the SQL statement to discover the next table", + NULL, NULL, 0); + +static MYSQL_THDVAR_BOOL(write_frm, 0, + "Whether to cache discovered table metadata in frm files", + NULL, NULL, TRUE); + +static struct st_mysql_sys_var *sysvars[] = { + MYSQL_SYSVAR(statement), + MYSQL_SYSVAR(write_frm), + NULL +}; + +typedef struct st_share { + const char *name; + THR_LOCK lock; + uint use_count; + struct st_share *next; +} SHARE; + +class ha_tsd: public handler +{ +private: + THR_LOCK_DATA lock; + SHARE *share; + +public: + ha_tsd(handlerton *hton, TABLE_SHARE *table_arg) + : handler(hton, table_arg) { } + ulonglong table_flags() const + { // NO_TRANSACTIONS and everything that affects CREATE TABLE + return HA_NO_TRANSACTIONS | HA_CAN_GEOMETRY | HA_NULL_IN_KEY | + HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | HA_CAN_RTREEKEYS | + HA_CAN_FULLTEXT; + } + + ulong index_flags(uint inx, uint part, bool all_parts) const { return 0; } + + THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, + enum thr_lock_type lock_type) + { + if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) + lock.type = lock_type; + *to ++= &lock; + return to; + } + + int rnd_init(bool scan) { return 0; } + int rnd_next(unsigned char *buf) { return HA_ERR_END_OF_FILE; } + void position(const uchar *record) { } + int rnd_pos(uchar *buf, uchar *pos) { return HA_ERR_END_OF_FILE; } + int info(uint flag) { return 0; } + uint max_supported_keys() const { return 16; } + int create(const char *name, TABLE *table_arg, + HA_CREATE_INFO *create_info) { return HA_ERR_WRONG_COMMAND; } + + int open(const char *name, int mode, uint test_if_locked); + int close(void); +}; + +static SHARE *find_or_create_share(const char *table_name, TABLE *table) +{ + SHARE *share; + for (share = (SHARE*)table->s->ha_data; share; share = share->next) + if (my_strcasecmp(table_alias_charset, table_name, share->name) == 0) + return share; + + share = (SHARE*)alloc_root(&table->s->mem_root, sizeof(*share)); + bzero(share, sizeof(*share)); + share->name = strdup_root(&table->s->mem_root, table_name); + share->next = (SHARE*)table->s->ha_data; + table->s->ha_data = share; + return share; +} + +int ha_tsd::open(const char *name, int mode, uint test_if_locked) +{ + mysql_mutex_lock(&table->s->LOCK_ha_data); + share = find_or_create_share(name, table); + if (share->use_count++ == 0) + thr_lock_init(&share->lock); + mysql_mutex_unlock(&table->s->LOCK_ha_data); + thr_lock_data_init(&share->lock,&lock,NULL); + + return 0; +} + +int ha_tsd::close(void) +{ + mysql_mutex_lock(&table->s->LOCK_ha_data); + if (--share->use_count == 0) + thr_lock_delete(&share->lock); + mysql_mutex_unlock(&table->s->LOCK_ha_data); + return 0; +} + +static handler *create_handler(handlerton *hton, TABLE_SHARE *table, + MEM_ROOT *mem_root) +{ + return new (mem_root) ha_tsd(hton, table); +} + +static int discover_table(handlerton *hton, THD* thd, TABLE_SHARE *share) +{ + const char *sql= THDVAR(thd, statement); + + // the table is discovered if sql starts from "table_name:" + if (!sql || + strncmp(sql, share->table_name.str, share->table_name.length) || + sql[share->table_name.length] != ':') + return HA_ERR_NO_SUCH_TABLE; + + sql+= share->table_name.length + 1; + return share->init_from_sql_statement_string(thd, THDVAR(thd, write_frm), + sql, strlen(sql)); +} + +static int init(void *p) +{ + handlerton *hton = (handlerton *)p; + hton->create = create_handler; + hton->discover_table = discover_table; + return 0; +} + +struct st_mysql_storage_engine descriptor = +{ MYSQL_HANDLERTON_INTERFACE_VERSION }; + +maria_declare_plugin(tsd) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &descriptor, + "TEST_SQL_DISCOVERY", + "Sergei Golubchik", + "Minimal engine to test table discovery via sql statements", + PLUGIN_LICENSE_GPL, + init, + NULL, + 0x0001, + NULL, + sysvars, + "0.1", + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL +} +maria_declare_plugin_end; + From 13b7bcd5d44d037984abfd0dd2acf8f1ce54b161 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:17:16 +0200 Subject: [PATCH 57/87] sequence engine --- storage/sequence/CMakeLists.txt | 1 + storage/sequence/mysql-test/sequence/inc.inc | 4 + storage/sequence/mysql-test/sequence/inc.opt | 1 + .../mysql-test/sequence/simple.result | 270 ++++++++++++++ .../sequence/mysql-test/sequence/simple.test | 93 +++++ storage/sequence/sequence.cc | 343 ++++++++++++++++++ 6 files changed, 712 insertions(+) create mode 100644 storage/sequence/CMakeLists.txt create mode 100644 storage/sequence/mysql-test/sequence/inc.inc create mode 100644 storage/sequence/mysql-test/sequence/inc.opt create mode 100644 storage/sequence/mysql-test/sequence/simple.result create mode 100644 storage/sequence/mysql-test/sequence/simple.test create mode 100644 storage/sequence/sequence.cc diff --git a/storage/sequence/CMakeLists.txt b/storage/sequence/CMakeLists.txt new file mode 100644 index 00000000000..9a68901520c --- /dev/null +++ b/storage/sequence/CMakeLists.txt @@ -0,0 +1 @@ +MYSQL_ADD_PLUGIN(sequence sequence.cc STORAGE_ENGINE) diff --git a/storage/sequence/mysql-test/sequence/inc.inc b/storage/sequence/mysql-test/sequence/inc.inc new file mode 100644 index 00000000000..702e90b2890 --- /dev/null +++ b/storage/sequence/mysql-test/sequence/inc.inc @@ -0,0 +1,4 @@ +if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'sequence' AND support='YES'`) +{ + --skip Test requires sequence engine +} diff --git a/storage/sequence/mysql-test/sequence/inc.opt b/storage/sequence/mysql-test/sequence/inc.opt new file mode 100644 index 00000000000..ad178af67c2 --- /dev/null +++ b/storage/sequence/mysql-test/sequence/inc.opt @@ -0,0 +1 @@ +--plugin-load=$HA_SEQUENCE_SO diff --git a/storage/sequence/mysql-test/sequence/simple.result b/storage/sequence/mysql-test/sequence/simple.result new file mode 100644 index 00000000000..102f17498fe --- /dev/null +++ b/storage/sequence/mysql-test/sequence/simple.result @@ -0,0 +1,270 @@ +select * from information_schema.engines where engine='sequence'; +ENGINE SEQUENCE +SUPPORT YES +COMMENT Generated tables filled with sequential values +TRANSACTIONS YES +XA YES +SAVEPOINTS YES +set sql_quote_show_create=0; +show create table seq_1_to_15_step_2; +Table Create Table +seq_1_to_15_step_2 CREATE TABLE seq_1_to_15_step_2 ( + seq bigint(20) unsigned NOT NULL, + PRIMARY KEY (seq) +) ENGINE=SEQUENCE DEFAULT CHARSET=latin1 +show create table seq_1_to_15_step; +ERROR 42S02: Table 'test.seq_1_to_15_step' doesn't exist +show create table seq_1_to_15_st; +ERROR 42S02: Table 'test.seq_1_to_15_st' doesn't exist +show create table seq_1_to_15; +Table Create Table +seq_1_to_15 CREATE TABLE seq_1_to_15 ( + seq bigint(20) unsigned NOT NULL, + PRIMARY KEY (seq) +) ENGINE=SEQUENCE DEFAULT CHARSET=latin1 +show create table seq_1_to_1; +Table Create Table +seq_1_to_1 CREATE TABLE seq_1_to_1 ( + seq bigint(20) unsigned NOT NULL, + PRIMARY KEY (seq) +) ENGINE=SEQUENCE DEFAULT CHARSET=latin1 +show create table seq_1_to_; +ERROR 42S02: Table 'test.seq_1_to_' doesn't exist +show create table seq_1_t; +ERROR 42S02: Table 'test.seq_1_t' doesn't exist +show create table seq_1; +ERROR 42S02: Table 'test.seq_1' doesn't exist +show create table seq_; +ERROR 42S02: Table 'test.seq_' doesn't exist +show create table se; +ERROR 42S02: Table 'test.se' doesn't exist +show create table seq_1_to_15_step_0; +ERROR HY000: Got error 140 "Wrong create options" from storage engine +select * from seq_1_to_15_step_2; +seq +1 +3 +5 +7 +9 +11 +13 +15 +select * from seq_1_to_15; +seq +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +select * from seq_1_to_1; +seq +1 +select * from seq_15_to_1; +seq +15 +14 +13 +12 +11 +10 +9 +8 +7 +6 +5 +4 +3 +2 +1 +select * from seq_15_to_1_step_2; +seq +15 +13 +11 +9 +7 +5 +3 +1 +select * from seq_1_to_15_step_12345; +seq +1 +select * from seq_15_to_1_step_12345; +seq +15 +explain select * from seq_15_to_1_step_12345; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_15_to_1_step_12345 ALL NULL NULL NULL NULL 1 +show open tables from test; +Database Table In_use Name_locked +test seq_15_to_1 0 0 +test seq_15_to_1_step_12345 0 0 +test seq_15_to_1_step_2 0 0 +test seq_1_to_1 0 0 +test seq_1_to_15 0 0 +test seq_1_to_15_step_12345 0 0 +test seq_1_to_15_step_2 0 0 +show tables; +Tables_in_test +explain select * from seq_1_to_15_step_2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_15_step_2 index NULL PRIMARY 8 NULL 8 Using index +explain select * from seq_1_to_15_step_2 where seq > 4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_15_step_2 range PRIMARY PRIMARY 8 NULL 6 Using where; Using index +explain select * from seq_1_to_15_step_2 where seq between 4 and 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_15_step_2 range PRIMARY PRIMARY 8 NULL 3 Using where; Using index +explain select * from seq_1_to_15_step_2 where seq between 20 and 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +explain select * from seq_1_to_15_step_2 where seq between 4 and 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_15_step_2 range PRIMARY PRIMARY 8 NULL 1 Using where; Using index +explain select * from seq_1_to_15_step_2 where seq between 4 and 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_15_step_2 range PRIMARY PRIMARY 8 NULL 1 Using where; Using index +explain select * from seq_1_to_15_step_2 where seq between 4 and 4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +explain select * from seq_1_to_15_step_2 where seq between 5 and 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE seq_1_to_15_step_2 const PRIMARY PRIMARY 8 const 1 Using index +create table t1 (a int, aa int, b varchar(100)); +insert t1 select seq, seq*seq, if (seq % 2, 'odd', 'even') from seq_1_to_20; +select * from t1; +a aa b +1 1 odd +2 4 even +3 9 odd +4 16 even +5 25 odd +6 36 even +7 49 odd +8 64 even +9 81 odd +10 100 even +11 121 odd +12 144 even +13 169 odd +14 196 even +15 225 odd +16 256 even +17 289 odd +18 324 even +19 361 odd +20 400 even +select aa, b from t1, seq_1_to_20_step_3 as seq where a=seq; +aa b +1 odd +16 even +49 odd +100 even +169 odd +256 even +361 odd +insert t1 +select seq, seq*seq, if (seq % 2, 'odd', 'even') from seq_1_to_30 +where seq > (select max(a) from t1); +select * from t1; +a aa b +1 1 odd +2 4 even +3 9 odd +4 16 even +5 25 odd +6 36 even +7 49 odd +8 64 even +9 81 odd +10 100 even +11 121 odd +12 144 even +13 169 odd +14 196 even +15 225 odd +16 256 even +17 289 odd +18 324 even +19 361 odd +20 400 even +21 441 odd +22 484 even +23 529 odd +24 576 even +25 625 odd +26 676 even +27 729 odd +28 784 even +29 841 odd +30 900 even +drop table t1; +select seq from seq_2_to_50 s1 where 0 not in +(select s1.seq % s2.seq from seq_2_to_50 s2 where s2.seq <= sqrt(s1.seq)); +seq +2 +3 +5 +7 +11 +13 +17 +19 +23 +29 +31 +37 +41 +43 +47 +explain select seq from seq_2_to_50 s1 where 0 not in +(select s1.seq % s2.seq from seq_2_to_50 s2 where s2.seq <= sqrt(s1.seq)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY s1 index NULL PRIMARY 8 NULL 49 Using where; Using index +2 DEPENDENT SUBQUERY s2 index PRIMARY PRIMARY 8 NULL 49 Using where; Using index +select year(dt) from +(select '1901-02-28' + interval seq year as dt from seq_0_to_99) as seqdt +where weekday(dt) = 0; +year(dt) +1910 +1916 +1921 +1927 +1938 +1944 +1949 +1955 +1966 +1972 +1977 +1983 +1994 +2000 +create table t1 (a int) engine=innodb; +reset master; +start transaction; +insert t1 select * from seq_1_to_10; +savepoint s1; +insert t1 select * from seq_11_to_20; +rollback to savepoint s1; +commit; +select count(*) from t1; +count(*) +10 +show binlog events limit 2,10; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 286 Query 1 354 BEGIN +master-bin.000001 354 Query 1 452 use test; insert t1 select * from seq_1_to_10 +master-bin.000001 452 Xid 1 479 COMMIT /* xid */ +drop table t1; diff --git a/storage/sequence/mysql-test/sequence/simple.test b/storage/sequence/mysql-test/sequence/simple.test new file mode 100644 index 00000000000..9559e42fafd --- /dev/null +++ b/storage/sequence/mysql-test/sequence/simple.test @@ -0,0 +1,93 @@ +--source inc.inc +--source include/have_xtradb.inc +--source include/have_binlog_format_statement.inc + +--query_vertical select * from information_schema.engines where engine='sequence' + +set sql_quote_show_create=0; + +show create table seq_1_to_15_step_2; +--error ER_NO_SUCH_TABLE +show create table seq_1_to_15_step; +--error ER_NO_SUCH_TABLE +show create table seq_1_to_15_st; +show create table seq_1_to_15; +show create table seq_1_to_1; +--error ER_NO_SUCH_TABLE +show create table seq_1_to_; +--error ER_NO_SUCH_TABLE +show create table seq_1_t; +--error ER_NO_SUCH_TABLE +show create table seq_1; +--error ER_NO_SUCH_TABLE +show create table seq_; +--error ER_NO_SUCH_TABLE +show create table se; +--error ER_GET_ERRNO +show create table seq_1_to_15_step_0; + +# simple select +select * from seq_1_to_15_step_2; +select * from seq_1_to_15; +select * from seq_1_to_1; +# backwards +select * from seq_15_to_1; +select * from seq_15_to_1_step_2; + +# step > |to - from| +select * from seq_1_to_15_step_12345; +select * from seq_15_to_1_step_12345; +explain select * from seq_15_to_1_step_12345; + +--sorted_result +show open tables from test; +show tables; +# row estimates +explain select * from seq_1_to_15_step_2; +explain select * from seq_1_to_15_step_2 where seq > 4; +explain select * from seq_1_to_15_step_2 where seq between 4 and 9; +explain select * from seq_1_to_15_step_2 where seq between 20 and 30; +explain select * from seq_1_to_15_step_2 where seq between 4 and 6; +explain select * from seq_1_to_15_step_2 where seq between 4 and 5; +explain select * from seq_1_to_15_step_2 where seq between 4 and 4; +explain select * from seq_1_to_15_step_2 where seq between 5 and 5; + +# join +create table t1 (a int, aa int, b varchar(100)); +insert t1 select seq, seq*seq, if (seq % 2, 'odd', 'even') from seq_1_to_20; +select * from t1; +select aa, b from t1, seq_1_to_20_step_3 as seq where a=seq; +# adding more rows, example +insert t1 + select seq, seq*seq, if (seq % 2, 'odd', 'even') from seq_1_to_30 + where seq > (select max(a) from t1); +select * from t1; +drop table t1; + +# Prime Numbers from 2 to 50 :) +select seq from seq_2_to_50 s1 where 0 not in + (select s1.seq % s2.seq from seq_2_to_50 s2 where s2.seq <= sqrt(s1.seq)); +explain select seq from seq_2_to_50 s1 where 0 not in + (select s1.seq % s2.seq from seq_2_to_50 s2 where s2.seq <= sqrt(s1.seq)); + +# Years of XX-th century where 28th of February was Monday +select year(dt) from + (select '1901-02-28' + interval seq year as dt from seq_0_to_99) as seqdt + where weekday(dt) = 0; + +# transactions and XA +create table t1 (a int) engine=innodb; +reset master; +start transaction; +# No warning about "accesses nontransactional table" +insert t1 select * from seq_1_to_10; +savepoint s1; +insert t1 select * from seq_11_to_20; +rollback to savepoint s1; +commit; +select count(*) from t1; +# must show Xid event +--replace_regex /xid=[0-9]+/xid/ +show binlog events limit 2,10; +drop table t1; + diff --git a/storage/sequence/sequence.cc b/storage/sequence/sequence.cc new file mode 100644 index 00000000000..62915f68484 --- /dev/null +++ b/storage/sequence/sequence.cc @@ -0,0 +1,343 @@ +/* + Copyright (c) 2013 Monty Program Ab + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + a engine that auto-creates tables with rows filled with sequential values +*/ + +#include +#include +#include +#include + +typedef struct st_share { + const char *name; + THR_LOCK lock; + uint use_count; + struct st_share *next; + + ulonglong from, to, step; + bool reverse; +} SHARE; + +class ha_seq: public handler +{ +private: + THR_LOCK_DATA lock; + SHARE *seqs; + ulonglong cur; + +public: + ha_seq(handlerton *hton, TABLE_SHARE *table_arg) + : handler(hton, table_arg), seqs(0) { } + ulonglong table_flags() const { return 0; } + + /* open/close/locking */ + int create(const char *name, TABLE *table_arg, + HA_CREATE_INFO *create_info) { return HA_ERR_WRONG_COMMAND; } + + int open(const char *name, int mode, uint test_if_locked); + int close(void); + THR_LOCK_DATA **store_lock(THD *, THR_LOCK_DATA **, enum thr_lock_type); + + /* table scan */ + int rnd_init(bool scan); + int rnd_next(unsigned char *buf); + void position(const uchar *record); + int rnd_pos(uchar *buf, uchar *pos); + int info(uint flag); + + /* indexes */ + ulong index_flags(uint inx, uint part, bool all_parts) const + { return HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | + HA_READ_RANGE | HA_KEYREAD_ONLY; } + uint max_supported_keys() const { return 1; } + int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, + enum ha_rkey_function find_flag); + int index_next(uchar *buf); + int index_prev(uchar *buf); + int index_first(uchar *buf); + int index_last(uchar *buf); + ha_rows records_in_range(uint inx, key_range *min_key, + key_range *max_key); + + double scan_time() { return nvalues(); } + double read_time(uint index, uint ranges, ha_rows rows) { return rows; } + double keyread_time(uint index, uint ranges, ha_rows rows) { return rows; } + +private: + void set(uchar *buf); + ulonglong nvalues() { return (seqs->to - seqs->from)/seqs->step; } +}; + +THR_LOCK_DATA **ha_seq::store_lock(THD *thd, THR_LOCK_DATA **to, + enum thr_lock_type lock_type) +{ + if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) + lock.type= TL_WRITE_ALLOW_WRITE; + *to ++= &lock; + return to; +} + +void ha_seq::set(unsigned char *buf) +{ + my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set); + my_ptrdiff_t offset = (my_ptrdiff_t) (buf - table->record[0]); + Field *field = table->field[0]; + field->move_field_offset(offset); + field->store(cur, true); + field->move_field_offset(-offset); + dbug_tmp_restore_column_map(table->write_set, old_map); +} + +int ha_seq::rnd_init(bool scan) +{ + cur= seqs->reverse ? seqs->to : seqs->from; + return 0; +} + +int ha_seq::rnd_next(unsigned char *buf) +{ + if (seqs->reverse) + return index_prev(buf); + else + return index_next(buf); +} + +void ha_seq::position(const uchar *record) +{ + *(ulonglong*)ref= cur; +} + +int ha_seq::rnd_pos(uchar *buf, uchar *pos) +{ + cur= *(ulonglong*)pos; + return rnd_next(buf); +} + +int ha_seq::info(uint flag) +{ + if (flag & HA_STATUS_VARIABLE) + stats.records = nvalues(); + return 0; +} + +int ha_seq::index_read_map(uchar *buf, const uchar *key_arg, + key_part_map keypart_map, + enum ha_rkey_function find_flag) +{ + ulonglong key= uint8korr(key_arg); + switch (find_flag) { + case HA_READ_AFTER_KEY: + key++; + // fall through + case HA_READ_KEY_OR_NEXT: + if (key <= seqs->from) + cur= seqs->from; + else + { + cur= (key - seqs->from + seqs->step - 1) / seqs->step * seqs->step + seqs->from; + if (cur >= seqs->to) + return HA_ERR_KEY_NOT_FOUND; + } + return index_next(buf); + + case HA_READ_KEY_EXACT: + if ((key - seqs->from) % seqs->step != 0 || key < seqs->from || key >= seqs->to) + return HA_ERR_KEY_NOT_FOUND; + cur= key; + return index_next(buf); + + case HA_READ_BEFORE_KEY: + key--; + // fall through + case HA_READ_PREFIX_LAST_OR_PREV: + if (key >= seqs->to) + cur= seqs->to; + else + { + if (key < seqs->from) + return HA_ERR_KEY_NOT_FOUND; + cur= (key - seqs->from) / seqs->step * seqs->step + seqs->from; + } + return index_prev(buf); + default: return HA_ERR_WRONG_COMMAND; + } +} + + +int ha_seq::index_next(uchar *buf) +{ + if (cur == seqs->to) + return HA_ERR_END_OF_FILE; + set(buf); + cur+= seqs->step; + return 0; +} + + +int ha_seq::index_prev(uchar *buf) +{ + if (cur == seqs->from) + return HA_ERR_END_OF_FILE; + cur-= seqs->step; + set(buf); + return 0; +} + + +int ha_seq::index_first(uchar *buf) +{ + cur= seqs->from; + return index_next(buf); +} + + +int ha_seq::index_last(uchar *buf) +{ + cur= seqs->to; + return index_prev(buf); +} + +ha_rows ha_seq::records_in_range(uint inx, key_range *min_key, + key_range *max_key) +{ + ulonglong kmin= min_key ? uint8korr(min_key->key) : seqs->from; + ulonglong kmax= max_key ? uint8korr(max_key->key) : seqs->to - 1; + if (kmin >= seqs->to || kmax < seqs->from || kmin > kmax) + return 0; + return (kmax - seqs->from) / seqs->step - + (kmin - seqs->from + seqs->step - 1) / seqs->step + 1; +} + + +int ha_seq::open(const char *name, int mode, uint test_if_locked) +{ + mysql_mutex_lock(&table->s->LOCK_ha_data); + seqs= (SHARE*)table->s->ha_data; + DBUG_ASSERT(my_strcasecmp(table_alias_charset, name, seqs->name) == 0); + if (seqs->use_count++ == 0) + thr_lock_init(&seqs->lock); + mysql_mutex_unlock(&table->s->LOCK_ha_data); + + ref_length= sizeof(cur); + thr_lock_data_init(&seqs->lock,&lock,NULL); + return 0; +} + +int ha_seq::close(void) +{ + mysql_mutex_lock(&table->s->LOCK_ha_data); + if (--seqs->use_count == 0) + thr_lock_delete(&seqs->lock); + mysql_mutex_unlock(&table->s->LOCK_ha_data); + return 0; +} + +static handler *create_handler(handlerton *hton, TABLE_SHARE *table, + MEM_ROOT *mem_root) +{ + return new (mem_root) ha_seq(hton, table); +} + +static int discover_table(handlerton *hton, THD *thd, TABLE_SHARE *share) +{ + // the table is discovered if it has the pattern of seq_1_to_10 or + // seq_1_to_10_step_3 + ulonglong from, to, step= 1; + uint n1= 0, n2= 0; + bool reverse; + sscanf(share->table_name.str, "seq_%llu_to_%llu%n_step_%llu%n", + &from, &to, &n1, &step, &n2); + if (n1 != share->table_name.length && n2 != share->table_name.length) + return HA_ERR_NO_SUCH_TABLE; + + if (step == 0) + return HA_WRONG_CREATE_OPTION; + + const char *sql="create table seq (seq bigint unsigned primary key)"; + int res= share->init_from_sql_statement_string(thd, 0, sql, strlen(sql)); + if (res) + return res; + + if ((reverse = from > to)) + { + if (step > from - to) + to = from; + else + swap_variables(ulonglong, from, to); + /* + when keyread is allowed, optimizer will always prefer an index to a + table scan for our tables, and we'll never see the range reversed. + */ + share->keys_for_keyread.clear_all(); + } + + to= (to - from) / step * step + step + from; + + SHARE *seqs= (SHARE*)alloc_root(&share->mem_root, sizeof(*seqs)); + bzero(seqs, sizeof(*seqs)); + seqs->name = share->normalized_path.str; + seqs->from= from; + seqs->to= to; + seqs->step= step; + seqs->reverse= reverse; + + share->ha_data = seqs; + return 0; +} + + +static int dummy_ret_int() { return 0; } + +static int init(void *p) +{ + handlerton *hton = (handlerton *)p; + hton->create = create_handler; + hton->discover_table = discover_table; + hton->discover_table_existence = + (int (*)(handlerton *, const char *, const char *)) &dummy_ret_int; + hton->commit= hton->rollback= hton->prepare= + (int (*)(handlerton *, THD *, bool)) &dummy_ret_int; + hton->savepoint_set= hton->savepoint_rollback= hton->savepoint_release= + (int (*)(handlerton *, THD *, void *)) &dummy_ret_int; + + return 0; +} + +static struct st_mysql_storage_engine descriptor = +{ MYSQL_HANDLERTON_INTERFACE_VERSION }; + +maria_declare_plugin(seq) +{ + MYSQL_STORAGE_ENGINE_PLUGIN, + &descriptor, + "SEQUENCE", + "Sergei Golubchik", + "Generated tables filled with sequential values", + PLUGIN_LICENSE_GPL, + init, + NULL, + 0x0100, + NULL, + NULL, + "0.1", + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL +} +maria_declare_plugin_end; + From b10937ea24d28e79a84b4537f4dc1d4597b5e0ac Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:10 +0200 Subject: [PATCH 58/87] update the comment --- sql/unireg.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sql/unireg.cc b/sql/unireg.cc index aa60a9e49c8..d95134c0390 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -49,10 +49,8 @@ static bool make_empty_rec(THD *, uchar *, uint, List &, uint, ulo Create a frm (table definition) file SYNOPSIS - mysql_create_frm() + build_frm_image() thd Thread handler - file_name Path for file (including database and .frm) - db Name of database table Name of table create_info create info parameters create_fields Fields to create From f6108b1fabe2dc95c4b72a754a85397987aa20c4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:21 +0200 Subject: [PATCH 59/87] comments --- sql/unireg.cc | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/sql/unireg.cc b/sql/unireg.cc index d95134c0390..8301ba0bc48 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -45,22 +45,19 @@ static bool pack_fields(uchar *, List &, ulong); static size_t packed_fields_length(List &); static bool make_empty_rec(THD *, uchar *, uint, List &, uint, ulong); -/* +/** Create a frm (table definition) file - SYNOPSIS - build_frm_image() - thd Thread handler - table Name of table - create_info create info parameters - create_fields Fields to create - keys number of keys to create - key_info Keys to create - db_file Handler to use. + @param thd Thread handler + @param table Name of table + @param create_info create info parameters + @param create_fields Fields to create + @param keys number of keys to create + @param key_info Keys to create + @param db_file Handler to use. - RETURN - false ok - true error + @return the generated frm image as a LEX_CUSTRING, + or null LEX_CUSTRING (str==0) in case of an error. */ LEX_CUSTRING build_frm_image(THD *thd, const char *table, @@ -200,16 +197,16 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, key_buff_length= uint4korr(fileinfo+47); - frm.length= FRM_HEADER_SIZE; // fileinfo; - frm.length+= 7; // "form entry" + frm.length= FRM_HEADER_SIZE; // fileinfo; + frm.length+= uint2korr(fileinfo+4) + 4; // "form entry" int2store(fileinfo+6, frm.length); frm.length+= key_buff_length; - frm.length+= reclength; // row with default values + frm.length+= reclength; // row with default values frm.length+= create_info->extra_size; filepos= frm.length; - frm.length+= FRM_FORMINFO_SIZE; // forminfo + frm.length+= FRM_FORMINFO_SIZE; // forminfo frm.length+= packed_fields_length(create_fields); frm_ptr= (uchar*) my_malloc(frm.length, MYF(MY_WME | MY_ZEROFILL | From f6168bb67bb5cab0584809c876c674a92051b5d1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:27 +0200 Subject: [PATCH 60/87] cleanup --- sql/share/errmsg-utf8.txt | 6 +++--- sql/unireg.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index fd74af7d56d..036d4a0258c 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6188,9 +6188,9 @@ ER_EXCEPTIONS_WRITE_ERROR eng "Write to exceptions table failed. Message: %-.128s"" ger "Schreiben in Ausnahme-Tabelle fehlgeschlagen. Meldung: %-.128s"" ER_TOO_LONG_TABLE_COMMENT - eng "Comment for table '%-.64s' is too long (max = %lu)" - por "Comentário para a tabela '%-.64s' é longo demais (max = %lu)" - ger "Kommentar für Tabelle '%-.64s' ist zu lang (max = %lu)" + eng "Comment for table '%-.64s' is too long (max = %u)" + por "Comentário para a tabela '%-.64s' é longo demais (max = %u)" + ger "Kommentar für Tabelle '%-.64s' ist zu lang (max = %u)" ER_TOO_LONG_FIELD_COMMENT eng "Comment for field '%-.64s' is too long (max = %lu)" por "Comentário para o campo '%-.64s' é longo demais (max = %lu)" diff --git a/sql/unireg.cc b/sql/unireg.cc index 8301ba0bc48..588ed622a60 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -166,12 +166,12 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), - real_table_name, static_cast(TABLE_COMMENT_MAXLEN)); + real_table_name, TABLE_COMMENT_MAXLEN); DBUG_RETURN(frm); } char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_TABLE_COMMENT), - real_table_name, static_cast(TABLE_COMMENT_MAXLEN)); + real_table_name, TABLE_COMMENT_MAXLEN); push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TOO_LONG_TABLE_COMMENT, warn_buff); create_info->comment.length= tmp_len; From 02c712aa546df8d6e9c285e6adc95309925673e3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:33 +0200 Subject: [PATCH 61/87] * frm extra2 segment. * persistent table versions in the extra2 * ha_archive::frm_compare using TABLE_SHARE::tabledef_version * distinguish between "important" and "optional" extra2 frm values * write engine-defined attributes (aka "table options") to extra2, not to extra, but still read from the old location, if they're found there. --- include/my_base.h | 2 +- mysql-test/suite/archive/archive.result | 9 ++- mysql-test/suite/archive/archive.test | 2 +- mysql-test/suite/archive/discover.result | 38 ++++----- mysql-test/suite/archive/discover.test | 15 ++-- .../suite/archive/partition_archive.result | 4 +- mysys/my_uuid.c | 2 +- sql/handler.h | 2 + sql/table.cc | 75 ++++++++++++++--- sql/table.h | 2 + sql/unireg.cc | 80 ++++++++++++------- sql/unireg.h | 16 ++++ storage/archive/azio.c | 18 +++++ storage/archive/azlib.h | 3 + storage/archive/ha_archive.cc | 31 ++----- .../mysql-test/archive/discover.rdiff | 35 ++++++++ 16 files changed, 233 insertions(+), 101 deletions(-) create mode 100644 storage/test_sql_discovery/mysql-test/archive/discover.rdiff diff --git a/include/my_base.h b/include/my_base.h index f1b6825319c..0984ff8dfa9 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -318,7 +318,7 @@ enum ha_base_keytype { #define HA_OPTION_NULL_FIELDS 1024 #define HA_OPTION_PAGE_CHECKSUM 2048 /* .frm has extra create options in linked-list format */ -#define HA_OPTION_TEXT_CREATE_OPTIONS (1L << 14) +#define HA_OPTION_TEXT_CREATE_OPTIONS_legacy (1L << 14) /* 5.2 to 5.5, unused since 10.0 */ #define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */ #define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */ #define HA_OPTION_NO_CHECKSUM (1L << 17) diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index 287c2991c1d..a170cdfbd8c 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -12701,12 +12701,12 @@ CREATE TABLE t1(a INT, b BLOB) ENGINE=archive; SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DATA_LENGTH AVG_ROW_LENGTH -535 15 +550 15 INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2'); SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DATA_LENGTH AVG_ROW_LENGTH -569 284 +584 292 DROP TABLE t1; SET @save_join_buffer_size= @@join_buffer_size; SET @@join_buffer_size= 8192; @@ -12818,10 +12818,11 @@ select * from t1; a b flush tables; select * from t1; -a b -1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +ERROR HY000: Table 't1' is marked as crashed and should be repaired show warnings; Level Code Message +Warning 127 Got error 127 when reading table `test`.`t1` +Error 1194 Table 't1' is marked as crashed and should be repaired drop table t1; create temporary table t1 (a int) engine=archive; insert t1 values (1),(2),(3); diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 2acf8b9e6b5..1114eb4e89a 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1738,7 +1738,7 @@ select * from t1; # open the table to create the frm flush tables; # and close the table again --remove_file $MYSQLD_DATADIR/test/t1.ARZ copy_file std_data/t917689.ARZ $MYSQLD_DATADIR/test/t1.ARZ; -#--error ER_CRASHED_ON_USAGE +--error ER_CRASHED_ON_USAGE select * from t1; show warnings; drop table t1; diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index 8cae289733b..7ffaf30d4d2 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -17,6 +17,8 @@ select * from t1; a 1 2 +t1.ARZ +t1.frm # # show tables # @@ -28,10 +30,9 @@ show tables; Tables_in_test t1 t2 -select * from t1; -a -1 -2 +t1.ARZ +t2.ARZ +t2.frm # # show full tables # @@ -40,29 +41,27 @@ show full tables; Tables_in_test Table_type t1 BASE TABLE t2 BASE TABLE -select * from t1; -a -1 -2 +t1.ARZ +t2.ARZ +t2.frm # # discover on truncate # flush tables; truncate table t1; ERROR HY000: Table storage engine for 't1' doesn't have this option -show tables; -Tables_in_test -t1 -t2 +t1.ARZ +t1.frm +t2.ARZ +t2.frm # # discover on rename # flush tables; rename table t2 to t0; -show tables; -Tables_in_test -t0 -t1 +t0.ARZ +t1.ARZ +t1.frm # # discover on HA_ERR_TABLE_DEF_CHANGED # @@ -77,9 +76,7 @@ t1 CREATE TABLE `t1` ( # flush tables; drop table t1; -show tables; -Tables_in_test -t0 +t0.ARZ # # discover of table non-existance on drop # @@ -89,6 +86,9 @@ flush tables; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist drop table t0; +show status like 'Handler_discover'; +Variable_name Value +Handler_discover 7 # # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE # diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 7a588d4654d..75668baafbf 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -13,6 +13,7 @@ remove_file $mysqld_datadir/test/t1.frm; flush tables; insert t1 values (2); select * from t1; +--list_files $mysqld_datadir/test --echo # --echo # show tables @@ -22,24 +23,22 @@ select * from t2; remove_file $mysqld_datadir/test/t1.frm; flush tables; show tables; -select * from t1; +--list_files $mysqld_datadir/test --echo # --echo # show full tables --echo # -remove_file $mysqld_datadir/test/t1.frm; flush tables; show full tables; -select * from t1; +--list_files $mysqld_datadir/test --echo # --echo # discover on truncate --echo # -remove_file $mysqld_datadir/test/t1.frm; flush tables; --error ER_ILLEGAL_HA truncate table t1; -show tables; +--list_files $mysqld_datadir/test --echo # --echo # discover on rename @@ -47,7 +46,7 @@ show tables; remove_file $mysqld_datadir/test/t2.frm; flush tables; rename table t2 to t0; -show tables; +--list_files $mysqld_datadir/test --echo # --echo # discover on HA_ERR_TABLE_DEF_CHANGED @@ -63,7 +62,7 @@ show create table t1; remove_file $mysqld_datadir/test/t1.frm; flush tables; drop table t1; -show tables; +--list_files $mysqld_datadir/test --echo # --echo # discover of table non-existance on drop @@ -74,6 +73,8 @@ flush tables; --error ER_NO_SUCH_TABLE select * from t1; drop table t0; +--list_files $mysqld_datadir/test +show status like 'Handler_discover'; --echo # --echo # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE diff --git a/mysql-test/suite/archive/partition_archive.result b/mysql-test/suite/archive/partition_archive.result index 27ec5edb429..0ba50c38e8d 100644 --- a/mysql-test/suite/archive/partition_archive.result +++ b/mysql-test/suite/archive/partition_archive.result @@ -15,10 +15,10 @@ ENGINE = ARCHIVE; INSERT INTO t1 VALUES(CURRENT_DATE); SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; DATA_LENGTH INDEX_LENGTH -520 0 +535 0 SELECT DATA_LENGTH, INDEX_LENGTH FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; DATA_LENGTH INDEX_LENGTH -520 0 +535 0 DROP TABLE t1; drop database if exists db99; drop table if exists t1; diff --git a/mysys/my_uuid.c b/mysys/my_uuid.c index ab1b259ae0f..01c59e42f2e 100644 --- a/mysys/my_uuid.c +++ b/mysys/my_uuid.c @@ -123,7 +123,7 @@ void my_uuid_init(ulong seed1, ulong seed2) Create a global unique identifier (uuid) @func my_uuid() - @param to Store uuid here. Must be of size MY_uuid_SIZE (16) + @param to Store uuid here. Must be of size MY_UUID_SIZE (16) */ void my_uuid(uchar *to) diff --git a/sql/handler.h b/sql/handler.h index 8e4d59e7f7f..edbff4b68e1 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1360,6 +1360,7 @@ enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES }; struct HA_CREATE_INFO { CHARSET_INFO *table_charset, *default_table_charset; + LEX_CUSTRING tabledef_version; LEX_STRING connect_string; const char *password, *tablespace; LEX_STRING comment; @@ -1393,6 +1394,7 @@ struct HA_CREATE_INFO enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY enum ha_choice page_checksum; ///< If we have page_checksums engine_option_value *option_list; ///< list of table create options + /* the following three are only for ALTER TABLE, check_if_incompatible_data() */ ha_table_option_struct *option_struct; ///< structure with parsed table options ha_field_option_struct **fields_option_struct; ///< array of field option structures diff --git a/sql/table.cc b/sql/table.cc index d6b109a880a..ad1f8893e47 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008-2011 Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -706,7 +706,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, uint i,j; bool use_hash; char *keynames, *names, *comment_pos; - const uchar *forminfo; + const uchar *forminfo, *extra2; const uchar *frm_image_end = frm_image + frm_length; uchar *record, *null_flags, *null_pos; const uchar *disk_buff, *strpos; @@ -723,7 +723,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, bool null_bits_are_used; uint vcol_screen_length, UNINIT_VAR(options_len); char *vcol_screen_pos; - const uchar *UNINIT_VAR(options); + const uchar *options= 0; KEY first_keyinfo; uint len; KEY_PART_INFO *first_key_part= NULL; @@ -749,8 +749,60 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, new_frm_ver= (frm_image[2] - FRM_VER); field_pack_length= new_frm_ver < 2 ? 11 : 17; - /* Position of the form in the form file. */ + /* Length of the MariaDB extra2 segment in the form file. */ len = uint2korr(frm_image+4); + extra2= frm_image + 64; + + if (*extra2 != '/') // old frm had '/' there + { + const uchar *e2end= extra2 + len; + while (extra2 < e2end) + { + uchar type= *extra2++; + size_t length= *extra2++; + if (!length) + { + length= uint2korr(extra2); + extra2+=2; + if (length < 256) + goto err; + } + switch (type) { + case EXTRA2_TABLEDEF_VERSION: + if (tabledef_version.str) // see init_from_sql_statement_string() + { + if (length != tabledef_version.length || + memcmp(extra2, tabledef_version.str, length)) + goto err; + } + else + { + uchar *buf= (uchar*) alloc_root(&mem_root, length); + if (!buf) + goto err; + memcpy(buf, extra2, length); + tabledef_version.str= buf; + tabledef_version.length= length; + } + break; + case EXTRA2_ENGINE_TABLEOPTS: + if (options) + goto err; + /* remember but delay parsing until we have read fields and keys */ + options= extra2; + options_len= length; + break; + default: + /* abort frm parsing if it's an unknown but important extra2 value */ + if (type >= 128) + goto err; + } + extra2+= length; + } + if (extra2 > e2end) + goto err; + } + if (frm_length < FRM_HEADER_SIZE + len || !(pos= uint4korr(frm_image + FRM_HEADER_SIZE + len))) goto err; @@ -1169,12 +1221,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, DBUG_ASSERT(next_chunk <= buff_end); - if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS) + if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS_legacy) { - /* - store options position, but skip till the time we will - know number of fields - */ + if (options) + goto err; options_len= uint4korr(next_chunk); options= next_chunk + 4; next_chunk+= options_len + 4; @@ -1839,7 +1889,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, null_length, 255); } - if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS) + if (options) { DBUG_ASSERT(options_len); if (engine_table_options_frm_read(options, options_len, share)) @@ -2028,6 +2078,9 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, thd->lex->create_info.db_type= plugin_data(db_plugin, handlerton *); + if (tabledef_version.str) + thd->lex->create_info.tabledef_version= tabledef_version; + file= mysql_create_frm_image(thd, db.str, table_name.str, &thd->lex->create_info, &thd->lex->alter_info, 0, 0, &frm); @@ -3086,7 +3139,7 @@ void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, fileinfo[3]= (uchar) ha_legacy_type( ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0)); - int2store(fileinfo+4,3); + /* Keep in sync with pack_keys() in unireg.cc For each key: diff --git a/sql/table.h b/sql/table.h index a10617cc938..6d20706cd92 100644 --- a/sql/table.h +++ b/sql/table.h @@ -616,6 +616,8 @@ struct TABLE_SHARE I_P_List used_tables; I_P_List free_tables; + LEX_CUSTRING tabledef_version; + engine_option_value *option_list; /* text options for table */ ha_table_option_struct *option_struct; /* structure with parsed options */ diff --git a/sql/unireg.cc b/sql/unireg.cc index 588ed622a60..5da9f88132d 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2009, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -122,13 +123,6 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, create_fields, keys, key_info); DBUG_PRINT("info", ("Options length: %u", options_len)); - if (options_len) - { - create_info->table_options|= HA_OPTION_TEXT_CREATE_OPTIONS; - create_info->extra_size+= (options_len + 4); - } - else - create_info->table_options&= ~HA_OPTION_TEXT_CREATE_OPTIONS; /* This gives us the byte-position of the character at @@ -193,13 +187,31 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, forminfo[46]=(uchar) create_info->comment.length; } + if (!create_info->tabledef_version.str) + { + uchar *to= (uchar*) thd->alloc(MY_UUID_SIZE); + if (unlikely(!to)) + DBUG_RETURN(frm); + my_uuid(to); + create_info->tabledef_version.str= to; + create_info->tabledef_version.length= MY_UUID_SIZE; + } + DBUG_ASSERT(create_info->tabledef_version.length > 0); + DBUG_ASSERT(create_info->tabledef_version.length <= 255); + prepare_frm_header(thd, reclength, fileinfo, create_info, keys, key_info); + /* one byte for a type, one or three for a length */ + uint extra2_size= 1 + 1 + create_info->tabledef_version.length; + if (options_len) + extra2_size+= 1 + (options_len > 255 ? 3 : 1) + options_len; + key_buff_length= uint4korr(fileinfo+47); frm.length= FRM_HEADER_SIZE; // fileinfo; - frm.length+= uint2korr(fileinfo+4) + 4; // "form entry" + frm.length+= extra2_size + 4; // mariadb extra2 frm segment + int2store(fileinfo+4, extra2_size); int2store(fileinfo+6, frm.length); frm.length+= key_buff_length; frm.length+= reclength; // row with default values @@ -214,11 +226,34 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, if (!frm_ptr) DBUG_RETURN(frm); - pos = frm_ptr + uint2korr(fileinfo+6); - key_info_length= pack_keys(pos, keys, key_info, data_offset); + /* write the extra2 segment */ + pos = frm_ptr + 64; + *pos++ = EXTRA2_TABLEDEF_VERSION; + *pos++ = create_info->tabledef_version.length; + memcpy(pos, create_info->tabledef_version.str, + create_info->tabledef_version.length); + pos+= create_info->tabledef_version.length; - memcpy(frm_ptr + FRM_HEADER_SIZE, "//", 3); - int4store(frm_ptr + 67, filepos); + if (options_len) + { + *pos++= EXTRA2_ENGINE_TABLEOPTS; + if (options_len < 255) + *pos++= options_len; + else + { + DBUG_ASSERT(options_len <= 65535); // FIXME if necessary + int2store(pos + 1, options_len); + pos+= 3; + } + pos= engine_table_options_frm_image(pos, create_info->option_list, + create_fields, keys, key_info); + } + + int4store(pos, filepos); // end of the extra2 segment + pos+= 4; + + DBUG_ASSERT(pos == frm_ptr + uint2korr(fileinfo+6)); + key_info_length= pack_keys(pos, keys, key_info, data_offset); maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); int2store(forminfo+2,maxlength); @@ -285,19 +320,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, pos+= create_info->comment.length; } - if (options_len) - { - int4store(pos, options_len); - pos+= 4; - engine_table_options_frm_image(pos, - create_info->option_list, - create_fields, - keys, key_info); - pos+= options_len; - } - - memcpy(frm_ptr + filepos, forminfo, FRM_FORMINFO_SIZE); - if (pack_fields(frm_ptr + filepos + FRM_FORMINFO_SIZE, create_fields, data_offset)) + memcpy(frm_ptr + filepos, forminfo, 288); + if (pack_fields(frm_ptr + filepos + 288, create_fields, data_offset)) goto err; { @@ -332,14 +356,12 @@ err: SYNOPSIS rea_create_table() thd Thread handler + frm binary frm image of the table to create path Name of file (including database, without .frm) db Data base name table_name Table name create_info create info parameters - create_fields Fields to create - keys number of keys to create - key_info Keys to create - file Handler to use + file Handler to use or NULL if only frm needs to be created RETURN 0 ok diff --git a/sql/unireg.h b/sql/unireg.h index 89dae6b2e97..8fba6e5cfbe 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -167,6 +167,22 @@ #include "sql_list.h" /* List<> */ #include "field.h" /* Create_field */ +/* + Types of values in the MariaDB extra2 frm segment. + Each value is written as + type: 1 byte + length: 1 byte (1..255) or \0 and 2 bytes. + binary value of the 'length' bytes. + + Older MariaDB servers can ignore values of unknown types if + the type code is less than 128. Otherwise older servers are required + to report an error. +*/ +enum extra2_frm_value_type { + EXTRA2_TABLEDEF_VERSION=0, + EXTRA2_ENGINE_TABLEOPTS=128, +}; + int rea_create_table(THD *thd, LEX_CUSTRING *frm, const char *path, const char *db, const char *table_name, HA_CREATE_INFO *create_info, handler *file); diff --git a/storage/archive/azio.c b/storage/archive/azio.c index c6058af2e3d..4519d15cefc 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -364,6 +364,8 @@ void read_header(azio_stream *s, unsigned char *buffer) { if (buffer[0] == az_magic[0] && buffer[1] == az_magic[1]) { + uchar tmp[AZ_FRMVER_LEN + 2]; + s->version= (unsigned int)buffer[AZ_VERSION_POS]; s->minor_version= (unsigned int)buffer[AZ_MINOR_VERSION_POS]; s->block_size= 1024 * buffer[AZ_BLOCK_POS]; @@ -379,6 +381,22 @@ void read_header(azio_stream *s, unsigned char *buffer) s->comment_start_pos= (unsigned int)uint4korr(buffer + AZ_COMMENT_POS); s->comment_length= (unsigned int)uint4korr(buffer + AZ_COMMENT_LENGTH_POS); s->dirty= (unsigned int)buffer[AZ_DIRTY_POS]; + + /* + we'll hard-code the current frm format for now, to avoid + changing archive table versions. + */ + if (s->frm_length == 0 || + my_pread(s->file, tmp, sizeof(tmp), s->frm_start_pos + 64, MYF(MY_NABP)) || + tmp[0] != 0 || tmp[1] != AZ_FRMVER_LEN) + { + s->frmver_length= 0; + } + else + { + s->frmver_length= tmp[1]; + memcpy(s->frmver, tmp+2, s->frmver_length); + } } else if (buffer[0] == gz_magic[0] && buffer[1] == gz_magic[1]) { diff --git a/storage/archive/azlib.h b/storage/archive/azlib.h index 09f61afcd28..2971705b2f1 100644 --- a/storage/archive/azlib.h +++ b/storage/archive/azlib.h @@ -198,6 +198,7 @@ extern "C" { #define AZ_BUFSIZE_READ 32768 #define AZ_BUFSIZE_WRITE 16384 +#define AZ_FRMVER_LEN 16 /* same as MY_UUID_SIZE in 10.0.2 */ typedef struct azio_stream { z_stream stream; @@ -227,6 +228,8 @@ typedef struct azio_stream { unsigned char dirty; /* State of file */ unsigned int frm_start_pos; /* Position for start of FRM */ unsigned int frm_length; /* Position for start of FRM */ + unsigned char frmver[AZ_FRMVER_LEN]; + unsigned int frmver_length; unsigned int comment_start_pos; /* Position for start of comment */ unsigned int comment_length; /* Position for start of comment */ } azio_stream; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 515ebf8cf3d..9f164da3359 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -673,33 +673,12 @@ int ha_archive::frm_copy(azio_stream *src, azio_stream *dst) int ha_archive::frm_compare(azio_stream *s) { - int rc= 0; - const uchar *frm_ptr= 0; - uchar *azfrm_ptr= 0; - size_t frm_len; + if (!s->frmver_length) + return 0; // Old pre-10.0 archive table. Never rediscover. - /* no frm = no discovery. perhaps it's a partitioned table */ - if (table->s->read_frm_image(&frm_ptr, &frm_len)) - goto err; - - if (!(azfrm_ptr= (uchar *) my_malloc(s->frm_length, - MYF(MY_THREAD_SPECIFIC | MY_WME)))) - goto err; - - rc= 1; - - if (frm_len != s->frm_length) - goto err; - - if (azread_frm(s, azfrm_ptr)) - goto err; - - rc= memcmp(frm_ptr, azfrm_ptr, frm_len); - -err: - my_free(const_cast(frm_ptr)); - my_free(azfrm_ptr); - return rc; + LEX_CUSTRING *ver= &table->s->tabledef_version; + return ver->length != s->frmver_length || + memcmp(ver->str, s->frmver, ver->length); } diff --git a/storage/test_sql_discovery/mysql-test/archive/discover.rdiff b/storage/test_sql_discovery/mysql-test/archive/discover.rdiff new file mode 100644 index 00000000000..3148999079f --- /dev/null +++ b/storage/test_sql_discovery/mysql-test/archive/discover.rdiff @@ -0,0 +1,35 @@ +--- suite/archive/discover.result 2013-04-08 00:06:37.000000000 +0200 ++++ /usr/home/serg/Abk/mysql/10.0-serg/storage/test_sql_discovery/mysql-test/archive/discover.reject 2013-04-08 00:07:02.000000000 +0200 +@@ -42,6 +42,7 @@ + t1 BASE TABLE + t2 BASE TABLE + t1.ARZ ++t1.frm + t2.ARZ + t2.frm + # +@@ -60,6 +61,7 @@ + flush tables; + rename table t2 to t0; + t0.ARZ ++t0.frm + t1.ARZ + t1.frm + # +@@ -77,6 +79,7 @@ + flush tables; + drop table t1; + t0.ARZ ++t0.frm + # + # discover of table non-existance on drop + # +@@ -86,7 +89,7 @@ + drop table t0; + show status like 'Handler_discover'; + Variable_name Value +-Handler_discover 7 ++Handler_discover 8 + # + # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE + # From 336da6e2709dac5f065a14cebadeb2c97eaf1f47 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:37 +0200 Subject: [PATCH 62/87] cleanup --- sql/mysqld.cc | 2 +- sql/partition_info.cc | 29 +++++++++++------------ sql/sql_parse.cc | 34 ++++++++++++++++++++++++++- sql/sql_parse.h | 1 + sql/sql_table.cc | 53 ++++--------------------------------------- 5 files changed, 53 insertions(+), 66 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 19d01e61771..d8e603d3009 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8065,7 +8065,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr) global_system_variables.sql_mode= expand_sql_mode(global_system_variables.sql_mode); -#if defined(HAVE_BROKEN_REALPATH) +#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH) my_use_symdir=0; my_disable_symlinks=1; have_symlink=SHOW_OPTION_NO; diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 028afd7899e..934f4e970cb 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1582,29 +1582,21 @@ bool check_partition_dirs(partition_info *part_info) partition_element *subpart_elem; while ((subpart_elem= sub_it++)) { - if (test_if_data_home_dir(subpart_elem->data_file_name)) - goto dd_err; - if (test_if_data_home_dir(subpart_elem->index_file_name)) - goto id_err; + if (error_if_data_home_dir(subpart_elem->data_file_name, + "DATA DIRECTORY") || + error_if_data_home_dir(subpart_elem->index_file_name, + "INDEX DIRECTORY")) + return 1; } } else { - if (test_if_data_home_dir(part_elem->data_file_name)) - goto dd_err; - if (test_if_data_home_dir(part_elem->index_file_name)) - goto id_err; + if (error_if_data_home_dir(part_elem->data_file_name, "DATA DIRECTORY") || + error_if_data_home_dir(part_elem->index_file_name, "INDEX DIRECTORY")) + return 1; } } return 0; - -dd_err: - my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY"); - return 1; - -id_err: - my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY"); - return 1; } @@ -2286,4 +2278,9 @@ void partition_info::print_debug(const char *str, uint *value) { } +bool check_partition_dirs(partition_info *part_info) +{ + return 0; +} + #endif /* WITH_PARTITION_STORAGE_ENGINE */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e866d2b74ef..62e5a99f941 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7683,6 +7683,7 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg, return TRUE; } +C_MODE_START /* Check if path does not contain mysql data home directory @@ -7695,7 +7696,6 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg, 0 ok 1 error ; Given path contains data directory */ -C_MODE_START int test_if_data_home_dir(const char *dir) { @@ -7706,6 +7706,22 @@ int test_if_data_home_dir(const char *dir) if (!dir) DBUG_RETURN(0); + /* + data_file_name and index_file_name include the table name without + extension. Mostly this does not refer to an existing file. When + comparing data_file_name or index_file_name against the data + directory, we try to resolve all symbolic links. On some systems, + we use realpath(3) for the resolution. This returns ENOENT if the + resolved path does not refer to an existing file. my_realpath() + does then copy the requested path verbatim, without symlink + resolution. Thereafter the comparison can fail even if the + requested path is within the data directory. E.g. if symlinks to + another file system are used. To make realpath(3) return the + resolved path, we strip the table name and compare the directory + path only. If the directory doesn't exist either, table creation + will fail anyway. + */ + (void) fn_format(path, dir, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); dir_len= strlen(path); @@ -7739,6 +7755,22 @@ int test_if_data_home_dir(const char *dir) C_MODE_END +int error_if_data_home_dir(const char *path, const char *what) +{ + size_t dirlen; + char dirpath[FN_REFLEN]; + if (path) + { + dirname_part(dirpath, path, &dirlen); + if (test_if_data_home_dir(dirpath)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), what); + return 1; + } + } + return 0; +} + /** Check that host name string is valid. diff --git a/sql/sql_parse.h b/sql/sql_parse.h index 6d47e648be2..25c41cc624c 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -34,6 +34,7 @@ enum enum_mysql_completiontype { }; extern "C" int test_if_data_home_dir(const char *dir); +int error_if_data_home_dir(const char *path, const char *what); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8f2320b9b30..a8f071558bf 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4346,55 +4346,7 @@ bool mysql_create_table_no_lock(THD *thd, if (!file) goto err; -#ifdef HAVE_READLINK - { - size_t dirlen; - char dirpath[FN_REFLEN]; - - /* - data_file_name and index_file_name include the table name without - extension. Mostly this does not refer to an existing file. When - comparing data_file_name or index_file_name against the data - directory, we try to resolve all symbolic links. On some systems, - we use realpath(3) for the resolution. This returns ENOENT if the - resolved path does not refer to an existing file. my_realpath() - does then copy the requested path verbatim, without symlink - resolution. Thereafter the comparison can fail even if the - requested path is within the data directory. E.g. if symlinks to - another file system are used. To make realpath(3) return the - resolved path, we strip the table name and compare the directory - path only. If the directory doesn't exist either, table creation - will fail anyway. - */ - if (create_info->data_file_name) - { - dirname_part(dirpath, create_info->data_file_name, &dirlen); - if (test_if_data_home_dir(dirpath)) - { - my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY"); - goto err; - } - } - if (create_info->index_file_name) - { - dirname_part(dirpath, create_info->index_file_name, &dirlen); - if (test_if_data_home_dir(dirpath)) - { - my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY"); - goto err; - } - } - } - -#ifdef WITH_PARTITION_STORAGE_ENGINE - if (check_partition_dirs(thd->lex->part_info)) - { - goto err; - } -#endif /* WITH_PARTITION_STORAGE_ENGINE */ - if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)) -#endif /* HAVE_READLINK */ { if (create_info->data_file_name) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, @@ -4406,6 +4358,11 @@ bool mysql_create_table_no_lock(THD *thd, "INDEX DIRECTORY"); create_info->data_file_name= create_info->index_file_name= 0; } + else + if (error_if_data_home_dir(create_info->data_file_name, "DATA DIRECTORY") || + error_if_data_home_dir(create_info->index_file_name, "INDEX DIRECTORY")|| + check_partition_dirs(thd->lex->part_info)) + goto err; /* Check if table exists */ if (create_info->tmp_table()) From e71cda83c685a27a4ec4f9d3083fed3f44b22642 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:44 +0200 Subject: [PATCH 63/87] cleanup: merge two mutually dependent function arguments into one, eliminating reduncancy and a possibility of setting them to a pair of invalid values. --- sql/sql_insert.cc | 4 +-- sql/sql_table.cc | 79 ++++++++++++++++++++--------------------------- sql/sql_table.h | 41 ++++++++++++++++++++---- sql/table.cc | 4 +-- 4 files changed, 72 insertions(+), 56 deletions(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index efbf35fe575..844725c5da7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3895,8 +3895,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, { if (!mysql_create_table_no_lock(thd, create_table->db, create_table->table_name, - create_info, alter_info, 0, - select_field_count, NULL)) + create_info, alter_info, NULL, + select_field_count)) { DEBUG_SYNC(thd,"create_table_select_before_open"); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a8f071558bf..66285abebc3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab + Copyright (c) 2010, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -70,8 +70,7 @@ static int copy_data_between_tables(THD *thd, TABLE *,TABLE *, static bool prepare_blob_field(THD *thd, Create_field *sql_field); static bool check_engine(THD *, const char *, const char *, HA_CREATE_INFO *); static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *, - bool, uint *, handler *, KEY **, uint *, - int); + uint *, handler *, KEY **, uint *, int); /** @brief Helper function for explain_filename @@ -1671,14 +1670,10 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) strxmov(shadow_frm_name, shadow_path, reg_ext, NullS); if (flags & WFRM_WRITE_SHADOW) { - if (mysql_prepare_create_table(lpt->thd, lpt->create_info, - lpt->alter_info, - /*tmp_table*/ 1, - &lpt->db_options, - lpt->table->file, - &lpt->key_info_buffer, - &lpt->key_count, - /*select_field_count*/ 0)) + if (mysql_prepare_create_table(lpt->thd, lpt->create_info, lpt->alter_info, + &lpt->db_options, lpt->table->file, + &lpt->key_info_buffer, &lpt->key_count, + C_ALTER_TABLE)) { DBUG_RETURN(TRUE); } @@ -2907,12 +2902,12 @@ void promote_first_timestamp_column(List *column_definitions) thd Thread object. create_info Create information (like MAX_ROWS). alter_info List of columns and indexes to create - tmp_table If a temporary table is to be created. db_options INOUT Table options (like HA_OPTION_PACK_RECORD). file The handler for the new table. key_info_buffer OUT An array of KEY structs for the indexes. key_count OUT The number of elements in the array. - select_field_count The number of fields coming from a select table. + create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, + C_CREATE_SELECT DESCRIPTION Prepares the table and key structures for table creation. @@ -2927,11 +2922,9 @@ void promote_first_timestamp_column(List *column_definitions) static int mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - bool tmp_table, - uint *db_options, + Alter_info *alter_info, uint *db_options, handler *file, KEY **key_info_buffer, - uint *key_count, int select_field_count) + uint *key_count, int create_table_mode) { const char *key_name; Create_field *sql_field,*dup_field; @@ -2944,6 +2937,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, List_iterator it(alter_info->create_list); List_iterator it2(alter_info->create_list); uint total_uneven_bit_length= 0; + int select_field_count= C_CREATE_SELECT(create_table_mode); + bool tmp_table= create_table_mode == C_ALTER_TABLE; DBUG_ENTER("mysql_prepare_create_table"); select_field_pos= alter_info->create_list.elements - select_field_count; @@ -4074,16 +4069,14 @@ static bool check_if_created_table_can_be_opened(THD *thd, handler *mysql_create_frm_image(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - bool internal_tmp_table, - uint select_field_count, LEX_CUSTRING *frm) + Alter_info *alter_info, int create_table_mode, + LEX_CUSTRING *frm) { uint db_options, key_count; KEY *key_info_buffer; handler *file; DBUG_ENTER("mysql_create_frm_image"); - /* Check for duplicate fields and check type of table to create */ if (!alter_info->create_list.elements) { my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS), @@ -4267,10 +4260,9 @@ handler *mysql_create_frm_image(THD *thd, } #endif - if (mysql_prepare_create_table(thd, create_info, alter_info, - internal_tmp_table, &db_options, file, - &key_info_buffer, &key_count, - select_field_count)) + if (mysql_prepare_create_table(thd, create_info, alter_info, &db_options, + file, &key_info_buffer, &key_count, + create_table_mode)) goto err; create_info->table_options=db_options; @@ -4298,11 +4290,10 @@ err: create_info Create information (like MAX_ROWS) fields List of fields to create keys List of keys to create - internal_tmp_table Set to 1 if this is an internal temporary table - (From ALTER TABLE) - select_field_count is_trans identifies the type of engine where the table was created: either trans or non-trans. + create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, + or any positive number (for C_CREATE_SELECT). DESCRIPTION If one creates a temporary table, this is automatically opened @@ -4323,10 +4314,8 @@ err: bool mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - bool internal_tmp_table, - uint select_field_count, - bool *is_trans) + Alter_info *alter_info, bool *is_trans, + int create_table_mode) { char path[FN_REFLEN + 1]; uint path_length; @@ -4334,6 +4323,7 @@ bool mysql_create_table_no_lock(THD *thd, handler *file; LEX_CUSTRING frm= {0,0}; bool error= TRUE; + bool internal_tmp_table= create_table_mode == C_ALTER_TABLE; DBUG_ENTER("mysql_create_table_no_lock"); DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", db, table_name, internal_tmp_table)); @@ -4341,7 +4331,7 @@ bool mysql_create_table_no_lock(THD *thd, alias= table_case_name(create_info, table_name); file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info, - internal_tmp_table, select_field_count, &frm); + create_table_mode, &frm); if (!file) goto err; @@ -4490,7 +4480,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, promote_first_timestamp_column(&alter_info->create_list); result= mysql_create_table_no_lock(thd, create_table->db, create_table->table_name, create_info, - alter_info, FALSE, 0, &is_trans); + alter_info, &is_trans, C_ORDINARY_CREATE); /* Don't write statement if: @@ -4725,7 +4715,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, if ((res= mysql_create_table_no_lock(thd, table->db, table->table_name, &local_create_info, &local_alter_info, - FALSE, 0, &is_trans))) + &is_trans, C_ORDINARY_CREATE))) goto err; /* @@ -5017,12 +5007,11 @@ mysql_compare_tables(TABLE *table, *need_copy_table= ALTER_TABLE_DATA_CHANGED; /* Create the prepared information. */ - if (mysql_prepare_create_table(thd, create_info, - &tmp_alter_info, - (table->s->tmp_table != NO_TMP_TABLE), - &db_options, - table->file, key_info_buffer, - &key_count, 0)) + int create_table_mode= table->s->tmp_table == NO_TMP_TABLE ? + C_ORDINARY_CREATE : C_ALTER_TABLE; + if (mysql_prepare_create_table(thd, create_info, &tmp_alter_info, + &db_options, table->file, key_info_buffer, + &key_count, create_table_mode)) DBUG_RETURN(1); /* Allocate result buffers. */ if (! (*index_drop_buffer= @@ -6721,10 +6710,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, HA_OPTION_PACK_RECORD)); } tmp_disable_binlog(thd); - error= mysql_create_table_no_lock(thd, new_db, tmp_name, - create_info, - alter_info, - 1, 0, NULL); + error= mysql_create_table_no_lock(thd, new_db, tmp_name, create_info, + alter_info, NULL, C_ALTER_TABLE); reenable_binlog(thd); if (error) goto err; @@ -7391,11 +7378,11 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to, if (!(copy= new Copy_field[to->s->fields])) goto err; /* purecov: inspected */ + /* We need external lock before we can disable/enable keys */ if (to->file->ha_external_lock(thd, F_WRLCK)) goto err; errpos= 2; - /* We need external lock before we can disable/enable keys */ alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff); /* We can abort alter table for any table type */ diff --git a/sql/sql_table.h b/sql/sql_table.h index 016260b6b26..a15a9770b87 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. + Copyright (c) 2011, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -135,18 +136,46 @@ uint build_table_shadow_filename(char *buff, size_t bufflen, bool mysql_create_table(THD *thd, TABLE_LIST *create_table, HA_CREATE_INFO *create_info, Alter_info *alter_info); + +/* + mysql_create_table_no_lock can be called in one of the following + mutually exclusive situations: + + - Just a normal ordinary CREATE TABLE statement that explicitly + defines the table structure. + + - CREATE TABLE ... SELECT. It is special, because only in this case, + the list of fields is allowed to have duplicates, as long as one of the + duplicates comes from the select list, and the other doesn't. For + example in + + CREATE TABLE t1 (a int(5) NOT NUL) SELECT b+10 as a FROM t2; + + the list in alter_info->create_list will have two fields `a`. + + - ALTER TABLE, that creates a temporary table #sql-xxx, which will be later + renamed to replace the original table. + + These situations are distinguished by the following "create table mode" + values, where a CREATE ... SELECT is denoted by any non-negative number + (which should be the number of fields in the SELECT ... part), and other + cases use constants as defined below. +*/ +#define C_CREATE_SELECT(X) ((X) > 0 ? (X) : 0) +#define C_ORDINARY_CREATE 0 +#define C_ALTER_TABLE -1 + bool mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, - Alter_info *alter_info, - bool tmp_table, uint select_field_count, - bool *is_trans); + Alter_info *alter_info, bool *is_trans, + int create_table_mode); + handler *mysql_create_frm_image(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, Alter_info *alter_info, - bool internal_tmp_table, - uint select_field_count, LEX_CUSTRING *frm); + int create_table_mode, LEX_CUSTRING *frm); bool mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); diff --git a/sql/table.cc b/sql/table.cc index ad1f8893e47..c35e9b5dde0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab + Copyright (c) 2008, 2013, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2083,7 +2083,7 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, file= mysql_create_frm_image(thd, db.str, table_name.str, &thd->lex->create_info, &thd->lex->alter_info, - 0, 0, &frm); + C_ORDINARY_CREATE, &frm); error|= file == 0; delete file; From 37379ef0ed598ee553907d87bbf2a7dfcdbc34f1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:47 +0200 Subject: [PATCH 64/87] limit frm size, when reading it in memory --- sql/discover.cc | 2 +- sql/table.cc | 9 ++++++--- sql/unireg.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sql/discover.cc b/sql/discover.cc index a499e234a8f..5add741fc0c 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -70,7 +70,7 @@ int readfrm(const char *name, const uchar **frmdata, size_t *len) error= 2; if (mysql_file_fstat(file, &state, MYF(0))) goto err; - read_len= (size_t)state.st_size; + read_len= (size_t)min(FRM_MAX_SIZE, state.st_size); // safety // Read whole frm file error= 3; diff --git a/sql/table.cc b/sql/table.cc index c35e9b5dde0..b311d8cb0a6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -596,6 +596,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) uchar *buf; uchar head[FRM_HEADER_SIZE]; char path[FN_REFLEN]; + size_t frmlen; DBUG_ENTER("open_table_def"); DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, share->table_name.str, share->normalized_path.str)); @@ -642,13 +643,15 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) if (my_fstat(file, &stats, MYF(0))) goto err; - if (!(buf= (uchar*)my_malloc(stats.st_size, MYF(MY_THREAD_SPECIFIC|MY_WME)))) + frmlen= min(FRM_MAX_SIZE, stats.st_size); // safety + + if (!(buf= (uchar*)my_malloc(frmlen, MYF(MY_THREAD_SPECIFIC|MY_WME)))) goto err; memcpy(buf, head, sizeof(head)); if (mysql_file_read(file, buf + sizeof(head), - stats.st_size - sizeof(head), MYF(MY_NABP))) + frmlen - sizeof(head), MYF(MY_NABP))) { share->error = my_errno == HA_ERR_FILE_TOO_SHORT ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR; @@ -657,7 +660,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) } mysql_file_close(file, MYF(MY_WME)); - share->init_from_binary_frm_image(thd, false, buf, stats.st_size); + share->init_from_binary_frm_image(thd, false, buf, frmlen); error_given= true; // init_from_binary_frm_image has already called my_error() my_free(buf); diff --git a/sql/unireg.h b/sql/unireg.h index 8fba6e5cfbe..0ef69beb08a 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -193,6 +193,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, #define FRM_HEADER_SIZE 64 #define FRM_FORMINFO_SIZE 288 +#define FRM_MAX_SIZE (256*1024) static inline bool is_binary_frm_header(uchar *head) { From 9c089b04b37a37261a6b143a7f5be6502b7f7b26 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:51 +0200 Subject: [PATCH 65/87] TABLE_SHARE::free_frm_image() method to free the memory allocated by the same allocator as in TABLE_SHARE::read_frm_image() --- sql/table.cc | 7 +++++++ sql/table.h | 26 ++++++++++++++++++++++++++ storage/archive/ha_archive.cc | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/sql/table.cc b/sql/table.cc index b311d8cb0a6..909ee241dcd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2137,6 +2137,13 @@ bool TABLE_SHARE::read_frm_image(const uchar **frm, size_t *len) } +void TABLE_SHARE::free_frm_image(const uchar *frm) +{ + if (frm) + my_free(const_cast(frm)); +} + + /* @brief Clear GET_FIXED_FIELDS_FLAG in all fields of a table diff --git a/sql/table.h b/sql/table.h index 6d20706cd92..2d929bfc41b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -991,12 +991,38 @@ struct TABLE_SHARE uint actual_n_key_parts(THD *thd); LEX_CUSTRING *frm_image; ///< only during CREATE TABLE (@sa ha_create_table) + + /* + populates TABLE_SHARE from the table description in the binary frm image. + if 'write' is true, this frm image is also written into a corresponding + frm file, that serves as a persistent metadata cache to avoid + discovering the table over and over again + */ int init_from_binary_frm_image(THD *thd, bool write, const uchar *frm_image, size_t frm_length); + + /* + populates TABLE_SHARE from the table description, specified as the + complete CREATE TABLE sql statement. + if 'write' is true, this frm image is also written into a corresponding + frm file, that serves as a persistent metadata cache to avoid + discovering the table over and over again + */ int init_from_sql_statement_string(THD *thd, bool write, const char *sql, size_t sql_length); + /* + writes the frm image to an frm file, corresponding to this table + */ bool write_frm_image(const uchar *frm_image, size_t frm_length); + + /* + returns an frm image for this table. + the memory is allocated and must be freed later + */ bool read_frm_image(const uchar **frm_image, size_t *frm_length); + + /* frees the memory allocated in read_frm_image */ + void free_frm_image(const uchar *frm); }; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 9f164da3359..d18e46c08b1 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -764,7 +764,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, if (!table_arg->s->read_frm_image(&frm_ptr, &frm_len)) { azwrite_frm(&create_stream, frm_ptr, frm_len); - my_free(const_cast(frm_ptr)); + table_arg->s->free_frm_image(frm_ptr); } if (create_info->comment.str) From 0c4cf3c7e58973511975443e52fb232b3d940e4a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:56 +0200 Subject: [PATCH 66/87] small cleanup --- sql/sql_table.cc | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 66285abebc3..e5b047d31c9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4083,6 +4083,7 @@ handler *mysql_create_frm_image(THD *thd, MYF(0)); DBUG_RETURN(NULL); } + if (check_engine(thd, db, table_name, create_info)) DBUG_RETURN(NULL); @@ -4328,8 +4329,6 @@ bool mysql_create_table_no_lock(THD *thd, DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", db, table_name, internal_tmp_table)); - alias= table_case_name(create_info, table_name); - file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info, create_table_mode, &frm); @@ -4354,6 +4353,8 @@ bool mysql_create_table_no_lock(THD *thd, check_partition_dirs(thd->lex->part_info)) goto err; + alias= table_case_name(create_info, table_name); + /* Check if table exists */ if (create_info->tmp_table()) { @@ -4460,41 +4461,32 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, HA_CREATE_INFO *create_info, Alter_info *alter_info) { - bool result; + const char *db= create_table->db; + const char *table_name= create_table->table_name; bool is_trans= FALSE; DBUG_ENTER("mysql_create_table"); - /* - Open or obtain an exclusive metadata lock on table being created. - */ + /* Open or obtain an exclusive metadata lock on table being created */ if (open_and_lock_tables(thd, thd->lex->query_tables, FALSE, 0)) { /* is_error() may be 0 if table existed and we generated a warning */ - result= thd->is_error(); - goto end; + DBUG_RETURN(thd->is_error()); } /* Got lock. */ DEBUG_SYNC(thd, "locked_table_name"); promote_first_timestamp_column(&alter_info->create_list); - result= mysql_create_table_no_lock(thd, create_table->db, - create_table->table_name, create_info, - alter_info, &is_trans, C_ORDINARY_CREATE); + if (mysql_create_table_no_lock(thd, db, table_name, create_info, + alter_info, &is_trans, C_ORDINARY_CREATE)) + DBUG_RETURN(1); - /* - Don't write statement if: - - Table creation has failed - - Row-based logging is used and we are creating a temporary table - Otherwise, the statement shall be binlogged. - */ - if (!result && - (!thd->is_current_stmt_binlog_format_row() || - (thd->is_current_stmt_binlog_format_row() && - !(create_info->tmp_table())))) - result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans); + /* In RBR we don't need to log CREATE TEMPORARY TABLE */ + if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table()) + DBUG_RETURN(0); -end: + bool result; + result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans); DBUG_RETURN(result); } From a53200d4e7e1377784034d676c609d9b533e9fb7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:19:01 +0200 Subject: [PATCH 67/87] remove HA_CREATE_INFO::frm_only - it's internal server flag, not part of the SE API, and, again, mutually exclusive with C_ORDINARY_CREATE and C_CREATE_SELECT. --- sql/handler.h | 1 - sql/sql_table.cc | 26 +++++++++++++++----------- sql/sql_table.h | 5 +++++ sql/unireg.cc | 20 ++++++++++---------- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/sql/handler.h b/sql/handler.h index edbff4b68e1..d2dbe169101 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1389,7 +1389,6 @@ struct HA_CREATE_INFO uint merge_insert_method; uint extra_size; /* length of extra data segment */ enum ha_choice transactional; - bool frm_only; ///< 1 if no ha_create_table() bool varchar; ///< 1 if table has a VARCHAR enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY enum ha_choice page_checksum; ///< If we have page_checksums diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e5b047d31c9..46e9dff1833 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4090,7 +4090,7 @@ handler *mysql_create_frm_image(THD *thd, set_table_default_charset(thd, create_info, (char*) db); db_options= create_info->table_options; - if (!create_info->frm_only && + if (create_table_mode != C_ALTER_TABLE_FRM_ONLY && create_info->row_type != ROW_TYPE_FIXED && create_info->row_type != ROW_TYPE_DEFAULT) db_options|= HA_OPTION_PACK_RECORD; @@ -4324,7 +4324,8 @@ bool mysql_create_table_no_lock(THD *thd, handler *file; LEX_CUSTRING frm= {0,0}; bool error= TRUE; - bool internal_tmp_table= create_table_mode == C_ALTER_TABLE; + bool internal_tmp_table= create_table_mode == C_ALTER_TABLE || + create_table_mode == C_ALTER_TABLE_FRM_ONLY; DBUG_ENTER("mysql_create_table_no_lock"); DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", db, table_name, internal_tmp_table)); @@ -4385,7 +4386,8 @@ bool mysql_create_table_no_lock(THD *thd, thd_proc_info(thd, "creating table"); - if (rea_create_table(thd, &frm, path, db, table_name, create_info, file)) + if (rea_create_table(thd, &frm, path, db, table_name, create_info, + create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file)) goto err; if (create_info->tmp_table()) @@ -4409,7 +4411,7 @@ bool mysql_create_table_no_lock(THD *thd, thd->thread_specific_used= TRUE; } #ifdef WITH_PARTITION_STORAGE_ENGINE - else if (thd->work_part_info && create_info->frm_only) + else if (thd->work_part_info && create_table_mode == C_ALTER_TABLE_FRM_ONLY) { /* For partitioned tables we can't find some problems with table @@ -5944,7 +5946,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, TABLE *table, *new_table= 0; MDL_ticket *mdl_ticket; MDL_request target_mdl_request; - int error= 0; + int error= 0, create_table_mode= C_ALTER_TABLE; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; @@ -6615,10 +6617,11 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, char frm_name[FN_REFLEN+1]; strxmov(frm_name, path, reg_ext, NullS); /* - frm_only can only be used if old frm exists. + C_ALTER_TABLE_FRM_ONLY can only be used if old frm exists. discovering frm-less engines cannot enjoy this optimization. */ - create_info->frm_only= !my_access(frm_name, F_OK); + if (!my_access(frm_name, F_OK)) + create_table_mode= C_ALTER_TABLE_FRM_ONLY; } #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -6688,13 +6691,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, my_sleep(100000);); /* Create a table with a temporary name. - With create_info->frm_only == 1 this creates a .frm file only and + With C_ALTER_TABLE_FRM_ONLY this creates a .frm file only and we keep the original row format. We don't log the statement, it will be logged later. */ if (need_copy_table == ALTER_TABLE_METADATA_ONLY) { - DBUG_ASSERT(create_info->frm_only); + DBUG_ASSERT(create_table_mode == C_ALTER_TABLE_FRM_ONLY); /* Ensure we keep the original table format */ create_info->table_options= ((create_info->table_options & ~HA_OPTION_PACK_RECORD) | @@ -6703,7 +6706,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } tmp_disable_binlog(thd); error= mysql_create_table_no_lock(thd, new_db, tmp_name, create_info, - alter_info, NULL, C_ALTER_TABLE); + alter_info, NULL, create_table_mode); reenable_binlog(thd); if (error) goto err; @@ -7224,7 +7227,8 @@ err_new_table_cleanup: } else (void) quick_rm_table(new_db_type, new_db, tmp_name, - create_info->frm_only ? FN_IS_TMP | FRM_ONLY : FN_IS_TMP); + create_table_mode == C_ALTER_TABLE_FRM_ONLY ? + FN_IS_TMP | FRM_ONLY : FN_IS_TMP); err: #ifdef WITH_PARTITION_STORAGE_ENGINE diff --git a/sql/sql_table.h b/sql/sql_table.h index a15a9770b87..3bed73f67c3 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -156,6 +156,10 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, - ALTER TABLE, that creates a temporary table #sql-xxx, which will be later renamed to replace the original table. + - ALTER TABLE as above, but which only modifies the frm file, it only + creates an frm file for the #sql-xxx, the table in the engine is not + created. + These situations are distinguished by the following "create table mode" values, where a CREATE ... SELECT is denoted by any non-negative number (which should be the number of fields in the SELECT ... part), and other @@ -164,6 +168,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, #define C_CREATE_SELECT(X) ((X) > 0 ? (X) : 0) #define C_ORDINARY_CREATE 0 #define C_ALTER_TABLE -1 +#define C_ALTER_TABLE_FRM_ONLY -2 bool mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, diff --git a/sql/unireg.cc b/sql/unireg.cc index 5da9f88132d..811ee50e502 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -361,7 +361,7 @@ err: db Data base name table_name Table name create_info create info parameters - file Handler to use or NULL if only frm needs to be created + file Handler to use or NULL if only frm needs to be created RETURN 0 ok @@ -374,21 +374,16 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm, { DBUG_ENTER("rea_create_table"); - if (thd->variables.keep_files_on_create) - create_info->options|= HA_CREATE_KEEP_FILES; - - if (create_info->frm_only) - { - if (writefrm(path, db, table_name, 1, frm->str, frm->length)) - goto err_handler; - } - else + if (file) { // TODO don't write frm for temp tables if (create_info->tmp_table() && writefrm(path, db, table_name, 0, frm->str, frm->length)) goto err_handler; + if (thd->variables.keep_files_on_create) + create_info->options|= HA_CREATE_KEEP_FILES; + if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, create_info) || ha_create_table(thd, path, db, table_name, create_info, frm)) @@ -398,6 +393,11 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm, goto err_handler; } } + else + { + if (writefrm(path, db, table_name, 1, frm->str, frm->length)) + goto err_handler; + } DBUG_RETURN(0); From db7809e8172997a0e713a907f29072cc7ff750b4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:19:05 +0200 Subject: [PATCH 68/87] dead code, remove unused argument --- sql/ha_partition.cc | 3 +-- sql/ha_partition.h | 3 +-- sql/handler.cc | 4 ++-- sql/handler.h | 4 ++-- sql/sql_table.cc | 13 ++++++------- sql/unireg.cc | 6 ++---- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index efb3ceae51f..b28580b7831 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -529,8 +529,7 @@ int ha_partition::rename_table(const char *from, const char *to) int ha_partition::create_partitioning_metadata(const char *path, const char *old_path, - int action_flag, - HA_CREATE_INFO *create_info) + int action_flag) { DBUG_ENTER("ha_partition::create_partitioning_metadata()"); diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 4f753cf5a9e..01b77e3f092 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -239,8 +239,7 @@ public: virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); virtual int create_partitioning_metadata(const char *name, - const char *old_name, int action_flag, - HA_CREATE_INFO *create_info); + const char *old_name, int action_flag); virtual void update_create_info(HA_CREATE_INFO *create_info); virtual char *update_table_comment(const char *comment); virtual int change_partitions(HA_CREATE_INFO *create_info, diff --git a/sql/handler.cc b/sql/handler.cc index 735c2b012e6..b9480e8611d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3844,11 +3844,11 @@ handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info) int handler::ha_create_partitioning_metadata(const char *name, const char *old_name, - int action_flag, HA_CREATE_INFO *info) + int action_flag) { mark_trx_read_write(); - return create_partitioning_metadata(name, old_name, action_flag, info); + return create_partitioning_metadata(name, old_name, action_flag); } diff --git a/sql/handler.h b/sql/handler.h index d2dbe169101..3424fa22edf 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2067,7 +2067,7 @@ public: int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info); int ha_create_partitioning_metadata(const char *name, const char *old_name, - int action_flag, HA_CREATE_INFO *info); + int action_flag); int ha_change_partitions(HA_CREATE_INFO *create_info, const char *path, @@ -3007,7 +3007,7 @@ private: virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0; virtual int create_partitioning_metadata(const char *name, const char *old_name, - int action_flag, HA_CREATE_INFO *info) + int action_flag) { return FALSE; } virtual int change_partitions(HA_CREATE_INFO *create_info, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 46e9dff1833..4f1fdc2e0db 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1713,7 +1713,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) my_free(const_cast(frm.str)); if (error || lpt->table->file->ha_create_partitioning_metadata(shadow_path, - NULL, CHF_CREATE_FLAG, lpt->create_info)) + NULL, CHF_CREATE_FLAG)) { mysql_file_delete(key_file_frm, shadow_frm_name, MYF(0)); error= 1; @@ -1765,13 +1765,13 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) if (mysql_file_delete(key_file_frm, frm_name, MYF(MY_WME)) || #ifdef WITH_PARTITION_STORAGE_ENGINE lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, - CHF_DELETE_FLAG, NULL) || + CHF_DELETE_FLAG) || deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) || (sync_ddl_log(), FALSE) || mysql_file_rename(key_file_frm, shadow_frm_name, frm_name, MYF(MY_WME)) || lpt->table->file->ha_create_partitioning_metadata(path, shadow_path, - CHF_RENAME_FLAG, NULL)) + CHF_RENAME_FLAG)) #else mysql_file_rename(key_file_frm, shadow_frm_name, frm_name, MYF(MY_WME))) @@ -4048,7 +4048,7 @@ static bool check_if_created_table_can_be_opened(THD *thd, /* It is impossible to open definition of partitioned table without .par file. */ - if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, create_info)) + if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG)) return TRUE; init_tmp_table_share(thd, &share, db, 0, table_name, path); @@ -4060,7 +4060,7 @@ static bool check_if_created_table_can_be_opened(THD *thd, (void) closefrm(&table, 0); free_table_share(&share); - (void) file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, create_info); + (void) file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG); return result; } #endif @@ -7172,8 +7172,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* Tell the handler that a new frm file is in place. */ error= t_table_list->table->file->ha_create_partitioning_metadata(path, NULL, - CHF_INDEX_FLAG, - create_info); + CHF_INDEX_FLAG); DBUG_ASSERT(thd->open_tables == t_table_list->table); close_thread_table(thd, &thd->open_tables); diff --git a/sql/unireg.cc b/sql/unireg.cc index 811ee50e502..bb34c6e800b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -384,12 +384,10 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm, if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; - if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG, - create_info) || + if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG) || ha_create_table(thd, path, db, table_name, create_info, frm)) { - file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG, - create_info); + file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG); goto err_handler; } } From 60aed41222bd7d4b5e607e098f778ca7438f0416 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:19:10 +0200 Subject: [PATCH 69/87] fix internal plugin names --- storage/sequence/sequence.cc | 2 +- storage/test_sql_discovery/test_sql_discovery.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/sequence/sequence.cc b/storage/sequence/sequence.cc index 62915f68484..2349f7aae63 100644 --- a/storage/sequence/sequence.cc +++ b/storage/sequence/sequence.cc @@ -323,7 +323,7 @@ static int init(void *p) static struct st_mysql_storage_engine descriptor = { MYSQL_HANDLERTON_INTERFACE_VERSION }; -maria_declare_plugin(seq) +maria_declare_plugin(sequence) { MYSQL_STORAGE_ENGINE_PLUGIN, &descriptor, diff --git a/storage/test_sql_discovery/test_sql_discovery.cc b/storage/test_sql_discovery/test_sql_discovery.cc index 00d488e4ad6..33438035b8d 100644 --- a/storage/test_sql_discovery/test_sql_discovery.cc +++ b/storage/test_sql_discovery/test_sql_discovery.cc @@ -155,7 +155,7 @@ static int init(void *p) struct st_mysql_storage_engine descriptor = { MYSQL_HANDLERTON_INTERFACE_VERSION }; -maria_declare_plugin(tsd) +maria_declare_plugin(test_sql_discovery) { MYSQL_STORAGE_ENGINE_PLUGIN, &descriptor, From 32ee15d851f3099d401b28321a1ae46dd36ef8ef Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:19:14 +0200 Subject: [PATCH 70/87] Assisted discovery --- sql/handler.h | 20 ++++++++++++++ sql/sql_table.cc | 72 ++++++++++++++++++++++++++++++++++++++---------- sql/sql_table.h | 3 ++ 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/sql/handler.h b/sql/handler.h index 3424fa22edf..2290b8f37fd 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -634,6 +634,7 @@ enum enum_schema_tables }; struct TABLE_SHARE; +struct HA_CREATE_INFO; struct st_foreign_key_info; typedef struct st_foreign_key_info FOREIGN_KEY_INFO; typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len, @@ -1169,6 +1170,25 @@ struct handlerton int (*discover_table_existence)(handlerton *hton, const char *db, const char *table_name); + /* + This is the assisted table discovery method. Unlike the fully + automatic discovery as above, here a user is expected to issue an + explicit CREATE TABLE with the appropriate table attributes to + "assist" the discovery of a table. But this "discovering" CREATE TABLE + statement will not specify the table structure - the engine discovers + it using this method. For example, FederatedX uses it in + + CREATE TABLE t1 ENGINE=FEDERATED CONNECTION="mysql://foo/bar/t1"; + + Given a TABLE_SHARE discover_table_structure() fills it in with a correct + table structure using one of the TABLE_SHARE::init_from_* methods. + + Assisted discovery works independently from the automatic discover. + An engine is allowed to support only assisted discovery and not + support automatic one. Or vice versa. + */ + int (*discover_table_structure)(handlerton *hton, THD* thd, + TABLE_SHARE *share, HA_CREATE_INFO *info); }; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4f1fdc2e0db..09220a41983 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2907,7 +2907,7 @@ void promote_first_timestamp_column(List *column_definitions) key_info_buffer OUT An array of KEY structs for the indexes. key_count OUT The number of elements in the array. create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, - C_CREATE_SELECT + C_CREATE_SELECT, C_ASSISTED_DISCOVERY DESCRIPTION Prepares the table and key structures for table creation. @@ -4293,7 +4293,7 @@ err: keys List of keys to create is_trans identifies the type of engine where the table was created: either trans or non-trans. - create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, + create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE, C_ASSISTED_DISCOVERY or any positive number (for C_CREATE_SELECT). DESCRIPTION @@ -4321,7 +4321,7 @@ bool mysql_create_table_no_lock(THD *thd, char path[FN_REFLEN + 1]; uint path_length; const char *alias; - handler *file; + handler *file= 0; LEX_CUSTRING frm= {0,0}; bool error= TRUE; bool internal_tmp_table= create_table_mode == C_ALTER_TABLE || @@ -4330,12 +4330,6 @@ bool mysql_create_table_no_lock(THD *thd, DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", db, table_name, internal_tmp_table)); - file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info, - create_table_mode, &frm); - - if (!file) - goto err; - if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)) { if (create_info->data_file_name) @@ -4386,9 +4380,53 @@ bool mysql_create_table_no_lock(THD *thd, thd_proc_info(thd, "creating table"); - if (rea_create_table(thd, &frm, path, db, table_name, create_info, - create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file)) - goto err; + if (create_table_mode == C_ASSISTED_DISCOVERY) + { + /* check that it's used correctly */ + DBUG_ASSERT(alter_info->create_list.elements == 0); + DBUG_ASSERT(alter_info->key_list.elements == 0); + + TABLE_SHARE share; + handlerton *hton= create_info->db_type; + int ha_err; + Field *no_fields= 0; + + if (!hton->discover_table_structure) + { + my_error(ER_ILLEGAL_HA, MYF(0), table_name); + goto err; + } + + init_tmp_table_share(thd, &share, db, 0, table_name, path); + + /* prepare everything for discovery */ + share.field= &no_fields; + share.db_plugin= plugin_int_to_ref(hton2plugin[hton->slot]); + share.option_list= create_info->option_list; + share.connect_string= create_info->connect_string; + + if (parse_engine_table_options(thd, hton, &share)) + goto err; + + ha_err= hton->discover_table_structure(hton, thd, &share, create_info); + free_table_share(&share); + + if (ha_err) + { + my_error(ER_GET_ERRNO, MYF(0), ha_err); + goto err; + } + } + else + { + file= mysql_create_frm_image(thd, db, table_name, create_info, alter_info, + create_table_mode, &frm); + if (!file) + goto err; + if (rea_create_table(thd, &frm, path, db, table_name, create_info, + create_table_mode == C_ALTER_TABLE_FRM_ONLY ? 0 : file)) + goto err; + } if (create_info->tmp_table()) { @@ -4466,6 +4504,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, const char *db= create_table->db; const char *table_name= create_table->table_name; bool is_trans= FALSE; + int create_table_mode; DBUG_ENTER("mysql_create_table"); /* Open or obtain an exclusive metadata lock on table being created */ @@ -4478,9 +4517,14 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, /* Got lock. */ DEBUG_SYNC(thd, "locked_table_name"); + if (alter_info->create_list.elements || alter_info->key_list.elements) + create_table_mode= C_ORDINARY_CREATE; + else + create_table_mode= C_ASSISTED_DISCOVERY; + promote_first_timestamp_column(&alter_info->create_list); - if (mysql_create_table_no_lock(thd, db, table_name, create_info, - alter_info, &is_trans, C_ORDINARY_CREATE)) + if (mysql_create_table_no_lock(thd, db, table_name, create_info, alter_info, + &is_trans, create_table_mode)) DBUG_RETURN(1); /* In RBR we don't need to log CREATE TEMPORARY TABLE */ diff --git a/sql/sql_table.h b/sql/sql_table.h index 3bed73f67c3..8bc6865decd 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -160,6 +160,8 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, creates an frm file for the #sql-xxx, the table in the engine is not created. + - Assisted discovery, CREATE TABLE statement without the table structure. + These situations are distinguished by the following "create table mode" values, where a CREATE ... SELECT is denoted by any non-negative number (which should be the number of fields in the SELECT ... part), and other @@ -169,6 +171,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, #define C_ORDINARY_CREATE 0 #define C_ALTER_TABLE -1 #define C_ALTER_TABLE_FRM_ONLY -2 +#define C_ASSISTED_DISCOVERY -3 bool mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, From ee92b2114d4b46e09f32821cb7667de47fcc6390 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:19:18 +0200 Subject: [PATCH 71/87] assisted discovery in federatedx --- .../suite/federated/assisted_discovery.result | 37 +++++++ .../suite/federated/assisted_discovery.test | 34 ++++++ sql/table.cc | 4 + storage/federatedx/ha_federatedx.cc | 103 +++++++++++++++--- storage/federatedx/ha_federatedx.h | 2 + 5 files changed, 162 insertions(+), 18 deletions(-) create mode 100644 mysql-test/suite/federated/assisted_discovery.result create mode 100644 mysql-test/suite/federated/assisted_discovery.test diff --git a/mysql-test/suite/federated/assisted_discovery.result b/mysql-test/suite/federated/assisted_discovery.result new file mode 100644 index 00000000000..7a351b9df6f --- /dev/null +++ b/mysql-test/suite/federated/assisted_discovery.result @@ -0,0 +1,37 @@ +CREATE DATABASE federated; +CREATE DATABASE federated; +CREATE TABLE t1 ( +`id` int(20) primary key, +`group` int NOT NULL default 1, +`a\\b` int NOT NULL default 2, +`a\\` int unsigned, +`name` varchar(32) default 'name') +DEFAULT CHARSET=latin1; +CREATE TABLE t1 ENGINE=FEDERATED +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(20) NOT NULL, + `group` int(11) NOT NULL DEFAULT '1', + `a\\b` int(11) NOT NULL DEFAULT '2', + `a\\` int(10) unsigned DEFAULT NULL, + `name` varchar(32) DEFAULT 'name', + PRIMARY KEY (`id`) +) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' +INSERT INTO t1 (id, name) VALUES (1, 'foo'); +INSERT INTO t1 (id, name) VALUES (2, 'fee'); +SELECT * FROM t1; +id group a\\b a\\ name +1 1 2 NULL foo +2 1 2 NULL fee +DROP TABLE t1; +SELECT * FROM t1; +id group a\\b a\\ name +1 1 2 NULL foo +2 1 2 NULL fee +DROP TABLE t1; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; +DROP TABLE IF EXISTS federated.t1; +DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/assisted_discovery.test b/mysql-test/suite/federated/assisted_discovery.test new file mode 100644 index 00000000000..9f3abe74ecc --- /dev/null +++ b/mysql-test/suite/federated/assisted_discovery.test @@ -0,0 +1,34 @@ +source include/federated.inc; +source have_federatedx.inc; + +connection slave; + +CREATE TABLE t1 ( + `id` int(20) primary key, + `group` int NOT NULL default 1, + `a\\b` int NOT NULL default 2, + `a\\` int unsigned, + `name` varchar(32) default 'name') + DEFAULT CHARSET=latin1; + +connection master; + +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; + +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +INSERT INTO t1 (id, name) VALUES (1, 'foo'); +INSERT INTO t1 (id, name) VALUES (2, 'fee'); +--sorted_result +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +--sorted_result +SELECT * FROM t1; +DROP TABLE t1; + +source include/federated_cleanup.inc; + diff --git a/sql/table.cc b/sql/table.cc index 909ee241dcd..f927b3febce 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2091,7 +2091,11 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, delete file; if (frm.str) + { + option_list= 0; // cleanup existing options ... + option_struct= 0; // ... if it's an assisted discovery error= init_from_binary_frm_image(thd, write, frm.str, frm.length); + } ret: my_free(const_cast(frm.str)); diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 1d298cf283d..81b57034e66 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -426,6 +426,7 @@ int federatedx_db_init(void *p) federatedx_hton->savepoint_release= ha_federatedx::savepoint_release; federatedx_hton->commit= ha_federatedx::commit; federatedx_hton->rollback= ha_federatedx::rollback; + federatedx_hton->discover_table_structure= ha_federatedx::discover_assisted; federatedx_hton->create= federatedx_create_handler; federatedx_hton->flags= HTON_ALTER_NOT_SUPPORTED; @@ -516,15 +517,16 @@ err: } -static int parse_url_error(FEDERATEDX_SHARE *share, TABLE *table, int error_num) +static int parse_url_error(FEDERATEDX_SHARE *share, TABLE_SHARE *table_s, + int error_num) { char buf[FEDERATEDX_QUERY_BUFFER_SIZE]; int buf_len; DBUG_ENTER("ha_federatedx parse_url_error"); - buf_len= min(table->s->connect_string.length, + buf_len= min(table_s->connect_string.length, FEDERATEDX_QUERY_BUFFER_SIZE-1); - strmake(buf, table->s->connect_string.str, buf_len); + strmake(buf, table_s->connect_string.str, buf_len); my_error(error_num, MYF(0), buf); DBUG_RETURN(error_num); } @@ -646,8 +648,8 @@ error: */ -static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table, - uint table_create_flag) +static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, + TABLE_SHARE *table_s, uint table_create_flag) { uint error_num= (table_create_flag ? ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE : @@ -657,11 +659,11 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table, share->port= 0; share->socket= 0; DBUG_PRINT("info", ("share at %lx", (long unsigned int) share)); - DBUG_PRINT("info", ("Length: %u", (uint) table->s->connect_string.length)); - DBUG_PRINT("info", ("String: '%.*s'", (int) table->s->connect_string.length, - table->s->connect_string.str)); - share->connection_string= strmake_root(mem_root, table->s->connect_string.str, - table->s->connect_string.length); + DBUG_PRINT("info", ("Length: %u", (uint) table_s->connect_string.length)); + DBUG_PRINT("info", ("String: '%.*s'", (int) table_s->connect_string.length, + table_s->connect_string.str)); + share->connection_string= strmake_root(mem_root, table_s->connect_string.str, + table_s->connect_string.length); DBUG_PRINT("info",("parse_url alloced share->connection_string %lx", (long unsigned int) share->connection_string)); @@ -714,9 +716,9 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table, Connection specifies everything but, resort to expecting remote and foreign table names to match */ - share->table_name= strmake_root(mem_root, table->s->table_name.str, + share->table_name= strmake_root(mem_root, table_s->table_name.str, (share->table_name_length= - table->s->table_name.length)); + table_s->table_name.length)); DBUG_PRINT("info", ("internal format, default table_name " "share->connection_string: %s share->table_name: %s", @@ -730,7 +732,7 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table, { share->parsed= TRUE; // Add a null for later termination of table name - share->connection_string[table->s->connect_string.length]= 0; + share->connection_string[table_s->connect_string.length]= 0; share->scheme= share->connection_string; DBUG_PRINT("info",("parse_url alloced share->scheme: %lx", (ulong) share->scheme)); @@ -817,7 +819,7 @@ static int parse_url(MEM_ROOT *mem_root, FEDERATEDX_SHARE *share, TABLE *table, DBUG_RETURN(0); error: - DBUG_RETURN(parse_url_error(share, table, error_num)); + DBUG_RETURN(parse_url_error(share, table_s, error_num)); } /***************************************************************************** @@ -1583,7 +1585,7 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table) tmp_share.share_key= table_name; tmp_share.share_key_length= strlen(table_name); - if (parse_url(&mem_root, &tmp_share, table, 0)) + if (parse_url(&mem_root, &tmp_share, table->s, 0)) goto error; /* TODO: change tmp_share.scheme to LEX_STRING object */ @@ -3350,7 +3352,7 @@ int ha_federatedx::create(const char *name, TABLE *table_arg, federatedx_io *tmp_io= NULL; DBUG_ENTER("ha_federatedx::create"); - if ((retval= parse_url(thd->mem_root, &tmp_share, table_arg, 1))) + if ((retval= parse_url(thd->mem_root, &tmp_share, table_arg->s, 1))) goto error; /* loopback socket connections hang due to LOCK_open mutex */ @@ -3572,6 +3574,71 @@ int ha_federatedx::rollback(handlerton *hton, MYSQL_THD thd, bool all) DBUG_RETURN(return_val); } + +/* + Federated supports assisted discovery, like + CREATE TABLE t1 CONNECTION="mysql://joe:pass@192.168.1.111/federated/t1"; + but not a fully automatic discovery where a table magically appear + on any use (like, on SELECT * from t1). +*/ +int ha_federatedx::discover_assisted(handlerton *hton, THD* thd, + TABLE_SHARE *table_s, HA_CREATE_INFO *info) +{ + int error= HA_ERR_NO_CONNECTION; + FEDERATEDX_SHARE tmp_share; + CHARSET_INFO *cs= system_charset_info; + MYSQL mysql; + char buf[1024]; + String query(buf, sizeof(buf), cs); + MYSQL_RES *res; + MYSQL_ROW rdata; + ulong *rlen; + + if (parse_url(thd->mem_root, &tmp_share, table_s, 1)) + return HA_WRONG_CREATE_OPTION; + + mysql_init(&mysql); + mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, cs->csname); + + if (!mysql_real_connect(&mysql, tmp_share.hostname, tmp_share.username, + tmp_share.password, tmp_share.database, + tmp_share.port, tmp_share.socket, 0)) + goto err1; + + if (mysql_real_query(&mysql, STRING_WITH_LEN("SET SQL_MODE=NO_TABLE_OPTIONS"))) + goto err1; + + query.copy(STRING_WITH_LEN("SHOW CREATE TABLE "), cs); + append_ident(&query, tmp_share.table_name, + tmp_share.table_name_length, ident_quote_char); + + if (mysql_real_query(&mysql, query.ptr(), query.length())) + goto err1; + + if (!((res= mysql_store_result(&mysql)))) + goto err1; + + if (!(rdata= mysql_fetch_row(res)) || !((rlen= mysql_fetch_lengths(res)))) + goto err2; + + query.copy(rdata[1], rlen[1], cs); + query.append(STRING_WITH_LEN(" CONNECTION=\""), cs); + query.append(table_s->connect_string.str, table_s->connect_string.length, cs); + query.append('"'); + + error= table_s->init_from_sql_statement_string(thd, true, + query.ptr(), query.length()); + +err2: + mysql_free_result(res); +err1: + if (error) + my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), mysql_error(&mysql)); + mysql_close(&mysql); + return error; +} + + struct st_mysql_storage_engine federatedx_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; @@ -3585,10 +3652,10 @@ maria_declare_plugin(federatedx) PLUGIN_LICENSE_GPL, federatedx_db_init, /* Plugin Init */ federatedx_done, /* Plugin Deinit */ - 0x0200 /* 2.0 */, + 0x0201 /* 2.1 */, NULL, /* status variables */ NULL, /* system variables */ - "2.0", /* string version */ + "2.1", /* string version */ MariaDB_PLUGIN_MATURITY_BETA /* maturity */ } maria_declare_plugin_end; diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 66eb4061ec3..44c20b6703a 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -297,6 +297,8 @@ private: static int savepoint_release(handlerton *hton, MYSQL_THD thd, void *sv); static int commit(handlerton *hton, MYSQL_THD thd, bool all); static int rollback(handlerton *hton, MYSQL_THD thd, bool all); + static int discover_assisted(handlerton *, THD*, TABLE_SHARE *, + HA_CREATE_INFO *); bool append_stmt_insert(String *query); From 3a8e1a2205b6e4147a484c598d59f01a9c8b720b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:19:22 +0200 Subject: [PATCH 72/87] mysql-test fixes --- mysql-test/r/lowercase_table2.result | 2 +- mysql-test/r/partition_disabled.result | 2 +- mysql-test/t/mysqld--help.test | 8 ++++---- mysql-test/t/sp-destruct.test | 3 --- storage/sequence/mysql-test/sequence/inc.opt | 1 + .../mysql-test/main/r/partition_disabled.rdiff | 11 ----------- .../mysql-test/sql_discovery/inc.opt | 1 + 7 files changed, 8 insertions(+), 20 deletions(-) delete mode 100644 storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result index c478d792e52..ac368a06bc9 100644 --- a/mysql-test/r/lowercase_table2.result +++ b/mysql-test/r/lowercase_table2.result @@ -272,7 +272,7 @@ Database Table In_use Name_locked test t_bug44738_uppercase 0 0 # So attempt to create table with the same name should fail. create table t_bug44738_UPPERCASE (i int); -ERROR HY000: Can't find file: 't_bug44738_uppercase' (errno: 2 "No such file or directory") +ERROR HY000: Can't find file: './test/t_bug44738_uppercase.MYI' (errno: 2 "No such file or directory") # And should succeed after FLUSH TABLES. flush tables; create table t_bug44738_UPPERCASE (i int); diff --git a/mysql-test/r/partition_disabled.result b/mysql-test/r/partition_disabled.result index 2978a3b6d2e..505bec79610 100644 --- a/mysql-test/r/partition_disabled.result +++ b/mysql-test/r/partition_disabled.result @@ -3,7 +3,7 @@ FLUSH TABLES; SELECT * FROM t1; ERROR HY000: The MariaDB server is running with the --skip-partition option so it cannot execute this statement TRUNCATE TABLE t1; -ERROR 42S02: Table 'test.t1' doesn't exist +ERROR HY000: The MariaDB server is running with the --skip-partition option so it cannot execute this statement ANALYZE TABLE t1; Table Op Msg_type Msg_text test.t1 analyze Error The MariaDB server is running with the --skip-partition option so it cannot execute this statement diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index 84d1fe85ec8..33bb50537ca 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -24,10 +24,10 @@ perl; # Plugins which may or may not be there: @plugins=qw/innodb ndb archive blackhole federated partition ndbcluster - feedback debug temp-pool ssl des-key-file - xtradb thread-concurrency super-large-pages - mutex-deadlock-detector null-audit maria aria pbxt oqgraph - sphinx thread-handling query-cache-info/; + feedback debug temp-pool ssl des-key-file xtradb sequence + thread-concurrency super-large-pages mutex-deadlock-detector + null-audit aria pbxt oqgraph sphinx thread-handling + test-sql-discovery query-cache-info/; # And substitute the content some environment variables with their # names: diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test index 75eeda8e289..f5d1dd57dfb 100644 --- a/mysql-test/t/sp-destruct.test +++ b/mysql-test/t/sp-destruct.test @@ -7,9 +7,6 @@ # In the case of trouble you might want to skip this. # -# embedded server returns different paths in error messages -# in lines like 'call bug14233();' -# mysqltest should be fixed to allow REPLACE_RESULT in error message -- source include/not_embedded.inc # Supress warnings written to the log file diff --git a/storage/sequence/mysql-test/sequence/inc.opt b/storage/sequence/mysql-test/sequence/inc.opt index ad178af67c2..5b96925ff59 100644 --- a/storage/sequence/mysql-test/sequence/inc.opt +++ b/storage/sequence/mysql-test/sequence/inc.opt @@ -1 +1,2 @@ --plugin-load=$HA_SEQUENCE_SO +--loose-sequence diff --git a/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff b/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff deleted file mode 100644 index 3bb52b39d29..00000000000 --- a/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.rdiff +++ /dev/null @@ -1,11 +0,0 @@ ---- r/partition_disabled.result 2013-04-07 12:36:57.000000000 +0200 -+++ /usr/home/serg/Abk/mysql/10.0-serg/storage/test_sql_discovery/mysql-test/main/r/partition_disabled.reject 2013-04-07 23:19:14.000000000 +0200 -@@ -3,7 +3,7 @@ - SELECT * FROM t1; - ERROR HY000: The MariaDB server is running with the --skip-partition option so it cannot execute this statement - TRUNCATE TABLE t1; --ERROR 42S02: Table 'test.t1' doesn't exist -+ERROR HY000: The MariaDB server is running with the --skip-partition option so it cannot execute this statement - ANALYZE TABLE t1; - Table Op Msg_type Msg_text - test.t1 analyze Error The MariaDB server is running with the --skip-partition option so it cannot execute this statement diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt b/storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt index 32a5e3a294e..7d5c2404a50 100644 --- a/storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt +++ b/storage/test_sql_discovery/mysql-test/sql_discovery/inc.opt @@ -1 +1,2 @@ --plugin-load=$HA_TEST_SQL_DISCOVERY_SO +--loose-test-sql-discovery From 050d7d6d75cbeb2f048dd0786c702452d2d7c18f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:20:48 +0200 Subject: [PATCH 73/87] optimize discovery for cases when the storage engine is known in advance --- sql/handler.cc | 13 ++++++++++--- sql/sql_base.cc | 6 +++++- sql/sql_base.h | 4 ++-- sql/sql_partition.cc | 2 +- sql/sql_table.cc | 11 +++++++---- sql/sql_truncate.cc | 2 +- sql/table.cc | 9 ++++----- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index b9480e8611d..f890c2c8324 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4162,6 +4162,8 @@ int ha_create_table(THD *thd, const char *path, else { // open an frm file + share.db_plugin= ha_lock_engine(thd, create_info->db_type); + if (open_table_def(thd, &share)) goto err; } @@ -4343,12 +4345,17 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, int ha_discover_table(THD *thd, TABLE_SHARE *share) { DBUG_ENTER("ha_discover_table"); + int found; DBUG_ASSERT(share->error == OPEN_FRM_OPEN_ERROR); // share is not OK yet - DBUG_ASSERT(!share->db_plugin); - if (!plugin_foreach(thd, discover_handlerton, - MYSQL_STORAGE_ENGINE_PLUGIN, share)) + if (share->db_plugin) + found= discover_handlerton(thd, share->db_plugin, share); + else + found= plugin_foreach(thd, discover_handlerton, + MYSQL_STORAGE_ENGINE_PLUGIN, share); + + if (!found) open_table_error(share, OPEN_FRM_OPEN_ERROR, ENOENT); // not found DBUG_RETURN(share->error != OPEN_FRM_OK); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 15eab7f32df..72a9e69b042 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5908,6 +5908,8 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, the opened TABLE instance will be addded to THD::temporary_tables list. @param thd Thread context. + @param hton Storage engine of the table, if known, + or NULL otherwise. @param path Path (without .frm) @param db Database name. @param table_name Table name. @@ -5923,7 +5925,8 @@ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, @retval NULL on error. */ -TABLE *open_table_uncached(THD *thd, const char *path, const char *db, +TABLE *open_table_uncached(THD *thd, handlerton *hton, + const char *path, const char *db, const char *table_name, bool add_to_temporary_tables_list) { @@ -5953,6 +5956,7 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db, init_tmp_table_share(thd, share, saved_cache_key, key_length, strend(saved_cache_key)+1, tmp_path); + share->db_plugin= ha_lock_engine(thd, hton); if (open_table_def(thd, share, GTS_TABLE | GTS_FORCE_DISCOVERY) || open_table_from_share(thd, share, table_name, diff --git a/sql/sql_base.h b/sql/sql_base.h index fc95ecb0119..95d9bf21fe8 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -195,8 +195,8 @@ bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias, bool get_key_map_from_key_list(key_map *map, TABLE *table, List *index_list); -TABLE *open_table_uncached(THD *thd, const char *path, const char *db, - const char *table_name, +TABLE *open_table_uncached(THD *thd, handlerton *hton, const char *path, + const char *db, const char *table_name, bool add_to_temporary_tables_list); TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name); TABLE *find_write_locked_table(TABLE *list, const char *db, diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index ecd8315b80d..b2e2016b47d 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -4536,7 +4536,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, */ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, MDL_INTENTION_EXCLUSIVE)); - new_table= open_table_uncached(thd, path, db, table_name, 0); + new_table= open_table_uncached(thd, old_db_type, path, db, table_name, 0); if (!new_table) DBUG_RETURN(TRUE); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 09220a41983..8862fcc7d0e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2303,7 +2303,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, Let's lock the plugin till the end of the statement. */ if (table_type && table_type != view_pseudo_hton) - plugin_lock(thd, plugin_int_to_ref(hton2plugin[table_type->slot])); + ha_lock_engine(thd, table_type); if (thd->locked_tables_mode) { @@ -4052,6 +4052,7 @@ static bool check_if_created_table_can_be_opened(THD *thd, return TRUE; init_tmp_table_share(thd, &share, db, 0, table_name, path); + share.db_plugin= ha_lock_engine(thd, file->ht); result= (open_table_def(thd, &share) || open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, @@ -4401,7 +4402,7 @@ bool mysql_create_table_no_lock(THD *thd, /* prepare everything for discovery */ share.field= &no_fields; - share.db_plugin= plugin_int_to_ref(hton2plugin[hton->slot]); + share.db_plugin= ha_lock_engine(thd, hton); share.option_list= create_info->option_list; share.connect_string= create_info->connect_string; @@ -4435,7 +4436,8 @@ bool mysql_create_table_no_lock(THD *thd, THD::temporary_tables list. */ - TABLE *table= open_table_uncached(thd, path, db, table_name, TRUE); + TABLE *table= open_table_uncached(thd, create_info->db_type, path, + db, table_name, TRUE); if (!table) { @@ -6779,7 +6781,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, build_table_filename(path, sizeof(path) - 1, new_db, tmp_name, "", FN_IS_TMP); /* Open our intermediate table. */ - new_table= open_table_uncached(thd, path, new_db, tmp_name, TRUE); + new_table= open_table_uncached(thd, new_db_type, path, + new_db, tmp_name, TRUE); } if (!new_table) goto err_new_table_cleanup; diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 92c4d150433..19ce553f5ce 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -269,7 +269,7 @@ static bool recreate_temporary_table(THD *thd, TABLE *table) dd_recreate_table(thd, share->db.str, share->table_name.str, share->normalized_path.str); - if (open_table_uncached(thd, share->path.str, share->db.str, + if (open_table_uncached(thd, table_type, share->path.str, share->db.str, share->table_name.str, TRUE)) { error= FALSE; diff --git a/sql/table.cc b/sql/table.cc index f927b3febce..ccb763847d6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1101,10 +1101,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name); if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, se_plugin)) { - if (legacy_db_type > DB_TYPE_UNKNOWN && - legacy_db_type < DB_TYPE_FIRST_DYNAMIC && - legacy_db_type != ha_legacy_type( - plugin_data(tmp_plugin, handlerton *))) + if (se_plugin) { /* bad file, legacy_db_type did not match the name */ goto err; @@ -1236,6 +1233,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } share->key_block_size= uint2korr(frm_image+62); + if (share->db_plugin && !plugin_equals(share->db_plugin, se_plugin)) + goto err; // wrong engine (someone changed the frm under our feet?) + extra_rec_buf_length= uint2korr(frm_image+59); rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length); share->rec_buff_length= rec_buff_length; @@ -1955,7 +1955,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, (void) my_hash_check(&share->name_hash); #endif - DBUG_ASSERT(!share->db_plugin || plugin_equals(share->db_plugin, se_plugin)); share->db_plugin= se_plugin; share->error= OPEN_FRM_OK; thd->status_var.opened_shares++; From 7ec57f2279b984d071b2c5c24261ee479e1caefc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:20:54 +0200 Subject: [PATCH 74/87] add sequence and sql_discovery suites to the default list. implement ./mtr --dry-run --- mysql-test/mysql-test-run.pl | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index def3cba672c..ea2ebfe4d38 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -208,6 +208,8 @@ our @opt_mysqld_envs; my $opt_stress; +my $opt_dry_run; + my $opt_compress; my $opt_ssl; my $opt_skip_ssl; @@ -347,7 +349,7 @@ my $exe_ndb_mgm; our %mysqld_variables; our @optional_plugins; -my $source_dist= 0; +my $source_dist= -d "../sql"; my $opt_max_save_core= env_or_val(MTR_MAX_SAVE_CORE => 5); my $opt_max_save_datadir= env_or_val(MTR_MAX_SAVE_DATADIR => 20); @@ -375,6 +377,8 @@ sub main { # directly before it executes them, like "make test-force-pl" in RPM builds. mtr_report("Logging: $0 ", join(" ", @ARGV)); + $DEFAULT_SUITES.=",sequence,sql_discovery" if $source_dist; + command_line_setup(); # --help will not reach here, so now it's safe to assume we have binaries @@ -420,6 +424,14 @@ sub main { my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases, \@opt_skip_test_list); mark_time_used('collect'); + if ($opt_dry_run) + { + for (@$tests) { + print $_->fullname(), "\n"; + } + exit 0; + } + if ( $opt_report_features ) { # Put "report features" as the first test to run my $tinfo = My::Test->new @@ -1237,6 +1249,7 @@ sub command_line_setup { 'report-times' => \$opt_report_times, 'result-file' => \$opt_resfile, 'stress=s' => \$opt_stress, + 'dry-run' => \$opt_dry_run, 'help|h' => \$opt_usage, # list-options is internal, not listed in help @@ -1255,11 +1268,6 @@ sub command_line_setup { report_option('verbose', $opt_verbose); } - if ( -d "../sql" ) - { - $source_dist= 1; - } - # Find the absolute path to the test directory $glob_mysql_test_dir= cwd(); if ($glob_mysql_test_dir =~ / /) @@ -6295,6 +6303,8 @@ Options to control what engine/variation to run all generated configs combination= Use at least twice to run tests with specified options to mysqld + dry-run Don't run any tests, print the list of tests + that were selected for execution Options to control directories to use tmpdir=DIR The directory where temporary files are stored From ffbd15eb3242ab9b003c025925a462b5bd24a761 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:20:59 +0200 Subject: [PATCH 75/87] post-review comments and other minor edits --- include/mysql_com.h | 2 +- sql/discover.cc | 10 ++++-- sql/discover.h | 2 +- sql/share/errmsg-utf8.txt | 6 ++-- sql/sql_table.cc | 8 ++--- sql/table.cc | 41 ++++++++++----------- sql/table.h | 6 ---- sql/unireg.cc | 55 +++++++++++++++-------------- sql/unireg.h | 6 +++- storage/federatedx/ha_federatedx.cc | 7 ++-- 10 files changed, 75 insertions(+), 68 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 5697fc952ce..9ba17b416c4 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -41,7 +41,7 @@ /* Maximum length of comments */ -#define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 6.0: 60 characters */ +#define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 5.5: 60 characters */ #define TABLE_COMMENT_MAXLEN 2048 #define COLUMN_COMMENT_MAXLEN 1024 #define INDEX_COMMENT_MAXLEN 1024 diff --git a/sql/discover.cc b/sql/discover.cc index 5add741fc0c..b5bccf7dcb0 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -111,17 +111,21 @@ int readfrm(const char *name, const uchar **frmdata, size_t *len) */ int writefrm(const char *path, const char *db, const char *table, - bool need_sync, const uchar *frmdata, size_t len) + bool tmp_table, const uchar *frmdata, size_t len) { char file_name[FN_REFLEN+1]; int error; + int create_flags= O_RDWR | O_TRUNC; DBUG_ENTER("writefrm"); DBUG_PRINT("enter",("name: '%s' len: %lu ",path, (ulong) len)); + if (tmp_table) + create_flags|= O_EXCL | O_NOFOLLOW; + strxnmov(file_name, sizeof(file_name)-1, path, reg_ext, NullS); File file= mysql_file_create(key_file_frm, file_name, - CREATE_MODE, O_RDWR | O_TRUNC, MYF(0)); + CREATE_MODE, create_flags, MYF(0)); if ((error= file < 0)) { @@ -134,7 +138,7 @@ int writefrm(const char *path, const char *db, const char *table, { error= mysql_file_write(file, frmdata, len, MYF(MY_WME | MY_NABP)); - if (!error && need_sync && opt_sync_frm) + if (!error && !tmp_table && opt_sync_frm) error= mysql_file_sync(file, MYF(MY_WME)) || my_sync_dir_by_file(file_name, MYF(MY_WME)); diff --git a/sql/discover.h b/sql/discover.h index aad8bb734ec..fbf94891c74 100644 --- a/sql/discover.h +++ b/sql/discover.h @@ -24,7 +24,7 @@ int extension_based_table_discovery(MY_DIR *dirp, const char *ext, #ifdef MYSQL_SERVER int readfrm(const char *name, const uchar **data, size_t *length); int writefrm(const char *path, const char *db, const char *table, - bool need_sync, const uchar *frmdata, size_t len); + bool tmp_table, const uchar *frmdata, size_t len); int ext_table_discovery_simple(MY_DIR *dirp, handlerton::discovered_list *result); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 036d4a0258c..6a7eafc5fc4 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6192,9 +6192,9 @@ ER_TOO_LONG_TABLE_COMMENT por "Comentário para a tabela '%-.64s' é longo demais (max = %u)" ger "Kommentar für Tabelle '%-.64s' ist zu lang (max = %u)" ER_TOO_LONG_FIELD_COMMENT - eng "Comment for field '%-.64s' is too long (max = %lu)" - por "Comentário para o campo '%-.64s' é longo demais (max = %lu)" - ger "Kommentar für Feld '%-.64s' ist zu lang (max = %lu)" + eng "Comment for field '%-.64s' is too long (max = %u)" + por "Comentário para o campo '%-.64s' é longo demais (max = %u)" + ger "Kommentar für Feld '%-.64s' ist zu lang (max = %u)" ER_FUNC_INEXISTENT_NAME_COLLISION 42000 eng "FUNCTION %s does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual" ger "FUNCTION %s existiert nicht. Erläuterungen im Abschnitt 'Function Name Parsing and Resolution' im Referenzhandbuch" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8862fcc7d0e..eb02e9f2baf 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1709,7 +1709,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) } int error= writefrm(shadow_path, lpt->db, lpt->table_name, - !lpt->create_info->tmp_table(), frm.str, frm.length); + lpt->create_info->tmp_table(), frm.str, frm.length); my_free(const_cast(frm.str)); if (error || lpt->table->file->ha_create_partitioning_metadata(shadow_path, @@ -1751,7 +1751,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) */ build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); - strxmov(frm_name, path, reg_ext, NullS); + strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS); /* When we are changing to use new frm file we need to ensure that we don't collide with another thread in process to open the frm file. @@ -4467,7 +4467,7 @@ bool mysql_create_table_no_lock(THD *thd, create_info, file)) { char frm_name[FN_REFLEN]; - strxmov(frm_name, path, reg_ext, NullS); + strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS); (void) mysql_file_delete(key_file_frm, frm_name, MYF(0)); goto err; } @@ -6661,7 +6661,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (need_copy_table == ALTER_TABLE_METADATA_ONLY) { char frm_name[FN_REFLEN+1]; - strxmov(frm_name, path, reg_ext, NullS); + strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS); /* C_ALTER_TABLE_FRM_ONLY can only be used if old frm exists. discovering frm-less engines cannot enjoy this optimization. diff --git a/sql/table.cc b/sql/table.cc index ccb763847d6..faa087cbaa4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -592,11 +592,10 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) { bool error_given= false; File file; - MY_STAT stats; uchar *buf; uchar head[FRM_HEADER_SIZE]; char path[FN_REFLEN]; - size_t frmlen; + size_t frmlen, read_length; DBUG_ENTER("open_table_def"); DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s'", share->db.str, share->table_name.str, share->normalized_path.str)); @@ -640,26 +639,26 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) goto err; } - if (my_fstat(file, &stats, MYF(0))) - goto err; - - frmlen= min(FRM_MAX_SIZE, stats.st_size); // safety + frmlen= uint4korr(head+10); + set_if_smaller(frmlen, FRM_MAX_SIZE); // safety if (!(buf= (uchar*)my_malloc(frmlen, MYF(MY_THREAD_SPECIFIC|MY_WME)))) goto err; memcpy(buf, head, sizeof(head)); - if (mysql_file_read(file, buf + sizeof(head), - frmlen - sizeof(head), MYF(MY_NABP))) + read_length= mysql_file_read(file, buf + sizeof(head), + frmlen - sizeof(head), MYF(MY_WME)); + if (read_length == 0 || read_length == (size_t)-1) { - share->error = my_errno == HA_ERR_FILE_TOO_SHORT - ? OPEN_FRM_CORRUPTED : OPEN_FRM_READ_ERROR; + share->error = OPEN_FRM_READ_ERROR; my_free(buf); goto err; } mysql_file_close(file, MYF(MY_WME)); + frmlen= read_length + sizeof(head); + share->init_from_binary_frm_image(thd, false, buf, frmlen); error_given= true; // init_from_binary_frm_image has already called my_error() my_free(buf); @@ -759,17 +758,21 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (*extra2 != '/') // old frm had '/' there { const uchar *e2end= extra2 + len; - while (extra2 < e2end) + while (extra2 + 3 < e2end) { uchar type= *extra2++; size_t length= *extra2++; if (!length) { + if (extra2 + 258 >= e2end) + goto err; length= uint2korr(extra2); extra2+=2; if (length < 256) goto err; } + if (extra2 + length > e2end) + goto err; switch (type) { case EXTRA2_TABLEDEF_VERSION: if (tabledef_version.str) // see init_from_sql_statement_string() @@ -780,12 +783,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } else { - uchar *buf= (uchar*) alloc_root(&mem_root, length); - if (!buf) - goto err; - memcpy(buf, extra2, length); - tabledef_version.str= buf; tabledef_version.length= length; + tabledef_version.str= (uchar*)memdup_root(&mem_root, extra2, length); + if (!tabledef_version.str) + goto err; } break; case EXTRA2_ENGINE_TABLEOPTS: @@ -797,12 +798,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, break; default: /* abort frm parsing if it's an unknown but important extra2 value */ - if (type >= 128) + if (type >= EXTRA2_ENGINE_IMPORTANT) goto err; } extra2+= length; } - if (extra2 > e2end) + if (extra2 != e2end) goto err; } @@ -2116,7 +2117,7 @@ ret: bool TABLE_SHARE::write_frm_image(const uchar *frm, size_t len) { - return writefrm(normalized_path.str, db.str, table_name.str, 1, frm, len); + return writefrm(normalized_path.str, db.str, table_name.str, false, frm, len); } @@ -3242,7 +3243,7 @@ rename_file_ext(const char * from,const char * to,const char * ext) char from_b[FN_REFLEN],to_b[FN_REFLEN]; (void) strxmov(from_b,from,ext,NullS); (void) strxmov(to_b,to,ext,NullS); - return (mysql_file_rename(key_file_frm, from_b, to_b, MYF(0))); + return mysql_file_rename(key_file_frm, from_b, to_b, MYF(0)); } diff --git a/sql/table.h b/sql/table.h index 2d929bfc41b..fa5bd83371a 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2539,12 +2539,6 @@ static inline int set_zone(int nr,int min_zone,int max_zone) return nr; } -/* Adjust number to next larger disk buffer */ -static inline ulong next_io_size(ulong pos) -{ - return MY_ALIGN(pos, IO_SIZE); -} - /* performance schema */ extern LEX_STRING PERFORMANCE_SCHEMA_DB_NAME; diff --git a/sql/unireg.cc b/sql/unireg.cc index bb34c6e800b..0940b34308f 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -67,7 +67,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, uint keys, KEY *key_info, handler *db_file) { LEX_STRING str_db_type; - uint reclength, key_info_length, maxlength, tmp_len, i; + uint reclength, key_info_length, tmp_len, i; ulong key_buff_length; ulong filepos, data_offset; uint options_len; @@ -173,7 +173,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, /* If table comment is longer than TABLE_COMMENT_INLINE_MAXLEN bytes, store the comment in an extra segment (up to TABLE_COMMENT_MAXLEN bytes). - Pre 6.0, the limit was 60 characters, with no extra segment-handling. + Pre 5.5, the limit was 60 characters, with no extra segment-handling. */ if (create_info->comment.length > TABLE_COMMENT_INLINE_MAXLEN) { @@ -212,7 +212,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, frm.length+= extra2_size + 4; // mariadb extra2 frm segment int2store(fileinfo+4, extra2_size); - int2store(fileinfo+6, frm.length); + int2store(fileinfo+6, frm.length); // Position to key information frm.length+= key_buff_length; frm.length+= reclength; // row with default values frm.length+= create_info->extra_size; @@ -228,7 +228,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, /* write the extra2 segment */ pos = frm_ptr + 64; - *pos++ = EXTRA2_TABLEDEF_VERSION; + compile_time_assert(EXTRA2_TABLEDEF_VERSION != '/'); + *pos++ = EXTRA2_TABLEDEF_VERSION; // old servers write '/' here *pos++ = create_info->tabledef_version.length; memcpy(pos, create_info->tabledef_version.str, create_info->tabledef_version.length); @@ -241,7 +242,11 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, *pos++= options_len; else { - DBUG_ASSERT(options_len <= 65535); // FIXME if necessary + /* + At the moment we support options_len up to 64K. + We can easily extend it in the future, if the need arises. + */ + DBUG_ASSERT(options_len <= 65535); int2store(pos + 1, options_len); pos+= 3; } @@ -255,9 +260,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, DBUG_ASSERT(pos == frm_ptr + uint2korr(fileinfo+6)); key_info_length= pack_keys(pos, keys, key_info, data_offset); - maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); - int2store(forminfo+2,maxlength); - int4store(fileinfo+10,(ulong) (filepos+maxlength)); + int2store(forminfo+2, frm.length - filepos); + int4store(fileinfo+10, frm.length); fileinfo[26]= (uchar) test((create_info->max_rows == 1) && (create_info->min_rows == 1) && (keys == 0)); int2store(fileinfo+28,key_info_length); @@ -312,7 +316,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table, pos+= key_info[i].parser_name->length + 1; } } - if (forminfo[46] == (uchar)255) + if (forminfo[46] == (uchar)255) // New style MySQL 5.5 table comment { int2store(pos, create_info->comment.length); pos+=2; @@ -378,7 +382,7 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm, { // TODO don't write frm for temp tables if (create_info->tmp_table() && - writefrm(path, db, table_name, 0, frm->str, frm->length)) + writefrm(path, db, table_name, true, frm->str, frm->length)) goto err_handler; if (thd->variables.keep_files_on_create) @@ -393,7 +397,7 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm, } else { - if (writefrm(path, db, table_name, 1, frm->str, frm->length)) + if (writefrm(path, db, table_name, false, frm->str, frm->length)) goto err_handler; } @@ -524,19 +528,18 @@ static bool pack_header(uchar *forminfo, List &create_fields, COLUMN_COMMENT_MAXLEN); if (tmp_len < field->comment.length) { - if ((current_thd->variables.sql_mode & - (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) - { - my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), field->field_name, - static_cast(COLUMN_COMMENT_MAXLEN)); + myf myf_warning= ME_JUST_WARNING; + ulonglong sql_mode= current_thd->variables.sql_mode; + + if (sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)) + myf_warning= 0; + + my_error(ER_TOO_LONG_FIELD_COMMENT, myf_warning, field->field_name, + COLUMN_COMMENT_MAXLEN); + + if (!myf_warning) DBUG_RETURN(1); - } - char warn_buff[MYSQL_ERRMSG_SIZE]; - my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_FIELD_COMMENT), - field->field_name, - static_cast(COLUMN_COMMENT_MAXLEN)); - push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_FIELD_COMMENT, warn_buff); + field->comment.length= tmp_len; } if (field->vcol_info) @@ -562,7 +565,7 @@ static bool pack_header(uchar *forminfo, List &create_fields, expressions saved in the frm file for virtual columns. */ vcol_info_length+= field->vcol_info->expr_str.length+ - FRM_VCOL_HEADER_SIZE(field->interval!=NULL); + FRM_VCOL_HEADER_SIZE(field->interval); } totlength+= field->length; @@ -890,10 +893,10 @@ static bool pack_fields(uchar *buff, List &create_fields, */ if (field->vcol_info && field->vcol_info->expr_str.length) { - *buff++= (uchar)(1 + test(field->interval_id)); + *buff++= (uchar)(1 + test(field->interval)); *buff++= (uchar) field->sql_type; *buff++= (uchar) field->stored_in_db; - if (field->interval_id) + if (field->interval) *buff++= (uchar) field->interval_id; memcpy(buff, field->vcol_info->expr_str.str, field->vcol_info->expr_str.length); buff+= field->vcol_info->expr_str.length; diff --git a/sql/unireg.h b/sql/unireg.h index 0ef69beb08a..5e232becbb2 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -175,11 +175,15 @@ binary value of the 'length' bytes. Older MariaDB servers can ignore values of unknown types if - the type code is less than 128. Otherwise older servers are required + the type code is less than 128 (EXTRA2_ENGINE_IMPORTANT). + Otherwise older (but newer than 10.0.1) servers are required to report an error. */ enum extra2_frm_value_type { EXTRA2_TABLEDEF_VERSION=0, + +#define EXTRA2_ENGINE_IMPORTANT 128 + EXTRA2_ENGINE_TABLEOPTS=128, }; diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 81b57034e66..2f84cdf5c45 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -3622,9 +3622,10 @@ int ha_federatedx::discover_assisted(handlerton *hton, THD* thd, goto err2; query.copy(rdata[1], rlen[1], cs); - query.append(STRING_WITH_LEN(" CONNECTION=\""), cs); - query.append(table_s->connect_string.str, table_s->connect_string.length, cs); - query.append('"'); + query.append(STRING_WITH_LEN(" CONNECTION='"), cs); + query.append_for_single_quote(table_s->connect_string.str, + table_s->connect_string.length); + query.append('\''); error= table_s->init_from_sql_statement_string(thd, true, query.ptr(), query.length()); From 3ad01d00f2eaef56ed06041f7ac26328e998155b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:07 +0200 Subject: [PATCH 76/87] error messages: name the storage engine explicitly, instead of "used storage engine" and similar changes. --- mysql-test/r/alter_table.result | 2 +- mysql-test/r/alter_table_trans.result | 2 +- mysql-test/r/create.result | 4 +- mysql-test/r/innodb_mysql_sync.result | 4 +- mysql-test/r/log_tables.result | 2 +- mysql-test/r/merge.result | 4 +- mysql-test/r/myisam.result | 2 +- mysql-test/r/partition_innodb_plugin.result | 2 +- mysql-test/r/partition_not_windows.result | 2 +- mysql-test/suite/archive/archive.result | 6 +- mysql-test/suite/archive/discover.result | 2 +- .../suite/archive/partition_archive.result | 1 + .../suite/archive/partition_archive.test | 3 +- mysql-test/suite/csv/csv.result | 2 +- .../suite/federated/federated_archive.result | 4 +- mysql-test/suite/federated/federatedx.result | 2 +- mysql-test/suite/handler/aria.result | 2 +- mysql-test/suite/handler/heap.result | 12 +- mysql-test/suite/handler/innodb.result | 2 +- mysql-test/suite/handler/interface.result | 2 +- mysql-test/suite/handler/myisam.result | 2 +- .../innodb/r/innodb-create-options.result | 120 ++++---- mysql-test/suite/innodb/r/innodb-index.result | 10 +- mysql-test/suite/innodb/r/innodb-zip.result | 84 +++--- mysql-test/suite/innodb/r/innodb.result | 6 +- .../suite/innodb/r/innodb_bug12400341.result | 2 +- .../suite/innodb/r/innodb_bug46000.result | 2 +- mysql-test/suite/innodb/r/innodb_gis.result | 2 +- .../suite/innodb/t/innodb-create-options.test | 76 ++--- mysql-test/suite/innodb/t/innodb-index.test | 10 +- mysql-test/suite/maria/maria.result | 2 +- mysql-test/suite/maria/maria3.result | 2 +- .../percona_innodb_fake_changes.result | 2 +- mysql-test/suite/perfschema/r/misc.result | 4 +- .../suite/perfschema/r/privilege.result | 32 +- mysql-test/t/partition_not_windows.test | 2 +- sql/discover.cc | 2 +- sql/handler.cc | 26 +- sql/item_func.cc | 2 +- sql/lock.cc | 18 +- sql/share/errmsg-utf8.txt | 282 +++++++----------- sql/sql_handler.cc | 6 +- sql/sql_plugin.cc | 2 +- sql/sql_table.cc | 82 +++-- storage/innobase/handler/handler0alter.cc | 2 + storage/pbxt/src/discover_xt.cc | 3 +- .../mysql-test/sequence/simple.result | 2 +- storage/sphinx/ha_sphinx.cc | 3 +- .../mysql-test/sql_discovery/simple.result | 24 +- storage/xtradb/handler/handler0alter.cc | 2 + 50 files changed, 398 insertions(+), 478 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 6b2f064d209..92b9d86365d 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -415,7 +415,7 @@ alter table t1 drop key a; drop table t1; CREATE TABLE T12207(a int) ENGINE=MYISAM; ALTER TABLE T12207 DISCARD TABLESPACE; -ERROR HY000: Table storage engine for 'T12207' doesn't have this option +ERROR HY000: Storage engine MyISAM of the table `test`.`T12207` doesn't have this option DROP TABLE T12207; create table t1 (a text) character set koi8r; insert into t1 values (_koi8r'ÔÅÓÔ'); diff --git a/mysql-test/r/alter_table_trans.result b/mysql-test/r/alter_table_trans.result index 3dd5c00d3d8..6e034e47e76 100644 --- a/mysql-test/r/alter_table_trans.result +++ b/mysql-test/r/alter_table_trans.result @@ -2,5 +2,5 @@ drop table if exists t1,t2; CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb; ALTER TABLE t1 RENAME TO t2, DISABLE KEYS; Warnings: -Note 1031 Table storage engine for 't1' doesn't have this option +Note 1031 Storage engine InnoDB of the table `test`.`t1` doesn't have this option DROP TABLE t2; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index bb3b672858a..7e814283d32 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -31,9 +31,9 @@ Warnings: Note 1051 Unknown table 't1' Note 1051 Unknown table 't2' create table t1 (b char(0) not null, index(b)); -ERROR 42000: The used storage engine can't index column 'b' +ERROR 42000: The storage engine MyISAM can't index column `b` create table t1 (a int not null,b text) engine=heap; -ERROR 42000: The used table type doesn't support BLOB/TEXT columns +ERROR 42000: Storage engine MEMORY doesn't support BLOB/TEXT columns drop table if exists t1; Warnings: Note 1051 Unknown table 't1' diff --git a/mysql-test/r/innodb_mysql_sync.result b/mysql-test/r/innodb_mysql_sync.result index 044e582ceb6..7c41ffec344 100644 --- a/mysql-test/r/innodb_mysql_sync.result +++ b/mysql-test/r/innodb_mysql_sync.result @@ -18,10 +18,10 @@ SET DEBUG_SYNC='now SIGNAL table_altered'; # Complete optimization Table Op Msg_type Msg_text test.t1 optimize note Table does not support optimize, doing recreate + analyze instead -test.t1 optimize error Got error -1 "Internal error < 0 (Not system error)" from storage engine +test.t1 optimize error Got error -1 "Internal error < 0 (Not system error)" from storage engine MEMORY test.t1 optimize status Operation failed Warnings: -Error 1030 Got error -1 "Internal error < 0 (Not system error)" from storage engine +Error 1030 Got error -1 "Internal error < 0 (Not system error)" from storage engine MEMORY DROP TABLE t1; SET DEBUG_SYNC='RESET'; # diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index dd3bee0ac88..d03540c9c27 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -251,7 +251,7 @@ alter table mysql.slow_log engine=NonExistentEngine; Warnings: Warning 1286 Unknown storage engine 'NonExistentEngine' alter table mysql.slow_log engine=memory; -ERROR HY000: This storage engine cannot be used for log tables +ERROR HY000: Storage engine MEMORY cannot be used for log tables set storage_engine= @save_storage_engine; drop table mysql.slow_log; drop table mysql.general_log; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 83a4caac919..5c4261e7d6d 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2257,7 +2257,7 @@ CREATE TABLE m1(a int)engine=merge union=(t1,t2,t3,t4,t5,t6,t7); SELECT 1 FROM m1; 1 HANDLER m1 OPEN; -ERROR HY000: Table storage engine for 'm1' doesn't have this option +ERROR HY000: Storage engine MRG_MyISAM of the table `test`.`m1` doesn't have this option DROP TABLE m1,t1,t2,t3,t4,t5,t6,t7; SELECT 1 FROM m1; ERROR 42S02: Table 'test.m1' doesn't exist @@ -3552,7 +3552,7 @@ CREATE TABLE t2 (c1 int); CREATE TABLE t3 (c1 int) ENGINE = MERGE UNION (t1,t2); START TRANSACTION; HANDLER t3 OPEN; -ERROR HY000: Table storage engine for 't3' doesn't have this option +ERROR HY000: Storage engine MRG_MyISAM of the table `test`.`t3` doesn't have this option DROP TABLE t1, t2, t3; # Connection default. # Disconnecting con1, all mdl_tickets must have been released. diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 1460467a91a..2530182ea67 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -618,7 +618,7 @@ t1 1 a 1 a A 1000 NULL NULL YES BTREE alter table t1 engine=heap; alter table t1 disable keys; Warnings: -Note 1031 Table storage engine for 't1' doesn't have this option +Note 1031 Storage engine MEMORY of the table `test`.`t1` doesn't have this option show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t1 1 a 1 a NULL 500 NULL NULL YES HASH diff --git a/mysql-test/r/partition_innodb_plugin.result b/mysql-test/r/partition_innodb_plugin.result index fa2ef5c6c18..ceade2a793c 100644 --- a/mysql-test/r/partition_innodb_plugin.result +++ b/mysql-test/r/partition_innodb_plugin.result @@ -67,7 +67,7 @@ LOCK TABLE t1 WRITE; # ALTER fails because COMPRESSED/KEY_BLOCK_SIZE # are incompatible with innodb_file_per_table = OFF; ALTER TABLE t1 ADD PARTITION PARTITIONS 1; -ERROR HY000: Got error 140 "Wrong create options" from storage engine +ERROR HY000: Got error 140 "Wrong create options" from storage engine InnoDB t1#P#p0.ibd t1.frm t1.par diff --git a/mysql-test/r/partition_not_windows.result b/mysql-test/r/partition_not_windows.result index 42dca557b3e..a1da9af675b 100644 --- a/mysql-test/r/partition_not_windows.result +++ b/mysql-test/r/partition_not_windows.result @@ -94,4 +94,4 @@ PARTITION p1 DATA DIRECTORY = '/not/existent/p1Data', PARTITION p2 DATA DIRECTORY = '/not/existent/p2Data', PARTITION p3 DATA DIRECTORY = '/not/existent/p3Data' ); -Got one of the listed errors +ERROR HY000: Can't create/write to file '/not/existent/p0Data/example#P#p0.MYD' (Errcode: 2 "No such file or directory") diff --git a/mysql-test/suite/archive/archive.result b/mysql-test/suite/archive/archive.result index a170cdfbd8c..a491b5bb9ee 100644 --- a/mysql-test/suite/archive/archive.result +++ b/mysql-test/suite/archive/archive.result @@ -6257,7 +6257,7 @@ auto fld1 companynr fld3 fld4 fld5 fld6 3 011402 37 Romans scholastics jarring 4 011403 37 intercepted audiology tinily DELETE FROM t2; -ERROR HY000: Table storage engine for 't2' doesn't have this option +ERROR HY000: Storage engine ARCHIVE of the table `test`.`t2` doesn't have this option SELECT * FROM t2; auto fld1 companynr fld3 fld4 fld5 fld6 1 000001 00 Omaha teethe neat @@ -8689,7 +8689,7 @@ auto fld1 companynr fld3 fld4 fld5 fld6 3 011402 37 Romans scholastics jarring 4 011403 37 intercepted audiology tinily TRUNCATE TABLE t2; -ERROR HY000: Table storage engine for 't2' doesn't have this option +ERROR HY000: Storage engine ARCHIVE of the table `test`.`t2` doesn't have this option SELECT * FROM t2; auto fld1 companynr fld3 fld4 fld5 fld6 1 000001 00 Omaha teethe neat @@ -12754,7 +12754,7 @@ DROP TABLE t1; CREATE TABLE t1 (a INT) ENGINE=ARCHIVE; INSERT INTO t1 VALUES (1); TRUNCATE TABLE t1; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine ARCHIVE of the table `test`.`t1` doesn't have this option DROP TABLE t1; # # BUG#46565 - repair of partition fail for archive engine diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index 7ffaf30d4d2..59e79664eb6 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -49,7 +49,7 @@ t2.frm # flush tables; truncate table t1; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine ARCHIVE of the table `test`.`t1` doesn't have this option t1.ARZ t1.frm t2.ARZ diff --git a/mysql-test/suite/archive/partition_archive.result b/mysql-test/suite/archive/partition_archive.result index 0ba50c38e8d..7b3c01694da 100644 --- a/mysql-test/suite/archive/partition_archive.result +++ b/mysql-test/suite/archive/partition_archive.result @@ -30,6 +30,7 @@ partition by list (a) (partition p0 values in (1), partition p1 values in (2)); insert into t1 values (1), (2); create index inx on t1 (a); +ERROR HY000: Can't create table `db99`.`#sql-temporary` (errno: 1 "Operation not permitted") alter table t1 add partition (partition p2 values in (3)); alter table t1 drop partition p2; use test; diff --git a/mysql-test/suite/archive/partition_archive.test b/mysql-test/suite/archive/partition_archive.test index 6f6a26c018a..e4cc39ff097 100644 --- a/mysql-test/suite/archive/partition_archive.test +++ b/mysql-test/suite/archive/partition_archive.test @@ -47,7 +47,8 @@ engine=archive partition by list (a) (partition p0 values in (1), partition p1 values in (2)); insert into t1 values (1), (2); ---error 0, ER_CANT_CREATE_TABLE +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ +--error ER_CANT_CREATE_TABLE create index inx on t1 (a); alter table t1 add partition (partition p2 values in (3)); alter table t1 drop partition p2; diff --git a/mysql-test/suite/csv/csv.result b/mysql-test/suite/csv/csv.result index d81cf6e28bc..be8ffa8f9e5 100644 --- a/mysql-test/suite/csv/csv.result +++ b/mysql-test/suite/csv/csv.result @@ -5379,7 +5379,7 @@ ERROR 42000: The storage engine for the table doesn't support nullable columns SHOW WARNINGS; Level Code Message Error 1178 The storage engine for the table doesn't support nullable columns -Error 1005 Can't create table 'test.t1' (errno: 138 "Unsupported extension used for table") +Error 1005 Can't create table `test`.`t1` (errno: 138 "Unsupported extension used for table") create table t1 (c1 tinyblob not null) engine=csv; insert into t1 values("This"); update t1 set c1="That" where c1="This"; diff --git a/mysql-test/suite/federated/federated_archive.result b/mysql-test/suite/federated/federated_archive.result index d67568ec11c..c2f43458126 100644 --- a/mysql-test/suite/federated/federated_archive.result +++ b/mysql-test/suite/federated/federated_archive.result @@ -20,13 +20,13 @@ id name 1 foo 2 bar DELETE FROM federated.t1 WHERE id = 1; -ERROR HY000: Got error 10000 'Error on remote system: 1031: Table storage engine for 'archive_table' doesn't have this option' from FEDERATED +ERROR HY000: Got error 10000 'Error on remote system: 1031: Storage engine ARCHIVE of the table `federated`.`archive_table` doesn'' from FEDERATED SELECT * FROM federated.t1; id name 1 foo 2 bar UPDATE federated.t1 SET name='baz' WHERE id = 1; -ERROR HY000: Got error 10000 'Error on remote system: 1031: Table storage engine for 'archive_table' doesn't have this option' from FEDERATED +ERROR HY000: Got error 10000 'Error on remote system: 1031: Storage engine ARCHIVE of the table `federated`.`archive_table` doesn'' from FEDERATED SELECT * FROM federated.t1; id name 1 foo diff --git a/mysql-test/suite/federated/federatedx.result b/mysql-test/suite/federated/federatedx.result index 2ece1a32b4f..5ae2abb46e5 100644 --- a/mysql-test/suite/federated/federatedx.result +++ b/mysql-test/suite/federated/federatedx.result @@ -1508,7 +1508,7 @@ id name 1 Monty 2 David ALTER TABLE federated.alter_me MODIFY COLUMN id int(16) NOT NULL; -ERROR HY000: Table storage engine for 'alter_me' doesn't have this option +ERROR HY000: Storage engine FEDERATED of the table `federated`.`alter_me` doesn't have this option SELECT * FROM federated.alter_me; id name 1 Monty diff --git a/mysql-test/suite/handler/aria.result b/mysql-test/suite/handler/aria.result index 95be170b5f8..630b16433a4 100644 --- a/mysql-test/suite/handler/aria.result +++ b/mysql-test/suite/handler/aria.result @@ -586,7 +586,7 @@ Note 1051 Unknown table 't1' create table t1 (a int not null) ENGINE=csv; --> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); diff --git a/mysql-test/suite/handler/heap.result b/mysql-test/suite/handler/heap.result index 8b526335024..55f9fd41c7a 100644 --- a/mysql-test/suite/handler/heap.result +++ b/mysql-test/suite/handler/heap.result @@ -586,7 +586,7 @@ Note 1051 Unknown table 't1' create table t1 (a int not null) ENGINE=csv; --> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); @@ -1728,9 +1728,9 @@ a b 4 40 5 50 HANDLER t1 READ a FIRST; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ a LAST; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ b FIRST LIMIT 2; a b 1 10 @@ -1781,11 +1781,11 @@ create table t1 (f1 integer not null, key (f1)) engine=Memory; insert into t1 values (1); HANDLER t1 OPEN; HANDLER t1 READ f1 NEXT; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ f1 NEXT; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ f1 NEXT; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 CLOSE; DROP TABLE t1; End of 5.3 tests diff --git a/mysql-test/suite/handler/innodb.result b/mysql-test/suite/handler/innodb.result index db36640ea39..d4103ddd6ff 100644 --- a/mysql-test/suite/handler/innodb.result +++ b/mysql-test/suite/handler/innodb.result @@ -587,7 +587,7 @@ Note 1051 Unknown table 't1' create table t1 (a int not null) ENGINE=csv; --> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); diff --git a/mysql-test/suite/handler/interface.result b/mysql-test/suite/handler/interface.result index 96d21e7373a..cebbc2784df 100644 --- a/mysql-test/suite/handler/interface.result +++ b/mysql-test/suite/handler/interface.result @@ -269,7 +269,7 @@ handler t1 open; lock table t1 write; alter table t1 engine=csv; handler t1 read a next; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option handler t1 close; unlock tables; drop table t1; diff --git a/mysql-test/suite/handler/myisam.result b/mysql-test/suite/handler/myisam.result index e8abe8047cd..980b87768da 100644 --- a/mysql-test/suite/handler/myisam.result +++ b/mysql-test/suite/handler/myisam.result @@ -586,7 +586,7 @@ Note 1051 Unknown table 't1' create table t1 (a int not null) ENGINE=csv; --> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); diff --git a/mysql-test/suite/innodb/r/innodb-create-options.result b/mysql-test/suite/innodb/r/innodb-create-options.result index c73baa60d42..c32af26c22d 100644 --- a/mysql-test/suite/innodb/r/innodb-create-options.result +++ b/mysql-test/suite/innodb/r/innodb-create-options.result @@ -10,11 +10,11 @@ Note 1051 Unknown table 't1' # 'FIXED' is sent to InnoDB since it is used by MyISAM. # But it is an invalid mode in InnoDB CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid ROW_FORMAT specifier. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message @@ -46,11 +46,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Compact ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid ROW_FORMAT specifier. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Compact @@ -58,23 +58,23 @@ t1 Compact # KEY_BLOCK_SIZE is incompatible with COMPACT, REDUNDANT, & DYNAMIC DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; SHOW WARNINGS; Level Code Message @@ -104,29 +104,29 @@ t1 Compressed key_block_size=16 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid ROW_FORMAT specifier. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; SHOW WARNINGS; Level Code Message @@ -146,11 +146,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Compact row_format=COMPACT ALTER TABLE t1 KEY_BLOCK_SIZE=2; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=REDUNDANT; SHOW WARNINGS; Level Code Message @@ -158,11 +158,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Redundant row_format=REDUNDANT ALTER TABLE t1 KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; SHOW WARNINGS; Level Code Message @@ -170,11 +170,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Dynamic row_format=DYNAMIC ALTER TABLE t1 KEY_BLOCK_SIZE=8; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; Level Code Message @@ -212,23 +212,23 @@ t1 CREATE TABLE `t1` ( `f1` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2 ALTER TABLE t1 ROW_FORMAT=COMPACT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=REDUNDANT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; Level Code Message @@ -250,11 +250,11 @@ t1 Compact row_format=COMPACT # Test 6) StrictMode=ON, CREATE with an invalid KEY_BLOCK_SIZE. DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=9; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") # Test 7) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and # and a valid non-zero KEY_BLOCK_SIZE are rejected with Antelope # and that they can be set to default values during strict mode. @@ -263,23 +263,23 @@ DROP TABLE IF EXISTS t1; Warnings: Note 1051 Unknown table 't1' CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; SHOW WARNINGS; Level Code Message @@ -298,34 +298,34 @@ CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; Level Code Message ALTER TABLE t1 KEY_BLOCK_SIZE=8; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SET GLOBAL innodb_file_format=Barracuda; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_format=Antelope; ALTER TABLE t1 ADD COLUMN f1 INT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message @@ -340,23 +340,23 @@ SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_file_per_table=OFF; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; SHOW WARNINGS; Level Code Message @@ -375,23 +375,23 @@ CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; Level Code Message ALTER TABLE t1 KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPACT; SHOW WARNINGS; Level Code Message @@ -415,12 +415,12 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_per_table=OFF; ALTER TABLE t1 ADD COLUMN f1 INT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 4b032ebabb5..9130b3a4ef2 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -545,7 +545,7 @@ t4 CREATE TABLE `t4` ( CONSTRAINT `dc` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 alter table t3 add constraint dc foreign key (a) references t1(a); -ERROR HY000: Can't create table '#sql-temporary' (errno: 121 "Duplicate key on write or update") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 121 "Duplicate key on write or update") show create table t3; Table Create Table t3 CREATE TABLE `t3` ( @@ -1146,17 +1146,17 @@ PRIMARY KEY (c1) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL; ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1); SHOW CREATE TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index f794ae7470f..5bb97e785a2 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -193,11 +193,11 @@ drop table t1; set innodb_strict_mode = on; create table t1 (id int primary key) engine = innodb key_block_size = 0; create table t2 (id int primary key) engine = innodb key_block_size = 9; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 1; create table t4 (id int primary key) engine = innodb key_block_size = 2; create table t5 (id int primary key) engine = innodb key_block_size = 4; @@ -225,25 +225,25 @@ create table t1 (id int primary key) engine = innodb key_block_size = 8 row_format = compressed; create table t2 (id int primary key) engine = innodb key_block_size = 8 row_format = redundant; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 8 row_format = compact; -ERROR HY000: Can't create table 'test.t3' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t3' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t3` (errno: 140 "Wrong create options") create table t4 (id int primary key) engine = innodb key_block_size = 8 row_format = dynamic; -ERROR HY000: Can't create table 'test.t4' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t4` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t4' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t4` (errno: 140 "Wrong create options") create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; SELECT table_schema, table_name, row_format, data_length, index_length @@ -254,74 +254,74 @@ test t5 Compressed 8192 0 drop table t1, t5; create table t1 (id int primary key) engine = innodb key_block_size = 9 row_format = redundant; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = compact; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = dynamic; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; table_schema table_name row_format data_length index_length set global innodb_file_per_table = off; create table t1 (id int primary key) engine = innodb key_block_size = 1; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 2; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 4; -ERROR HY000: Can't create table 'test.t3' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t3' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t3` (errno: 140 "Wrong create options") create table t4 (id int primary key) engine = innodb key_block_size = 8; -ERROR HY000: Can't create table 'test.t4' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t4` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t4' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t4` (errno: 140 "Wrong create options") create table t5 (id int primary key) engine = innodb key_block_size = 16; -ERROR HY000: Can't create table 'test.t5' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t5` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t5' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t5` (errno: 140 "Wrong create options") create table t6 (id int primary key) engine = innodb row_format = compressed; -ERROR HY000: Can't create table 'test.t6' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t6` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table 'test.t6' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t6` (errno: 140 "Wrong create options") create table t7 (id int primary key) engine = innodb row_format = dynamic; -ERROR HY000: Can't create table 'test.t7' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t7` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table 'test.t7' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t7` (errno: 140 "Wrong create options") create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format, data_length, index_length @@ -333,47 +333,47 @@ drop table t8, t9; set global innodb_file_per_table = on; set global innodb_file_format = `0`; create table t1 (id int primary key) engine = innodb key_block_size = 1; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 2; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 4; -ERROR HY000: Can't create table 'test.t3' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t3' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t3` (errno: 140 "Wrong create options") create table t4 (id int primary key) engine = innodb key_block_size = 8; -ERROR HY000: Can't create table 'test.t4' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t4` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t4' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t4` (errno: 140 "Wrong create options") create table t5 (id int primary key) engine = innodb key_block_size = 16; -ERROR HY000: Can't create table 'test.t5' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t5` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t5' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t5` (errno: 140 "Wrong create options") create table t6 (id int primary key) engine = innodb row_format = compressed; -ERROR HY000: Can't create table 'test.t6' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t6` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t6' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t6` (errno: 140 "Wrong create options") create table t7 (id int primary key) engine = innodb row_format = dynamic; -ERROR HY000: Can't create table 'test.t7' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t7` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t7' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t7` (errno: 140 "Wrong create options") create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format, data_length, index_length diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 7307ce9dc24..96ce3d477c9 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -1600,7 +1600,7 @@ concat(a, b) drop table t1; CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); -ERROR HY000: The used table type doesn't support FULLTEXT indexes +ERROR HY000: The storage engine InnoDB doesn't support FULLTEXT indexes DROP TABLE t1; CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO t1 VALUES (1),(2),(3); @@ -2525,13 +2525,13 @@ drop table t1; set foreign_key_checks=0; create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; create table t1(a char(10) primary key, b varchar(20)) engine = innodb; -ERROR HY000: Can't create table 'test.t1' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") set foreign_key_checks=1; drop table t2; set foreign_key_checks=0; create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; -ERROR HY000: Can't create table 'test.t2' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") set foreign_key_checks=1; drop table t1; set foreign_key_checks=0; diff --git a/mysql-test/suite/innodb/r/innodb_bug12400341.result b/mysql-test/suite/innodb/r/innodb_bug12400341.result index 02d609d8092..eced0895e3a 100644 --- a/mysql-test/suite/innodb/r/innodb_bug12400341.result +++ b/mysql-test/suite/innodb/r/innodb_bug12400341.result @@ -15,7 +15,7 @@ select count(*) from information_schema.processlist; count(*) 33 CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; -ERROR HY000: Can't create table 'mysqltest.testtable' (errno: 177 "Too many active concurrent transactions") +ERROR HY000: Can't create table `mysqltest`.`testtable` (errno: 177 "Too many active concurrent transactions") select count(*) from information_schema.processlist; count(*) 33 diff --git a/mysql-test/suite/innodb/r/innodb_bug46000.result b/mysql-test/suite/innodb/r/innodb_bug46000.result index 9ee0c935d71..f3dff71539b 100644 --- a/mysql-test/suite/innodb/r/innodb_bug46000.result +++ b/mysql-test/suite/innodb/r/innodb_bug46000.result @@ -6,7 +6,7 @@ show warnings; Level Code Message Warning 1280 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index. Error 1280 Incorrect index name 'GEN_CLUST_INDEX' -Error 1005 Can't create table 'test.bug46000' (errno: -1 "Internal error < 0 (Not system error)") +Error 1005 Can't create table `test`.`bug46000` (errno: -1 "Internal error < 0 (Not system error)") create table bug46000(id int) engine=innodb; create index GEN_CLUST_INDEX on bug46000(id); ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX' diff --git a/mysql-test/suite/innodb/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result index 36b37e4ccd8..21c1234d7d3 100644 --- a/mysql-test/suite/innodb/r/innodb_gis.result +++ b/mysql-test/suite/innodb/r/innodb_gis.result @@ -598,4 +598,4 @@ create table t1 (a int not null, b linestring not null, unique key b (b(12))); create unique index a on t1(a); drop table t1; create table t1 (g geometry not null, spatial gk(g)) engine=innodb; -ERROR HY000: The used table type doesn't support SPATIAL indexes +ERROR HY000: The storage engine InnoDB doesn't support SPATIAL indexes diff --git a/mysql-test/suite/innodb/t/innodb-create-options.test b/mysql-test/suite/innodb/t/innodb-create-options.test index 12c24820031..0f8e6f8dda2 100644 --- a/mysql-test/suite/innodb/t/innodb-create-options.test +++ b/mysql-test/suite/innodb/t/innodb-create-options.test @@ -96,10 +96,10 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; @@ -141,25 +141,25 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE --echo # Test 3) StrictMode=ON, ALTER with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; SHOW WARNINGS; @@ -173,26 +173,26 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=2; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=REDUNDANT; SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DYNAMIC; SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=8; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; @@ -213,20 +213,20 @@ CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=2; SHOW CREATE TABLE t1; ALTER TABLE t1 ADD COLUMN f1 INT; SHOW CREATE TABLE t1; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPACT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=REDUNDANT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; @@ -276,29 +276,29 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=8; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPRESSED; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; SET GLOBAL innodb_file_format=Barracuda; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_format=Antelope; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ADD COLUMN f1 INT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; @@ -337,20 +337,20 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=1; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPRESSED; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=COMPACT; SHOW WARNINGS; @@ -365,10 +365,10 @@ SET GLOBAL innodb_file_per_table=ON; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_per_table=OFF; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ADD COLUMN f1 INT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test index cea9055b873..a8ef524c3e9 100644 --- a/mysql-test/suite/innodb/t/innodb-index.test +++ b/mysql-test/suite/innodb/t/innodb-index.test @@ -250,7 +250,7 @@ insert into t2 values (1,1,1,1,1); commit; alter table t4 add constraint dc foreign key (a) references t1(a); show create table t4; ---replace_regex /'test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ # a foreign key 'test/dc' already exists --error ER_CANT_CREATE_TABLE alter table t3 add constraint dc foreign key (a) references t1(a); @@ -620,20 +620,20 @@ CREATE TABLE t2( PRIMARY KEY (c1) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1); ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1); ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL; ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result index a7e038675a9..ddd0adade57 100644 --- a/mysql-test/suite/maria/maria.result +++ b/mysql-test/suite/maria/maria.result @@ -653,7 +653,7 @@ t1 1 a 1 a A 1000 NULL NULL YES BTREE alter table t1 engine=heap; alter table t1 disable keys; Warnings: -Note 1031 Table storage engine for 't1' doesn't have this option +Note 1031 Storage engine MEMORY of the table `test`.`t1` doesn't have this option show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t1 1 a 1 a NULL 500 NULL NULL YES HASH diff --git a/mysql-test/suite/maria/maria3.result b/mysql-test/suite/maria/maria3.result index 27d72b75930..b502d71e772 100644 --- a/mysql-test/suite/maria/maria3.result +++ b/mysql-test/suite/maria/maria3.result @@ -359,7 +359,7 @@ NULL NULL 0 NULL 0 0 alter table t1 add column d char(0) not null, add key (d); -ERROR 42000: The used storage engine can't index column 'd' +ERROR 42000: The storage engine Aria can't index column `d` drop table t1; CREATE TABLE t1 (a bit(3)); insert into t1 values (NULL),(0),(1),(2),(3),(4),(5),(6),(7); diff --git a/mysql-test/suite/percona/percona_innodb_fake_changes.result b/mysql-test/suite/percona/percona_innodb_fake_changes.result index 5540c76f2e5..434b7283146 100644 --- a/mysql-test/suite/percona/percona_innodb_fake_changes.result +++ b/mysql-test/suite/percona/percona_innodb_fake_changes.result @@ -43,7 +43,7 @@ SET autocommit=0; SET innodb_fake_changes=1; BEGIN; CREATE TABLE t2 (a INT) ENGINE=InnoDB; -ERROR HY000: Can't create table 'test.t2' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t2` (errno: 131 "Command not supported by database") DROP TABLE t1; ERROR 42S02: Unknown table 't1' TRUNCATE TABLE t1; diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result index 1dbde982328..3b088496b0a 100644 --- a/mysql-test/suite/perfschema/r/misc.result +++ b/mysql-test/suite/perfschema/r/misc.result @@ -6,9 +6,9 @@ AND EVENT_NAME IN WHERE NAME LIKE "wait/synch/%") LIMIT 1; create table test.t1(a int) engine=performance_schema; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table performance_schema.t1(a int); ERROR 42000: CREATE command denied to user 'root'@'localhost' for table 't1' drop table if exists test.ghost; diff --git a/mysql-test/suite/perfschema/r/privilege.result b/mysql-test/suite/perfschema/r/privilege.result index 019d8964523..32a502db34b 100644 --- a/mysql-test/suite/perfschema/r/privilege.result +++ b/mysql-test/suite/perfschema/r/privilege.result @@ -152,13 +152,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'setup_instruments' @@ -250,13 +250,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'setup_instruments' @@ -348,13 +348,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'setup_instruments' @@ -446,13 +446,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'setup_instruments' diff --git a/mysql-test/t/partition_not_windows.test b/mysql-test/t/partition_not_windows.test index 333e12e2b16..429329c79bb 100644 --- a/mysql-test/t/partition_not_windows.test +++ b/mysql-test/t/partition_not_windows.test @@ -199,7 +199,7 @@ DROP TABLE example; --rmdir $MYSQLTEST_VARDIR/p2Index --rmdir $MYSQLTEST_VARDIR/p3Index ---error ER_CANT_CREATE_TABLE,1 +--error 1 CREATE TABLE `example` ( `ID_EXAMPLE` int(10) unsigned NOT NULL AUTO_INCREMENT, `DESCRIPTION` varchar(30) NOT NULL, diff --git a/sql/discover.cc b/sql/discover.cc index b5bccf7dcb0..4224e8ce0b0 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -132,7 +132,7 @@ int writefrm(const char *path, const char *db, const char *table, if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR, MYF(0), db); else - my_error(ER_CANT_CREATE_TABLE, MYF(0), table, my_errno); + my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table, my_errno); } else { diff --git a/sql/handler.cc b/sql/handler.cc index f890c2c8324..f094ff7bebb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1138,7 +1138,8 @@ int ha_prepare(THD *thd) else { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), + ER_GET_ERRNO, ER(ER_GET_ERRNO), + HA_ERR_WRONG_COMMAND, ha_resolve_storage_engine_name(ht)); } } @@ -2004,7 +2005,7 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv) } if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset))) { // cannot happen - my_error(ER_GET_ERRNO, MYF(0), err); + my_error(ER_GET_ERRNO, MYF(0), err, hton_name(ht)->str); error=1; } status_var_increment(thd->status_var.ha_savepoint_count); @@ -2035,7 +2036,7 @@ int ha_release_savepoint(THD *thd, SAVEPOINT *sv) if ((err= ht->savepoint_release(ht, thd, (uchar *)(sv+1) + ht->savepoint_offset))) { // cannot happen - my_error(ER_GET_ERRNO, MYF(0), err); + my_error(ER_GET_ERRNO, MYF(0), err, hton_name(ht)->str); error=1; } } @@ -2971,7 +2972,7 @@ void handler::print_error(int error, myf errflag) DBUG_ENTER("handler::print_error"); DBUG_PRINT("enter",("error: %d",error)); - int textno=ER_GET_ERRNO; + int textno= -1; // impossible value switch (error) { case EACCES: textno=ER_OPEN_AS_READONLY; @@ -3100,7 +3101,9 @@ void handler::print_error(int error, myf errflag) textno=ER_OUT_OF_RESOURCES; break; case HA_ERR_WRONG_COMMAND: - textno=ER_ILLEGAL_HA; + my_error(ER_ILLEGAL_HA, MYF(0), table_type(), table_share->db.str, + table_share->table_name.str); + DBUG_VOID_RETURN; break; case HA_ERR_OLD_FILE: textno=ER_OLD_KEYFILE; @@ -3219,10 +3222,11 @@ void handler::print_error(int error, myf errflag) } } else - my_error(ER_GET_ERRNO,errflag,error); + my_error(ER_GET_ERRNO, errflag, error, table_type()); DBUG_VOID_RETURN; } } + DBUG_ASSERT(textno > 0); if (fatal_error) { /* Ensure this becomes a true error */ @@ -4181,10 +4185,8 @@ int ha_create_table(THD *thd, const char *path, (void) closefrm(&table, 0); if (error) - { - strxmov(name_buff, db, ".", table_name, NullS); - my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error); - } + my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table_name, error); + err: free_table_share(&share); DBUG_RETURN(error != 0); @@ -4326,7 +4328,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, if (error) { DBUG_ASSERT(share->error); // MUST be always set for get_cached_table_share to work - my_error(ER_GET_ERRNO, MYF(0), error); + my_error(ER_GET_ERRNO, MYF(0), error, plugin_name(plugin)->str); share->db_plugin= 0; } else @@ -5116,7 +5118,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) if (!result && !thd->is_error()) my_eof(thd); else if (!thd->is_error()) - my_error(ER_GET_ERRNO, MYF(0), errno); + my_error(ER_GET_ERRNO, MYF(0), errno, hton_name(db_type)->str); return result; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 108943541c9..2d27876df0b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6143,7 +6143,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) table=((Item_field *)item)->field->table; if (!(table->file->ha_table_flags() & HA_CAN_FULLTEXT)) { - my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0), table->file->table_type()); return 1; } table->fulltext_searched=1; diff --git a/sql/lock.cc b/sql/lock.cc index 3a1a6d41ce3..5bb42185d90 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -93,7 +93,7 @@ extern HASH open_cache; static int lock_external(THD *thd, TABLE **table,uint count); static int unlock_external(THD *thd, TABLE **table,uint count); -static void print_lock_error(int error, const char *); +static void print_lock_error(int error, TABLE *); /* Map the return value of thr_lock to an error from errmsg.txt */ static int thr_lock_errno_to_mysql[]= @@ -358,7 +358,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count) if ((error=(*tables)->file->ha_external_lock(thd,lock_type))) { - print_lock_error(error, (*tables)->file->table_type()); + print_lock_error(error, *tables); while (--i) { tables--; @@ -673,7 +673,7 @@ static int unlock_external(THD *thd, TABLE **table,uint count) if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK))) { error_code=error; - print_lock_error(error_code, (*table)->file->table_type()); + print_lock_error(error_code, *table); } } table++; @@ -895,7 +895,7 @@ bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type, } -static void print_lock_error(int error, const char *table) +static void print_lock_error(int error, TABLE *table) { int textno; DBUG_ENTER("print_lock_error"); @@ -911,17 +911,15 @@ static void print_lock_error(int error, const char *table) textno=ER_LOCK_DEADLOCK; break; case HA_ERR_WRONG_COMMAND: - textno=ER_ILLEGAL_HA; - break; + my_error(ER_ILLEGAL_HA, MYF(0), table->file->table_type(), + table->s->db.str, table->s->table_name.str); + DBUG_VOID_RETURN; default: textno=ER_CANT_LOCK; break; } - if ( textno == ER_ILLEGAL_HA ) - my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), table); - else - my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error); + my_error(textno, MYF(0), error); DBUG_VOID_RETURN; } diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 6a7eafc5fc4..e0b16b7a1ed 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -75,30 +75,30 @@ ER_CANT_CREATE_FILE swe "Kan inte skapa filen '%-.200s' (Felkod: %M)" ukr "Ðе можу Ñтворити файл '%-.200s' (помилка: %M)" ER_CANT_CREATE_TABLE - cze "Nemohu vytvo-BÅ™it tabulku '%-.200s' (chybový kód: %M)" - dan "Kan ikke oprette tabellen '%-.200s' (Fejlkode: %M)" - nla "Kan tabel '%-.200s' niet aanmaken (Errcode: %M)" - eng "Can't create table '%-.200s' (errno: %M)" - jps "'%-.200s' テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)", - est "Ei suuda luua tabelit '%-.200s' (veakood: %M)" - fre "Ne peut créer la table '%-.200s' (Errcode: %M)" - ger "Kann Tabelle '%-.200s' nicht erzeugen (Fehler: %M)" - greek "ΑδÏνατη η δημιουÏγία του πίνακα '%-.200s' (κωδικός λάθους: %M)" - hun "A '%-.200s' tabla nem hozhato letre (hibakod: %M)" - ita "Impossibile creare la tabella '%-.200s' (errno: %M)" - jpn "'%-.200s' テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)" - kor "í…Œì´ë¸” '%-.200s'를 만들지 못했습니다. (ì—러번호: %M)" - nor "Kan ikke opprette tabellen '%-.200s' (Feilkode: %M)" - norwegian-ny "Kan ikkje opprette tabellen '%-.200s' (Feilkode: %M)" - pol "Nie można stworzyć tabeli '%-.200s' (Kod błędu: %M)" - por "Não pode criar a tabela '%-.200s' (erro no. %M)" - rum "Nu pot sa creez tabla '%-.200s' (Eroare: %M)" - rus "Ðевозможно Ñоздать таблицу '%-.200s' (ошибка: %M)" - serbian "Ne mogu da kreiram tabelu '%-.200s' (errno: %M)" - slo "Nemôžem vytvoriÅ¥ tabuľku '%-.200s' (chybový kód: %M)" - spa "No puedo crear tabla '%-.200s' (Error: %M)" - swe "Kan inte skapa tabellen '%-.200s' (Felkod: %M)" - ukr "Ðе можу Ñтворити таблицю '%-.200s' (помилка: %M)" + cze "Nemohu vytvo-BÅ™it tabulku %`s.%`s (chybový kód: %M)" + dan "Kan ikke oprette tabellen %`s.%`s (Fejlkode: %M)" + nla "Kan tabel %`s.%`s niet aanmaken (Errcode: %M)" + eng "Can't create table %`s.%`s (errno: %M)" + jps "%`s.%`s テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)", + est "Ei suuda luua tabelit %`s.%`s (veakood: %M)" + fre "Ne peut créer la table %`s.%`s (Errcode: %M)" + ger "Kann Tabelle %`s.%`s nicht erzeugen (Fehler: %M)" + greek "ΑδÏνατη η δημιουÏγία του πίνακα %`s.%`s (κωδικός λάθους: %M)" + hun "A %`s.%`s tabla nem hozhato letre (hibakod: %M)" + ita "Impossibile creare la tabella %`s.%`s (errno: %M)" + jpn "%`s.%`s テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)" + kor "í…Œì´ë¸” %`s.%`s를 만들지 못했습니다. (ì—러번호: %M)" + nor "Kan ikke opprette tabellen %`s.%`s (Feilkode: %M)" + norwegian-ny "Kan ikkje opprette tabellen %`s.%`s (Feilkode: %M)" + pol "Nie można stworzyć tabeli %`s.%`s (Kod błędu: %M)" + por "Não pode criar a tabela %`s.%`s (erro no. %M)" + rum "Nu pot sa creez tabla %`s.%`s (Eroare: %M)" + rus "Ðевозможно Ñоздать таблицу %`s.%`s (ошибка: %M)" + serbian "Ne mogu da kreiram tabelu %`s.%`s (errno: %M)" + slo "Nemôžem vytvoriÅ¥ tabuľku %`s.%`s (chybový kód: %M)" + spa "No puedo crear tabla %`s.%`s (Error: %M)" + swe "Kan inte skapa tabellen %`s.%`s (Felkod: %M)" + ukr "Ðе можу Ñтворити таблицю %`s.%`s (помилка: %M)" ER_CANT_CREATE_DB cze "Nemohu vytvo-BÅ™it databázi '%-.192s' (chybový kód: %M)" dan "Kan ikke oprette databasen '%-.192s' (Fejlkode: %M)" @@ -696,53 +696,26 @@ ER_FORM_NOT_FOUND swe "Formulär '%-.192s' finns inte i '%-.192s'" ukr "ВиглÑд '%-.192s' не Ñ–Ñнує Ð´Ð»Ñ '%-.192s'" ER_GET_ERRNO - cze "Obsluha tabulky vr-Bátila chybu %M" - dan "Modtog fejl %M fra tabel hÃ¥ndteringen" - nla "Fout %M van tabel handler" - eng "Got error %M from storage engine" - est "Tabeli handler tagastas vea %M" - fre "Reçu l'erreur %M du handler de la table" - ger "Fehler %M (Speicher-Engine)" - greek "Ελήφθη μήνυμα λάθους %M από τον χειÏιστή πίνακα (table handler)" - hun "%M hibajelzes a tablakezelotol" - ita "Rilevato l'errore %M dal gestore delle tabelle" - jpn "Got error %M from table handler" - kor "í…Œì´ë¸” handlerì—서 %M ì—러가 ë°œìƒ í•˜ì˜€ìŠµë‹ˆë‹¤." - nor "Mottok feil %M fra tabell hÃ¥ndterer" - norwegian-ny "Mottok feil %M fra tabell handterar" - pol "Otrzymano bÅ‚?d %M z obsÅ‚ugi tabeli" - por "Obteve erro %M no manipulador de tabelas" - rum "Eroarea %M obtinuta din handlerul tabelei" - rus "Получена ошибка %M от обработчика таблиц" - serbian "Handler tabela je vratio greÅ¡ku %M" - slo "Obsluha tabuľky vrátila chybu %M" - spa "Error %M desde el manejador de la tabla" - swe "Fick felkod %M frÃ¥n databashanteraren" - ukr "Отримано помилку %M від деÑкриптора таблиці" + nla "Fout %M van tabel handler %s" + eng "Got error %M from storage engine %s" + fre "Reçu l'erreur %M du handler de la table %s" + ger "Fehler %M von Speicher-Engine %s" + greek "Ελήφθη μήνυμα λάθους %M από τον χειÏιστή πίνακα (table handler) %s" + ita "Rilevato l'errore %M dal gestore delle tabelle %s" + nor "Mottok feil %M fra tabell hÃ¥ndterer %s" + norwegian-ny "Mottok feil %M fra tabell handterar %s" + pol "Otrzymano bÅ‚?d %M z obsÅ‚ugi tabeli %s" + por "Obteve erro %M no manipulador de tabelas %s" + rum "Eroarea %M obtinuta din handlerul tabelei %s" + rus "Получена ошибка %M от обработчика таблиц %s" + spa "Error %M desde el manejador de la tabla %s" + swe "Fick felkod %M frÃ¥n databashanteraren %s" + ukr "Отримано помилку %M від деÑкриптора таблиці %s" ER_ILLEGAL_HA - cze "Obsluha tabulky '%-.192s' nem-Bá tento parametr" - dan "Denne mulighed eksisterer ikke for tabeltypen '%-.192s'" - nla "Tabel handler voor '%-.192s' heeft deze optie niet" - eng "Table storage engine for '%-.192s' doesn't have this option" - est "Tabeli '%-.192s' handler ei toeta antud operatsiooni" - fre "Le handler de la table '%-.192s' n'a pas cette option" - ger "Diese Option gibt es nicht (Speicher-Engine für '%-.192s')" - greek "Ο χειÏιστής πίνακα (table handler) για '%-.192s' δεν διαθέτει αυτή την επιλογή" - hun "A(z) '%-.192s' tablakezelonek nincs ilyen opcioja" - ita "Il gestore delle tabelle per '%-.192s' non ha questa opzione" - jpn "Table handler for '%-.192s' doesn't have this option" - kor "'%-.192s'ì˜ í…Œì´ë¸” handler는 ì´ëŸ¬í•œ ì˜µì…˜ì„ ì œê³µí•˜ì§€ 않ì니다." - nor "Tabell hÃ¥ndtereren for '%-.192s' har ikke denne muligheten" - norwegian-ny "Tabell hÃ¥ndteraren for '%-.192s' har ikkje denne moglegheita" - pol "ObsÅ‚uga tabeli '%-.192s' nie posiada tej opcji" - por "Manipulador de tabela para '%-.192s' não tem esta opção" - rum "Handlerul tabelei pentru '%-.192s' nu are aceasta optiune" - rus "Обработчик таблицы '%-.192s' не поддерживает Ñту возможноÑть" - serbian "Handler tabela za '%-.192s' nema ovu opciju" - slo "Obsluha tabuľky '%-.192s' nemá tento parameter" - spa "El manejador de la tabla de '%-.192s' no tiene esta opcion" - swe "Tabellhanteraren for tabell '%-.192s' stödjer ej detta" - ukr "ДеÑкриптор таблиці '%-.192s' не має цієї влаÑтивоÑті" + eng "Storage engine %s of the table %`s.%`s doesn't have this option" + ger "Diese Option gibt es nicht in Speicher-Engine %s für %`s.%`s" + rus "Обработчик %s таблицы %`s.%`s не поддерживает Ñту возможноÑть" + ukr "ДеÑкриптор %s таблиці %`s.%`s не має цієї влаÑтивоÑті" ER_KEY_NOT_FOUND cze "Nemohu naj-Bít záznam v '%-.192s'" dan "Kan ikke finde posten i '%-.192s'" @@ -1750,28 +1723,10 @@ ER_KEY_COLUMN_DOES_NOT_EXITS 42000 S1009 swe "Nyckelkolumn '%-.192s' finns inte" ukr "Ключовий Ñтовбець '%-.192s' не Ñ–Ñнує у таблиці" ER_BLOB_USED_AS_KEY 42000 S1009 - cze "Blob sloupec '%-.192s' nem-Bůže být použit jako klíÄ" - dan "BLOB feltet '%-.192s' kan ikke bruges ved specifikation af indeks" - nla "BLOB kolom '%-.192s' kan niet gebruikt worden bij zoeksleutel specificatie" - eng "BLOB column '%-.192s' can't be used in key specification with the used table type" - est "BLOB-tüüpi tulpa '%-.192s' ei saa kasutada võtmena" - fre "Champ BLOB '%-.192s' ne peut être utilisé dans une clé" - ger "BLOB-Feld '%-.192s' kann beim verwendeten Tabellentyp nicht als Schlüssel verwendet werden" - greek "Πεδίο Ï„Ïπου Blob '%-.192s' δεν μποÏεί να χÏησιμοποιηθεί στον οÏισμό ενός ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï (key specification)" - hun "Blob objektum '%-.192s' nem hasznalhato kulcskent" - ita "La colonna BLOB '%-.192s' non puo` essere usata nella specifica della chiave" - kor "BLOB 칼럼 '%-.192s'는 키 ì •ì˜ì—서 ì‚¬ìš©ë  ìˆ˜ 없습니다." - nor "Blob felt '%-.192s' kan ikke brukes ved spesifikasjon av nøkler" - norwegian-ny "Blob kolonne '%-.192s' kan ikkje brukast ved spesifikasjon av nyklar" - pol "Kolumna typu Blob '%-.192s' nie może być użyta w specyfikacji klucza" - por "Coluna BLOB '%-.192s' não pode ser utilizada na especificação de chave para o tipo de tabela usado" - rum "Coloana de tip BLOB '%-.192s' nu poate fi folosita in specificarea cheii cu tipul de tabla folosit" - rus "Столбец типа BLOB '%-.192s' не может быть иÑпользован как значение ключа в таблице такого типа" - serbian "BLOB kolona '%-.192s' ne može biti upotrebljena za navoÄ‘enje kljuÄa sa tipom tabele koji se trenutno koristi" - slo "Blob pole '%-.192s' nemôže byÅ¥ použité ako kľúÄ" - spa "La columna Blob '%-.192s' no puede ser usada en una declaracion de clave" - swe "En BLOB '%-.192s' kan inte vara nyckel med den använda tabelltypen" - ukr "BLOB Ñтовбець '%-.192s' не може бути викориÑтаний у визначенні ключа в цьому типі таблиці" + eng "BLOB column %`s can't be used in key specification in the %s table" + ger "BLOB-Feld %`s kann beim %s Tabellen nicht als Schlüssel verwendet werden" + rus "Столбец типа BLOB %`s не может быть иÑпользован как значение ключа в %s таблице" + ukr "BLOB Ñтовбець %`s не може бути викориÑтаний у визначенні ключа в %s таблиці" ER_TOO_BIG_FIELDLENGTH 42000 S1009 cze "P-BříliÅ¡ velká délka sloupce '%-.192s' (nejvíce %lu). Použijte BLOB" dan "For stor feltlængde for kolonne '%-.192s' (maks = %lu). Brug BLOB i stedet" @@ -3691,39 +3646,39 @@ ER_TOO_LONG_STRING 42000 swe "Resultatsträngen är längre än max_allowed_packet" ukr "Строка результату довша ніж max_allowed_packet" ER_TABLE_CANT_HANDLE_BLOB 42000 - cze "Typ pou-Bžité tabulky nepodporuje BLOB/TEXT sloupce" - dan "Denne tabeltype understøtter ikke brug af BLOB og TEXT kolonner" - nla "Het gebruikte tabel type ondersteunt geen BLOB/TEXT kolommen" - eng "The used table type doesn't support BLOB/TEXT columns" - est "Valitud tabelitüüp ei toeta BLOB/TEXT tüüpi välju" - fre "Ce type de table ne supporte pas les colonnes BLOB/TEXT" - ger "Der verwendete Tabellentyp unterstützt keine BLOB- und TEXT-Felder" - hun "A hasznalt tabla tipus nem tamogatja a BLOB/TEXT mezoket" - ita "Il tipo di tabella usata non supporta colonne di tipo BLOB/TEXT" - por "Tipo de tabela usado não permite colunas BLOB/TEXT" - rum "Tipul de tabela folosit nu suporta coloane de tip BLOB/TEXT" - rus "ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° не поддерживает типы BLOB/TEXT" - serbian "IskoriÅ¡teni tip tabele ne podržava kolone tipa 'BLOB' odnosno 'TEXT'" - spa "El tipo de tabla usada no permite soporte para columnas BLOB/TEXT" - swe "Den använda tabelltypen kan inte hantera BLOB/TEXT-kolumner" - ukr "ВикориÑтаний тип таблиці не підтримує BLOB/TEXT Ñтовбці" + cze "Typ pou-Bžité tabulky (%s) nepodporuje BLOB/TEXT sloupce" + dan "Denne tabeltype (%s) understøtter ikke brug af BLOB og TEXT kolonner" + nla "Het gebruikte tabel type (%s) ondersteunt geen BLOB/TEXT kolommen" + eng "Storage engine %s doesn't support BLOB/TEXT columns" + est "Valitud tabelitüüp (%s) ei toeta BLOB/TEXT tüüpi välju" + fre "Ce type de table (%s) ne supporte pas les colonnes BLOB/TEXT" + ger "Der verwendete Tabellentyp (%s) unterstützt keine BLOB- und TEXT-Felder" + hun "A hasznalt tabla tipus (%s) nem tamogatja a BLOB/TEXT mezoket" + ita "Il tipo di tabella usata (%s) non supporta colonne di tipo BLOB/TEXT" + por "Tipo de tabela usado (%s) não permite colunas BLOB/TEXT" + rum "Tipul de tabela folosit (%s) nu suporta coloane de tip BLOB/TEXT" + rus "%s таблицы не поддерживают типы BLOB/TEXT" + serbian "IskoriÅ¡teni tip tabele (%s) ne podržava kolone tipa 'BLOB' odnosno 'TEXT'" + spa "El tipo de tabla usada (%s) no permite soporte para columnas BLOB/TEXT" + swe "Den använda tabelltypen (%s) kan inte hantera BLOB/TEXT-kolumner" + ukr "%s таблиці не підтримують BLOB/TEXT Ñтовбці" ER_TABLE_CANT_HANDLE_AUTO_INCREMENT 42000 - cze "Typ pou-Bžité tabulky nepodporuje AUTO_INCREMENT sloupce" - dan "Denne tabeltype understøtter ikke brug af AUTO_INCREMENT kolonner" - nla "Het gebruikte tabel type ondersteunt geen AUTO_INCREMENT kolommen" - eng "The used table type doesn't support AUTO_INCREMENT columns" - est "Valitud tabelitüüp ei toeta AUTO_INCREMENT tüüpi välju" - fre "Ce type de table ne supporte pas les colonnes AUTO_INCREMENT" - ger "Der verwendete Tabellentyp unterstützt keine AUTO_INCREMENT-Felder" - hun "A hasznalt tabla tipus nem tamogatja az AUTO_INCREMENT tipusu mezoket" - ita "Il tipo di tabella usata non supporta colonne di tipo AUTO_INCREMENT" - por "Tipo de tabela usado não permite colunas AUTO_INCREMENT" - rum "Tipul de tabela folosit nu suporta coloane de tip AUTO_INCREMENT" - rus "ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° не поддерживает автоинкрементные Ñтолбцы" - serbian "IskoriÅ¡teni tip tabele ne podržava kolone tipa 'AUTO_INCREMENT'" - spa "El tipo de tabla usada no permite soporte para columnas AUTO_INCREMENT" - swe "Den använda tabelltypen kan inte hantera AUTO_INCREMENT-kolumner" - ukr "ВикориÑтаний тип таблиці не підтримує AUTO_INCREMENT Ñтовбці" + cze "Typ pou-Bžité tabulky (%s) nepodporuje AUTO_INCREMENT sloupce" + dan "Denne tabeltype understøtter (%s) ikke brug af AUTO_INCREMENT kolonner" + nla "Het gebruikte tabel type (%s) ondersteunt geen AUTO_INCREMENT kolommen" + eng "Storage engine %s doesn't support AUTO_INCREMENT columns" + est "Valitud tabelitüüp (%s) ei toeta AUTO_INCREMENT tüüpi välju" + fre "Ce type de table (%s) ne supporte pas les colonnes AUTO_INCREMENT" + ger "Der verwendete Tabellentyp (%s) unterstützt keine AUTO_INCREMENT-Felder" + hun "A hasznalt tabla tipus (%s) nem tamogatja az AUTO_INCREMENT tipusu mezoket" + ita "Il tipo di tabella usata (%s) non supporta colonne di tipo AUTO_INCREMENT" + por "Tipo de tabela usado (%s) não permite colunas AUTO_INCREMENT" + rum "Tipul de tabela folosit (%s) nu suporta coloane de tip AUTO_INCREMENT" + rus "%s таблицы не поддерживают автоинкрементные Ñтолбцы" + serbian "IskoriÅ¡teni tip tabele (%s) ne podržava kolone tipa 'AUTO_INCREMENT'" + spa "El tipo de tabla usada (%s) no permite soporte para columnas AUTO_INCREMENT" + swe "Den använda tabelltypen (%s) kan inte hantera AUTO_INCREMENT-kolumner" + ukr "%s таблиці не підтримують AUTO_INCREMENT Ñтовбці" ER_DELAYED_INSERT_TABLE_LOCKED cze "INSERT DELAYED nen-Bí možno s tabulkou '%-.192s' použít, protože je zamÄená pomocí LOCK TABLES" dan "INSERT DELAYED kan ikke bruges med tabellen '%-.192s', fordi tabellen er lÃ¥st med LOCK TABLES" @@ -3766,29 +3721,10 @@ ER_WRONG_COLUMN_NAME 42000 swe "Felaktigt kolumnnamn '%-.100s'" ukr "Ðевірне ім'Ñ ÑÑ‚Ð¾Ð²Ð±Ñ†Ñ '%-.100s'" ER_WRONG_KEY_COLUMN 42000 - cze "Handler pou-Bžité tabulky neumí indexovat sloupce '%-.192s'" - dan "Den brugte tabeltype kan ikke indeksere kolonnen '%-.192s'" - nla "De gebruikte tabel 'handler' kan kolom '%-.192s' niet indexeren" - eng "The used storage engine can't index column '%-.192s'" - est "Tabelihandler ei oska indekseerida tulpa '%-.192s'" - fre "Le handler de la table ne peut indexé la colonne '%-.192s'" - ger "Die verwendete Speicher-Engine kann die Spalte '%-.192s' nicht indizieren" - greek "The used table handler can't index column '%-.192s'" - hun "A hasznalt tablakezelo nem tudja a '%-.192s' mezot indexelni" - ita "Il gestore delle tabelle non puo` indicizzare la colonna '%-.192s'" - jpn "The used table handler can't index column '%-.192s'" - kor "The used table handler can't index column '%-.192s'" - nor "The used table handler can't index column '%-.192s'" - norwegian-ny "The used table handler can't index column '%-.192s'" - pol "The used table handler can't index column '%-.192s'" - por "O manipulador de tabela usado não pode indexar a coluna '%-.192s'" - rum "Handler-ul tabelei folosite nu poate indexa coloana '%-.192s'" - rus "ИÑпользованный обработчик таблицы не может проиндекÑировать Ñтолбец '%-.192s'" - serbian "Handler tabele ne može da indeksira kolonu '%-.192s'" - slo "The used table handler can't index column '%-.192s'" - spa "El manipulador de tabla usado no puede indexar columna '%-.192s'" - swe "Den använda tabelltypen kan inte indexera kolumn '%-.192s'" - ukr "ВикориÑтаний вказівник таблиці не може індекÑувати Ñтовбець '%-.192s'" + eng "The storage engine %s can't index column %`s" + ger "Die Speicher-Engine %s kann die Spalte %`s nicht indizieren" + rus "Обработчик таблиц %s не может проиндекÑировать Ñтолбец %`s" + ukr "Вказівник таблиц %s не може індекÑувати Ñтовбець %`s" ER_WRONG_MRG_TABLE cze "V-BÅ¡echny tabulky v MERGE tabulce nejsou definovány stejnÄ›" dan "Tabellerne i MERGE er ikke defineret ens" @@ -4088,22 +4024,8 @@ ER_NEW_ABORTING_CONNECTION 08S01 spa "Abortada conexión %ld para db: '%-.192s' usuario: '%-.48s' servidor: '%-.64s' (%-.64s)" swe "Avbröt länken för trÃ¥d %ld till db '%-.192s', användare '%-.48s', host '%-.64s' (%-.64s)" ukr "Перервано з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ %ld до бази данних: '%-.192s' кориÑтувач: '%-.48s' хоÑÑ‚: '%-.64s' (%-.64s)" -ER_DUMP_NOT_IMPLEMENTED - cze "Handler tabulky nepodporuje bin-Bární dump" - dan "Denne tabeltype unserstøtter ikke binært tabeldump" - nla "De 'handler' voor de tabel ondersteund geen binaire tabel dump" - eng "The storage engine for the table does not support binary table dump" - fre "Ce type de table ne supporte pas les copies binaires" - ger "Die Speicher-Engine für die Tabelle unterstützt keinen binären Tabellen-Dump" - ita "Il gestore per la tabella non supporta il dump binario" - jpn "The handler for the table does not support binary table dump" - por "O manipulador de tabela não suporta 'dump' binário de tabela" - rum "The handler for the table does not support binary table dump" - rus "Обработчик Ñтой таблицы не поддерживает двоичного ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ð° таблицы (dump)" - serbian "Handler tabele ne podržava binarni dump tabele" - spa "El manipulador de tabla no soporta dump para tabla binaria" - swe "Tabellhanteraren klarar inte en binär kopiering av tabellen" - ukr "Цей тип таблиці не підтримує бінарну передачу таблиці" +ER_unused_2 + eng "You should never see it" ER_FLUSH_MASTER_BINLOG_CLOSED eng "Binlog closed, cannot RESET MASTER" ger "Binlog geschlossen. Kann RESET MASTER nicht ausführen" @@ -4477,18 +4399,18 @@ ER_LOCK_DEADLOCK 40001 spa "Encontrado deadlock cuando tentando obtener el bloqueo; Tente recomenzar la transición" swe "Fick 'DEADLOCK' vid lÃ¥sförsök av block/rad. Försök att starta om transaktionen" ER_TABLE_CANT_HANDLE_FT - nla "Het gebruikte tabel type ondersteund geen FULLTEXT indexen" - eng "The used table type doesn't support FULLTEXT indexes" - est "Antud tabelitüüp ei toeta FULLTEXT indekseid" - fre "Le type de table utilisé ne supporte pas les index FULLTEXT" - ger "Der verwendete Tabellentyp unterstützt keine FULLTEXT-Indizes" - ita "La tabella usata non supporta gli indici FULLTEXT" - por "O tipo de tabela utilizado não suporta índices de texto completo (fulltext indexes)" - rus "ИÑпользуемый тип таблиц не поддерживает полнотекÑтовых индекÑов" - serbian "Upotrebljeni tip tabele ne podržava 'FULLTEXT' indekse" - spa "El tipo de tabla usada no soporta índices FULLTEXT" - swe "Tabelltypen har inte hantering av FULLTEXT-index" - ukr "ВикориÑтаний тип таблиці не підтримує FULLTEXT індекÑів" + nla "Het gebruikte tabel type (%s) ondersteund geen FULLTEXT indexen" + eng "The storage engine %s doesn't support FULLTEXT indexes" + est "Antud tabelitüüp (%s) ei toeta FULLTEXT indekseid" + fre "Le type de table utilisé (%s) ne supporte pas les index FULLTEXT" + ger "Der verwendete Tabellentyp (%s) unterstützt keine FULLTEXT-Indizes" + ita "La tabella usata (%s) non supporta gli indici FULLTEXT" + por "O tipo de tabela utilizado (%s) não suporta índices de texto completo (fulltext indexes)" + rus "ИÑпользуемый тип таблиц (%s) не поддерживает полнотекÑтовых индекÑов" + serbian "Upotrebljeni tip tabele (%s) ne podržava 'FULLTEXT' indekse" + spa "El tipo de tabla usada (%s) no soporta índices FULLTEXT" + swe "Tabelltypen (%s) har inte hantering av FULLTEXT-index" + ukr "ВикориÑтаний тип таблиці (%s) не підтримує FULLTEXT індекÑів" ER_CANNOT_ADD_FOREIGN nla "Kan foreign key beperking niet toevoegen" eng "Cannot add foreign key constraint" @@ -5622,8 +5544,8 @@ ER_NON_GROUPING_FIELD_USED 42000 eng "Non-grouping field '%-.192s' is used in %-.64s clause" ger "In der %-.192s-Klausel wird das die Nicht-Gruppierungsspalte '%-.64s' verwendet" ER_TABLE_CANT_HANDLE_SPKEYS - eng "The used table type doesn't support SPATIAL indexes" - ger "Der verwendete Tabellentyp unterstützt keine SPATIAL-Indizes" + eng "The storage engine %s doesn't support SPATIAL indexes" + ger "Der verwendete Tabellentyp (%s) unterstützt keine SPATIAL-Indizes" ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA eng "Triggers can not be created on system tables" ger "Trigger können nicht auf Systemtabellen erzeugt werden" @@ -6017,8 +5939,8 @@ ER_ONLY_INTEGERS_ALLOWED eng "Only integers allowed as number here" ger "An dieser Stelle sind nur Ganzzahlen zulässig" ER_UNSUPORTED_LOG_ENGINE - eng "This storage engine cannot be used for log tables" - ger "Diese Speicher-Engine kann für Logtabellen nicht verwendet werden" + eng "Storage engine %s cannot be used for log tables" + ger "Speicher-Engine %s kann für Logtabellen nicht verwendet werden" ER_BAD_LOG_STATEMENT eng "You cannot '%s' a log table if logging is enabled" ger "Sie können eine Logtabelle nicht '%s', wenn Loggen angeschaltet ist" @@ -6498,7 +6420,7 @@ ER_BINLOG_UNSAFE_INSERT_TWO_KEYS ER_TABLE_IN_FK_CHECK eng "Table is being used in foreign key check." -ER_UNUSED_1 +ER_unused_1 eng "You should never see it" ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 1c93a59904c..d1e5d731183 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -304,7 +304,8 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) /* There can be only one table in '*tables'. */ if (! (table->file->ha_table_flags() & HA_CAN_SQL_HANDLER)) { - my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); + my_error(ER_ILLEGAL_HA, MYF(0), table->file->table_type(), + table->s->db.str, table->s->table_name.str); goto err; } @@ -901,7 +902,8 @@ retry: break; } default: - my_message(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0)); + my_error(ER_ILLEGAL_HA, MYF(0), table->file->table_type(), + table->s->db.str, table->s->table_name.str); goto err; } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index d6a64b38446..2f9bcf92f6d 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1764,7 +1764,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) mysql_mutex_unlock(&LOCK_plugin); } if (error > 0) - sql_print_error(ER(ER_GET_ERRNO), my_errno); + sql_print_error(ER(ER_GET_ERRNO), my_errno, table->file->table_type()); end_read_record(&read_record_info); table->m_needs_reopen= TRUE; // Force close to free memory close_mysql_tables(new_thd); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eb02e9f2baf..dd00d921b6e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -963,7 +963,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) plugin_ref plugin= ha_resolve_by_name(thd, &handler_name); if (!plugin) { - my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name); + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), ddl_log_entry->handler_name); goto error; } hton= plugin_data(plugin, handlerton*); @@ -3255,15 +3255,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (auto_increment && (file->ha_table_flags() & HA_NO_AUTO_INCREMENT)) { - my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, - ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS)) { - my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB), - MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_BLOB, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } @@ -3439,8 +3437,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->ha_table_flags() & HA_CAN_FULLTEXT)) { - my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT), - MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } } @@ -3457,8 +3454,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->ha_table_flags() & HA_CAN_RTREEKEYS)) { - my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS), - MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } if (key_info->key_parts != 1) @@ -3573,7 +3569,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS)) { - my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str); + my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str, + file->table_type()); DBUG_RETURN(TRUE); } if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type == @@ -3695,7 +3692,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } else if (length == 0 && (sql_field->flags & NOT_NULL_FLAG)) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str); + my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), + column->field_name.str); DBUG_RETURN(TRUE); } if (length > file->max_key_part_length() && key->type != Key::FULLTEXT) @@ -4394,7 +4392,7 @@ bool mysql_create_table_no_lock(THD *thd, if (!hton->discover_table_structure) { - my_error(ER_ILLEGAL_HA, MYF(0), table_name); + my_error(ER_ILLEGAL_HA, MYF(0), hton_name(hton)->str, db, table_name); goto err; } @@ -4414,7 +4412,7 @@ bool mysql_create_table_no_lock(THD *thd, if (ha_err) { - my_error(ER_GET_ERRNO, MYF(0), ha_err); + my_error(ER_GET_ERRNO, MYF(0), ha_err, hton_name(hton)->str); goto err; } } @@ -5417,6 +5415,7 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, switch (keys_onoff) { case ENABLE: + DEBUG_SYNC(table->in_use, "alter_table_enable_indexes"); error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); break; case LEAVE_AS_IS: @@ -5431,7 +5430,8 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, { push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->s->table_name.str); + table->file->table_type(), + table->s->db.str, table->s->table_name.str); error= 0; } else if (error) table->file->print_error(error, MYF(0)); @@ -6051,7 +6051,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (!create_info->db_type || /* unknown engine */ !(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES))) { - my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0)); + my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0), + hton_name(create_info->db_type)->str); DBUG_RETURN(TRUE); } @@ -6267,11 +6268,19 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, DBUG_PRINT("info", ("old type: %s new type: %s", ha_resolve_storage_engine_name(old_db_type), ha_resolve_storage_engine_name(new_db_type))); - if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) || - ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED)) + if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED)) { DBUG_PRINT("info", ("doesn't support alter")); - my_error(ER_ILLEGAL_HA, MYF(0), table_name); + my_error(ER_ILLEGAL_HA, MYF(0), hton_name(old_db_type)->str, + db, table_name); + goto err; + } + + if (ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED)) + { + DBUG_PRINT("info", ("doesn't support alter")); + my_error(ER_ILLEGAL_HA, MYF(0), hton_name(new_db_type)->str, + new_db, new_name); goto err; } @@ -6279,35 +6288,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) && !table->s->tmp_table) // no need to touch frm { - switch (alter_info->keys_onoff) { - case LEAVE_AS_IS: - break; - case ENABLE: - if (wait_while_table_is_used(thd, table, extra_func, - TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) - goto err; - DEBUG_SYNC(thd,"alter_table_enable_indexes"); - error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - table->s->allow_access_to_protected_table(); - break; - case DISABLE: - if (wait_while_table_is_used(thd, table, extra_func, - TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) - goto err; - error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - table->s->allow_access_to_protected_table(); - break; - default: - DBUG_ASSERT(FALSE); - error= 0; - break; - } - if (error == HA_ERR_WRONG_COMMAND) + if (alter_info->keys_onoff != LEAVE_AS_IS) { - error= 0; - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias.c_ptr()); + if (wait_while_table_is_used(thd, table, extra_func, + TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) + goto err; + error= alter_table_manage_keys(table, 0, alter_info->keys_onoff); + table->s->allow_access_to_protected_table(); } if (!error && (new_name != table_name || new_db != db)) @@ -6365,7 +6352,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, error= 0; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias.c_ptr()); + table->file->table_type(), + table->s->db.str, table->s->table_name.str); } if (!error) diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cdd5078c262..3f61fbb3302 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -311,6 +311,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -325,6 +326,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } diff --git a/storage/pbxt/src/discover_xt.cc b/storage/pbxt/src/discover_xt.cc index 05891bdf19d..23941374fb1 100644 --- a/storage/pbxt/src/discover_xt.cc +++ b/storage/pbxt/src/discover_xt.cc @@ -1196,7 +1196,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } else if (length == 0) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name); + my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), + column->field_name); DBUG_RETURN(TRUE); } if (length > file->max_key_part_length() && key->type != Key::FULLTEXT) diff --git a/storage/sequence/mysql-test/sequence/simple.result b/storage/sequence/mysql-test/sequence/simple.result index 102f17498fe..b14fde2cfef 100644 --- a/storage/sequence/mysql-test/sequence/simple.result +++ b/storage/sequence/mysql-test/sequence/simple.result @@ -39,7 +39,7 @@ ERROR 42S02: Table 'test.seq_' doesn't exist show create table se; ERROR 42S02: Table 'test.se' doesn't exist show create table seq_1_to_15_step_0; -ERROR HY000: Got error 140 "Wrong create options" from storage engine +ERROR HY000: Got error 140 "Wrong create options" from storage engine SEQUENCE select * from seq_1_to_15_step_2; seq 1 diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index 94940e0b82f..23bf21b6cbe 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -3424,7 +3424,8 @@ int ha_sphinx::create ( const char * name, TABLE * table, HA_CREATE_INFO * ) // report and bail if ( sError[0] ) { - my_error ( ER_CANT_CREATE_TABLE, MYF(0), sError, -1 ); + my_error ( ER_CANT_CREATE_TABLE, MYF(0), + table->s->db.str, table->s->table_name, sError ); SPH_RET(-1); } diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result index c2b9160f7c3..4fee0a983ed 100644 --- a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result +++ b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result @@ -4,7 +4,7 @@ test_sql_discovery_statement test_sql_discovery_write_frm ON set sql_quote_show_create=0; create table t1 (a int) engine=test_sql_discovery; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist set @@test_sql_discovery_statement='t1:foobar bwa-ha-ha'; @@ -16,7 +16,7 @@ show warnings; Level Code Message Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'foobar bwa-ha-ha' at line 1 Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:select 1'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -24,7 +24,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'select 1' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int primary key) partition by hash(id) partitions 2'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -32,7 +32,7 @@ show warnings; Level Code Message Error 1290 The MariaDB server is running with the --skip-partition option so it cannot execute this statement Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) union=(t3,t4)'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -40,7 +40,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) union=(t3,t4)' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 like t2'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -48,7 +48,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 like t2' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 select * from t2'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -56,7 +56,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 select * from t2' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) index directory="/tmp"'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -64,7 +64,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) index directory="/tmp"' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) data directory="/tmp"'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -72,7 +72,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) data directory="/tmp"' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) engine=myisam'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -80,7 +80,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) engine=myisam' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create temporary table t1 (a int)'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -88,7 +88,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create temporary table t1 (a int)' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table if not exists t1 (a int)'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -96,7 +96,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table if not exists t1 (a int)' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int)'; select * from t1; a diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 88b07bbebe3..3a32cf95bc9 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -312,6 +312,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -326,6 +327,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } From eda4c51241b647094b727643e1aad4153c45d647 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:14 +0200 Subject: [PATCH 77/87] cleanup --- sql/create_options.cc | 30 ++++++++++++++---------------- sql/create_options.h | 15 ++++++--------- sql/sql_plugin.cc | 11 ----------- 3 files changed, 20 insertions(+), 36 deletions(-) diff --git a/sql/create_options.cc b/sql/create_options.cc index 5cedfa03a63..47d3a2d06ea 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -74,7 +74,7 @@ void engine_option_value::link(engine_option_value **start, } static bool report_wrong_value(THD *thd, const char *name, const char *val, - my_bool suppress_warning) + bool suppress_warning) { if (suppress_warning) return 0; @@ -92,7 +92,7 @@ static bool report_wrong_value(THD *thd, const char *name, const char *val, } static bool report_unknown_option(THD *thd, engine_option_value *val, - my_bool suppress_warning) + bool suppress_warning) { DBUG_ENTER("report_unknown_option"); @@ -116,7 +116,7 @@ static bool report_unknown_option(THD *thd, engine_option_value *val, static bool set_one_value(ha_create_table_option *opt, THD *thd, LEX_STRING *value, void *base, - my_bool suppress_warning, + bool suppress_warning, MEM_ROOT *root) { DBUG_ENTER("set_one_value"); @@ -257,11 +257,10 @@ static const size_t ha_option_type_sizeof[]= @retval FALSE OK */ -my_bool parse_option_list(THD* thd, void *option_struct_arg, - engine_option_value *option_list, - ha_create_table_option *rules, - my_bool suppress_warning, - MEM_ROOT *root) +bool parse_option_list(THD* thd, void *option_struct_arg, + engine_option_value *option_list, + ha_create_table_option *rules, + bool suppress_warning, MEM_ROOT *root) { ha_create_table_option *opt; size_t option_struct_size= 0; @@ -269,13 +268,13 @@ my_bool parse_option_list(THD* thd, void *option_struct_arg, void **option_struct= (void**)option_struct_arg; DBUG_ENTER("parse_option_list"); DBUG_PRINT("enter", - ("struct: 0x%lx list: 0x%lx rules: 0x%lx suppres %u root 0x%lx", - (ulong) *option_struct, (ulong)option_list, (ulong)rules, - (uint) suppress_warning, (ulong) root)); + ("struct: %p list: %p rules: %p suppress_warning: %u root: %p", + *option_struct, option_list, rules, + (uint) suppress_warning, root)); if (rules) { - LEX_STRING default_val= {NULL, 0}; + LEX_STRING default_val= null_lex_str; for (opt= rules; opt->name; opt++) set_if_bigger(option_struct_size, opt->offset + ha_option_type_sizeof[opt->type]); @@ -323,8 +322,7 @@ my_bool parse_option_list(THD* thd, void *option_struct_arg, @retval FALSE OK */ -my_bool parse_engine_table_options(THD *thd, handlerton *ht, - TABLE_SHARE *share) +bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share) { MEM_ROOT *root= &share->mem_root; DBUG_ENTER("parse_engine_table_options"); @@ -543,8 +541,8 @@ uchar *engine_option_value::frm_read(const uchar *buff, engine_option_value **st @retval FALSE OK */ -my_bool engine_table_options_frm_read(const uchar *buff, uint length, - TABLE_SHARE *share) +bool engine_table_options_frm_read(const uchar *buff, uint length, + TABLE_SHARE *share) { const uchar *buff_end= buff + length; engine_option_value *UNINIT_VAR(end); diff --git a/sql/create_options.h b/sql/create_options.h index ae918f6cea1..5db826a3038 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -69,16 +69,13 @@ class engine_option_value: public Sql_alloc typedef struct st_key KEY; class Create_field; -my_bool parse_engine_table_options(THD *thd, handlerton *ht, +bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share); +bool parse_option_list(THD* thd, void *option_struct, + engine_option_value *option_list, + ha_create_table_option *rules, + bool suppress_warning, MEM_ROOT *root); +bool engine_table_options_frm_read(const uchar *buff, uint length, TABLE_SHARE *share); -my_bool parse_option_list(THD* thd, void *option_struct, - engine_option_value *option_list, - ha_create_table_option *rules, - my_bool suppress_warning, - MEM_ROOT *root); -my_bool engine_table_options_frm_read(const uchar *buff, - uint length, - TABLE_SHARE *share); engine_option_value *merge_engine_table_options(engine_option_value *source, engine_option_value *changes, MEM_ROOT *root); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2f9bcf92f6d..b19d6853164 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3387,17 +3387,6 @@ static void plugin_opt_set_limits(struct my_option *options, options->arg_type= OPT_ARG; } -extern "C" my_bool get_one_plugin_option(int optid, const struct my_option *, - char *); - -my_bool get_one_plugin_option(int optid __attribute__((unused)), - const struct my_option *opt, - char *argument) -{ - return 0; -} - - /** Creates a set of my_option objects associated with a specified plugin- handle. From 7d3288129f6e5b52c7377ff68295f51606c7f002 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:19 +0200 Subject: [PATCH 78/87] create sys_var::val_str(), sys_var::val_int(), sys_var::val_real(). Change Item_func_get_system_var::val_xxx functions to use that. mysql-test/t/variables.test: @@GLOBAL.INIT_CONNECT is never NULL anymore. Nor it ever was. It was a bug that empty string system variables appeared as NULL in the *integer context* (but not in a string, real, or decimal context!) --- mysql-test/r/variables.result | 10 -- mysql-test/t/func_time.test | 2 + mysql-test/t/variables.test | 16 --- sql/item_func.cc | 180 +++------------------------------- sql/set_var.cc | 111 ++++++++++++++++++++- sql/set_var.h | 4 + 6 files changed, 127 insertions(+), 196 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 6ec9d77230b..f280fce08d3 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1479,16 +1479,6 @@ SELECT @@GLOBAL.server_id; @@GLOBAL.server_id 0 SET GLOBAL server_id = @old_server_id; -SELECT @@GLOBAL.INIT_CONNECT, @@GLOBAL.INIT_CONNECT IS NULL; -@@GLOBAL.INIT_CONNECT @@GLOBAL.INIT_CONNECT IS NULL - 1 -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (); -SET @bug42778= @@sql_safe_updates; -SET @@sql_safe_updates= 0; -DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_CONNECT) ASC LIMIT 10; -SET @@sql_safe_updates= @bug42778; -DROP TABLE t1; # # BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback # diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index f65681a6c5b..7a72c21d0ff 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -883,7 +883,9 @@ SELECT STR_TO_DATE(SPACE(2),'1'); --echo # SET GLOBAL SQL_MODE=''; +--disable_warnings DO STR_TO_DATE((''), FROM_DAYS(@@GLOBAL.SQL_MODE)); +--enable_warnings SET GLOBAL SQL_MODE=DEFAULT; --echo # diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 792859386e9..08e7e68c225 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1206,22 +1206,6 @@ SET GLOBAL server_id = -1; SELECT @@GLOBAL.server_id; SET GLOBAL server_id = @old_server_id; -# -# Bug #42778: delete order by null global variable causes -# assertion .\filesort.cc, line 797 -# - -SELECT @@GLOBAL.INIT_CONNECT, @@GLOBAL.INIT_CONNECT IS NULL; - -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (); -SET @bug42778= @@sql_safe_updates; -SET @@sql_safe_updates= 0; -DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_CONNECT) ASC LIMIT 10; -SET @@sql_safe_updates= @bug42778; - -DROP TABLE t1; - --echo # --echo # BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback --echo # diff --git a/sql/item_func.cc b/sql/item_func.cc index 2d27876df0b..5316f89e730 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5668,24 +5668,6 @@ enum_field_types Item_func_get_system_var::field_type() const } -/* - Uses var, var_type, component, cache_present, used_query_id, thd, - cached_llval, null_value, cached_null_value -*/ -#define get_sys_var_safe(type) \ -do { \ - type value; \ - mysql_mutex_lock(&LOCK_global_system_variables); \ - value= *(type*) var->value_ptr(thd, var_type, &component); \ - mysql_mutex_unlock(&LOCK_global_system_variables); \ - cache_present |= GET_SYS_VAR_CACHE_LONG; \ - used_query_id= thd->query_id; \ - cached_llval= null_value ? 0 : (longlong) value; \ - cached_null_value= null_value; \ - return cached_llval; \ -} while (0) - - longlong Item_func_get_system_var::val_int() { THD *thd= current_thd; @@ -5719,51 +5701,11 @@ longlong Item_func_get_system_var::val_int() } } - switch (var->show_type()) - { - case SHOW_SINT: get_sys_var_safe (int); - case SHOW_SLONG: get_sys_var_safe (long); - case SHOW_SLONGLONG:get_sys_var_safe (longlong); - case SHOW_UINT: get_sys_var_safe (uint); - case SHOW_ULONG: get_sys_var_safe (ulong); - case SHOW_ULONGLONG:get_sys_var_safe (ulonglong); - case SHOW_HA_ROWS: get_sys_var_safe (ha_rows); - case SHOW_BOOL: get_sys_var_safe (bool); - case SHOW_MY_BOOL: get_sys_var_safe (my_bool); - case SHOW_DOUBLE: - { - double dval= val_real(); - - used_query_id= thd->query_id; - cached_llval= (longlong) dval; - cache_present|= GET_SYS_VAR_CACHE_LONG; - return cached_llval; - } - case SHOW_CHAR: - case SHOW_CHAR_PTR: - case SHOW_LEX_STRING: - { - String *str_val= val_str(NULL); - - if (str_val && str_val->length()) - cached_llval= longlong_from_string_with_check (system_charset_info, - str_val->c_ptr(), - str_val->c_ptr() + - str_val->length()); - else - { - null_value= TRUE; - cached_llval= 0; - } - - cache_present|= GET_SYS_VAR_CACHE_LONG; - return cached_llval; - } - - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - return 0; // keep the compiler happy - } + cached_llval= var->val_int(&null_value, thd, var_type, &component); + cache_present |= GET_SYS_VAR_CACHE_LONG; + used_query_id= thd->query_id; + cached_null_value= null_value; + return cached_llval; } @@ -5796,61 +5738,10 @@ String* Item_func_get_system_var::val_str(String* str) } } - str= &cached_strval; - switch (var->show_type()) - { - case SHOW_CHAR: - case SHOW_CHAR_PTR: - case SHOW_LEX_STRING: - { - mysql_mutex_lock(&LOCK_global_system_variables); - char *cptr= var->show_type() == SHOW_CHAR ? - (char*) var->value_ptr(thd, var_type, &component) : - *(char**) var->value_ptr(thd, var_type, &component); - if (cptr) - { - size_t len= var->show_type() == SHOW_LEX_STRING ? - ((LEX_STRING*)(var->value_ptr(thd, var_type, &component)))->length : - strlen(cptr); - if (str->copy(cptr, len, collation.collation)) - { - null_value= TRUE; - str= NULL; - } - } - else - { - null_value= TRUE; - str= NULL; - } - mysql_mutex_unlock(&LOCK_global_system_variables); - break; - } - - case SHOW_SINT: - case SHOW_SLONG: - case SHOW_SLONGLONG: - case SHOW_UINT: - case SHOW_ULONG: - case SHOW_ULONGLONG: - case SHOW_HA_ROWS: - case SHOW_BOOL: - case SHOW_MY_BOOL: - str->set (val_int(), collation.collation); - break; - case SHOW_DOUBLE: - str->set_real (val_real(), decimals, collation.collation); - break; - - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - str= NULL; - break; - } - + str= var->val_str(&cached_strval, thd, var_type, &component); cache_present|= GET_SYS_VAR_CACHE_STRING; used_query_id= thd->query_id; - cached_null_value= null_value; + cached_null_value= null_value= !str; return str; } @@ -5888,58 +5779,11 @@ double Item_func_get_system_var::val_real() } } - switch (var->show_type()) - { - case SHOW_DOUBLE: - mysql_mutex_lock(&LOCK_global_system_variables); - cached_dval= *(double*) var->value_ptr(thd, var_type, &component); - mysql_mutex_unlock(&LOCK_global_system_variables); - used_query_id= thd->query_id; - cached_null_value= null_value; - if (null_value) - cached_dval= 0; - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - return cached_dval; - case SHOW_CHAR: - case SHOW_LEX_STRING: - case SHOW_CHAR_PTR: - { - mysql_mutex_lock(&LOCK_global_system_variables); - char *cptr= var->show_type() == SHOW_CHAR ? - (char*) var->value_ptr(thd, var_type, &component) : - *(char**) var->value_ptr(thd, var_type, &component); - if (cptr) - cached_dval= double_from_string_with_check (system_charset_info, - cptr, cptr + strlen (cptr)); - else - { - null_value= TRUE; - cached_dval= 0; - } - mysql_mutex_unlock(&LOCK_global_system_variables); - used_query_id= thd->query_id; - cached_null_value= null_value; - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - return cached_dval; - } - case SHOW_SINT: - case SHOW_SLONG: - case SHOW_SLONGLONG: - case SHOW_UINT: - case SHOW_ULONG: - case SHOW_ULONGLONG: - case SHOW_HA_ROWS: - case SHOW_BOOL: - case SHOW_MY_BOOL: - cached_dval= (double) val_int(); - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - used_query_id= thd->query_id; - cached_null_value= null_value; - return cached_dval; - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - return 0; - } + cached_dval= var->val_real(&null_value, thd, var_type, &component); + cache_present |= GET_SYS_VAR_CACHE_DOUBLE; + used_query_id= thd->query_id; + cached_null_value= null_value; + return cached_dval; } diff --git a/sql/set_var.cc b/sql/set_var.cc index 2d3e0b7fec4..48f7cc7a054 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -257,8 +257,7 @@ uchar *sys_var::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) bool sys_var::set_default(THD *thd, enum_var_type type) { - LEX_STRING empty={0,0}; - set_var var(type, this, &empty, 0); + set_var var(type, this, &null_lex_str, 0); if (type == OPT_GLOBAL || scope() == GLOBAL) global_save_default(thd, &var); @@ -268,6 +267,114 @@ bool sys_var::set_default(THD *thd, enum_var_type type) return check(thd, &var) || update(thd, &var); } + +#define do_num_val(T,CMD) \ +do { \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + T val= *(T*) value_ptr(thd, type, base); \ + mysql_mutex_unlock(&LOCK_global_system_variables); \ + CMD; \ +} while (0) + +#define case_for_integers(CMD) \ + case SHOW_SINT: do_num_val (int,CMD); \ + case SHOW_SLONG: do_num_val (long,CMD); \ + case SHOW_SLONGLONG:do_num_val (longlong,CMD); \ + case SHOW_UINT: do_num_val (uint,CMD); \ + case SHOW_ULONG: do_num_val (ulong,CMD); \ + case SHOW_ULONGLONG:do_num_val (ulonglong,CMD); \ + case SHOW_HA_ROWS: do_num_val (ha_rows,CMD); \ + case SHOW_BOOL: do_num_val (bool,CMD); \ + case SHOW_MY_BOOL: do_num_val (my_bool,CMD) + +#define case_for_double(CMD) \ + case SHOW_DOUBLE: do_num_val (double,CMD) + +#define case_get_string_as_lex_string \ + case SHOW_CHAR: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval.str= (char*) value_ptr(thd, type, base); \ + sval.length= sval.str ? strlen(sval.str) : 0; \ + break; \ + case SHOW_CHAR_PTR: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval.str= *(char**) value_ptr(thd, type, base); \ + sval.length= sval.str ? strlen(sval.str) : 0; \ + break; \ + case SHOW_LEX_STRING: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval= *(LEX_STRING *) value_ptr(thd, type, base); \ + break + +longlong sys_var::val_int(bool *is_null, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + *is_null= false; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return val); + case_for_double(return val); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + longlong ret= 0; + if (!(*is_null= !sval.str)) + ret= longlong_from_string_with_check(system_charset_info, + sval.str, sval.str + sval.length); + mysql_mutex_unlock(&LOCK_global_system_variables); + return ret; +} + + +String *sys_var::val_str(String *str, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return str->set((ulonglong)val, system_charset_info) ? 0 : str); + case_for_double(return str->set_real(val, 6, system_charset_info) ? 0 : str); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + if (!sval.str || str->copy(sval.str, sval.length, system_charset_info)) + str= NULL; + mysql_mutex_unlock(&LOCK_global_system_variables); + return str; +} + + +double sys_var::val_real(bool *is_null, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + *is_null= false; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return val); + case_for_double(return val); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + double ret= 0; + if (!(*is_null= !sval.str)) + ret= double_from_string_with_check(system_charset_info, + sval.str, sval.str + sval.length); + mysql_mutex_unlock(&LOCK_global_system_variables); + return ret; +} + + void sys_var::do_deprecated_warning(THD *thd) { if (deprecation_substitute != NULL) diff --git a/sql/set_var.h b/sql/set_var.h index f912c9fffad..6cb0cd33f87 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -108,6 +108,10 @@ public: bool set_default(THD *thd, enum_var_type type); bool update(THD *thd, set_var *var); + longlong val_int(bool *is_null, THD *thd, enum_var_type type, LEX_STRING *base); + String *val_str(String *str, THD *thd, enum_var_type type, LEX_STRING *base); + double val_real(bool *is_null, THD *thd, enum_var_type type, LEX_STRING *base); + SHOW_TYPE show_type() { return show_val_type; } int scope() const { return flags & SCOPE_MASK; } CHARSET_INFO *charset(THD *thd); From 5f293dd694f9b1b4a0bdf73bb6ae80cda70f21d4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:24 +0200 Subject: [PATCH 79/87] MDEV-4022 table attributes with sysvar as a default value --- mysql-test/r/partition_example.result | 4 +- mysql-test/r/plugin.result | 36 ++++-- mysql-test/t/plugin.test | 11 ++ sql/create_options.cc | 175 +++++++++++++++++++++++--- sql/create_options.h | 6 +- sql/handler.cc | 6 +- sql/handler.h | 28 ++++- sql/sql_plugin.cc | 21 +++- sql/sql_plugin.h | 2 + sql/sql_table.cc | 12 +- storage/example/ha_example.cc | 10 ++ 11 files changed, 265 insertions(+), 46 deletions(-) diff --git a/mysql-test/r/partition_example.result b/mysql-test/r/partition_example.result index 2129eea0818..7b6e9aa5213 100644 --- a/mysql-test/r/partition_example.result +++ b/mysql-test/r/partition_example.result @@ -7,7 +7,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='5' /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ @@ -20,7 +20,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 `VAROPT`='5' /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index ac2ba843131..06e343a0886 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -49,6 +49,7 @@ show variables like 'example%'; Variable_name Value example_enum_var e1 example_ulong_var 500 +example_varopt_default 5 UNINSTALL SONAME 'ha_example'; Warnings: Warning 1620 Plugin is busy and will be uninstalled on shutdown @@ -119,7 +120,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,f,f,f' -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0 `VAROPT`='5' drop table t1; SET @OLD_SQL_MODE=@@SQL_MODE; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; @@ -133,20 +134,20 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' #alter table alter table t1 ULL=10000000; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 alter table t1 change a a int complex='c,c,c'; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,c,c' -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 drop table t1; #illegal value error SET SQL_MODE=''; @@ -161,17 +162,38 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=4660 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=4660 `VAROPT`='5' +SET example_varopt_default=33; select create_options from information_schema.tables where table_schema='test' and table_name='t1'; create_options -`ULL`=4660 +`ULL`=4660 `VAROPT`='5' ALTER TABLE t1 ULL=DEFAULT; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='5' DROP TABLE t1; +create table t1 (a int) engine=example; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='33' +drop table t1; +create table t1 (a int) engine=example varopt=15; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `varopt`=15 +alter table t1 varopt=default; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='33' +drop table t1; SET @@SQL_MODE=@OLD_SQL_MODE; select 1; 1 diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index 71ca860e269..602b2e3c5c9 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -144,6 +144,7 @@ CREATE TABLE t1 (a int) ENGINE=example ULL=1e2; CREATE TABLE t1 (a int) ENGINE=example ULL=0x1234; SHOW CREATE TABLE t1; +SET example_varopt_default=33; # does not affect varopt of t1 select create_options from information_schema.tables where table_schema='test' and table_name='t1'; @@ -152,6 +153,16 @@ SHOW CREATE TABLE t1; DROP TABLE t1; +create table t1 (a int) engine=example; # varopt is 10 +show create table t1; +drop table t1; + +create table t1 (a int) engine=example varopt=15; +show create table t1; +alter table t1 varopt=default; +show create table t1; +drop table t1; + SET @@SQL_MODE=@OLD_SQL_MODE; # diff --git a/sql/create_options.cc b/sql/create_options.cc index 47d3a2d06ea..f12120bd0a1 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -21,6 +21,7 @@ #include "create_options.h" #include +#include "set_var.h" #define FRM_QUOTED_VALUE 0x8000 @@ -115,7 +116,7 @@ static bool report_unknown_option(THD *thd, engine_option_value *val, } static bool set_one_value(ha_create_table_option *opt, - THD *thd, LEX_STRING *value, void *base, + THD *thd, const LEX_STRING *value, void *base, bool suppress_warning, MEM_ROOT *root) { @@ -126,6 +127,8 @@ static bool set_one_value(ha_create_table_option *opt, (value->str ? value->str : ""))); switch (opt->type) { + case HA_OPTION_TYPE_SYSVAR: + DBUG_ASSERT(0); // HA_OPTION_TYPE_SYSVAR's are replaced in resolve_sysvars() case HA_OPTION_TYPE_ULL: { ulonglong *val= (ulonglong*)((char*)base + opt->offset); @@ -257,51 +260,92 @@ static const size_t ha_option_type_sizeof[]= @retval FALSE OK */ -bool parse_option_list(THD* thd, void *option_struct_arg, - engine_option_value *option_list, +bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg, + engine_option_value **option_list, ha_create_table_option *rules, bool suppress_warning, MEM_ROOT *root) { ha_create_table_option *opt; size_t option_struct_size= 0; - engine_option_value *val= option_list; + engine_option_value *val, *last; void **option_struct= (void**)option_struct_arg; DBUG_ENTER("parse_option_list"); DBUG_PRINT("enter", ("struct: %p list: %p rules: %p suppress_warning: %u root: %p", - *option_struct, option_list, rules, + *option_struct, *option_list, rules, (uint) suppress_warning, root)); if (rules) { - LEX_STRING default_val= null_lex_str; for (opt= rules; opt->name; opt++) set_if_bigger(option_struct_size, opt->offset + ha_option_type_sizeof[opt->type]); *option_struct= alloc_root(root, option_struct_size); - - /* set all values to default */ - for (opt= rules; opt->name; opt++) - set_one_value(opt, thd, &default_val, *option_struct, - suppress_warning, root); } - for (; val; val= val->next) + for (opt= rules; opt && opt->name; opt++) { - for (opt= rules; opt && opt->name; opt++) + bool seen=false; + for (val= *option_list; val; val= val->next) { + last= val; if (my_strnncoll(system_charset_info, (uchar*)opt->name, opt->name_length, (uchar*)val->name.str, val->name.length)) continue; + seen=true; + + if (val->parsed && !val->value.str) + continue; + if (set_one_value(opt, thd, &val->value, *option_struct, suppress_warning || val->parsed, root)) DBUG_RETURN(TRUE); val->parsed= true; break; } + if (!seen) + { + LEX_STRING default_val= null_lex_str; + + /* + If it's CREATE/ALTER TABLE parsing mode (options are created in the + transient thd->mem_root, not in the long living TABLE_SHARE::mem_root), + and variable-backed option was not explicitly set. + + If it's not create, but opening of the existing frm (that was, + probably, created with the older version of the storage engine and + does not have this option stored), we take the *default* value of the + sysvar, not the *current* value. Because we don't want to have + different option values for the same table if it's opened many times. + */ + if (root == thd->mem_root && opt->var) + { + // take a value from the variable and add it to the list + sys_var *sysvar= find_hton_sysvar(hton, opt->var); + DBUG_ASSERT(sysvar); + + char buf[256]; + String sbuf(buf, sizeof(buf), system_charset_info), *str; + if ((str= sysvar->val_str(&sbuf, thd, OPT_SESSION, 0))) + { + LEX_STRING name= { const_cast(opt->name), opt->name_length }; + default_val.str= strmake_root(root, str->ptr(), str->length()); + default_val.length= str->length(); + val= new (root) engine_option_value(name, default_val, true, + option_list, &last); + val->parsed= true; + } + } + set_one_value(opt, thd, &default_val, *option_struct, + suppress_warning, root); + } + } + + for (val= *option_list; val; val= val->next) + { if (report_unknown_option(thd, val, suppress_warning)) DBUG_RETURN(TRUE); val->parsed= true; @@ -311,6 +355,102 @@ bool parse_option_list(THD* thd, void *option_struct_arg, } +/** + Resolves all HA_OPTION_TYPE_SYSVAR elements. + + This is done when an engine is loaded. +*/ +static bool resolve_sysvars(handlerton *hton, ha_create_table_option *rules) +{ + for (ha_create_table_option *opt= rules; opt && opt->name; opt++) + { + if (opt->type == HA_OPTION_TYPE_SYSVAR) + { + struct my_option optp; + plugin_opt_set_limits(&optp, opt->var); + switch(optp.var_type) { + case GET_ULL: + case GET_ULONG: + case GET_UINT: + opt->type= HA_OPTION_TYPE_ULL; + opt->def_value= (ulonglong)optp.def_value; + opt->min_value= (ulonglong)optp.min_value; + opt->max_value= (ulonglong)optp.max_value; + opt->block_size= (ulonglong)optp.block_size; + break; + case GET_STR: + case GET_STR_ALLOC: + opt->type= HA_OPTION_TYPE_STRING; + break; + case GET_BOOL: + opt->type= HA_OPTION_TYPE_BOOL; + opt->def_value= optp.def_value; + break; + case GET_ENUM: + { + opt->type= HA_OPTION_TYPE_ENUM; + opt->def_value= optp.def_value; + + char buf[256]; + String str(buf, sizeof(buf), system_charset_info); + for (const char **s= optp.typelib->type_names; *s; s++) + { + if (str.append(*s) || str.append(',')) + return 1; + } + DBUG_ASSERT(str.length()); + opt->values= my_strndup(str.ptr(), str.length()-1, MYF(MY_WME)); + if (!opt->values) + return 1; + break; + } + default: + DBUG_ASSERT(0); + } + } + } + return 0; +} + +bool resolve_sysvar_table_options(handlerton *hton) +{ + return resolve_sysvars(hton, hton->table_options) || + resolve_sysvars(hton, hton->field_options) || + resolve_sysvars(hton, hton->index_options); +} + +/* + Restore HA_OPTION_TYPE_SYSVAR options back as they were + before resolve_sysvars(). + + This is done when the engine is unloaded, so that we could + call resolve_sysvars() if the engine is installed again. +*/ +static void free_sysvars(handlerton *hton, ha_create_table_option *rules) +{ + for (ha_create_table_option *opt= rules; opt && opt->name; opt++) + { + if (opt->var) + { + my_free(const_cast(opt->values)); + opt->type= HA_OPTION_TYPE_SYSVAR; + opt->def_value= 0; + opt->min_value= 0; + opt->max_value= 0; + opt->block_size= 0; + opt->values= 0; + } + } +} + +void free_sysvar_table_options(handlerton *hton) +{ + free_sysvars(hton, hton->table_options); + free_sysvars(hton, hton->field_options); + free_sysvars(hton, hton->index_options); +} + + /** Parses all table/fields/keys options @@ -327,21 +467,22 @@ bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share) MEM_ROOT *root= &share->mem_root; DBUG_ENTER("parse_engine_table_options"); - if (parse_option_list(thd, &share->option_struct, share->option_list, + if (parse_option_list(thd, ht, &share->option_struct, & share->option_list, ht->table_options, TRUE, root)) DBUG_RETURN(TRUE); for (Field **field= share->field; *field; field++) { - if (parse_option_list(thd, &(*field)->option_struct, (*field)->option_list, + if (parse_option_list(thd, ht, &(*field)->option_struct, + & (*field)->option_list, ht->field_options, TRUE, root)) DBUG_RETURN(TRUE); } for (uint index= 0; index < share->keys; index ++) { - if (parse_option_list(thd, &share->key_info[index].option_struct, - share->key_info[index].option_list, + if (parse_option_list(thd, ht, &share->key_info[index].option_struct, + & share->key_info[index].option_list, ht->index_options, TRUE, root)) DBUG_RETURN(TRUE); } diff --git a/sql/create_options.h b/sql/create_options.h index 5db826a3038..ea05bf75fac 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -69,9 +69,11 @@ class engine_option_value: public Sql_alloc typedef struct st_key KEY; class Create_field; +bool resolve_sysvar_table_options(handlerton *hton); +void free_sysvar_table_options(handlerton *hton); bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share); -bool parse_option_list(THD* thd, void *option_struct, - engine_option_value *option_list, +bool parse_option_list(THD* thd, handlerton *hton, void *option_struct, + engine_option_value **option_list, ha_create_table_option *rules, bool suppress_warning, MEM_ROOT *root); bool engine_table_options_frm_read(const uchar *buff, uint length, diff --git a/sql/handler.cc b/sql/handler.cc index f094ff7bebb..2061b92c4e4 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -448,6 +448,9 @@ int ha_finalize_handlerton(st_plugin_int *plugin) } } + free_sysvar_table_options(hton); + update_discovery_counters(hton, -1); + /* In case a plugin is uninstalled and re-installed later, it should reuse an array slot. Otherwise the number of uninstall/install @@ -461,8 +464,6 @@ int ha_finalize_handlerton(st_plugin_int *plugin) hton2plugin[hton->slot]= NULL; } - update_discovery_counters(hton, -1); - my_free(hton); end: @@ -603,6 +604,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin) break; }; + resolve_sysvar_table_options(hton); update_discovery_counters(hton, 1); DBUG_RETURN(0); diff --git a/sql/handler.h b/sql/handler.h index 2290b8f37fd..12f6b8808b3 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -714,22 +714,26 @@ struct ha_index_option_struct; enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_OPTION_TYPE_STRING, /* char * */ HA_OPTION_TYPE_ENUM, /* uint */ - HA_OPTION_TYPE_BOOL}; /* bool */ + HA_OPTION_TYPE_BOOL, /* bool */ + HA_OPTION_TYPE_SYSVAR};/* type of the sysval */ #define HA_xOPTION_NUMBER(name, struc, field, def, min, max, blk_siz) \ { HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \ - offsetof(struc, field), def, min, max, blk_siz, 0 } + offsetof(struc, field), def, min, max, blk_siz, 0, 0 } #define HA_xOPTION_STRING(name, struc, field) \ { HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \ - offsetof(struc, field), 0, 0, 0, 0, 0 } + offsetof(struc, field), 0, 0, 0, 0, 0, 0} #define HA_xOPTION_ENUM(name, struc, field, values, def) \ { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \ offsetof(struc, field), def, 0, \ - sizeof(values)-1, 0, values } + sizeof(values)-1, 0, values, 0 } #define HA_xOPTION_BOOL(name, struc, field, def) \ { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \ - offsetof(struc, field), def, 0, 1, 0, 0 } -#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 } + offsetof(struc, field), def, 0, 1, 0, 0, 0 } +#define HA_xOPTION_SYSVAR(name, struc, field, sysvar) \ + { HA_OPTION_TYPE_SYSVAR, name, sizeof(name)-1, \ + offsetof(struc, field), 0, 0, 0, 0, 0, MYSQL_SYSVAR(sysvar) } +#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0, 0 } #define HA_TOPTION_NUMBER(name, field, def, min, max, blk_siz) \ HA_xOPTION_NUMBER(name, ha_table_option_struct, field, def, min, max, blk_siz) @@ -739,6 +743,8 @@ enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def) #define HA_TOPTION_BOOL(name, field, def) \ HA_xOPTION_BOOL(name, ha_table_option_struct, field, def) +#define HA_TOPTION_SYSVAR(name, field, sysvar) \ + HA_xOPTION_SYSVAR(name, ha_table_option_struct, field, sysvar) #define HA_TOPTION_END HA_xOPTION_END #define HA_FOPTION_NUMBER(name, field, def, min, max, blk_siz) \ @@ -749,6 +755,8 @@ enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def) #define HA_FOPTION_BOOL(name, field, def) \ HA_xOPTION_BOOL(name, ha_field_option_struct, field, def) +#define HA_FOPTION_SYSVAR(name, field, sysvar) \ + HA_xOPTION_SYSVAR(name, ha_field_option_struct, field, sysvar) #define HA_FOPTION_END HA_xOPTION_END #define HA_IOPTION_NUMBER(name, field, def, min, max, blk_siz) \ @@ -759,6 +767,8 @@ enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_xOPTION_ENUM(name, ha_index_option_struct, field, values, def) #define HA_IOPTION_BOOL(name, field, values, def) \ HA_xOPTION_BOOL(name, ha_index_option_struct, field, values, def) +#define HA_IOPTION_SYSVAR(name, field, sysvar) \ + HA_xOPTION_SYSVAR(name, ha_index_option_struct, field, sysvar) #define HA_IOPTION_END HA_xOPTION_END typedef struct st_ha_create_table_option { @@ -769,6 +779,7 @@ typedef struct st_ha_create_table_option { ulonglong def_value; ulonglong min_value, max_value, block_size; const char *values; + struct st_mysql_sys_var *var; } ha_create_table_option; enum handler_iterator_type @@ -1197,6 +1208,11 @@ static inline LEX_STRING *hton_name(const handlerton *hton) return &(hton2plugin[hton->slot]->name); } +static inline sys_var *find_hton_sysvar(handlerton *hton, st_mysql_sys_var *var) +{ + return find_plugin_sysvar(hton2plugin[hton->slot], var); +} + /* Possible flags of a handlerton (there can be 32 of them) */ #define HTON_NO_FLAGS 0 diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index b19d6853164..6cf1050998b 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -308,8 +308,6 @@ static void unlock_variables(THD *thd, struct system_variables *vars); static void cleanup_variables(THD *thd, struct system_variables *vars); static void plugin_vars_free_values(sys_var *vars); static void restore_pluginvar_names(sys_var *first); -static void plugin_opt_set_limits(struct my_option *, - const struct st_mysql_sys_var *); static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin); static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void reap_plugins(void); @@ -3286,8 +3284,8 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var) options->block_size= (long) (opt)->blk_sz -static void plugin_opt_set_limits(struct my_option *options, - const struct st_mysql_sys_var *opt) +void plugin_opt_set_limits(struct my_option *options, + const struct st_mysql_sys_var *opt) { options->sub_size= 0; @@ -3866,3 +3864,18 @@ void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root) } } + +/** + Returns a sys_var corresponding to a particular MYSQL_SYSVAR(...) +*/ +sys_var *find_plugin_sysvar(st_plugin_int *plugin, st_mysql_sys_var *plugin_var) +{ + for (sys_var *var= plugin->system_vars; var; var= var->next) + { + sys_var_pluginvar *pvar=var->cast_pluginvar(); + if (pvar->plugin_var == plugin_var) + return var; + } + return 0; +} + diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index d3c41a1e17b..bf4dbef6fc8 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -163,6 +163,8 @@ extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, extern bool plugin_register_builtin(struct st_mysql_plugin *plugin); extern void plugin_thdvar_init(THD *thd); extern void plugin_thdvar_cleanup(THD *thd); +sys_var *find_plugin_sysvar(st_plugin_int *plugin, st_mysql_sys_var *var); +void plugin_opt_set_limits(struct my_option *, const struct st_mysql_sys_var *); extern SHOW_COMP_OPTION plugin_status(const char *name, size_t len, int type); extern bool check_valid_path(const char *path, size_t length); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dd00d921b6e..39c297fb5a2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3224,8 +3224,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->offset= record_offset; if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) auto_increment++; - if (parse_option_list(thd, &sql_field->option_struct, - sql_field->option_list, + if (parse_option_list(thd, create_info->db_type, &sql_field->option_struct, + &sql_field->option_list, create_info->db_type->field_options, FALSE, thd->mem_root)) DBUG_RETURN(TRUE); @@ -3427,8 +3427,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_info->usable_key_parts= key_number; key_info->algorithm= key->key_create_info.algorithm; key_info->option_list= key->option_list; - if (parse_option_list(thd, &key_info->option_struct, - key_info->option_list, + if (parse_option_list(thd, create_info->db_type, &key_info->option_struct, + &key_info->option_list, create_info->db_type->index_options, FALSE, thd->mem_root)) DBUG_RETURN(TRUE); @@ -3874,8 +3874,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, file->engine_name()->str, "TRANSACTIONAL=1"); - if (parse_option_list(thd, &create_info->option_struct, - create_info->option_list, + if (parse_option_list(thd, file->partition_ht(), &create_info->option_struct, + &create_info->option_list, file->partition_ht()->table_options, FALSE, thd->mem_root)) DBUG_RETURN(TRUE); diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index dac1ff81c10..bcf934b6b1c 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -118,6 +118,8 @@ static HASH example_open_tables; /* The mutex used to init the hash; variable for example share methods */ mysql_mutex_t example_mutex; +static MYSQL_THDVAR_ULONG(varopt_default, PLUGIN_VAR_RQCMDARG, + "default value of the VAROPT table option", NULL, NULL, 5, 0, 100, 0); /** Structure for CREATE TABLE options (table options). @@ -133,6 +135,7 @@ struct ha_table_option_struct ulonglong ullparam; uint enumparam; bool boolparam; + ulonglong varparam; }; @@ -179,6 +182,12 @@ ha_create_table_option example_table_option_list[]= The default is 1, that is true, yes, on. */ HA_TOPTION_BOOL("YESNO", boolparam, 1), + /* + one option defined by the system variable. The type, the range, or + a list of allowed values is the same as for the system variable. + */ + HA_TOPTION_SYSVAR("VAROPT", varparam, varopt_default), + HA_TOPTION_END }; @@ -1089,6 +1098,7 @@ static MYSQL_SYSVAR_ULONG( static struct st_mysql_sys_var* example_system_variables[]= { MYSQL_SYSVAR(enum_var), MYSQL_SYSVAR(ulong_var), + MYSQL_SYSVAR(varopt_default), NULL }; From c7eead7a965b33fbad5099c927d2bb0723725bf3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:29 +0200 Subject: [PATCH 80/87] MDEV-3807 show plugins soname 'xxx' and INFORMATION_SCHEMA.ALL_PLUGINS table with condition pushdown for I_S.ALL_PLUGINS and a new status variable to cound successful dlopen's --- mysql-test/r/information_schema-big.result | 2 + mysql-test/r/information_schema.result | 4 +- .../r/information_schema_all_engines.result | 10 +- .../suite/funcs_1/r/is_columns_is.result | 30 +++++- .../funcs_1/r/is_columns_is_embedded.result | 30 +++++- .../suite/funcs_1/r/is_tables_is.result | 46 +++++++++ .../funcs_1/r/is_tables_is_embedded.result | 46 +++++++++ .../suite/plugins/r/show_all_plugins.result | 35 +++++++ .../suite/plugins/t/show_all_plugins.test | 22 +++++ .../suite/rpl/r/rpl_table_options.result | 2 +- .../t/information_schema_all_engines.test | 2 +- sql/handler.h | 1 + sql/mysqld.cc | 11 ++- sql/sql_plugin.cc | 74 ++++++++++++++- sql/sql_plugin.h | 4 + sql/sql_show.cc | 93 +++++++++++++++++-- sql/sql_yacc.yy | 14 +++ 17 files changed, 402 insertions(+), 24 deletions(-) create mode 100644 mysql-test/suite/plugins/r/show_all_plugins.result create mode 100644 mysql-test/suite/plugins/t/show_all_plugins.test diff --git a/mysql-test/r/information_schema-big.result b/mysql-test/r/information_schema-big.result index 3d4fa27859d..c0016a8e5c3 100644 --- a/mysql-test/r/information_schema-big.result +++ b/mysql-test/r/information_schema-big.result @@ -36,6 +36,7 @@ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME +ALL_PLUGINS PLUGIN_NAME PROCESSLIST ID PROFILING QUERY_ID REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA @@ -88,6 +89,7 @@ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME +ALL_PLUGINS PLUGIN_NAME PROCESSLIST ID PROFILING QUERY_ID REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index a30fe668490..a7051f275d7 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -46,6 +46,7 @@ table_name not like 'ndb_%' AND table_name not like 'innodb_%' AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%'; select * from v1; c +ALL_PLUGINS CHARACTER_SETS CLIENT_STATISTICS COLLATIONS @@ -802,6 +803,7 @@ information_schema PARTITIONS PARTITION_EXPRESSION information_schema PARTITIONS SUBPARTITION_EXPRESSION information_schema PARTITIONS PARTITION_DESCRIPTION information_schema PLUGINS PLUGIN_DESCRIPTION +information_schema ALL_PLUGINS PLUGIN_DESCRIPTION information_schema PROCESSLIST INFO information_schema ROUTINES DTD_IDENTIFIER information_schema ROUTINES ROUTINE_DEFINITION @@ -1180,7 +1182,7 @@ group by column_type order by num; column_type group_concat(table_schema, '.', table_name) num varchar(27) information_schema.COLUMNS 1 varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2 -varchar(20) information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PROFILING 6 +varchar(20) information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.PROFILING 9 create table t1(f1 char(1) not null, f2 char(9) not null) default character set utf8; select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result index 455f2e36ffc..8b1aff8a209 100644 --- a/mysql-test/r/information_schema_all_engines.result +++ b/mysql-test/r/information_schema_all_engines.result @@ -1,6 +1,7 @@ use INFORMATION_SCHEMA; show tables; Tables_in_information_schema +ALL_PLUGINS CHARACTER_SETS CLIENT_STATISTICS COLLATIONS @@ -74,6 +75,7 @@ c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' ) order by t.table_name; table_name column_name +ALL_PLUGINS PLUGIN_NAME CHARACTER_SETS CHARACTER_SET_NAME CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME @@ -147,6 +149,7 @@ c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' ) order by t.table_name; table_name column_name +ALL_PLUGINS PLUGIN_NAME CHARACTER_SETS CHARACTER_SET_NAME CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME @@ -205,7 +208,7 @@ USER_PRIVILEGES GRANTEE USER_STATISTICS USER VIEWS TABLE_SCHEMA XTRADB_ADMIN_COMMAND result_message -select 1 as f1 from information_schema.tables where "CHARACTER_SETS"= +select 1 as f1 from information_schema.tables where "ALL_PLUGINS"= (select cast(table_name as char) from information_schema.tables order by table_name limit 1) limit 1; f1 @@ -226,6 +229,7 @@ c2.table_schema='information_schema' and group by c2.column_type order by num limit 1) group by t.table_name order by num1, t.table_name; table_name group_concat(t.table_schema, '.', t.table_name) num1 +ALL_PLUGINS information_schema.ALL_PLUGINS 1 CHARACTER_SETS information_schema.CHARACTER_SETS 1 CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1 COLLATIONS information_schema.COLLATIONS 1 @@ -288,6 +292,7 @@ VIEWS information_schema.VIEWS 1 +---------------------------------------+ Database: information_schema | Tables | +| ALL_PLUGINS | | CHARACTER_SETS | | CLIENT_STATISTICS | | COLLATIONS | @@ -351,6 +356,7 @@ Database: information_schema +---------------------------------------+ Database: INFORMATION_SCHEMA | Tables | +| ALL_PLUGINS | | CHARACTER_SETS | | CLIENT_STATISTICS | | COLLATIONS | @@ -417,5 +423,5 @@ Wildcard: inf_rmation_schema | information_schema | SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 58 +information_schema 59 mysql 26 diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index e161e8ed058..8bf290ba168 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -3,6 +3,19 @@ WHERE table_schema = 'information_schema' AND table_name <> 'profiling' AND table_name not like 'innodb_%' ORDER BY table_schema, table_name, column_name; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +def information_schema ALL_PLUGINS LOAD_OPTION 11 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION 13 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select +def information_schema ALL_PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select +def information_schema ALL_PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select +def information_schema ALL_PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select +def information_schema ALL_PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select +def information_schema ALL_PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select +def information_schema ALL_PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select +def information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select +def information_schema ALL_PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select def information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) select @@ -215,7 +228,7 @@ def information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 N def information_schema PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select def information_schema PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select def information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select -def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) select +def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select def information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select def information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select def information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select @@ -473,6 +486,19 @@ WHERE table_schema = 'information_schema' AND table_name <> 'profiling' AND table_name not like 'innodb_%' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION; COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE +3.0000 information_schema ALL_PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64) +1.0000 information_schema ALL_PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext +3.0000 information_schema ALL_PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS LOAD_OPTION varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema CHARACTER_SETS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60) @@ -678,7 +704,7 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema PARTITIONS TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) -3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 10 30 utf8 utf8_general_ci varchar(10) +3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) 3.0000 information_schema PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) 3.0000 information_schema PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index 003f506fee8..ba5166691c1 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -4,6 +4,19 @@ AND table_name <> 'profiling' AND table_name not like 'innodb_%' AND table_name not like 'pbxt_%' ORDER BY table_schema, table_name, column_name; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +def information_schema ALL_PLUGINS LOAD_OPTION 11 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION 13 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) +def information_schema ALL_PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext +def information_schema ALL_PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) +def information_schema ALL_PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) +def information_schema ALL_PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) +def information_schema ALL_PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) +def information_schema ALL_PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) +def information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) +def information_schema ALL_PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) def information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) @@ -216,7 +229,7 @@ def information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 N def information_schema PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) def information_schema PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) def information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) -def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) +def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) def information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) def information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) def information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) @@ -478,6 +491,19 @@ AND table_name <> 'profiling' AND table_name not like 'innodb_%' AND table_name not like 'pbxt_%' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION; COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE +3.0000 information_schema ALL_PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64) +1.0000 information_schema ALL_PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext +3.0000 information_schema ALL_PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS LOAD_OPTION varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema CHARACTER_SETS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60) @@ -683,7 +709,7 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema PARTITIONS TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) -3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 10 30 utf8 utf8_general_ci varchar(10) +3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) 3.0000 information_schema PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) 3.0000 information_schema PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index 6aa2e3bb93d..6e92285dbaf 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -16,6 +16,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -816,6 +839,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result index 6aa2e3bb93d..6e92285dbaf 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result @@ -16,6 +16,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -816,6 +839,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY diff --git a/mysql-test/suite/plugins/r/show_all_plugins.result b/mysql-test/suite/plugins/r/show_all_plugins.result new file mode 100644 index 00000000000..8b9a41e0e1f --- /dev/null +++ b/mysql-test/suite/plugins/r/show_all_plugins.result @@ -0,0 +1,35 @@ +flush status; +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 0 +select * from information_schema.all_plugins where plugin_library='ha_example.so'; +PLUGIN_NAME PLUGIN_VERSION PLUGIN_STATUS PLUGIN_TYPE PLUGIN_TYPE_VERSION PLUGIN_LIBRARY PLUGIN_LIBRARY_VERSION PLUGIN_AUTHOR PLUGIN_DESCRIPTION PLUGIN_LICENSE LOAD_OPTION PLUGIN_MATURITY PLUGIN_AUTH_VERSION +EXAMPLE 0.1 NOT INSTALLED STORAGE ENGINE 100001.0 ha_example.so 1.4 Brian Aker, MySQL AB Example storage engine GPL OFF Experimental 0.1 +UNUSABLE 3.14 NOT INSTALLED DAEMON 100001.0 ha_example.so 1.4 Sergei Golubchik Unusable Daemon GPL OFF Experimental 3.14.15.926 +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 1 +show plugins soname 'ha_example.so'; +Name Status Type Library License +EXAMPLE NOT INSTALLED STORAGE ENGINE ha_example.so GPL +UNUSABLE NOT INSTALLED DAEMON ha_example.so GPL +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 2 +show plugins soname like '%example%'; +Name Status Type Library License +EXAMPLE NOT INSTALLED STORAGE ENGINE ha_example.so GPL +UNUSABLE NOT INSTALLED DAEMON ha_example.so GPL +daemon_example NOT INSTALLED DAEMON libdaemon_example.so GPL +three_attempts NOT INSTALLED AUTHENTICATION dialog_examples.so GPL +two_questions NOT INSTALLED AUTHENTICATION dialog_examples.so GPL +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 6 +show plugins soname where library = 'ha_example.so'; +Name Status Type Library License +EXAMPLE NOT INSTALLED STORAGE ENGINE ha_example.so GPL +UNUSABLE NOT INSTALLED DAEMON ha_example.so GPL +select variable_value > 10 from information_schema.global_status where variable_name like '%libraries%'; +variable_value > 10 +1 diff --git a/mysql-test/suite/plugins/t/show_all_plugins.test b/mysql-test/suite/plugins/t/show_all_plugins.test new file mode 100644 index 00000000000..dcc0fb09bd3 --- /dev/null +++ b/mysql-test/suite/plugins/t/show_all_plugins.test @@ -0,0 +1,22 @@ +if (!$DIALOG_EXAMPLES_SO) { skip requires dialog_examples.so; } +if (!$HA_EXAMPLE_SO) { skip requires ha_examples.so; } +if (!$LIBDAEMON_EXAMPLE_SO) { skip requires libdaemon_examples.so; } +if (!$UDF_EXAMPLE_SO) { skip requires udf_example.so; } + +flush status; +show status like '%libraries%'; +#--sorted_result +#select * from information_schema.all_plugins; +#show status like '%libraries%'; +select * from information_schema.all_plugins where plugin_library='ha_example.so'; +show status like '%libraries%'; +--sorted_result +show plugins soname 'ha_example.so'; +show status like '%libraries%'; +--sorted_result +show plugins soname like '%example%'; +show status like '%libraries%'; +--sorted_result +show plugins soname where library = 'ha_example.so'; +select variable_value > 10 from information_schema.global_status where variable_name like '%libraries%'; + diff --git a/mysql-test/suite/rpl/r/rpl_table_options.result b/mysql-test/suite/rpl/r/rpl_table_options.result index 423a2b65583..d69570a1709 100644 --- a/mysql-test/suite/rpl/r/rpl_table_options.result +++ b/mysql-test/suite/rpl/r/rpl_table_options.result @@ -7,7 +7,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 `VAROPT`='5' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/t/information_schema_all_engines.test b/mysql-test/t/information_schema_all_engines.test index 553367d2b9a..73ed00376ab 100644 --- a/mysql-test/t/information_schema_all_engines.test +++ b/mysql-test/t/information_schema_all_engines.test @@ -49,7 +49,7 @@ SELECT t.table_name, c1.column_name # # Bug#24630 Subselect query crashes mysqld # -select 1 as f1 from information_schema.tables where "CHARACTER_SETS"= +select 1 as f1 from information_schema.tables where "ALL_PLUGINS"= (select cast(table_name as char) from information_schema.tables order by table_name limit 1) limit 1; diff --git a/sql/handler.h b/sql/handler.h index 12f6b8808b3..18639b6a8a4 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -610,6 +610,7 @@ enum enum_schema_tables SCH_PARAMETERS, SCH_PARTITIONS, SCH_PLUGINS, + SCH_ALL_PLUGINS, SCH_PROCESSLIST, SCH_PROFILES, SCH_REFERENTIAL_CONSTRAINTS, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d8e603d3009..64cc94fa8bd 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7105,8 +7105,8 @@ SHOW_VAR status_vars[]= { {"Feature_locale", (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS}, {"Feature_subquery", (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS}, {"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS}, - {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS}, - {"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS}, + {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS}, + {"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS}, {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH}, {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, @@ -7114,8 +7114,8 @@ SHOW_VAR status_vars[]= { {"Handler_icp_attempts", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS}, {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS}, {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS}, - {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, - {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, + {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, + {"Handler_mrr_rowid_refills",(char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, @@ -7142,9 +7142,10 @@ SHOW_VAR status_vars[]= { {"Open_table_definitions", (char*) &show_table_definitions, SHOW_SIMPLE_FUNC}, {"Open_tables", (char*) &show_open_tables, SHOW_SIMPLE_FUNC}, {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH}, + {"Opened_plugin_libraries", (char*) &dlopen_count, SHOW_LONG}, {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}, {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, - {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS}, + {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS}, {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_SIMPLE_FUNC}, {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 6cf1050998b..8d2379d7738 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -53,7 +53,6 @@ static TYPELIB global_plugin_typelib= { array_elements(global_plugin_typelib_names)-1, "", global_plugin_typelib_names, NULL }; - char *opt_plugin_load= NULL; char *opt_plugin_dir_ptr; char opt_plugin_dir[FN_REFLEN]; @@ -197,6 +196,8 @@ static bool reap_needed= false; static int plugin_array_version=0; static bool initialized= 0; +ulong dlopen_count; + /* write-lock on LOCK_system_variables_hash is required before modifying @@ -746,6 +747,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg); goto ret; } + dlopen_count++; /* Checks which plugin interface present and reads info */ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym))) @@ -1485,6 +1487,8 @@ int plugin_init(int *argc, char **argv, int flags) if (initialized) DBUG_RETURN(0); + dlopen_count =0; + #ifdef HAVE_PSI_INTERFACE init_plugin_psi_keys(); #endif @@ -2333,6 +2337,74 @@ err: } +static bool plugin_dl_foreach_internal(THD *thd, st_plugin_dl *plugin_dl, + st_maria_plugin *plug, + plugin_foreach_func *func, void *arg) +{ + for (; plug->name; plug++) + { + st_plugin_int tmp, *plugin; + + tmp.name.str= const_cast(plug->name); + tmp.name.length= strlen(plug->name); + tmp.plugin= plug; + tmp.plugin_dl= plugin_dl; + + mysql_mutex_lock(&LOCK_plugin); + if ((plugin= plugin_find_internal(&tmp.name, MYSQL_ANY_PLUGIN)) && + plugin->plugin == plug) + + { + tmp.state= plugin->state; + tmp.load_option= plugin->load_option; + } + else + { + tmp.state= PLUGIN_IS_FREED; + tmp.load_option= PLUGIN_OFF; + } + mysql_mutex_unlock(&LOCK_plugin); + + plugin= &tmp; + if (func(thd, plugin_int_to_ref(plugin), arg)) + return 1; + } + return 0; +} + +bool plugin_dl_foreach(THD *thd, const LEX_STRING *dl, + plugin_foreach_func *func, void *arg) +{ + bool err= 0; + + if (dl) + { + mysql_mutex_lock(&LOCK_plugin); + st_plugin_dl *plugin_dl= plugin_dl_add(dl, REPORT_TO_USER); + mysql_mutex_unlock(&LOCK_plugin); + + if (!plugin_dl) + return 1; + + err= plugin_dl_foreach_internal(thd, plugin_dl, plugin_dl->plugins, + func, arg); + + mysql_mutex_lock(&LOCK_plugin); + plugin_dl_del(plugin_dl); + mysql_mutex_unlock(&LOCK_plugin); + } + else + { + struct st_maria_plugin **builtins; + for (builtins= mysql_mandatory_plugins; !err && *builtins; builtins++) + err= plugin_dl_foreach_internal(thd, 0, *builtins, func, arg); + for (builtins= mysql_optional_plugins; !err && *builtins; builtins++) + err= plugin_dl_foreach_internal(thd, 0, *builtins, func, arg); + } + return err; +} + + /**************************************************************************** Internal type declarations for variables support ****************************************************************************/ diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index bf4dbef6fc8..11c91fe93eb 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -39,6 +39,8 @@ enum enum_plugin_load_option { PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE, PLUGIN_FORCE_PLUS_PERMANENT }; extern const char *global_plugin_typelib_names[]; +extern ulong dlopen_count; + #include #ifdef DBUG_OFF @@ -174,4 +176,6 @@ typedef my_bool (plugin_foreach_func)(THD *thd, #define plugin_foreach(A,B,C,D) plugin_foreach_with_mask(A,B,C,PLUGIN_IS_READY,D) extern bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, int type, uint state_mask, void *arg); +extern bool plugin_dl_foreach(THD *thd, const LEX_STRING *dl, + plugin_foreach_func *func, void *arg); #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a0fa9807b29..eea1289015a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -119,6 +119,14 @@ append_algorithm(TABLE_LIST *table, String *buff); static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table); +typedef struct st_lookup_field_values +{ + LEX_STRING db_value, table_value; + bool wild_db_value, wild_table_value; +} LOOKUP_FIELD_VALUES; + +bool get_lookup_field_values(THD *, COND *, TABLE_LIST *, LOOKUP_FIELD_VALUES *); + /*************************************************************************** ** List all table types supported ***************************************************************************/ @@ -157,7 +165,6 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, cs); switch (plugin_state(plugin)) { - /* case PLUGIN_IS_FREED: does not happen */ case PLUGIN_IS_DELETED: table->field[2]->store(STRING_WITH_LEN("DELETED"), cs); break; @@ -170,6 +177,9 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, case PLUGIN_IS_DISABLED: table->field[2]->store(STRING_WITH_LEN("DISABLED"), cs); break; + case PLUGIN_IS_FREED: // filtered in fill_plugins, used in fill_all_plugins + table->field[2]->store(STRING_WITH_LEN("NOT INSTALLED"), cs); + break; default: DBUG_ASSERT(0); } @@ -267,6 +277,65 @@ int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond) } +int fill_all_plugins(THD *thd, TABLE_LIST *tables, COND *cond) +{ + DBUG_ENTER("fill_all_plugins"); + TABLE *table= tables->table; + LOOKUP_FIELD_VALUES lookup; + + if (get_lookup_field_values(thd, cond, tables, &lookup)) + DBUG_RETURN(0); + + if (lookup.db_value.str && !lookup.db_value.str[0]) + DBUG_RETURN(0); // empty string never matches a valid SONAME + + MY_DIR *dirp= my_dir(opt_plugin_dir, MY_THREAD_SPECIFIC); + if (!dirp) + { + my_error(ER_CANT_READ_DIR, MYF(0), opt_plugin_dir, my_errno); + DBUG_RETURN(1); + } + + if (!lookup.db_value.str) + plugin_dl_foreach(thd, 0, show_plugins, table); + + const char *wstr= lookup.db_value.str, *wend= wstr + lookup.db_value.length; + for (uint i=0; i < (uint) dirp->number_of_files; i++) + { + FILEINFO *file= dirp->dir_entry+i; + LEX_STRING dl= { file->name, strlen(file->name) }; + const char *dlend= dl.str + dl.length; + const size_t so_ext_len= sizeof(SO_EXT) - 1; + + if (strcasecmp(dlend - so_ext_len, SO_EXT)) + continue; + + if (lookup.db_value.str) + { + if (lookup.wild_db_value) + { + if (my_wildcmp(files_charset_info, dl.str, dlend, wstr, wend, + wild_prefix, wild_one, wild_many)) + continue; + } + else + { + if (my_strnncoll(files_charset_info, + (uchar*)dl.str, dl.length, + (uchar*)lookup.db_value.str, lookup.db_value.length)) + continue; + } + } + + plugin_dl_foreach(thd, &dl, show_plugins, table); + thd->clear_error(); + } + + my_dirend(dirp); + DBUG_RETURN(0); +} + + /*************************************************************************** ** List all Authors. ** If you can update it, you get to be in it :) @@ -3260,13 +3329,6 @@ void calc_sum_of_all_status(STATUS_VAR *to) /* This is only used internally, but we need it here as a forward reference */ extern ST_SCHEMA_TABLE schema_tables[]; -typedef struct st_lookup_field_values -{ - LEX_STRING db_value, table_value; - bool wild_db_value, wild_table_value; -} LOOKUP_FIELD_VALUES; - - /* Store record to I_S table, convert HEAP table to MyISAM if necessary @@ -3587,6 +3649,17 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, lookup_field_values->wild_table_value= 1; } break; + case SQLCOM_SHOW_PLUGINS: + if (lex->ident.str) + thd->make_lex_string(&lookup_field_values->db_value, + lex->ident.str, lex->ident.length); + else if (lex->wild) + { + thd->make_lex_string(&lookup_field_values->db_value, + lex->wild->ptr(), lex->wild->length()); + lookup_field_values->wild_db_value= 1; + } + break; default: /* The "default" is for queries over I_S. @@ -8558,7 +8631,7 @@ ST_FIELD_INFO plugin_fields_info[]= {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN_TABLE}, {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, - {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, + {"PLUGIN_STATUS", 16, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE}, {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library", @@ -8819,6 +8892,8 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"PLUGINS", plugin_fields_info, create_schema_table, fill_plugins, make_old_format, 0, -1, -1, 0, 0}, + {"ALL_PLUGINS", plugin_fields_info, create_schema_table, + fill_all_plugins, make_old_format, 0, 5, -1, 0, 0}, {"PROCESSLIST", processlist_fields_info, create_schema_table, fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0}, {"PROFILING", query_profile_statistics_info, create_schema_table, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 68319da9cf2..0c3a016fa28 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11449,6 +11449,7 @@ show: { LEX *lex=Lex; lex->wild=0; + lex->ident=null_lex_str; mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; bzero((char*) &lex->create_info,sizeof(lex->create_info)); @@ -11512,6 +11513,19 @@ show_param: if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS)) MYSQL_YYABORT; } + | PLUGINS_SYM SONAME_SYM TEXT_STRING_sys + { + Lex->ident= $3; + Lex->sql_command= SQLCOM_SHOW_PLUGINS; + if (prepare_schema_table(YYTHD, Lex, 0, SCH_ALL_PLUGINS)) + MYSQL_YYABORT; + } + | PLUGINS_SYM SONAME_SYM wild_and_where + { + Lex->sql_command= SQLCOM_SHOW_PLUGINS; + if (prepare_schema_table(YYTHD, Lex, 0, SCH_ALL_PLUGINS)) + MYSQL_YYABORT; + } | ENGINE_SYM known_storage_engines show_engine_param { Lex->create_info.db_type= $2; } | ENGINE_SYM ALL show_engine_param From 775e82638b825747a2a8b7cf7d6d29c872693422 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:33 +0200 Subject: [PATCH 81/87] put status variables in the proper pluginname_ scope (but support the scopeless mysql style too). always output status/system variables in the correct lettercase --- mysql-test/r/plugin.result | 2 +- mysql-test/suite/plugins/r/audit_null.result | 4 +- plugin/audit_null/audit_null.c | 10 ++--- plugin/auth_socket/auth_socket.c | 17 -------- plugin/daemon_example/daemon_example.cc | 17 -------- plugin/fulltext/plugin_example.c | 18 -------- plugin/sql_errlog/sql_errlog.c | 18 -------- sql/sql_plugin.cc | 45 +++++++++----------- sql/sql_show.cc | 13 +++++- storage/cassandra/ha_cassandra.cc | 14 +++--- storage/example/ha_example.cc | 2 +- storage/maria/ha_maria.cc | 7 +-- 12 files changed, 49 insertions(+), 118 deletions(-) diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 06e343a0886..0eb49584c4a 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -44,7 +44,7 @@ set global example_ulong_var=500; set global example_enum_var= e1; show status like 'example%'; Variable_name Value -example_func_example enum_var is 0, ulong_var is 500, really +Example_func_example enum_var is 0, ulong_var is 500, really show variables like 'example%'; Variable_name Value example_enum_var e1 diff --git a/mysql-test/suite/plugins/r/audit_null.result b/mysql-test/suite/plugins/r/audit_null.result index 4cf648510e6..2b1b64a9d85 100644 --- a/mysql-test/suite/plugins/r/audit_null.result +++ b/mysql-test/suite/plugins/r/audit_null.result @@ -9,8 +9,8 @@ ERROR 42S22: Unknown column 'foobar' in 'field list' show status like 'audit_null%'; Variable_name Value Audit_null_called 9 -Audit_null_general_error 1 Audit_null_general_log 3 +Audit_null_general_error 1 Audit_null_general_result 2 create procedure au1(x char(16)) select concat("test1", x); call au1("-12"); @@ -19,8 +19,8 @@ test1-12 show status like 'audit_null%'; Variable_name Value Audit_null_called 19 -Audit_null_general_error 1 Audit_null_general_log 7 +Audit_null_general_error 1 Audit_null_general_result 5 uninstall plugin audit_null; Warnings: diff --git a/plugin/audit_null/audit_null.c b/plugin/audit_null/audit_null.c index be0c70fbd35..0616f192f20 100644 --- a/plugin/audit_null/audit_null.c +++ b/plugin/audit_null/audit_null.c @@ -127,12 +127,10 @@ static struct st_mysql_audit audit_null_descriptor= static struct st_mysql_show_var simple_status[]= { - { "Audit_null_called", (char *) &number_of_calls, SHOW_INT }, - { "Audit_null_general_log", (char *) &number_of_calls_general_log, SHOW_INT }, - { "Audit_null_general_error", (char *) &number_of_calls_general_error, - SHOW_INT }, - { "Audit_null_general_result", (char *) &number_of_calls_general_result, - SHOW_INT }, + { "called", (char *) &number_of_calls, SHOW_INT }, + { "general_log", (char *) &number_of_calls_general_log, SHOW_INT }, + { "general_error", (char *) &number_of_calls_general_error, SHOW_INT }, + { "general_result", (char *) &number_of_calls_general_result, SHOW_INT }, { 0, 0, 0} }; diff --git a/plugin/auth_socket/auth_socket.c b/plugin/auth_socket/auth_socket.c index 41cb1039fd2..78d7e769f7b 100644 --- a/plugin/auth_socket/auth_socket.c +++ b/plugin/auth_socket/auth_socket.c @@ -85,23 +85,6 @@ static struct st_mysql_auth socket_auth_handler= socket_auth }; -mysql_declare_plugin(socket_auth) -{ - MYSQL_AUTHENTICATION_PLUGIN, - &socket_auth_handler, - "unix_socket", - "Sergei Golubchik", - "Unix Socket based authentication", - PLUGIN_LICENSE_GPL, - NULL, - NULL, - 0x0100, - NULL, - NULL, - NULL, - 0, -} -mysql_declare_plugin_end; maria_declare_plugin(socket_auth) { MYSQL_AUTHENTICATION_PLUGIN, diff --git a/plugin/daemon_example/daemon_example.cc b/plugin/daemon_example/daemon_example.cc index ec2979de3c3..7d047b2eaf7 100644 --- a/plugin/daemon_example/daemon_example.cc +++ b/plugin/daemon_example/daemon_example.cc @@ -188,23 +188,6 @@ struct st_mysql_daemon daemon_example_plugin= Plugin library descriptor */ -mysql_declare_plugin(daemon_example) -{ - MYSQL_DAEMON_PLUGIN, - &daemon_example_plugin, - "daemon_example", - "Brian Aker", - "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log", - PLUGIN_LICENSE_GPL, - daemon_example_plugin_init, /* Plugin Init */ - daemon_example_plugin_deinit, /* Plugin Deinit */ - 0x0100 /* 1.0 */, - NULL, /* status variables */ - NULL, /* system variables */ - NULL, /* config options */ - 0, /* flags */ -} -mysql_declare_plugin_end; maria_declare_plugin(daemon_example) { MYSQL_DAEMON_PLUGIN, diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c index 981335bddd6..2af3555393c 100644 --- a/plugin/fulltext/plugin_example.c +++ b/plugin/fulltext/plugin_example.c @@ -254,24 +254,6 @@ static struct st_mysql_sys_var* simple_system_variables[]= { Plugin library descriptor */ -mysql_declare_plugin(ftexample) -{ - MYSQL_FTPARSER_PLUGIN, /* type */ - &simple_parser_descriptor, /* descriptor */ - "simple_parser", /* name */ - "Sergei Golubchik", /* author */ - "Simple Full-Text Parser", /* description */ - PLUGIN_LICENSE_GPL, - simple_parser_plugin_init, /* init function (when loaded) */ - simple_parser_plugin_deinit,/* deinit function (when unloaded) */ - 0x0001, /* version */ - simple_status, /* status variables */ - simple_system_variables, /* system variables */ - NULL, - 0, -} -mysql_declare_plugin_end; - maria_declare_plugin(ftexample) { MYSQL_FTPARSER_PLUGIN, /* type */ diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c index ce383916621..f84af963aca 100644 --- a/plugin/sql_errlog/sql_errlog.c +++ b/plugin/sql_errlog/sql_errlog.c @@ -144,24 +144,6 @@ static struct st_mysql_audit descriptor = { MYSQL_AUDIT_GENERAL_CLASSMASK } }; -mysql_declare_plugin(sql_errlog) -{ - MYSQL_AUDIT_PLUGIN, - &descriptor, - "SQL_ERROR_LOG", - "Alexey Botchkov", - "Log SQL level errors to a file with rotation", - PLUGIN_LICENSE_GPL, - sql_error_log_init, - sql_error_log_deinit, - 0x0100, - NULL, - vars, - NULL, - 0 -} -mysql_declare_plugin_end; - maria_declare_plugin(sql_errlog) { MYSQL_AUDIT_PLUGIN, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 8d2379d7738..e04a6f7c1eb 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1133,22 +1133,21 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check) if (plugin->plugin->status_vars) { -#ifdef FIX_LATER - /** - @todo - unfortunately, status variables were introduced without a - pluginname_ namespace, that is pluginname_ was not added automatically - to status variable names. It should be fixed together with the next - incompatible API change. + /* + historical ndb behavior caused MySQL plugins to specify + status var names in full, with the plugin name prefix. + this was never fixed in MySQL. + MariaDB fixes that but support MySQL style too. */ - SHOW_VAR array[2]= { + SHOW_VAR *show_vars= plugin->plugin->status_vars; + SHOW_VAR tmp_array[2]= { {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY}, {0, 0, SHOW_UNDEF} }; - remove_status_vars(array); -#else - remove_status_vars(plugin->plugin->status_vars); -#endif /* FIX_LATER */ + if (strncasecmp(show_vars->name, plugin->name.str, plugin->name.length)) + show_vars= tmp_array; + + remove_status_vars(show_vars); } if (plugin_type_deinitialize[plugin->plugin->type]) @@ -1358,24 +1357,22 @@ static int plugin_initialize(struct st_plugin_int *plugin) if (plugin->plugin->status_vars) { -#ifdef FIX_LATER /* - We have a problem right now where we can not prepend without - breaking backwards compatibility. We will fix this shortly so - that engines have "use names" and we wil use those for - CREATE TABLE, and use the plugin name then for adding automatic - variable names. + historical ndb behavior caused MySQL plugins to specify + status var names in full, with the plugin name prefix. + this was never fixed in MySQL. + MariaDB fixes that, but supports MySQL style too. */ - SHOW_VAR array[2]= { + SHOW_VAR *show_vars= plugin->plugin->status_vars; + SHOW_VAR tmp_array[2]= { {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY}, {0, 0, SHOW_UNDEF} }; - if (add_status_vars(array)) // add_status_vars makes a copy + if (strncasecmp(show_vars->name, plugin->name.str, plugin->name.length)) + show_vars= tmp_array; + + if (add_status_vars(show_vars)) goto err; -#else - if (add_status_vars(plugin->plugin->status_vars)) - goto err; -#endif /* FIX_LATER */ } /* diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eea1289015a..ac71837def4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2626,7 +2626,7 @@ static bool status_vars_inited= 0; C_MODE_START static int show_var_cmp(const void *var1, const void *var2) { - return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); + return strcasecmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); } C_MODE_END @@ -2831,6 +2831,17 @@ static bool show_status_array(THD *thd, const char *wild, name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ if (ucase_names) my_caseup_str(system_charset_info, name_buffer); + else + { + my_casedn_str(system_charset_info, name_buffer); + DBUG_ASSERT(name_buffer[0] >= 'a'); + DBUG_ASSERT(name_buffer[0] <= 'z'); + + /* traditionally status variables have a first letter uppercased */ + if (status_var) + name_buffer[0]-= 'a' - 'A'; + } + restore_record(table, s->default_values); table->field[0]->store(name_buffer, strlen(name_buffer), diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 968d23c94b5..1ab64dcb697 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -2568,21 +2568,21 @@ struct st_mysql_storage_engine cassandra_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; static SHOW_VAR cassandra_status_variables[]= { - {"Cassandra_row_inserts", + {"row_inserts", (char*) &cassandra_counters.row_inserts, SHOW_LONG}, - {"Cassandra_row_insert_batches", + {"row_insert_batches", (char*) &cassandra_counters.row_insert_batches, SHOW_LONG}, - {"Cassandra_multiget_keys_scanned", + {"multiget_keys_scanned", (char*) &cassandra_counters.multiget_keys_scanned, SHOW_LONG}, - {"Cassandra_multiget_reads", + {"multiget_reads", (char*) &cassandra_counters.multiget_reads, SHOW_LONG}, - {"Cassandra_multiget_rows_read", + {"multiget_rows_read", (char*) &cassandra_counters.multiget_rows_read, SHOW_LONG}, - {"Cassandra_timeout_exceptions", + {"timeout_exceptions", (char*) &cassandra_counters.timeout_exceptions, SHOW_LONG}, - {"Cassandra_unavailable_exceptions", + {"unavailable_exceptions", (char*) &cassandra_counters.unavailable_exceptions, SHOW_LONG}, {NullS, NullS, SHOW_LONG} }; diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index bcf934b6b1c..0dc8e27fe61 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -1117,7 +1117,7 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, static struct st_mysql_show_var func_status[]= { - {"example_func_example", (char *)show_func_example, SHOW_SIMPLE_FUNC}, + {"func_example", (char *)show_func_example, SHOW_SIMPLE_FUNC}, {0,0,SHOW_UNDEF} }; diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 6ea1dccc40b..1a11bdd6050 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -3753,11 +3753,6 @@ SHOW_VAR status_variables[]= { {NullS, NullS, SHOW_LONG} }; -static struct st_mysql_show_var aria_status_variables[]= { - {"Aria", (char*) &status_variables, SHOW_ARRAY}, - {NullS, NullS, SHOW_LONG} -}; - /**************************************************************************** * Maria MRR implementation: use DS-MRR ***************************************************************************/ @@ -3832,7 +3827,7 @@ maria_declare_plugin(aria) ha_maria_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0105, /* 1.5 */ - aria_status_variables, /* status variables */ + status_variables, /* status variables */ system_variables, /* system variables */ "1.5", /* string version */ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ From 68f6c229c563b5e92a2ef7ea2a429edbdb69c303 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:37 +0200 Subject: [PATCH 82/87] prefer static inline functions to macros. avoid unnecessary strlen()'s --- sql/mysqld.cc | 2 +- sql/sql_audit.h | 91 +++++++++++++++++++++++++++++----------------- sql/sql_connect.cc | 2 +- sql/sql_parse.cc | 2 +- 4 files changed, 60 insertions(+), 37 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 64cc94fa8bd..c8d8c09cbba 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2414,7 +2414,7 @@ void close_connection(THD *thd, uint sql_errno) { sleep(0); /* Workaround to avoid tailcall optimisation */ } - MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, sql_errno); + mysql_audit_notify_connection_disconnect(thd, sql_errno); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ diff --git a/sql/sql_audit.h b/sql/sql_audit.h index 46afe4b7596..a651ce61374 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -43,10 +43,16 @@ static inline bool mysql_audit_general_enabled() return mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK; } +static inline bool mysql_audit_connection_enabled() +{ + return mysql_global_audit_mask[0] & MYSQL_AUDIT_CONNECTION_CLASSMASK; +} + #else static inline void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...) { } #define mysql_audit_general_enabled() 0 +#define mysql_audit_connection_enabled() 0 #endif extern void mysql_audit_release(THD *thd); @@ -137,41 +143,58 @@ void mysql_audit_general(THD *thd, uint event_subtype, } } -#define MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd) mysql_audit_notify(\ - (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CONNECT,\ - (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ - (thd)->thread_id, (thd)->security_ctx->user,\ - (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ - (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ - (thd)->security_ctx->external_user,\ - (thd)->security_ctx->external_user ?\ - strlen((thd)->security_ctx->external_user) : 0,\ - (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ - (thd)->security_ctx->host,\ - (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ - (thd)->security_ctx->ip,\ - (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ - (thd)->db, (thd)->db ? strlen((thd)->db) : 0) +static inline +void mysql_audit_notify_connection_connect(THD *thd) +{ + if (mysql_audit_connection_enabled()) + { + const Security_context *sctx= thd->security_ctx; + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, + MYSQL_AUDIT_CONNECTION_CONNECT, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0, + thd->thread_id, + sctx->user, sctx->user ? strlen(sctx->user) : 0, + sctx->priv_user, strlen(sctx->priv_user), + sctx->external_user, + sctx->external_user ? strlen(sctx->external_user) : 0, + sctx->proxy_user, strlen(sctx->proxy_user), + sctx->host, sctx->host ? strlen(sctx->host) : 0, + sctx->ip, sctx->ip ? strlen(sctx->ip) : 0, + thd->db, thd->db ? strlen(thd->db) : 0); + } +} -#define MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode)\ - mysql_audit_notify(\ - (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_DISCONNECT,\ - (errcode), (thd)->thread_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +static inline +void mysql_audit_notify_connection_disconnect(THD *thd, int errcode) +{ + if (mysql_audit_connection_enabled()) + { + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, + MYSQL_AUDIT_CONNECTION_DISCONNECT, + errcode, thd->thread_id, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } +} -#define MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd) mysql_audit_notify(\ - (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CHANGE_USER,\ - (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ - (thd)->thread_id, (thd)->security_ctx->user,\ - (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ - (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ - (thd)->security_ctx->external_user,\ - (thd)->security_ctx->external_user ?\ - strlen((thd)->security_ctx->external_user) : 0,\ - (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ - (thd)->security_ctx->host,\ - (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ - (thd)->security_ctx->ip,\ - (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ - (thd)->db, (thd)->db ? strlen((thd)->db) : 0) +static inline +void mysql_audit_notify_connection_change_user(THD *thd) +{ + if (mysql_audit_connection_enabled()) + { + const Security_context *sctx= thd->security_ctx; + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, + MYSQL_AUDIT_CONNECTION_CHANGE_USER, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0, + thd->thread_id, + sctx->user, sctx->user ? strlen(sctx->user) : 0, + sctx->priv_user, strlen(sctx->priv_user), + sctx->external_user, + sctx->external_user ? strlen(sctx->external_user) : 0, + sctx->proxy_user, strlen(sctx->proxy_user), + sctx->host, sctx->host ? strlen(sctx->host) : 0, + sctx->ip, sctx->ip ? strlen(sctx->ip) : 0, + thd->db, thd->db ? strlen(thd->db) : 0); + } +} #endif /* SQL_AUDIT_INCLUDED */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 40bd59975f3..17e75f15adf 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1187,7 +1187,7 @@ bool thd_prepare_connection(THD *thd) bool rc; lex_start(thd); rc= login_connection(thd); - MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + mysql_audit_notify_connection_connect(thd); if (rc) return rc; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 62e5a99f941..c68e20f1b3a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1011,7 +1011,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, else rc= acl_authenticate(thd, 0, packet_length); - MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd); + mysql_audit_notify_connection_change_user(thd); if (rc) { /* Free user if allocated by acl_authenticate */ From da7eca021bbcd0d199a05543f58fae99e34646a1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:41 +0200 Subject: [PATCH 83/87] remove old workaround for replicating from old MySQL 5.1 and 5.2 alpha trees. --- .../suite/binlog/r/binlog_old_versions.result | 15 --- .../binlog/std_data/ver_5_1-wl2325_r.001 | Bin 705 -> 0 bytes .../binlog/std_data/ver_5_1-wl2325_s.001 | Bin 149796 -> 0 bytes .../suite/binlog/t/binlog_old_versions.test | 19 ---- sql/log_event.cc | 103 ------------------ 5 files changed, 137 deletions(-) delete mode 100644 mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 delete mode 100644 mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 diff --git a/mysql-test/suite/binlog/r/binlog_old_versions.result b/mysql-test/suite/binlog/r/binlog_old_versions.result index a4850b835c8..169a23b2019 100644 --- a/mysql-test/suite/binlog/r/binlog_old_versions.result +++ b/mysql-test/suite/binlog/r/binlog_old_versions.result @@ -38,21 +38,6 @@ SELECT COUNT(*) FROM t3; COUNT(*) 17920 DROP TABLE t1, t3; -==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== -SELECT * FROM t1 ORDER BY a; -a b -0 last_insert_id -1 one -3 last stm in trx: next event should be xid -4 four -781729 random -SELECT * FROM t2 ORDER BY a; -a b -3 first stm in trx -SELECT COUNT(*) FROM t3; -COUNT(*) -17920 -DROP TABLE t1, t2, t3; ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== SELECT * FROM t1 ORDER BY a; a b diff --git a/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 deleted file mode 100644 index 47071c011f91d63b666e3013f18acc019e884cbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmeyDl$rO*yv?1Tk%56B35e5xn1O+X!Bo#k&qy~hKBXwXz^uT~ST`j#sWe?TCqEsm z01E*!M%aRvfrCMafdvSJ7#RH7fPjHT3M9n@vY`lwZ-DhOLrq{|V2}bb9T*ru@?gNm zTwIdE!T~ghgP|m~xP-wu$kj2#RUyRD$;VZp#85#aQ6V$0L`NY>Avq(lNW;`XQ&Yj! z&)w6{Rl!!lx6(7%(HF%=FR;<%+h~N}M$f#wd>1FUji69mL!phv=r$Sw{Rpx_0A#Ql z5MP1^7cjQKp~O^T$iT$>52Q*EB&iF;|KX|_8JPb61d1>)=jWyV1PL>jl;@)usmcVB zhX4#Cg+N;Dfj9-O3X74*X8!~!#IU3bt{scJg+Z360P#AwDzGImllUy!+?hdYgn{@V GSPcNT7kLN( diff --git a/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 deleted file mode 100644 index 4302bfed879d3b9dc692f11c13029f733771d724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149796 zcmeI5&u-k-6~=EY#gGj+|Nj7P7X%VONe~;gjRZzF@fcQI0fr33O11*2p){<=WI|Gc zv}}Op8Tt%aWZ5_Az7NoiU!chO&LycD>SBg7tK>HZhnE};$)OML{l0U)bMAk$qCCF; z)8jW^3n65-9N7}WX87Xv-P?C>r3cfx`u@xB@7%jJ&9jr^Tl4DJ|KR_;=`io!zY(^= zJ7Lpa?}YI5s=dPIO?`AlXLw}G&;H#j-4QlJxM|G?A?R~|UEOHf>E@OlXe+dN(}ssT zk9YTmW6bT3w1lwCF?RQ!?R>MJ?C$M9P1?K3cataI?mSCAx%YXpeN@y6i zcjqm?ln``%Z)neFw*1>a(%V_M@|CT&Y_Z$wui=-ZwmI<|Hu|nz{E`P}x^2}-9k23+ zPX3WCQ$KdGeeJeR{>$NiwzVFv;RoCJ*SfCZo5|jzPd-gPOYZ#1Uv@=xT28AM@tR)O zHT}_+mwrNR`D?hCbKCsuhW4%DhCG=(+dqgVcCc%gWf!CW>4Tzd^4eD2f9LzUj1TRE zf7{SWwM^1_cG6t8RaIV}WNDUOx8?A;-j7&ETA7_<*zP;Oz*UGo*{IsyI>w~VTTi3V!YjJlZ}r87A5o_=yUO*y z;A?%`8bz7T)jB!U8MX2sq((eW*YZENot1u)_EmMiOUKtW+83=c_qQUIA>{MM4I;0n zxt-Z|)MeVvbS-&phOSep;itlgFd{PtjL3T_JzQx+Pvm_KJyF>YR~ks8ZTRrRaOR^} z?)QY@Y$=fC{fu`r5yOCq9MOP@mO<(mkv%~GYcqot=pIId5v}Yqz=$v+j0isw&PMAA zTbzwJ8)u!T8jm#|YbZWpkCDMRfHlAxU=6SaSOcty;%hVnSVskj#zmwcb{9-m)CXwM z6QL(kkUkPFwK^8AW^W`!@e!rDGS0dVbsxme{Bc3qxLC)rcB!O~U~wFCaW2CdQjn$T z9!4ZQjK-Sb%ryH5^{qQt5C=1yk?pZE4#tQuB8CsyX2qGqFY3}RNuWARwa z4$u?fv8H;gfu$~`1dp}#3V5tVqw!c%$9mE6(XA!g4A~wo32}iCg+G_^USdQVd&u^H zouMaMs_Zmj55gWRyLB)kj0htlc1G+>IGorSu`^<4#Lm_{3m+68ioY_*!iX>;jEL&7 zOP3RZ;zRLQ?l>?aj0hvbPlTTcKT%9s6dEUaF`_Z=7pMwC6yG`rG}dUWt#4dZLk6%0 zSOcs9)&OgOHNcv=J<_b3yn*CJgGMGtm}J&52v7m60oDNPW6JH7X-o1V$%~x>vZ_TM zNM00;CV7$M#YG)YZY|MfNM0m)F+K7QLlYk)Pt8ek2u23P~EZI0{|kM&>&0PAr=M2rYv4X_4S z1FQko0BeBt0I2X-7Vu zQ&E4M-d3Dll2m)gh%h3IsIT9s{}+s%Q{>8^kr3A!(np~9h|*RDSr`#Ugb~FGj3^uJS-?+(p9nvZhDFNlO^v&eyh!q* z=i*uVM^UD8!6h?`ZskL!w&g~SpE$*f%}SZ!7!i4AlYk)Pt+IqqkkF_P4F?}b~cbbey<05(@xf+^b&equSJTZ!)%R0~##W{XS86stf zS%#QpXbov%WyzcM4oh%h3Ih=L9jbP#`|jy2gH)Ul?HHFc~9mQEe(aTz`UYk)Pt z8ek2u23V6uP1s`qR8&f%Qrc-@X|EPB?x*ZjA%VWFA+w*Plj%DzcN_p~fHlAxU=6Sa zSOcstkB_cHi)u9L6H%XNoc9tVvL}f8L}mtuqzu8%%nmfrxQN$VT?x(0qYvy1b_P3x zox#ooq0kedCqhqzo(MhB5Yr&+F^-V~tO3>lYk)Pt8emP>@3afP8k21`&*HsClYu%5ZGv9!n!Omc3urt`% zAfP6VdR)8|c`Rwvq){VEBkV!ggEVT=s0Tnr8Z~Lur-kVR%;V5|shN%11_|{MQ9Oa3 zh-?qB2RznztnpY!H?`c7(N&Gd+HArHiYdVQHw3JY@Bj4p+G`<%4|hWN$6u~kOAAm* z9l(*sLx)KH8mL5Y-w{#?RB|$f^qSzle2tzL4OBW*w;+TBR4R}AL6hJoRR;DzqclBfvUFDFD_0Yk+l8rgQ5Ugs8g}z#3p3tC0;Tir_xM zeS-VXg(vY?$3oNqYpU>B-3O}h8E~QspW|q%@KJ?t-1z9`qtTTrd{p5Z3$idG5qKsa zqF6}h+3Z6g3L1Cq2-o@z&x*d-Pzrq}FEK`BeF+t3+!2Toq2H(C46(Dc>8L)UG>wqP z`l&dBD2>?JqWNvGGl2EVg(EN`j0hvDUF-@wvu9z^(TB1{Qup*+{(qXJ=wn23`$6%c z_)z>v?5kQHb11%s3@APne^HPHJ5#qo0G8Mp0ay<$FWPay&VGOFOl46%P+637Ti)L7 z%c9su*bL#O*GRc$8y{;=2oFNgAN%X-M$=9=w}Sqe7`Y8ko=zSmk0$$*WOwiD-6uQA nc2*o892N8Y_B3s`ZSVfmWPkF|K56g$XeZv#vEH@iV?Xh)HkN#? diff --git a/mysql-test/suite/binlog/t/binlog_old_versions.test b/mysql-test/suite/binlog/t/binlog_old_versions.test index b294adbc69d..77b3db31983 100644 --- a/mysql-test/suite/binlog/t/binlog_old_versions.test +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test @@ -64,25 +64,6 @@ SELECT COUNT(*) FROM t3; DROP TABLE t1, t3; ---echo ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== - -# In this version, it was not possible to switch between row-based and -# statement-based binlogging without restarting the server. So, we -# have two binlogs; one for row based and one for statement based -# replication. - -# Read rbr binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_r.001 | $MYSQL --local-infile=1 -# Read stm binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_s.001 | $MYSQL --local-infile=1 -# Show result. -SELECT * FROM t1 ORDER BY a; -SELECT * FROM t2 ORDER BY a; -SELECT COUNT(*) FROM t3; -# Reset. -DROP TABLE t1, t2, t3; - - --echo ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== # Read binlog. diff --git a/sql/log_event.cc b/sql/log_event.cc index 19bc79babb1..6c637be19fa 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4568,109 +4568,6 @@ Format_description_log_event(const char* buf, checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF; } - /* - In some previous versions, the events were given other event type - id numbers than in the present version. When replicating from such - a version, we therefore set up an array that maps those id numbers - to the id numbers of the present server. - - If post_header_len is null, it means malloc failed, and is_valid - will fail, so there is no need to do anything. - - The trees in which events have wrong id's are: - - mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha - mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0 - mysql-5.1-wl2325-no-dd - - (this was found by grepping for two lines in sequence where the - first matches "FORMAT_DESCRIPTION_EVENT," and the second matches - "TABLE_MAP_EVENT," in log_event.h in all trees) - - In these trees, the following server_versions existed since - TABLE_MAP_EVENT was introduced: - - 5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha - 5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12 - 5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15 - 5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c - 5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5 - 5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8 - 5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b - 5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19 - 5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1 - 5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3 - 5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6 - 5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12 - 5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8 - 5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b - 5.2.2-a_drop6p13c - - (this was found by grepping for "mysql," in all historical - versions of configure.in in the trees listed above). - - There are 5.1.1-alpha versions that use the new event id's, so we - do not test that version string. So replication from 5.1.1-alpha - with the other event id's to a new version does not work. - Moreover, we can safely ignore the part after drop[56]. This - allows us to simplify the big list above to the following regexes: - - 5\.1\.[1-5]-a_drop5.* - 5\.1\.4-a_drop6.* - 5\.2\.[0-2]-a_drop6.* - - This is what we test for in the 'if' below. - */ - if (post_header_len && - server_version[0] == '5' && server_version[1] == '.' && - server_version[3] == '.' && - strncmp(server_version + 5, "-a_drop", 7) == 0 && - ((server_version[2] == '1' && - server_version[4] >= '1' && server_version[4] <= '5' && - server_version[12] == '5') || - (server_version[2] == '1' && - server_version[4] == '4' && - server_version[12] == '6') || - (server_version[2] == '2' && - server_version[4] >= '0' && server_version[4] <= '2' && - server_version[12] == '6'))) - { - if (number_of_event_types != 22) - { - DBUG_PRINT("info", (" number_of_event_types=%d", - number_of_event_types)); - /* this makes is_valid() return false. */ - my_free(post_header_len); - post_header_len= NULL; - DBUG_VOID_RETURN; - } - static const uint8 perm[23]= - { - UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT, - INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT, - APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT, - NEW_LOAD_EVENT, - RAND_EVENT, USER_VAR_EVENT, - FORMAT_DESCRIPTION_EVENT, - TABLE_MAP_EVENT, - PRE_GA_WRITE_ROWS_EVENT, - PRE_GA_UPDATE_ROWS_EVENT, - PRE_GA_DELETE_ROWS_EVENT, - XID_EVENT, - BEGIN_LOAD_QUERY_EVENT, - EXECUTE_LOAD_QUERY_EVENT, - }; - event_type_permutation= perm; - /* - Since we use (permuted) event id's to index the post_header_len - array, we need to permute the post_header_len array too. - */ - uint8 post_header_len_temp[23]; - for (int i= 1; i < 23; i++) - post_header_len_temp[perm[i] - 1]= post_header_len[i - 1]; - for (int i= 0; i < 22; i++) - post_header_len[i] = post_header_len_temp[i]; - } DBUG_VOID_RETURN; } From c50ee6c23dbeb090963580754bec2f0a96ac0557 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:52 +0200 Subject: [PATCH 84/87] MDEV-4088 Replication 10.0 -> 5.5 fails --- include/mysql_com.h | 7 +++++++ sql-common/client.c | 6 ++++++ sql/sql_acl.cc | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 9ba17b416c4..e9a24fd767d 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -34,6 +34,13 @@ #define MYSQL50_TABLE_NAME_PREFIX_LENGTH (sizeof(MYSQL50_TABLE_NAME_PREFIX)-1) #define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH) +#ifdef EMBEDDED_LIBRARY +#define RPL_VERSION_HACK "" +#else +/* this version must be the one that *does not* support pluggable auth */ +#define RPL_VERSION_HACK "5.5.5-" +#endif + #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 #define LIST_PROCESS_HOST_LEN 64 diff --git a/sql-common/client.c b/sql-common/client.c index 64010919fe3..e48cdac369e 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -3416,6 +3416,12 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, strmov(mysql->server_version,(char*) net->read_pos+1); mysql->port=port; + /* remove the rpl hack from the version string */ + if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH && + strncmp(mysql->server_version, RPL_VERSION_HACK, + sizeof(RPL_VERSION_HACK) - 1) == 0) + mysql->server_version+= sizeof(RPL_VERSION_HACK) - 1; + if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1) { /* diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 56dec73bac5..d9470094c63 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7957,7 +7957,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, data_len= SCRAMBLE_LENGTH; } - end= strnmov(end, server_version, SERVER_VERSION_LENGTH) + 1; + end= strxnmov(end, SERVER_VERSION_LENGTH, RPL_VERSION_HACK, server_version, NullS) + 1; int4store((uchar*) end, mpvio->thd->thread_id); end+= 4; From 0d25ee4f13b2eb79e9af3b3778c23f63d9a57c12 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:28:21 +0200 Subject: [PATCH 85/87] MDEV-4254 Semisync plugins to link statically into MariaDB fix semisync plugins and tests to work with both with static and dynamic linking --- cmake/plugin.cmake | 8 +- mysql-test/include/have_semisync.inc | 4 + mysql-test/include/have_semisync.opt | 4 + mysql-test/include/have_semisync_plugin.inc | 15 -- mysql-test/suite/rpl/r/rpl_mdev359.result | 2 - mysql-test/suite/rpl/r/rpl_semi_sync.result | 69 ++++++---- .../suite/rpl/r/rpl_semi_sync_event.result | 13 +- .../suite/rpl/r/semisync_memleak_4066.result | 2 - mysql-test/suite/rpl/t/rpl_mdev359.test | 7 +- mysql-test/suite/rpl/t/rpl_semi_sync.test | 128 +++++------------- .../suite/rpl/t/rpl_semi_sync_event.test | 37 +---- .../suite/rpl/t/semisync_memleak_4066.test | 6 +- .../rpl_semi_sync_master_enabled_basic.result | 2 - .../rpl_semi_sync_master_timeout_basic.result | 2 - ..._semi_sync_master_trace_level_basic.result | 2 - ...emi_sync_master_wait_no_slave_basic.result | 2 - .../rpl_semi_sync_slave_enabled_basic.result | 2 - ...l_semi_sync_slave_trace_level_basic.result | 2 - .../t/rpl_semi_sync_master_enabled_basic.test | 7 +- .../t/rpl_semi_sync_master_timeout_basic.test | 7 +- ...pl_semi_sync_master_trace_level_basic.test | 7 +- ..._semi_sync_master_wait_no_slave_basic.test | 6 +- .../t/rpl_semi_sync_slave_enabled_basic.test | 7 +- ...rpl_semi_sync_slave_trace_level_basic.test | 7 +- mysql-test/t/mysqld--help.test | 2 +- plugin/semisync/CMakeLists.txt | 7 +- plugin/semisync/semisync_master.cc | 3 +- plugin/semisync/semisync_master.h | 4 +- plugin/semisync/semisync_master_plugin.cc | 12 +- plugin/semisync/semisync_slave_plugin.cc | 11 +- sql/rpl_handler.cc | 20 +++ 31 files changed, 157 insertions(+), 250 deletions(-) create mode 100644 mysql-test/include/have_semisync.inc create mode 100644 mysql-test/include/have_semisync.opt delete mode 100644 mysql-test/include/have_semisync_plugin.inc diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 2978fb1a13c..f016d8eab4f 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -171,12 +171,12 @@ MACRO(MYSQL_ADD_PLUGIN) IF(ARG_MANDATORY) SET (mysql_mandatory_plugins - "${mysql_mandatory_plugins} builtin_maria_${target}_plugin," - PARENT_SCOPE) + "${mysql_mandatory_plugins} builtin_maria_${target}_plugin,") + SET (mysql_mandatory_plugins ${mysql_mandatory_plugins} PARENT_SCOPE) ELSE() SET (mysql_optional_plugins - "${mysql_optional_plugins} builtin_maria_${target}_plugin," - PARENT_SCOPE) + "${mysql_optional_plugins} builtin_maria_${target}_plugin,") + SET (mysql_optional_plugins ${mysql_optional_plugins} PARENT_SCOPE) ENDIF() ELSEIF(NOT WITHOUT_${plugin} AND NOT ARG_STATIC_ONLY AND NOT WITHOUT_DYNAMIC_PLUGINS) diff --git a/mysql-test/include/have_semisync.inc b/mysql-test/include/have_semisync.inc new file mode 100644 index 00000000000..243fad83717 --- /dev/null +++ b/mysql-test/include/have_semisync.inc @@ -0,0 +1,4 @@ +if (`select count(*) < 2 from information_schema.plugins where plugin_name like 'rpl_semi_sync_%'`) +{ + --skip Test requires semisync plugins +} diff --git a/mysql-test/include/have_semisync.opt b/mysql-test/include/have_semisync.opt new file mode 100644 index 00000000000..2888844cdcd --- /dev/null +++ b/mysql-test/include/have_semisync.opt @@ -0,0 +1,4 @@ +--plugin-load=$SEMISYNC_MASTER_SO +--plugin-load=$SEMISYNC_SLAVE_SO +--loose-rpl-semi-sync-master +--loose-rpl-semi-sync-slave diff --git a/mysql-test/include/have_semisync_plugin.inc b/mysql-test/include/have_semisync_plugin.inc deleted file mode 100644 index 8a1679de636..00000000000 --- a/mysql-test/include/have_semisync_plugin.inc +++ /dev/null @@ -1,15 +0,0 @@ -# -# Check if server has support for loading plugins -# -if (`SELECT @@have_dynamic_loading != 'YES'`) { - --skip Requires dynamic loading -} - -# -# Check if the variable SEMISYNC_MASTER_SO is set -# -if (!$SEMISYNC_MASTER_SO) -{ - skip Need semisync plugins; -} - diff --git a/mysql-test/suite/rpl/r/rpl_mdev359.result b/mysql-test/suite/rpl/r/rpl_mdev359.result index f4382f672e4..c0c7bac1175 100644 --- a/mysql-test/suite/rpl/r/rpl_mdev359.result +++ b/mysql-test/suite/rpl/r/rpl_mdev359.result @@ -1,7 +1,6 @@ include/master-slave.inc [connection master] CREATE TABLE t1 (a INT) ENGINE=MyISAM; -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master'; SET GLOBAL rpl_semi_sync_master_enabled = ON; SET DEBUG_SYNC = "rpl_semisync_master_commit_trx_before_lock SIGNAL m1_ready WAIT_FOR m1_cont"; INSERT INTO t1 SELECT * FROM t1; @@ -9,5 +8,4 @@ SET DEBUG_SYNC= "now WAIT_FOR m1_ready"; SET GLOBAL rpl_semi_sync_master_enabled = OFF; SET DEBUG_SYNC= "now SIGNAL m1_cont"; DROP TABLE t1; -UNINSTALL PLUGIN rpl_semi_sync_master; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync.result index 51859b5b49b..06eb56a40c5 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync.result @@ -1,13 +1,26 @@ include/master-slave.inc [connection master] +call mtr.add_suppression("Timeout waiting for reply of binlog"); +call mtr.add_suppression("Read semi-sync reply"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); +call mtr.add_suppression("Master server does not support semi-sync"); +call mtr.add_suppression("Semi-sync slave .* reply"); +call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); # # Uninstall semi-sync plugins on master and slave # include/stop_slave.inc +reset slave; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; +reset master; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; # # Main test of semi-sync replication start here # [ on master ] +set global rpl_semi_sync_master_timeout= 60000; [ default state of semi-sync on master should be OFF ] show variables like 'rpl_semi_sync_master_enabled'; Variable_name Value @@ -41,9 +54,7 @@ Rpl_semi_sync_master_status OFF show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 0 -# -# INSTALL PLUGIN semi-sync on slave -# +reset master; [ on slave ] [ default state of semi-sync on slave should be OFF ] show variables like 'rpl_semi_sync_slave_enabled'; @@ -84,6 +95,16 @@ select CONNECTIONS_NORMAL_SLAVE - CONNECTIONS_NORMAL_SLAVE as 'Should be 0'; Should be 0 0 [ insert records to table ] +insert t1 values (10); +insert t1 values (9); +insert t1 values (8); +insert t1 values (7); +insert t1 values (6); +insert t1 values (5); +insert t1 values (4); +insert t1 values (3); +insert t1 values (2); +insert t1 values (1); [ master status after inserts ] show status like 'Rpl_semi_sync_master_status'; Variable_name Value @@ -159,6 +180,16 @@ Rpl_semi_sync_master_no_tx 1 show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 14 +delete from t1 where a=10; +delete from t1 where a=9; +delete from t1 where a=8; +delete from t1 where a=7; +delete from t1 where a=6; +delete from t1 where a=5; +delete from t1 where a=4; +delete from t1 where a=3; +delete from t1 where a=2; +delete from t1 where a=1; insert into t1 values (100); [ master status should be OFF ] show status like 'Rpl_semi_sync_master_status'; @@ -278,6 +309,7 @@ Rpl_semi_sync_master_yes_tx 0 [ on slave ] include/stop_slave.inc reset slave; +kill query _tid; include/start_slave.inc [ on master ] create table t1 (a int) engine = ENGINE_TYPE; @@ -307,6 +339,7 @@ include/stop_slave.inc reset slave; [ on master ] reset master; +kill query _tid; set sql_log_bin=0; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; flush privileges; @@ -357,6 +390,7 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF [ on master ] +kill query _tid; [ Semi-sync status on master should be ON ] show status like 'Rpl_semi_sync_master_clients'; Variable_name Value @@ -385,11 +419,7 @@ Variable_name Value Rpl_semi_sync_slave_status ON include/stop_slave.inc [ on master ] -set sql_log_bin=0; -UNINSTALL PLUGIN rpl_semi_sync_master; -set sql_log_bin=1; -SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'; -Variable_name Value +set global rpl_semi_sync_master_enabled= 0; [ on slave ] SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; Variable_name Value @@ -397,18 +427,10 @@ rpl_semi_sync_slave_enabled ON include/start_slave.inc [ on master ] insert into t1 values (10); -[ on slave ] -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; -Variable_name Value -Rpl_semi_sync_slave_status OFF # # Test non-semi-sync slave connect to semi-sync master # -set sql_log_bin=0; -INSTALL PLUGIN rpl_semi_sync_master SONAME 'SEMISYNC_MASTER_SO'; set global rpl_semi_sync_master_timeout= 5000; -/* 5s */ -set sql_log_bin=1; set global rpl_semi_sync_master_enabled= 1; [ on slave ] include/stop_slave.inc @@ -416,16 +438,8 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF [ uninstall semi-sync slave plugin ] -UNINSTALL PLUGIN rpl_semi_sync_slave; -SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; -Variable_name Value -include/start_slave.inc -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; -Variable_name Value -include/stop_slave.inc -[ reinstall semi-sync slave plugin and disable semi-sync ] -INSTALL PLUGIN rpl_semi_sync_slave SONAME 'SEMISYNC_SLAVE_SO'; set global rpl_semi_sync_slave_enabled= 0; +[ reinstall semi-sync slave plugin and disable semi-sync ] SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; Variable_name Value rpl_semi_sync_slave_enabled OFF @@ -440,11 +454,12 @@ Rpl_semi_sync_slave_status OFF # Clean up # include/stop_slave.inc -UNINSTALL PLUGIN rpl_semi_sync_slave; -UNINSTALL PLUGIN rpl_semi_sync_master; +set global rpl_semi_sync_slave_enabled= 0; +set global rpl_semi_sync_master_enabled= 0; change master to master_user='root',master_password=''; include/start_slave.inc drop table t1; drop user rpl@127.0.0.1; flush privileges; +set global rpl_semi_sync_master_timeout= default; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result index 1c6d73fe681..456c0c4475a 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result @@ -1,6 +1,15 @@ include/master-slave.inc [connection master] +call mtr.add_suppression("Timeout waiting for reply of binlog"); +call mtr.add_suppression("Semi-sync master .* waiting for slave reply"); +call mtr.add_suppression("Read semi-sync reply"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); +call mtr.add_suppression("Master server does not support semi-sync"); +call mtr.add_suppression("Semi-sync slave .* reply"); +call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); +set global rpl_semi_sync_master_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc SET GLOBAL event_scheduler = ON; CREATE TABLE t1 (i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f varchar(8)) ENGINE=ENGINE_TYPE; @@ -34,8 +43,8 @@ UPDATE t1 SET f = CONCAT('up_',CONNECTION_ID()) WHERE i = 2; UPDATE t1 SET f = CONCAT('up_',CONNECTION_ID()) WHERE i = 1; SET GLOBAL event_scheduler = OFF; include/stop_slave.inc -UNINSTALL PLUGIN rpl_semi_sync_slave; -UNINSTALL PLUGIN rpl_semi_sync_master; +set global rpl_semi_sync_slave_enabled = 0; +set global rpl_semi_sync_master_enabled = 0; include/start_slave.inc DROP EVENT ev1; DROP EVENT ev2; diff --git a/mysql-test/suite/rpl/r/semisync_memleak_4066.result b/mysql-test/suite/rpl/r/semisync_memleak_4066.result index c0dd9f0c993..c599f1426d3 100644 --- a/mysql-test/suite/rpl/r/semisync_memleak_4066.result +++ b/mysql-test/suite/rpl/r/semisync_memleak_4066.result @@ -1,6 +1,4 @@ include/master-slave.inc [connection master] -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; CREATE TEMPORARY TABLE tmp (i INT); include/rpl_end.inc -uninstall plugin rpl_semi_sync_master; diff --git a/mysql-test/suite/rpl/t/rpl_mdev359.test b/mysql-test/suite/rpl/t/rpl_mdev359.test index ef4e41f5291..96c7ac859d9 100644 --- a/mysql-test/suite/rpl/t/rpl_mdev359.test +++ b/mysql-test/suite/rpl/t/rpl_mdev359.test @@ -1,4 +1,4 @@ ---source include/have_semisync_plugin.inc +--source include/have_semisync.inc --source include/not_embedded.inc --source include/have_debug_sync.inc --source include/have_binlog_format_mixed_or_statement.inc @@ -13,7 +13,6 @@ # the code, disable the semisync, and then continue the paused thread. CREATE TABLE t1 (a INT) ENGINE=MyISAM; -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master'; SET GLOBAL rpl_semi_sync_master_enabled = ON; --connection master1 SET DEBUG_SYNC = "rpl_semisync_master_commit_trx_before_lock SIGNAL m1_ready WAIT_FOR m1_cont"; @@ -29,8 +28,4 @@ SET DEBUG_SYNC= "now SIGNAL m1_cont"; connection master; DROP TABLE t1; -disable_warnings; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; - --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync.test b/mysql-test/suite/rpl/t/rpl_semi_sync.test index ac5511e28a3..aa36d70d4b7 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync.test @@ -1,4 +1,4 @@ -source include/have_semisync_plugin.inc; +source include/have_semisync.inc; source include/not_embedded.inc; source include/have_innodb.inc; source include/master-slave.inc; @@ -7,7 +7,6 @@ let $engine_type= InnoDB; #let $engine_type= MyISAM; # Suppress warnings that might be generated during the test -disable_query_log; connection master; call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Read semi-sync reply"); @@ -16,7 +15,6 @@ connection slave; call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); -enable_query_log; connection master; # wait for dying connections (if any) to disappear @@ -32,27 +30,15 @@ let $_connections_normal_slave= query_get_value(SHOW STATUS LIKE 'Threads_connec --echo # Uninstall semi-sync plugins on master and slave --echo # connection slave; -disable_query_log; source include/stop_slave.inc; reset slave; -disable_warnings; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_slave; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; connection master; reset master; -set sql_log_bin=0; -disable_warnings; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_slave; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; -set sql_log_bin=1; -enable_query_log; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; --echo # --echo # Main test of semi-sync replication start here @@ -61,16 +47,7 @@ enable_query_log; connection master; echo [ on master ]; -disable_query_log; -let $value = query_get_value(show variables like 'rpl_semi_sync_master_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; - set global rpl_semi_sync_master_timeout= 60000; /* 60s */ - set sql_log_bin=1; -} -enable_query_log; +set global rpl_semi_sync_master_timeout= 60000; # 60s echo [ default state of semi-sync on master should be OFF ]; show variables like 'rpl_semi_sync_master_enabled'; @@ -116,28 +93,12 @@ show status like 'Rpl_semi_sync_master_status'; --replace_result 305 304 show status like 'Rpl_semi_sync_master_yes_tx'; -disable_query_log; # reset master to make sure the following test will start with a clean environment reset master; -enable_query_log; - ---echo # ---echo # INSTALL PLUGIN semi-sync on slave ---echo # connection slave; echo [ on slave ]; -disable_query_log; -let $value= query_get_value(show variables like 'rpl_semi_sync_slave_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; - set sql_log_bin=1; -} -enable_query_log; - echo [ default state of semi-sync on slave should be OFF ]; show variables like 'rpl_semi_sync_slave_enabled'; @@ -177,15 +138,17 @@ let $_connections_semisync_slave= query_get_value(SHOW STATUS LIKE 'Threads_conn replace_result $_connections_normal_slave CONNECTIONS_NORMAL_SLAVE $_connections_semisync_slave CONNECTIONS_SEMISYNC_SLAVE; eval select $_connections_semisync_slave - $_connections_normal_slave as 'Should be 0'; -let $i=10; echo [ insert records to table ]; -disable_query_log; -while ($i) -{ - eval insert into t1 values ($i); - dec $i; -} -enable_query_log; +insert t1 values (10); +insert t1 values (9); +insert t1 values (8); +insert t1 values (7); +insert t1 values (6); +insert t1 values (5); +insert t1 values (4); +insert t1 values (3); +insert t1 values (2); +insert t1 values (1); echo [ master status after inserts ]; show status like 'Rpl_semi_sync_master_status'; @@ -271,14 +234,16 @@ show status like 'Rpl_semi_sync_master_yes_tx'; # Semi-sync status on master is now OFF, so all these transactions # will be replicated asynchronously. -let $i=10; -disable_query_log; -while ($i) -{ - eval delete from t1 where a=$i; - dec $i; -} -enable_query_log; +delete from t1 where a=10; +delete from t1 where a=9; +delete from t1 where a=8; +delete from t1 where a=7; +delete from t1 where a=6; +delete from t1 where a=5; +delete from t1 where a=4; +delete from t1 where a=3; +delete from t1 where a=2; +delete from t1 where a=1; insert into t1 values (100); @@ -408,9 +373,8 @@ connection master; let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; if ($_tid) { - disable_query_log; + --replace_result $_tid _tid eval kill query $_tid; - enable_query_log; # After dump thread exit, Rpl_semi_sync_master_clients will be 0 let $status_var= Rpl_semi_sync_master_clients; @@ -463,9 +427,8 @@ reset master; let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; if ($_tid) { - disable_query_log; + --replace_result $_tid _tid eval kill query $_tid; - enable_query_log; # After dump thread exit, Rpl_semi_sync_master_clients will be 0 let $status_var= Rpl_semi_sync_master_clients; @@ -525,9 +488,8 @@ echo [ on master ]; let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; if ($_tid) { - disable_query_log; + --replace_result $_tid _tid eval kill query $_tid; - enable_query_log; # After dump thread exit, Rpl_semi_sync_master_clients will be 0 let $status_var= Rpl_semi_sync_master_clients; @@ -562,11 +524,7 @@ connection slave; source include/stop_slave.inc; connection master; echo [ on master ]; -set sql_log_bin=0; -UNINSTALL PLUGIN rpl_semi_sync_master; -set sql_log_bin=1; -enable_query_log; -SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'; +set global rpl_semi_sync_master_enabled= 0; connection slave; echo [ on slave ]; @@ -577,19 +535,13 @@ connection master; echo [ on master ]; insert into t1 values (10); sync_slave_with_master; -echo [ on slave ]; -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; --echo # --echo # Test non-semi-sync slave connect to semi-sync master --echo # connection master; -set sql_log_bin=0; -replace_result $SEMISYNC_MASTER_SO SEMISYNC_MASTER_SO; -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; -set global rpl_semi_sync_master_timeout= 5000; /* 5s */ -set sql_log_bin=1; +set global rpl_semi_sync_master_timeout= 5000; # 5s set global rpl_semi_sync_master_enabled= 1; connection slave; @@ -598,16 +550,9 @@ source include/stop_slave.inc; SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; echo [ uninstall semi-sync slave plugin ]; -UNINSTALL PLUGIN rpl_semi_sync_slave; -SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; -source include/start_slave.inc; -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; -source include/stop_slave.inc; +set global rpl_semi_sync_slave_enabled= 0; echo [ reinstall semi-sync slave plugin and disable semi-sync ]; -replace_result $SEMISYNC_SLAVE_SO SEMISYNC_SLAVE_SO; -eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; -set global rpl_semi_sync_slave_enabled= 0; SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; source include/start_slave.inc; @@ -619,14 +564,10 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; connection slave; source include/stop_slave.inc; -UNINSTALL PLUGIN rpl_semi_sync_slave; +set global rpl_semi_sync_slave_enabled= 0; connection master; -# The dump thread may still be running on the master, and so the following -# UNINSTALL could generate a warning about the plugin is busy. -disable_warnings; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; +set global rpl_semi_sync_master_enabled= 0; connection slave; change master to master_user='root',master_password=''; @@ -639,4 +580,5 @@ sync_slave_with_master; connection master; drop user rpl@127.0.0.1; flush privileges; +set global rpl_semi_sync_master_timeout= default; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test index b4a9a9e6e59..b8f3c8130be 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test @@ -1,12 +1,11 @@ -source include/have_semisync_plugin.inc; +source include/have_semisync.inc; source include/not_embedded.inc; -source include/master-slave.inc; source include/have_innodb.inc; +source include/master-slave.inc; let $engine_type= InnoDB; # Suppress warnings that might be generated during the test -disable_query_log; connection master; call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Semi-sync master .* waiting for slave reply"); @@ -16,33 +15,13 @@ connection slave; call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); -enable_query_log; connection master; -disable_query_log; -let $value = query_get_value(show variables like 'rpl_semi_sync_master_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; - SET GLOBAL rpl_semi_sync_master_enabled = 1; - set sql_log_bin=1; -} -enable_query_log; +set global rpl_semi_sync_master_enabled = 1; connection slave; source include/stop_slave.inc; - -disable_query_log; -let $value= query_get_value(show variables like 'rpl_semi_sync_slave_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; - SET GLOBAL rpl_semi_sync_slave_enabled = 1; - set sql_log_bin=1; -} -enable_query_log; +set global rpl_semi_sync_slave_enabled = 1; source include/start_slave.inc; @@ -93,18 +72,16 @@ while ($run) # connection slave; source include/stop_slave.inc; - -disable_warnings; -UNINSTALL PLUGIN rpl_semi_sync_slave; +set global rpl_semi_sync_slave_enabled = 0; connection master; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; +set global rpl_semi_sync_master_enabled = 0; connection slave; source include/start_slave.inc; connection master; + DROP EVENT ev1; DROP EVENT ev2; DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/semisync_memleak_4066.test b/mysql-test/suite/rpl/t/semisync_memleak_4066.test index 687af883936..f888f764b43 100644 --- a/mysql-test/suite/rpl/t/semisync_memleak_4066.test +++ b/mysql-test/suite/rpl/t/semisync_memleak_4066.test @@ -1,19 +1,15 @@ # # MDEV-4066 semisync_master + temporary tables causes memory leaks # -source include/have_semisync_plugin.inc; +source include/have_semisync.inc; source include/have_binlog_format_row.inc; source include/master-slave.inc; connection master; ---replace_result .dll .so -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; - --connect (con1,localhost,root,,) CREATE TEMPORARY TABLE tmp (i INT); --disconnect con1 source include/rpl_end.inc; -uninstall plugin rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result index 3e444519441..7454f0b0089 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_enabled; @@global.rpl_semi_sync_master_enabled 0 @@ -70,4 +69,3 @@ SET @@global.rpl_semi_sync_master_enabled = @start_global_value; select @@global.rpl_semi_sync_master_enabled; @@global.rpl_semi_sync_master_enabled 0 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result index e77bcc1c12a..78fee2a91dc 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_timeout; @@global.rpl_semi_sync_master_timeout 10000 @@ -51,4 +50,3 @@ SET @@global.rpl_semi_sync_master_timeout = @start_global_value; select @@global.rpl_semi_sync_master_timeout; @@global.rpl_semi_sync_master_timeout 10000 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result index 55df5f57d9e..1096fa995e7 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_trace_level; @@global.rpl_semi_sync_master_trace_level 32 @@ -69,4 +68,3 @@ SET @@global.rpl_semi_sync_master_trace_level = @start_global_value; select @@global.rpl_semi_sync_master_trace_level; @@global.rpl_semi_sync_master_trace_level 32 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result index 3d951b499ed..535f777eff7 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_wait_no_slave; @@global.rpl_semi_sync_master_wait_no_slave 1 @@ -70,4 +69,3 @@ SET @@global.rpl_semi_sync_master_wait_no_slave = @start_global_value; select @@global.rpl_semi_sync_master_wait_no_slave; @@global.rpl_semi_sync_master_wait_no_slave 1 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result index a23b160e6f2..f52e8e80127 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; select @@global.rpl_semi_sync_slave_enabled; @@global.rpl_semi_sync_slave_enabled 0 @@ -70,4 +69,3 @@ SET @@global.rpl_semi_sync_slave_enabled = @start_global_value; select @@global.rpl_semi_sync_slave_enabled; @@global.rpl_semi_sync_slave_enabled 0 -UNINSTALL PLUGIN rpl_semi_sync_slave; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result index f7796309aea..9917ec6fce5 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; select @@global.rpl_semi_sync_slave_trace_level; @@global.rpl_semi_sync_slave_trace_level 32 @@ -69,4 +68,3 @@ SET @@global.rpl_semi_sync_slave_trace_level = @start_global_value; select @@global.rpl_semi_sync_slave_trace_level; @@global.rpl_semi_sync_slave_trace_level 32 -UNINSTALL PLUGIN rpl_semi_sync_slave; diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test index ded489f36ff..2ff03a53c42 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test @@ -6,10 +6,7 @@ # # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_enabled; SET @start_global_value = @@global.rpl_semi_sync_master_enabled; @@ -61,5 +58,3 @@ set global rpl_semi_sync_master_enabled="some text"; # SET @@global.rpl_semi_sync_master_enabled = @start_global_value; select @@global.rpl_semi_sync_master_enabled; -UNINSTALL PLUGIN rpl_semi_sync_master; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test index 5258894150d..74d3c41150b 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test @@ -5,10 +5,7 @@ # 2010-01-21 OBN - Added # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_timeout; SET @start_global_value = @@global.rpl_semi_sync_master_timeout; @@ -51,5 +48,3 @@ set global rpl_semi_sync_master_timeout="some text"; # SET @@global.rpl_semi_sync_master_timeout = @start_global_value; select @@global.rpl_semi_sync_master_timeout; -UNINSTALL PLUGIN rpl_semi_sync_master; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test index d9b1d860b35..c41b53fe5e6 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test @@ -5,10 +5,7 @@ # 2010-01-21 OBN - Added # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_trace_level; SET @start_global_value = @@global.rpl_semi_sync_master_trace_level; @@ -59,5 +56,3 @@ set global rpl_semi_sync_master_trace_level="some text"; # SET @@global.rpl_semi_sync_master_trace_level = @start_global_value; select @@global.rpl_semi_sync_master_trace_level; -UNINSTALL PLUGIN rpl_semi_sync_master; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test index 896bd50d156..d4a46a08140 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test @@ -6,10 +6,7 @@ # # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_wait_no_slave; SET @start_global_value = @@global.rpl_semi_sync_master_wait_no_slave; @@ -61,5 +58,4 @@ set global rpl_semi_sync_master_wait_no_slave="some text"; # SET @@global.rpl_semi_sync_master_wait_no_slave = @start_global_value; select @@global.rpl_semi_sync_master_wait_no_slave; -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test index 030b0827a11..c7ce371970d 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test @@ -6,10 +6,7 @@ # # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_slave_enabled; SET @start_global_value = @@global.rpl_semi_sync_slave_enabled; @@ -62,5 +59,3 @@ set global rpl_semi_sync_slave_enabled="some text"; # SET @@global.rpl_semi_sync_slave_enabled = @start_global_value; select @@global.rpl_semi_sync_slave_enabled; -UNINSTALL PLUGIN rpl_semi_sync_slave; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test index 64c935ee957..d7e001b7322 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test @@ -5,10 +5,7 @@ # 2010-01-21 OBN - Added # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_slave_trace_level; SET @start_global_value = @@global.rpl_semi_sync_slave_trace_level; @@ -59,5 +56,3 @@ set global rpl_semi_sync_slave_trace_level="some text"; # SET @@global.rpl_semi_sync_slave_trace_level = @start_global_value; select @@global.rpl_semi_sync_slave_trace_level; -UNINSTALL PLUGIN rpl_semi_sync_slave; - diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index 33bb50537ca..d1b68192250 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -27,7 +27,7 @@ perl; feedback debug temp-pool ssl des-key-file xtradb sequence thread-concurrency super-large-pages mutex-deadlock-detector null-audit aria pbxt oqgraph sphinx thread-handling - test-sql-discovery query-cache-info/; + test-sql-discovery rpl-semi-sync query-cache-info/; # And substitute the content some environment variables with their # names: diff --git a/plugin/semisync/CMakeLists.txt b/plugin/semisync/CMakeLists.txt index f1ada507f4f..33c0895e5e1 100644 --- a/plugin/semisync/CMakeLists.txt +++ b/plugin/semisync/CMakeLists.txt @@ -17,11 +17,10 @@ SET(SEMISYNC_MASTER_SOURCES semisync.cc semisync_master.cc semisync_master_plugin.cc semisync.h semisync_master.h) -MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES} - MODULE_ONLY MODULE_OUTPUT_NAME "semisync_master") +MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES}) SET(SEMISYNC_SLAVE_SOURCES semisync.cc semisync_slave.cc semisync_slave_plugin.cc semisync.h semisync_slave.h ) -MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES} - MODULE_ONLY MODULE_OUTPUT_NAME "semisync_slave") + +MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES}) diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc index f8eb962b857..88ae34e2a2d 100644 --- a/plugin/semisync/semisync_master.cc +++ b/plugin/semisync/semisync_master.cc @@ -429,12 +429,13 @@ int ReplSemiSyncMaster::disableMaster() return 0; } -ReplSemiSyncMaster::~ReplSemiSyncMaster() +void ReplSemiSyncMaster::cleanup() { if (init_done_) { mysql_mutex_destroy(&LOCK_binlog_); mysql_cond_destroy(&COND_binlog_send_); + init_done_= 0; } delete active_tranxs_; diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h index 841c24197fc..9b266ca6565 100644 --- a/plugin/semisync/semisync_master.h +++ b/plugin/semisync/semisync_master.h @@ -453,7 +453,9 @@ class ReplSemiSyncMaster public: ReplSemiSyncMaster(); - ~ReplSemiSyncMaster(); + ~ReplSemiSyncMaster() {} + + void cleanup(); bool getMasterEnabled() { return master_enabled_; diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc index c811cb1cc9e..81ed9b55d99 100644 --- a/plugin/semisync/semisync_master_plugin.cc +++ b/plugin/semisync/semisync_master_plugin.cc @@ -19,7 +19,7 @@ #include "semisync_master.h" #include "sql_class.h" // THD -ReplSemiSyncMaster repl_semisync; +static ReplSemiSyncMaster repl_semisync; C_MODE_START @@ -405,6 +405,7 @@ static int semi_sync_master_plugin_deinit(void *p) sql_print_error("unregister_binlog_transmit_observer failed"); return 1; } + repl_semisync.cleanup(); sql_print_information("unregister_replicator OK"); return 0; } @@ -416,7 +417,7 @@ struct Mysql_replication semi_sync_master_plugin= { /* Plugin library descriptor */ -mysql_declare_plugin(semi_sync_master) +maria_declare_plugin(semisync_master) { MYSQL_REPLICATION_PLUGIN, &semi_sync_master_plugin, @@ -429,7 +430,8 @@ mysql_declare_plugin(semi_sync_master) 0x0100 /* 1.0 */, semi_sync_master_status_vars, /* status variables */ semi_sync_master_system_vars, /* system variables */ - NULL, /* config options */ - 0, /* flags */ + "1.0", + MariaDB_PLUGIN_MATURITY_UNKNOWN } -mysql_declare_plugin_end; +maria_declare_plugin_end; + diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc index 5d373fa0862..96e614b845e 100644 --- a/plugin/semisync/semisync_slave_plugin.cc +++ b/plugin/semisync/semisync_slave_plugin.cc @@ -18,7 +18,7 @@ #include "semisync_slave.h" #include -ReplSemiSyncSlave repl_semisync; +static ReplSemiSyncSlave repl_semisync; /* indicate whether or not the slave should send a reply to the master. @@ -212,7 +212,7 @@ struct Mysql_replication semi_sync_slave_plugin= { /* Plugin library descriptor */ -mysql_declare_plugin(semi_sync_slave) +maria_declare_plugin(semisync_slave) { MYSQL_REPLICATION_PLUGIN, &semi_sync_slave_plugin, @@ -225,7 +225,8 @@ mysql_declare_plugin(semi_sync_slave) 0x0100 /* 1.0 */, semi_sync_slave_status_vars, /* status variables */ semi_sync_slave_system_vars, /* system variables */ - NULL, /* config options */ - 0, /* flags */ + "1.0", + MariaDB_PLUGIN_MATURITY_UNKNOWN } -mysql_declare_plugin_end; +maria_declare_plugin_end; + diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc index 258dae0edb2..1d21b3f9445 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -555,4 +555,24 @@ int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void { return binlog_relay_io_delegate->remove_observer(observer, (st_plugin_int *)p); } +#else +int register_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p) +{ + return 0; +} + +int unregister_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p) +{ + return 0; +} + +int register_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p) +{ + return 0; +} + +int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p) +{ + return 0; +} #endif /* HAVE_REPLICATION */ From 3ed6b24d820edbee3bc333c726dd0aa66c015b56 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 10 Apr 2013 07:25:13 +0200 Subject: [PATCH 86/87] Linking problem on Windows --- storage/innobase/handler/handler0alter.cc | 6 ++---- storage/xtradb/handler/handler0alter.cc | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3f61fbb3302..9019c7ba5df 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -310,8 +310,7 @@ innobase_check_index_keys( } } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -325,8 +324,7 @@ innobase_check_index_keys( continue; } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 3a32cf95bc9..9886e8f6bd9 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -311,8 +311,7 @@ innobase_check_index_keys( } } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -326,8 +325,7 @@ innobase_check_index_keys( continue; } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } From ff3407a111ec268e7bd5e726a75527089871c914 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 10 Apr 2013 15:43:57 +0200 Subject: [PATCH 87/87] portability fixes for mysql-test mysql-test/r/mysqld--help.result: that's default to number of CPUs mysql-test/suite/archive/discover.test: move_file uses rename(2), which may end up with "Invalid cross-device link" mysql-test/suite/archive/partition_archive.test: on Solaris the error message is different --- mysql-test/r/mysqld--help,win.rdiff | 61 +++++++++++++++---- mysql-test/r/mysqld--help.result | 1 - mysql-test/suite/archive/discover.test | 4 +- .../suite/archive/partition_archive.test | 2 +- .../suite/plugins/t/show_all_plugins.test | 10 ++- mysql-test/t/mysqld--help.test | 2 +- 6 files changed, 62 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/mysqld--help,win.rdiff b/mysql-test/r/mysqld--help,win.rdiff index cd39445f3e6..24719fce917 100644 --- a/mysql-test/r/mysqld--help,win.rdiff +++ b/mysql-test/r/mysqld--help,win.rdiff @@ -1,6 +1,6 @@ --- mysql-test/r/mysqld--help.result 2012-09-08 22:22:06 +0000 +++ mysql-test/r/mysqld--help.result 2012-10-01 14:03:59 +0000 -@@ -244,7 +244,6 @@ +@@ -248,7 +248,6 @@ The number of segments in a key cache -L, --language=name Client error messages in given language. May be given as a full path. Deprecated. Use --lc-messages-dir instead. @@ -8,7 +8,7 @@ --lc-messages=name Set the language used for the error messages. -L, --lc-messages-dir=name Directory where error messages are -@@ -440,6 +439,7 @@ +@@ -443,6 +442,7 @@ NULLS_UNEQUAL (default behavior for 4.1 and later), NULLS_EQUAL (emulate 4.0 behavior), and NULLS_IGNORED --myisam-use-mmap Use memory mapping for reading and writing MyISAM tables @@ -16,7 +16,7 @@ --net-buffer-length=# Buffer length for TCP/IP and socket communication --net-read-timeout=# -@@ -707,6 +707,9 @@ +@@ -710,6 +710,9 @@ files within specified directory --server-id=# Uniquely identifies the server instance in the community of replication partners @@ -26,7 +26,7 @@ --show-slave-auth-info Show user and password in SHOW SLAVE HOSTS on this master. -@@ -774,6 +777,10 @@ +@@ -777,6 +780,10 @@ Log slow queries to given log file. Defaults logging to 'hostname'-slow.log. Must be enabled to activate other slow log options @@ -37,7 +37,7 @@ --socket=name Socket file to use for connection --sort-buffer-size=# Each thread that needs to do a sort allocates a buffer of -@@ -782,6 +789,7 @@ +@@ -785,6 +792,7 @@ for the complete list of valid sql modes --stack-trace Print a symbolic stack trace on failure (Defaults to on; use --skip-stack-trace to disable.) @@ -45,7 +45,35 @@ --stored-program-cache=# The soft upper limit for number of cached stored routines for one connection. -@@ -822,8 +830,8 @@ +@@ -817,25 +825,11 @@ + values are COMMIT or ROLLBACK. + --thread-cache-size=# + How many threads we should keep in a cache for reuse +- --thread-pool-idle-timeout=# +- Timeout in seconds for an idle thread in the thread +- pool.Worker thread will be shut down after timeout + --thread-pool-max-threads=# + Maximum allowed number of worker threads in the thread + pool +- --thread-pool-oversubscribe=# +- How many additional active worker threads in a group are +- allowed. +- --thread-pool-size=# +- Number of thread groups in the pool. This parameter is +- roughly equivalent to maximum number of concurrently +- executing threads (threads in a waiting state do not +- count as executing). +- --thread-pool-stall-limit=# +- Maximum query execution time in milliseconds,before an +- executing non-yielding thread is considered stalled.If a +- worker thread is stalled, additional worker thread may be +- created to handle remaining clients. ++ --thread-pool-min-threads=# ++ Minimum number of threads in the thread pool. + --thread-stack=# The stack size for each thread + --time-format=name The TIME format (ignored) + --timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are +@@ -844,8 +838,8 @@ size, MySQL will automatically convert it to an on-disk MyISAM or Aria table -t, --tmpdir=name Path for temporary files. Several paths may be specified, @@ -56,7 +84,7 @@ --transaction-alloc-block-size=# Allocation block size for transactions to be stored in binary log -@@ -923,7 +931,6 @@ key-cache-age-threshold 300 +@@ -949,7 +943,6 @@ key-cache-block-size 1024 key-cache-division-limit 100 key-cache-segments 0 @@ -64,7 +92,7 @@ lc-messages en_US lc-messages-dir MYSQL_SHAREDIR/ lc-time-names en_US -@@ -986,6 +993,7 @@ myisam-repair-threads 1 +@@ -1012,6 +1005,7 @@ myisam-sort-buffer-size 8388608 myisam-stats-method nulls_unequal myisam-use-mmap FALSE @@ -72,7 +100,7 @@ net-buffer-length 16384 net-read-timeout 30 net-retry-count 10 -@@ -1051,6 +1059,8 @@ safe-user-create FALSE +@@ -1077,6 +1071,8 @@ secure-auth FALSE secure-file-priv (No default value) server-id 0 @@ -81,7 +109,7 @@ show-slave-auth-info FALSE skip-grant-tables TRUE skip-name-resolve FALSE -@@ -1067,6 +1077,7 @@ slave-transaction-retries 10 +@@ -1093,6 +1089,7 @@ slave-type-conversions slow-launch-time 2 slow-query-log FALSE @@ -89,4 +117,15 @@ sort-buffer-size 2097152 sql-mode stack-trace TRUE - +@@ -1109,10 +1106,8 @@ + table-open-cache 400 + tc-heuristic-recover COMMIT + thread-cache-size 0 +-thread-pool-idle-timeout 60 + thread-pool-max-threads 500 +-thread-pool-oversubscribe 3 +-thread-pool-stall-limit 500 ++thread-pool-min-threads 1 + thread-stack 294912 + time-format %H:%i:%s + timed-mutexes FALSE diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index e5edb963ca9..2a551b1175e 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1112,7 +1112,6 @@ thread-cache-size 0 thread-pool-idle-timeout 60 thread-pool-max-threads 500 thread-pool-oversubscribe 3 -thread-pool-size 4 thread-pool-stall-limit 500 thread-stack 294912 time-format %H:%i:%s diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 75668baafbf..0b7e521185d 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -53,7 +53,9 @@ rename table t2 to t0; --echo # copy_file $mysqld_datadir/test/t1.ARZ $MYSQL_TMP_DIR/t1.ARZ; alter table t1 modify a int default 5; -move_file $MYSQL_TMP_DIR/t1.ARZ $mysqld_datadir/test/t1.ARZ; +remove_file $mysqld_datadir/test/t1.ARZ; +copy_file $MYSQL_TMP_DIR/t1.ARZ $mysqld_datadir/test/t1.ARZ; +remove_file $MYSQL_TMP_DIR/t1.ARZ; show create table t1; --echo # diff --git a/mysql-test/suite/archive/partition_archive.test b/mysql-test/suite/archive/partition_archive.test index e4cc39ff097..be2abeada73 100644 --- a/mysql-test/suite/archive/partition_archive.test +++ b/mysql-test/suite/archive/partition_archive.test @@ -47,7 +47,7 @@ engine=archive partition by list (a) (partition p0 values in (1), partition p1 values in (2)); insert into t1 values (1), (2); ---replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ /Not owner/Operation not permitted/ --error ER_CANT_CREATE_TABLE create index inx on t1 (a); alter table t1 add partition (partition p2 values in (3)); diff --git a/mysql-test/suite/plugins/t/show_all_plugins.test b/mysql-test/suite/plugins/t/show_all_plugins.test index dcc0fb09bd3..1beca12b52c 100644 --- a/mysql-test/suite/plugins/t/show_all_plugins.test +++ b/mysql-test/suite/plugins/t/show_all_plugins.test @@ -8,15 +8,19 @@ show status like '%libraries%'; #--sorted_result #select * from information_schema.all_plugins; #show status like '%libraries%'; -select * from information_schema.all_plugins where plugin_library='ha_example.so'; +--replace_result .dll .so +eval select * from information_schema.all_plugins where plugin_library='$HA_EXAMPLE_SO'; show status like '%libraries%'; --sorted_result -show plugins soname 'ha_example.so'; +--replace_result .dll .so +eval show plugins soname '$HA_EXAMPLE_SO'; show status like '%libraries%'; --sorted_result +--replace_result .dll .so show plugins soname like '%example%'; show status like '%libraries%'; --sorted_result -show plugins soname where library = 'ha_example.so'; +--replace_result .dll .so +eval show plugins soname where library = '$HA_EXAMPLE_SO'; select variable_value > 10 from information_schema.global_status where variable_name like '%libraries%'; diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index d1b68192250..0f3df10ea70 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -20,7 +20,7 @@ perl; # their paths may vary: @skipvars=qw/basedir open-files-limit general-log-file log plugin-dir log-slow-queries pid-file slow-query-log-file log-basename - datadir slave-load-tmpdir tmpdir socket/; + datadir slave-load-tmpdir tmpdir socket thread-pool-size/; # Plugins which may or may not be there: @plugins=qw/innodb ndb archive blackhole federated partition ndbcluster