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);
363
#define LIST_PROCESS_HOST_LEN 64
365
static bool get_field_default_value(Field *timestamp_field,
366
Field *field, String *def_value,
370
bool has_now_default;
373
We are using CURRENT_TIMESTAMP instead of NOW because it is
376
has_now_default= (timestamp_field == field &&
377
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
379
has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
380
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
381
field->unireg_check != Field::NEXT_NUMBER);
383
def_value->length(0);
387
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
388
else if (!field->is_null())
389
{ // Not null by default
390
char tmp[MAX_FIELD_WIDTH];
391
String type(tmp, sizeof(tmp), field->charset());
392
field->val_str(&type);
396
uint32_t dummy_errors;
397
/* convert to system_charset_info == utf8 */
398
def_val.copy(type.ptr(), type.length(), field->charset(),
399
system_charset_info, &dummy_errors);
401
append_unescaped(def_value, def_val.ptr(), def_val.length());
403
def_value->append(def_val.ptr(), def_val.length());
406
def_value->append(STRING_WITH_LEN("''"));
408
else if (field->maybe_null() && quoted)
409
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
417
Build a CREATE TABLE statement for a table.
421
table_list A list containing one table to write statement
423
packet Pointer to a string where statement will be
427
Currently always return 0, but might return error code in the
434
int store_create_info(TableList *table_list, String *packet, bool is_if_not_exists)
436
List<Item> field_list;
437
char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
440
String type(tmp, sizeof(tmp), system_charset_info);
441
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
443
uint32_t primary_key;
445
Table *table= table_list->table;
446
Cursor *cursor= table->cursor;
447
TableShare *share= table->s;
448
HA_CREATE_INFO create_info;
449
bool show_table_options= false;
450
my_bitmap_map *old_map;
452
table->restoreRecordAsDefault(); // Get empty record
454
if (share->tmp_table)
455
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
457
packet->append(STRING_WITH_LEN("CREATE TABLE "));
458
if (is_if_not_exists)
459
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
460
alias= share->table_name.str;
462
packet->append_identifier(alias, strlen(alias));
463
packet->append(STRING_WITH_LEN(" (\n"));
465
We need this to get default values from the table
466
We have to restore the read_set if we are called from insert in case
467
of row based replication.
469
old_map= table->use_all_columns(table->read_set);
471
for (ptr=table->field ; (field= *ptr); ptr++)
473
uint32_t flags = field->flags;
475
if (ptr != table->field)
476
packet->append(STRING_WITH_LEN(",\n"));
478
packet->append(STRING_WITH_LEN(" "));
479
packet->append_identifier(field->field_name, strlen(field->field_name));
481
// check for surprises from the previous call to Field::sql_type()
482
if (type.ptr() != tmp)
483
type.set(tmp, sizeof(tmp), system_charset_info);
485
type.set_charset(system_charset_info);
487
field->sql_type(type);
488
packet->append(type.ptr(), type.length(), system_charset_info);
490
if (field->has_charset())
492
if (field->charset() != share->table_charset)
494
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
495
packet->append(field->charset()->csname);
499
For string types dump collation name only if
500
collation is not primary for the given charset
502
if (!(field->charset()->state & MY_CS_PRIMARY))
504
packet->append(STRING_WITH_LEN(" COLLATE "));
505
packet->append(field->charset()->name);
509
if (flags & NOT_NULL_FLAG)
510
packet->append(STRING_WITH_LEN(" NOT NULL"));
511
else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
514
TIMESTAMP field require explicit NULL flag, because unlike
515
all other fields they are treated as NOT NULL by default.
517
packet->append(STRING_WITH_LEN(" NULL"));
521
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
522
and about STORAGE (DISK or MEMORY).
524
enum column_format_type column_format= (enum column_format_type)
525
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
528
packet->append(STRING_WITH_LEN(" /*!"));
529
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
530
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
531
packet->append(STRING_WITH_LEN(" FIXED */"));
533
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
536
if (get_field_default_value(table->timestamp_field, field, &def_value, 1))
538
packet->append(STRING_WITH_LEN(" DEFAULT "));
539
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
542
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
543
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
545
if (field->unireg_check == Field::NEXT_NUMBER)
546
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
548
if (field->comment.length)
550
packet->append(STRING_WITH_LEN(" COMMENT "));
551
append_unescaped(packet, field->comment.str, field->comment.length);
555
key_info= table->key_info;
556
memset(&create_info, 0, sizeof(create_info));
557
/* Allow update_create_info to update row type */
558
create_info.row_type= share->row_type;
559
cursor->update_create_info(&create_info);
560
primary_key= share->primary_key;
562
for (uint32_t i=0 ; i < share->keys ; i++,key_info++)
564
KEY_PART_INFO *key_part= key_info->key_part;
565
bool found_primary=0;
566
packet->append(STRING_WITH_LEN(",\n "));
568
if (i == primary_key && is_primary_key(key_info))
572
No space at end, because a space will be added after where the
573
identifier would go, but that is not added for primary key.
575
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
577
else if (key_info->flags & HA_NOSAME)
578
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
580
packet->append(STRING_WITH_LEN("KEY "));
583
packet->append_identifier(key_info->name, strlen(key_info->name));
585
packet->append(STRING_WITH_LEN(" ("));
587
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
593
packet->append_identifier(key_part->field->field_name,
594
strlen(key_part->field->field_name));
595
if (key_part->field &&
597
table->field[key_part->fieldnr-1]->key_length()))
600
buff.append(to_string((int32_t) key_part->length /
601
key_part->field->charset()->mbmaxlen));
603
packet->append(buff.c_str(), buff.length());
607
store_key_options(packet, table, key_info);
611
Get possible foreign key definitions stored in InnoDB and append them
612
to the CREATE TABLE statement
615
if ((for_str= cursor->get_foreign_key_create_info()))
617
packet->append(for_str, strlen(for_str));
618
cursor->free_foreign_key_create_info(for_str);
621
packet->append(STRING_WITH_LEN("\n)"));
623
show_table_options= true;
625
Get possible table space definitions and append them
626
to the CREATE TABLE statement
630
We should always store engine since we will now be
631
making sure engines accept options (aka... no
632
dangling arguments for engines.
634
packet->append(STRING_WITH_LEN(" ENGINE="));
635
packet->append(cursor->engine->getName().c_str());
637
if (share->db_create_options & HA_OPTION_PACK_KEYS)
638
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
639
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
640
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
641
if (create_info.row_type != ROW_TYPE_DEFAULT)
643
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
644
packet->append(ha_row_type[(uint32_t) create_info.row_type]);
646
if (table->s->hasKeyBlockSize())
648
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
649
buff= to_string(table->s->getKeyBlockSize());
650
packet->append(buff.c_str(), buff.length());
652
if (share->block_size)
654
packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
655
buff= to_string(share->block_size);
656
packet->append(buff.c_str(), buff.length());
658
table->cursor->append_create_info(packet);
659
if (share->hasComment() && share->getCommentLength())
661
packet->append(STRING_WITH_LEN(" COMMENT="));
662
append_unescaped(packet, share->getComment(),
663
share->getCommentLength());
666
table->restore_column_map(old_map);
670
static void store_key_options(String *packet, Table *table, KEY *key_info)
674
if (key_info->algorithm == HA_KEY_ALG_BTREE)
675
packet->append(STRING_WITH_LEN(" USING BTREE"));
677
if (key_info->algorithm == HA_KEY_ALG_HASH)
678
packet->append(STRING_WITH_LEN(" USING HASH"));
680
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
681
table->s->getKeyBlockSize() != key_info->block_size)
683
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
684
end= int64_t10_to_str(key_info->block_size, buff, 10);
685
packet->append(buff, (uint32_t) (end - buff));
688
assert(test(key_info->flags & HA_USES_COMMENT) ==
689
(key_info->comment.length > 0));
690
if (key_info->flags & HA_USES_COMMENT)
692
packet->append(STRING_WITH_LEN(" COMMENT "));
693
append_unescaped(packet, key_info->comment.str,
694
key_info->comment.length);
699
/****************************************************************************
700
Return info about all processes
701
returns for each thread: thread id, user, host, db, command, info
702
****************************************************************************/
704
class thread_info :public ilink {
706
static void *operator new(size_t size)
708
return (void*) sql_alloc((uint32_t) size);
710
static void operator delete(void *, size_t)
716
const char *user,*host,*db,*proc_info,*state_info;
720
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
721
template class I_List<thread_info>;
724
void mysqld_list_processes(Session *session,const char *user, bool)
727
List<Item> field_list;
728
I_List<thread_info> thread_infos;
730
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
731
field_list.push_back(new Item_empty_string("User",16));
732
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
733
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
734
field->maybe_null= true;
735
field_list.push_back(new Item_empty_string("Command",16));
736
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
737
field_list.push_back(field=new Item_empty_string("State",30));
738
field->maybe_null= true;
739
field_list.push_back(field=new Item_empty_string("Info", PROCESS_LIST_WIDTH));
740
field->maybe_null= true;
741
if (session->client->sendFields(&field_list))
744
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
745
if (!session->killed)
748
for(vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it)
751
Security_context *tmp_sctx= &tmp->security_ctx;
752
struct st_my_thread_var *mysys_var;
753
if (tmp->client->isConnected() && (!user || (tmp_sctx->user.c_str() && !strcmp(tmp_sctx->user.c_str(), user))))
755
thread_info *session_info= new thread_info;
757
session_info->thread_id=tmp->thread_id;
758
session_info->user= session->strdup(tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user");
759
session_info->host= session->strdup(tmp_sctx->ip.c_str());
760
if ((session_info->db= tmp->db.c_str())) // Safe test
761
session_info->db=session->strdup(session_info->db);
762
session_info->command=(int) tmp->command;
763
if ((mysys_var= tmp->mysys_var))
764
pthread_mutex_lock(&mysys_var->mutex);
766
if (tmp->killed == Session::KILL_CONNECTION)
767
session_info->proc_info= (char*) "Killed";
769
session_info->proc_info= command_name[session_info->command].str;
771
session_info->state_info= (char*) (tmp->client->isWriting() ?
773
tmp->client->isReading() ?
774
(session_info->command == COM_SLEEP ?
775
NULL : "Reading from net") :
776
tmp->get_proc_info() ? tmp->get_proc_info() :
778
tmp->mysys_var->current_cond ?
779
"Waiting on cond" : NULL);
781
pthread_mutex_unlock(&mysys_var->mutex);
783
session_info->start_time= tmp->start_time;
784
session_info->query= NULL;
785
if (tmp->process_list_info[0])
786
session_info->query= session->strdup(tmp->process_list_info);
787
thread_infos.append(session_info);
791
pthread_mutex_unlock(&LOCK_thread_count);
793
thread_info *session_info;
794
time_t now= time(NULL);
795
while ((session_info=thread_infos.get()))
797
session->client->store((uint64_t) session_info->thread_id);
798
session->client->store(session_info->user);
799
session->client->store(session_info->host);
800
session->client->store(session_info->db);
801
session->client->store(session_info->proc_info);
803
if (session_info->start_time)
804
session->client->store((uint32_t) (now - session_info->start_time));
806
session->client->store();
808
session->client->store(session_info->state_info);
809
session->client->store(session_info->query);
811
if (session->client->flush())
818
/*****************************************************************************
820
*****************************************************************************/
822
static vector<SHOW_VAR *> all_status_vars;
823
static bool status_vars_inited= 0;
824
static int show_var_cmp(const void *var1, const void *var2)
826
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
829
class show_var_cmp_functor
832
show_var_cmp_functor() { }
833
inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const
835
int val= strcmp(var1->name, var2->name);
840
class show_var_remove_if
843
show_var_remove_if() { }
844
inline bool operator()(const SHOW_VAR *curr) const
846
return (curr->type == SHOW_UNDEF);
850
SHOW_VAR *getFrontOfStatusVars()
852
return all_status_vars.front();
856
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
859
add_status_vars(SHOW_VAR *list)
860
list - an array of SHOW_VAR entries to add to all_status_vars
861
the last entry must be {0,0,SHOW_UNDEF}
864
The handling of all_status_vars[] is completely internal, it's allocated
865
automatically when something is added to it, and deleted completely when
866
the last entry is removed.
868
As a special optimization, if add_status_vars() is called before
869
init_status_vars(), it assumes "startup mode" - neither concurrent access
870
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
872
int add_status_vars(SHOW_VAR *list)
875
if (status_vars_inited)
876
pthread_mutex_lock(&LOCK_status);
878
all_status_vars.insert(all_status_vars.begin(), list++);
879
if (status_vars_inited)
880
sort(all_status_vars.begin(), all_status_vars.end(),
881
show_var_cmp_functor());
882
if (status_vars_inited)
883
pthread_mutex_unlock(&LOCK_status);
888
Make all_status_vars[] usable for SHOW STATUS
891
See add_status_vars(). Before init_status_vars() call, add_status_vars()
892
works in a special fast "startup" mode. Thus init_status_vars()
893
should be called as late as possible but before enabling multi-threading.
895
void init_status_vars()
897
status_vars_inited= 1;
898
sort(all_status_vars.begin(), all_status_vars.end(),
899
show_var_cmp_functor());
902
void reset_status_vars()
904
vector<SHOW_VAR *>::iterator p= all_status_vars.begin();
905
while (p != all_status_vars.end())
907
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
908
if ((*p)->type == SHOW_LONG)
915
catch-all cleanup function, cleans up everything no matter what
918
This function is not strictly required if all add_to_status/
919
remove_status_vars are properly paired, but it's a safety measure that
920
deletes everything from the all_status_vars vector even if some
921
remove_status_vars were forgotten
923
void free_status_vars()
925
all_status_vars.clear();
929
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
932
remove_status_vars(SHOW_VAR *list)
933
list - an array of SHOW_VAR entries to remove to all_status_vars
934
the last entry must be {0,0,SHOW_UNDEF}
937
there's lots of room for optimizing this, especially in non-sorted mode,
938
but nobody cares - it may be called only in case of failed plugin
939
initialization in the mysqld startup.
942
void remove_status_vars(SHOW_VAR *list)
944
if (status_vars_inited)
946
pthread_mutex_lock(&LOCK_status);
947
SHOW_VAR *all= all_status_vars.front();
948
int a= 0, b= all_status_vars.size(), c= (a+b)/2;
950
for (; list->name; list++)
953
for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
955
res= show_var_cmp(list, all+c);
964
all[c].type= SHOW_UNDEF;
966
/* removes all the SHOW_UNDEF elements from the vector */
967
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
968
all_status_vars.end(),show_var_remove_if()),
969
all_status_vars.end());
970
pthread_mutex_unlock(&LOCK_status);
974
SHOW_VAR *all= all_status_vars.front();
976
for (; list->name; list++)
978
for (i= 0; i < all_status_vars.size(); i++)
980
if (show_var_cmp(list, all+i))
982
all[i].type= SHOW_UNDEF;
986
/* removes all the SHOW_UNDEF elements from the vector */
987
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
988
all_status_vars.end(),show_var_remove_if()),
989
all_status_vars.end());
993
/* collect status for all running threads */
995
void calc_sum_of_all_status(STATUS_VAR *to)
997
/* Ensure that thread id not killed during loop */
998
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1000
/* Get global values as base */
1001
*to= global_status_var;
1003
/* Add to this status from existing threads */
1004
for(vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
1006
add_to_status(to, &((*it)->status_var));
1009
pthread_mutex_unlock(&LOCK_thread_count);
1014
static int make_table_list(Session *session, Select_Lex *sel,
1015
LEX_STRING *db_name, LEX_STRING *table_name)
1017
Table_ident *table_ident;
1018
table_ident= new Table_ident(*db_name, *table_name);
1020
if (! sel->add_table_to_list(session, table_ident, 0, 0, TL_READ))
1027
@brief Get lookup value from the part of 'WHERE' condition
1029
@details This function gets lookup value from
1030
the part of 'WHERE' condition if it's possible and
1031
fill appropriate lookup_field_vals struct field
1034
@param[in] session thread Cursor
1035
@param[in] item_func part of WHERE condition
1036
@param[in] table I_S table
1037
@param[in, out] lookup_field_vals Struct which holds lookup values
1041
1 error, there can be no matching records for the condition
1044
static bool get_lookup_value(Session *session, Item_func *item_func,
1046
LOOKUP_FIELD_VALUES *lookup_field_vals,
1047
plugin::InfoSchemaTable *schema_table)
1049
const char *field_name1= schema_table->getFirstColumnIndex() >= 0 ?
1050
schema_table->getColumnName(schema_table->getFirstColumnIndex()).c_str() : "";
1051
const char *field_name2= schema_table->getSecondColumnIndex() >= 0 ?
1052
schema_table->getColumnName(schema_table->getSecondColumnIndex()).c_str() : "";
1054
if (item_func->functype() == Item_func::EQ_FUNC ||
1055
item_func->functype() == Item_func::EQUAL_FUNC)
1057
int idx_field, idx_val;
1058
char tmp[MAX_FIELD_WIDTH];
1059
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1060
Item_field *item_field;
1061
const CHARSET_INFO * const cs= system_charset_info;
1063
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1064
item_func->arguments()[1]->const_item())
1069
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1070
item_func->arguments()[0]->const_item())
1078
item_field= (Item_field*) item_func->arguments()[idx_field];
1079
if (table->table != item_field->field->table)
1081
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1083
/* impossible value */
1087
/* Lookup value is database name */
1088
if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1089
(unsigned char *) item_field->field_name,
1090
strlen(item_field->field_name), 0))
1092
session->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1093
tmp_str->length(), false);
1095
/* Lookup value is table name */
1096
else if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name2,
1097
strlen(field_name2),
1098
(unsigned char *) item_field->field_name,
1099
strlen(item_field->field_name), 0))
1101
session->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1102
tmp_str->length(), false);
1110
@brief Calculates lookup values from 'WHERE' condition
1112
@details This function calculates lookup value(database name, table name)
1113
from 'WHERE' condition if it's possible and
1114
fill lookup_field_vals struct fields with these values.
1116
@param[in] session thread Cursor
1117
@param[in] cond WHERE condition
1118
@param[in] table I_S table
1119
@param[in, out] lookup_field_vals Struct which holds lookup values
1123
1 error, there can be no matching records for the condition
1126
bool calc_lookup_values_from_cond(Session *session, COND *cond, TableList *table,
1127
LOOKUP_FIELD_VALUES *lookup_field_vals,
1128
plugin::InfoSchemaTable *schema_table)
1133
if (cond->type() == Item::COND_ITEM)
1135
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1137
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1139
while ((item= li++))
1141
if (item->type() == Item::FUNC_ITEM)
1143
if (get_lookup_value(session, (Item_func*)item, table, lookup_field_vals, schema_table))
1148
if (calc_lookup_values_from_cond(session, item, table, lookup_field_vals, schema_table))
1155
else if (cond->type() == Item::FUNC_ITEM &&
1156
get_lookup_value(session, (Item_func*) cond, table, lookup_field_vals, schema_table))
1162
static bool uses_only_table_name_fields(Item *item, Table *table, plugin::InfoSchemaTable *schema_table)
1164
if (item->type() == Item::FUNC_ITEM)
1166
Item_func *item_func= (Item_func*)item;
1167
for (uint32_t i=0; i<item_func->argument_count(); i++)
1169
if (! uses_only_table_name_fields(item_func->arguments()[i], table, schema_table))
1173
else if (item->type() == Item::FIELD_ITEM)
1175
Item_field *item_field= (Item_field*)item;
1176
const CHARSET_INFO * const cs= system_charset_info;
1177
const char *field_name1= schema_table->getFirstColumnIndex() >= 0 ?
1178
schema_table->getColumnName(schema_table->getFirstColumnIndex()).c_str() : "";
1179
const char *field_name2= schema_table->getSecondColumnIndex() >= 0 ?
1180
schema_table->getColumnName(schema_table->getSecondColumnIndex()).c_str() : "";
1181
if (table != item_field->field->table ||
1182
(cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1183
(unsigned char *) item_field->field_name,
1184
strlen(item_field->field_name), 0) &&
1185
cs->coll->strnncollsp(cs, (unsigned char *) field_name2, strlen(field_name2),
1186
(unsigned char *) item_field->field_name,
1187
strlen(item_field->field_name), 0)))
1190
else if (item->type() == Item::REF_ITEM)
1191
return uses_only_table_name_fields(item->real_item(), table, schema_table);
1193
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1200
static COND * make_cond_for_info_schema(COND *cond, Table *table, plugin::InfoSchemaTable *schema_table)
1204
if (cond->type() == Item::COND_ITEM)
1206
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1208
/* Create new top level AND item */
1209
Item_cond_and *new_cond=new Item_cond_and;
1212
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1216
Item *fix= make_cond_for_info_schema(item, table, schema_table);
1218
new_cond->argument_list()->push_back(fix);
1220
switch (new_cond->argument_list()->elements) {
1224
return new_cond->argument_list()->head();
1226
new_cond->quick_fix_field();
1232
Item_cond_or *new_cond=new Item_cond_or;
1235
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1239
Item *fix=make_cond_for_info_schema(item, table, schema_table);
1242
new_cond->argument_list()->push_back(fix);
1244
new_cond->quick_fix_field();
1245
new_cond->top_level_item();
1250
if (! uses_only_table_name_fields(cond, table, schema_table))
1257
@brief Calculate lookup values(database name, table name)
1259
@details This function calculates lookup values(database name, table name)
1260
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1261
from LEX struct and fill lookup_field_vals struct field
1264
@param[in] session thread Cursor
1265
@param[in] cond WHERE condition
1266
@param[in] tables I_S table
1267
@param[in, out] lookup_field_values Struct which holds lookup values
1271
1 error, there can be no matching records for the condition
1274
bool get_lookup_field_values(Session *session, COND *cond, TableList *tables,
1275
LOOKUP_FIELD_VALUES *lookup_field_values,
1276
plugin::InfoSchemaTable *schema_table)
1278
LEX *lex= session->lex;
1279
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1280
memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1281
switch (lex->sql_command) {
1282
case SQLCOM_SHOW_DATABASES:
1285
lookup_field_values->db_value.str= (char*) wild;
1286
lookup_field_values->db_value.length= strlen(wild);
1287
lookup_field_values->wild_db_value= 1;
1290
case SQLCOM_SHOW_TABLES:
1291
case SQLCOM_SHOW_TABLE_STATUS:
1292
lookup_field_values->db_value.str= lex->select_lex.db;
1293
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1296
lookup_field_values->table_value.str= (char*)wild;
1297
lookup_field_values->table_value.length= strlen(wild);
1298
lookup_field_values->wild_table_value= 1;
1303
The "default" is for queries over I_S.
1304
All previous cases handle SHOW commands.
1306
return calc_lookup_values_from_cond(session, cond, tables, lookup_field_values, schema_table);
1312
* Function used for sorting with std::sort within make_db_list.
1314
* @returns true if a < b, false otherwise
1317
static bool lex_string_sort(const LEX_STRING *a, const LEX_STRING *b)
1319
return (strcmp(a->str, b->str) < 0);
1325
* Create db names list. Information schema name always is first in list
1327
* @param[in] session Thread Cursor
1328
* @param[out] files List of db names
1329
* @param[in] wild Wild string
1330
* @param[in] idx_field_vals idx_field_vals->db_name contains db name or
1332
* @param[out] with_i_schema Returns 1 if we added 'IS' name to list
1333
* otherwise returns 0
1338
int make_db_list(Session *session, vector<LEX_STRING*> &files,
1339
LOOKUP_FIELD_VALUES *lookup_field_vals,
1340
bool *with_i_schema)
1342
LEX_STRING *i_s_name_copy= 0;
1343
i_s_name_copy= session->make_lex_string(i_s_name_copy,
1344
INFORMATION_SCHEMA_NAME.c_str(),
1345
INFORMATION_SCHEMA_NAME.length(), true);
1347
if (lookup_field_vals->wild_db_value)
1350
This part of code is only for SHOW DATABASES command.
1351
idx_field_vals->db_value can be 0 when we don't use
1352
LIKE clause (see also get_index_field_values() function)
1354
if (!lookup_field_vals->db_value.str ||
1355
!wild_case_compare(system_charset_info,
1356
INFORMATION_SCHEMA_NAME.c_str(),
1357
lookup_field_vals->db_value.str))
1360
files.push_back(i_s_name_copy);
1363
if (find_schemas(session, files, drizzle_data_home,
1364
lookup_field_vals->db_value.str) == true)
1369
sort(files.begin()+1, files.end(), lex_string_sort);
1375
If we have db lookup vaule we just add it to list and
1376
exit from the function
1378
if (lookup_field_vals->db_value.str)
1380
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.c_str(),
1381
lookup_field_vals->db_value.str))
1384
files.push_back(i_s_name_copy);
1388
files.push_back(&lookup_field_vals->db_value);
1393
Create list of existing databases. It is used in case
1394
of select from information schema table
1396
files.push_back(i_s_name_copy);
1400
if (find_schemas(session, files, drizzle_data_home, NULL) == true)
1405
sort(files.begin()+1, files.end(), lex_string_sort);
1411
@brief Create table names list
1413
@details The function creates the list of table names in
1416
@param[in] session thread Cursor
1417
@param[in] table_names List of table names in database
1418
@param[in] lex pointer to LEX struct
1419
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
1420
@param[in] with_i_schema true means that we add I_S tables to list
1421
@param[in] db_name database name
1423
@return Operation status
1425
@retval 1 fatal error
1426
@retval 2 Not fatal error; Safe to ignore this cursor list
1430
make_table_name_list(Session *session, vector<LEX_STRING*> &table_names,
1431
LOOKUP_FIELD_VALUES *lookup_field_vals,
1432
bool with_i_schema, LEX_STRING *db_name)
1434
char path[FN_REFLEN];
1435
set<string> set_of_names;
1437
build_table_filename(path, sizeof(path), db_name->str, "", false);
1439
if (!lookup_field_vals->wild_table_value &&
1440
lookup_field_vals->table_value.str)
1444
if (plugin::InfoSchemaTable::getTable(lookup_field_vals->table_value.str))
1446
table_names.push_back(&lookup_field_vals->table_value);
1451
table_names.push_back(&lookup_field_vals->table_value);
1456
string db(db_name->str);
1457
plugin::StorageEngine::getTableNames(db, set_of_names);
1460
New I_S engine will make this go away, so ignore lack of foreach() usage.
1462
Notice how bad this design is... sure we created a set... but then we
1463
are just pushing to another set. --
1464
Also... callback design won't work, so we need to rewrite this to
1465
feed (which means new I_S). For the moment we will not optimize this.
1468
for (set<string>::iterator it= set_of_names.begin(); it != set_of_names.end(); it++)
1470
LEX_STRING *file_name= NULL;
1472
file_name= session->make_lex_string(file_name, (*it).c_str(),
1473
(*it).length(), true);
1474
const char* wild= lookup_field_vals->table_value.str;
1475
if (wild && wild_compare((*it).c_str(), wild, 0))
1478
table_names.push_back(file_name);
1486
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
1488
@param[in] session thread Cursor
1489
@param[in] tables TableList for I_S table
1490
@param[in] schema_table pointer to I_S structure
1491
@param[in] open_tables_state_backup pointer to Open_tables_state object
1492
which is used to save|restore original
1493
status of variables related to
1496
@return Operation status
1502
fill_schema_show_cols_or_idxs(Session *session, TableList *tables,
1503
plugin::InfoSchemaTable *schema_table,
1504
Open_tables_state *open_tables_state_backup)
1506
LEX *lex= session->lex;
1508
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
1509
enum_sql_command save_sql_command= lex->sql_command;
1510
TableList *show_table_list= (TableList*) tables->schema_select_lex->
1512
Table *table= tables->table;
1515
lex->all_selects_list= tables->schema_select_lex;
1517
Restore session->temporary_tables to be able to process
1518
temporary tables(only for 'show index' & 'show columns').
1519
This should be changed when processing of temporary tables for
1520
I_S tables will be done.
1522
session->temporary_tables= open_tables_state_backup->temporary_tables;
1524
Let us set fake sql_command so views won't try to merge
1525
themselves into main statement. If we don't do this,
1526
SELECT * from information_schema.xxxx will cause problems.
1527
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
1529
lex->sql_command= SQLCOM_SHOW_FIELDS;
1530
res= session->openTables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
1531
lex->sql_command= save_sql_command;
1533
get_all_tables() returns 1 on failure and 0 on success thus
1534
return only these and not the result code of ::process_table()
1536
We should use show_table_list->alias instead of
1537
show_table_list->table_name because table_name
1538
could be changed during opening of I_S tables. It's safe
1539
to use alias because alias contains original table name
1540
in this case(this part of code is used only for
1541
'show columns' & 'show statistics' commands).
1543
table_name= session->make_lex_string(&tmp_lex_string1, show_table_list->alias,
1544
strlen(show_table_list->alias), false);
1545
db_name= session->make_lex_string(&tmp_lex_string, show_table_list->db,
1546
show_table_list->db_length, false);
1549
table->setWriteSet();
1550
error= test(schema_table->processTable(session, show_table_list,
1551
table, res, db_name,
1553
session->temporary_tables= 0;
1554
session->close_tables_for_reopen(&show_table_list);
1561
@brief Fill I_S table for SHOW Table NAMES commands
1563
@param[in] session thread Cursor
1564
@param[in] table Table struct for I_S table
1565
@param[in] db_name database name
1566
@param[in] table_name table name
1567
@param[in] with_i_schema I_S table if true
1569
@return Operation status
1574
static int fill_schema_table_names(Session *session, Table *table,
1575
LEX_STRING *db_name, LEX_STRING *table_name,
1577
plugin::InfoSchemaTable *schema_table)
1581
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
1582
system_charset_info);
1586
char path[FN_REFLEN];
1587
(void) build_table_filename(path, sizeof(path), db_name->str,
1588
table_name->str, false);
1590
table->field[3]->store(STRING_WITH_LEN("BASE Table"),
1591
system_charset_info);
1593
if (session->is_error() && session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
1595
session->clear_error();
1599
schema_table->addRow(table->record[0], table->s->reclength);
1605
@brief Fill I_S tables whose data are retrieved
1606
from frm files and storage engine
1608
@details The information schema tables are internally represented as
1609
temporary tables that are filled at query execution time.
1610
Those I_S tables whose data are retrieved
1611
from frm files and storage engine are filled by the function
1612
plugin::InfoSchemaMethods::fillTable().
1614
@param[in] session thread Cursor
1615
@param[in] tables I_S table
1617
@return Operation status
1621
int plugin::InfoSchemaMethods::fillTable(Session *session,
1623
plugin::InfoSchemaTable *schema_table)
1625
LEX *lex= session->lex;
1626
Select_Lex *old_all_select_lex= lex->all_selects_list;
1627
enum_sql_command save_sql_command= lex->sql_command;
1628
Select_Lex *lsel= table->pos_in_table_list->schema_select_lex;
1630
LOOKUP_FIELD_VALUES lookup_field_vals;
1632
vector<LEX_STRING*> db_names, table_names;
1633
/* the WHERE clause */
1634
COND *cond= table->reginfo.join_tab->select_cond;
1635
COND *partial_cond= 0;
1636
uint32_t derived_tables= lex->derived_tables;
1638
Open_tables_state open_tables_state_backup;
1639
Query_tables_list query_tables_list_backup;
1640
bool old_value= session->no_warnings_for_error;
1643
We should not introduce deadlocks even if we already have some
1644
tables open and locked, since we won't lock tables which we will
1645
open and will ignore possible name-locks for these tables.
1647
session->reset_n_backup_open_tables_state(&open_tables_state_backup);
1650
this branch processes SHOW FIELDS, SHOW INDEXES commands.
1651
see sql_parse.cc, prepare_schema_table() function where
1652
this values are initialized
1654
if (lsel && lsel->table_list.first)
1656
error= fill_schema_show_cols_or_idxs(session, table->pos_in_table_list, schema_table,
1657
&open_tables_state_backup);
1661
if (get_lookup_field_values(session,
1663
table->pos_in_table_list,
1671
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
1674
if lookup value is empty string then
1675
it's impossible table name or db name
1677
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
1678
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
1685
if (lookup_field_vals.db_value.length &&
1686
!lookup_field_vals.wild_db_value)
1687
table->pos_in_table_list->has_db_lookup_value= true;
1689
if (lookup_field_vals.table_value.length &&
1690
!lookup_field_vals.wild_table_value)
1691
table->pos_in_table_list->has_table_lookup_value= true;
1693
if (table->pos_in_table_list->has_db_lookup_value &&
1694
table->pos_in_table_list->has_table_lookup_value)
1697
partial_cond= make_cond_for_info_schema(cond, table, schema_table);
1701
/* EXPLAIN SELECT */
1706
table->setWriteSet();
1707
if (make_db_list(session, db_names, &lookup_field_vals, &with_i_schema))
1710
for (vector<LEX_STRING*>::iterator db_name= db_names.begin(); db_name != db_names.end(); ++db_name )
1712
session->no_warnings_for_error= 1;
1713
table_names.clear();
1714
int res= make_table_name_list(session, table_names,
1716
with_i_schema, *db_name);
1718
if (res == 2) /* Not fatal error, continue */
1725
for (vector<LEX_STRING*>::iterator table_name= table_names.begin(); table_name != table_names.end(); ++table_name)
1727
table->restoreRecordAsDefault();
1728
table->field[schema_table->getFirstColumnIndex()]->
1729
store((*db_name)->str, (*db_name)->length, system_charset_info);
1730
table->field[schema_table->getSecondColumnIndex()]->
1731
store((*table_name)->str, (*table_name)->length, system_charset_info);
1733
if (!partial_cond || partial_cond->val_int())
1735
/* SHOW Table NAMES command */
1736
if (schema_table->getTableName().compare("TABLE_NAMES") == 0)
1738
if (fill_schema_table_names(session,
1748
LEX_STRING tmp_lex_string, orig_db_name;
1750
Set the parent lex of 'sel' because it is needed by
1751
sel.init_query() which is called inside make_table_list.
1753
session->no_warnings_for_error= 1;
1754
sel.parent_lex= lex;
1755
/* db_name can be changed in make_table_list() func */
1756
if (! session->make_lex_string(&orig_db_name,
1764
if (make_table_list(session, &sel, *db_name, *table_name))
1767
TableList *show_table_list= (TableList*) sel.table_list.first;
1768
lex->all_selects_list= &sel;
1769
lex->derived_tables= 0;
1770
lex->sql_command= SQLCOM_SHOW_FIELDS;
1771
show_table_list->i_s_requested_object=
1772
schema_table->getRequestedObject();
1773
res= session->openTables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
1774
lex->sql_command= save_sql_command;
1776
XXX-> show_table_list has a flag i_is_requested,
1777
and when it's set, openTables()
1778
can return an error without setting an error message
1779
in Session, which is a hack. This is why we have to
1780
check for res, then for session->is_error() only then
1781
for session->main_da.sql_errno().
1783
if (res && session->is_error() &&
1784
session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
1787
Hide error for not existing table.
1788
This error can occur for example when we use
1789
where condition with db name and table name and this
1790
table does not exist.
1793
session->clear_error();
1798
We should use show_table_list->alias instead of
1799
show_table_list->table_name because table_name
1800
could be changed during opening of I_S tables. It's safe
1801
to use alias because alias contains original table name
1804
session->make_lex_string(&tmp_lex_string, show_table_list->alias,
1805
strlen(show_table_list->alias), false);
1806
res= schema_table->processTable(session, show_table_list, table,
1809
session->close_tables_for_reopen(&show_table_list);
1811
assert(!lex->query_tables_own_last);
1818
If we have information schema its always the first table and only
1819
the first table. Reset for other tables.
1827
session->restore_backup_open_tables_state(&open_tables_state_backup);
1828
lex->derived_tables= derived_tables;
1829
lex->all_selects_list= old_all_select_lex;
1830
lex->sql_command= save_sql_command;
1831
session->no_warnings_for_error= old_value;
1837
@brief Store field characteristics into appropriate I_S table columns
1839
@param[in] table I_S table
1840
@param[in] field processed field
1841
@param[in] cs I_S table charset
1842
@param[in] offset offset from beginning of table
1843
to DATE_TYPE column in I_S table
1848
static void store_column_type(Table *table, Field *field,
1849
const CHARSET_INFO * const cs,
1853
int decimals, field_length;
1854
const char *tmp_buff;
1855
char column_type_buff[MAX_FIELD_WIDTH];
1856
String column_type(column_type_buff, sizeof(column_type_buff), cs);
1858
field->sql_type(column_type);
1859
/* DTD_IDENTIFIER column */
1860
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
1861
table->field[offset + 7]->set_notnull();
1862
tmp_buff= strchr(column_type.ptr(), '(');
1863
/* DATA_TYPE column */
1864
table->field[offset]->store(column_type.ptr(),
1865
(tmp_buff ? tmp_buff - column_type.ptr() :
1866
column_type.length()), cs);
1867
is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
1868
if (field->has_charset() || is_blob ||
1869
field->real_type() == DRIZZLE_TYPE_VARCHAR) // For varbinary type
1871
uint32_t octet_max_length= field->max_display_length();
1872
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
1873
octet_max_length /= field->charset()->mbmaxlen;
1874
int64_t char_max_len= is_blob ?
1875
(int64_t) octet_max_length / field->charset()->mbminlen :
1876
(int64_t) octet_max_length / field->charset()->mbmaxlen;
1877
/* CHARACTER_MAXIMUM_LENGTH column*/
1878
table->field[offset + 1]->store(char_max_len, true);
1879
table->field[offset + 1]->set_notnull();
1880
/* CHARACTER_OCTET_LENGTH column */
1881
table->field[offset + 2]->store((int64_t) octet_max_length, true);
1882
table->field[offset + 2]->set_notnull();
1886
Calculate field_length and decimals.
1887
They are set to -1 if they should not be set (we should return NULL)
1890
decimals= field->decimals();
1891
switch (field->type()) {
1892
case DRIZZLE_TYPE_DECIMAL:
1893
field_length= ((Field_decimal*) field)->precision;
1895
case DRIZZLE_TYPE_LONG:
1896
case DRIZZLE_TYPE_LONGLONG:
1897
field_length= field->max_display_length() - 1;
1899
case DRIZZLE_TYPE_DOUBLE:
1900
field_length= field->field_length;
1901
if (decimals == NOT_FIXED_DEC)
1902
decimals= -1; // return NULL
1905
field_length= decimals= -1;
1909
/* NUMERIC_PRECISION column */
1910
if (field_length >= 0)
1912
table->field[offset + 3]->store((int64_t) field_length, true);
1913
table->field[offset + 3]->set_notnull();
1915
/* NUMERIC_SCALE column */
1918
table->field[offset + 4]->store((int64_t) decimals, true);
1919
table->field[offset + 4]->set_notnull();
1921
if (field->has_charset())
1923
/* CHARACTER_SET_NAME column*/
1924
tmp_buff= field->charset()->csname;
1925
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
1926
table->field[offset + 5]->set_notnull();
1927
/* COLLATION_NAME column */
1928
tmp_buff= field->charset()->name;
1929
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
1930
table->field[offset + 6]->set_notnull();
1935
int plugin::InfoSchemaMethods::processTable(
1936
plugin::InfoSchemaTable *store_table,
1939
Table *table, bool res,
1940
LEX_STRING *db_name,
1941
LEX_STRING *table_name)
1943
LEX *lex= session->lex;
1944
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1945
const CHARSET_INFO * const cs= system_charset_info;
1947
TableShare *show_table_share;
1948
Field **ptr, *field, *timestamp_field;
1953
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
1956
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
1957
rather than in SHOW COLUMNS
1959
if (session->is_error())
1960
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1961
session->main_da.sql_errno(), session->main_da.message());
1962
session->clear_error();
1968
show_table= tables->table;
1969
show_table_share= show_table->s;
1972
ptr= show_table_share->field;
1973
timestamp_field= show_table_share->timestamp_field;
1975
/* For the moment we just set everything to read */
1976
if (!show_table->read_set)
1978
show_table->def_read_set.setAll();
1979
show_table->read_set= &show_table->def_read_set;
1981
show_table->use_all_columns(); // Required for default
1983
for (; (field= *ptr) ; ptr++)
1986
char tmp[MAX_FIELD_WIDTH];
1987
String type(tmp,sizeof(tmp), system_charset_info);
1990
/* to satisfy 'field->val_str' ASSERTs */
1991
field->table= show_table;
1992
show_table->in_use= session;
1994
if (wild && wild[0] &&
1995
wild_case_compare(system_charset_info, field->field_name,wild))
1999
/* Get default row, with all NULL fields set to NULL */
2000
table->restoreRecordAsDefault();
2002
table->field[1]->store(db_name->str, db_name->length, cs);
2003
table->field[2]->store(table_name->str, table_name->length, cs);
2004
table->field[3]->store(field->field_name, strlen(field->field_name),
2006
table->field[4]->store((int64_t) count, true);
2008
if (get_field_default_value(timestamp_field, field, &type, 0))
2010
table->field[5]->store(type.ptr(), type.length(), cs);
2011
table->field[5]->set_notnull();
2013
pos=(unsigned char*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
2014
table->field[6]->store((const char*) pos,
2015
strlen((const char*) pos), cs);
2016
store_column_type(table, field, cs, 7);
2018
pos=(unsigned char*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
2019
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
2020
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
2021
table->field[15]->store((const char*) pos,
2022
strlen((const char*) pos), cs);
2025
if (field->unireg_check == Field::NEXT_NUMBER)
2026
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
2027
if (timestamp_field == field &&
2028
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
2029
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
2031
table->field[18]->store(field->comment.str, field->comment.length, cs);
2033
enum column_format_type column_format= (enum column_format_type)
2034
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
2035
pos=(unsigned char*)"Default";
2036
table->field[19]->store((const char*) pos,
2037
strlen((const char*) pos), cs);
2038
pos=(unsigned char*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
2039
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
2041
table->field[20]->store((const char*) pos,
2042
strlen((const char*) pos), cs);
2044
store_table->addRow(table->record[0], table->s->reclength);
2051
For old SHOW compatibility. It is used when
2052
old SHOW doesn't have generated column names
2053
Make list of fields for SHOW
2056
plugin::InfoSchemaMethods::oldFormat()
2057
session thread Cursor
2058
schema_table pointer to 'schema_tables' element
2065
int plugin::InfoSchemaMethods::oldFormat(Session *session, plugin::InfoSchemaTable *schema_table)
2068
Name_resolution_context *context= &session->lex->select_lex.context;
2069
const plugin::InfoSchemaTable::Columns columns= schema_table->getColumns();
2070
plugin::InfoSchemaTable::Columns::const_iterator iter= columns.begin();
2072
while (iter != columns.end())
2074
const plugin::ColumnInfo *column= *iter;
2075
if (column->getOldName().length() != 0)
2077
Item_field *field= new Item_field(context,
2079
column->getName().c_str());
2082
field->set_name(column->getOldName().c_str(),
2083
column->getOldName().length(),
2084
system_charset_info);
2085
if (session->add_item_to_list(field))
2096
Generate select from information_schema table
2099
make_schema_select()
2100
session thread Cursor
2101
sel pointer to Select_Lex
2102
schema_table_name name of 'schema_tables' element
2108
bool make_schema_select(Session *session, Select_Lex *sel,
2109
const string& schema_table_name)
2111
plugin::InfoSchemaTable *schema_table= plugin::InfoSchemaTable::getTable(schema_table_name.c_str());
2112
LEX_STRING db, table;
2114
We have to make non const db_name & table_name
2115
because of lower_case_table_names
2117
session->make_lex_string(&db, INFORMATION_SCHEMA_NAME.c_str(),
2118
INFORMATION_SCHEMA_NAME.length(), 0);
2119
session->make_lex_string(&table, schema_table->getTableName().c_str(),
2120
schema_table->getTableName().length(), 0);
2121
if (schema_table->oldFormat(session, schema_table) || /* Handle old syntax */
2122
! sel->add_table_to_list(session, new Table_ident(db, table), 0, 0, TL_READ))
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 */