summaryrefslogtreecommitdiff
path: root/sql/sql_show.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r--sql/sql_show.cc902
1 files changed, 548 insertions, 354 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 4f217159e5c..4e37b53b87e 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -39,7 +39,6 @@
#include "tztime.h" // struct Time_zone
#include "sql_acl.h" // TABLE_ACLS, check_grant, DB_ACLS, acl_get,
// check_grant_db
-#include "filesort.h" // filesort_free_buffers
#include "sp.h"
#include "sp_head.h"
#include "sp_pcontext.h"
@@ -93,6 +92,20 @@ enum enum_i_s_events_fields
#define USERNAME_WITH_HOST_CHAR_LENGTH (USERNAME_CHAR_LENGTH + HOSTNAME_LENGTH + 2)
+
+static const LEX_STRING trg_action_time_type_names[]=
+{
+ { C_STRING_WITH_LEN("BEFORE") },
+ { C_STRING_WITH_LEN("AFTER") }
+};
+
+static const LEX_STRING trg_event_type_names[]=
+{
+ { C_STRING_WITH_LEN("INSERT") },
+ { C_STRING_WITH_LEN("UPDATE") },
+ { C_STRING_WITH_LEN("DELETE") }
+};
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static const char *grant_names[]={
"select","insert","update","delete","create","drop","reload","shutdown",
@@ -774,6 +787,57 @@ static void dispose_db_dir(void *ptr)
}
+/*
+ Append an element into @@ignore_db_dirs
+
+ This is a function to be called after regular option processing has been
+ finalized.
+*/
+
+void ignore_db_dirs_append(const char *dirname_arg)
+{
+ char *new_entry_buf;
+ LEX_STRING *new_entry;
+ size_t len= strlen(dirname_arg);
+
+ if (!my_multi_malloc(0,
+ &new_entry, sizeof(LEX_STRING),
+ &new_entry_buf, len + 1,
+ NullS))
+ return;
+
+ memcpy(new_entry_buf, dirname_arg, len+1);
+ new_entry->str = new_entry_buf;
+ new_entry->length= len;
+
+ if (my_hash_insert(&ignore_db_dirs_hash, (uchar *)new_entry))
+ {
+ // Either the name is already there or out-of-memory.
+ my_free(new_entry);
+ return;
+ }
+
+ // Append the name to the option string.
+ size_t curlen= strlen(opt_ignore_db_dirs);
+ // Add one for comma and one for \0.
+ size_t newlen= curlen + len + 1 + 1;
+ char *new_db_dirs;
+ if (!(new_db_dirs= (char*)my_malloc(newlen ,MYF(0))))
+ {
+ // This is not a critical condition
+ return;
+ }
+
+ memcpy(new_db_dirs, opt_ignore_db_dirs, curlen);
+ if (curlen != 0)
+ new_db_dirs[curlen]=',';
+ memcpy(new_db_dirs + (curlen + ((curlen!=0)?1:0)), dirname_arg, len+1);
+
+ if (opt_ignore_db_dirs)
+ my_free(opt_ignore_db_dirs);
+ opt_ignore_db_dirs= new_db_dirs;
+}
+
bool
ignore_db_dirs_process_additions()
{
@@ -1069,7 +1133,7 @@ public:
}
bool handle_condition(THD *thd, uint sql_errno, const char * /* sqlstate */,
- Sql_condition::enum_warning_level level,
+ Sql_condition::enum_warning_level *level,
const char *message, Sql_condition ** /* cond_hdl */)
{
/*
@@ -1169,7 +1233,7 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
Temporary tables should be opened for SHOW CREATE TABLE, but not
for SHOW CREATE VIEW.
*/
- if (open_temporary_tables(thd, table_list))
+ if (thd->open_temporary_tables(table_list))
goto exit;
/*
@@ -1206,7 +1270,7 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
bool open_error=
open_tables(thd, &table_list, &counter,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL) ||
- mysql_handle_derived(lex, DT_PREPARE);
+ mysql_handle_derived(lex, DT_INIT | DT_PREPARE);
thd->pop_internal_handler();
if (open_error && (thd->killed || thd->is_error()))
goto exit;
@@ -1464,7 +1528,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
if (open_normal_and_derived_tables(thd, table_list,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL,
- DT_PREPARE | DT_CREATE))
+ DT_INIT | DT_PREPARE | DT_CREATE))
DBUG_VOID_RETURN;
table= table_list->table;
@@ -1511,14 +1575,13 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
static const char *require_quotes(const char *name, uint name_length)
{
- uint length;
bool pure_digit= TRUE;
const char *end= name + name_length;
for (; name < end ; name++)
{
uchar chr= (uchar) *name;
- length= my_mbcharlen(system_charset_info, chr);
+ int length= my_charlen(system_charset_info, name, end);
if (length == 1 && !system_charset_info->ident_map[chr])
return name;
if (length == 1 && (chr < '0' || chr > '9'))
@@ -1576,24 +1639,25 @@ append_identifier(THD *thd, String *packet, const char *name, uint length)
if (packet->append(&quote_char, 1, quote_charset))
return true;
- for (name_end= name+length ; name < name_end ; name+= length)
+ for (name_end= name+length ; name < name_end ; )
{
uchar chr= (uchar) *name;
- length= my_mbcharlen(system_charset_info, chr);
+ int char_length= my_charlen(system_charset_info, name, name_end);
/*
- my_mbcharlen can return 0 on a wrong multibyte
+ charlen can return 0 and negative numbers on a wrong multibyte
sequence. It is possible when upgrading from 4.0,
and identifier contains some accented characters.
The manual says it does not work. So we'll just
- change length to 1 not to hang in the endless loop.
+ change char_length to 1 not to hang in the endless loop.
*/
- if (!length)
- length= 1;
- if (length == 1 && chr == (uchar) quote_char &&
+ if (char_length <= 0)
+ char_length= 1;
+ if (char_length == 1 && chr == (uchar) quote_char &&
packet->append(&quote_char, 1, quote_charset))
return true;
- if (packet->append(name, length, system_charset_info))
+ if (packet->append(name, char_length, system_charset_info))
return true;
+ name+= char_length;
}
return packet->append(&quote_char, 1, quote_charset);
}
@@ -1684,9 +1748,11 @@ static bool print_on_update_clause(Field *field, String *val, bool lcase)
val->append(STRING_WITH_LEN("on update "));
else
val->append(STRING_WITH_LEN("ON UPDATE "));
- val->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
+ val->append(STRING_WITH_LEN("current_timestamp"));
if (field->decimals() > 0)
val->append_parenthesized(field->decimals());
+ else
+ val->append(STRING_WITH_LEN("()"));
return true;
}
return false;
@@ -1697,64 +1763,62 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value,
bool quoted)
{
bool has_default;
- bool has_now_default;
enum enum_field_types field_type= field->type();
- /*
- We are using CURRENT_TIMESTAMP instead of NOW because it is
- more standard
- */
- has_now_default= field->has_insert_default_function();
-
- has_default= (field_type != FIELD_TYPE_BLOB &&
- !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
- field->unireg_check != Field::NEXT_NUMBER &&
- !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
- && has_now_default));
+ has_default= (field->default_value ||
+ (!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
+ field->unireg_check != Field::NEXT_NUMBER));
def_value->length(0);
if (has_default)
{
- if (has_now_default)
+ StringBuffer<MAX_FIELD_WIDTH> str(field->charset());
+ if (field->default_value)
{
- def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
- if (field->decimals() > 0)
- def_value->append_parenthesized(field->decimals());
+ field->default_value->print(&str);
+ if (field->default_value->expr->need_parentheses_in_default())
+ {
+ def_value->set_charset(&my_charset_utf8mb4_general_ci);
+ def_value->append('(');
+ def_value->append(str);
+ def_value->append(')');
+ }
+ else
+ def_value->append(str);
}
else if (!field->is_null())
{ // Not null by default
- char tmp[MAX_FIELD_WIDTH];
- String type(tmp, sizeof(tmp), field->charset());
if (field_type == MYSQL_TYPE_BIT)
{
- longlong dec= field->val_int();
- char *ptr= longlong2str(dec, tmp + 2, 2);
- uint32 length= (uint32) (ptr - tmp);
- tmp[0]= 'b';
- tmp[1]= '\'';
- tmp[length]= '\'';
- type.length(length + 1);
+ str.qs_append('b');
+ str.qs_append('\'');
+ str.qs_append(field->val_int(), 2);
+ str.qs_append('\'');
quoted= 0;
}
else
- field->val_str(&type);
- if (type.length())
{
- String def_val;
+ field->val_str(&str);
+ if (!field->str_needs_quotes())
+ quoted= 0;
+ }
+ if (str.length())
+ {
+ StringBuffer<MAX_FIELD_WIDTH> def_val;
uint dummy_errors;
/* convert to system_charset_info == utf8 */
- def_val.copy(type.ptr(), type.length(), field->charset(),
+ def_val.copy(str.ptr(), str.length(), field->charset(),
system_charset_info, &dummy_errors);
if (quoted)
append_unescaped(def_value, def_val.ptr(), def_val.length());
else
- def_value->append(def_val.ptr(), def_val.length());
+ def_value->append(def_val);
}
else if (quoted)
- def_value->append(STRING_WITH_LEN("''"));
+ def_value->set(STRING_WITH_LEN("''"), system_charset_info);
}
else if (field->maybe_null() && quoted)
- def_value->append(STRING_WITH_LEN("NULL")); // Null as default
+ def_value->set(STRING_WITH_LEN("NULL"), system_charset_info); // Null as default
else
return 0;
@@ -1841,8 +1905,8 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
List<Item> field_list;
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
const char *alias;
- String type(tmp, sizeof(tmp), system_charset_info);
- String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
+ String type;
+ String def_value;
Field **ptr,*field;
uint primary_key;
KEY *key_info;
@@ -1935,12 +1999,8 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" "));
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
packet->append(' ');
- // check for surprises from the previous call to Field::sql_type()
- if (type.ptr() != tmp)
- type.set(tmp, sizeof(tmp), system_charset_info);
- else
- type.set_charset(system_charset_info);
+ type.set(tmp, sizeof(tmp), system_charset_info);
field->sql_type(type);
packet->append(type.ptr(), type.length(), system_charset_info);
@@ -1964,13 +2024,13 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
if (field->vcol_info)
{
- packet->append(STRING_WITH_LEN(" AS ("));
- packet->append(field->vcol_info->expr_str.str,
- field->vcol_info->expr_str.length,
- system_charset_info);
+ StringBuffer<MAX_FIELD_WIDTH> str(&my_charset_utf8mb4_general_ci);
+ field->vcol_info->print(&str);
+ packet->append(STRING_WITH_LEN(" GENERATED ALWAYS AS ("));
+ packet->append(str);
packet->append(STRING_WITH_LEN(")"));
- if (field->stored_in_db)
- packet->append(STRING_WITH_LEN(" PERSISTENT"));
+ if (field->vcol_info->stored_in_db)
+ packet->append(STRING_WITH_LEN(" STORED"));
else
packet->append(STRING_WITH_LEN(" VIRTUAL"));
}
@@ -1987,6 +2047,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" NULL"));
}
+ def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info);
if (get_field_default_value(thd, field, &def_value, 1))
{
packet->append(STRING_WITH_LEN(" DEFAULT "));
@@ -2010,8 +2071,19 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" COMMENT "));
append_unescaped(packet, field->comment.str, field->comment.length);
}
+
append_create_options(thd, packet, field->option_list, check_options,
hton->field_options);
+
+ if (field->check_constraint)
+ {
+ StringBuffer<MAX_FIELD_WIDTH> str(&my_charset_utf8mb4_general_ci);
+ field->check_constraint->print(&str);
+ packet->append(STRING_WITH_LEN(" CHECK ("));
+ packet->append(str);
+ packet->append(STRING_WITH_LEN(")"));
+ }
+
}
key_info= table->key_info;
@@ -2093,6 +2165,28 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
file->free_foreign_key_create_info(for_str);
}
+ /* Add table level check constraints */
+ if (share->table_check_constraints)
+ {
+ for (uint i= share->field_check_constraints;
+ i < share->table_check_constraints ; i++)
+ {
+ StringBuffer<MAX_FIELD_WIDTH> str(&my_charset_utf8mb4_general_ci);
+ Virtual_column_info *check= table->check_constraints[i];
+ check->print(&str);
+
+ packet->append(STRING_WITH_LEN(",\n "));
+ if (check->name.length)
+ {
+ packet->append(STRING_WITH_LEN("CONSTRAINT "));
+ append_identifier(thd, packet, check->name.str, check->name.length);
+ }
+ packet->append(STRING_WITH_LEN(" CHECK ("));
+ packet->append(str);
+ packet->append(STRING_WITH_LEN(")"));
+ }
+ }
+
packet->append(STRING_WITH_LEN("\n)"));
if (show_table_options)
{
@@ -2246,20 +2340,14 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
*/
uint part_syntax_len;
char *part_syntax;
- String comment_start;
- table->part_info->set_show_version_string(&comment_start);
- if ((part_syntax= generate_partition_syntax(table->part_info,
+ if ((part_syntax= generate_partition_syntax(thd, table->part_info,
&part_syntax_len,
- FALSE,
show_table_options,
- NULL, NULL,
- comment_start.c_ptr())))
+ NULL, NULL)))
{
- packet->append(comment_start);
- if (packet->append(part_syntax, part_syntax_len) ||
- packet->append(STRING_WITH_LEN(" */")))
+ packet->append('\n');
+ if (packet->append(part_syntax, part_syntax_len))
error= 1;
- my_free(part_syntax);
}
}
}
@@ -2459,7 +2547,7 @@ public:
size_t size __attribute__((unused)))
{ TRASH_FREE(ptr, size); }
- ulong thread_id;
+ my_thread_id thread_id;
uint32 os_thread_id;
ulonglong start_time;
uint command;
@@ -2633,7 +2721,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
while ((thd_info=thread_infos.get()))
{
protocol->prepare_for_resend();
- protocol->store((ulonglong) thd_info->thread_id);
+ protocol->store(thd_info->thread_id);
protocol->store(thd_info->user, system_charset_info);
protocol->store(thd_info->host, system_charset_info);
protocol->store(thd_info->db, system_charset_info);
@@ -2709,7 +2797,7 @@ int select_result_explain_buffer::send_data(List<Item> &items)
DBUG_ENTER("select_result_explain_buffer::send_data");
/*
- Switch to the recieveing thread, so that we correctly count memory used
+ Switch to the receiveing thread, so that we correctly count memory used
by it. This is needed as it's the receiving thread that will free the
memory.
*/
@@ -2911,7 +2999,7 @@ int fill_show_explain(THD *thd, TABLE_LIST *table, COND *cond)
}
else
{
- my_error(ER_NO_SUCH_THREAD, MYF(0), thread_id);
+ my_error(ER_NO_SUCH_THREAD, MYF(0), (ulong) thread_id);
DBUG_RETURN(1);
}
}
@@ -3128,7 +3216,7 @@ int add_status_vars(SHOW_VAR *list)
if (status_vars_inited)
mysql_mutex_lock(&LOCK_show_status);
if (!all_status_vars.buffer && // array is not allocated yet - do it now
- my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20, MYF(0)))
+ my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 250, 50, MYF(0)))
{
res= 1;
goto err;
@@ -3245,6 +3333,132 @@ void remove_status_vars(SHOW_VAR *list)
}
+/**
+ @brief Returns the value of a system or a status variable.
+
+ @param thd [in] The handle of the current THD.
+ @param variable [in] Details of the variable.
+ @param value_type [in] Variable type.
+ @param show_type [in] Variable show type.
+ @param charset [out] Character set of the value.
+ @param buff [in,out] Buffer to store the value.
+ (Needs to have enough memory
+ to hold the value of variable.)
+ @param length [out] Length of the value.
+
+ @return Pointer to the value buffer.
+*/
+
+const char* get_one_variable(THD *thd,
+ const SHOW_VAR *variable,
+ enum_var_type value_type, SHOW_TYPE show_type,
+ system_status_var *status_var,
+ const CHARSET_INFO **charset, char *buff,
+ size_t *length)
+{
+ void *value= variable->value;
+ const char *pos= buff;
+ const char *end= buff;
+
+
+ if (show_type == SHOW_SYS)
+ {
+ sys_var *var= (sys_var *) value;
+ show_type= var->show_type();
+ value= var->value_ptr(thd, value_type, &null_lex_str);
+ *charset= var->charset(thd);
+ }
+
+ /*
+ note that value may be == buff. All SHOW_xxx code below
+ should still work in this case
+ */
+ switch (show_type) {
+ case SHOW_DOUBLE_STATUS:
+ value= ((char *) status_var + (intptr) value);
+ /* fall through */
+ case SHOW_DOUBLE:
+ /* 6 is the default precision for '%f' in sprintf() */
+ end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
+ break;
+ case SHOW_LONG_STATUS:
+ value= ((char *) status_var + (intptr) value);
+ /* fall through */
+ case SHOW_ULONG:
+ case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
+ end= int10_to_str(*(long*) value, buff, 10);
+ break;
+ case SHOW_LONGLONG_STATUS:
+ value= ((char *) status_var + (intptr) value);
+ /* fall through */
+ case SHOW_ULONGLONG:
+ end= longlong10_to_str(*(longlong*) value, buff, 10);
+ break;
+ case SHOW_HA_ROWS:
+ end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
+ break;
+ case SHOW_BOOL:
+ end= strmov(buff, *(bool*) value ? "ON" : "OFF");
+ break;
+ case SHOW_MY_BOOL:
+ end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
+ break;
+ case SHOW_UINT:
+ end= int10_to_str((long) *(uint*) value, buff, 10);
+ break;
+ case SHOW_SINT:
+ end= int10_to_str((long) *(int*) value, buff, -10);
+ break;
+ case SHOW_SLONG:
+ end= int10_to_str(*(long*) value, buff, -10);
+ break;
+ case SHOW_SLONGLONG:
+ end= longlong10_to_str(*(longlong*) value, buff, -10);
+ break;
+ case SHOW_HAVE:
+ {
+ SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
+ pos= show_comp_option_name[(int) tmp];
+ end= strend(pos);
+ break;
+ }
+ case SHOW_CHAR:
+ {
+ if (!(pos= (char*)value))
+ pos= "";
+ end= strend(pos);
+ break;
+ }
+ case SHOW_CHAR_PTR:
+ {
+ if (!(pos= *(char**) value))
+ pos= "";
+
+ end= strend(pos);
+ break;
+ }
+ case SHOW_LEX_STRING:
+ {
+ LEX_STRING *ls=(LEX_STRING*)value;
+ if (!(pos= ls->str))
+ end= pos= "";
+ else
+ end= pos + ls->length;
+ break;
+ }
+ case SHOW_UNDEF:
+ break; // Return empty string
+ case SHOW_SYS: // Cannot happen
+ default:
+ DBUG_ASSERT(0);
+ break;
+ }
+
+ *length= (size_t) (end - pos);
+ return pos;
+}
+
+
static bool show_status_array(THD *thd, const char *wild,
SHOW_VAR *variables,
enum enum_var_type scope,
@@ -3269,7 +3483,7 @@ static bool show_status_array(THD *thd, const char *wild,
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
if (*prefix)
*prefix_end++= '_';
- len=name_buffer + sizeof(name_buffer) - prefix_end;
+ len=(int)(name_buffer + sizeof(name_buffer) - prefix_end);
#ifdef WITH_WSREP
bool is_wsrep_var= FALSE;
@@ -3287,7 +3501,7 @@ static bool show_status_array(THD *thd, const char *wild,
for (; variables->name; variables++)
{
- bool wild_checked= 0;
+ bool wild_checked= false;
strnmov(prefix_end, variables->name, len);
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
@@ -3353,113 +3567,25 @@ static bool show_status_array(THD *thd, const char *wild,
else
{
if ((wild_checked ||
- (wild && wild[0] && wild_case_compare(system_charset_info,
- name_buffer, wild))) &&
+ !(wild && wild[0] && wild_case_compare(system_charset_info,
+ name_buffer, wild))) &&
(!cond || cond->val_int()))
{
- void *value=var->value;
- const char *pos, *end; // We assign a lot of const's
+ const char *pos; // We assign a lot of const's
+ size_t length;
if (show_type == SHOW_SYS)
- {
- sys_var *var= (sys_var *) value;
- show_type= var->show_type();
mysql_mutex_lock(&LOCK_global_system_variables);
- value= var->value_ptr(thd, scope, &null_lex_str);
- charset= var->charset(thd);
- }
-
- pos= end= buff;
- /*
- note that value may be == buff. All SHOW_xxx code below
- should still work in this case
- */
- switch (show_type) {
- case SHOW_DOUBLE_STATUS:
- value= ((char *) status_var + (intptr) value);
- /* fall through */
- case SHOW_DOUBLE:
- /* 6 is the default precision for '%f' in sprintf() */
- end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
- break;
- case SHOW_LONG_STATUS:
- value= ((char *) status_var + (intptr) value);
- /* fall through */
- case SHOW_ULONG:
- case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
- end= int10_to_str(*(long*) value, buff, 10);
- break;
- case SHOW_LONGLONG_STATUS:
- value= ((char *) status_var + (intptr) value);
- /* fall through */
- case SHOW_ULONGLONG:
- end= longlong10_to_str(*(longlong*) value, buff, 10);
- break;
- case SHOW_HA_ROWS:
- end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
- break;
- case SHOW_BOOL:
- end= strmov(buff, *(bool*) value ? "ON" : "OFF");
- break;
- case SHOW_MY_BOOL:
- end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
- break;
- case SHOW_UINT:
- end= int10_to_str((long) *(uint*) value, buff, 10);
- break;
- case SHOW_SINT:
- end= int10_to_str((long) *(int*) value, buff, -10);
- break;
- case SHOW_SLONG:
- end= int10_to_str(*(long*) value, buff, -10);
- break;
- case SHOW_SLONGLONG:
- end= longlong10_to_str(*(longlong*) value, buff, -10);
- break;
- case SHOW_HAVE:
- {
- SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
- pos= show_comp_option_name[(int) tmp];
- end= strend(pos);
- break;
- }
- case SHOW_CHAR:
- {
- if (!(pos= (char*)value))
- pos= "";
- end= strend(pos);
- break;
- }
- case SHOW_CHAR_PTR:
- {
- if (!(pos= *(char**) value))
- pos= "";
+ pos= get_one_variable(thd, var, scope, show_type, status_var,
+ &charset, buff, &length);
- end= strend(pos);
- break;
- }
- case SHOW_LEX_STRING:
- {
- LEX_STRING *ls=(LEX_STRING*)value;
- if (!(pos= ls->str))
- end= pos= "";
- else
- end= pos + ls->length;
- break;
- }
- case SHOW_UNDEF:
- break; // Return empty string
- case SHOW_SYS: // Cannot happen
- default:
- DBUG_ASSERT(0);
- break;
- }
- table->field[1]->store(pos, (uint32) (end - pos), charset);
+ table->field[1]->store(pos, (uint32) length, charset);
+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
table->field[1]->set_notnull();
-
- if (var->type == SHOW_SYS)
+ if (show_type == SHOW_SYS)
mysql_mutex_unlock(&LOCK_global_system_variables);
+
if (schema_table_store_record(thd, table))
{
res= TRUE;
@@ -3625,7 +3751,7 @@ bool get_lookup_value(THD *thd, Item_func *item_func,
/* Lookup value is database name */
if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
(uchar *) item_field->field_name,
- strlen(item_field->field_name), 0))
+ strlen(item_field->field_name)))
{
thd->make_lex_string(&lookup_field_vals->db_value,
tmp_str->ptr(), tmp_str->length());
@@ -3634,7 +3760,7 @@ bool get_lookup_value(THD *thd, Item_func *item_func,
else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
strlen(field_name2),
(uchar *) item_field->field_name,
- strlen(item_field->field_name), 0))
+ strlen(item_field->field_name)))
{
thd->make_lex_string(&lookup_field_vals->table_value,
tmp_str->ptr(), tmp_str->length());
@@ -3729,10 +3855,10 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
if (table->table != item_field->field->table ||
(cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
(uchar *) item_field->field_name,
- strlen(item_field->field_name), 0) &&
+ strlen(item_field->field_name)) &&
cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
(uchar *) item_field->field_name,
- strlen(item_field->field_name), 0)))
+ strlen(item_field->field_name))))
return 0;
}
else if (item->type() == Item::EXPR_CACHE_ITEM)
@@ -4277,13 +4403,14 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
'only_view_structure()'.
*/
lex->sql_command= SQLCOM_SHOW_FIELDS;
- result= (open_temporary_tables(thd, table_list) ||
+ result= (thd->open_temporary_tables(table_list) ||
open_normal_and_derived_tables(thd, table_list,
(MYSQL_OPEN_IGNORE_FLUSH |
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
(can_deadlock ?
MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)),
- DT_PREPARE | DT_CREATE));
+ DT_INIT | DT_PREPARE | DT_CREATE));
+
/*
Restore old value of sql_command back as it is being looked at in
process_table() function.
@@ -4344,6 +4471,7 @@ end:
all tables open within this Open_tables_state.
*/
thd->temporary_tables= NULL;
+
close_thread_tables(thd);
/*
Release metadata lock we might have acquired.
@@ -4622,7 +4750,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
goto end;
}
- share= tdc_acquire_share_shortlived(thd, &table_list, GTS_TABLE | GTS_VIEW);
+ share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW);
if (!share)
{
if (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE ||
@@ -4676,7 +4804,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
table_list.view= (LEX*) share->is_view;
res= schema_table->process_table(thd, &table_list, table,
res, db_name, table_name);
- free_root(&tbl.mem_root, MYF(0));
+ closefrm(&tbl);
}
@@ -4714,16 +4842,14 @@ public:
bool handle_condition(THD *thd,
uint sql_errno,
const char* sqlstate,
- Sql_condition::enum_warning_level level,
+ Sql_condition::enum_warning_level *level,
const char* msg,
Sql_condition ** cond_hdl)
{
- if (sql_errno == ER_PARSE_ERROR ||
- sql_errno == ER_TRG_NO_DEFINER ||
- sql_errno == ER_TRG_NO_CREATION_CTX)
+ if (sql_errno == ER_TRG_NO_DEFINER || sql_errno == ER_TRG_NO_CREATION_CTX)
return true;
- if (level != Sql_condition::WARN_LEVEL_ERROR)
+ if (*level != Sql_condition::WARN_LEVEL_ERROR)
return false;
if (!thd->get_stmt_da()->is_error())
@@ -5077,10 +5203,11 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
if (share->tmp_table == SYSTEM_TMP_TABLE)
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
- else if (share->tmp_table)
- table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
else
+ {
+ DBUG_ASSERT(share->tmp_table == NO_TMP_TABLE);
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
+ }
for (int i= 4; i < 20; i++)
{
@@ -5357,7 +5484,7 @@ static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs,
*/
tmp_buff= strchr(column_type.c_ptr_safe(), ' ');
table->field[offset]->store(column_type.ptr(),
- (tmp_buff ? tmp_buff - column_type.ptr() :
+ (tmp_buff ? (uint)(tmp_buff - column_type.ptr()) :
column_type.length()), cs);
is_blob= (field->type() == MYSQL_TYPE_BLOB);
@@ -5462,6 +5589,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
TABLE *show_table;
Field **ptr, *field;
int count;
+ bool quoted_defaults= lex->sql_command != SQLCOM_SHOW_FIELDS;
DBUG_ENTER("get_schema_column_record");
if (res)
@@ -5531,7 +5659,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
cs);
table->field[4]->store((longlong) count, TRUE);
- if (get_field_default_value(thd, field, &type, 0))
+ if (get_field_default_value(thd, field, &type, quoted_defaults))
{
table->field[5]->store(type.ptr(), type.length(), cs);
table->field[5]->set_notnull();
@@ -5550,13 +5678,24 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
table->field[17]->store(STRING_WITH_LEN("auto_increment"), cs);
if (print_on_update_clause(field, &type, true))
table->field[17]->store(type.ptr(), type.length(), cs);
+
if (field->vcol_info)
{
- if (field->stored_in_db)
- table->field[17]->store(STRING_WITH_LEN("PERSISTENT"), cs);
+ String gen_s(tmp,sizeof(tmp), system_charset_info);
+ gen_s.length(0);
+ field->vcol_info->print(&gen_s);
+ table->field[21]->store(gen_s.ptr(), gen_s.length(), cs);
+ table->field[21]->set_notnull();
+ table->field[20]->store(STRING_WITH_LEN("ALWAYS"), cs);
+
+ if (field->vcol_info->stored_in_db)
+ table->field[17]->store(STRING_WITH_LEN("STORED GENERATED"), cs);
else
- table->field[17]->store(STRING_WITH_LEN("VIRTUAL"), cs);
+ table->field[17]->store(STRING_WITH_LEN("VIRTUAL GENERATED"), cs);
}
+ else
+ table->field[20]->store(STRING_WITH_LEN("NEVER"), cs);
+
table->field[19]->store(field->comment.str, field->comment.length, cs);
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -5836,7 +5975,6 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
if (sp)
{
Field *field;
- Create_field *field_def;
String tmp_string;
if (routine_type == TYPE_ENUM_FUNCTION)
{
@@ -5848,14 +5986,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
get_field(thd->mem_root, proc_table->field[MYSQL_PROC_MYSQL_TYPE],
&tmp_string);
table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs);
- field_def= &sp->m_return_field_def;
- field= make_field(&share, thd->mem_root,
- (uchar*) 0, field_def->length,
- (uchar*) "", 0, field_def->pack_flag,
- field_def->sql_type, field_def->charset,
- field_def->geom_type, field_def->srid, Field::NONE,
- field_def->interval, "");
-
+ field= sp->m_return_field_def.make_field(&share, thd->mem_root, "");
field->table= &tbl;
tbl.in_use= thd;
store_column_type(table, field, cs, 6);
@@ -5874,7 +6005,6 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
{
const char *tmp_buff;
sp_variable *spvar= spcont->find_variable(i);
- field_def= &spvar->field_def;
switch (spvar->mode) {
case sp_variable::MODE_IN:
tmp_buff= "IN";
@@ -5903,12 +6033,8 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
&tmp_string);
table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs);
- field= make_field(&share, thd->mem_root, (uchar*) 0, field_def->length,
- (uchar*) "", 0, field_def->pack_flag,
- field_def->sql_type, field_def->charset,
- field_def->geom_type, field_def->srid, Field::NONE,
- field_def->interval, spvar->name.str);
-
+ field= spvar->field_def.make_field(&share, thd->mem_root,
+ spvar->name.str);
field->table= &tbl;
tbl.in_use= thd;
store_column_type(table, field, cs, 6);
@@ -5995,18 +6121,11 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
TABLE_SHARE share;
TABLE tbl;
Field *field;
- Create_field *field_def= &sp->m_return_field_def;
bzero((char*) &tbl, sizeof(TABLE));
(void) build_table_filename(path, sizeof(path), "", "", "", 0);
init_tmp_table_share(thd, &share, "", 0, "", path);
- field= make_field(&share, thd->mem_root, (uchar*) 0,
- field_def->length,
- (uchar*) "", 0, field_def->pack_flag,
- field_def->sql_type, field_def->charset,
- field_def->geom_type, field_def->srid, Field::NONE,
- field_def->interval, "");
-
+ field= sp->m_return_field_def.make_field(&share, thd->mem_root, "");
field->table= &tbl;
tbl.in_use= thd;
store_column_type(table, field, cs, 5);
@@ -6354,7 +6473,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
table->field[5]->store(STRING_WITH_LEN("NO"), cs);
}
- definer_len= (strxmov(definer, tables->definer.user.str, "@",
+ definer_len= (uint)(strxmov(definer, tables->definer.user.str, "@",
tables->definer.host.str, NullS) - definer);
table->field[6]->store(definer, definer_len, cs);
if (tables->view_suid)
@@ -6401,6 +6520,56 @@ bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
return schema_table_store_record(thd, table);
}
+static int get_check_constraints_record(THD *thd, TABLE_LIST *tables,
+ TABLE *table, bool res,
+ LEX_STRING *db_name,
+ LEX_STRING *table_name)
+{
+ DBUG_ENTER("get_check_constraints_record");
+ if (res)
+ {
+ if (thd->is_error())
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ thd->get_stmt_da()->sql_errno(),
+ thd->get_stmt_da()->message());
+ thd->clear_error();
+ DBUG_RETURN(0);
+ }
+ if (!tables->view)
+ {
+ StringBuffer<MAX_FIELD_WIDTH> str(system_charset_info);
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ TABLE_LIST table_acl_check;
+ bzero((char*) &table_acl_check, sizeof(table_acl_check));
+#endif
+ for (uint i= 0; i < tables->table->s->table_check_constraints; 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, FALSE, 1, TRUE))
+ continue;
+ }
+#endif
+ Virtual_column_info *check= tables->table->check_constraints[i];
+ table->field[0]->store(STRING_WITH_LEN("def"), system_charset_info);
+ table->field[3]->store(check->name.str, check->name.length,
+ system_charset_info);
+ /* Make sure the string is empty between each print. */
+ str.length(0);
+ check->print(&str);
+ table->field[4]->store(str.ptr(), str.length(), system_charset_info);
+ if (schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_RETURN(res);
+}
static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
TABLE *table, bool res,
@@ -6447,6 +6616,19 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
}
}
+ // Table check constraints
+ for ( uint i = 0; i < show_table->s->table_check_constraints; i++ )
+ {
+ Virtual_column_info *check = show_table->check_constraints[ i ];
+
+ if ( store_constraints( thd, table, db_name, table_name, check->name.str,
+ check->name.length,
+ STRING_WITH_LEN( "CHECK" ) ) )
+ {
+ DBUG_RETURN( 1 );
+ }
+ }
+
show_table->file->get_foreign_key_list(thd, &f_key_list);
FOREIGN_KEY_INFO *f_key_info;
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
@@ -6463,43 +6645,56 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
}
-static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name,
- LEX_STRING *table_name, LEX_STRING *trigger_name,
- enum trg_event_type event,
- enum trg_action_time_type timing,
- LEX_STRING *trigger_stmt,
- ulong sql_mode,
- LEX_STRING *definer_buffer,
- LEX_STRING *client_cs_name,
- LEX_STRING *connection_cl_name,
- LEX_STRING *db_cl_name)
+static bool store_trigger(THD *thd, Trigger *trigger,
+ TABLE *table, LEX_STRING *db_name,
+ LEX_STRING *table_name)
{
CHARSET_INFO *cs= system_charset_info;
LEX_STRING sql_mode_rep;
+ MYSQL_TIME timestamp;
+ char definer_holder[USER_HOST_BUFF_SIZE];
+ LEX_STRING definer_buffer, trigger_stmt, trigger_body;
+ definer_buffer.str= definer_holder;
+
+ trigger->get_trigger_info(&trigger_stmt, &trigger_body, &definer_buffer);
restore_record(table, s->default_values);
table->field[0]->store(STRING_WITH_LEN("def"), cs);
table->field[1]->store(db_name->str, db_name->length, cs);
- table->field[2]->store(trigger_name->str, trigger_name->length, cs);
- table->field[3]->store(trg_event_type_names[event].str,
- trg_event_type_names[event].length, cs);
+ table->field[2]->store(trigger->name.str, trigger->name.length, cs);
+ table->field[3]->store(trg_event_type_names[trigger->event].str,
+ trg_event_type_names[trigger->event].length, cs);
table->field[4]->store(STRING_WITH_LEN("def"), cs);
table->field[5]->store(db_name->str, db_name->length, cs);
table->field[6]->store(table_name->str, table_name->length, cs);
- table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs);
+ table->field[7]->store(trigger->action_order);
+ table->field[9]->store(trigger_body.str, trigger_body.length, cs);
table->field[10]->store(STRING_WITH_LEN("ROW"), cs);
- table->field[11]->store(trg_action_time_type_names[timing].str,
- trg_action_time_type_names[timing].length, cs);
+ table->field[11]->store(trg_action_time_type_names[trigger->action_time].str,
+ trg_action_time_type_names[trigger->action_time].length, cs);
table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
- sql_mode_string_representation(thd, sql_mode, &sql_mode_rep);
+ if (trigger->create_time)
+ {
+ table->field[16]->set_notnull();
+ thd->variables.time_zone->gmt_sec_to_TIME(&timestamp,
+ (my_time_t)(trigger->create_time/100));
+ /* timestamp is with 6 digits */
+ timestamp.second_part= (trigger->create_time % 100) * 10000;
+ ((Field_temporal_with_date*) table->field[16])->store_time_dec(&timestamp,
+ 2);
+ }
+
+ sql_mode_string_representation(thd, trigger->sql_mode, &sql_mode_rep);
table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
- table->field[18]->store(definer_buffer->str, definer_buffer->length, cs);
- table->field[19]->store(client_cs_name->str, client_cs_name->length, cs);
- table->field[20]->store(connection_cl_name->str,
- connection_cl_name->length, cs);
- table->field[21]->store(db_cl_name->str, db_cl_name->length, cs);
+ table->field[18]->store(definer_buffer.str, definer_buffer.length, cs);
+ table->field[19]->store(trigger->client_cs_name.str,
+ trigger->client_cs_name.length, cs);
+ table->field[20]->store(trigger->connection_cl_name.str,
+ trigger->connection_cl_name.length, cs);
+ table->field[21]->store(trigger->db_cl_name.str,
+ trigger->db_cl_name.length, cs);
return schema_table_store_record(thd, table);
}
@@ -6536,35 +6731,16 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
{
for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
{
- LEX_STRING trigger_name;
- LEX_STRING trigger_stmt;
- ulong sql_mode;
- char definer_holder[USER_HOST_BUFF_SIZE];
- LEX_STRING definer_buffer;
- LEX_STRING client_cs_name;
- LEX_STRING connection_cl_name;
- LEX_STRING db_cl_name;
-
- definer_buffer.str= definer_holder;
- if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
- (enum trg_action_time_type)timing,
- &trigger_name, &trigger_stmt,
- &sql_mode,
- &definer_buffer,
- &client_cs_name,
- &connection_cl_name,
- &db_cl_name))
- continue;
-
- if (store_trigger(thd, table, db_name, table_name, &trigger_name,
- (enum trg_event_type) event,
- (enum trg_action_time_type) timing, &trigger_stmt,
- sql_mode,
- &definer_buffer,
- &client_cs_name,
- &connection_cl_name,
- &db_cl_name))
- DBUG_RETURN(1);
+ Trigger *trigger;
+ for (trigger= triggers->
+ get_trigger((enum trg_event_type) event,
+ (enum trg_action_time_type) timing) ;
+ trigger;
+ trigger= trigger->next)
+ {
+ if (store_trigger(thd, trigger, table, db_name, table_name))
+ DBUG_RETURN(1);
+ }
}
}
}
@@ -6841,7 +7017,7 @@ get_partition_column_description(THD *thd,
{
part_column_list_val *col_val= &list_value->col_val_array[i];
if (col_val->max_value)
- tmp_str.append(partition_keywords[PKW_MAXVALUE].str);
+ tmp_str.append(STRING_WITH_LEN("MAXVALUE"));
else if (col_val->null_value)
tmp_str.append("NULL");
else
@@ -6918,27 +7094,21 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
case LIST_PARTITION:
tmp_res.length(0);
if (part_info->part_type == RANGE_PARTITION)
- tmp_res.append(partition_keywords[PKW_RANGE].str,
- partition_keywords[PKW_RANGE].length);
+ tmp_res.append(STRING_WITH_LEN("RANGE"));
else
- tmp_res.append(partition_keywords[PKW_LIST].str,
- partition_keywords[PKW_LIST].length);
+ tmp_res.append(STRING_WITH_LEN("LIST"));
if (part_info->column_list)
- tmp_res.append(partition_keywords[PKW_COLUMNS].str,
- partition_keywords[PKW_COLUMNS].length);
+ tmp_res.append(STRING_WITH_LEN(" COLUMNS"));
table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
break;
case HASH_PARTITION:
tmp_res.length(0);
if (part_info->linear_hash_ind)
- tmp_res.append(partition_keywords[PKW_LINEAR].str,
- partition_keywords[PKW_LINEAR].length);
+ tmp_res.append(STRING_WITH_LEN("LINEAR "));
if (part_info->list_of_part_fields)
- tmp_res.append(partition_keywords[PKW_KEY].str,
- partition_keywords[PKW_KEY].length);
+ tmp_res.append(STRING_WITH_LEN("KEY"));
else
- tmp_res.append(partition_keywords[PKW_HASH].str,
- partition_keywords[PKW_HASH].length);
+ tmp_res.append(STRING_WITH_LEN("HASH"));
table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
break;
default:
@@ -6951,8 +7121,9 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
/* Partition expression */
if (part_info->part_expr)
{
- table->field[9]->store(part_info->part_func_string,
- part_info->part_func_len, cs);
+ StringBuffer<STRING_BUFFER_USUAL_SIZE> str(cs);
+ part_info->part_expr->print_for_table_def(&str);
+ table->field[9]->store(str.ptr(), str.length(), str.charset());
}
else if (part_info->list_of_part_fields)
{
@@ -6966,22 +7137,20 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
/* Subpartition method */
tmp_res.length(0);
if (part_info->linear_hash_ind)
- tmp_res.append(partition_keywords[PKW_LINEAR].str,
- partition_keywords[PKW_LINEAR].length);
+ tmp_res.append(STRING_WITH_LEN("LINEAR "));
if (part_info->list_of_subpart_fields)
- tmp_res.append(partition_keywords[PKW_KEY].str,
- partition_keywords[PKW_KEY].length);
+ tmp_res.append(STRING_WITH_LEN("KEY"));
else
- tmp_res.append(partition_keywords[PKW_HASH].str,
- partition_keywords[PKW_HASH].length);
+ tmp_res.append(STRING_WITH_LEN("HASH"));
table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs);
table->field[8]->set_notnull();
/* Subpartition expression */
if (part_info->subpart_expr)
{
- table->field[10]->store(part_info->subpart_func_string,
- part_info->subpart_func_len, cs);
+ StringBuffer<STRING_BUFFER_USUAL_SIZE> str(cs);
+ part_info->subpart_expr->print_for_table_def(&str);
+ table->field[10]->store(str.ptr(), str.length(), str.charset());
}
else if (part_info->list_of_subpart_fields)
{
@@ -7022,8 +7191,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
if (part_elem->range_value != LONGLONG_MAX)
table->field[11]->store((longlong) part_elem->range_value, FALSE);
else
- table->field[11]->store(partition_keywords[PKW_MAXVALUE].str,
- partition_keywords[PKW_MAXVALUE].length, cs);
+ table->field[11]->store(STRING_WITH_LEN("MAXVALUE"), cs);
}
table->field[11]->set_notnull();
}
@@ -7338,7 +7506,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
COND *partial_cond= make_cond_for_info_schema(thd, cond, tables);
- mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ mysql_prlock_rdlock(&LOCK_system_variables_hash);
/*
Avoid recursive LOCK_system_variables_hash acquisition in
@@ -7353,7 +7521,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, scope),
scope, NULL, "", tables->table,
upper_case_names, partial_cond);
- mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_prlock_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res);
}
@@ -7648,6 +7816,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
strlen(fields_info->field_name),
fields_info->field_type)))
DBUG_RETURN(0);
+ item->decimals= fields_info->field_length;
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
@@ -7677,7 +7846,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
item->max_length+= 1;
if (item->decimals > 0)
item->max_length+= 1;
- item->set_name(fields_info->field_name,
+ item->set_name(thd, fields_info->field_name,
strlen(fields_info->field_name), cs);
break;
case MYSQL_TYPE_TINY_BLOB:
@@ -7700,7 +7869,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
{
DBUG_RETURN(0);
}
- item->set_name(fields_info->field_name,
+ item->set_name(thd, fields_info->field_name,
strlen(fields_info->field_name), cs);
break;
}
@@ -7759,7 +7928,7 @@ static int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
Item_field(thd, context, NullS, NullS, field_info->field_name);
if (field)
{
- field->set_name(field_info->old_name,
+ field->set_name(thd, field_info->old_name,
strlen(field_info->old_name),
system_charset_info);
if (add_item_to_list(thd, field))
@@ -7794,7 +7963,7 @@ int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
buffer.append(lex->wild->ptr());
buffer.append(')');
}
- field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
+ field->set_name(thd, buffer.ptr(), buffer.length(), system_charset_info);
}
return 0;
}
@@ -7821,15 +7990,15 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
NullS, NullS, field_info->field_name);
if (add_item_to_list(thd, field))
return 1;
- field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
+ field->set_name(thd, buffer.ptr(), buffer.length(), system_charset_info);
if (thd->lex->verbose)
{
- field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
+ field->set_name(thd, buffer.ptr(), buffer.length(), system_charset_info);
field_info= &schema_table->fields_info[3];
field= new (thd->mem_root) Item_field(thd, context, NullS, NullS, field_info->field_name);
if (add_item_to_list(thd, field))
return 1;
- field->set_name(field_info->old_name, strlen(field_info->old_name),
+ field->set_name(thd, field_info->old_name, strlen(field_info->old_name),
system_charset_info);
}
return 0;
@@ -7854,7 +8023,7 @@ int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
NullS, NullS, field_info->field_name);
if (field)
{
- field->set_name(field_info->old_name,
+ field->set_name(thd, field_info->old_name,
strlen(field_info->old_name),
system_charset_info);
if (add_item_to_list(thd, field))
@@ -7879,7 +8048,7 @@ int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
NullS, NullS, field_info->field_name);
if (field)
{
- field->set_name(field_info->old_name,
+ field->set_name(thd, field_info->old_name,
strlen(field_info->old_name),
system_charset_info);
if (add_item_to_list(thd, field))
@@ -7904,7 +8073,7 @@ int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
NullS, NullS, field_info->field_name);
if (field)
{
- field->set_name(field_info->old_name,
+ field->set_name(thd, field_info->old_name,
strlen(field_info->old_name),
system_charset_info);
if (add_item_to_list(thd, field))
@@ -8130,7 +8299,6 @@ end:
bool optimize_schema_tables_reads(JOIN *join)
{
THD *thd= join->thd;
- bool result= 0;
DBUG_ENTER("optimize_schema_tables_reads");
JOIN_TAB *tab;
@@ -8165,11 +8333,11 @@ bool optimize_schema_tables_reads(JOIN *join)
*/
cond= tab->cache_select->cond;
}
-
- optimize_for_get_all_tables(thd, table_list, cond);
+ if (optimize_for_get_all_tables(thd, table_list, cond))
+ DBUG_RETURN(TRUE); // Handle OOM
}
}
- DBUG_RETURN(result);
+ DBUG_RETURN(FALSE);
}
@@ -8256,8 +8424,6 @@ bool get_schema_tables_result(JOIN *join,
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
table_list->table->file->ha_delete_all_rows();
- free_io_cache(table_list->table);
- filesort_free_buffers(table_list->table,1);
table_list->table->null_row= 0;
}
else
@@ -8277,6 +8443,7 @@ bool get_schema_tables_result(JOIN *join,
cond= tab->cache_select->cond;
}
+ Switch_to_definer_security_ctx backup_ctx(thd, table_list);
if (table_list->schema_table->fill_table(thd, table_list, cond))
{
result= 1;
@@ -8516,10 +8683,13 @@ ST_FIELD_INFO columns_fields_info[]=
OPEN_FRM_ONLY},
{"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
{"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
- {"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
+ {"EXTRA", 30, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
{"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0,
"Comment", OPEN_FRM_ONLY},
+ {"IS_GENERATED", 6, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
+ {"GENERATION_EXPRESSION", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0, 1,
+ 0, OPEN_FRM_ONLY},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -8854,7 +9024,8 @@ ST_FIELD_INFO triggers_fields_info[]=
OPEN_FRM_ONLY},
{"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
{"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
- {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FRM_ONLY},
+ /* 2 here indicates 2 decimals */
+ {"CREATED", 2, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FRM_ONLY},
{"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FRM_ONLY},
{"DEFINER", DEFINER_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FRM_ONLY},
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
@@ -8958,7 +9129,7 @@ ST_FIELD_INFO processlist_fields_info[]=
{"MAX_STAGE", 2, MYSQL_TYPE_TINY, 0, 0, "Max_stage", SKIP_OPEN_TABLE},
{"PROGRESS", 703, MYSQL_TYPE_DECIMAL, 0, 0, "Progress",
SKIP_OPEN_TABLE},
- {"MEMORY_USED", 7, MYSQL_TYPE_LONG, 0, 0, "Memory_used", SKIP_OPEN_TABLE},
+ {"MEMORY_USED", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Memory_used", SKIP_OPEN_TABLE},
{"EXAMINED_ROWS", 7, MYSQL_TYPE_LONG, 0, 0, "Examined_rows", SKIP_OPEN_TABLE},
{"QUERY_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
{"INFO_BINARY", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_BLOB, 0, 1,
@@ -8991,7 +9162,7 @@ ST_FIELD_INFO plugin_fields_info[]=
ST_FIELD_INFO files_fields_info[]=
{
{"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
- {"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
+ {"FILE_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
SKIP_OPEN_TABLE},
@@ -9211,6 +9382,18 @@ ST_FIELD_INFO spatial_ref_sys_fields_info[]=
};
#endif /*HAVE_SPATIAL*/
+ST_FIELD_INFO check_constraints_fields_info[]=
+{
+ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+ OPEN_FULL_TABLE},
+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
+ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+ OPEN_FULL_TABLE},
+ {"CHECK_CLAUSE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
+ OPEN_FULL_TABLE},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
+};
/*
Description of ST_FIELD_INFO in table.h
@@ -9227,6 +9410,8 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_schema_applicable_roles, 0, 0, -1, -1, 0, 0},
{"CHARACTER_SETS", charsets_fields_info, 0,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
+ {"CHECK_CONSTRAINTS", check_constraints_fields_info, 0, get_all_tables, 0,
+ get_check_constraints_record, 1, 2, 0, OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY},
{"COLLATIONS", collation_fields_info, 0,
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
@@ -9385,35 +9570,35 @@ int finalize_schema_table(st_plugin_int *plugin)
DBUG_RETURN(0);
}
+/*
+ This is used to create a timestamp field
+*/
+
+MYSQL_TIME zero_time={ 0,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_TIME };
/**
Output trigger information (SHOW CREATE TRIGGER) to the client.
@param thd Thread context.
- @param triggers List of triggers for the table.
- @param trigger_idx Index of the trigger to dump.
+ @param trigger Trigger to dump
@return Operation status
@retval TRUE Error.
@retval FALSE Success.
*/
-static bool show_create_trigger_impl(THD *thd,
- Table_triggers_list *triggers,
- int trigger_idx)
+static bool show_create_trigger_impl(THD *thd, Trigger *trigger)
{
int ret_code;
Protocol *p= thd->protocol;
List<Item> fields;
- LEX_STRING trg_name;
- ulonglong trg_sql_mode;
- LEX_STRING trg_sql_mode_str;
+ LEX_STRING trg_sql_mode_str, trg_body;
LEX_STRING trg_sql_original_stmt;
- LEX_STRING trg_client_cs_name;
- LEX_STRING trg_connection_cl_name;
- LEX_STRING trg_db_cl_name;
+ LEX_STRING trg_definer;
CHARSET_INFO *trg_client_cs;
MEM_ROOT *mem_root= thd->mem_root;
+ char definer_holder[USER_HOST_BUFF_SIZE];
+ trg_definer.str= definer_holder;
/*
TODO: Check privileges here. This functionality will be added by
@@ -9427,20 +9612,12 @@ static bool show_create_trigger_impl(THD *thd,
/* Prepare trigger "object". */
- triggers->get_trigger_info(thd,
- trigger_idx,
- &trg_name,
- &trg_sql_mode,
- &trg_sql_original_stmt,
- &trg_client_cs_name,
- &trg_connection_cl_name,
- &trg_db_cl_name);
-
- sql_mode_string_representation(thd, trg_sql_mode, &trg_sql_mode_str);
+ trigger->get_trigger_info(&trg_sql_original_stmt, &trg_body, &trg_definer);
+ sql_mode_string_representation(thd, trigger->sql_mode, &trg_sql_mode_str);
/* Resolve trigger client character set. */
- if (resolve_charset(trg_client_cs_name.str, NULL, &trg_client_cs))
+ if (resolve_charset(trigger->client_cs_name.str, NULL, &trg_client_cs))
return TRUE;
/* Send header. */
@@ -9482,6 +9659,11 @@ static bool show_create_trigger_impl(THD *thd,
MY_CS_NAME_SIZE),
mem_root);
+ Item_datetime_literal *tmp= (new (mem_root)
+ Item_datetime_literal(thd, &zero_time, 2));
+ tmp->set_name(thd, STRING_WITH_LEN("Created"), system_charset_info);
+ fields.push_back(tmp, mem_root);
+
if (p->send_result_set_metadata(&fields,
Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
@@ -9491,8 +9673,8 @@ static bool show_create_trigger_impl(THD *thd,
p->prepare_for_resend();
- p->store(trg_name.str,
- trg_name.length,
+ p->store(trigger->name.str,
+ trigger->name.length,
system_charset_info);
p->store(trg_sql_mode_str.str,
@@ -9503,18 +9685,30 @@ static bool show_create_trigger_impl(THD *thd,
trg_sql_original_stmt.length,
trg_client_cs);
- p->store(trg_client_cs_name.str,
- trg_client_cs_name.length,
+ p->store(trigger->client_cs_name.str,
+ trigger->client_cs_name.length,
system_charset_info);
- p->store(trg_connection_cl_name.str,
- trg_connection_cl_name.length,
+ p->store(trigger->connection_cl_name.str,
+ trigger->connection_cl_name.length,
system_charset_info);
- p->store(trg_db_cl_name.str,
- trg_db_cl_name.length,
+ p->store(trigger->db_cl_name.str,
+ trigger->db_cl_name.length,
system_charset_info);
+ if (trigger->create_time)
+ {
+ MYSQL_TIME timestamp;
+ thd->variables.time_zone->gmt_sec_to_TIME(&timestamp,
+ (my_time_t)(trigger->create_time/100));
+ timestamp.second_part= (trigger->create_time % 100) * 10000;
+ p->store(&timestamp, 2);
+ }
+ else
+ p->store_null();
+
+
ret_code= p->write();
if (!ret_code)
@@ -9606,7 +9800,7 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name)
TABLE_LIST *lst= get_trigger_table(thd, trg_name);
uint num_tables; /* NOTE: unused, only to pass to open_tables(). */
Table_triggers_list *triggers;
- int trigger_idx;
+ Trigger *trigger;
bool error= TRUE;
if (!lst)
@@ -9647,9 +9841,9 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name)
goto exit;
}
- trigger_idx= triggers->find_trigger_by_name(&trg_name->m_name);
+ trigger= triggers->find_trigger(&trg_name->m_name, 0);
- if (trigger_idx < 0)
+ if (!trigger)
{
my_error(ER_TRG_CORRUPTED_FILE, MYF(0),
(const char *) trg_name->m_db.str,
@@ -9658,7 +9852,7 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name)
goto exit;
}
- error= show_create_trigger_impl(thd, triggers, trigger_idx);
+ error= show_create_trigger_impl(thd, trigger);
/*
NOTE: if show_create_trigger_impl() failed, that means we could not
@@ -9840,7 +10034,7 @@ char *thd_get_error_context_description(THD *thd, char *buffer,
int len;
len= my_snprintf(header, sizeof(header),
- "MySQL thread id %lu, OS thread handle 0x%lx, query id %lu",
+ "MySQL thread id %lu, OS thread handle %lu, query id %lu",
thd->thread_id, (ulong) thd->real_id, (ulong) thd->query_id);
str.length(0);
str.append(header, len);