new version of help

parent 0b1dda40
......@@ -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);
}
}
......
......@@ -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
......
......@@ -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
......
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;
-- 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;
......@@ -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
#!@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;"
#!/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
......@@ -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
......
......@@ -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 */
......
......@@ -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)
{
......
......@@ -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);
}
......@@ -1160,6 +1160,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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment