summaryrefslogtreecommitdiff
path: root/sql/sql_help.cc
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2004-06-23 12:36:07 +0200
committerunknown <serg@serg.mylan>2004-06-23 12:36:07 +0200
commiteb70dc5593e987ac2745224ce0ac37f5def22c48 (patch)
treef131301a9d0f77a68268ec331013df866919066f /sql/sql_help.cc
parent540121e1f9f16e32f80dce3a536c6b6d67486681 (diff)
parent9a554b4751237bc96f9ad6eae2df8b310567479d (diff)
downloadmariadb-git-eb70dc5593e987ac2745224ce0ac37f5def22c48.tar.gz
merged
configure.in: Auto merged mysql-test/Makefile.am: Auto merged mysql-test/r/fulltext.result: Auto merged sql/field.cc: Auto merged sql/ha_berkeley.cc: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_innodb.h: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item_subselect.cc: Auto merged sql/lex.h: Auto merged sql/opt_range.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_delete.cc: Auto merged sql/sql_help.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_update.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.cc: Auto merged sql/unireg.cc: Auto merged
Diffstat (limited to 'sql/sql_help.cc')
-rw-r--r--sql/sql_help.cc236
1 files changed, 107 insertions, 129 deletions
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index c5a49cab3b5..eabe66d33bf 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -22,8 +22,6 @@ struct st_find_field
Field *field;
};
-static void free_select(SQL_SELECT *sel);
-
/* Used fields */
static struct st_find_field init_used_fields[]=
@@ -48,9 +46,9 @@ static struct st_find_field init_used_fields[]=
enum enum_used_fields
{
help_topic_help_topic_id= 0,
- help_topic_name,
+ help_topic_name,
help_topic_help_category_id,
- help_topic_description,
+ help_topic_description,
help_topic_example,
help_category_help_category_id,
@@ -60,13 +58,13 @@ enum enum_used_fields
help_keyword_help_keyword_id,
help_keyword_name,
- help_relation_help_topic_id,
+ help_relation_help_topic_id,
help_relation_help_keyword_id
};
/*
- Fill st_find_field structure with pointers to fields
+ Fill st_find_field structure with pointers to fields
SYNOPSIS
init_fields()
@@ -90,7 +88,7 @@ static bool init_fields(THD *thd, TABLE_LIST *tables,
/* We have to use 'new' here as field will be re_linked on free */
Item_field *field= new Item_field("mysql", find_fields->table_name,
find_fields->field_name);
- if (!(find_fields->field= find_field_in_tables(thd, field, tables,
+ if (!(find_fields->field= find_field_in_tables(thd, field, tables,
&not_used, TRUE)))
DBUG_RETURN(1);
}
@@ -119,12 +117,12 @@ static bool init_fields(THD *thd, TABLE_LIST *tables,
NOTE
Field 'names' is set only if more than one topic is found.
- Fields 'name', 'description', 'example' are set only if
+ Fields 'name', 'description', 'example' are set only if
found exactly one topic.
*/
void memorize_variant_topic(THD *thd, TABLE *topics, int count,
- struct st_find_field *find_fields,
+ struct st_find_field *find_fields,
List<String> *names,
String *name, String *description, String *example)
{
@@ -136,7 +134,7 @@ void memorize_variant_topic(THD *thd, TABLE *topics, int count,
get_field(mem_root,find_fields[help_topic_description].field, description);
get_field(mem_root,find_fields[help_topic_example].field, example);
}
- else
+ else
{
if (count == 1)
names->push_back(name);
@@ -168,7 +166,7 @@ void memorize_variant_topic(THD *thd, TABLE *topics, int count,
NOTE
Field 'names' is set only if more than one topic was found.
- Fields 'name', 'description', 'example' are set only if
+ Fields 'name', 'description', 'example' are set only if
exactly one topic was found.
*/
@@ -179,12 +177,12 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields,
{
DBUG_ENTER("search_topics");
int count= 0;
-
+
READ_RECORD read_record_info;
init_read_record(&read_record_info, thd, topics, select,1,0);
while (!read_record_info.read_record(&read_record_info))
{
- if (!select->cond->val_int()) // Dosn't match like
+ if (!select->cond->val_int()) // Doesn't match like
continue;
memorize_variant_topic(thd,topics,count,find_fields,
names,name,description,example);
@@ -219,7 +217,7 @@ int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields,
{
DBUG_ENTER("search_keyword");
int count= 0;
-
+
READ_RECORD read_record_info;
init_read_record(&read_record_info, thd, keywords, select,1,0);
while (!read_record_info.read_record(&read_record_info) && count<2)
@@ -256,13 +254,13 @@ int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields,
description description of found topic (out)
example example for found topic (out)
- NOTE
+ NOTE
Field 'names' is set only if more than one topic was found.
- Fields 'name', 'description', 'example' are set only if
+ Fields 'name', 'description', 'example' are set only if
exactly one topic was found.
*/
-int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
+int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
struct st_find_field *find_fields, int16 key_id,
List<String> *names,
String *name, String *description, String *example)
@@ -273,7 +271,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
Field *rtopic_id, *rkey_id;
DBUG_ENTER("get_topics_for_keyword");
-
+
if ((iindex_topic= find_type((char*) primary_key_name,
&topics->keynames, 1+2)-1)<0 ||
(iindex_relations= find_type((char*) primary_key_name,
@@ -284,18 +282,18 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
}
rtopic_id= find_fields[help_relation_help_topic_id].field;
rkey_id= find_fields[help_relation_help_keyword_id].field;
-
- topics->file->index_init(iindex_topic);
- relations->file->index_init(iindex_relations);
-
+
+ topics->file->ha_index_init(iindex_topic);
+ relations->file->ha_index_init(iindex_relations);
+
rkey_id->store((longlong) key_id);
rkey_id->get_key_image(buff, rkey_id->pack_length(), rkey_id->charset(),
Field::itRAW);
int key_res= relations->file->index_read(relations->record[0],
(byte *)buff, rkey_id->pack_length(),
HA_READ_KEY_EXACT);
-
- for ( ;
+
+ for ( ;
!key_res && key_id == (int16) rkey_id->val_int() ;
key_res= relations->file->index_next(relations->record[0]))
{
@@ -305,7 +303,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
field->store((longlong) topic_id);
field->get_key_image(topic_id_buff, field->pack_length(), field->charset(),
Field::itRAW);
-
+
if (!topics->file->index_read(topics->record[0], (byte *)topic_id_buff,
field->pack_length(), HA_READ_KEY_EXACT))
{
@@ -314,50 +312,12 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
count++;
}
}
+ topics->file->ha_index_end();
+ relations->file->ha_index_end();
DBUG_RETURN(count);
}
/*
- Look for topics with keyword by mask
-
- SYNOPSIS
- search_topics_by_keyword()
- thd Thread handler
- keywords Table of keywords
- topics Table of topics
- relations Table of m:m relation "topic/keyword"
- find_fields Filled array of info for fields
- select Function to test for if matching help keyword.
- Normally 'help_keyword.name like 'bit%'
-
- RETURN VALUES
- # number of topics found
-
- names array of name of found topics (out)
-
- name name of found topic (out)
- description description of found topic (out)
- example example for found topic (out)
-
- NOTE
- Field 'names' is set only if more than one topic was found.
- Fields 'name', 'description', 'example' are set only if
- exactly one topic was found.
-*/
-
-int search_topics_by_keyword(THD *thd,
- TABLE *keywords, TABLE *topics, TABLE *relations,
- struct st_find_field *find_fields,
- SQL_SELECT *select, List<String> *names,
- String *name, String *description, String *example)
-{
- int key_id;
- return search_keyword(thd,keywords,find_fields,select,&key_id)!=1
- ? 0 : get_topics_for_keyword(thd,topics,relations,find_fields,key_id,
- names,name,description,example);
-}
-
-/*
Look for categories by mask
SYNOPSIS
@@ -382,10 +342,10 @@ int search_categories(THD *thd, TABLE *categories,
Field *pfname= find_fields[help_category_name].field;
Field *pcat_id= find_fields[help_category_help_category_id].field;
int count= 0;
- READ_RECORD read_record_info;
+ READ_RECORD read_record_info;
DBUG_ENTER("search_categories");
-
+
init_read_record(&read_record_info, thd, categories, select,1,0);
while (!read_record_info.read_record(&read_record_info))
{
@@ -398,7 +358,7 @@ int search_categories(THD *thd, TABLE *categories,
names->push_back(lname);
}
end_read_record(&read_record_info);
-
+
DBUG_RETURN(count);
}
@@ -423,7 +383,7 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
init_read_record(&read_record_info, thd, items, select,1,0);
while (!read_record_info.read_record(&read_record_info))
{
- if (!select->cond->val_int())
+ if (!select->cond->val_int())
continue;
String *name= new (&thd->mem_root) String();
get_field(&thd->mem_root,pfname,name);
@@ -436,7 +396,7 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
/*
Send to client answer for help request
-
+
SYNOPSIS
send_answer_1()
protocol - protocol for sending
@@ -466,10 +426,10 @@ int send_answer_1(Protocol *protocol, String *s1, String *s2, String *s3)
field_list.push_back(new Item_empty_string("name",64));
field_list.push_back(new Item_empty_string("description",1000));
field_list.push_back(new Item_empty_string("example",1000));
-
+
if (protocol->send_fields(&field_list,1))
DBUG_RETURN(1);
-
+
protocol->prepare_for_resend();
protocol->store(s1);
protocol->store(s2);
@@ -539,7 +499,7 @@ extern "C" int string_ptr_cmp(const void* ptr1, const void* ptr2)
SYNOPSIS
send_variant_2_list()
protocol Protocol for sending
- names List of names
+ names List of names
cat Value of the column <is_it_category>
source_name name of category for all items..
@@ -548,8 +508,8 @@ extern "C" int string_ptr_cmp(const void* ptr1, const void* ptr2)
0 Data was successefully send
*/
-int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
- List<String> *names,
+int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
+ List<String> *names,
const char *cat, String *source_name)
{
DBUG_ENTER("send_variant_2_list");
@@ -589,17 +549,22 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
table goal table
error code of error (out)
-
+
RETURN VALUES
- # created SQL_SELECT
+ # created SQL_SELECT
*/
-SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
+SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
TABLE *table, int *error)
{
cond->fix_fields(thd, tables, &cond); // can never fail
SQL_SELECT *res= make_select(table,0,0,cond,error);
- return (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR))) ? 0 : res;
+ if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)))
+ {
+ delete res;
+ res=0;
+ }
+ return res;
}
/*
@@ -615,9 +580,9 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
pfname field "name" in table
error code of error (out)
-
+
RETURN VALUES
- # created SQL_SELECT
+ # created SQL_SELECT
*/
SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
@@ -649,12 +614,10 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
int mysqld_help(THD *thd, const char *mask)
{
Protocol *protocol= thd->protocol;
- SQL_SELECT *select_topics_by_name= 0, *select_keyword_by_name= 0,
- *select_cat_by_name= 0, *select_topics_by_cat= 0, *select_cat_by_cat= 0,
- *select_root_cats= 0;
+ SQL_SELECT *select;
st_find_field used_fields[array_elements(init_used_fields)];
DBUG_ENTER("mysqld_help");
-
+
TABLE_LIST tables[4];
bzero((gptr)tables,sizeof(tables));
tables[0].alias= tables[0].real_name= (char*) "help_topic";
@@ -670,13 +633,13 @@ int mysqld_help(THD *thd, const char *mask)
tables[3].lock_type= TL_READ;
tables[3].next= 0;
tables[0].db= tables[1].db= tables[2].db= tables[3].db= (char*) "mysql";
-
+
List<String> topics_list, categories_list, subcategories_list;
String name, description, example;
int res, count_topics, count_categories, error;
uint mlen= strlen(mask);
MEM_ROOT *mem_root= &thd->mem_root;
-
+
if (open_and_lock_tables(thd, tables))
{
res= -1;
@@ -684,7 +647,7 @@ int mysqld_help(THD *thd, const char *mask)
}
/* Init tables and fields to be usable from items */
setup_tables(tables);
- memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
+ memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
{
res= -1;
@@ -693,39 +656,55 @@ int mysqld_help(THD *thd, const char *mask)
size_t i;
for (i=0; i<sizeof(tables)/sizeof(TABLE_LIST); i++)
tables[i].table->file->init_table_handle_for_HANDLER();
-
- if (!(select_topics_by_name=
+
+ if (!(select=
prepare_select_for_name(thd,mask,mlen,tables,tables[0].table,
- used_fields[help_topic_name].field,&error)) ||
- !(select_cat_by_name=
- prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
- used_fields[help_category_name].field,&error))||
- !(select_keyword_by_name=
- prepare_select_for_name(thd,mask,mlen,tables,tables[3].table,
- used_fields[help_keyword_name].field,&error)))
+ used_fields[help_topic_name].field,&error)))
{
res= -1;
goto end;
}
res= 1;
- count_topics= search_topics(thd,tables[0].table,used_fields,
- select_topics_by_name,&topics_list,
+ count_topics= search_topics(thd,tables[0].table,used_fields,
+ select,&topics_list,
&name, &description, &example);
+ delete select;
if (count_topics == 0)
- count_topics= search_topics_by_keyword(thd,tables[3].table,tables[0].table,
- tables[2].table,used_fields,
- select_keyword_by_name,&topics_list,
- &name,&description,&example);
-
+ {
+ int key_id;
+ if (!(select=
+ prepare_select_for_name(thd,mask,mlen,tables,tables[3].table,
+ used_fields[help_keyword_name].field,&error)))
+ {
+ res= -1;
+ goto end;
+ }
+ count_topics=search_keyword(thd,tables[3].table,used_fields,select,&key_id);
+ delete select;
+ count_topics= (count_topics != 1) ? 0 :
+ get_topics_for_keyword(thd,tables[0].table,tables[2].table,
+ used_fields,key_id,&topics_list,&name,
+ &description,&example);
+ }
+
if (count_topics == 0)
{
int16 category_id;
Field *cat_cat_id= used_fields[help_category_parent_category_id].field;
+ if (!(select=
+ prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
+ used_fields[help_category_name].field,&error)))
+ {
+ res= -1;
+ goto end;
+ }
+
count_categories= search_categories(thd, tables[1].table, used_fields,
- select_cat_by_name,
+ select,
&categories_list,&category_id);
+ delete select;
if (!count_categories)
{
if (send_header_2(protocol,FALSE))
@@ -746,22 +725,26 @@ int mysqld_help(THD *thd, const char *mask)
Item *cond_cat_by_cat=
new Item_func_equal(new Item_field(cat_cat_id),
new Item_int((int32)category_id));
- if (!(select_topics_by_cat= prepare_simple_select(thd,cond_topic_by_cat,
- tables,tables[0].table,
- &error)) ||
- !(select_cat_by_cat=
- prepare_simple_select(thd,cond_cat_by_cat,tables,
- tables[1].table,&error)))
+ if (!(select= prepare_simple_select(thd,cond_topic_by_cat,
+ tables,tables[0].table,&error)))
{
res= -1;
goto end;
}
get_all_items_for_category(thd,tables[0].table,
used_fields[help_topic_name].field,
- select_topics_by_cat,&topics_list);
+ select,&topics_list);
+ delete select;
+ if (!(select= prepare_simple_select(thd,cond_cat_by_cat,tables,
+ tables[1].table,&error)))
+ {
+ res= -1;
+ goto end;
+ }
get_all_items_for_category(thd,tables[1].table,
used_fields[help_category_name].field,
- select_cat_by_cat,&subcategories_list);
+ select,&subcategories_list);
+ delete select;
String *cat= categories_list.head();
if (send_header_2(protocol, true) ||
send_variant_2_list(mem_root,protocol,&topics_list, "N",cat) ||
@@ -780,30 +763,25 @@ int mysqld_help(THD *thd, const char *mask)
if (send_header_2(protocol, FALSE) ||
send_variant_2_list(mem_root,protocol, &topics_list, "N", 0))
goto end;
- search_categories(thd, tables[1].table, used_fields,
- select_cat_by_name,&categories_list, 0);
+ if (!(select=
+ prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
+ used_fields[help_category_name].field,&error)))
+ {
+ res= -1;
+ goto end;
+ }
+ search_categories(thd, tables[1].table, used_fields,
+ select,&categories_list, 0);
+ delete select;
/* Then send categories */
if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0))
goto end;
}
res= 0;
-
+
send_eof(thd);
end:
- free_select(select_topics_by_name);
- free_select(select_keyword_by_name);
- free_select(select_cat_by_name);
- free_select(select_topics_by_cat);
- free_select(select_cat_by_cat);
- free_select(select_root_cats);
-
DBUG_RETURN(res);
}
-
-static void free_select(SQL_SELECT *sel)
-{
- if (sel)
- delete sel->quick;
-}