summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <vva@eagle.mysql.r18.ru>2003-05-29 17:47:31 -0400
committerunknown <vva@eagle.mysql.r18.ru>2003-05-29 17:47:31 -0400
commit69e084af1eedff2dda70fcf073dd4fa349718b69 (patch)
treea9f85257a75430a22735e52666cbf25e605ea2bb
parentf440077bd03869f48ff278bc2b73fab7a30e282b (diff)
downloadmariadb-git-69e084af1eedff2dda70fcf073dd4fa349718b69.tar.gz
new version of help
-rw-r--r--client/mysql.cc83
-rw-r--r--mysql-test/install_test_db.sh210
-rw-r--r--mysql-test/r/connect.result3
-rw-r--r--mysql-test/r/help.result254
-rw-r--r--mysql-test/t/help.test111
-rw-r--r--scripts/Makefile.am20
-rw-r--r--scripts/fill_help_tables.sh560
-rw-r--r--scripts/mysql_create_system_tables.sh311
-rw-r--r--scripts/mysql_install_db.sh220
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/protocol.h2
-rw-r--r--sql/sql_help.cc782
-rw-r--r--sql/table.cc27
13 files changed, 1653 insertions, 931 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index aa9dcca92db..1bfadb37eb2 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1457,6 +1457,16 @@ int mysql_store_result_for_lazy(MYSQL_RES **result)
return 0;
}
+static void print_help_item(MYSQL_ROW *cur, int num_name, int num_cat, char *last_char)
+{
+ char ccat= (*cur)[num_cat][0];
+ if (*last_char != ccat)
+ {
+ put_info(ccat == 'Y' ? "categories :" : "topics :", INFO_INFO);
+ *last_char= ccat;
+ }
+ tee_fprintf(PAGER, " %s\n", (*cur)[num_name]);
+}
static int com_server_help(String *buffer __attribute__((unused)),
char *line __attribute__((unused)), char *help_arg)
@@ -1465,14 +1475,15 @@ static int com_server_help(String *buffer __attribute__((unused)),
const char *server_cmd= buffer->ptr();
char cmd_buf[100];
MYSQL_RES *result;
+ MYSQL_FIELD *fields;
int error;
-
+
if (help_arg[0] != '\'')
{
(void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
server_cmd= cmd_buf;
}
-
+
if (!status.batch)
{
old_buffer= *buffer;
@@ -1482,15 +1493,16 @@ static int com_server_help(String *buffer __attribute__((unused)),
if (!connected && reconnect())
return 1;
- if ((error= mysql_real_query_for_lazy(server_cmd,strlen(server_cmd))))
- return error;
- if ((error= mysql_store_result_for_lazy(&result)))
+ if ((error= mysql_real_query_for_lazy(server_cmd,strlen(server_cmd))) ||
+ (error= mysql_store_result_for_lazy(&result)))
return error;
if (result)
{
- ulonglong num_rows= mysql_num_rows(result);
- if (num_rows == 1)
+ unsigned int num_fields= mysql_num_fields(result);
+ my_ulonglong num_rows= mysql_num_rows(result);
+ fields= mysql_fetch_fields(result);
+ if (num_fields==3 && num_rows==1)
{
if (!(cur= mysql_fetch_row(result)))
{
@@ -1499,46 +1511,45 @@ static int com_server_help(String *buffer __attribute__((unused)),
}
init_pager();
- if (cur[1][0] == 'Y')
- {
- tee_fprintf(PAGER, "Help topic \'%s\'\n", cur[0]);
- tee_fprintf(PAGER, "%s\n", cur[2]);
- tee_fprintf(PAGER, "For help on specific function please type 'help <function>'\nwhere function is one of next:\n%s\n", cur[3]);
- }
- else
- {
- tee_fprintf(PAGER, "Name: \'%s\'\n\n", cur[0]);
- tee_fprintf(PAGER, "Description:\n%s\n\n", cur[2]);
- if (cur[3])
- tee_fprintf(PAGER, "Examples:\n%s\n", cur[3]);
- }
+ tee_fprintf(PAGER, "Name: \'%s\'\n", cur[0]);
+ tee_fprintf(PAGER, "Description:\n%s", cur[1]);
+ if (cur[2] && *((char*)cur[2]))
+ tee_fprintf(PAGER, "Examples:\n%s", cur[2]);
+ tee_fprintf(PAGER, "\n");
end_pager();
}
- else if (num_rows > 1)
+ else if (num_fields >= 2 && num_rows)
{
- put_info("Many help items for your request exist", INFO_INFO);
- put_info("For more specific request please type 'help <item>' where item is one of next:", INFO_INFO);
-
init_pager();
- char last_char= '_';
- while ((cur= mysql_fetch_row(result)))
+ char last_char;
+
+ int num_name, num_cat;
+ if (num_fields == 2)
{
- if (cur[1][0]!=last_char)
- {
- put_info("-------------------------------------------", INFO_INFO);
- put_info(cur[1][0] == 'Y' ?
- "categories:" : "functions:", INFO_INFO);
- put_info("-------------------------------------------", INFO_INFO);
- }
- last_char= cur[1][0];
- tee_fprintf(PAGER, "%s\n", cur[0]);
+ put_info("Many help items for your request exist", INFO_INFO);
+ put_info("For more specific request please type 'help <item>' where item is one of next", INFO_INFO);
+ num_name= 0;
+ num_cat= 1;
+ last_char= '_';
}
+ else if ((cur= mysql_fetch_row(result)))
+ {
+ tee_fprintf(PAGER, "You asked help about help category: \"%s\"\n", cur[0]);
+ put_info("For a more information type 'help <item>' where item is one of the following", INFO_INFO);
+ num_name= 1;
+ num_cat= 2;
+ print_help_item(&cur,1,2,&last_char);
+ }
+
+ while ((cur= mysql_fetch_row(result)))
+ print_help_item(&cur,num_name,num_cat,&last_char);
tee_fprintf(PAGER, "\n");
end_pager();
}
else
{
- put_info("\nNothing found\n", INFO_INFO);
+ put_info("\nNothing found", INFO_INFO);
+ put_info("Please try to run 'help contents' for list of all accessible topics\n", INFO_INFO);
}
}
diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh
index fc3e00d8501..ca6d393e3b4 100644
--- a/mysql-test/install_test_db.sh
+++ b/mysql-test/install_test_db.sh
@@ -11,10 +11,12 @@ if [ x$1 = x"-bin" ]; then
bindir=../bin
BINARY_DIST=1
fix_bin=mysql-test
+ scriptdir=../bin
else
execdir=../sql
bindir=../client
fix_bin=.
+ scriptdir=../scripts
fi
vardir=var
@@ -60,217 +62,11 @@ basedir=.
EXTRA_ARG="--language=../sql/share/english/"
fi
-# Initialize variables
-c_d="" i_d=""
-c_h="" i_h=""
-c_u="" i_u=""
-c_f="" i_f=""
-c_t="" c_c=""
-c_hl="" c_hl=""
-c_hc="" c_hc=""
-c_clr="" c_clr=""
-
-# Check for old tables
-if test ! -f $mdata/db.frm
-then
- # mysqld --bootstrap wants one command/line
- c_d="$c_d CREATE TABLE db ("
- c_d="$c_d Host char(60) DEFAULT '' NOT NULL,"
- c_d="$c_d Db char(64) DEFAULT '' NOT NULL,"
- c_d="$c_d User char(16) DEFAULT '' NOT NULL,"
- c_d="$c_d Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d PRIMARY KEY Host (Host,Db,User),"
- c_d="$c_d KEY User (User)"
- c_d="$c_d )"
- c_d="$c_d comment='Database privileges';"
-
- i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
- INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');"
-fi
-
-if test ! -f $mdata/host.frm
-then
- c_h="$c_h CREATE TABLE host ("
- c_h="$c_h Host char(60) DEFAULT '' NOT NULL,"
- c_h="$c_h Db char(64) DEFAULT '' NOT NULL,"
- c_h="$c_h Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h PRIMARY KEY Host (Host,Db)"
- c_h="$c_h )"
- c_h="$c_h comment='Host privileges; Merged with database privileges';"
-fi
-
-if test ! -f $mdata/user.frm
-then
- c_u="$c_u CREATE TABLE user ("
- c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL,"
- c_u="$c_u User char(16) binary DEFAULT '' NOT NULL,"
- c_u="$c_u Password char(45) binary DEFAULT '' NOT NULL,"
- c_u="$c_u Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Process_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u File_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
- c_u="$c_u ssl_cipher BLOB NOT NULL,"
- c_u="$c_u x509_issuer BLOB NOT NULL,"
- c_u="$c_u x509_subject BLOB NOT NULL,"
- c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
- c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
- c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
- c_u="$c_u PRIMARY KEY Host (Host,User)"
- c_u="$c_u )"
- c_u="$c_u comment='Users and global privileges';"
-
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
- INSERT INTO user (host,user) values ('localhost','');
- INSERT INTO user (host,user) values ('$hostname','');"
-fi
-
-if test ! -f $mdata/func.frm
-then
- c_f="$c_f CREATE TABLE func ("
- c_f="$c_f name char(64) DEFAULT '' NOT NULL,"
- c_f="$c_f ret tinyint(1) DEFAULT '0' NOT NULL,"
- c_f="$c_f dl char(128) DEFAULT '' NOT NULL,"
- c_f="$c_f type enum ('function','aggregate') NOT NULL,"
- c_f="$c_f PRIMARY KEY (name)"
- c_f="$c_f )"
- c_f="$c_f comment='User defined functions';"
-fi
-
-if test ! -f $mdata/tables_priv.frm
-then
- c_t="$c_t CREATE TABLE tables_priv ("
- c_t="$c_t Host char(60) DEFAULT '' NOT NULL,"
- c_t="$c_t Db char(64) DEFAULT '' NOT NULL,"
- c_t="$c_t User char(16) DEFAULT '' NOT NULL,"
- c_t="$c_t Table_name char(60) DEFAULT '' NOT NULL,"
- c_t="$c_t Grantor char(77) DEFAULT '' NOT NULL,"
- c_t="$c_t Timestamp timestamp(14),"
- c_t="$c_t Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL,"
- c_t="$c_t Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,"
- c_t="$c_t PRIMARY KEY (Host,Db,User,Table_name),"
- c_t="$c_t KEY Grantor (Grantor)"
- c_t="$c_t )"
- c_t="$c_t comment='Table privileges';"
-fi
-
-if test ! -f $mdata/columns_priv.frm
-then
- c_c="$c_c CREATE TABLE columns_priv ("
- c_c="$c_c Host char(60) DEFAULT '' NOT NULL,"
- c_c="$c_c Db char(64) DEFAULT '' NOT NULL,"
- c_c="$c_c User char(16) DEFAULT '' NOT NULL,"
- c_c="$c_c Table_name char(64) DEFAULT '' NOT NULL,"
- c_c="$c_c Column_name char(64) DEFAULT '' NOT NULL,"
- c_c="$c_c Timestamp timestamp(14),"
- c_c="$c_c Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,"
- c_c="$c_c PRIMARY KEY (Host,Db,User,Table_name,Column_name)"
- c_c="$c_c )"
- c_c="$c_c comment='Column privileges';"
-fi
-
-if test ! -f $mdata/help_topic.frm
-then
- c_hl="$c_hl CREATE TABLE help_topic ("
- c_hl="$c_hl help_topic_id int unsigned not null auto_increment,"
- c_hl="$c_hl name varchar(64) not null,"
- c_hl="$c_hl description text not null,"
- c_hl="$c_hl example text not null,"
- c_hl="$c_hl url varchar(128) not null,"
- c_hl="$c_hl primary key (help_topic_id),"
- c_hl="$c_hl unique index (name)"
- c_hl="$c_hl )"
- c_hl="$c_hl comment='help topics';"
-fi
-
-if test ! -f $mdata/help_category.frm
-then
- c_clr="$c_clr CREATE TABLE help_category ("
- c_clr="$c_clr help_category_id smallint unsigned not null auto_increment,"
- c_clr="$c_clr name varchar(64) not null,"
- c_clr="$c_clr url varchar(128) not null,"
- c_clr="$c_clr primary key (help_category_id),"
- c_clr="$c_clr unique index (name)"
- c_clr="$c_clr )"
- c_clr="$c_clr comment='help topics-categories relation';"
-fi
-
-if test ! -f $mdata/help_relation.frm
-then
- c_hc="$c_hc CREATE TABLE help_relation ("
- c_hc="$c_hc help_topic_id int unsigned not null references help_topic,"
- c_hc="$c_hc help_category_id smallint unsigned not null references help_category,"
- c_hc="$c_hc primary key (help_category_id, help_topic_id),"
- c_hc="$c_hc )"
- c_hc="$c_hc comment='categories of help topics';"
-fi
-
mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
--basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $EXTRA_ARG"
echo "running $mysqld_boot"
-if $mysqld_boot << END_OF_DATA
-use mysql;
-$c_d
-$i_d
-
-$c_h
-$i_h
-
-$c_u
-$i_u
-
-$c_f
-$i_f
-
-$c_t
-$c_c
-
-$c_hl
-$c_hc
-$c_clr
-END_OF_DATA
+if $scriptdir/mysql_create_system_tables test $mdata $hostname | $mysqld_boot
then
exit 0
else
diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result
index b7243ac5d0b..a80ddc24d05 100644
--- a/mysql-test/r/connect.result
+++ b/mysql-test/r/connect.result
@@ -4,6 +4,7 @@ columns_priv
db
func
help_category
+help_keyword
help_relation
help_topic
host
@@ -19,6 +20,7 @@ columns_priv
db
func
help_category
+help_keyword
help_relation
help_topic
host
@@ -34,6 +36,7 @@ columns_priv
db
func
help_category
+help_keyword
help_relation
help_topic
host
diff --git a/mysql-test/r/help.result b/mysql-test/r/help.result
index 4da4a84d4ad..d22539b2bcb 100644
--- a/mysql-test/r/help.result
+++ b/mysql-test/r/help.result
@@ -1,123 +1,243 @@
-truncate mysql.help_topic;
-truncate mysql.help_category;
-truncate mysql.help_relation;
-insert into mysql.help_topic(name,description,example)values('impossible_function_1','description of \n impossible_function1','example of \n impossible_function1');
-SELECT @topic1_id:=LAST_INSERT_ID();
-@topic1_id:=LAST_INSERT_ID()
+insert into mysql.help_category(help_category_id,name)values(1,'impossible_category_1');
+select @category1_id:= 1;
+@category1_id:= 1
1
-insert into mysql.help_topic(name,description,example)values('impossible_function_2','description of \n impossible_function2','example of \n impossible_function2');
-SELECT @topic2_id:=LAST_INSERT_ID();
-@topic2_id:=LAST_INSERT_ID()
+insert into mysql.help_category(help_category_id,name)values(2,'impossible_category_2');
+select @category2_id:= 2;
+@category2_id:= 2
2
-insert into mysql.help_topic(name,description,example)values('impossible_function_3','description of \n impossible_function3','example of \n impossible_function3');
-SELECT @topic3_id:=LAST_INSERT_ID();
-@topic3_id:=LAST_INSERT_ID()
+insert into mysql.help_category(help_category_id,name,parent_category_id)values(3,'impossible_category_3',@category2_id);
+select @category3_id:= 3;
+@category3_id:= 3
3
-insert into mysql.help_category(name)values('impossible_category_1');
-SELECT @category1_id:=LAST_INSERT_ID();
-@category1_id:=LAST_INSERT_ID()
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(1,'impossible_function_1',@category1_id,'description of \n impossible_function1\n','example of \n impossible_function1');
+select @topic1_id:= 1;
+@topic1_id:= 1
1
-insert into mysql.help_category(name)values('impossible_category_2');
-SELECT @category2_id:=LAST_INSERT_ID();
-@category2_id:=LAST_INSERT_ID()
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(2,'impossible_function_2',@category1_id,'description of \n impossible_function2\n','example of \n impossible_function2');
+select @topic2_id:= 2;
+@topic2_id:= 2
2
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category1_id,@topic1_id);
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category1_id,@topic2_id);
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category2_id,@topic2_id);
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category2_id,@topic3_id);
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(3,'impossible_function_3',@category2_id,'description of \n impossible_function3\n','example of \n impossible_function3');
+select @topic3_id:= 3;
+@topic3_id:= 3
+3
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(4,'impossible_function_4',@category2_id,'description of \n impossible_function4\n','example of \n impossible_function4');
+select @topic4_id:= 4;
+@topic4_id:= 4
+4
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(5,'impossible_function_7',@category3_id,'description of \n impossible_function5\n','example of \n impossible_function7');
+select @topic5_id:= 5;
+@topic5_id:= 5
+5
+insert into mysql.help_keyword(help_keyword_id,name)values(1,'impossible_function_1');
+select @keyword1_id:= 1;
+@keyword1_id:= 1
+1
+insert into mysql.help_keyword(help_keyword_id,name)values(2,'impossible_function_5');
+select @keyword2_id:= 2;
+@keyword2_id:= 2
+2
+insert into mysql.help_keyword(help_keyword_id,name)values(3,'impossible_function_6');
+select @keyword3_id:= 3;
+@keyword3_id:= 3
+3
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword1_id,@topic2_id);
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword2_id,@topic1_id);
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword3_id,@topic3_id);
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword3_id,@topic4_id);
help 'function_of_my_dream';
-Name Category
-impossible_category_1 Y
-impossible_category_2 Y
+name is_it_category
help '%possible_f%';
-Name Category
+name is_it_category
impossible_function_1 N
impossible_function_2 N
impossible_function_3 N
+impossible_function_4 N
+impossible_function_7 N
help 'impossible_func%';
-Name Category
+name is_it_category
impossible_function_1 N
impossible_function_2 N
impossible_function_3 N
+impossible_function_4 N
+impossible_function_7 N
help 'impossible_category%';
-Name Category
+name is_it_category
impossible_category_1 Y
impossible_category_2 Y
+impossible_category_3 Y
help 'impossible_%';
-Name Category
+name is_it_category
impossible_function_1 N
impossible_function_2 N
impossible_function_3 N
+impossible_function_4 N
+impossible_function_7 N
impossible_category_1 Y
impossible_category_2 Y
+impossible_category_3 Y
+help '%function_1';
+name description example
+impossible_function_1 description of
+ impossible_function1
+ example of
+ impossible_function1
help '%function_2';
-Name Category Description Example
-impossible_function_2 N description of
- impossible_function2 example of
+name description example
+impossible_function_2 description of
+ impossible_function2
+ example of
impossible_function2
+help '%function_3';
+name description example
+impossible_function_3 description of
+ impossible_function3
+ example of
+ impossible_function3
+help '%function_4';
+name description example
+impossible_function_4 description of
+ impossible_function4
+ example of
+ impossible_function4
+help '%function_5';
+name description example
+impossible_function_1 description of
+ impossible_function1
+ example of
+ impossible_function1
+help '%function_6';
+name is_it_category
+impossible_function_3 N
+impossible_function_4 N
+help '%function_7';
+name description example
+impossible_function_7 description of
+ impossible_function5
+ example of
+ impossible_function7
help '%category_2';
-Name Category Description Example
-impossible_category_2 Y impossible_function_2
-impossible_function_3
-
+source_category_name name is_it_category
+impossible_category_2 impossible_function_3 N
+impossible_category_2 impossible_function_4 N
+impossible_category_2 impossible_category_3 Y
help 'impossible_function_1';
-Name Category Description Example
-impossible_function_1 N description of
- impossible_function1 example of
+name description example
+impossible_function_1 description of
+ impossible_function1
+ example of
impossible_function1
help 'impossible_category_1';
-Name Category Description Example
-impossible_category_1 Y impossible_function_1
-impossible_function_2
-
+source_category_name name is_it_category
+impossible_category_1 impossible_function_1 N
+impossible_category_1 impossible_function_2 N
+alter table mysql.help_relation type=innodb;
+alter table mysql.help_keyword type=innodb;
alter table mysql.help_topic type=innodb;
alter table mysql.help_category type=innodb;
-alter table mysql.help_relation type=innodb;
help 'function_of_my_dream';
-Name Category
-impossible_category_1 Y
-impossible_category_2 Y
-help '%ble_f%';
-Name Category
+name is_it_category
+help '%possible_f%';
+name is_it_category
impossible_function_1 N
impossible_function_2 N
impossible_function_3 N
+impossible_function_4 N
+impossible_function_7 N
help 'impossible_func%';
-Name Category
+name is_it_category
impossible_function_1 N
impossible_function_2 N
impossible_function_3 N
+impossible_function_4 N
+impossible_function_7 N
help 'impossible_category%';
-Name Category
+name is_it_category
impossible_category_1 Y
impossible_category_2 Y
+impossible_category_3 Y
help 'impossible_%';
-Name Category
+name is_it_category
impossible_function_1 N
impossible_function_2 N
impossible_function_3 N
+impossible_function_4 N
+impossible_function_7 N
impossible_category_1 Y
impossible_category_2 Y
+impossible_category_3 Y
+help '%function_1';
+name description example
+impossible_function_1 description of
+ impossible_function1
+ example of
+ impossible_function1
help '%function_2';
-Name Category Description Example
-impossible_function_2 N description of
- impossible_function2 example of
+name description example
+impossible_function_2 description of
+ impossible_function2
+ example of
impossible_function2
+help '%function_3';
+name description example
+impossible_function_3 description of
+ impossible_function3
+ example of
+ impossible_function3
+help '%function_4';
+name description example
+impossible_function_4 description of
+ impossible_function4
+ example of
+ impossible_function4
+help '%function_5';
+name description example
+impossible_function_1 description of
+ impossible_function1
+ example of
+ impossible_function1
+help '%function_6';
+name is_it_category
+impossible_function_3 N
+impossible_function_4 N
+help '%function_7';
+name description example
+impossible_function_7 description of
+ impossible_function5
+ example of
+ impossible_function7
help '%category_2';
-Name Category Description Example
-impossible_category_2 Y impossible_function_2
-impossible_function_3
-
+source_category_name name is_it_category
+impossible_category_2 impossible_function_3 N
+impossible_category_2 impossible_function_4 N
+impossible_category_2 impossible_category_3 Y
help 'impossible_function_1';
-Name Category Description Example
-impossible_function_1 N description of
- impossible_function1 example of
+name description example
+impossible_function_1 description of
+ impossible_function1
+ example of
impossible_function1
help 'impossible_category_1';
-Name Category Description Example
-impossible_category_1 Y impossible_function_1
-impossible_function_2
-
+source_category_name name is_it_category
+impossible_category_1 impossible_function_1 N
+impossible_category_1 impossible_function_2 N
+alter table mysql.help_relation type=myisam;
+alter table mysql.help_keyword type=myisam;
alter table mysql.help_topic type=myisam;
alter table mysql.help_category type=myisam;
-alter table mysql.help_relation type=myisam;
+delete from mysql.help_topic where help_topic_id=@topic1_id;
+delete from mysql.help_topic where help_topic_id=@topic2_id;
+delete from mysql.help_topic where help_topic_id=@topic3_id;
+delete from mysql.help_topic where help_topic_id=@topic4_id;
+delete from mysql.help_topic where help_topic_id=@topic5_id;
+delete from mysql.help_category where help_category_id=@category3_id;
+delete from mysql.help_category where help_category_id=@category2_id;
+delete from mysql.help_category where help_category_id=@category1_id;
+delete from mysql.help_keyword where help_keyword_id=@keyword1_id;
+delete from mysql.help_keyword where help_keyword_id=@keyword2_id;
+delete from mysql.help_keyword where help_keyword_id=@keyword3_id;
+delete from mysql.help_relation where help_keyword_id=@keyword1_id and help_topic_id=@topic2_id;
+delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topic_id=@topic1_id;
+delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
+delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;
diff --git a/mysql-test/t/help.test b/mysql-test/t/help.test
index c36b670c6b3..82312340336 100644
--- a/mysql-test/t/help.test
+++ b/mysql-test/t/help.test
@@ -1,50 +1,115 @@
-- source include/have_innodb.inc
-truncate mysql.help_topic;
-truncate mysql.help_category;
-truncate mysql.help_relation;
-
-insert into mysql.help_topic(name,description,example)values('impossible_function_1','description of \n impossible_function1','example of \n impossible_function1');
-SELECT @topic1_id:=LAST_INSERT_ID();
-insert into mysql.help_topic(name,description,example)values('impossible_function_2','description of \n impossible_function2','example of \n impossible_function2');
-SELECT @topic2_id:=LAST_INSERT_ID();
-insert into mysql.help_topic(name,description,example)values('impossible_function_3','description of \n impossible_function3','example of \n impossible_function3');
-SELECT @topic3_id:=LAST_INSERT_ID();
-
-insert into mysql.help_category(name)values('impossible_category_1');
-SELECT @category1_id:=LAST_INSERT_ID();
-insert into mysql.help_category(name)values('impossible_category_2');
-SELECT @category2_id:=LAST_INSERT_ID();
-
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category1_id,@topic1_id);
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category1_id,@topic2_id);
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category2_id,@topic2_id);
-insert into mysql.help_relation(help_category_id,help_topic_id)values(@category2_id,@topic3_id);
+# category: topic: keyword:
+#
+# impossible_category_1
+# impossible_function_1
+# impossible_function_5
+# impossible_function_2
+# impossible_function_1
+# impossible_category_2
+# impossible_function_3
+# impossible_function_6
+# impossible_function_4
+# impossible_function_6
+# impossible_category_3
+# impossible_function_7
+insert into mysql.help_category(help_category_id,name)values(1,'impossible_category_1');
+select @category1_id:= 1;
+insert into mysql.help_category(help_category_id,name)values(2,'impossible_category_2');
+select @category2_id:= 2;
+insert into mysql.help_category(help_category_id,name,parent_category_id)values(3,'impossible_category_3',@category2_id);
+select @category3_id:= 3;
+
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(1,'impossible_function_1',@category1_id,'description of \n impossible_function1\n','example of \n impossible_function1');
+select @topic1_id:= 1;
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(2,'impossible_function_2',@category1_id,'description of \n impossible_function2\n','example of \n impossible_function2');
+select @topic2_id:= 2;
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(3,'impossible_function_3',@category2_id,'description of \n impossible_function3\n','example of \n impossible_function3');
+select @topic3_id:= 3;
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(4,'impossible_function_4',@category2_id,'description of \n impossible_function4\n','example of \n impossible_function4');
+select @topic4_id:= 4;
+insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(5,'impossible_function_7',@category3_id,'description of \n impossible_function5\n','example of \n impossible_function7');
+select @topic5_id:= 5;
+
+insert into mysql.help_keyword(help_keyword_id,name)values(1,'impossible_function_1');
+select @keyword1_id:= 1;
+insert into mysql.help_keyword(help_keyword_id,name)values(2,'impossible_function_5');
+select @keyword2_id:= 2;
+insert into mysql.help_keyword(help_keyword_id,name)values(3,'impossible_function_6');
+select @keyword3_id:= 3;
+
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword1_id,@topic2_id);
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword2_id,@topic1_id);
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword3_id,@topic3_id);
+insert into mysql.help_relation(help_keyword_id,help_topic_id)values(@keyword3_id,@topic4_id);
+
+##############
help 'function_of_my_dream';
help '%possible_f%';
help 'impossible_func%';
help 'impossible_category%';
help 'impossible_%';
+
+help '%function_1';
help '%function_2';
+help '%function_3';
+help '%function_4';
+help '%function_5';
+help '%function_6';
+help '%function_7';
+
help '%category_2';
help 'impossible_function_1';
help 'impossible_category_1';
+##############
+alter table mysql.help_relation type=innodb;
+alter table mysql.help_keyword type=innodb;
alter table mysql.help_topic type=innodb;
alter table mysql.help_category type=innodb;
-alter table mysql.help_relation type=innodb;
+##############
help 'function_of_my_dream';
-help '%ble_f%';
+help '%possible_f%';
help 'impossible_func%';
help 'impossible_category%';
help 'impossible_%';
+
+help '%function_1';
help '%function_2';
+help '%function_3';
+help '%function_4';
+help '%function_5';
+help '%function_6';
+help '%function_7';
+
help '%category_2';
help 'impossible_function_1';
help 'impossible_category_1';
+##############
+alter table mysql.help_relation type=myisam;
+alter table mysql.help_keyword type=myisam;
alter table mysql.help_topic type=myisam;
alter table mysql.help_category type=myisam;
-alter table mysql.help_relation type=myisam;
+
+delete from mysql.help_topic where help_topic_id=@topic1_id;
+delete from mysql.help_topic where help_topic_id=@topic2_id;
+delete from mysql.help_topic where help_topic_id=@topic3_id;
+delete from mysql.help_topic where help_topic_id=@topic4_id;
+delete from mysql.help_topic where help_topic_id=@topic5_id;
+
+delete from mysql.help_category where help_category_id=@category3_id;
+delete from mysql.help_category where help_category_id=@category2_id;
+delete from mysql.help_category where help_category_id=@category1_id;
+
+delete from mysql.help_keyword where help_keyword_id=@keyword1_id;
+delete from mysql.help_keyword where help_keyword_id=@keyword2_id;
+delete from mysql.help_keyword where help_keyword_id=@keyword3_id;
+
+delete from mysql.help_relation where help_keyword_id=@keyword1_id and help_topic_id=@topic2_id;
+delete from mysql.help_relation where help_keyword_id=@keyword2_id and help_topic_id=@topic1_id;
+delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic3_id;
+delete from mysql.help_relation where help_keyword_id=@keyword3_id and help_topic_id=@topic4_id;
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 88f561e0e6d..1134226bfaf 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -32,7 +32,9 @@ bin_SCRIPTS = @server_scripts@ \
mysqldumpslow \
mysql_explain_log \
mysql_tableinfo \
- mysqld_multi
+ mysqld_multi \
+ fill_help_tables \
+ mysql_create_system_tables
EXTRA_SCRIPTS = make_binary_distribution.sh \
make_win_src_distribution.sh \
@@ -54,14 +56,13 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \
mysqld_multi.sh \
mysql_tableinfo.sh \
mysqld_safe.sh \
- fill_help_tables.sh
+ fill_help_tables.sh \
+ mysql_create_system_tables.sh
EXTRA_DIST = $(EXTRA_SCRIPTS) \
mysqlaccess.conf \
mysqlbug
-pkgdata_DATA = fill_help_tables.sql
-
# mysqlbug should be distributed built so that people can report build
# failures with it.
CLEANFILES = @server_scripts@ \
@@ -81,7 +82,7 @@ CLEANFILES = @server_scripts@ \
mysqldumpslow \
mysqld_multi \
fill_help_tables \
- fill_help_tables.sql
+ mysql_create_system_tables
SUPERCLEANFILES = mysqlbug
@@ -137,12 +138,5 @@ SUFFIXES = .sh
# Don't update the files from bitkeeper
%::SCCS/s.%
-all: fill_help_tables.sql make_win_src_distribution make_binary_distribution
-
-# The following rule is here to ensure that build will continue
-# even if we don't have perl installed. In this case the help tables
-# will be empty
+all: make_win_src_distribution make_binary_distribution
-fill_help_tables.sql: fill_help_tables ../Docs/manual.texi
- -./fill_help_tables < ../Docs/manual.texi > fill_help_tables.sql
- echo "" >> fill_help_tables.sql
diff --git a/scripts/fill_help_tables.sh b/scripts/fill_help_tables.sh
index e21b0ff2bb0..b8cf4ccb3a7 100644
--- a/scripts/fill_help_tables.sh
+++ b/scripts/fill_help_tables.sh
@@ -1,31 +1,178 @@
#!@PERL@
#
-# Usage: fill_help_tables <manual.texi>
-# Example: ./fill_help_tables < ../Docs/manual.texi > fill_help_tables.sql
+# Copyright (C) 2003 MySQL AB
+# For a more info consult the file COPYRIGHT distributed with this file.
#
# This script generates the SQL statements required by mysql_install_db to
# fill up the tables for the server-side online function help, which can be
# invoked with "help <function>" from the MySQL client.
#
+# Usage:
+# fill_help_tables OPTIONS < manual.texi > fill_help_tables.sql
+#
+# --help display this helpscreen and exit
+# --verbose print information about help completeness to STDERR
+# --lexems=path path to file with lexems. it is used with verbose option.
+# default value is ../sql/lex.h
+# Examples:
+# ./fill_help_tables --help
+# ./fill_help_tables --verbose < manual.texi > fill_help_tables.sql
+# ./fill_help_tables < manual.texi > fill_help_tables.sql
+#
# Please note, that you first need to update Docs/manual.texi with the
# manual file from the separate "mysqldoc" BitKeeper-Tree! The manual.texi
# included in the source tree is just an empty stub file - the full manual
# is now maintained in a separate tree.
#
+# extra tags in manual.texi:
+#
+# @c help_category <category_name>[@<parent_category_name>]
+#
+# @c description_for_help_topic <topic_name> <keyword1> <keyword2>
+# ....
+# @c end_description_for_help_topic
+#
+# @c example_for_help_topic <topic_name>
+# @example
+# ....
+# @example
+#
+#
# Original version by Victor Vagin <vva@mysql.com>
#
-my $cat_name= "";
-my $func_name= "";
-my $text= "";
-my $example= "";
+use strict;
+use Getopt::Long;
+
+my $insert_portion_size= 25;
+my $error_prefix= "help parsing error:";
+
+my $path_to_lex_file= "../sql/lex.h";
+my $verbose_option= 0;
+my $help_option= 0;
+
+GetOptions(
+ "help",\$help_option,
+ "verbose",\$verbose_option,
+ "lexems=s",\$path_to_lex_file
+);
+
+if ($help_option ne 0)
+{
+ print <<_HELP;
+
+This script generates the SQL statements required by mysql_install_db to
+fill up the tables for the server-side online function help, which can be
+invoked with "help <function>" from the MySQL client.
+
+Usage:
+ fill_help_tables OPTIONS < manual.texi > fill_help_tables.sql
+
+ --help display this helpscreen and exit
+ --verbose print information about help completeness to STDERR
+ --lexems=path path to file with lexems. it is used with verbose option.
+ default value is ../sql/lex.h
+
+Examples:
+ ./fill_help_tables --help
+ ./fill_help_tables --verbose < manual.texi > fill_help_tables.sql
+ ./fill_help_tables < manual.texi > fill_help_tables.sql
+
+_HELP
+ exit;
+}
-local $mode= "";
+my $current_category= "";
+my $current_parent_category= "";
+my $next_example_for_topic= "";
+
+my %topics;
+my %categories;
+my %keywords;
+
+$categories{Contents}->{__parent_category__}= "";
+
+sub add_topic_to_category
+{
+ my ($topic_name)= @_;
+
+ $categories{$current_category}->{$topic_name}= $topics{$topic_name};
+ my $category= $categories{$current_category};
+
+ if (exists($category->{__parent_category__}))
+ {
+ my $old_parent= $category->{__parent_category__};
+ if ($old_parent ne $current_parent_category)
+ {
+ print STDERR "$error_prefix wrong parent for $current_category\n";
+ }
+ }
+
+ if ($current_parent_category ne "")
+ {
+ $category->{__parent_category__}= $current_parent_category;
+ }
+
+ if (exists($topics{$topic_name}->{category}))
+ {
+ my $old_category= $topics{$topic_name}->{category};
+ if ($old_category ne $category)
+ {
+ print STDERR "$error_prefix wrong category for $topic_name\n";
+ }
+ }
+
+ $topics{$topic_name}->{category}= $category;
+}
+
+sub add_example
+{
+ my ($topic_name,$example)= @_;
+
+ $topic_name=~ tr/a-z/A-Z/;
+
+ if (exists($topics{$topic_name}->{example}))
+ {
+ print STDERR "$error_prefix double example for $topic_name\n";
+ }
+
+ $topics{$topic_name}->{example}= $example;
+ add_topic_to_category($topic_name);
+}
+
+sub add_description
+{
+ my ($topic_name,$description)= @_;
+
+ $topic_name=~ tr/a-z/A-Z/;
+
+ if (exists($topics{$topic_name}->{description}))
+ {
+ print STDERR "$error_prefix double description for $topic_name\n";
+ }
+ $topics{$topic_name}->{description}= $description;
+ add_topic_to_category($topic_name);
+}
+
+sub add_keyword
+{
+ my ($topic_name,$keyword)= @_;
+
+ $topic_name=~ tr/a-z/A-Z/;
+ $keyword=~ tr/a-z/A-Z/;
+
+ push(@{$topics{$topic_name}->{keywords}},$keyword);
+ if (exists($keywords{$keyword}->{$topic_name}))
+ {
+ print STDERR "$error_prefix double keyword $keyword for $topic_name\n";
+ }
+ $keywords{$keyword}->{$topic_name}= $topics{$topic_name};
+}
sub prepare_name
{
my ($a)= @_;
-
+
$a =~ s/(\@itemize \@bullet)/ /g;
$a =~ s/(\@end itemize)/ /g;
$a =~ s/(\@end multitable)/ /g;
@@ -46,41 +193,57 @@ sub prepare_name
$a =~ s/\`/\`\`/g;
$a =~ s/\@table \@code/ /g;
-
$a =~ s/\(\)//g;
-
- $a =~ s/((\w|\s)+)\(([\+-=><\/%*!<>\s]+)\)/$3/gxs; #$a =~ s/((\w|\s)+)\(([\+-=><\/%*!<>\s]+)\)/$3 $1/gxs;
- $a =~ s/([\+-=><\/%*!<>\s]+)\(((\w|\s)+)\)/$1/gxs;#$a =~ s/([\+-=><\/%*!<>\s]+)\(((\w|\s)+)\)/$1 $2/gxs;
+ $a =~ s/\"/\\\"/g;
+
+ $a =~ s/((\w|\s)+)\(([\+-=><\/%*!<>\s]+)\)/$3/gxs;
+ $a =~ s/([\+-=><\/%*!<>\s]+)\(((\w|\s)+)\)/$1/gxs;
$a =~ s/((\w|\s)+)\((.+)\)/$1/gxs;
-
+
return $a;
}
-sub prepare_text
+sub prepare_description
{
my ($a)= @_;
- $a =~ s/(\@itemize \@bullet)/ /g;
- $a =~ s/(\@end itemize)/ /g;
+ $a =~ s/(\@itemize \@bullet\n)//g;
+ $a =~ s/(\@c help_keyword (.*?)\n)//g;
+ $a =~ s/(\@end itemize\n)//g;
+ $a =~ s/(\@end example\n)//g;
+ $a =~ s/(\@example\n)//g;
+ $a =~ s/(\@{)/{/g;
+ $a =~ s/(\@})/}/g;
$a =~ s/(\@end multitable)/ /g;
$a =~ s/(\@end table)/ /g;
- $a =~ s/(\@cindex(.*?)\n)/ /g;
+ $a =~ s/(\@cindex(.*?)\n)//g;
+ $a =~ s/(\@findex(.*?)\n)//g;
+ $a =~ s/(\@table(.*?)\n)//g;
$a =~ s/(\@multitable \@columnfractions(.*?)\n)/ /g;
$a =~ s/(\@node(.*?)\n)/ /g;
$a =~ s/(\@tab)/\t/g;
$a =~ s/\@itemx/ /g;
- $a =~ s/\@item/ /g;
+ $a =~ s/(\@item\n(\s*?))(\S)/ --- $3/g;
+ $a =~ s/(\@item)/ /g;
+ $a =~ s/(\@tindex\s(.*?)\n)//g;
+ $a =~ s/(\@c\s(.*?)\n)//g;
$a =~ s/\@code\{((.|\n)+?)\}/$1/go;
$a =~ s/\@strong\{(.+?)\}/$1/go;
$a =~ s/\@samp\{(.+?)\}/$1/go;
$a =~ s/\@emph\{((.|\n)+?)\}/\/$1\//go;
$a =~ s/\@xref\{((.|\n)+?)\}/See also : [$1]/go;
$a =~ s/\@ref\{((.|\n)+?)\}/[$1]/go;
- $a =~ s/\'/\'\'/g;
+ $a =~ s/\@w\{((.|\n)+?)\}/$1/go;
+ $a =~ s/\@strong\{((.|\n)+?)\}/\n!!!!\n$1\n!!!!\n/go;
+ $a =~ s/\@file\{((.|\n)+?)\}/\*$1/go;
$a =~ s/\\/\\\\/g;
- $a =~ s/\`/\`\`/g;
- $a =~ s/(\n*?)$//g;
+ $a =~ s/\n\n$/\n/g;
+ $a =~ s/\n\n$/\n/g;
+ $a =~ s/\n\n$/\n/g;
+ $a =~ s/\n\n$/\n/g;
+ $a =~ s/\n\n$/\n/g;
$a =~ s/\n/\\n/g;
+ $a =~ s/\"/\\\"/g;
$a =~ s/\@table \@code/ /g;
@@ -91,148 +254,291 @@ sub prepare_example
{
my ($a)= @_;
- $a =~ s/\'/\'\'/g;
+ $a =~ s/(^\@c for_help_topic(.*?)\n)//g;
+
$a =~ s/\\/\\\\/g;
- $a =~ s/\`/\`\`/g;
+ $a =~ s/(\@{)/{/g;
+ $a =~ s/(\@})/}/g;
+ $a =~ s/(\@\@)/\@/g;
$a =~ s/(\n*?)$//g;
$a =~ s/\n/\\n/g;
-
+ $a =~ s/\"/\\\"/g;
+
return $a;
}
-sub flush_all
+sub parse_example
{
- my ($mode) = @_;
-
- if ($mode eq ""){return;}
-
- $func_name= prepare_name($func_name);
- $text= prepare_text($text);
- $example= prepare_example($example);
-
- if ($func_name ne "" && $text ne "" && !($func_name =~ /[abcdefghikjlmnopqrstuvwxyz]/)){
- print "INSERT IGNORE INTO help_topic (name,description,example) VALUES (";
- print "'$func_name',";
- print "'$text',";
- print "'$example'";
- print ");\n";
- print "INSERT IGNORE INTO help_relation (help_category_id,help_topic_id) VALUES (\@cur_category,LAST_INSERT_ID());\n";
+ return if (!($_=~/\@example/));
+ return if ($next_example_for_topic eq "");
+
+ my $topic_name= $next_example_for_topic;
+ $next_example_for_topic= "";
+ my $text= "";
+
+ while (<>)
+ {
+ last if ($_=~/\@end example/);
+ $text .= $_;
}
+
+ $text= prepare_example($text);
- $func_name= "";
- $text= "";
- $example= "";
- $mode= "";
+ add_example($topic_name,$text) if ($topic_name ne "");
}
-sub new_category
+sub parse_example_for_topic
{
- my ($category)= @_;
-
- $category= prepare_text($category);
-
- print "INSERT IGNORE INTO help_category (name) VALUES (\'$category\');\n";
- print "SET \@cur_category=LAST_INSERT_ID();\n";
+ my ($for_topic)= m|\@c example_for_help_topic (.+?)$|;
+ return if ($for_topic eq "");
+
+ $next_example_for_topic= $for_topic;
}
-#print "INSERT IGNORE INTO db (Host,DB,User,Select_priv) VALUES ('%','mysql_help','','Y');\n";
-#print "CREATE DATABASE mysql_help;\n";
+sub parse_description
+{
+ my ($topic_description)= m|\@c description_for_help_topic (.+?)$|;
+ return if ($topic_description eq "");
+
+ my ($topic_name,$topic_keywords)= split(/ /,$topic_description);
+
+ if ($topic_name eq "" || $topic_keywords eq "")
+ {
+ $topic_name= $topic_description;
+ }
+ else
+ {
+ my $keyword;
+ foreach $keyword (split(/ /,$topic_keywords))
+ {
+ add_keyword($topic_name,$keyword) if ($keyword ne "");
+ }
+ }
+
+ my $text= "";
+
+ while (<>)
+ {
+ last if ($_=~/\@c end_description_for_help_topic/);
+ $text .= $_;
+ }
+
+ $text= prepare_description($text);
+ add_description($topic_name,$text);
+}
-print "USE mysql;\n";
+sub parse_category
+{
+ my ($c_name,$pc_name)= m|\@c help_category (.+?)\@(.+?)$|;
-print "DROP TABLE IF EXISTS help_topic;\n";
-print "CREATE TABLE help_topic (";
-print " help_topic_id int unsigned not null auto_increment,";
-print " name varchar(64) not null,";
-print " description text not null,";
-print " example text not null,";
-print " url varchar(128) not null,";
-print " primary key (help_topic_id),";
-print " unique index(name)";
-print ") type=myisam;\n\n";
+ if ($pc_name ne "")
+ {
+ $current_category= prepare_name($c_name);
+ $current_parent_category= prepare_name($pc_name);
+ }
+ else
+ {
+ my ($c_name)=m|\@c help_category (.+?)$|;
+ return if ($c_name eq "");
-print "DROP TABLE IF EXISTS help_category;\n";
-print "CREATE TABLE help_category (";
-print " help_category_id smallint unsigned not null auto_increment,";
-print " name varchar(64) not null,";
-print " url varchar(128) not null,";
-print " primary key (help_category_id),";
-print " unique index (name)";
-print ") type=myisam;\n\n";
+ $current_category= prepare_name($c_name);
+ $current_parent_category= "Contents"
+ }
+}
-print "DROP TABLE IF EXISTS help_relation;\n";
-print "CREATE TABLE help_relation (";
-print" help_topic_id int unsigned not null references help_topic,";
-print" help_category_id smallint unsigned not null references help_category,";
-print" primary key (help_category_id, help_topic_id),";
-print ") type=myisam;\n\n";
+# parse manual:
-print "SET \@cur_category=null;\n\n";
+while (<>)
+{
+ parse_example_for_topic ();
+ parse_example ();
+ parse_description ();
+ parse_category ();
+}
-my $in_section_6_3= 0;
+# test results of parsing:
-for(<>)
+sub print_bad_names
{
- if ($_=~/\@section Functions for Use in \@code{SELECT} and \@code{WHERE} Clauses/ &&
- !$in_section_6_3){
- $in_section_6_3= 1;
- next;
+ my($names,$prompt)= @_;
+ if (scalar(@{$names}))
+ {
+ print STDERR "\n-------------- $prompt : \n\n";
+ my $name;
+ foreach $name (@{$names})
+ {
+ print STDERR "$name\n";
+ }
+ print STDERR "\n";
}
+}
- if ($_=~/\@section/ && $in_section_6_3){
- $in_section_6_3= 0;
- next;
+sub print_verbose_errors
+{
+ my($name_of_log_file)= @_;
+
+ my @without_help;
+ my @description_with_at;
+ my @example_with_at;
+ my @without_description;
+ my @without_example;
+
+ print STDERR "\n-------------- parameters of help completeness : \n\n";
+
+ my $count_lex= 0;
+ if (!open (TLEX,"<$path_to_lex_file"))
+ {
+ print STDERR "Error opening lex file \"$path_to_lex_file\" $!\n";
}
+ else
+ {
+ for (<TLEX>)
+ {
+ my ($a,$lex,$b)=m|(.+?)\"(.+?)\"(.+?)$|;
+ next if ($lex eq "");
+ $count_lex++;
+ next if (exists($topics{$lex}) || exists($keywords{$lex}));
+ push(@without_help,$lex);
+ }
+ close(TLEX);
+ print STDERR "number of lexems in \"$path_to_lex_file\" - $count_lex\n";
+ }
+
+ my $name;
+ my @topic_names= keys(%topics);
+ foreach $name (@topic_names)
+ {
+ my $topic= $topics{$name};
+ push(@description_with_at,$name) if ($topic->{description}=~/\@/);
+ push(@example_with_at,$name) if ($topic->{example}=~/\@/);
+ push(@without_description,$name) if (!exists($topic->{description}));
+ push(@without_example,$name) if (!exists($topic->{example}));
+ }
+
+ my $count_categories= scalar(keys(%categories));
+ print STDERR "number of help categories - ",$count_categories,"\n";
+ my $count_topics= scalar(@topic_names);
+ print STDERR "number of help topics - ",$count_topics,"\n";
+ my $count_keywords= scalar(keys(%keywords));
+ print STDERR "number of help keywords - ",$count_keywords,"\n";
+
+ my $count_without_help= scalar(@without_help);
+ print_bad_names(\@without_help,"lexems without help (".
+ $count_without_help." ~ ".
+ (int (($count_without_help/$count_lex)*100)).
+ "%)");
+ print_bad_names(\@description_with_at,
+ " topics below have symbol \'@\' in their descriptions.\n".
+ "it's probably the litter from 'texi' tags (script needs fixing)");
+ print_bad_names(\@example_with_at,
+ " topics below have symbol \'@\' in their examples.\n".
+ "it's probably the litter from 'texi' tags (script needs fixing)");
+ print_bad_names(\@without_description,"topics without description");
+
+ my $count_without_example= scalar(@without_example);
+ print_bad_names(\@without_example,"topics without example (".
+ $count_without_example." ~ ".
+ (int (($count_without_example/$count_topics)*100)).
+ "%)");
+}
- if (!$in_section_6_3) { next; }
+print_verbose_errors if ($verbose_option ne 0);
- my $c_name= "";
+# output result
- ($c_name)=m|\@c for_mysql_help,(.+?)$|;
- if (!($c_name eq "") && ! ($c_name =~ m/$cat_name/i)){
- ($cat_name)= $c_name;
- new_category($cat_name);
- next;
+sub print_insert_header
+{
+ my($count,$header)= @_;
+
+ if ($count % $insert_portion_size ne 0) {
+ print ",";
+ } else {
+ print ";\n" if ($count ne 0);
+ print "$header";
}
+}
- ($c_name)=m|\@subsubsection (.+?)$|;
- if (!($c_name eq "") && ! ($c_name =~ m/$cat_name/i)){
- ($cat_name)= $c_name;
- new_category($cat_name);
- next;
- }
+print "delete from help_topic;\n";
+print "delete from help_category;\n";
+print "delete from help_keyword;\n";
+print "delete from help_relation;\n\n";
- ($c_name)=m|\@subsection (.+?)$|;
- if (!($c_name eq "") && ! ($c_name =~ m/$cat_name/i)){
- ($cat_name)= $c_name;
- new_category($cat_name);
- next;
+my @category_names= keys(%categories);
+if (scalar(@category_names))
+{
+ my $cat_name;
+ my $count= 0;
+ foreach $cat_name (@category_names)
+ {
+ $categories{$cat_name}->{__id__}= $count;
+ $count++;
}
- ($f_name)=m|\@findex (.+?)$|;
- if (!($f_name eq "")){
- flush_all($mode);
- ($func_name)= ($f_name);
- $mode= "text";
- next;
+ my $header= "insert into help_category ".
+ "(help_category_id,name,parent_category_id) values ";
+ $count= 0;
+ foreach $cat_name (@category_names)
+ {
+ print_insert_header($count,$header);
+ my $parent_cat_name= $categories{$cat_name}->{__parent_category__};
+ my $parent_cat_id= $parent_cat_name eq ""
+ ? "-1" : $categories{$parent_cat_name}->{__id__};
+ print "($count,\"$cat_name\",$parent_cat_id)";
+ $count++;
}
+ printf ";\n\n";
+}
- if ($_=~/\@example/ && ($mode eq "text")){
- $mode= "example";
- next;
+my @topic_names= keys(%topics);
+if (scalar(@topic_names))
+{
+ my $header= "insert into help_topic ".
+ "(help_topic_id,help_category_id,name,description,example) values ";
+ my $topic_name;
+ my $count= 0;
+ foreach $topic_name (@topic_names)
+ {
+ print_insert_header($count,$header);
+ my $topic= $topics{$topic_name};
+ print "($count,";
+ print "$topic->{category}->{__id__},";
+ print "\"$topic_name\",";
+ print "\"$topic->{description}\",";
+ print "\"$topic->{example}\")";
+ $topics{$topic_name}->{__id__}= $count;
+ $count++;
}
+ printf ";\n\n";
+}
- if ($_=~/\@end example/ && ($mode eq "example")){
- flush_all($mode);
- next;
+my @keywords_names= keys(%keywords);
+if (scalar(@keywords_names))
+{
+ my $header= "insert into help_keyword (help_keyword_id,name) values ";
+ my $keyword_name;
+ my $count= 0;
+ foreach $keyword_name (@keywords_names)
+ {
+ print_insert_header($count,$header);
+ print "($count,\"$keyword_name\")";
+ $count++;
}
-
- if ($mode eq "text") { $text .= $_; }
- if ($mode eq "example") { $example .= $_; }
+ printf ";\n\n";
+
+ $header= "insert into help_relation ".
+ "(help_topic_id,help_keyword_id) values ";
+ $count= 0;
+ my $count_keyword= 0;
+ foreach $keyword_name (@keywords_names)
+ {
+ my $topic_name;
+ foreach $topic_name (keys(%{$keywords{$keyword_name}}))
+ {
+ print_insert_header($count,$header);
+ print "($topics{$topic_name}->{__id__},$count_keyword)";
+ $count++;
+ }
+ $count_keyword++;
+ }
+ printf ";\n\n";
}
-
-
-print "DELETE help_category ";
-print "FROM help_category ";
-print "LEFT JOIN help_relation ON help_category.help_category_id=help_relation.help_category_id ";
-print "WHERE help_relation.help_category_id is null;"
diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh
new file mode 100644
index 00000000000..c54394305cd
--- /dev/null
+++ b/scripts/mysql_create_system_tables.sh
@@ -0,0 +1,311 @@
+#!/bin/sh
+
+# Copyright (C) 1997-2002 MySQL AB
+# For a more info consult the file COPYRIGHT distributed with this file
+
+# This script writes on stdout SQL commands to generate all not
+# existing MySQL system tables. It also replaces the help tables with
+# new context from the manual (from fill_help_tables.sql).
+
+# $1 - "test" or "real" or "verbose" variant of database
+# $2 - path to mysql-database directory
+# $3 - hostname
+# $4 - windows option
+
+if test x$1 = x"" ;
+then
+ echo "
+This script writes on stdout SQL commands to generate all not
+existing MySQL system tables. It also replaces the help tables with
+new context from the manual (from fill_help_tables.sql).
+
+Usage:
+ mysql_create_system_tables {help|real|verbose} <path to mysql-database directory> <hostname> <windows option>
+";
+ exit;
+fi
+
+mdata=$2
+hostname=$3
+windows=$4
+
+# Initialize variables
+c_d="" i_d=""
+c_h="" i_h=""
+c_u="" i_u=""
+c_f="" i_f=""
+c_t="" c_c=""
+c_ht=""
+c_hc=""
+c_hr=""
+c_hk=""
+i_ht=""
+
+# Check for old tables
+if test ! -f $mdata/db.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing db table" 1>&2;
+ fi
+
+ # mysqld --bootstrap wants one command/line
+ c_d="$c_d CREATE TABLE db ("
+ c_d="$c_d Host char(60) binary DEFAULT '' NOT NULL,"
+ c_d="$c_d Db char(64) binary DEFAULT '' NOT NULL,"
+ c_d="$c_d User char(16) binary DEFAULT '' NOT NULL,"
+ c_d="$c_d Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_d="$c_d PRIMARY KEY Host (Host,Db,User),"
+ c_d="$c_d KEY User (User)"
+ c_d="$c_d )"
+ c_d="$c_d comment='Database privileges';"
+
+ i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
+ INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');"
+fi
+
+if test ! -f $mdata/host.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing host table" 1>&2;
+ fi
+
+ c_h="$c_h CREATE TABLE host ("
+ c_h="$c_h Host char(60) binary DEFAULT '' NOT NULL,"
+ c_h="$c_h Db char(64) binary DEFAULT '' NOT NULL,"
+ c_h="$c_h Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_h="$c_h PRIMARY KEY Host (Host,Db)"
+ c_h="$c_h )"
+ c_h="$c_h comment='Host privileges; Merged with database privileges';"
+fi
+
+if test ! -f $mdata/user.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing user table" 1>&2;
+ fi
+
+ c_u="$c_u CREATE TABLE user ("
+ c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u User char(16) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u Password char(45) binary DEFAULT '' NOT NULL,"
+ c_u="$c_u Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Process_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u File_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
+ c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
+ c_u="$c_u ssl_cipher BLOB NOT NULL,"
+ c_u="$c_u x509_issuer BLOB NOT NULL,"
+ c_u="$c_u x509_subject BLOB NOT NULL,"
+ c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
+ c_u="$c_u PRIMARY KEY Host (Host,User)"
+ c_u="$c_u )"
+ c_u="$c_u comment='Users and global privileges';"
+
+ if test x$1 = x"test"
+ then
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user (host,user) values ('localhost','');
+ INSERT INTO user (host,user) values ('$hostname','');"
+ else
+ i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user (host,user) values ('localhost','');"
+ if test "$windows" -eq 0
+ then
+ i_u="$i_u
+ INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
+ INSERT INTO user (host,user) values ('$hostname','');"
+ fi
+ fi
+fi
+
+if test ! -f $mdata/func.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing func table" 1>&2;
+ fi
+
+ c_f="$c_f CREATE TABLE func ("
+ c_f="$c_f name char(64) binary DEFAULT '' NOT NULL,"
+ c_f="$c_f ret tinyint(1) DEFAULT '0' NOT NULL,"
+ c_f="$c_f dl char(128) DEFAULT '' NOT NULL,"
+ c_f="$c_f type enum ('function','aggregate') NOT NULL,"
+ c_f="$c_f PRIMARY KEY (name)"
+ c_f="$c_f )"
+ c_f="$c_f comment='User defined functions';"
+fi
+
+if test ! -f $mdata/tables_priv.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing tables_priv table" 1>&2;
+ fi
+
+ c_t="$c_t CREATE TABLE tables_priv ("
+ c_t="$c_t Host char(60) binary DEFAULT '' NOT NULL,"
+ c_t="$c_t Db char(64) binary DEFAULT '' NOT NULL,"
+ c_t="$c_t User char(16) binary DEFAULT '' NOT NULL,"
+ c_t="$c_t Table_name char(60) binary DEFAULT '' NOT NULL,"
+ c_t="$c_t Grantor char(77) DEFAULT '' NOT NULL,"
+ c_t="$c_t Timestamp timestamp(14),"
+ c_t="$c_t Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL,"
+ c_t="$c_t Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,"
+ c_t="$c_t PRIMARY KEY (Host,Db,User,Table_name),"
+ c_t="$c_t KEY Grantor (Grantor)"
+ c_t="$c_t )"
+ c_t="$c_t comment='Table privileges';"
+fi
+
+if test ! -f $mdata/columns_priv.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing columns_priv table" 1>&2;
+ fi
+
+ c_c="$c_c CREATE TABLE columns_priv ("
+ c_c="$c_c Host char(60) binary DEFAULT '' NOT NULL,"
+ c_c="$c_c Db char(64) binary DEFAULT '' NOT NULL,"
+ c_c="$c_c User char(16) binary DEFAULT '' NOT NULL,"
+ c_c="$c_c Table_name char(64) binary DEFAULT '' NOT NULL,"
+ c_c="$c_c Column_name char(64) binary DEFAULT '' NOT NULL,"
+ c_c="$c_c Timestamp timestamp(14),"
+ c_c="$c_c Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,"
+ c_c="$c_c PRIMARY KEY (Host,Db,User,Table_name,Column_name)"
+ c_c="$c_c )"
+ c_c="$c_c comment='Column privileges';"
+fi
+
+if test ! -f $mdata/help_topic.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing help_topic table" 1>&2;
+ fi
+
+ c_ht="$c_ht CREATE TABLE help_topic ("
+ c_ht="$c_ht help_topic_id int unsigned not null,"
+ c_ht="$c_ht name varchar(64) not null,"
+ c_ht="$c_ht help_category_id smallint unsigned not null,"
+ c_ht="$c_ht description text not null,"
+ c_ht="$c_ht example text not null,"
+ c_ht="$c_ht url varchar(128) not null,"
+ c_ht="$c_ht primary key (help_topic_id),"
+ c_ht="$c_ht unique index (name)"
+ c_ht="$c_ht )"
+ c_ht="$c_ht comment='help topics';"
+fi
+
+old_categories="yes"
+
+if test ! -f $mdata/help_category.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing help_category table" 1>&2;
+ fi
+
+ c_hc="$c_hc CREATE TABLE help_category ("
+ c_hc="$c_hc help_category_id smallint unsigned not null,"
+ c_hc="$c_hc name varchar(64) not null,"
+ c_hc="$c_hc parent_category_id smallint unsigned null,"
+ c_hc="$c_hc url varchar(128) not null,"
+ c_hc="$c_hc primary key (help_category_id),"
+ c_hc="$c_hc unique index (name)"
+ c_hc="$c_hc )"
+ c_hc="$c_hc comment='help categories';"
+fi
+
+if test ! -f $mdata/help_keyword.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing help_keyword table" 1>&2;
+ fi
+
+ c_hk="$c_hk CREATE TABLE help_keyword ("
+ c_hk="$c_hk help_keyword_id int unsigned not null,"
+ c_hk="$c_hk name varchar(64) not null,"
+ c_hk="$c_hk primary key (help_keyword_id),"
+ c_hk="$c_hk unique index (name)"
+ c_hk="$c_hk )"
+ c_hk="$c_hk comment='help keywords';"
+fi
+
+if test ! -f $mdata/help_relation.frm
+then
+ if test x$1 = x"verbose" ; then
+ echo "Preparing help_relation table" 1>&2;
+ fi
+
+ c_hr="$c_hr CREATE TABLE help_relation ("
+ c_hr="$c_hr help_topic_id int unsigned not null references help_topic,"
+ c_hr="$c_hr help_keyword_id int unsigned not null references help_keyword,"
+ c_hr="$c_hr primary key (help_keyword_id, help_topic_id)"
+ c_hr="$c_hr )"
+ c_hr="$c_hr comment='keyword-topic relation';"
+fi
+
+cat << END_OF_DATA
+use mysql;
+$c_d
+$i_d
+
+$c_h
+$i_h
+
+$c_u
+$i_u
+
+$c_f
+$i_f
+
+$c_t
+$c_c
+
+$c_ht
+$c_hc
+$c_hr
+$c_hk
+END_OF_DATA
+
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 15bc834e850..96e33d3e7c5 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -87,7 +87,7 @@ if test -z "$basedir"
then
basedir=@prefix@
bindir=@bindir@
- execdir=@libexecdir@
+ execdir=@libexecdir@
pkgdatadir=@pkgdatadir@
else
bindir="$basedir/bin"
@@ -100,24 +100,24 @@ else
else
execdir="$basedir/bin"
fi
-
- # find fill_help_tables.sh
- for i in $basedir/support-files $basedir/share $basedir/share/mysql $basedir/scripts @pkgdatadir@
- do
- if test -f $i/fill_help_tables.sql
- then
- pkgdatadir=$i
- fi
- done
fi
+# find fill_help_tables.sh
+for i in $basedir/support-files $basedir/share $basedir/share/mysql $basedir/scripts `pwd` @pkgdatadir@
+do
+ if test -f $i/fill_help_tables.sql
+ then
+ pkgdatadir=$i
+ fi
+done
+
if test -f $pkgdatadir/fill_help_tables.sql
then
fill_help_tables=$pkgdatadir/fill_help_tables.sql
else
if test $verbose -eq 1
then
- echo "Could not find help file 'fill_help_tables.sql'".
+ echo "Could not find help file 'fill_help_tables.sql' ;$pkgdatadir; ;$basedir;".
fi
fi
@@ -172,205 +172,21 @@ fi
chown $user $ldata $ldata/mysql $ldata/test;
fi
-# Initialize variables
-c_d="" i_d=""
-c_h="" i_h=""
-c_u="" i_u=""
-c_f="" i_f=""
-c_t="" c_c=""
-
-# Check for old tables
if test ! -f $mdata/db.frm
then
- if test $verbose -eq 1 ; then
- echo "Preparing db table"
- fi
- # mysqld --bootstrap wants one command/line
- c_d="$c_d CREATE TABLE db ("
- c_d="$c_d Host char(60) binary DEFAULT '' NOT NULL,"
- c_d="$c_d Db char(64) binary DEFAULT '' NOT NULL,"
- c_d="$c_d User char(16) binary DEFAULT '' NOT NULL,"
- c_d="$c_d Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_d="$c_d PRIMARY KEY Host (Host,Db,User),"
- c_d="$c_d KEY User (User)"
- c_d="$c_d )"
- c_d="$c_d comment='Database privileges';"
-
- i_d="INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
- INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');"
-fi
-
-if test ! -f $mdata/host.frm
-then
- if test $verbose -eq 1 ; then
- echo "Preparing host table"
- fi
-
- c_h="$c_h CREATE TABLE host ("
- c_h="$c_h Host char(60) binary DEFAULT '' NOT NULL,"
- c_h="$c_h Db char(64) binary DEFAULT '' NOT NULL,"
- c_h="$c_h Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_h="$c_h PRIMARY KEY Host (Host,Db)"
- c_h="$c_h )"
- c_h="$c_h comment='Host privileges; Merged with database privileges';"
+ c_d="yes"
fi
-if test ! -f $mdata/user.frm
+if test $verbose -eq 1
then
- if test $verbose -eq 1 ; then
- echo "Preparing user table"
- fi
-
- c_u="$c_u CREATE TABLE user ("
- c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL,"
- c_u="$c_u User char(16) binary DEFAULT '' NOT NULL,"
- c_u="$c_u Password char(45) binary DEFAULT '' NOT NULL,"
- c_u="$c_u Select_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Update_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Create_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Process_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u File_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
- c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL,"
- c_u="$c_u ssl_cipher BLOB NOT NULL,"
- c_u="$c_u x509_issuer BLOB NOT NULL,"
- c_u="$c_u x509_subject BLOB NOT NULL,"
- c_u="$c_u max_questions int(11) unsigned DEFAULT 0 NOT NULL,"
- c_u="$c_u max_updates int(11) unsigned DEFAULT 0 NOT NULL,"
- c_u="$c_u max_connections int(11) unsigned DEFAULT 0 NOT NULL,"
- c_u="$c_u PRIMARY KEY Host (Host,User)"
- c_u="$c_u )"
- c_u="$c_u comment='Users and global privileges';"
-
- i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
-
- REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
-
- INSERT INTO user (host,user) values ('localhost','');
-"
-
- if test "$windows" -eq 0
- then
- i_u="$i_u INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
-
- REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
-
- INSERT INTO user (host,user) values ('$hostname','');"
- fi
-fi
-
-if test ! -f $mdata/func.frm
-then
- if test $verbose -eq 1 ; then
- echo "Preparing func table"
- fi
-
- c_f="$c_f CREATE TABLE func ("
- c_f="$c_f name char(64) binary DEFAULT '' NOT NULL,"
- c_f="$c_f ret tinyint(1) DEFAULT '0' NOT NULL,"
- c_f="$c_f dl char(128) DEFAULT '' NOT NULL,"
- c_f="$c_f type enum ('function','aggregate') NOT NULL,"
- c_f="$c_f PRIMARY KEY (name)"
- c_f="$c_f )"
- c_f="$c_f comment='User defined functions';"
-fi
-
-if test ! -f $mdata/tables_priv.frm
-then
- if test $verbose -eq 1 ; then
- echo "Preparing tables_priv table"
- fi
-
- c_t="$c_t CREATE TABLE tables_priv ("
- c_t="$c_t Host char(60) binary DEFAULT '' NOT NULL,"
- c_t="$c_t Db char(64) binary DEFAULT '' NOT NULL,"
- c_t="$c_t User char(16) binary DEFAULT '' NOT NULL,"
- c_t="$c_t Table_name char(60) binary DEFAULT '' NOT NULL,"
- c_t="$c_t Grantor char(77) DEFAULT '' NOT NULL,"
- c_t="$c_t Timestamp timestamp(14),"
- c_t="$c_t Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL,"
- c_t="$c_t Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,"
- c_t="$c_t PRIMARY KEY (Host,Db,User,Table_name),"
- c_t="$c_t KEY Grantor (Grantor)"
- c_t="$c_t )"
- c_t="$c_t comment='Table privileges';"
-fi
-
-if test ! -f $mdata/columns_priv.frm
-then
- if test $verbose -eq 1 ; then
- echo "Preparing columns_priv table"
- fi
-
- c_c="$c_c CREATE TABLE columns_priv ("
- c_c="$c_c Host char(60) binary DEFAULT '' NOT NULL,"
- c_c="$c_c Db char(64) binary DEFAULT '' NOT NULL,"
- c_c="$c_c User char(16) binary DEFAULT '' NOT NULL,"
- c_c="$c_c Table_name char(64) binary DEFAULT '' NOT NULL,"
- c_c="$c_c Column_name char(64) binary DEFAULT '' NOT NULL,"
- c_c="$c_c Timestamp timestamp(14),"
- c_c="$c_c Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL,"
- c_c="$c_c PRIMARY KEY (Host,Db,User,Table_name,Column_name)"
- c_c="$c_c )"
- c_c="$c_c comment='Column privileges';"
+ create_option="verbose"
+else
+ create_option="real"
fi
-echo "Installing privilege tables"
+echo "Installing all prepared tables"
if (
- cat << END_OF_DATA
-use mysql;
-$c_d
-$i_d
-
-$c_h
-$i_h
-
-$c_u
-$i_u
-
-$c_f
-$i_f
-
-$c_t
-$c_c
-END_OF_DATA
+ mysql_create_system_tables $create_option $mdata $hostname $windows
if test -n "$fill_help_tables"
then
cat $fill_help_tables
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 712c8853a20..a59f1d4b81a 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -877,6 +877,7 @@ bool check_db_name(char *db);
bool check_column_name(const char *name);
bool check_table_name(const char *name, uint length);
char *get_field(MEM_ROOT *mem, Field *field);
+bool get_field(MEM_ROOT *mem, Field *field, class String *res);
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
/* from hostname.cc */
diff --git a/sql/protocol.h b/sql/protocol.h
index 2110f1877c2..ffd61b3e848 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -60,6 +60,8 @@ public:
{ return store_longlong((longlong) from, 0); }
inline bool store(ulonglong from)
{ return store_longlong((longlong) from, 1); }
+ inline bool store(String *str)
+ { return store(str->c_ptr(),str->length(),str->charset()); }
virtual bool prepare_for_send(List<Item> *item_list)
{
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 36c7ef87b17..a9b89a728d2 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -26,74 +26,155 @@ struct st_find_field
static struct st_find_field init_used_fields[]=
{
- { "help_topic", "name", 0},
- { "help_topic","description", 0},
- { "help_topic","example", 0},
- { "help_topic", "help_topic_id", 0},
- { "help_category","name", 0},
- { "help_category","help_category_id", 0},
- { "help_relation","help_topic_id", 0},
- { "help_relation","help_category_id", 0}
+ { "help_topic", "help_topic_id", 0},
+ { "help_topic", "name", 0},
+ { "help_topic", "help_category_id", 0},
+ { "help_topic", "description", 0},
+ { "help_topic", "example", 0},
+
+ { "help_category", "help_category_id", 0},
+ { "help_category", "parent_category_id", 0},
+ { "help_category", "name", 0},
+
+ { "help_keyword", "help_keyword_id", 0},
+ { "help_keyword", "name", 0},
+
+ { "help_relation", "help_topic_id", 0},
+ { "help_relation", "help_keyword_id", 0}
};
enum enum_used_fields
{
- help_topic_name=0, help_topic_description, help_topic_example,
- help_topic_help_topic_id,
- help_category_name, help_category_help_category_id,
- help_relation_help_topic_id, help_relation_help_category_id
+ help_topic_help_topic_id= 0,
+ help_topic_name,
+ help_topic_help_category_id,
+ help_topic_description,
+ help_topic_example,
+
+ help_category_help_category_id,
+ help_category_parent_category_id,
+ help_category_name,
+
+ help_keyword_help_keyword_id,
+ help_keyword_name,
+
+ help_relation_help_topic_id,
+ help_relation_help_keyword_id
};
/*
- Fill local used field structure with pointer to fields */
+ Fill st_find_field structure with pointers to fields
+
+ SYNOPSIS
+ init_fields()
+ thd Thread handler
+ tables list of all tables for fields
+ find_fields array of structures
+ count size of previous array
+
+ RETURN VALUES
+ 0 all ok
+ 1 one of the fileds didn't finded
+*/
static bool init_fields(THD *thd, TABLE_LIST *tables,
- struct st_find_field *find_field,
- uint count)
+ struct st_find_field *find_fields, uint count)
{
- for (; count-- ; find_field++)
+ DBUG_ENTER("init_fields");
+ for (; count-- ; find_fields++)
{
TABLE_LIST *not_used;
/* We have to use 'new' here as field will be re_linked on free */
- Item_field *field= new Item_field("mysql", find_field->table_name,
- find_field->field_name);
- if (!(find_field->field= find_field_in_tables(thd, field, tables,
- &not_used,
- TRUE)))
- return 1;
+ 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,
+ &not_used, TRUE)))
+ DBUG_RETURN(1);
}
- return 0;
+ DBUG_RETURN(0);
}
+/*
+
+ Returns variants of found topic for help (if it is just single topic,
+ returns description and example, or else returns only names..)
+
+ SYNOPSIS
+ memorize_variant_topic()
+
+ thd Thread handler
+ topics Table of topics
+ count number of alredy found topics
+ find_fields Filled array of information for work with fields
+
+ RETURN VALUES
+ names array of names of found topics (out)
-#define help_charset &my_charset_latin1
+ 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 is found.
+ 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,
+ List<String> *names,
+ String *name, String *description, String *example)
+{
+ DBUG_ENTER("memorize_variant_topic");
+ MEM_ROOT *mem_root= &thd->mem_root;
+ if (count==0)
+ {
+ get_field(mem_root,find_fields[help_topic_name].field, name);
+ get_field(mem_root,find_fields[help_topic_description].field, description);
+ get_field(mem_root,find_fields[help_topic_example].field, example);
+ }
+ else
+ {
+ if (count==1)
+ names->push_back(name);
+ String *new_name= new String;
+ get_field(mem_root,find_fields[help_topic_name].field,new_name);
+ names->push_back(new_name);
+ }
+ DBUG_VOID_RETURN;
+}
/*
Look for topics by mask
SYNOPSIS
search_topics()
- thd Thread handler
- topics Table of topic
- select Function to test for if matching help topic.
- Normally 'help_topic.name like 'bit%'
- pfname Pointer to Field structure for field "name"
- names List of founded topic's names (out)
- name Name of founded topic (out),
- Only set if founded exactly one topic)
- description Description of founded topic (out)
- Only set if founded exactly one topic.
- example Example for founded topic (out)
- Only if founded exactly one topic.
+ thd Thread handler
+ topics Table of topics
+ find_fields Filled array of info for fields
+ select Function to test for matching help topic.
+ Normally 'help_topic.name like 'bit%'
+
RETURN VALUES
- # number of topics founded
+ # number of topics found
+
+ names array of names 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(THD *thd, TABLE *topics, struct st_find_field *find_field,
- SQL_SELECT *select, List<char> *names,
- char **name, char **description, char **example)
+int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields,
+ SQL_SELECT *select, List<String> *names,
+ String *name, String *description, String *example)
{
- DBUG_ENTER("search_functions");
+ DBUG_ENTER("search_topics");
int count= 0;
READ_RECORD read_record_info;
@@ -102,139 +183,93 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_field,
{
if (!select->cond->val_int()) // Dosn't match like
continue;
-
- char *lname= get_field(&thd->mem_root, find_field[help_topic_name].field);
+ memorize_variant_topic(thd,topics,count,find_fields,
+ names,name,description,example);
count++;
- if (count > 2)
- {
- names->push_back(lname);
- }
- else if (count == 1)
- {
- *description= get_field(&thd->mem_root,
- find_field[help_topic_description].field);
- *example= get_field(&thd->mem_root,
- find_field[help_topic_example].field);
- *name= lname;
- }
- else
- {
- names->push_back(*name);
- names->push_back(lname);
- *name= 0;
- *description= 0;
- *example= 0;
- }
}
end_read_record(&read_record_info);
+
DBUG_RETURN(count);
}
/*
- Look for categories by mask
+ Look for keyword by mask
SYNOPSIS
- search_categories()
- thd THD for init_read_record
- categories Table of categories
- select Function to test for if matching help topic.
- Normally 'help_topic.name like 'bit%'
- names List of founded topic's names (out)
- res_id Primary index of founded category (only if
- founded exactly one category)
+ search_keyword()
+ thd Thread handler
+ keywords Table of keywords
+ find_fields Filled array of info for fields
+ select Function to test for matching keyword.
+ Normally 'help_keyword.name like 'bit%'
+
+ key_id help_keyword_if of found topics (out)
RETURN VALUES
- # Number of categories founded
+ 0 didn't find any topics matching the mask
+ 1 found exactly one topic matching the mask
+ 2 found more then one topic matching the mask
*/
-int search_categories(THD *thd, TABLE *categories,
- struct st_find_field *find_fields,
- SQL_SELECT *select, List<char> *names, int16 *res_id)
+int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields,
+ SQL_SELECT *select, int *key_id)
{
- Field *pfname= find_fields[help_category_name].field;
- DBUG_ENTER("search_categories");
+ DBUG_ENTER("search_keyword");
int count= 0;
- READ_RECORD read_record_info;
- init_read_record(&read_record_info, thd, categories, select,1,0);
- while (!read_record_info.read_record(&read_record_info))
+ 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)
{
- if (select && !select->cond->val_int())
+ if (!select->cond->val_int()) // Dosn't match like
continue;
- char *lname= get_field(&thd->mem_root,pfname);
- if (++count == 1 && res_id)
- {
- Field *pcat_id= find_fields[help_category_help_category_id].field;
- *res_id= (int16) pcat_id->val_int();
- }
- names->push_back(lname);
+
+ *key_id= find_fields[help_keyword_help_keyword_id].field->val_int();
+
+ count++;
}
end_read_record(&read_record_info);
-
+
DBUG_RETURN(count);
}
-
/*
- Send to client rows in format:
- column1 : <name>
- column2 : <is_it_category>
+ Look for all topics with keyword
SYNOPSIS
- send_variant_2_list()
- protocol Protocol for sending
- names List of names
- cat Value of the column <is_it_category>
+ get_topics_for_keyword()
+ thd Thread handler
+ topics Table of topics
+ relations Table of m:m relation "topic/keyword"
+ find_fields Filled array of info for fields
+ key_id Primary index to use to find for keyword
RETURN VALUES
- -1 Writing fail
- 0 Data was successefully send
-*/
-
-int send_variant_2_list(Protocol *protocol, List<char> *names,
- const char *cat)
-{
- DBUG_ENTER("send_names");
-
- List_iterator<char> it(*names);
- const char *cur_name;
- while ((cur_name= it++))
- {
- protocol->prepare_for_resend();
- protocol->store(cur_name, system_charset_info);
- protocol->store(cat, system_charset_info);
- if (protocol->write())
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
+ # number of topics found
+ names array of name of found topics (out)
-/*
- Look for all topics of category
+ name name of found topic (out)
+ description description of found topic (out)
+ example example for found topic (out)
- SYNOPSIS
- get_all_topics_for_category()
- thd Thread handler
- topics Table of topics
- relations Table of m:m relation "topic/category"
- cat_id Primary index looked for category
- res List of founded topic's names (out)
-
- RETURN VALUES
- -1 corrupt database
- 0 succesefull
+ 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 get_all_topics_for_category(THD *thd, TABLE *topics, TABLE *relations,
- struct st_find_field *find_fields,
- int16 cat_id, List<char> *res)
+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)
{
- char buff[8]; // Max int length
- DBUG_ENTER("get_all_topics_for_category");
-
+ char buff[8]; // Max int length
+ int count= 0;
int iindex_topic, iindex_relations;
- Field *rtopic_id, *rcat_id;
+ Field *rtopic_id, *rkey_id;
+
+ DBUG_ENTER("get_topics_for_keyword");
if ((iindex_topic= find_type((char*) "PRIMARY",
&topics->keynames, 1+2)-1)<0 ||
@@ -245,37 +280,156 @@ int get_all_topics_for_category(THD *thd, TABLE *topics, TABLE *relations,
DBUG_RETURN(-1);
}
rtopic_id= find_fields[help_relation_help_topic_id].field;
- rcat_id= find_fields[help_relation_help_category_id].field;
+ rkey_id= find_fields[help_relation_help_keyword_id].field;
topics->file->index_init(iindex_topic);
relations->file->index_init(iindex_relations);
- rcat_id->store((longlong) cat_id);
- rcat_id->get_key_image(buff, rcat_id->pack_length(), help_charset,
+ 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, rcat_id->pack_length(),
+ (byte *)buff, rkey_id->pack_length(),
HA_READ_KEY_EXACT);
- for ( ; !key_res && cat_id == (int16) rcat_id->val_int() ;
+ for ( ;
+ !key_res && key_id == (int16) rkey_id->val_int() ;
key_res= relations->file->index_next(relations->record[0]))
{
char topic_id_buff[8];
longlong topic_id= rtopic_id->val_int();
Field *field= find_fields[help_topic_help_topic_id].field;
field->store((longlong) topic_id);
- field->get_key_image(topic_id_buff, field->pack_length(), help_charset,
+ 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))
- res->push_back(get_field(&thd->mem_root,
- find_fields[help_topic_name].field));
+ field->pack_length(), HA_READ_KEY_EXACT))
+ {
+ memorize_variant_topic(thd,topics,count,find_fields,
+ names,name,description,example);
+ count++;
+ }
}
- DBUG_RETURN(0);
+ 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
+ search_categories()
+ thd THD for init_read_record
+ categories Table of categories
+ find_fields Filled array of info for fields
+ select Function to test for if matching help topic.
+ Normally 'help_vategory.name like 'bit%'
+ names List of found categories names (out)
+ res_id Primary index of found category (only if
+ found exactly one category)
+
+ RETURN VALUES
+ # Number of categories found
+*/
+
+int search_categories(THD *thd, TABLE *categories,
+ struct st_find_field *find_fields,
+ SQL_SELECT *select, List<String> *names, int16 *res_id)
+{
+ 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;
+
+ DBUG_ENTER("search_categories");
+
+ init_read_record(&read_record_info, thd, categories, select,1,0);
+ while (!read_record_info.read_record(&read_record_info))
+ {
+ if (select && !select->cond->val_int())
+ continue;
+ String *lname= new String;
+ get_field(&thd->mem_root,pfname,lname);
+ if (++count == 1 && res_id)
+ *res_id= (int16) pcat_id->val_int();
+ names->push_back(lname);
+ }
+ end_read_record(&read_record_info);
+
+ DBUG_RETURN(count);
}
+/*
+ Look for all topics or subcategories of category
+
+ SYNOPSIS
+ get_all_items_for_category()
+ thd Thread handler
+ items Table of items
+ pfname Field "name" in items
+ select "where" part of query..
+ res list of finded names
+*/
+
+void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
+ SQL_SELECT *select, List<String> *res)
+{
+ DBUG_ENTER("get_all_items_for_category");
+
+ READ_RECORD read_record_info;
+ 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())
+ continue;
+ String *name= new String();
+ get_field(&thd->mem_root,pfname,name);
+ res->push_back(name);
+ }
+ end_read_record(&read_record_info);
+
+ DBUG_VOID_RETURN;
+}
/*
Send to client answer for help request
@@ -284,17 +438,16 @@ int get_all_topics_for_category(THD *thd, TABLE *topics, TABLE *relations,
send_answer_1()
protocol - protocol for sending
s1 - value of column "Name"
- s2 - value of column "Category"
- s3 - value of column "Description"
- s4 - value of column "Example"
+ s2 - value of column "Description"
+ s3 - value of column "Example"
IMPLEMENTATION
Format used:
- +----------+---------+------------+------------+
- |Name: |Category |Description |Example |
- +----------+---------+------------+------------+
- |String(64)|String(1)|String(1000)|String(1000)|
- +----------+---------+------------+------------+
+ +----------+------------+------------+
+ |name |description |example |
+ +----------+------------+------------+
+ |String(64)|String(1000)|String(1000)|
+ +----------+------------+------------+
with exactly one row!
RETURN VALUES
@@ -303,24 +456,21 @@ int get_all_topics_for_category(THD *thd, TABLE *topics, TABLE *relations,
0 Successeful send
*/
-int send_answer_1(Protocol *protocol, const char *s1, const char *s2,
- const char *s3, const char *s4)
+int send_answer_1(Protocol *protocol, String *s1, String *s2, String *s3)
{
DBUG_ENTER("send_answer_1");
List<Item> field_list;
- field_list.push_back(new Item_empty_string("Name",64));
- field_list.push_back(new Item_empty_string("Category",1));
- field_list.push_back(new Item_empty_string("Description",1000));
- field_list.push_back(new Item_empty_string("Example",1000));
+ 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, system_charset_info);
- protocol->store(s2, system_charset_info);
- protocol->store(s3, system_charset_info);
- protocol->store(s4, system_charset_info);
+ protocol->store(s1);
+ protocol->store(s2);
+ protocol->store(s3);
if (protocol->write())
DBUG_RETURN(-1);
DBUG_RETURN(0);
@@ -332,28 +482,151 @@ int send_answer_1(Protocol *protocol, const char *s1, const char *s2,
SYNOPSIS
send_header_2()
- protocol - protocol for sending
+ protocol - protocol for sending
+ is_it_category - need column 'source_category_name'
IMPLEMENTATION
- +----------+---------+
- |Name: |Category |
- +----------+---------+
- |String(64)|String(1)|
- +----------+---------+
+ +- -+
+ |+-------------------- | +----------+--------------+
+ ||source_category_name | |name |is_it_category|
+ |+-------------------- | +----------+--------------+
+ ||String(64) | |String(64)|String(1) |
+ |+-------------------- | +----------+--------------+
+ +- -+
RETURN VALUES
result of protocol->send_fields
*/
-int send_header_2(Protocol *protocol)
+int send_header_2(Protocol *protocol, bool for_category)
{
- DBUG_ENTER("send_header2");
+ DBUG_ENTER("send_header_2");
List<Item> field_list;
- field_list.push_back(new Item_empty_string("Name",64));
- field_list.push_back(new Item_empty_string("Category",1));
+ if (for_category)
+ field_list.push_back(new Item_empty_string("source_category_name",64));
+ field_list.push_back(new Item_empty_string("name",64));
+ field_list.push_back(new Item_empty_string("is_it_category",1));
DBUG_RETURN(protocol->send_fields(&field_list,1));
}
+/*
+ strcmp for using in qsort
+
+ SYNOPSIS
+ strptrcmp()
+ ptr1 (const void*)&str1
+ ptr2 (const void*)&str2
+
+ RETURN VALUES
+ same as strcmp
+*/
+
+int string_ptr_cmp(const void* ptr1, const void* ptr2)
+{
+ String *str1= *(String**)ptr1;
+ String *str2= *(String**)ptr2;
+ return strcmp(str1->c_ptr(),str2->c_ptr());
+}
+
+/*
+ Send to client rows in format:
+ column1 : <name>
+ column2 : <is_it_category>
+
+ SYNOPSIS
+ send_variant_2_list()
+ protocol Protocol for sending
+ names List of names
+ cat Value of the column <is_it_category>
+ source_name name of category for all items..
+
+ RETURN VALUES
+ -1 Writing fail
+ 0 Data was successefully send
+*/
+
+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");
+
+ String **pointers= (String**)alloc_root(mem_root,
+ sizeof(String*)*names->elements);
+ String **pos= pointers;
+
+ List_iterator<String> it(*names);
+ String *cur_name;
+ while (*pos++= it++);
+
+ qsort(pointers,names->elements,sizeof(String*),string_ptr_cmp);
+
+ String **end= pointers + names->elements;
+ for (String **pos= pointers; pos!=end; pos++)
+ {
+ protocol->prepare_for_resend();
+ if (source_name)
+ protocol->store(source_name);
+ protocol->store(*pos);
+ protocol->store(cat,1,&my_charset_latin1);
+ if (protocol->write())
+ DBUG_RETURN(-1);
+ }
+
+ DBUG_RETURN(0);
+}
+
+/*
+ Prepare simple SQL_SELECT table.* WHERE <Item>
+
+ SYNOPSIS
+ prepare_simple_select()
+ thd Thread handler
+ cond WHERE part of select
+ tables list of tables, used in WHERE
+ table goal table
+
+ error code of error (out)
+
+ RETURN VALUES
+ # created SQL_SELECT
+*/
+
+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(0, HA_POS_ERROR))) ? 0 : res;
+}
+
+/*
+ Prepare simple SQL_SELECT table.* WHERE table.name LIKE mask
+
+ SYNOPSIS
+ prepare_select_for_name()
+ thd Thread handler
+ mask mask for compare with name
+ mlen length of mask
+ tables list of tables, used in WHERE
+ table goal table
+ pfname field "name" in table
+
+ error code of error (out)
+
+ RETURN VALUES
+ # created SQL_SELECT
+*/
+
+SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
+ TABLE_LIST *tables, TABLE *table,
+ Field *pfname, int *error)
+{
+ Item *cond= new Item_func_like(new Item_field(pfname),
+ new Item_string(mask,mlen,pfname->charset()),
+ (char*) "\\");
+ return prepare_simple_select(thd,cond,tables,table,error);
+}
/*
Server-side function 'help'
@@ -371,12 +644,13 @@ int send_header_2(Protocol *protocol)
int mysqld_help(THD *thd, const char *mask)
{
Protocol *protocol= thd->protocol;
- SQL_SELECT *select= 0, *select_cat= 0;
- Item *cond_topic, *cond_cat;
+ 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;
st_find_field used_fields[array_elements(init_used_fields)];
DBUG_ENTER("mysqld_help");
- TABLE_LIST tables[3];
+ TABLE_LIST tables[4];
bzero((gptr)tables,sizeof(tables));
tables[0].alias= tables[0].real_name= (char*) "help_topic";
tables[0].lock_type= TL_READ;
@@ -389,11 +663,17 @@ int mysqld_help(THD *thd, const char *mask)
tables[2].alias= tables[2].real_name= (char*) "help_relation";
tables[2].lock_type= TL_READ;
tables[2].db= (char*) "mysql";
- tables[2].next= 0;
+ tables[2].next= &tables[3];
+ tables[3].alias= tables[3].real_name= (char*) "help_keyword";
+ tables[3].lock_type= TL_READ;
+ tables[3].db= (char*) "mysql";
+ tables[3].next= 0;
- List<char> function_list, categories_list;
- char *name, *description, *example;
+ 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))
{
@@ -409,111 +689,101 @@ int mysqld_help(THD *thd, const char *mask)
goto end;
}
- /* TODO: Find out why these are needed (should not be) */
- tables[0].table->file->init_table_handle_for_HANDLER();
- tables[1].table->file->init_table_handle_for_HANDLER();
- tables[2].table->file->init_table_handle_for_HANDLER();
+ for (int i=0; i<sizeof(tables)/sizeof(TABLE_LIST); i++)
+ tables[i].table->file->init_table_handle_for_HANDLER();
- cond_topic= new Item_func_like(new Item_field(used_fields[help_topic_name].
- field),
- new Item_string(mask, strlen(mask),
- help_charset),
- (char*) "\\");
- cond_topic->fix_fields(thd, tables, &cond_topic); // can never fail
- select= make_select(tables[0].table,0,0,cond_topic,&error);
- if (error || (select && select->check_quick(0, HA_POS_ERROR)))
- {
- res= -1;
- goto end;
- }
-
- cond_cat= new Item_func_like(new Item_field(used_fields[help_category_name].
- field),
- new Item_string(mask, strlen(mask),
- help_charset),
- (char*) "\\");
- cond_cat->fix_fields(thd, tables, &cond_topic); // can never fail
- select_cat= make_select(tables[1].table,0,0,cond_cat,&error);
- if (error || (select_cat && select_cat->check_quick(0, HA_POS_ERROR)))
+ if (!(select_topics_by_name=
+ 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)))
{
res= -1;
goto end;
}
res= 1;
- count_topics= search_topics(thd,tables[0].table, used_fields, select,
- &function_list, &name, &description, &example);
+ count_topics= search_topics(thd,tables[0].table,used_fields,
+ select_topics_by_name,&topics_list,
+ &name, &description, &example);
+
+ 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);
+
if (count_topics == 0)
{
int16 category_id;
- Item *cond=
- new Item_func_like(new
- Item_field(used_fields[help_category_name].field),
- new Item_string(mask, strlen(mask),
- help_charset),
- (char*) "\\");
- (void) cond->fix_fields(thd, tables, &cond); // can never fail
-
+ Field *cat_cat_id= used_fields[help_category_parent_category_id].field;
count_categories= search_categories(thd, tables[1].table, used_fields,
- select_cat, &categories_list,
- &category_id);
- if (count_categories == 1)
+ select_cat_by_name,
+ &categories_list,&category_id);
+ if (!count_categories)
{
- if (get_all_topics_for_category(thd,tables[0].table,
- tables[2].table, used_fields,
- category_id, &function_list))
- {
- res= -1;
+ if (send_header_2(protocol,false))
goto end;
- }
- List_iterator<char> it(function_list);
- char *cur_topic;
- char buff[1024];
- String example(buff, sizeof(buff), help_charset);
- example.length(0);
-
- while ((cur_topic= it++))
- {
- example.append(cur_topic);
- example.append("\n",1);
- }
- if ((send_answer_1(protocol, categories_list.head(),
- "Y","",example.ptr())))
+ }
+ else if (count_categories > 1)
+ {
+ if (send_header_2(protocol,false) ||
+ send_variant_2_list(mem_root,protocol,&categories_list,"Y",0))
goto end;
}
- else
+ else
{
- if (send_header_2(protocol))
+ Field *topic_cat_id= used_fields[help_topic_help_category_id].field;
+ Item *cond_topic_by_cat= new Item_func_equal(new Item_field(topic_cat_id),
+ new Item_int(category_id));
+ Item *cond_cat_by_cat= new Item_func_equal(new Item_field(cat_cat_id),
+ new Item_int(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)))
+ {
+ res= -1;
goto end;
- if (count_categories == 0)
- search_categories(thd,tables[1].table, used_fields, (SQL_SELECT *) 0,
- &categories_list, 0);
- if (send_variant_2_list(protocol,&categories_list,"Y"))
+ }
+ get_all_items_for_category(thd,tables[0].table,
+ used_fields[help_topic_name].field,
+ select_topics_by_cat,&topics_list);
+ get_all_items_for_category(thd,tables[1].table,
+ used_fields[help_category_name].field,
+ select_cat_by_cat,&subcategories_list);
+ String *cat= categories_list.head();
+ if (send_header_2(protocol, true) ||
+ send_variant_2_list(mem_root,protocol,&topics_list, "N",cat) ||
+ send_variant_2_list(mem_root,protocol,&subcategories_list,"Y",cat))
goto end;
}
}
else if (count_topics == 1)
{
- if (send_answer_1(protocol,name,"N",description, example))
+ if (send_answer_1(protocol,&name,&description,&example))
goto end;
}
else
{
/* First send header and functions */
- if (send_header_2(protocol) ||
- send_variant_2_list(protocol, &function_list, "N"))
+ 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,
- &categories_list, 0);
+ search_categories(thd, tables[1].table, used_fields,
+ select_cat_by_name,&categories_list, 0);
/* Then send categories */
- if (send_variant_2_list(protocol, &categories_list, "Y"))
+ if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0))
goto end;
}
res= 0;
send_eof(thd);
end:
- delete select;
- delete select_cat;
DBUG_RETURN(res);
}
diff --git a/sql/table.cc b/sql/table.cc
index 3aed75c7ac6..908d6807450 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1161,6 +1161,33 @@ rename_file_ext(const char * from,const char * to,const char * ext)
/*
+ Allocate string field in MEM_ROOT and return it as String
+
+ SYNOPSIS
+ get_field()
+ mem MEM_ROOT for allocating
+ field Field for retrieving of string
+ res result String
+
+ RETURN VALUES
+ true string is empty
+ false all ok
+*/
+
+bool get_field(MEM_ROOT *mem, Field *field, String *res)
+{
+ char buff[MAX_FIELD_WIDTH];
+ String str(buff,sizeof(buff),&my_charset_bin);
+ field->val_str(&str,&str);
+ uint length=str.length();
+ if (!length)
+ return true;
+ char *to= strmake_root(mem, str.ptr(), length);
+ res->set(to,length,((Field_str*)field)->charset());
+ return false;
+}
+
+/*
Allocate string field in MEM_ROOT and return it as NULL-terminated string
SYNOPSIS