19 #include "sql_table.h"
21 #include "opt_range.h"
27 const char *table_name, *field_name;
35 {
"help_topic",
"help_topic_id", 0},
36 {
"help_topic",
"name", 0},
37 {
"help_topic",
"help_category_id", 0},
38 {
"help_topic",
"description", 0},
39 {
"help_topic",
"example", 0},
41 {
"help_category",
"help_category_id", 0},
42 {
"help_category",
"parent_category_id", 0},
43 {
"help_category",
"name", 0},
45 {
"help_keyword",
"help_keyword_id", 0},
46 {
"help_keyword",
"name", 0},
48 {
"help_relation",
"help_topic_id", 0},
49 {
"help_relation",
"help_keyword_id", 0}
54 help_topic_help_topic_id= 0,
56 help_topic_help_category_id,
57 help_topic_description,
60 help_category_help_category_id,
61 help_category_parent_category_id,
64 help_keyword_help_keyword_id,
67 help_relation_help_topic_id,
68 help_relation_help_keyword_id
87 static bool init_fields(THD *thd,
TABLE_LIST *tables,
91 DBUG_ENTER(
"init_fields");
92 context->resolve_in_table_list_only(tables);
93 for (; count-- ; find_fields++)
97 "mysql", find_fields->table_name,
98 find_fields->field_name);
99 if (!(find_fields->field= find_field_in_tables(thd, field, tables, NULL,
100 0, REPORT_ALL_ERRORS, 1,
103 bitmap_set_bit(find_fields->field->table->read_set,
104 find_fields->field->field_index);
106 bitmap_set_bit(find_fields->field->table->write_set,
107 find_fields->field->field_index);
138 void memorize_variant_topic(THD *thd,
TABLE *topics,
int count,
143 DBUG_ENTER(
"memorize_variant_topic");
147 get_field(mem_root,find_fields[help_topic_name].field, name);
148 get_field(mem_root,find_fields[help_topic_description].field, description);
149 get_field(mem_root,find_fields[help_topic_example].field, example);
154 names->push_back(name);
156 get_field(mem_root,find_fields[help_topic_name].field,new_name);
157 names->push_back(new_name);
194 DBUG_ENTER(
"search_topics");
196 if (init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE))
199 while (!read_record_info.read_record(&read_record_info))
201 if (!select->cond->val_int())
203 memorize_variant_topic(thd,topics,count,find_fields,
204 names,name,description,example);
207 end_read_record(&read_record_info);
236 DBUG_ENTER(
"search_keyword");
238 if (init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE))
241 while (!read_record_info.read_record(&read_record_info) && count<2)
243 if (!select->cond->val_int())
246 *key_id= (int)find_fields[help_keyword_help_keyword_id].field->val_int();
250 end_read_record(&read_record_info);
281 int get_topics_for_keyword(THD *thd,
TABLE *topics,
TABLE *relations,
288 int iindex_topic, iindex_relations;
289 Field *rtopic_id, *rkey_id;
290 DBUG_ENTER(
"get_topics_for_keyword");
293 find_type(primary_key_name, &topics->s->keynames,
294 FIND_TYPE_NO_PREFIX) - 1) < 0 ||
296 find_type(primary_key_name, &relations->s->keynames,
297 FIND_TYPE_NO_PREFIX) - 1) < 0)
299 my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0));
302 rtopic_id= find_fields[help_relation_help_topic_id].field;
303 rkey_id= find_fields[help_relation_help_keyword_id].field;
308 if (topics->file->inited)
310 my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0));
314 rkey_id->store((longlong) key_id, TRUE);
315 rkey_id->get_key_image(buff, rkey_id->pack_length(), Field::itRAW);
317 buff, (key_part_map) 1,
321 !key_res && key_id == (int16) rkey_id->val_int() ;
322 key_res= relations->file->
ha_index_next(relations->record[0]))
324 uchar topic_id_buff[8];
325 longlong topic_id= rtopic_id->val_int();
326 Field *field= find_fields[help_topic_help_topic_id].field;
327 field->store((longlong) topic_id, TRUE);
328 field->get_key_image(topic_id_buff, field->pack_length(), Field::itRAW);
331 (key_part_map)1, HA_READ_KEY_EXACT))
333 memorize_variant_topic(thd,topics,count,find_fields,
334 names,name,description,example);
361 int search_categories(THD *thd,
TABLE *categories,
365 Field *pfname= find_fields[help_category_name].field;
366 Field *pcat_id= find_fields[help_category_help_category_id].field;
370 DBUG_ENTER(
"search_categories");
372 if (init_read_record(&read_record_info, thd, categories, select,
376 while (!read_record_info.read_record(&read_record_info))
378 if (select && !select->cond->val_int())
381 get_field(thd->mem_root,pfname,lname);
382 if (++count == 1 && res_id)
383 *res_id= (int16) pcat_id->val_int();
384 names->push_back(lname);
386 end_read_record(&read_record_info);
407 DBUG_ENTER(
"get_all_items_for_category");
409 if (init_read_record(&read_record_info, thd, items, select,
412 while (!read_record_info.read_record(&read_record_info))
414 if (!select->cond->val_int())
417 get_field(thd->mem_root,pfname,name);
418 res->push_back(name);
420 end_read_record(&read_record_info);
452 DBUG_ENTER(
"send_answer_1");
459 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
462 protocol->prepare_for_resend();
466 if (protocol->write())
493 int send_header_2(
Protocol *protocol,
bool for_category)
495 DBUG_ENTER(
"send_header_2");
502 Protocol::SEND_EOF));
517 extern "C" int string_ptr_cmp(
const void* ptr1,
const void* ptr2)
521 return strcmp(str1->c_ptr(),str2->c_ptr());
543 const char *cat,
String *source_name)
545 DBUG_ENTER(
"send_variant_2_list");
548 sizeof(
String*)*names->elements);
550 String **end= pointers + names->elements;
553 for (pos= pointers; pos!=end; (*pos++= it++)) ;
555 my_qsort(pointers,names->elements,
sizeof(
String*),string_ptr_cmp);
557 for (pos= pointers; pos!=end; pos++)
559 protocol->prepare_for_resend();
561 protocol->
store(source_name);
562 protocol->
store(*pos);
563 protocol->
store(cat,1,&my_charset_latin1);
564 if (protocol->write())
590 cond->fix_fields(thd, &cond);
593 table->covering_keys.clear_all();
595 SQL_SELECT *res= make_select(table, 0, 0, cond, 0, error);
599 if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
600 (res && res->quick && res->quick->reset()))
626 SQL_SELECT *prepare_select_for_name(THD *thd,
const char *mask, uint mlen,
628 Field *pfname,
int *error)
634 if (thd->is_fatal_error)
636 return prepare_simple_select(thd, cond, table, error);
652 bool mysqld_help(THD *thd,
const char *mask)
659 List<String> topics_list, categories_list, subcategories_list;
661 int count_topics, count_categories, error;
662 uint mlen= strlen(mask);
665 DBUG_ENTER(
"mysqld_help");
668 C_STRING_WITH_LEN(
"help_topic"),
669 "help_topic", TL_READ);
671 C_STRING_WITH_LEN(
"help_category"),
672 "help_category", TL_READ);
674 C_STRING_WITH_LEN(
"help_relation"),
675 "help_relation", TL_READ);
677 C_STRING_WITH_LEN(
"help_keyword"),
678 "help_keyword", TL_READ);
679 tables[0].next_global= tables[0].next_local=
680 tables[0].next_name_resolution_table= &tables[1];
681 tables[1].next_global= tables[1].next_local=
682 tables[1].next_name_resolution_table= &tables[2];
683 tables[2].next_global= tables[2].next_local=
684 tables[2].next_name_resolution_table= &tables[3];
691 Open_tables_backup open_tables_state_backup;
692 if (open_system_tables_for_read(thd, tables, &open_tables_state_backup))
699 thd->lex->select_lex.context.table_list=
700 thd->lex->select_lex.context.first_name_resolution_table= &tables[0];
701 if (setup_tables(thd, &thd->lex->select_lex.context,
702 &thd->lex->select_lex.top_join_list,
703 tables, &leaves, FALSE))
705 memcpy((
char*) used_fields, (
char*) init_used_fields,
sizeof(used_fields));
706 if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
708 for (i=0; i<
sizeof(tables)/
sizeof(
TABLE_LIST); i++)
709 tables[i].table->file->init_table_handle_for_HANDLER();
712 prepare_select_for_name(thd,mask,mlen,tables,tables[0].table,
713 used_fields[help_topic_name].field,&error)))
716 count_topics= search_topics(thd,tables[0].table,used_fields,
718 &name, &description, &example);
721 if (count_topics == 0)
723 int UNINIT_VAR(key_id);
725 prepare_select_for_name(thd,mask,mlen,tables,tables[3].table,
726 used_fields[help_keyword_name].field,
730 count_topics= search_keyword(thd,tables[3].table, used_fields, select,
733 count_topics= (count_topics != 1) ? 0 :
734 get_topics_for_keyword(thd,tables[0].table,tables[2].table,
735 used_fields,key_id,&topics_list,&name,
736 &description,&example);
739 if (count_topics == 0)
742 Field *cat_cat_id= used_fields[help_category_parent_category_id].field;
744 prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
745 used_fields[help_category_name].field,
749 count_categories= search_categories(thd, tables[1].table, used_fields,
751 &categories_list,&category_id);
753 if (!count_categories)
755 if (send_header_2(protocol,FALSE))
758 else if (count_categories > 1)
760 if (send_header_2(protocol,FALSE) ||
761 send_variant_2_list(mem_root,protocol,&categories_list,
"Y",0))
766 Field *topic_cat_id= used_fields[help_topic_help_category_id].field;
767 Item *cond_topic_by_cat=
770 Item *cond_cat_by_cat=
773 if (!(select= prepare_simple_select(thd, cond_topic_by_cat,
774 tables[0].table, &error)))
776 get_all_items_for_category(thd,tables[0].table,
777 used_fields[help_topic_name].field,
778 select,&topics_list);
780 if (!(select= prepare_simple_select(thd, cond_cat_by_cat,
781 tables[1].table, &error)))
783 get_all_items_for_category(thd,tables[1].table,
784 used_fields[help_category_name].field,
785 select,&subcategories_list);
787 String *cat= categories_list.head();
788 if (send_header_2(protocol, TRUE) ||
789 send_variant_2_list(mem_root,protocol,&topics_list,
"N",cat) ||
790 send_variant_2_list(mem_root,protocol,&subcategories_list,
"Y",cat))
794 else if (count_topics == 1)
796 if (send_answer_1(protocol,&name,&description,&example))
802 if (send_header_2(protocol, FALSE) ||
803 send_variant_2_list(mem_root,protocol, &topics_list,
"N", 0))
806 prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
807 used_fields[help_category_name].field,&error)))
809 search_categories(thd, tables[1].table, used_fields,
810 select,&categories_list, 0);
813 if (send_variant_2_list(mem_root,protocol, &categories_list,
"Y", 0))
818 close_system_tables(thd, &open_tables_state_backup);
822 close_system_tables(thd, &open_tables_state_backup);