132
bool buildScemas(Session *session)
134
session->getLex()->sql_command= SQLCOM_SELECT;
135
session->getLex()->statement= new statement::Show(session);
137
std::string column_name= "Database";
138
if (session->getLex()->wild)
140
column_name.append(" (");
141
column_name.append(session->getLex()->wild->ptr());
142
column_name.append(")");
145
if (session->getLex()->current_select->where)
147
if (prepare_new_schema_table(session, session->getLex(), "SCHEMAS"))
152
if (prepare_new_schema_table(session, session->getLex(), "SHOW_SCHEMAS"))
156
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "SCHEMA_NAME");
157
my_field->is_autogenerated_name= false;
158
my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
160
if (session->add_item_to_list(my_field))
163
if (session->add_order_to_list(my_field, true))
169
bool buildTables(Session *session, const char *ident)
171
session->getLex()->sql_command= SQLCOM_SELECT;
173
drizzled::statement::Show *select= new statement::Show(session);
174
session->getLex()->statement= select;
176
std::string column_name= "Tables_in_";
178
util::string::const_shared_ptr schema(session->schema());
181
identifier::Schema identifier(ident);
182
column_name.append(ident);
183
session->getLex()->select_lex.db= const_cast<char *>(ident);
184
if (not plugin::StorageEngine::doesSchemaExist(identifier))
186
my_error(ER_BAD_DB_ERROR, MYF(0), ident);
188
select->setShowPredicate(ident, "");
190
else if (schema and not schema->empty())
192
column_name.append(*schema);
193
select->setShowPredicate(*schema, "");
197
my_error(ER_NO_DB_ERROR, MYF(0));
202
if (session->getLex()->wild)
204
column_name.append(" (");
205
column_name.append(session->getLex()->wild->ptr());
206
column_name.append(")");
209
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TABLES"))
212
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "TABLE_NAME");
213
my_field->is_autogenerated_name= false;
214
my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
216
if (session->add_item_to_list(my_field))
219
if (session->add_order_to_list(my_field, true))
225
bool buildTemporaryTables(Session *session)
227
session->getLex()->sql_command= SQLCOM_SELECT;
229
session->getLex()->statement= new statement::Show(session);
232
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TEMPORARY_TABLES"))
235
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
238
(session->lex->current_select->with_wild)++;
243
bool buildTableStatus(Session *session, const char *ident)
245
session->getLex()->sql_command= SQLCOM_SELECT;
246
drizzled::statement::Show *select= new statement::Show(session);
247
session->getLex()->statement= select;
249
std::string column_name= "Tables_in_";
251
util::string::const_shared_ptr schema(session->schema());
254
session->getLex()->select_lex.db= const_cast<char *>(ident);
256
identifier::Schema identifier(ident);
257
if (not plugin::StorageEngine::doesSchemaExist(identifier))
259
my_error(ER_BAD_DB_ERROR, MYF(0), ident);
262
select->setShowPredicate(ident, "");
266
select->setShowPredicate(*schema, "");
270
my_error(ER_NO_DB_ERROR, MYF(0));
274
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TABLE_STATUS"))
277
if (session->add_item_to_list( new Item_field(&session->lex->current_select->
282
(session->lex->current_select->with_wild)++;
287
bool buildEngineStatus(Session *session, LEX_STRING)
289
session->getLex()->sql_command= SQLCOM_SELECT;
290
drizzled::statement::Show *select= new statement::Show(session);
291
session->getLex()->statement= select;
293
my_error(ER_USE_DATA_DICTIONARY);
297
bool buildColumns(Session *session, const char *schema_ident, Table_ident *table_ident)
299
session->getLex()->sql_command= SQLCOM_SELECT;
301
drizzled::statement::Show *select= new statement::Show(session);
302
session->getLex()->statement= select;
304
util::string::const_shared_ptr schema(session->schema());
307
select->setShowPredicate(schema_ident, table_ident->table.str);
309
else if (table_ident->db.str)
311
select->setShowPredicate(table_ident->db.str, table_ident->table.str);
315
select->setShowPredicate(*schema, table_ident->table.str);
319
my_error(ER_NO_DB_ERROR, MYF(0));
324
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
325
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
327
my_error(ER_TABLE_UNKNOWN, identifier);
331
if (prepare_new_schema_table(session, session->getLex(), "SHOW_COLUMNS"))
334
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
337
(session->lex->current_select->with_wild)++;
342
void buildSelectWarning(Session *session)
344
(void) create_select_for_variable(session, "warning_count");
345
session->getLex()->statement= new statement::Show(session);
348
void buildSelectError(Session *session)
350
(void) create_select_for_variable(session, "error_count");
351
session->getLex()->statement= new statement::Show(session);
354
void buildWarnings(Session *session)
356
session->getLex()->statement= new statement::ShowWarnings(session);
359
void buildErrors(Session *session)
361
session->getLex()->statement= new statement::ShowErrors(session);
364
bool buildIndex(Session *session, const char *schema_ident, Table_ident *table_ident)
366
session->getLex()->sql_command= SQLCOM_SELECT;
367
drizzled::statement::Show *select= new statement::Show(session);
368
session->getLex()->statement= select;
370
util::string::const_shared_ptr schema(session->schema());
373
select->setShowPredicate(schema_ident, table_ident->table.str);
375
else if (table_ident->db.str)
377
select->setShowPredicate(table_ident->db.str, table_ident->table.str);
381
select->setShowPredicate(*schema, table_ident->table.str);
385
my_error(ER_NO_DB_ERROR, MYF(0));
390
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
391
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
393
my_error(ER_TABLE_UNKNOWN, identifier);
397
if (prepare_new_schema_table(session, session->getLex(), "SHOW_INDEXES"))
400
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
403
(session->lex->current_select->with_wild)++;
408
bool buildStatus(Session *session, const drizzled::sql_var_t is_global)
410
session->getLex()->sql_command= SQLCOM_SELECT;
411
session->getLex()->statement= new statement::Show(session);
413
if (is_global == OPT_GLOBAL)
415
if (prepare_new_schema_table(session, session->getLex(), "GLOBAL_STATUS"))
420
if (prepare_new_schema_table(session, session->getLex(), "SESSION_STATUS"))
424
std::string key("Variable_name");
425
std::string value("Value");
427
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_NAME");
428
my_field->is_autogenerated_name= false;
429
my_field->set_name(key.c_str(), key.length(), system_charset_info);
431
if (session->add_item_to_list(my_field))
434
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_VALUE");
435
my_field->is_autogenerated_name= false;
436
my_field->set_name(value.c_str(), value.length(), system_charset_info);
438
if (session->add_item_to_list(my_field))
444
bool buildCreateTable(Session *session, Table_ident *ident)
446
session->getLex()->sql_command= SQLCOM_SELECT;
447
statement::Show *select= new statement::Show(session);
448
session->getLex()->statement= select;
450
if (session->getLex()->statement == NULL)
453
if (prepare_new_schema_table(session, session->getLex(), "TABLE_SQL_DEFINITION"))
456
util::string::const_shared_ptr schema(session->schema());
459
select->setShowPredicate(ident->db.str, ident->table.str);
463
select->setShowPredicate(*schema, ident->table.str);
467
my_error(ER_NO_DB_ERROR, MYF(0));
471
std::string key("Table");
472
std::string value("Create Table");
474
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "TABLE_NAME");
475
my_field->is_autogenerated_name= false;
476
my_field->set_name(key.c_str(), key.length(), system_charset_info);
478
if (session->add_item_to_list(my_field))
481
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "TABLE_SQL_DEFINITION");
482
my_field->is_autogenerated_name= false;
483
my_field->set_name(value.c_str(), value.length(), system_charset_info);
485
if (session->add_item_to_list(my_field))
491
bool buildProcesslist(Session *session)
493
session->getLex()->sql_command= SQLCOM_SELECT;
494
session->getLex()->statement= new statement::Show(session);
496
if (prepare_new_schema_table(session, session->getLex(), "PROCESSLIST"))
499
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
502
(session->lex->current_select->with_wild)++;
507
bool buildVariables(Session *session, const drizzled::sql_var_t is_global)
509
session->getLex()->sql_command= SQLCOM_SELECT;
510
session->getLex()->statement= new statement::Show(session);
512
if (is_global == OPT_GLOBAL)
514
if (prepare_new_schema_table(session, session->getLex(), "GLOBAL_VARIABLES"))
519
if (prepare_new_schema_table(session, session->getLex(), "SESSION_VARIABLES"))
523
std::string key("Variable_name");
524
std::string value("Value");
526
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_NAME");
527
my_field->is_autogenerated_name= false;
528
my_field->set_name(key.c_str(), key.length(), system_charset_info);
530
if (session->add_item_to_list(my_field))
533
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_VALUE");
534
my_field->is_autogenerated_name= false;
535
my_field->set_name(value.c_str(), value.length(), system_charset_info);
537
if (session->add_item_to_list(my_field))
543
bool buildCreateSchema(Session *session, LEX_STRING &ident)
545
session->getLex()->sql_command= SQLCOM_SELECT;
546
drizzled::statement::Show *select= new statement::Show(session);
547
session->getLex()->statement= select;
549
if (prepare_new_schema_table(session, session->getLex(), "SCHEMA_SQL_DEFINITION"))
552
util::string::const_shared_ptr schema(session->schema());
555
select->setShowPredicate(ident.str);
559
select->setShowPredicate(*schema);
563
my_error(ER_NO_DB_ERROR, MYF(0));
567
std::string key("Database");
568
std::string value("Create Database");
570
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "SCHEMA_NAME");
571
my_field->is_autogenerated_name= false;
572
my_field->set_name(key.c_str(), key.length(), system_charset_info);
574
if (session->add_item_to_list(my_field))
577
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "SCHEMA_SQL_DEFINITION");
578
my_field->is_autogenerated_name= false;
579
my_field->set_name(value.c_str(), value.length(), system_charset_info);
581
if (session->add_item_to_list(my_field))
587
bool buildDescribe(Session *session, Table_ident *ident)
589
session->getLex()->lock_option= TL_READ;
590
init_select(session->getLex());
591
session->getLex()->current_select->parsing_place= SELECT_LIST;
592
session->getLex()->sql_command= SQLCOM_SELECT;
593
drizzled::statement::Show *select= new statement::Show(session);
594
session->getLex()->statement= select;
595
session->getLex()->select_lex.db= 0;
597
util::string::const_shared_ptr schema(session->schema());
600
select->setShowPredicate(ident->db.str, ident->table.str);
604
select->setShowPredicate(*schema, ident->table.str);
608
my_error(ER_NO_DB_ERROR, MYF(0));
613
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), ident->table.str);
614
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
616
my_error(ER_TABLE_UNKNOWN, identifier);
620
if (prepare_new_schema_table(session, session->getLex(), "SHOW_COLUMNS"))
625
if (session->add_item_to_list( new Item_field(&session->lex->current_select->
632
(session->lex->current_select->with_wild)++;
637
} /* namespace drizzled */
639
} /* namespace drizzled */
384
#define LIST_PROCESS_HOST_LEN 64
386
static bool get_field_default_value(Field *timestamp_field,
387
Field *field, String *def_value,
391
bool has_now_default;
394
We are using CURRENT_TIMESTAMP instead of NOW because it is
397
has_now_default= (timestamp_field == field &&
398
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
400
has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
401
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
402
field->unireg_check != Field::NEXT_NUMBER);
404
def_value->length(0);
408
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
409
else if (!field->is_null())
410
{ // Not null by default
411
char tmp[MAX_FIELD_WIDTH];
412
String type(tmp, sizeof(tmp), field->charset());
413
field->val_str(&type);
417
uint32_t dummy_errors;
418
/* convert to system_charset_info == utf8 */
419
def_val.copy(type.ptr(), type.length(), field->charset(),
420
system_charset_info, &dummy_errors);
422
append_unescaped(def_value, def_val.ptr(), def_val.length());
424
def_value->append(def_val.ptr(), def_val.length());
427
def_value->append(STRING_WITH_LEN("''"));
429
else if (field->maybe_null() && quoted)
430
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
438
Build a CREATE TABLE statement for a table.
442
table_list A list containing one table to write statement
444
packet Pointer to a string where statement will be
446
create_info_arg Pointer to create information that can be used
447
to tailor the format of the statement. Can be
448
NULL, in which case only SQL_MODE is considered
449
when building the statement.
452
Currently always return 0, but might return error code in the
459
int store_create_info(TableList *table_list, String *packet, HA_CREATE_INFO *create_info_arg)
461
List<Item> field_list;
462
char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
465
String type(tmp, sizeof(tmp), system_charset_info);
466
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
468
uint32_t primary_key;
470
Table *table= table_list->table;
471
handler *file= table->file;
472
TableShare *share= table->s;
473
HA_CREATE_INFO create_info;
474
bool show_table_options= false;
475
my_bitmap_map *old_map;
477
table->restoreRecordAsDefault(); // Get empty record
479
if (share->tmp_table)
480
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
482
packet->append(STRING_WITH_LEN("CREATE TABLE "));
483
if (create_info_arg &&
484
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
485
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
486
if (table_list->schema_table)
487
alias= table_list->schema_table->getTableName().c_str();
489
alias= share->table_name.str;
491
packet->append_identifier(alias, strlen(alias));
492
packet->append(STRING_WITH_LEN(" (\n"));
494
We need this to get default values from the table
495
We have to restore the read_set if we are called from insert in case
496
of row based replication.
498
old_map= table->use_all_columns(table->read_set);
500
for (ptr=table->field ; (field= *ptr); ptr++)
502
uint32_t flags = field->flags;
504
if (ptr != table->field)
505
packet->append(STRING_WITH_LEN(",\n"));
507
packet->append(STRING_WITH_LEN(" "));
508
packet->append_identifier(field->field_name, strlen(field->field_name));
510
// check for surprises from the previous call to Field::sql_type()
511
if (type.ptr() != tmp)
512
type.set(tmp, sizeof(tmp), system_charset_info);
514
type.set_charset(system_charset_info);
516
field->sql_type(type);
517
packet->append(type.ptr(), type.length(), system_charset_info);
519
if (field->has_charset())
521
if (field->charset() != share->table_charset)
523
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
524
packet->append(field->charset()->csname);
528
For string types dump collation name only if
529
collation is not primary for the given charset
531
if (!(field->charset()->state & MY_CS_PRIMARY))
533
packet->append(STRING_WITH_LEN(" COLLATE "));
534
packet->append(field->charset()->name);
538
if (flags & NOT_NULL_FLAG)
539
packet->append(STRING_WITH_LEN(" NOT NULL"));
540
else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
543
TIMESTAMP field require explicit NULL flag, because unlike
544
all other fields they are treated as NOT NULL by default.
546
packet->append(STRING_WITH_LEN(" NULL"));
550
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
551
and about STORAGE (DISK or MEMORY).
553
enum column_format_type column_format= (enum column_format_type)
554
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
557
packet->append(STRING_WITH_LEN(" /*!"));
558
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
559
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
560
packet->append(STRING_WITH_LEN(" FIXED */"));
562
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
565
if (get_field_default_value(table->timestamp_field, field, &def_value, 1))
567
packet->append(STRING_WITH_LEN(" DEFAULT "));
568
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
571
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
572
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
574
if (field->unireg_check == Field::NEXT_NUMBER)
575
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
577
if (field->comment.length)
579
packet->append(STRING_WITH_LEN(" COMMENT "));
580
append_unescaped(packet, field->comment.str, field->comment.length);
584
key_info= table->key_info;
585
memset(&create_info, 0, sizeof(create_info));
586
/* Allow update_create_info to update row type */
587
create_info.row_type= share->row_type;
588
file->update_create_info(&create_info);
589
primary_key= share->primary_key;
591
for (uint32_t i=0 ; i < share->keys ; i++,key_info++)
593
KEY_PART_INFO *key_part= key_info->key_part;
594
bool found_primary=0;
595
packet->append(STRING_WITH_LEN(",\n "));
597
if (i == primary_key && is_primary_key(key_info))
601
No space at end, because a space will be added after where the
602
identifier would go, but that is not added for primary key.
604
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
606
else if (key_info->flags & HA_NOSAME)
607
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
609
packet->append(STRING_WITH_LEN("KEY "));
612
packet->append_identifier(key_info->name, strlen(key_info->name));
614
packet->append(STRING_WITH_LEN(" ("));
616
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
622
packet->append_identifier(key_part->field->field_name,
623
strlen(key_part->field->field_name));
624
if (key_part->field &&
626
table->field[key_part->fieldnr-1]->key_length()))
629
buff.append(to_string((int32_t) key_part->length /
630
key_part->field->charset()->mbmaxlen));
632
packet->append(buff.c_str(), buff.length());
636
store_key_options(packet, table, key_info);
640
Get possible foreign key definitions stored in InnoDB and append them
641
to the CREATE TABLE statement
644
if ((for_str= file->get_foreign_key_create_info()))
646
packet->append(for_str, strlen(for_str));
647
file->free_foreign_key_create_info(for_str);
650
packet->append(STRING_WITH_LEN("\n)"));
652
show_table_options= true;
654
Get possible table space definitions and append them
655
to the CREATE TABLE statement
660
THEN add ENGINE only if it was used when creating the table
662
if (!create_info_arg ||
663
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
665
packet->append(STRING_WITH_LEN(" ENGINE="));
666
packet->append(file->engine->getName().c_str());
669
if (share->db_create_options & HA_OPTION_PACK_KEYS)
670
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
671
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
672
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
673
if (create_info.row_type != ROW_TYPE_DEFAULT)
675
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
676
packet->append(ha_row_type[(uint32_t) create_info.row_type]);
678
if (table->s->key_block_size)
680
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
681
buff= to_string(table->s->key_block_size);
682
packet->append(buff.c_str(), buff.length());
684
if (share->block_size)
686
packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
687
buff= to_string(share->block_size);
688
packet->append(buff.c_str(), buff.length());
690
table->file->append_create_info(packet);
691
if (share->hasComment() && share->getCommentLength())
693
packet->append(STRING_WITH_LEN(" COMMENT="));
694
append_unescaped(packet, share->getComment(),
695
share->getCommentLength());
698
table->restore_column_map(old_map);
702
static void store_key_options(String *packet, Table *table, KEY *key_info)
706
if (key_info->algorithm == HA_KEY_ALG_BTREE)
707
packet->append(STRING_WITH_LEN(" USING BTREE"));
709
if (key_info->algorithm == HA_KEY_ALG_HASH)
710
packet->append(STRING_WITH_LEN(" USING HASH"));
712
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
713
table->s->key_block_size != key_info->block_size)
715
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
716
end= int64_t10_to_str(key_info->block_size, buff, 10);
717
packet->append(buff, (uint32_t) (end - buff));
720
assert(test(key_info->flags & HA_USES_COMMENT) ==
721
(key_info->comment.length > 0));
722
if (key_info->flags & HA_USES_COMMENT)
724
packet->append(STRING_WITH_LEN(" COMMENT "));
725
append_unescaped(packet, key_info->comment.str,
726
key_info->comment.length);
731
/****************************************************************************
732
Return info about all processes
733
returns for each thread: thread id, user, host, db, command, info
734
****************************************************************************/
736
class thread_info :public ilink {
738
static void *operator new(size_t size)
740
return (void*) sql_alloc((uint32_t) size);
742
static void operator delete(void *, size_t)
743
{ TRASH(ptr, size); }
745
my_thread_id thread_id;
748
const char *user,*host,*db,*proc_info,*state_info;
752
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
753
template class I_List<thread_info>;
756
void mysqld_list_processes(Session *session,const char *user, bool)
759
List<Item> field_list;
760
I_List<thread_info> thread_infos;
761
plugin::Protocol *protocol= session->protocol;
763
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
764
field_list.push_back(new Item_empty_string("User",16));
765
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
766
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
767
field->maybe_null= true;
768
field_list.push_back(new Item_empty_string("Command",16));
769
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
770
field_list.push_back(field=new Item_empty_string("State",30));
771
field->maybe_null= true;
772
field_list.push_back(field=new Item_empty_string("Info", PROCESS_LIST_WIDTH));
773
field->maybe_null= true;
774
if (protocol->sendFields(&field_list))
777
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
778
if (!session->killed)
781
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
784
Security_context *tmp_sctx= &tmp->security_ctx;
785
struct st_my_thread_var *mysys_var;
786
if (tmp->protocol->isConnected() && (!user || (tmp_sctx->user.c_str() && !strcmp(tmp_sctx->user.c_str(), user))))
788
thread_info *session_info= new thread_info;
790
session_info->thread_id=tmp->thread_id;
791
session_info->user= session->strdup(tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user");
792
session_info->host= session->strdup(tmp_sctx->ip.c_str());
793
if ((session_info->db=tmp->db)) // Safe test
794
session_info->db=session->strdup(session_info->db);
795
session_info->command=(int) tmp->command;
796
if ((mysys_var= tmp->mysys_var))
797
pthread_mutex_lock(&mysys_var->mutex);
799
if (tmp->killed == Session::KILL_CONNECTION)
800
session_info->proc_info= (char*) "Killed";
802
session_info->proc_info= command_name[session_info->command].str;
804
session_info->state_info= (char*) (tmp->protocol->isWriting() ?
806
tmp->protocol->isReading() ?
807
(session_info->command == COM_SLEEP ?
808
NULL : "Reading from net") :
809
tmp->get_proc_info() ? tmp->get_proc_info() :
811
tmp->mysys_var->current_cond ?
812
"Waiting on cond" : NULL);
814
pthread_mutex_unlock(&mysys_var->mutex);
816
session_info->start_time= tmp->start_time;
817
session_info->query= NULL;
818
if (tmp->process_list_info[0])
819
session_info->query= session->strdup(tmp->process_list_info);
820
thread_infos.append(session_info);
824
pthread_mutex_unlock(&LOCK_thread_count);
826
thread_info *session_info;
827
time_t now= time(NULL);
828
while ((session_info=thread_infos.get()))
830
protocol->prepareForResend();
831
protocol->store((uint64_t) session_info->thread_id);
832
protocol->store(session_info->user);
833
protocol->store(session_info->host);
834
protocol->store(session_info->db);
835
protocol->store(session_info->proc_info);
837
if (session_info->start_time)
838
protocol->store((uint32_t) (now - session_info->start_time));
842
protocol->store(session_info->state_info);
843
protocol->store(session_info->query);
845
if (protocol->write())
846
break; /* purecov: inspected */
852
/*****************************************************************************
854
*****************************************************************************/
856
static vector<SHOW_VAR *> all_status_vars;
857
static bool status_vars_inited= 0;
858
int show_var_cmp(const void *var1, const void *var2)
860
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
863
class show_var_cmp_functor
866
show_var_cmp_functor() { }
867
inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const
869
int val= strcmp(var1->name, var2->name);
874
class show_var_remove_if
877
show_var_remove_if() { }
878
inline bool operator()(const SHOW_VAR *curr) const
880
return (curr->type == SHOW_UNDEF);
884
SHOW_VAR *getFrontOfStatusVars()
886
return all_status_vars.front();
890
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
893
add_status_vars(SHOW_VAR *list)
894
list - an array of SHOW_VAR entries to add to all_status_vars
895
the last entry must be {0,0,SHOW_UNDEF}
898
The handling of all_status_vars[] is completely internal, it's allocated
899
automatically when something is added to it, and deleted completely when
900
the last entry is removed.
902
As a special optimization, if add_status_vars() is called before
903
init_status_vars(), it assumes "startup mode" - neither concurrent access
904
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
906
int add_status_vars(SHOW_VAR *list)
909
if (status_vars_inited)
910
pthread_mutex_lock(&LOCK_status);
912
all_status_vars.insert(all_status_vars.begin(), list++);
913
if (status_vars_inited)
914
sort(all_status_vars.begin(), all_status_vars.end(),
915
show_var_cmp_functor());
916
if (status_vars_inited)
917
pthread_mutex_unlock(&LOCK_status);
922
Make all_status_vars[] usable for SHOW STATUS
925
See add_status_vars(). Before init_status_vars() call, add_status_vars()
926
works in a special fast "startup" mode. Thus init_status_vars()
927
should be called as late as possible but before enabling multi-threading.
929
void init_status_vars()
931
status_vars_inited= 1;
932
sort(all_status_vars.begin(), all_status_vars.end(),
933
show_var_cmp_functor());
936
void reset_status_vars()
938
vector<SHOW_VAR *>::iterator p= all_status_vars.begin();
939
while (p != all_status_vars.end())
941
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
942
if ((*p)->type == SHOW_LONG)
949
catch-all cleanup function, cleans up everything no matter what
952
This function is not strictly required if all add_to_status/
953
remove_status_vars are properly paired, but it's a safety measure that
954
deletes everything from the all_status_vars vector even if some
955
remove_status_vars were forgotten
957
void free_status_vars()
959
all_status_vars.clear();
963
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
966
remove_status_vars(SHOW_VAR *list)
967
list - an array of SHOW_VAR entries to remove to all_status_vars
968
the last entry must be {0,0,SHOW_UNDEF}
971
there's lots of room for optimizing this, especially in non-sorted mode,
972
but nobody cares - it may be called only in case of failed plugin
973
initialization in the mysqld startup.
976
void remove_status_vars(SHOW_VAR *list)
978
if (status_vars_inited)
980
pthread_mutex_lock(&LOCK_status);
981
SHOW_VAR *all= all_status_vars.front();
982
int a= 0, b= all_status_vars.size(), c= (a+b)/2;
984
for (; list->name; list++)
987
for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
989
res= show_var_cmp(list, all+c);
998
all[c].type= SHOW_UNDEF;
1000
/* removes all the SHOW_UNDEF elements from the vector */
1001
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
1002
all_status_vars.end(),show_var_remove_if()),
1003
all_status_vars.end());
1004
pthread_mutex_unlock(&LOCK_status);
1008
SHOW_VAR *all= all_status_vars.front();
1010
for (; list->name; list++)
1012
for (i= 0; i < all_status_vars.size(); i++)
1014
if (show_var_cmp(list, all+i))
1016
all[i].type= SHOW_UNDEF;
1020
/* removes all the SHOW_UNDEF elements from the vector */
1021
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
1022
all_status_vars.end(),show_var_remove_if()),
1023
all_status_vars.end());
1027
/* collect status for all running threads */
1029
void calc_sum_of_all_status(STATUS_VAR *to)
1031
/* Ensure that thread id not killed during loop */
1032
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1034
/* Get global values as base */
1035
*to= global_status_var;
1037
/* Add to this status from existing threads */
1038
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1040
add_to_status(to, &((*it)->status_var));
1043
pthread_mutex_unlock(&LOCK_thread_count);
1048
Store record to I_S table, convert HEAP table
1049
to MyISAM if necessary
1052
schema_table_store_record()
1053
session thread handler
1054
table Information schema table to be updated
1061
bool schema_table_store_record(Session *session, Table *table)
1064
if ((error= table->file->ha_write_row(table->record[0])))
1066
Tmp_Table_Param *param= table->pos_in_table_list->schema_table_param;
1068
if (create_myisam_from_heap(session, table, param->start_recinfo,
1069
¶m->recinfo, error, 0))
1076
static int make_table_list(Session *session, Select_Lex *sel,
1077
LEX_STRING *db_name, LEX_STRING *table_name)
1079
Table_ident *table_ident;
1080
table_ident= new Table_ident(*db_name, *table_name);
1082
if (! sel->add_table_to_list(session, table_ident, 0, 0, TL_READ))
1089
@brief Get lookup value from the part of 'WHERE' condition
1091
@details This function gets lookup value from
1092
the part of 'WHERE' condition if it's possible and
1093
fill appropriate lookup_field_vals struct field
1096
@param[in] session thread handler
1097
@param[in] item_func part of WHERE condition
1098
@param[in] table I_S table
1099
@param[in, out] lookup_field_vals Struct which holds lookup values
1103
1 error, there can be no matching records for the condition
1106
static bool get_lookup_value(Session *session, Item_func *item_func,
1108
LOOKUP_FIELD_VALUES *lookup_field_vals)
1110
InfoSchemaTable *schema_table= table->schema_table;
1111
const char *field_name1= schema_table->getFirstColumnIndex() >= 0 ?
1112
schema_table->getColumnName(schema_table->getFirstColumnIndex()).c_str() : "";
1113
const char *field_name2= schema_table->getSecondColumnIndex() >= 0 ?
1114
schema_table->getColumnName(schema_table->getSecondColumnIndex()).c_str() : "";
1116
if (item_func->functype() == Item_func::EQ_FUNC ||
1117
item_func->functype() == Item_func::EQUAL_FUNC)
1119
int idx_field, idx_val;
1120
char tmp[MAX_FIELD_WIDTH];
1121
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1122
Item_field *item_field;
1123
const CHARSET_INFO * const cs= system_charset_info;
1125
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1126
item_func->arguments()[1]->const_item())
1131
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1132
item_func->arguments()[0]->const_item())
1140
item_field= (Item_field*) item_func->arguments()[idx_field];
1141
if (table->table != item_field->field->table)
1143
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1145
/* impossible value */
1149
/* Lookup value is database name */
1150
if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1151
(unsigned char *) item_field->field_name,
1152
strlen(item_field->field_name), 0))
1154
session->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1155
tmp_str->length(), false);
1157
/* Lookup value is table name */
1158
else if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name2,
1159
strlen(field_name2),
1160
(unsigned char *) item_field->field_name,
1161
strlen(item_field->field_name), 0))
1163
session->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1164
tmp_str->length(), false);
1172
@brief Calculates lookup values from 'WHERE' condition
1174
@details This function calculates lookup value(database name, table name)
1175
from 'WHERE' condition if it's possible and
1176
fill lookup_field_vals struct fields with these values.
1178
@param[in] session thread handler
1179
@param[in] cond WHERE condition
1180
@param[in] table I_S table
1181
@param[in, out] lookup_field_vals Struct which holds lookup values
1185
1 error, there can be no matching records for the condition
1188
bool calc_lookup_values_from_cond(Session *session, COND *cond, TableList *table,
1189
LOOKUP_FIELD_VALUES *lookup_field_vals)
1194
if (cond->type() == Item::COND_ITEM)
1196
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1198
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1200
while ((item= li++))
1202
if (item->type() == Item::FUNC_ITEM)
1204
if (get_lookup_value(session, (Item_func*)item, table, lookup_field_vals))
1209
if (calc_lookup_values_from_cond(session, item, table, lookup_field_vals))
1216
else if (cond->type() == Item::FUNC_ITEM &&
1217
get_lookup_value(session, (Item_func*) cond, table, lookup_field_vals))
1223
static bool uses_only_table_name_fields(Item *item, TableList *table)
1225
if (item->type() == Item::FUNC_ITEM)
1227
Item_func *item_func= (Item_func*)item;
1228
for (uint32_t i=0; i<item_func->argument_count(); i++)
1230
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1234
else if (item->type() == Item::FIELD_ITEM)
1236
Item_field *item_field= (Item_field*)item;
1237
const CHARSET_INFO * const cs= system_charset_info;
1238
InfoSchemaTable *schema_table= table->schema_table;
1239
const char *field_name1= schema_table->getFirstColumnIndex() >= 0 ?
1240
schema_table->getColumnName(schema_table->getFirstColumnIndex()).c_str() : "";
1241
const char *field_name2= schema_table->getSecondColumnIndex() >= 0 ?
1242
schema_table->getColumnName(schema_table->getSecondColumnIndex()).c_str() : "";
1243
if (table->table != item_field->field->table ||
1244
(cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1245
(unsigned char *) item_field->field_name,
1246
strlen(item_field->field_name), 0) &&
1247
cs->coll->strnncollsp(cs, (unsigned char *) field_name2, strlen(field_name2),
1248
(unsigned char *) item_field->field_name,
1249
strlen(item_field->field_name), 0)))
1252
else if (item->type() == Item::REF_ITEM)
1253
return uses_only_table_name_fields(item->real_item(), table);
1255
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1262
static COND * make_cond_for_info_schema(COND *cond, TableList *table)
1266
if (cond->type() == Item::COND_ITEM)
1268
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1270
/* Create new top level AND item */
1271
Item_cond_and *new_cond=new Item_cond_and;
1274
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1278
Item *fix= make_cond_for_info_schema(item, table);
1280
new_cond->argument_list()->push_back(fix);
1282
switch (new_cond->argument_list()->elements) {
1286
return new_cond->argument_list()->head();
1288
new_cond->quick_fix_field();
1294
Item_cond_or *new_cond=new Item_cond_or;
1297
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1301
Item *fix=make_cond_for_info_schema(item, table);
1304
new_cond->argument_list()->push_back(fix);
1306
new_cond->quick_fix_field();
1307
new_cond->top_level_item();
1312
if (!uses_only_table_name_fields(cond, table))
1319
@brief Calculate lookup values(database name, table name)
1321
@details This function calculates lookup values(database name, table name)
1322
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1323
from LEX struct and fill lookup_field_vals struct field
1326
@param[in] session thread handler
1327
@param[in] cond WHERE condition
1328
@param[in] tables I_S table
1329
@param[in, out] lookup_field_values Struct which holds lookup values
1333
1 error, there can be no matching records for the condition
1336
bool get_lookup_field_values(Session *session, COND *cond, TableList *tables,
1337
LOOKUP_FIELD_VALUES *lookup_field_values)
1339
LEX *lex= session->lex;
1340
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1341
memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1342
switch (lex->sql_command) {
1343
case SQLCOM_SHOW_DATABASES:
1346
lookup_field_values->db_value.str= (char*) wild;
1347
lookup_field_values->db_value.length= strlen(wild);
1348
lookup_field_values->wild_db_value= 1;
1351
case SQLCOM_SHOW_TABLES:
1352
case SQLCOM_SHOW_TABLE_STATUS:
1353
lookup_field_values->db_value.str= lex->select_lex.db;
1354
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1357
lookup_field_values->table_value.str= (char*)wild;
1358
lookup_field_values->table_value.length= strlen(wild);
1359
lookup_field_values->wild_table_value= 1;
1364
The "default" is for queries over I_S.
1365
All previous cases handle SHOW commands.
1367
return calc_lookup_values_from_cond(session, cond, tables, lookup_field_values);
1373
* Function used for sorting with std::sort within make_db_list.
1375
* @returns true if a < b, false otherwise
1378
static bool lex_string_sort(const LEX_STRING *a, const LEX_STRING *b)
1380
return (strcmp(a->str, b->str) < 0);
1386
* Create db names list. Information schema name always is first in list
1388
* @param[in] session Thread handler
1389
* @param[out] files List of db names
1390
* @param[in] wild Wild string
1391
* @param[in] idx_field_vals idx_field_vals->db_name contains db name or
1393
* @param[out] with_i_schema Returns 1 if we added 'IS' name to list
1394
* otherwise returns 0
1399
int make_db_list(Session *session, vector<LEX_STRING*> &files,
1400
LOOKUP_FIELD_VALUES *lookup_field_vals,
1401
bool *with_i_schema)
1403
LEX_STRING *i_s_name_copy= 0;
1404
i_s_name_copy= session->make_lex_string(i_s_name_copy,
1405
INFORMATION_SCHEMA_NAME.c_str(),
1406
INFORMATION_SCHEMA_NAME.length(), true);
1408
if (lookup_field_vals->wild_db_value)
1411
This part of code is only for SHOW DATABASES command.
1412
idx_field_vals->db_value can be 0 when we don't use
1413
LIKE clause (see also get_index_field_values() function)
1415
if (!lookup_field_vals->db_value.str ||
1416
!wild_case_compare(system_charset_info,
1417
INFORMATION_SCHEMA_NAME.c_str(),
1418
lookup_field_vals->db_value.str))
1421
files.push_back(i_s_name_copy);
1424
if (find_schemas(session, files, drizzle_data_home,
1425
lookup_field_vals->db_value.str) == true)
1430
sort(files.begin()+1, files.end(), lex_string_sort);
1436
If we have db lookup vaule we just add it to list and
1437
exit from the function
1439
if (lookup_field_vals->db_value.str)
1441
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.c_str(),
1442
lookup_field_vals->db_value.str))
1445
files.push_back(i_s_name_copy);
1449
files.push_back(&lookup_field_vals->db_value);
1454
Create list of existing databases. It is used in case
1455
of select from information schema table
1457
files.push_back(i_s_name_copy);
1461
if (find_schemas(session, files, drizzle_data_home, NULL) == true)
1466
sort(files.begin()+1, files.end(), lex_string_sort);
1471
class AddSchemaTable : public unary_function<InfoSchemaTable *, bool>
1475
vector<LEX_STRING*> &files;
1478
AddSchemaTable(Session *session_arg, vector<LEX_STRING*> &files_arg, const char *wild_arg)
1479
: session(session_arg), wild(wild_arg), files(files_arg)
1482
result_type operator() (argument_type schema_table)
1484
if (schema_table->isHidden())
1489
const string &schema_table_name= schema_table->getTableName();
1491
if (wild && wild_case_compare(files_charset_info, schema_table_name.c_str(), wild))
1496
LEX_STRING *file_name= 0;
1497
file_name= session->make_lex_string(file_name, schema_table_name.c_str(),
1498
schema_table_name.length(), true);
1499
if (file_name == NULL)
1504
files.push_back(file_name);
1510
static int schema_tables_add(Session *session, vector<LEX_STRING*> &files, const char *wild)
1512
vector<InfoSchemaTable *>::iterator iter= find_if(all_schema_tables.begin(),
1513
all_schema_tables.end(),
1514
AddSchemaTable(session, files, wild));
1516
if (iter != all_schema_tables.end())
1526
@brief Create table names list
1528
@details The function creates the list of table names in
1531
@param[in] session thread handler
1532
@param[in] table_names List of table names in database
1533
@param[in] lex pointer to LEX struct
1534
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
1535
@param[in] with_i_schema true means that we add I_S tables to list
1536
@param[in] db_name database name
1538
@return Operation status
1540
@retval 1 fatal error
1541
@retval 2 Not fatal error; Safe to ignore this file list
1545
make_table_name_list(Session *session, vector<LEX_STRING*> &table_names, LEX *lex,
1546
LOOKUP_FIELD_VALUES *lookup_field_vals,
1547
bool with_i_schema, LEX_STRING *db_name)
1549
char path[FN_REFLEN];
1550
build_table_filename(path, sizeof(path), db_name->str, "", false);
1551
if (!lookup_field_vals->wild_table_value &&
1552
lookup_field_vals->table_value.str)
1556
if (find_schema_table(lookup_field_vals->table_value.str))
1558
table_names.push_back(&lookup_field_vals->table_value);
1563
table_names.push_back(&lookup_field_vals->table_value);
1569
This call will add all matching the wildcards (if specified) IS tables
1573
return (schema_tables_add(session, table_names,
1574
lookup_field_vals->table_value.str));
1576
string db(db_name->str);
1578
TableNameIterator tniter(db);
1583
err= tniter.next(&table_name);
1587
LEX_STRING *file_name= NULL;
1588
file_name= session->make_lex_string(file_name, table_name.c_str(),
1589
table_name.length(), true);
1590
const char* wild= lookup_field_vals->table_value.str;
1591
if (wild && wild_compare(table_name.c_str(), wild, 0))
1593
table_names.push_back(file_name);
1600
/* who knows what this error condition really does...
1601
anyway, we're keeping behaviour from days of yore */
1602
if (lex->sql_command != SQLCOM_SELECT)
1604
session->clear_error();
1613
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
1615
@param[in] session thread handler
1616
@param[in] tables TableList for I_S table
1617
@param[in] schema_table pointer to I_S structure
1618
@param[in] open_tables_state_backup pointer to Open_tables_state object
1619
which is used to save|restore original
1620
status of variables related to
1623
@return Operation status
1629
fill_schema_show_cols_or_idxs(Session *session, TableList *tables,
1630
InfoSchemaTable *schema_table,
1631
Open_tables_state *open_tables_state_backup)
1633
LEX *lex= session->lex;
1635
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
1636
enum_sql_command save_sql_command= lex->sql_command;
1637
TableList *show_table_list= (TableList*) tables->schema_select_lex->
1639
Table *table= tables->table;
1642
lex->all_selects_list= tables->schema_select_lex;
1644
Restore session->temporary_tables to be able to process
1645
temporary tables(only for 'show index' & 'show columns').
1646
This should be changed when processing of temporary tables for
1647
I_S tables will be done.
1649
session->temporary_tables= open_tables_state_backup->temporary_tables;
1651
Let us set fake sql_command so views won't try to merge
1652
themselves into main statement. If we don't do this,
1653
SELECT * from information_schema.xxxx will cause problems.
1654
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
1656
lex->sql_command= SQLCOM_SHOW_FIELDS;
1657
res= session->openTables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
1658
lex->sql_command= save_sql_command;
1660
get_all_tables() returns 1 on failure and 0 on success thus
1661
return only these and not the result code of ::process_table()
1663
We should use show_table_list->alias instead of
1664
show_table_list->table_name because table_name
1665
could be changed during opening of I_S tables. It's safe
1666
to use alias because alias contains original table name
1667
in this case(this part of code is used only for
1668
'show columns' & 'show statistics' commands).
1670
table_name= session->make_lex_string(&tmp_lex_string1, show_table_list->alias,
1671
strlen(show_table_list->alias), false);
1672
db_name= session->make_lex_string(&tmp_lex_string, show_table_list->db,
1673
show_table_list->db_length, false);
1676
table->setWriteSet();
1677
error= test(schema_table->processTable(session, show_table_list,
1678
table, res, db_name,
1680
session->temporary_tables= 0;
1681
session->close_tables_for_reopen(&show_table_list);
1688
@brief Fill I_S table for SHOW Table NAMES commands
1690
@param[in] session thread handler
1691
@param[in] table Table struct for I_S table
1692
@param[in] db_name database name
1693
@param[in] table_name table name
1694
@param[in] with_i_schema I_S table if true
1696
@return Operation status
1701
static int fill_schema_table_names(Session *session, Table *table,
1702
LEX_STRING *db_name, LEX_STRING *table_name,
1707
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
1708
system_charset_info);
1712
char path[FN_REFLEN];
1713
(void) build_table_filename(path, sizeof(path), db_name->str,
1714
table_name->str, false);
1716
table->field[3]->store(STRING_WITH_LEN("BASE Table"),
1717
system_charset_info);
1719
if (session->is_error() && session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
1721
session->clear_error();
1725
if (schema_table_store_record(session, table))
1732
@brief Get open table method
1734
@details The function calculates the method which will be used
1736
SKIP_OPEN_TABLE - do not open table
1737
OPEN_FRM_ONLY - open FRM file only
1738
OPEN_FULL_TABLE - open FRM, data, index files
1739
@param[in] tables I_S table table_list
1740
@param[in] schema_table I_S table struct
1742
@return return a set of flags
1743
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
1746
static uint32_t get_table_open_method(TableList *tables,
1747
InfoSchemaTable *schema_table)
1750
determine which method will be used for table opening
1752
if (schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
1754
Field **ptr, *field;
1755
int table_open_method= 0, field_indx= 0;
1756
for (ptr= tables->table->field; (field= *ptr) ; ptr++)
1758
if (field->isReadSet())
1759
table_open_method|= schema_table->getColumnOpenMethod(field_indx);
1762
return table_open_method;
1764
/* I_S tables which use get_all_tables but can not be optimized */
1765
return (uint32_t) OPEN_FULL_TABLE;
1770
@brief Fill I_S table with data from FRM file only
1772
@param[in] session thread handler
1773
@param[in] table Table struct for I_S table
1774
@param[in] schema_table I_S table struct
1775
@param[in] db_name database name
1776
@param[in] table_name table name
1778
@return Operation status
1779
@retval 0 Table is processed and we can continue
1781
@retval 1 It's view and we have to use
1782
open_tables function for this table
1785
static int fill_schema_table_from_frm(Session *session,TableList *tables,
1786
InfoSchemaTable *schema_table,
1787
LEX_STRING *db_name,
1788
LEX_STRING *table_name)
1790
Table *table= tables->table;
1793
TableList table_list;
1796
char key[MAX_DBKEY_LENGTH];
1797
uint32_t key_length;
1799
memset(&tbl, 0, sizeof(Table));
1801
table_list.table_name= table_name->str;
1802
table_list.db= db_name->str;
1804
key_length= table_list.create_table_def_key(key);
1805
pthread_mutex_lock(&LOCK_open); /* Locking to get table share when filling schema table from FRM */
1806
share= TableShare::getShare(session, &table_list, key, key_length, 0, &error);
1815
table_list.table= &tbl;
1816
res= schema_table->processTable(session, &table_list, table,
1817
res, db_name, table_name);
1819
/* For the moment we just set everything to read */
1820
table->setReadSet();
1822
TableShare::release(share);
1825
pthread_mutex_unlock(&LOCK_open);
1826
session->clear_error();
1833
@brief Fill I_S tables whose data are retrieved
1834
from frm files and storage engine
1836
@details The information schema tables are internally represented as
1837
temporary tables that are filled at query execution time.
1838
Those I_S tables whose data are retrieved
1839
from frm files and storage engine are filled by the function
1840
InfoSchemaMethods::fillTable().
1842
@param[in] session thread handler
1843
@param[in] tables I_S table
1844
@param[in] cond 'WHERE' condition
1846
@return Operation status
1850
int InfoSchemaMethods::fillTable(Session *session, TableList *tables, COND *cond)
1852
LEX *lex= session->lex;
1853
Table *table= tables->table;
1854
Select_Lex *old_all_select_lex= lex->all_selects_list;
1855
enum_sql_command save_sql_command= lex->sql_command;
1856
Select_Lex *lsel= tables->schema_select_lex;
1857
InfoSchemaTable *schema_table= tables->schema_table;
1859
LOOKUP_FIELD_VALUES lookup_field_vals;
1861
vector<LEX_STRING*> db_names, table_names;
1862
COND *partial_cond= 0;
1863
uint32_t derived_tables= lex->derived_tables;
1865
Open_tables_state open_tables_state_backup;
1866
Query_tables_list query_tables_list_backup;
1867
uint32_t table_open_method;
1868
bool old_value= session->no_warnings_for_error;
1871
We should not introduce deadlocks even if we already have some
1872
tables open and locked, since we won't lock tables which we will
1873
open and will ignore possible name-locks for these tables.
1875
session->reset_n_backup_open_tables_state(&open_tables_state_backup);
1877
tables->table_open_method= table_open_method=
1878
get_table_open_method(tables, schema_table);
1880
this branch processes SHOW FIELDS, SHOW INDEXES commands.
1881
see sql_parse.cc, prepare_schema_table() function where
1882
this values are initialized
1884
if (lsel && lsel->table_list.first)
1886
error= fill_schema_show_cols_or_idxs(session, tables, schema_table,
1887
&open_tables_state_backup);
1891
if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
1897
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
1900
if lookup value is empty string then
1901
it's impossible table name or db name
1903
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
1904
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
1911
if (lookup_field_vals.db_value.length &&
1912
!lookup_field_vals.wild_db_value)
1913
tables->has_db_lookup_value= true;
1915
if (lookup_field_vals.table_value.length &&
1916
!lookup_field_vals.wild_table_value)
1917
tables->has_table_lookup_value= true;
1919
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
1922
partial_cond= make_cond_for_info_schema(cond, tables);
1926
/* EXPLAIN SELECT */
1931
table->setWriteSet();
1932
if (make_db_list(session, db_names, &lookup_field_vals, &with_i_schema))
1935
for (vector<LEX_STRING*>::iterator db_name= db_names.begin(); db_name != db_names.end(); ++db_name )
1937
session->no_warnings_for_error= 1;
1938
table_names.clear();
1939
int res= make_table_name_list(session, table_names, lex,
1941
with_i_schema, *db_name);
1943
if (res == 2) /* Not fatal error, continue */
1950
for (vector<LEX_STRING*>::iterator table_name= table_names.begin(); table_name != table_names.end(); ++table_name)
1952
table->restoreRecordAsDefault();
1953
table->field[schema_table->getFirstColumnIndex()]->
1954
store((*db_name)->str, (*db_name)->length, system_charset_info);
1955
table->field[schema_table->getSecondColumnIndex()]->
1956
store((*table_name)->str, (*table_name)->length, system_charset_info);
1958
if (!partial_cond || partial_cond->val_int())
1961
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
1962
we can skip table opening and we don't have lookup value for
1963
table name or lookup value is wild string(table name list is
1964
already created by make_table_name_list() function).
1966
if (! table_open_method &&
1967
schema_table->getTableName().compare("TABLES") == 0 &&
1968
(! lookup_field_vals.table_value.length ||
1969
lookup_field_vals.wild_table_value))
1971
if (schema_table_store_record(session, table))
1972
goto err; /* Out of space in temporary table */
1976
/* SHOW Table NAMES command */
1977
if (schema_table->getTableName().compare("TABLE_NAMES") == 0)
1979
if (fill_schema_table_names(session, tables->table, *db_name,
1980
*table_name, with_i_schema))
1985
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
1988
if (!fill_schema_table_from_frm(session, tables, schema_table, *db_name,
1993
LEX_STRING tmp_lex_string, orig_db_name;
1995
Set the parent lex of 'sel' because it is needed by
1996
sel.init_query() which is called inside make_table_list.
1998
session->no_warnings_for_error= 1;
1999
sel.parent_lex= lex;
2000
/* db_name can be changed in make_table_list() func */
2001
if (!session->make_lex_string(&orig_db_name, (*db_name)->str,
2002
(*db_name)->length, false))
2005
if (make_table_list(session, &sel, *db_name, *table_name))
2008
TableList *show_table_list= (TableList*) sel.table_list.first;
2009
lex->all_selects_list= &sel;
2010
lex->derived_tables= 0;
2011
lex->sql_command= SQLCOM_SHOW_FIELDS;
2012
show_table_list->i_s_requested_object=
2013
schema_table->getRequestedObject();
2014
res= session->openTables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
2015
lex->sql_command= save_sql_command;
2017
XXX-> show_table_list has a flag i_is_requested,
2018
and when it's set, openTables()
2019
can return an error without setting an error message
2020
in Session, which is a hack. This is why we have to
2021
check for res, then for session->is_error() only then
2022
for session->main_da.sql_errno().
2024
if (res && session->is_error() &&
2025
session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2028
Hide error for not existing table.
2029
This error can occur for example when we use
2030
where condition with db name and table name and this
2031
table does not exist.
2034
session->clear_error();
2039
We should use show_table_list->alias instead of
2040
show_table_list->table_name because table_name
2041
could be changed during opening of I_S tables. It's safe
2042
to use alias because alias contains original table name
2045
session->make_lex_string(&tmp_lex_string, show_table_list->alias,
2046
strlen(show_table_list->alias), false);
2047
res= schema_table->processTable(session, show_table_list, table,
2050
session->close_tables_for_reopen(&show_table_list);
2052
assert(!lex->query_tables_own_last);
2059
If we have information schema its always the first table and only
2060
the first table. Reset for other tables.
2068
session->restore_backup_open_tables_state(&open_tables_state_backup);
2069
lex->derived_tables= derived_tables;
2070
lex->all_selects_list= old_all_select_lex;
2071
lex->sql_command= save_sql_command;
2072
session->no_warnings_for_error= old_value;
2078
@brief Store field characteristics into appropriate I_S table columns
2080
@param[in] table I_S table
2081
@param[in] field processed field
2082
@param[in] cs I_S table charset
2083
@param[in] offset offset from beginning of table
2084
to DATE_TYPE column in I_S table
2089
static void store_column_type(Table *table, Field *field,
2090
const CHARSET_INFO * const cs,
2094
int decimals, field_length;
2095
const char *tmp_buff;
2096
char column_type_buff[MAX_FIELD_WIDTH];
2097
String column_type(column_type_buff, sizeof(column_type_buff), cs);
2099
field->sql_type(column_type);
2100
/* DTD_IDENTIFIER column */
2101
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
2102
table->field[offset + 7]->set_notnull();
2103
tmp_buff= strchr(column_type.ptr(), '(');
2104
/* DATA_TYPE column */
2105
table->field[offset]->store(column_type.ptr(),
2106
(tmp_buff ? tmp_buff - column_type.ptr() :
2107
column_type.length()), cs);
2108
is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
2109
if (field->has_charset() || is_blob ||
2110
field->real_type() == DRIZZLE_TYPE_VARCHAR) // For varbinary type
2112
uint32_t octet_max_length= field->max_display_length();
2113
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
2114
octet_max_length /= field->charset()->mbmaxlen;
2115
int64_t char_max_len= is_blob ?
2116
(int64_t) octet_max_length / field->charset()->mbminlen :
2117
(int64_t) octet_max_length / field->charset()->mbmaxlen;
2118
/* CHARACTER_MAXIMUM_LENGTH column*/
2119
table->field[offset + 1]->store(char_max_len, true);
2120
table->field[offset + 1]->set_notnull();
2121
/* CHARACTER_OCTET_LENGTH column */
2122
table->field[offset + 2]->store((int64_t) octet_max_length, true);
2123
table->field[offset + 2]->set_notnull();
2127
Calculate field_length and decimals.
2128
They are set to -1 if they should not be set (we should return NULL)
2131
decimals= field->decimals();
2132
switch (field->type()) {
2133
case DRIZZLE_TYPE_NEWDECIMAL:
2134
field_length= ((Field_new_decimal*) field)->precision;
2136
case DRIZZLE_TYPE_LONG:
2137
case DRIZZLE_TYPE_LONGLONG:
2138
field_length= field->max_display_length() - 1;
2140
case DRIZZLE_TYPE_DOUBLE:
2141
field_length= field->field_length;
2142
if (decimals == NOT_FIXED_DEC)
2143
decimals= -1; // return NULL
2146
field_length= decimals= -1;
2150
/* NUMERIC_PRECISION column */
2151
if (field_length >= 0)
2153
table->field[offset + 3]->store((int64_t) field_length, true);
2154
table->field[offset + 3]->set_notnull();
2156
/* NUMERIC_SCALE column */
2159
table->field[offset + 4]->store((int64_t) decimals, true);
2160
table->field[offset + 4]->set_notnull();
2162
if (field->has_charset())
2164
/* CHARACTER_SET_NAME column*/
2165
tmp_buff= field->charset()->csname;
2166
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
2167
table->field[offset + 5]->set_notnull();
2168
/* COLLATION_NAME column */
2169
tmp_buff= field->charset()->name;
2170
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
2171
table->field[offset + 6]->set_notnull();
2176
int InfoSchemaMethods::processTable(Session *session, TableList *tables,
2177
Table *table, bool res,
2178
LEX_STRING *db_name,
2179
LEX_STRING *table_name) const
2181
LEX *lex= session->lex;
2182
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
2183
const CHARSET_INFO * const cs= system_charset_info;
2185
TableShare *show_table_share;
2186
Field **ptr, *field, *timestamp_field;
2191
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
2194
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
2195
rather than in SHOW COLUMNS
2197
if (session->is_error())
2198
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2199
session->main_da.sql_errno(), session->main_da.message());
2200
session->clear_error();
2206
show_table= tables->table;
2207
show_table_share= show_table->s;
2210
if (tables->schema_table)
2212
ptr= show_table->field;
2213
timestamp_field= show_table->timestamp_field;
2217
ptr= show_table_share->field;
2218
timestamp_field= show_table_share->timestamp_field;
2221
/* For the moment we just set everything to read */
2222
if (!show_table->read_set)
2224
show_table->def_read_set.setAll();
2225
show_table->read_set= &show_table->def_read_set;
2227
show_table->use_all_columns(); // Required for default
2229
for (; (field= *ptr) ; ptr++)
2232
char tmp[MAX_FIELD_WIDTH];
2233
String type(tmp,sizeof(tmp), system_charset_info);
2236
/* to satisfy 'field->val_str' ASSERTs */
2237
field->table= show_table;
2238
show_table->in_use= session;
2240
if (wild && wild[0] &&
2241
wild_case_compare(system_charset_info, field->field_name,wild))
2245
/* Get default row, with all NULL fields set to NULL */
2246
table->restoreRecordAsDefault();
2248
table->field[1]->store(db_name->str, db_name->length, cs);
2249
table->field[2]->store(table_name->str, table_name->length, cs);
2250
table->field[3]->store(field->field_name, strlen(field->field_name),
2252
table->field[4]->store((int64_t) count, true);
2254
if (get_field_default_value(timestamp_field, field, &type, 0))
2256
table->field[5]->store(type.ptr(), type.length(), cs);
2257
table->field[5]->set_notnull();
2259
pos=(unsigned char*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
2260
table->field[6]->store((const char*) pos,
2261
strlen((const char*) pos), cs);
2262
store_column_type(table, field, cs, 7);
2264
pos=(unsigned char*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
2265
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
2266
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
2267
table->field[15]->store((const char*) pos,
2268
strlen((const char*) pos), cs);
2271
if (field->unireg_check == Field::NEXT_NUMBER)
2272
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
2273
if (timestamp_field == field &&
2274
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
2275
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
2277
table->field[18]->store(field->comment.str, field->comment.length, cs);
2279
enum column_format_type column_format= (enum column_format_type)
2280
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
2281
pos=(unsigned char*)"Default";
2282
table->field[19]->store((const char*) pos,
2283
strlen((const char*) pos), cs);
2284
pos=(unsigned char*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
2285
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
2287
table->field[20]->store((const char*) pos,
2288
strlen((const char*) pos), cs);
2290
if (schema_table_store_record(session, table))
2297
class FindSchemaTableByName : public unary_function<InfoSchemaTable *, bool>
2299
const char *table_name;
2301
FindSchemaTableByName(const char *table_name_arg)
2302
: table_name(table_name_arg) {}
2303
result_type operator() (argument_type schema_table)
2305
return ! my_strcasecmp(system_charset_info,
2306
schema_table->getTableName().c_str(),
2313
Find schema_tables elment by name
2317
table_name table name
2321
# pointer to 'schema_tables' element
2324
InfoSchemaTable *find_schema_table(const char* table_name)
2326
vector<InfoSchemaTable *>::iterator iter=
2327
find_if(all_schema_tables.begin(), all_schema_tables.end(),
2328
FindSchemaTableByName(table_name));
2329
if (iter != all_schema_tables.end())
2338
Table *InfoSchemaMethods::createSchemaTable(Session *session, TableList *table_list)
2344
List<Item> field_list;
2345
const CHARSET_INFO * const cs= system_charset_info;
2346
const InfoSchemaTable::Columns &columns= table_list->schema_table->getColumns();
2347
InfoSchemaTable::Columns::const_iterator iter= columns.begin();
2349
while (iter != columns.end())
2351
const ColumnInfo *column= *iter;
2352
switch (column->getType()) {
2353
case DRIZZLE_TYPE_LONG:
2354
case DRIZZLE_TYPE_LONGLONG:
2355
if (!(item= new Item_return_int(column->getName().c_str(),
2356
column->getLength(),
2358
column->getValue())))
2362
item->unsigned_flag= (column->getFlags() & MY_I_S_UNSIGNED);
2364
case DRIZZLE_TYPE_DATE:
2365
case DRIZZLE_TYPE_TIMESTAMP:
2366
case DRIZZLE_TYPE_DATETIME:
2367
if (!(item=new Item_return_date_time(column->getName().c_str(),
2368
column->getType())))
2373
case DRIZZLE_TYPE_DOUBLE:
2374
if ((item= new Item_float(column->getName().c_str(), 0.0, NOT_FIXED_DEC,
2375
column->getLength())) == NULL)
2378
case DRIZZLE_TYPE_NEWDECIMAL:
2379
if (!(item= new Item_decimal((int64_t) column->getValue(), false)))
2383
item->unsigned_flag= (column->getFlags() & MY_I_S_UNSIGNED);
2384
item->decimals= column->getLength() % 10;
2385
item->max_length= (column->getLength()/100)%100;
2386
if (item->unsigned_flag == 0)
2387
item->max_length+= 1;
2388
if (item->decimals > 0)
2389
item->max_length+= 1;
2390
item->set_name(column->getName().c_str(),
2391
column->getName().length(), cs);
2393
case DRIZZLE_TYPE_BLOB:
2394
if (!(item= new Item_blob(column->getName().c_str(),
2395
column->getLength())))
2401
if (!(item= new Item_empty_string("", column->getLength(), cs)))
2405
item->set_name(column->getName().c_str(),
2406
column->getName().length(), cs);
2409
field_list.push_back(item);
2410
item->maybe_null= (column->getFlags() & MY_I_S_MAYBE_NULL);
2414
Tmp_Table_Param *tmp_table_param =
2415
(Tmp_Table_Param*) (session->alloc(sizeof(Tmp_Table_Param)));
2416
tmp_table_param->init();
2417
tmp_table_param->table_charset= cs;
2418
tmp_table_param->field_count= field_count;
2419
tmp_table_param->schema_table= 1;
2420
Select_Lex *select_lex= session->lex->current_select;
2421
if (!(table= create_tmp_table(session, tmp_table_param,
2422
field_list, (order_st*) 0, 0, 0,
2423
(select_lex->options | session->options |
2424
TMP_TABLE_ALL_COLUMNS),
2425
HA_POS_ERROR, table_list->alias)))
2427
my_bitmap_map* bitmaps=
2428
(my_bitmap_map*) session->alloc(bitmap_buffer_size(field_count));
2429
table->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
2430
table->read_set= &table->def_read_set;
2431
table->read_set->clearAll();
2432
table_list->schema_table_param= tmp_table_param;
2438
For old SHOW compatibility. It is used when
2439
old SHOW doesn't have generated column names
2440
Make list of fields for SHOW
2443
InfoSchemaMethods::oldFormat()
2444
session thread handler
2445
schema_table pointer to 'schema_tables' element
2452
int InfoSchemaMethods::oldFormat(Session *session, InfoSchemaTable *schema_table)
2455
Name_resolution_context *context= &session->lex->select_lex.context;
2456
const InfoSchemaTable::Columns columns= schema_table->getColumns();
2457
InfoSchemaTable::Columns::const_iterator iter= columns.begin();
2459
while (iter != columns.end())
2461
const ColumnInfo *column= *iter;
2462
if (column->getOldName().length() != 0)
2464
Item_field *field= new Item_field(context,
2466
column->getName().c_str());
2469
field->set_name(column->getOldName().c_str(),
2470
column->getOldName().length(),
2471
system_charset_info);
2472
if (session->add_item_to_list(field))
2483
Create information_schema table
2486
mysql_schema_table()
2487
session thread handler
2489
table_list pointer to table_list
2495
bool mysql_schema_table(Session *session, LEX *, TableList *table_list)
2498
if (!(table= table_list->schema_table->createSchemaTable(session, table_list)))
2500
table->s->tmp_table= SYSTEM_TMP_TABLE;
2502
This test is necessary to make
2503
case insensitive file systems +
2504
upper case table names(information schema tables) +
2508
if (table_list->schema_table_name)
2509
table->alias_name_used= my_strcasecmp(table_alias_charset,
2510
table_list->schema_table_name,
2512
table_list->table_name= table->s->table_name.str;
2513
table_list->table_name_length= table->s->table_name.length;
2514
table_list->table= table;
2515
table->next= session->derived_tables;
2516
session->derived_tables= table;
2517
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
2524
Generate select from information_schema table
2527
make_schema_select()
2528
session thread handler
2529
sel pointer to Select_Lex
2530
schema_table_name name of 'schema_tables' element
2536
bool make_schema_select(Session *session, Select_Lex *sel,
2537
const string& schema_table_name)
2539
InfoSchemaTable *schema_table= find_schema_table(schema_table_name.c_str());
2540
LEX_STRING db, table;
2542
We have to make non const db_name & table_name
2543
because of lower_case_table_names
2545
session->make_lex_string(&db, INFORMATION_SCHEMA_NAME.c_str(),
2546
INFORMATION_SCHEMA_NAME.length(), 0);
2547
session->make_lex_string(&table, schema_table->getTableName().c_str(),
2548
schema_table->getTableName().length(), 0);
2549
if (schema_table->oldFormat(session, schema_table) || /* Handle old syntax */
2550
! sel->add_table_to_list(session, new Table_ident(db, table), 0, 0, TL_READ))
2559
Fill temporary schema tables before SELECT
2562
get_schema_tables_result()
2563
join join which use schema tables
2564
executed_place place where I_S table processed
2571
bool get_schema_tables_result(JOIN *join,
2572
enum enum_schema_table_state executed_place)
2574
JoinTable *tmp_join_tab= join->join_tab+join->tables;
2575
Session *session= join->session;
2576
LEX *lex= session->lex;
2579
session->no_warnings_for_error= 1;
2580
for (JoinTable *tab= join->join_tab; tab < tmp_join_tab; tab++)
2582
if (!tab->table || !tab->table->pos_in_table_list)
2585
TableList *table_list= tab->table->pos_in_table_list;
2586
if (table_list->schema_table)
2588
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
2589
lex->current_select->master_unit()->item);
2592
/* skip I_S optimizations specific to get_all_tables */
2593
if (session->lex->describe &&
2594
(table_list->schema_table->isOptimizationPossible() != true))
2600
If schema table is already processed and
2601
the statement is not a subselect then
2602
we don't need to fill this table again.
2603
If schema table is already processed and
2604
schema_table_state != executed_place then
2605
table is already processed and
2606
we should skip second data processing.
2608
if (table_list->schema_table_state &&
2609
(!is_subselect || table_list->schema_table_state != executed_place))
2613
if table is used in a subselect and
2614
table has been processed earlier with the same
2615
'executed_place' value then we should refresh the table.
2617
if (table_list->schema_table_state && is_subselect)
2619
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
2620
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
2621
table_list->table->file->ha_delete_all_rows();
2622
table_list->table->free_io_cache();
2623
table_list->table->filesort_free_buffers(true);
2624
table_list->table->null_row= 0;
2627
table_list->table->file->stats.records= 0;
2629
if (table_list->schema_table->fillTable(session, table_list,
2634
tab->read_record.file= table_list->table->file;
2635
table_list->schema_table_state= executed_place;
2638
tab->read_record.file= table_list->table->file;
2639
table_list->schema_table_state= executed_place;
2642
session->no_warnings_for_error= 0;