From 18d6d83c0afccd4e75895a552e88f063b951d360 Mon Sep 17 00:00:00 2001 From: "mwagner@work.mysql.com" <> Date: Fri, 4 Oct 2002 09:34:58 +0200 Subject: [PATCH 01/83] configure.in Updated for 5.0 post-commit Updated for 5.0 post-commit Removed truncate for commits to internal lists (for complete code reviews) --- BitKeeper/etc/logging_ok | 1 + BitKeeper/triggers/post-commit | 19 ++++++++++--------- configure.in | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 61c80f8b878..08bcae8e203 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -88,3 +88,4 @@ worm@altair.is.lan zak@balfor.local zak@linux.local zgreant@mysql.com +mwagner@work.mysql.com diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index f8ab599fc98..52d4a1e247f 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -6,6 +6,7 @@ FROM=$USER@mysql.com INTERNALS=internals@lists.mysql.com DOCS=docs-commit@mysql.com LIMIT=10000 +REPOV=5.0 if [ "$REAL_EMAIL" = "" ] then @@ -25,15 +26,15 @@ then echo "Commit successful, notifying developers at $TO" ( cat < +List-ID: From: $FROM To: $TO -Subject: bk commit - 4.1 tree +Subject: bk commit - $REPOV tree EOF bk changes -v -r+ bk cset -r+ -d - ) | head -n $LIMIT | /usr/sbin/sendmail -t + ) | /usr/sbin/sendmail -t #++ # internals@ mail @@ -41,13 +42,13 @@ EOF echo "Notifying internals list at $INTERNALS" ( cat < +List-ID: From: $FROM To: $INTERNALS -Subject: bk commit into 4.1 tree +Subject: bk commit into $REPOV tree Below is the list of changes that have just been committed into a local -4.1 repository of $USER. When $USER does a push these changes will +$REPOV repository of $USER. When $USER does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository @@ -68,15 +69,15 @@ EOF echo "Notifying docs list at $DOCS" ( cat < +List-ID: From: $FROM To: $DOCS -Subject: bk commit - 4.1 tree (Manual) +Subject: bk commit - $REPOV tree (Manual) EOF bk changes -v -r+ bk cset -r+ -d - ) | head -n $LIMIT | /usr/sbin/sendmail -t + ) | /usr/sbin/sendmail -t fi else diff --git a/configure.in b/configure.in index 51737f969a3..43ca6f76056 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.1.0-alpha) +AM_INIT_AUTOMAKE(mysql, 5.0.0-alpha) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 77a12f7647cab2f8afacba3c70a4b40252b8b3de Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 6 Oct 2002 16:21:52 +0200 Subject: [PATCH 02/83] Added missing semicolons in sql_yacc.yy, and did a style clean-up. Note: Textual changes only, no functional changes. --- BitKeeper/etc/logging_ok | 1 + sql/sql_yacc.yy | 850 +++++++++++++++++++++++++-------------- 2 files changed, 556 insertions(+), 295 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 08bcae8e203..faa87511acc 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -89,3 +89,4 @@ zak@balfor.local zak@linux.local zgreant@mysql.com mwagner@work.mysql.com +pem@mysql.com diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index dbc401b3ddc..bcd1ce2554f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -656,7 +656,8 @@ query: thd->lex.sql_command = SQLCOM_EMPTY_QUERY; } } - | verb_clause END_OF_INPUT {}; + | verb_clause END_OF_INPUT {} + ; verb_clause: alter @@ -694,7 +695,8 @@ verb_clause: | handler | unlock | update - | use; + | use + ; /* change master */ @@ -704,11 +706,13 @@ change: LEX *lex = Lex; lex->sql_command = SQLCOM_CHANGE_MASTER; memset(&lex->mi, 0, sizeof(lex->mi)); - } master_defs; + } master_defs + ; master_defs: master_def - | master_defs ',' master_def; + | master_defs ',' master_def + ; master_def: MASTER_HOST_SYM EQ TEXT_STRING @@ -754,8 +758,8 @@ master_def: RELAY_LOG_POS_SYM EQ ULONG_NUM { Lex->mi.relay_log_pos = $3; - }; - + } + ; /* create a table */ @@ -819,11 +823,13 @@ create: LEX *lex=Lex; lex->udf.returns=(Item_result) $7; lex->udf.dl=$9.str; - }; + } + ; create2: '(' field_list ')' opt_create_table_options create3 {} - | opt_create_table_options create3 {}; + | opt_create_table_options create3 {} + ; create3: /* empty */ {} @@ -833,34 +839,42 @@ create3: lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; mysql_init_select(lex); } - select_options select_item_list opt_select_from union {}; + select_options select_item_list opt_select_from union {} + ; opt_as: /* empty */ {} - | AS {}; + | AS {} + ; opt_table_options: /* empty */ { $$= 0; } - | table_options { $$= $1;}; + | table_options { $$= $1;} + ; table_options: table_option { $$=$1; } - | table_option table_options { $$= $1 | $2; }; + | table_option table_options { $$= $1 | $2; } + ; table_option: - TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }; + TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; } + ; opt_if_not_exists: /* empty */ { $$= 0; } - | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }; + | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; } + ; opt_create_table_options: /* empty */ - | create_table_options; + | create_table_options + ; create_table_options: create_table_option - | create_table_option create_table_options; + | create_table_option create_table_options + ; create_table_option: TYPE_SYM EQ table_types { Lex->create_info.db_type= $3; } @@ -898,7 +912,8 @@ create_table_option: } | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; } - | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; }; + | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; } + ; table_types: ISAM_SYM { $$= DB_TYPE_ISAM; } @@ -906,41 +921,48 @@ table_types: | MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; } | HEAP_SYM { $$= DB_TYPE_HEAP; } | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } - | INNOBASE_SYM { $$= DB_TYPE_INNODB; }; + | INNOBASE_SYM { $$= DB_TYPE_INNODB; } + ; row_types: DEFAULT { $$= ROW_TYPE_DEFAULT; } | FIXED_SYM { $$= ROW_TYPE_FIXED; } | DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; } - | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }; + | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; } + ; raid_types: RAID_STRIPED_SYM { $$= RAID_TYPE_0; } | RAID_0_SYM { $$= RAID_TYPE_0; } - | ULONG_NUM { $$=$1;}; + | ULONG_NUM { $$=$1; } + ; merge_insert_types: NO_SYM { $$= MERGE_INSERT_DISABLED; } | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; } - | LAST_SYM { $$= MERGE_INSERT_TO_LAST; }; + | LAST_SYM { $$= MERGE_INSERT_TO_LAST; } + ; opt_select_from: /* empty */ - | select_from select_lock_type; + | select_from select_lock_type + ; udf_func_type: /* empty */ { $$ = UDFTYPE_FUNCTION; } - | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; }; + | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; } + ; udf_type: STRING_SYM {$$ = (int) STRING_RESULT; } | REAL {$$ = (int) REAL_RESULT; } - | INT_SYM {$$ = (int) INT_RESULT; }; + | INT_SYM {$$ = (int) INT_RESULT; } + ; field_list: field_list_item - | field_list ',' field_list_item; - + | field_list ',' field_list_item + ; field_list_item: field_spec @@ -968,11 +990,13 @@ field_list_item: | opt_constraint CHECK_SYM '(' expr ')' { Lex->col_list.empty(); /* Alloced by sql_alloc */ - }; + } + ; opt_constraint: /* empty */ - | CONSTRAINT opt_ident; + | CONSTRAINT opt_ident + ; field_spec: field_ident @@ -991,7 +1015,8 @@ field_spec: lex->default_value, lex->comment, lex->change,lex->interval,lex->charset)) YYABORT; - }; + } + ; type: int_type opt_len field_options { Lex->length=$2; $$=$1; } @@ -1052,65 +1077,77 @@ type: LEX *lex=Lex; lex->interval=typelib(lex->interval_list); $$=FIELD_TYPE_SET; - }; + } + ; char: CHAR_SYM {} | NCHAR_SYM {} - | NATIONAL_SYM CHAR_SYM {}; + | NATIONAL_SYM CHAR_SYM {} + ; varchar: char VARYING {} | VARCHAR {} | NATIONAL_SYM VARCHAR {} - | NCHAR_SYM VARCHAR {}; + | NCHAR_SYM VARCHAR {} + ; int_type: INT_SYM { $$=FIELD_TYPE_LONG; } | TINYINT { $$=FIELD_TYPE_TINY; } | SMALLINT { $$=FIELD_TYPE_SHORT; } | MEDIUMINT { $$=FIELD_TYPE_INT24; } - | BIGINT { $$=FIELD_TYPE_LONGLONG; }; + | BIGINT { $$=FIELD_TYPE_LONGLONG; } + ; real_type: REAL { $$= current_thd->sql_mode & MODE_REAL_AS_FLOAT ? FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } - | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; + | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; } + ; float_options: /* empty */ {} | '(' NUM ')' { Lex->length=$2.str; } - | precision {}; + | precision {} + ; precision: '(' NUM ',' NUM ')' { LEX *lex=Lex; lex->length=$2.str; lex->dec=$4.str; - }; + } + ; field_options: /* empty */ {} - | field_opt_list {}; + | field_opt_list {} + ; field_opt_list: field_opt_list field_option {} - | field_option {}; + | field_option {} + ; field_option: SIGNED_SYM {} | UNSIGNED { Lex->type|= UNSIGNED_FLAG;} - | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }; + | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + ; opt_len: /* empty */ { $$=(char*) 0; } /* use default length */ - | '(' NUM ')' { $$=$2.str; }; + | '(' NUM ')' { $$=$2.str; } + ; opt_precision: /* empty */ {} - | precision {}; + | precision {} + ; opt_attribute: /* empty */ {} @@ -1128,7 +1165,8 @@ attribute: | PRIMARY_SYM KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; } | UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; } | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } - | COMMENT_SYM text_literal { Lex->comment= $2; }; + | COMMENT_SYM text_literal { Lex->comment= $2; } + ; charset_name: ident @@ -1138,20 +1176,24 @@ charset_name: net_printf(current_thd,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; } - }; + } + ; charset_name_or_default: charset_name { $$=$1; } - | DEFAULT { $$=NULL; } ; + | DEFAULT { $$=NULL; } + ; opt_db_default_character_set: /* empty */ { $$=default_charset_info; } - | DEFAULT CHAR_SYM SET charset_name_or_default { $$=$4; }; + | DEFAULT CHAR_SYM SET charset_name_or_default { $$=$4; } + ; opt_binary: /* empty */ { Lex->charset=NULL; } | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; } - | CHAR_SYM SET charset_name { Lex->charset=$3; } ; + | CHAR_SYM SET charset_name { Lex->charset=$3; } + ; references: REFERENCES table_ident @@ -1163,38 +1205,45 @@ references: opt_ref_list { $$=$2; - }; + } + ; opt_ref_list: /* empty */ opt_on_delete {} - | '(' ref_list ')' opt_on_delete {}; + | '(' ref_list ')' opt_on_delete {} + ; ref_list: ref_list ',' ident { Lex->ref_list.push_back(new key_part_spec($3.str)); } - | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); }; + | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); } + ; opt_on_delete: /* empty */ {} - | opt_on_delete_list {}; + | opt_on_delete_list {} + ; opt_on_delete_list: opt_on_delete_list opt_on_delete_item {} - | opt_on_delete_item {}; + | opt_on_delete_item {} + ; opt_on_delete_item: ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; } | ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; } | MATCH FULL { Lex->fk_match_option= foreign_key::FK_MATCH_FULL; } | MATCH PARTIAL { Lex->fk_match_option= foreign_key::FK_MATCH_PARTIAL; } - | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; }; + | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; } + ; delete_option: RESTRICT { $$= (int) foreign_key::FK_OPTION_RESTRICT; } | CASCADE { $$= (int) foreign_key::FK_OPTION_CASCADE; } | SET NULL_SYM { $$= (int) foreign_key::FK_OPTION_SET_NULL; } | NO_SYM ACTION { $$= (int) foreign_key::FK_OPTION_NO_ACTION; } - | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; }; + | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; } + ; key_type: opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } @@ -1204,46 +1253,56 @@ key_type: | SPATIAL_SYM { $$= Key::SPATIAL; } | SPATIAL_SYM key_or_index { $$= Key::SPATIAL; } | opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; } - | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; }; + | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; } + ; key_or_index: KEY_SYM {} - | INDEX {}; + | INDEX {} + ; keys_or_index: KEYS {} | INDEX {} - | INDEXES {}; + | INDEXES {} + ; opt_unique_or_fulltext: /* empty */ { $$= Key::MULTIPLE; } | UNIQUE_SYM { $$= Key::UNIQUE; } - | SPATIAL_SYM { $$= Key::SPATIAL; }; + | SPATIAL_SYM { $$= Key::SPATIAL; } + ; key_alg: /* empty */ { $$= HA_KEY_ALG_UNDEF; } - | USING opt_btree_or_rtree { $$= $2; }; + | USING opt_btree_or_rtree { $$= $2; } + ; opt_btree_or_rtree: BTREE_SYM { $$= HA_KEY_ALG_BTREE; } | RTREE_SYM { $$= HA_KEY_ALG_RTREE; } - | HASH_SYM { $$= HA_KEY_ALG_HASH; }; + | HASH_SYM { $$= HA_KEY_ALG_HASH; } + ; key_list: key_list ',' key_part order_dir { Lex->col_list.push_back($3); } - | key_part order_dir { Lex->col_list.push_back($1); }; + | key_part order_dir { Lex->col_list.push_back($1); } + ; key_part: ident { $$=new key_part_spec($1.str); } - | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); }; + | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); } + ; opt_ident: /* empty */ { $$=(char*) 0; } /* Defaultlength */ - | field_ident { $$=$1.str; }; + | field_ident { $$=$1.str; } + ; string_list: text_string { Lex->interval_list.push_back($1); } - | string_list ',' text_string { Lex->interval_list.push_back($3); }; + | string_list ',' text_string { Lex->interval_list.push_back($3); } + ; /* ** Alter table @@ -1275,23 +1334,24 @@ alter: lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } - alter_list; - + alter_list | ALTER DATABASE ident opt_db_default_character_set { LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; lex->create_info.table_charset=$4; - }; - + } + ; alter_list: | alter_list_item - | alter_list ',' alter_list_item; + | alter_list ',' alter_list_item + ; add_column: - ADD opt_column { Lex->change=0; }; + ADD opt_column { Lex->change=0; } + ; alter_list_item: add_column field_list_item opt_place { Lex->simple_alter=0; } @@ -1360,31 +1420,37 @@ alter_list_item: lex->name= $3->table.str; } | create_table_options { Lex->simple_alter=0; } - | order_clause { Lex->simple_alter=0; }; + | order_clause { Lex->simple_alter=0; } + ; opt_column: /* empty */ {} - | COLUMN_SYM {}; + | COLUMN_SYM {} + ; opt_ignore: /* empty */ { Lex->duplicates=DUP_ERROR; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; + | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; } + ; opt_restrict: /* empty */ {} | RESTRICT {} - | CASCADE {}; + | CASCADE {} + ; opt_place: /* empty */ {} | AFTER_SYM ident { store_position_for_column($2.str); } - | FIRST_SYM { store_position_for_column(first_keyword); }; + | FIRST_SYM { store_position_for_column(first_keyword); } + ; opt_to: /* empty */ {} | TO_SYM {} | EQ {} - | AS {}; + | AS {} + ; slave: SLAVE START_SYM slave_thread_opts @@ -1399,11 +1465,13 @@ slave: LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_STOP; lex->type = 0; - }; + } + ; slave_thread_opts: slave_thread_opt - | slave_thread_opts ',' slave_thread_opt; + | slave_thread_opts ',' slave_thread_opt + ; slave_thread_opt: /*empty*/ {} @@ -1419,7 +1487,8 @@ restore: table_list FROM TEXT_STRING { Lex->backup_dir = $6.str; - }; + } + ; backup: BACKUP_SYM table_or_tables @@ -1429,7 +1498,8 @@ backup: table_list TO_SYM TEXT_STRING { Lex->backup_dir = $6.str; - }; + } + ; repair: REPAIR table_or_tables @@ -1438,20 +1508,24 @@ repair: lex->sql_command = SQLCOM_REPAIR; lex->check_opt.init(); } - table_list opt_mi_repair_type; + table_list opt_mi_repair_type + ; opt_mi_repair_type: /* empty */ { Lex->check_opt.flags = T_MEDIUM; } - | mi_repair_types {}; + | mi_repair_types {} + ; mi_repair_types: mi_repair_type {} - | mi_repair_type mi_repair_types {}; + | mi_repair_type mi_repair_types {} + ; mi_repair_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } - | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; }; + | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; } + ; analyze: ANALYZE_SYM table_or_tables @@ -1460,7 +1534,8 @@ analyze: lex->sql_command = SQLCOM_ANALYZE; lex->check_opt.init(); } - table_list opt_mi_check_type; + table_list opt_mi_check_type + ; check: CHECK_SYM table_or_tables @@ -1469,22 +1544,26 @@ check: lex->sql_command = SQLCOM_CHECK; lex->check_opt.init(); } - table_list opt_mi_check_type; + table_list opt_mi_check_type + ; opt_mi_check_type: /* empty */ { Lex->check_opt.flags = T_MEDIUM; } - | mi_check_types {}; + | mi_check_types {} + ; mi_check_types: mi_check_type {} - | mi_check_type mi_check_types {}; + | mi_check_type mi_check_types {} + ; mi_check_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | FAST_SYM { Lex->check_opt.flags|= T_FAST; } | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } - | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }; + | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; } + ; optimize: OPTIMIZE table_or_tables @@ -1493,25 +1572,29 @@ optimize: lex->sql_command = SQLCOM_OPTIMIZE; lex->check_opt.init(); } - table_list opt_mi_check_type; + table_list opt_mi_check_type + ; rename: RENAME table_or_tables { Lex->sql_command=SQLCOM_RENAME_TABLE; } - table_to_table_list; + table_to_table_list + ; table_to_table_list: table_to_table - | table_to_table_list ',' table_to_table; + | table_to_table_list ',' table_to_table + ; table_to_table: table_ident TO_SYM table_ident { if (!add_table_to_list($1,NULL,1,TL_IGNORE) || !add_table_to_list($3,NULL,1,TL_IGNORE)) YYABORT; - }; + } + ; /* Select : retrieve data from table @@ -1519,7 +1602,8 @@ table_to_table: select: - select_init { Lex->sql_command=SQLCOM_SELECT; }; + select_init { Lex->sql_command=SQLCOM_SELECT; } + ; select_init: SELECT_SYM select_part2 { Select->braces=false; } union @@ -1531,7 +1615,8 @@ select_init: /* select in braces, can't contain global parameters */ sel->master_unit()->global_parameters= sel->master_unit(); - } union_opt; + } union_opt + ; select_part2: { @@ -1539,25 +1624,29 @@ select_part2: lex->lock_option=TL_READ; mysql_init_select(lex); } - select_options select_item_list select_into select_lock_type; + select_options select_item_list select_into select_lock_type + ; select_into: limit_clause {} | select_from | opt_into select_from - | select_from opt_into; + | select_from opt_into + ; select_from: - FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause; - + FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause + ; select_options: /* empty*/ - | select_option_list; + | select_option_list + ; select_option_list: select_option_list select_option - | select_option; + | select_option + ; select_option: STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } @@ -1614,8 +1703,8 @@ select_item_list: { if (add_item_to_list(new Item_field(NULL,NULL,"*"))) YYABORT; - }; - + } + ; select_item: remember_name select_item2 remember_end select_alias @@ -1626,32 +1715,39 @@ select_item: $2->set_name($4.str); else if (!$2->name) $2->set_name($1,(uint) ($3 - $1)); - }; + } + ; remember_name: - { $$=(char*) Lex->tok_start; }; + { $$=(char*) Lex->tok_start; } + ; remember_end: - { $$=(char*) Lex->tok_end; }; + { $$=(char*) Lex->tok_end; } + ; select_item2: table_wild { $$=$1; } /* table.* */ - | expr { $$=$1; }; + | expr { $$=$1; } + ; select_alias: { $$.str=0;} | AS ident { $$=$2; } | AS TEXT_STRING { $$=$2; } | ident { $$=$1; } - | TEXT_STRING { $$=$1; }; + | TEXT_STRING { $$=$1; } + ; optional_braces: /* empty */ {} - | '(' ')' {}; + | '(' ')' {} + ; /* all possible expressions */ expr: expr_expr { $$= $1; } - | simple_expr { $$= $1; }; + | simple_expr { $$= $1; } + ; /* expressions that begin with 'expr' */ expr_expr: @@ -1695,7 +1791,8 @@ expr_expr: | expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } | expr COLLATE_SYM charset_name - { $$= new Item_func_set_collation($1,$3); }; + { $$= new Item_func_set_collation($1,$3); } + ; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ no_in_expr: @@ -1734,7 +1831,8 @@ no_in_expr: { $$= new Item_date_add_interval($1,$4,$5,0); } | no_in_expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } - | simple_expr; + | simple_expr + ; /* expressions that begin with 'expr' that does NOT follow AND */ no_and_expr: @@ -1776,7 +1874,8 @@ no_and_expr: { $$= new Item_date_add_interval($1,$4,$5,0); } | no_and_expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } - | simple_expr; + | simple_expr + ; simple_expr: simple_ident @@ -2105,11 +2204,13 @@ simple_expr: current_thd->safe_to_cache_query=0; } | EXTRACT_SYM '(' interval FROM expr ')' - { $$=new Item_extract( $3, $5); }; + { $$=new Item_extract( $3, $5); } + ; udf_expr_list: /* empty */ { $$= NULL; } - | expr_list { $$= $1;}; + | expr_list { $$= $1; } + ; sum_expr: AVG_SYM '(' in_sum_expr ')' @@ -2133,7 +2234,8 @@ sum_expr: | STD_SYM '(' in_sum_expr ')' { $$=new Item_sum_std($3); } | SUM_SYM '(' in_sum_expr ')' - { $$=new Item_sum_sum($3); }; + { $$=new Item_sum_sum($3); } + ; in_sum_expr: { Select->in_sum_expr++; } @@ -2141,7 +2243,8 @@ in_sum_expr: { Select->in_sum_expr--; $$=$2; - }; + } + ; cast_type: BINARY { $$=ITEM_CAST_BINARY; } @@ -2151,42 +2254,51 @@ cast_type: | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; } | DATE_SYM { $$=ITEM_CAST_DATE; } | TIME_SYM { $$=ITEM_CAST_TIME; } - | DATETIME { $$=ITEM_CAST_DATETIME; }; + | DATETIME { $$=ITEM_CAST_DATETIME; } + ; expr_list: { Select->expr_list.push_front(new List); } expr_list2 - { $$= Select->expr_list.pop(); }; + { $$= Select->expr_list.pop(); } + ; expr_list2: expr { Select->expr_list.head()->push_back($1); } - | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); }; + | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); } + ; ident_list_arg: ident_list { $$= $1; } - | '(' ident_list ')' { $$= $2; }; + | '(' ident_list ')' { $$= $2; } + ; ident_list: { Select->expr_list.push_front(new List); } ident_list2 - { $$= Select->expr_list.pop(); }; + { $$= Select->expr_list.pop(); } + ; ident_list2: simple_ident { Select->expr_list.head()->push_back($1); } - | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); }; + | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); } + ; opt_expr: /* empty */ { $$= NULL; } - | expr { $$= $1; }; + | expr { $$= $1; } + ; opt_else: /* empty */ { $$= NULL; } - | ELSE expr { $$= $2; }; + | ELSE expr { $$= $2; } + ; when_list: { Select->when_list.push_front(new List); } when_list2 - { $$= Select->when_list.pop(); }; + { $$= Select->when_list.pop(); } + ; when_list2: expr THEN_SYM expr @@ -2200,11 +2312,13 @@ when_list2: SELECT_LEX *sel=Select; sel->when_list.head()->push_back($3); sel->when_list.head()->push_back($5); - }; + } + ; opt_pad: /* empty */ { $$=new Item_string(" ",1,default_charset_info); } - | expr { $$=$1; }; + | expr { $$=$1; } + ; join_table_list: '(' join_table_list ')' { $$=$2; } @@ -2246,12 +2360,14 @@ join_table_list: | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table { add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } | join_table_list NATURAL JOIN_SYM join_table - { add_join_natural($1,$4); $$=$4; }; + { add_join_natural($1,$4); $$=$4; } + ; normal_join: ',' {} | JOIN_SYM {} - | CROSS JOIN_SYM {}; + | CROSS JOIN_SYM {} + ; join_table: { @@ -2275,7 +2391,8 @@ join_table: if (!($$= add_table_to_list(new Table_ident(unit), $5,0,TL_UNLOCK))) YYABORT; - }; + } + ; select_part3: { @@ -2288,14 +2405,17 @@ select_part3: lex->select->linkage= DERIVED_TABLE_TYPE; } select_options select_item_list select_intoto + ; select_intoto: limit_clause {} | select_from + ; opt_outer: /* empty */ {} - | OUTER {}; + | OUTER {} + ; opt_key_definition: /* empty */ {} @@ -2310,11 +2430,13 @@ opt_key_definition: SELECT_LEX *sel=Select; sel->ignore_index= *$2; sel->ignore_index_ptr= &sel->ignore_index; - }; + } + ; key_usage_list: key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')' - { $$= &Select->interval_list; }; + { $$= &Select->interval_list; } + ; key_usage_list2: key_usage_list2 ',' ident @@ -2322,7 +2444,8 @@ key_usage_list2: | ident { Select->interval_list.push_back(new String((const char*) $1.str,$1.length,default_charset_info)); } | PRIMARY_SYM - { Select->interval_list.push_back(new String("PRIMARY",7,default_charset_info)); }; + { Select->interval_list.push_back(new String("PRIMARY",7,default_charset_info)); } + ; using_list: ident @@ -2336,7 +2459,8 @@ using_list: SELECT_LEX *sel=Select; if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1))) YYABORT; - }; + } + ; interval: DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; } @@ -2351,22 +2475,25 @@ interval: | MONTH_SYM { $$=INTERVAL_MONTH; } | SECOND_SYM { $$=INTERVAL_SECOND; } | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } - | YEAR_SYM { $$=INTERVAL_YEAR; }; + | YEAR_SYM { $$=INTERVAL_YEAR; } + ; table_alias: /* empty */ | AS - | EQ; + | EQ + ; opt_table_alias: /* empty */ { $$=0; } | table_alias ident - { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); }; - + { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); } + ; where_clause: /* empty */ { Select->where= 0; } - | WHERE expr { Select->where= $2; }; + | WHERE expr { Select->where= $2; } + ; having_clause: /* empty */ @@ -2374,11 +2501,13 @@ having_clause: { SELECT_LEX *sel=Select; sel->having= $3; sel->create_refs=0; - }; + } + ; opt_escape: ESCAPE_SYM TEXT_STRING { $$= $2.str; } - | /* empty */ { $$= (char*) "\\"; }; + | /* empty */ { $$= (char*) "\\"; } + ; /* @@ -2387,13 +2516,15 @@ opt_escape: group_clause: /* empty */ - | GROUP BY group_list olap_opt; + | GROUP BY group_list olap_opt + ; group_list: group_list ',' order_ident order_dir { if (add_group_to_list($3,(bool) $4)) YYABORT; } | order_ident order_dir - { if (add_group_to_list($1,(bool) $2)) YYABORT; }; + { if (add_group_to_list($1,(bool) $2)) YYABORT; } + ; olap_opt: /* empty */ {} @@ -2421,7 +2552,8 @@ olap_opt: opt_order_clause: /* empty */ - | order_clause; + | order_clause + ; order_clause: ORDER_SYM BY @@ -2440,19 +2572,21 @@ order_clause: "ORDER BY"); YYABORT; } - } order_list; + } order_list + ; order_list: order_list ',' order_ident order_dir { if (add_order_to_list($3,(bool) $4)) YYABORT; } | order_ident order_dir - { if (add_order_to_list($1,(bool) $2)) YYABORT; }; + { if (add_order_to_list($1,(bool) $2)) YYABORT; } + ; order_dir: /* empty */ { $$ = 1; } | ASC { $$ =1; } - | DESC { $$ =0; }; - + | DESC { $$ =0; } + ; limit_clause: /* empty */ {} @@ -2483,7 +2617,8 @@ limit_clause: SELECT_LEX *sel=lex->select; sel->select_limit= $4; sel->offset_limit= $2; - }; + } + ; delete_limit_clause: /* empty */ @@ -2497,20 +2632,23 @@ delete_limit_clause: lex->select->select_limit= HA_POS_ERROR; } | LIMIT ulonglong_num - { Select->select_limit= (ha_rows) $2; }; + { Select->select_limit= (ha_rows) $2; } + ; ULONG_NUM: NUM { $$= strtoul($1.str,NULL,10); } | ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); } | REAL_NUM { $$= strtoul($1.str,NULL,10); } - | FLOAT_NUM { $$= strtoul($1.str,NULL,10); }; + | FLOAT_NUM { $$= strtoul($1.str,NULL,10); } + ; ulonglong_num: NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } | ULONGLONG_NUM { $$= strtoull($1.str,NULL,10); } | LONG_NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } | REAL_NUM { $$= strtoull($1.str,NULL,10); } - | FLOAT_NUM { $$= strtoull($1.str,NULL,10); }; + | FLOAT_NUM { $$= strtoull($1.str,NULL,10); } + ; procedure_clause: /* empty */ @@ -2524,16 +2662,18 @@ procedure_clause: YYABORT; current_thd->safe_to_cache_query=0; } - '(' procedure_list ')'; - + '(' procedure_list ')' + ; procedure_list: /* empty */ {} - | procedure_list2 {}; + | procedure_list2 {} + ; procedure_list2: procedure_list2 ',' procedure_item - | procedure_item; + | procedure_item + ; procedure_item: remember_name expr @@ -2542,7 +2682,8 @@ procedure_item: YYABORT; if (!$2->name) $2->set_name($1,(uint) ((char*) Lex->tok_end - $1)); - }; + } + ; opt_into: INTO OUTFILE TEXT_STRING @@ -2555,7 +2696,8 @@ opt_into: { if (!(Lex->exchange= new sql_exchange($3.str,1))) YYABORT; - }; + } + ; /* DO statement @@ -2568,7 +2710,9 @@ do: DO_SYM if (!(lex->insert_list = new List_item)) YYABORT; } - values; + values + ; + /* Drop : delete tables or index */ @@ -2602,27 +2746,32 @@ drop: LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_FUNCTION; lex->udf.name=$3.str; - }; + } + ; table_list: table_name - | table_list ',' table_name; + | table_list ',' table_name + ; table_name: table_ident - { if (!add_table_to_list($1,NULL,1)) YYABORT; }; + { if (!add_table_to_list($1,NULL,1)) YYABORT; } + ; if_exists: /* empty */ { $$=0; } - | IF EXISTS { $$= 1; }; + | IF EXISTS { $$= 1; } + ; /* ** Insert : add new data to table */ insert: - INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec; + INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec + ; replace: REPLACE @@ -2631,21 +2780,25 @@ replace: lex->sql_command = SQLCOM_REPLACE; lex->duplicates= DUP_REPLACE; } - replace_lock_option insert2 insert_field_spec; + replace_lock_option insert2 insert_field_spec + ; insert_lock_option: /* empty */ { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT; } | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; } - | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; }; + | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; } + ; replace_lock_option: opt_low_priority {} - | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; }; + | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; } + ; insert2: INTO insert_table {} - | insert_table {}; + | insert_table {} + ; insert_table: table_name @@ -2654,7 +2807,8 @@ insert_table: lex->field_list.empty(); lex->many_values.empty(); lex->insert_list=0; - }; + } + ; insert_field_spec: opt_field_spec insert_values {} @@ -2665,16 +2819,19 @@ insert_field_spec: lex->many_values.push_back(lex->insert_list)) YYABORT; } - ident_eq_list; + ident_eq_list + ; opt_field_spec: /* empty */ { } | '(' fields ')' { } - | '(' ')' { }; + | '(' ')' { } + ; fields: fields ',' insert_ident { Lex->field_list.push_back($3); } - | insert_ident { Lex->field_list.push_back($1); }; + | insert_ident { Lex->field_list.push_back($1); } + ; insert_values: VALUES values_list {} @@ -2687,25 +2844,29 @@ insert_values: mysql_init_select(lex); } select_options select_item_list select_from select_lock_type - union {}; + union {} + ; values_list: values_list ',' no_braces - | no_braces; + | no_braces + ; ident_eq_list: ident_eq_list ',' ident_eq_value | - ident_eq_value; + ident_eq_value + ; ident_eq_value: simple_ident equal expr_or_default - { + { LEX *lex=Lex; if (lex->field_list.push_back($1) || lex->insert_list->push_back($3)) YYABORT; - }; + } + ; equal: EQ {} | SET_VAR {} @@ -2727,11 +2888,13 @@ no_braces: LEX *lex=Lex; if (lex->many_values.push_back(lex->insert_list)) YYABORT; - }; + } + ; opt_values: /* empty */ {} - | values; + | values + ; values: values ',' expr_or_default @@ -2762,7 +2925,8 @@ update: lex->select->order_list.first=0; lex->select->order_list.next= (byte**) &lex->select->order_list.first; } - opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause; + opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause + ; update_list: update_list ',' simple_ident equal expr @@ -2774,11 +2938,13 @@ update_list: { if (add_item_to_list($1) || add_value_to_list($3)) YYABORT; - }; + } + ; opt_low_priority: /* empty */ { Lex->lock_option= current_thd->update_lock_default; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + ; /* Delete rows from a table */ @@ -2792,7 +2958,8 @@ delete: lex->select->order_list.first=0; lex->select->order_list.next= (byte**) &lex->select->order_list.first; } - opt_delete_options single_multi {}; + opt_delete_options single_multi {} + ; single_multi: FROM table_name where_clause opt_order_clause delete_limit_clause {} @@ -2801,11 +2968,13 @@ single_multi: FROM join_table_list where_clause | FROM table_wild_list { mysql_init_multi_delete(Lex); } - USING join_table_list where_clause; + USING join_table_list where_clause + ; table_wild_list: table_wild_one {} - | table_wild_list ',' table_wild_one {}; + | table_wild_list ',' table_wild_one {} + ; table_wild_one: ident opt_wild @@ -2817,20 +2986,24 @@ table_wild_one: { if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) YYABORT; - }; + } + ; opt_wild: /* empty */ {} - | '.' '*' {}; + | '.' '*' {} + ; opt_delete_options: /* empty */ {} - | opt_delete_option opt_delete_options {}; + | opt_delete_option opt_delete_options {} + ; opt_delete_option: QUICK { Select->options|= OPTION_QUICK; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + ; truncate: TRUNCATE_SYM opt_table_sym table_name @@ -2841,15 +3014,19 @@ truncate: lex->select->order_list.elements=0; lex->select->order_list.first=0; lex->select->order_list.next= (byte**) &lex->select->order_list.first; - lex->lock_option= current_thd->update_lock_default; }; + lex->lock_option= current_thd->update_lock_default; + } + ; opt_table_sym: /* empty */ - | TABLE_SYM; + | TABLE_SYM + ; /* Show things */ -show: SHOW { Lex->wild=0;} show_param; +show: SHOW { Lex->wild=0;} show_param + ; show_param: DATABASES wild @@ -2979,31 +3156,38 @@ show_param: | SLAVE STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - }; + } + ; opt_db: /* empty */ { $$= 0; } - | from_or_in ident { $$= $2.str; }; + | from_or_in ident { $$= $2.str; } + ; wild: /* empty */ - | LIKE text_string { Lex->wild= $2; }; + | LIKE text_string { Lex->wild= $2; } + ; opt_full: /* empty */ { Lex->verbose=0; } - | FULL { Lex->verbose=1; }; + | FULL { Lex->verbose=1; } + ; from_or_in: FROM - | IN_SYM; + | IN_SYM + ; binlog_in: /* empty */ { Lex->mi.log_file_name = 0; } - | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; }; + | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; } + ; binlog_from: /* empty */ { Lex->mi.pos = 4; /* skip magic number */ } - | FROM ulonglong_num { Lex->mi.pos = $2; }; + | FROM ulonglong_num { Lex->mi.pos = $2; } + ; /* A Oracle compatible synonym for show */ @@ -3019,18 +3203,21 @@ describe: } opt_describe_column | describe_command select - { Lex->select_lex.options|= SELECT_DESCRIBE; }; + { Lex->select_lex.options|= SELECT_DESCRIBE; } + ; describe_command: DESC - | DESCRIBE; + | DESCRIBE + ; opt_describe_column: /* empty */ {} | text_string { Lex->wild= $1; } | ident - { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); }; + { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); } + ; /* flush things */ @@ -3041,11 +3228,13 @@ flush: LEX *lex=Lex; lex->sql_command= SQLCOM_FLUSH; lex->type=0; } - flush_options; + flush_options + ; flush_options: flush_options ',' flush_option - | flush_option; + | flush_option + ; flush_option: table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list @@ -3058,26 +3247,32 @@ flush_option: | SLAVE { Lex->type|= REFRESH_SLAVE; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; } - | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }; + | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; } + ; opt_table_list: - /* empty */ {;} - | table_list {;}; + /* empty */ {} + | table_list {} + ; reset: RESET_SYM { LEX *lex=Lex; lex->sql_command= SQLCOM_RESET; lex->type=0; - } reset_options; + } reset_options + ; + reset_options: reset_options ',' reset_option - | reset_option; + | reset_option + ; reset_option: SLAVE { Lex->type|= REFRESH_SLAVE; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } - | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}; + | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;} + ; purge: PURGE @@ -3087,9 +3282,10 @@ purge: lex->type=0; } MASTER_SYM LOGS_SYM TO_SYM TEXT_STRING - { + { Lex->to_log = $6.str; - } ; + } + ; /* kill threads */ @@ -3104,7 +3300,8 @@ kill: } lex->sql_command=SQLCOM_KILL; lex->thread_id= (ulong) $2->val_int(); - }; + } + ; /* change database */ @@ -3112,7 +3309,8 @@ use: USE_SYM ident { LEX *lex=Lex; lex->sql_command=SQLCOM_CHANGE_DB; lex->select->db= $2.str; - }; + } + ; /* import, export of files */ @@ -3143,30 +3341,36 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING LOAD DATA_SYM FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_DATA; - }; + } + ; opt_local: - /* empty */ { $$=0;} - | LOCAL_SYM { $$=1;}; + /* empty */ { $$=0; } + | LOCAL_SYM { $$=1; } + ; load_data_lock: /* empty */ { Lex->lock_option= current_thd->update_lock_default; } | CONCURRENT { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT ; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + ; opt_duplicate: /* empty */ { Lex->duplicates=DUP_ERROR; } | REPLACE { Lex->duplicates=DUP_REPLACE; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; + | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; } + ; opt_field_term: /* empty */ - | COLUMNS field_term_list; + | COLUMNS field_term_list + ; field_term_list: field_term_list field_term - | field_term; + | field_term + ; field_term: TERMINATED BY text_string { Lex->exchange->field_term= $3;} @@ -3176,25 +3380,30 @@ field_term: lex->exchange->enclosed= $4; lex->exchange->opt_enclosed=1; } - | ENCLOSED BY text_string { Lex->exchange->enclosed= $3;} - | ESCAPED BY text_string { Lex->exchange->escaped= $3;}; + | ENCLOSED BY text_string { Lex->exchange->enclosed= $3; } + | ESCAPED BY text_string { Lex->exchange->escaped= $3; } + ; opt_line_term: /* empty */ - | LINES line_term_list; + | LINES line_term_list + ; line_term_list: line_term_list line_term - | line_term; + | line_term + ; line_term: - TERMINATED BY text_string { Lex->exchange->line_term= $3;} - | STARTING BY text_string { Lex->exchange->line_start= $3;}; + TERMINATED BY text_string { Lex->exchange->line_term= $3; } + | STARTING BY text_string { Lex->exchange->line_start= $3; } + ; opt_ignore_lines: /* empty */ | IGNORE_SYM NUM LINES - { Lex->exchange->skip_lines=atol($2.str); }; + { Lex->exchange->skip_lines=atol($2.str); } + ; /* Common definitions */ @@ -3202,7 +3411,8 @@ text_literal: TEXT_STRING { $$ = new Item_string($1.str,$1.length,default_charset_info); } | UNDERSCORE_CHARSET TEXT_STRING { $$ = new Item_string($2.str,$2.length,Lex->charset); } | text_literal TEXT_STRING - { ((Item_string*) $1)->append($2.str,$2.length); }; + { ((Item_string*) $1)->append($2.str,$2.length); } + ; text_string: TEXT_STRING { $$= new String($1.str,$1.length,default_charset_info); } @@ -3210,7 +3420,9 @@ text_string: { Item *tmp = new Item_varbinary($1.str,$1.length,default_charset_info); $$= tmp ? tmp->val_str((String*) 0) : (String*) 0; - }; + } + ; + param_marker: '?' { @@ -3226,6 +3438,8 @@ param_marker: YYABORT; } } + ; + literal: text_literal { $$ = $1; } | NUM { $$ = new Item_int($1.str, (longlong) atol($1.str),$1.length); } @@ -3238,7 +3452,8 @@ literal: | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length,default_charset_info);} | DATE_SYM text_literal { $$ = $2; } | TIME_SYM text_literal { $$ = $2; } - | TIMESTAMP text_literal { $$ = $2; }; + | TIMESTAMP text_literal { $$ = $2; } + ; /********************************************************************** ** Createing different items. @@ -3246,16 +3461,19 @@ literal: insert_ident: simple_ident { $$=$1; } - | table_wild { $$=$1; }; + | table_wild { $$=$1; } + ; table_wild: ident '.' '*' { $$ = new Item_field(NullS,$1.str,"*"); } | ident '.' ident '.' '*' { $$ = new Item_field((current_thd->client_capabilities & - CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); }; + CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); } + ; order_ident: - expr { $$=$1; }; + expr { $$=$1; } + ; simple_ident: ident @@ -3277,19 +3495,20 @@ simple_ident: { SELECT_LEX *sel=Select; $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); - }; - + } + ; field_ident: ident { $$=$1;} | ident '.' ident { $$=$3;} /* Skipp schema name in create*/ - | '.' ident { $$=$2;} /* For Delphi */; + | '.' ident { $$=$2;} /* For Delphi */ + ; table_ident: ident { $$=new Table_ident($1); } | ident '.' ident { $$=new Table_ident($1,$3,0);} - | '.' ident { $$=new Table_ident($2);} - /* For Delphi */; + | '.' ident { $$=new Table_ident($2);} /* For Delphi */ + ; ident: IDENT { $$=$1; } @@ -3300,12 +3519,14 @@ ident: $$.length=$1.length; if ((lex=Lex)->next_state != STATE_END) lex->next_state=STATE_OPERATOR_OR_IDENT; - }; + } + ; ident_or_text: ident { $$=$1;} | TEXT_STRING { $$=$1;} - | LEX_HOSTNAME { $$=$1;}; + | LEX_HOSTNAME { $$=$1;} + ; user: ident_or_text @@ -3319,7 +3540,8 @@ user: if (!($$=(LEX_USER*) sql_alloc(sizeof(st_lex_user)))) YYABORT; $$->user = $1; $$->host=$3; - }; + } + ; /* Keyword that we allow for identifiers */ @@ -3492,15 +3714,18 @@ set: lex->option_type=OPT_DEFAULT; lex->var_list.empty(); } - option_value_list; + option_value_list + ; opt_option: /* empty */ {} - | OPTION {}; + | OPTION {} + ; option_value_list: option_type option_value - | option_value_list ',' option_type option_value; + | option_value_list ',' option_type option_value + ; option_type: /* empty */ {} @@ -3566,6 +3791,7 @@ option_value: { Lex->var_list.push_back(new set_var_password($3,$5)); } + ; internal_variable_name: ident @@ -3575,6 +3801,7 @@ internal_variable_name: YYABORT; $$=tmp; } + ; isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } @@ -3595,8 +3822,8 @@ text_or_password: make_scrambled_password(buff,$3.str); $$=buff; } - }; - + } + ; set_expr_or_default: expr { $$=$1; } @@ -3613,28 +3840,34 @@ lock: { Lex->sql_command=SQLCOM_LOCK_TABLES; } - table_lock_list; + table_lock_list + ; table_or_tables: TABLE_SYM - | TABLES; + | TABLES + ; table_lock_list: table_lock - | table_lock_list ',' table_lock; + | table_lock_list ',' table_lock + ; table_lock: table_ident opt_table_alias lock_option - { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; }; + { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; } + ; lock_option: READ_SYM { $$=TL_READ_NO_INSERT; } | WRITE_SYM { $$=current_thd->update_lock_default; } | LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; } - | READ_SYM LOCAL_SYM { $$= TL_READ; }; + | READ_SYM LOCAL_SYM { $$= TL_READ; } + ; unlock: - UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; }; + UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; } + ; /* @@ -3664,15 +3897,18 @@ handler: if (!add_table_to_list($2,0,0)) YYABORT; } - handler_read_or_scan where_clause limit_clause { }; + handler_read_or_scan where_clause limit_clause { } + ; handler_read_or_scan: handler_scan_function { Lex->backup_dir= 0; } - | ident handler_rkey_function { Lex->backup_dir= $1.str; }; + | ident handler_rkey_function { Lex->backup_dir= $1.str; } + ; handler_scan_function: FIRST_SYM { Lex->ha_read_mode = RFIRST; } - | NEXT_SYM { Lex->ha_read_mode = RNEXT; }; + | NEXT_SYM { Lex->ha_read_mode = RNEXT; } + ; handler_rkey_function: FIRST_SYM { Lex->ha_read_mode = RFIRST; } @@ -3680,20 +3916,23 @@ handler_rkey_function: | PREV_SYM { Lex->ha_read_mode = RPREV; } | LAST_SYM { Lex->ha_read_mode = RLAST; } | handler_rkey_mode - { - LEX *lex=Lex; - lex->ha_read_mode = RKEY; - lex->ha_rkey_mode=$1; - if (!(lex->insert_list = new List_item)) - YYABORT; - } '(' values ')' { }; + { + LEX *lex=Lex; + lex->ha_read_mode = RKEY; + lex->ha_rkey_mode=$1; + if (!(lex->insert_list = new List_item)) + YYABORT; + } + '(' values ')' { } + ; handler_rkey_mode: EQ { $$=HA_READ_KEY_EXACT; } | GE { $$=HA_READ_KEY_OR_NEXT; } | LE { $$=HA_READ_KEY_OR_PREV; } | GT_SYM { $$=HA_READ_AFTER_KEY; } - | LT { $$=HA_READ_BEFORE_KEY; }; + | LT { $$=HA_READ_BEFORE_KEY; } + ; /* GRANT / REVOKE */ @@ -3710,7 +3949,8 @@ revoke: lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; bzero((char*) &lex->mqh, sizeof(lex->mqh)); } - grant_privileges ON opt_table FROM user_list; + grant_privileges ON opt_table FROM user_list + ; grant: GRANT @@ -3726,16 +3966,19 @@ grant: bzero(&(lex->mqh),sizeof(lex->mqh)); } grant_privileges ON opt_table TO_SYM user_list - require_clause grant_options; + require_clause grant_options + ; grant_privileges: grant_privilege_list {} | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;} - | ALL { Lex->grant = GLOBAL_ACLS;}; + | ALL { Lex->grant = GLOBAL_ACLS;} + ; grant_privilege_list: grant_privilege - | grant_privilege_list ',' grant_privilege; + | grant_privilege_list ',' grant_privilege + ; grant_privilege: SELECT_SYM { Lex->which_columns = SELECT_ACL;} opt_column_list @@ -3762,7 +4005,6 @@ grant_privilege: | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;} ; - opt_and: /* empty */ {} | AND {} @@ -3850,8 +4092,8 @@ opt_table: YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; - }; - + } + ; user_list: grant_user { if (Lex->users_list.push_back($1)) YYABORT;} @@ -3862,7 +4104,6 @@ user_list: } ; - grant_user: user IDENTIFIED_SYM BY TEXT_STRING { @@ -3881,8 +4122,8 @@ grant_user: | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING { $$=$1; $1->password=$5 ; } | user - { $$=$1; $1->password.str=NullS; }; - + { $$=$1; $1->password.str=NullS; } + ; opt_column_list: /* empty */ @@ -3890,11 +4131,13 @@ opt_column_list: LEX *lex=Lex; lex->grant |= lex->which_columns; } - | '(' column_list ')'; + | '(' column_list ')' + ; column_list: column_list ',' column_list_id - | column_list_id; + | column_list_id + ; column_list_id: ident @@ -3914,8 +4157,8 @@ column_list_id: point->rights |= lex->which_columns; else lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns)); - }; - + } + ; require_clause: /* empty */ | REQUIRE_SYM require_list @@ -3934,14 +4177,17 @@ require_clause: /* empty */ { Lex->ssl_type=SSL_TYPE_NONE; } + ; grant_options: /* empty */ {} - | WITH grant_option_list; + | WITH grant_option_list + ; grant_option_list: grant_option_list grant_option {} - | grant_option {}; + | grant_option {} + ; grant_option: GRANT OPTION { Lex->grant |= GRANT_ACL;} @@ -3959,20 +4205,25 @@ grant_option: { Lex->mqh.connections=$2; Lex->mqh.bits |= 4; - }; + } + ; begin: - BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work; + BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work + ; opt_work: /* empty */ {} - | WORK_SYM {;}; + | WORK_SYM {} + ; commit: - COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}; + COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT; } + ; rollback: - ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;}; + ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK; } + ; /* @@ -3982,7 +4233,8 @@ rollback: union: /* empty */ {} - | union_list; + | union_list + ; union_list: UNION_SYM union_option @@ -4008,7 +4260,8 @@ union_list: union_opt: union {} - | optional_order_or_limit {}; + | optional_order_or_limit {} + ; optional_order_or_limit: /* empty */ {} @@ -4034,44 +4287,51 @@ optional_order_or_limit: union_option: /* empty */ {} - | ALL {Lex->union_option=1;}; + | ALL {Lex->union_option=1; } + ; singleval_subselect: subselect_start singleval_subselect_init subselect_end { $$= $2; - }; + } + ; singleval_subselect_init: select_init { $$= new Item_singleval_subselect(current_thd, Lex->select); - }; + } + ; exists_subselect: subselect_start exists_subselect_init subselect_end { $$= $2; - }; + } + ; exists_subselect_init: select_init { $$= new Item_exists_subselect(current_thd, Lex->select); - }; + } + ; subselect_start: '(' { if (mysql_new_select(Lex, 1)) YYABORT; - }; + } + ; subselect_end: ')' { LEX *lex=Lex; lex->select = lex->select->outer_select(); - }; + } + ; From 3207ac185c66d9a85e8d6ede617f0094c8315ef4 Mon Sep 17 00:00:00 2001 From: "bk@admin.bk" <> Date: Sun, 20 Oct 2002 21:26:25 +0200 Subject: [PATCH 03/83] BK automatic LOD removal. --- BitKeeper/etc/gone | 2324 +++++++++++++++++++------------------- BitKeeper/etc/logging_ok | 5 +- BitKeeper/etc/skipkeys | 7 + 3 files changed, 1173 insertions(+), 1163 deletions(-) create mode 100644 BitKeeper/etc/skipkeys diff --git a/BitKeeper/etc/gone b/BitKeeper/etc/gone index 03c7cacb8bc..5f2b9e1209d 100644 --- a/BitKeeper/etc/gone +++ b/BitKeeper/etc/gone @@ -1,8 +1,27 @@ BK|Build-tools/Do-compile-all|19700101030959|00060|f119832ce3aca102 +BK|Docs/Attic/myisam.doc|19700101030959|00502|519bb06ecc870298 +BK|Docs/Flags/island.eps|19700101030959|00181|8cec5a55768bc59e +BK|Docs/Flags/island.gif|19700101030959|00142|e274d5e96ee0975a +BK|Docs/Flags/island.txt|19700101030959|00220|301ede0f81c5f3e1 +BK|Docs/Flags/kroatia.eps|19700101030959|00185|f50fcd444e7efceb +BK|Docs/Flags/kroatia.gif|19700101030959|00146|bea7bbe0316d462d +BK|Docs/Flags/kroatia.txt|19700101030959|00224|dde7f89f25d616b2 +BK|Docs/Flags/south-africa1.eps|19700101030959|00193|111e4f92f4562e9d +BK|Docs/Flags/south-africa1.gif|19700101030959|00154|1ea38de5a535f732 +BK|Docs/Flags/south-africa1.txt|19700101030959|00232|87a53fdcd2149c6e +BK|client/Attic/libmysql.c|19700101030959|00582|72949a7043113807 +BK|client/Attic/net.c|19700101030959|00583|c18042da6fa4e693 BK|client/mysql-test.c|19700101030959|00560|809ade45d58e28ab +BK|client/violite.c|19700101030959|00561|afa871b4aab14371 BK|config.h.in|19700101030959|00050|aecae693cca472c +BK|extra/Attic/print_defaults.c|19700101030959|01513|362952979aa7b330 +BK|include/Attic/config-win32.h|19700101030959|00116|65db818ec7e8f21b +BK|include/Attic/m_ctype.h.in|19700101030959|00114|f671e3c2d611ba97 +BK|include/Attic/mysql_com.h.in|19700101030959|00115|85b1ea7ced528c32 BK|include/my_global.h|19700101030959|00105|f657f708961a4632 BK|libmysql/acconfig.h|19700101030959|02604|7b620dbd69ea6074 +BK|libmysql/configure.in|19700101030959|02603|c6fc04d4e3d6e291 +BK|libmysql/violite.c|19700101030959|02600|984c09cffe14a11b BK|mit-pthreads/config.flags|19700101030959|00594|dcec5296ef811cd6 BK|mit-pthreads/machdep/i386-sco-3.2v5/__math.h|19700101030959|01011|79d9a37715f2c7fe BK|mit-pthreads/machdep/i386-sco-3.2v5/__signal.h|19700101030959|01012|45332b2a56f62580 @@ -32,9 +51,15 @@ BK|mit-pthreads/machdep/sco-3.2v5/socket.h|19700101030959|00980|1b409f3f1fcbbf7a BK|mit-pthreads/machdep/sco-3.2v5/syscall.h|19700101030959|00981|c69bd58eba4d5076 BK|mit-pthreads/machdep/sco-3.2v5/timers.h|19700101030959|00982|4907a958151368ed BK|mit-pthreads/machdep/sco-3.2v5/trash.can|19700101030959|00983|7eecac9fc944ade2 +BK|mit-pthreads/pg++|19700101030959|00597|3beac0502025d766 +BK|mit-pthreads/pgcc|19700101030959|00596|154a03d0c1a0a600 +BK|myisam/Attic/ft_global.h|19700101030959|01673|fe46fb515f1e375 BK|myisam/common_words|19700101030959|01665|13c10ef32aaa7537 +BK|myisam/ft_search.c|19700101030959|01642|c011cb6e8041bb59 BK|myisam/mi_test_all|19700101030959|01666|ae7a366c45527b4e +BK|mysql.proj|19700101030959|00071|3e34edc585d18be8 BK|mysys/mf_reccache.c|19700101030959|01419|f8191c8485e158fe +BK|mysys/test_vsnprintf.c|19700101030959|01502|e3d568aca62dc81e BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02361|6a0a837742a861bb BK|sql-bench/Results-linux/ATIS-interbase-Linux_2.2.14_5.0_i686|19700101030959|02348|e87091e2a6dce931 BK|sql-bench/Results-linux/ATIS-mysql-Linux_2.0.33_i586-cmp-access,mysql|19700101030959|02326|70981cb1dd58d3fb @@ -161,10 +186,21 @@ BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.12_20smp_i686|1970010103095 BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.13_SMP_alpha|19700101030959|02347|ad7babd436f26841 BK|sql-bench/Results-linux/wisconsin-mysql-Linux_2.2.14_5.0_i686-cmp-interbase,mysql|19700101030959|02442|74b238eca114dbbe BK|sql-bench/Results-linux/wisconsin-mysql_fast-Linux_2.2.13_SMP_alpha|19700101030959|02451|6ad065fe4c6b4fa9 +BK|sql-bench/Results-win32/ATIS-mysql-win98|19700101030959|02523|cd0705815d3af451 +BK|sql-bench/Results-win32/RUN-mysql-win98|19700101030959|02526|7f09e396772a8665 +BK|sql-bench/Results-win32/alter-table-mysql-win98|19700101030959|02529|e8743982f790462 +BK|sql-bench/Results-win32/big-tables-mysql-win98|19700101030959|02532|99a1882effebbdf2 +BK|sql-bench/Results-win32/connect-mysql-win98|19700101030959|02535|2a11d5e3dfc0bc67 +BK|sql-bench/Results-win32/create-mysql-win98|19700101030959|02538|f66c2cb2909c4792 +BK|sql-bench/Results-win32/insert-mysql-win98|19700101030959|02541|6d6cafc85a6c837 +BK|sql-bench/Results-win32/select-mysql-win98|19700101030959|02544|f370fac2d66a9faf +BK|sql-bench/Results-win32/wisconsin-mysql-win98|19700101030959|02547|8b3da9c5c5d2365b +BK|sql-bench/Results/ATIS-mysql-3.21-Linux_2.2.1_i686|19700101030959|02022|660fb76ed6ccfb6f BK|sql-bench/Results/ATIS-mysql-Linux_2.2.10_i686|19700101030959|02025|3fa4d167cceff7e8 BK|sql-bench/Results/ATIS-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02312|84ca3b85ff306133 BK|sql-bench/Results/ATIS-mysql-Linux_2.2.14_i686_xeon|19700101030959|02044|3e820c28bf4af63a BK|sql-bench/Results/ATIS-mysql-SunOS_5.6_sun4m|19700101030959|02032|62028e0375b3b8b +BK|sql-bench/Results/ATIS-mysql_3.21-Linux_2.0.35_i686|19700101030959|02036|c25425e045ca8dfc BK|sql-bench/Results/ATIS-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02304|cbe120d860296d2f BK|sql-bench/Results/ATIS-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02027|a74e7b82d3908fa9 BK|sql-bench/Results/ATIS-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02313|8c6fc2968f78773 @@ -223,77 +259,258 @@ BK|sql-bench/Results/Attic/wisconsin-mysql-Linux_2.2.1_i686-cmp-mysql,pg|1970010 BK|sql-bench/Results/Attic/wisconsin-mysql_fast-Linux_2.2.10_i686-cmp-mysql,pg|19700101030959|02218|b4e89cdac0620cba BK|sql-bench/Results/Attic/wisconsin-pg-Linux_2.2.10_i686-cmp-mysql,pg|19700101030959|02219|7d641554f51cf45a BK|sql-bench/Results/Attic/wisconsin-pg_fast-Linux_2.2.10_i686-cmp-mysql,pg|19700101030959|02220|db31ec971b4c5051 +BK|sql-bench/Results/RUN-mysql-3.21-Linux_2.2.1_i686|19700101030959|02050|f6fdd64859e11de9 BK|sql-bench/Results/RUN-mysql-Linux_2.2.10_i686|19700101030959|02041|712f52be5d195406 BK|sql-bench/Results/RUN-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02038|8ee87b26b91c86fe BK|sql-bench/Results/RUN-mysql-Linux_2.2.14_i686_xeon|19700101030959|02055|17854e751e1d9d1d BK|sql-bench/Results/RUN-mysql-SunOS_5.6_sun4m|19700101030959|02059|eafc8188345e262b +BK|sql-bench/Results/RUN-mysql_3.21-Linux_2.0.35_i686|19700101030959|02064|ea8672d8473435 BK|sql-bench/Results/RUN-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02310|a902e1a967d79c42 BK|sql-bench/Results/RUN-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02030|413ab3b8a99e61e9 BK|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02046|a910a9b3fde431e1 BK|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02165|e0f060fdbf92325e +BK|sql-bench/Results/alter-table-mysql-3.21-Linux_2.2.1_i686|19700101030959|02073|f6f7ccd7b3c35f97 BK|sql-bench/Results/alter-table-mysql-Linux_2.2.10_i686|19700101030959|02081|93b78a85b720a186 BK|sql-bench/Results/alter-table-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02314|4ae4b989301df98b BK|sql-bench/Results/alter-table-mysql-Linux_2.2.14_i686_xeon|19700101030959|02057|64cc4b874cd6fabf BK|sql-bench/Results/alter-table-mysql-SunOS_5.6_sun4m|19700101030959|02088|8a1bd6589a189890 +BK|sql-bench/Results/alter-table-mysql_3.21-Linux_2.0.35_i686|19700101030959|02092|762639f2560976bd BK|sql-bench/Results/alter-table-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02316|1390155aad5b6e86 BK|sql-bench/Results/alter-table-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02317|9090bebb62ef164b BK|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02094|4e02d36dc17ecbfa BK|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02233|b8721431b356177 +BK|sql-bench/Results/big-tables-mysql-3.21-Linux_2.2.1_i686|19700101030959|02106|baa649caba113497 BK|sql-bench/Results/big-tables-mysql-Linux_2.2.10_i686|19700101030959|02109|99daa1c5370d077d BK|sql-bench/Results/big-tables-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02315|2804ec3c95be436a BK|sql-bench/Results/big-tables-mysql-Linux_2.2.14_i686_xeon|19700101030959|02074|290c2c3de9d8e6b BK|sql-bench/Results/big-tables-mysql-SunOS_5.6_sun4m|19700101030959|02116|f351a7f3e1e2257e +BK|sql-bench/Results/big-tables-mysql_3.21-Linux_2.0.35_i686|19700101030959|02120|190e827e569c99a4 BK|sql-bench/Results/big-tables-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02318|c5eabcb89ceac698 BK|sql-bench/Results/big-tables-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02319|856d503725373684 BK|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02122|a442a8aff47fae20 BK|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02235|e5a33639e51290fd +BK|sql-bench/Results/connect-mysql-3.21-Linux_2.2.1_i686|19700101030959|02134|c0c26d4320182d85 BK|sql-bench/Results/connect-mysql-Linux_2.2.10_i686|19700101030959|02137|c92505d77e19d5ec BK|sql-bench/Results/connect-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02084|e7e2959b7387251f BK|sql-bench/Results/connect-mysql-Linux_2.2.14_i686_xeon|19700101030959|02071|ea19dc3ec55b3618 BK|sql-bench/Results/connect-mysql-SunOS_5.6_sun4m|19700101030959|02143|a10e3ddfa26a3e7f +BK|sql-bench/Results/connect-mysql_3.21-Linux_2.0.35_i686|19700101030959|02146|650abd213e6828c6 BK|sql-bench/Results/connect-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02320|ce69cc65bc827b5c BK|sql-bench/Results/connect-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02066|f801e08429a4f7c6 BK|sql-bench/Results/connect-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02086|1d95d36fd717990 BK|sql-bench/Results/connect-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02244|f6ab4d00b0ae09c1 +BK|sql-bench/Results/create-mysql-3.21-Linux_2.2.1_i686|19700101030959|02158|51581b24f45e0f5c BK|sql-bench/Results/create-mysql-Linux_2.2.10_i686|19700101030959|02161|9e7822f66df6aa76 BK|sql-bench/Results/create-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02102|34ded91c5fc25de9 BK|sql-bench/Results/create-mysql-Linux_2.2.14_i686_xeon|19700101030959|02139|50d15991293030ef BK|sql-bench/Results/create-mysql-SunOS_5.6_sun4m|19700101030959|02221|9233114ae6f8c5f +BK|sql-bench/Results/create-mysql_3.21-Linux_2.0.35_i686|19700101030959|02225|df1b037d17b33587 BK|sql-bench/Results/create-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02321|e985e71d552ff09e BK|sql-bench/Results/create-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02099|483dcf223d5abf81 BK|sql-bench/Results/create-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02112|a140e5e229a53b7b BK|sql-bench/Results/create-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02246|177fd39cc1d298a8 +BK|sql-bench/Results/insert-mysql-3.21-Linux_2.2.1_i686|19700101030959|02239|fd082017c7c57a6 BK|sql-bench/Results/insert-mysql-Linux_2.2.10_i686|19700101030959|02242|763edf9aec633f51 BK|sql-bench/Results/insert-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02130|5be3d6f299738a31 BK|sql-bench/Results/insert-mysql-Linux_2.2.14_i686_xeon|19700101030959|02141|c683ee4b9d214298 BK|sql-bench/Results/insert-mysql-SunOS_5.6_sun4m|19700101030959|02248|3402d060ae20e19 +BK|sql-bench/Results/insert-mysql_3.21-Linux_2.0.35_i686|19700101030959|02252|60c0965dff31db07 BK|sql-bench/Results/insert-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02322|ed252140ff399961 BK|sql-bench/Results/insert-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02114|29a3b8a1ca8aa9d BK|sql-bench/Results/insert-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02148|e65dd14f2ed9abbf BK|sql-bench/Results/insert-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02259|b5bf77586c18d2b5 +BK|sql-bench/Results/select-mysql-3.21-Linux_2.2.1_i686|19700101030959|02265|ed3687e713ff0571 BK|sql-bench/Results/select-mysql-Linux_2.2.10_i686|19700101030959|02268|a2e264d777b787d BK|sql-bench/Results/select-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02227|308117295c3bc096 BK|sql-bench/Results/select-mysql-Linux_2.2.14_i686_xeon|19700101030959|02152|ead3f11b46ac626f BK|sql-bench/Results/select-mysql-SunOS_5.6_sun4m|19700101030959|02274|4da215905bce988d +BK|sql-bench/Results/select-mysql_3.21-Linux_2.0.35_i686|19700101030959|02278|5fadbac5f98696a BK|sql-bench/Results/select-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02323|e8c0871a668a610d BK|sql-bench/Results/select-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02127|963a98ed526e2be4 BK|sql-bench/Results/select-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02254|f9ab7726ff14ea90 BK|sql-bench/Results/select-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02261|188d6b5b72d8e0a +BK|sql-bench/Results/wisconsin-mysql-3.21-Linux_2.2.1_i686|19700101030959|02290|8147dc16a1dc6c47 BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.10_i686|19700101030959|02288|301a82b12a84922b BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02280|d01900af34fb33b8 BK|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_i686_xeon|19700101030959|02154|7525b23938631801 BK|sql-bench/Results/wisconsin-mysql-SunOS_5.6_sun4m|19700101030959|02298|ec61b14072715dc8 +BK|sql-bench/Results/wisconsin-mysql_3.21-Linux_2.0.35_i686|19700101030959|02302|31703d40ea6b4f66 BK|sql-bench/Results/wisconsin-mysql_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02324|ec075a89dbdbbe6a BK|sql-bench/Results/wisconsin-pg-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02325|233d5aa529979990 BK|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_5.0_i686-cmp-mysql,pg|19700101030959|02295|ec361eee4f4128cd BK|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_5.0_i686|19700101030959|02270|ef201ca14f635c57 +BK|sql/Attic/lex_hash.h|19700101030959|01912|14f912771118b50c +BK|sql/Attic/mini_client.c|19700101030959|01910|9a3778c387d06a81 +BK|sql/Attic/mini_client_errors.c|19700101030959|01909|29edad51a5d0b068 +BK|sql/Attic/mybinlogdump.cc|19700101030959|01908|5dbdd2bde98d6169 +BK|sql/Attic/net_serv.c|19700101030959|01911|52dabcd773a39e10 +BK|sql/ha_hash.h|19700101030959|01902|27e36916116beb3e +BK|sql/share/czech/errmsg.sys|19700101030959|01828|93104a2bd5c732a +BK|sql/share/danish/errmsg.sys|19700101030959|01831|3a6d0fb8451a3313 +BK|sql/share/dutch/errmsg.sys|19700101030959|01833|b5aff4d08478bafd +BK|sql/share/english/errmsg.sys|19700101030959|01834|f29bd4ea5aaf54c8 +BK|sql/share/estonia/errmsg.sys|19700101030959|01836|83b86d7ed4cdd5d0 +BK|sql/share/french/errmsg.sys|19700101030959|01838|9f024dc5e6fe50f5 +BK|sql/share/german/errmsg.sys|19700101030959|01840|1ea60675399c84c +BK|sql/share/greek/errmsg.sys|19700101030959|01842|fedf585fa73e7cf1 +BK|sql/share/hungarian/errmsg.sys|19700101030959|01845|aff82c16a77fc800 +BK|sql/share/italian/errmsg.sys|19700101030959|01846|c5108ecb850b79a +BK|sql/share/japanese/errmsg.sys|19700101030959|01848|302478c84697dc00 +BK|sql/share/korean/errmsg.sys|19700101030959|01850|a30e3687ae75a7c9 +BK|sql/share/norwegian-ny/.cvsignore|19700101030959|01855|469064b5190d703d +BK|sql/share/norwegian/.cvsignore|19700101030959|01853|a91d63182f0b2366 +BK|sql/share/polish/errmsg.sys|19700101030959|01857|126b03af92054f0f +BK|sql/share/portuguese/errmsg.sys|19700101030959|01859|c0187322f8c9d805 +BK|sql/share/romania/errmsg.sys|19700101030959|01871|e08aa93bae96d25e BK|sql/share/romanian/errmsg.sys|19700101030959|01869|9d8282efb437e8cc BK|sql/share/romanian/errmsg.txt|19700101030959|01870|2c64fb13a8f104ad +BK|sql/share/russian/errmsg.sys|19700101030959|01860|72688df0beeabcb3 +BK|sql/share/slovak/errmsg.sys|19700101030959|01862|148510616ae825cf +BK|sql/share/spanish/errmsg.sys|19700101030959|01865|10c8f32da39070b2 +BK|sql/share/swedish/errmsg.sys|19700101030959|01866|dd772e93db859993 +BK|sql/violite.c|19700101030959|01738|d7b85be615595ace +BK|strings/Attic/bootstrap-ctype.c|19700101030959|01360|6d2a8cda2d6a35ff +BK|strings/Attic/ct_init.c|19700101030959|01338|f0948bdd35ceedc3 +BK|strings/Attic/ctype-cp1251.c|19700101030959|01339|cdf74b9168408b3 +BK|strings/Attic/ctype-cp1257.c|19700101030959|01340|732611cbc74aeafc +BK|strings/Attic/ctype-croat.c|19700101030959|01341|d2d805ee6f10cbcc +BK|strings/Attic/ctype-danish.c|19700101030959|01342|dc5451066eb272ae +BK|strings/Attic/ctype-dec8.c|19700101030959|01343|68f257dd2202d0c7 +BK|strings/Attic/ctype-dos.c|19700101030959|01344|f77bd08acf13a8c1 +BK|strings/Attic/ctype-estonia.c|19700101030959|01345|fc8a69424f7cb66b +BK|strings/Attic/ctype-german1.c|19700101030959|01346|f7830c509bb358f7 +BK|strings/Attic/ctype-greek.c|19700101030959|01347|90acdff1195209ca +BK|strings/Attic/ctype-hebrew.c|19700101030959|01348|d3b4a000d51e76dc +BK|strings/Attic/ctype-hp8.c|19700101030959|01349|749e1be0f028d349 +BK|strings/Attic/ctype-hungarian.c|19700101030959|01350|5cf0bf7fa0312637 +BK|strings/Attic/ctype-koi8_ru.c|19700101030959|01351|8ff4188c642c9bd +BK|strings/Attic/ctype-koi8_ukr.c|19700101030959|01352|a04aa14a6d62335a +BK|strings/Attic/ctype-latin1.c|19700101030959|01353|cc63880f19c2303e +BK|strings/Attic/ctype-latin2.c|19700101030959|01354|31895c4b83654342 +BK|strings/Attic/ctype-swe7.c|19700101030959|01355|bb1b012225d7d02c +BK|strings/Attic/ctype-usa7.c|19700101030959|01356|d19d859dca5675f +BK|strings/Attic/ctype-win1250.c|19700101030959|01357|1ce7a24255780a1 +BK|strings/Attic/ctype-win1251.c|19700101030959|01358|762607f4fd7d52ad +BK|strings/Attic/ctype-win1251ukr.c|19700101030959|01359|b5a7cca889bbef58 +BK|strings/Attic/ctype.c.in|19700101030959|01361|8bf48d4bcbc5f675 +BK|strings/Attic/memory.h|19700101030959|01336|450f586e82a26d99 +BK|strings/Attic/ptr_cmp.c|19700101030959|01337|57e682a26e769597 +BK|strings/READ-ME|19700101030959|01362|ed6c5184d4bf6b7c +BK|support-files/Attic/my-example.cnf.sh|19700101030959|02584|87a7e1f4d24b62a9 +BK|support-files/Attic/my-huge.cfg.sh|19700101030959|02585|589bdcd2d2c4360b +BK|support-files/Attic/my-large.cfg.sh|19700101030959|02586|842c8e76253c9396 +BK|support-files/Attic/my-medium.cfg.sh|19700101030959|02587|c49880d26ef0648e +BK|support-files/Attic/my-small.cfg.sh|19700101030959|02588|85023c559a1d96c +BK|tests/fork3_test.pl|19700101030959|01947|c4a7bffb4f8e813c +BK|tests/fork_test.pl|19700101030959|01945|3d3535329ed8cd5e +BK|vio/Vio.cc|19700101030959|00003|60737ce02ab2bc25 +BK|vio/Vio.h|19700101030959|00004|f4416b2949647602 +BK|vio/VioAcceptorFd.cc|19700101030959|00005|a5a08947a31f88de +BK|vio/VioAcceptorFd.h|19700101030959|00006|7f9c4358477ba9a3 +BK|vio/VioConnectorFd.cc|19700101030959|00007|ddbd7821c43c83a2 +BK|vio/VioConnectorFd.h|19700101030959|00008|58bc11cdc885b951 +BK|vio/VioFd.cc|19700101030959|00009|6e444647affef63b +BK|vio/VioFd.h|19700101030959|00010|8294293a88c7b4b8 +BK|vio/VioPipe.cc|19700101030959|00011|12cf83b9a2f48f6c +BK|vio/VioPipe.h|19700101030959|00012|21cebbe61a1da546 +BK|vio/VioSSL.cc|19700101030959|00013|6e85340b11fa42a8 +BK|vio/VioSSL.h|19700101030959|00014|70d367b7ec8cac3e +BK|vio/VioSSLAcceptorFd.cc|19700101030959|00015|4c828f3688ed74ec +BK|vio/VioSSLFactoriesFd.cc|19700101030959|00016|89f6bf5073937947 +BK|vio/VioSSLFactoriesFd.h|19700101030959|00017|1d63ae149a63f85 +BK|vio/VioSocket.cc|19700101030959|00018|71c615783f29b5e1 +BK|vio/VioSocket.h|19700101030959|00019|a26d535bd5a1a6 +BK|vio/version.cc|19700101030959|00020|7237acf12bed4a97 +BK|vio/vio-global.h|19700101030959|00021|c261412c01b2f4 +BK|vio/vioelitexx.cc|19700101030959|00022|3eaba70da792a7fc +BK|vio/violite.h|19700101030959|00023|58d2942a52ea7a83 +BK|vio/viotypes.h|19700101030959|00027|f5a38e7326bd50f3 +Sinisa@sinisa.nasamreza.org|=6|20010818122920|53462|33f33b0a159dc5d5 +Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522121240|20995|360af2095c88cb8c +Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522133259|25000|4b5fbc60d0d9754f +Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133300|08911|21904fbd1c95cb1 +Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133624|23665|445526a8a20de101 +Sinisa@sinisa.nasamreza.org|scripts/mysql_new_fix_privilege_tables.sh|20011226144909|43765|b1664b401375eece +arjen@co3064164-a.bitbike.com|BitKeeper/etc/logging_ok|20011212060636|33009 +arjen@co3064164-a.bitbike.com|Docs/section.Comparisons.texi|20011108043647|22614|692b647b +arjen@fred.bitbike.com|scripts/mysql_fix_extensions.sh|20020516001337|12363|f1048a78f4759b4d +ccarkner@nslinuxw10.bedford.progress.com|mysql-test/r/isolation.result|20010327145543|25059|4da11e109a3d93a9 +ccarkner@nslinuxw10.bedford.progress.com|mysql-test/t/isolation.test|20010327145543|39049|6a39e4138dd4a456 +jani@hynda.mysql.fi|client/mysqlcheck|20010419221207|26716|363e3278166d84ec +jcole@tetra.bedford.progress.com|BitKeeper/etc/logging_ok|20001004201211|30554 +miguel@hegel.local|zlib/ChangeLog|20020319032513|28917|5d5425fc84737083 miguel@hegel.local|zlib/Make_vms.com|20020319032513|57151|35050a50ec612bbf miguel@hegel.local|zlib/Makefile.riscos|20020319032513|63798|8ab53f195fe429af +miguel@hegel.local|zlib/adler32.c|20020319032513|04487|f98728c6da1ac164 +miguel@hegel.local|zlib/algorithm.txt|20020319032513|12903|fbc4dda3d31c2005 miguel@hegel.local|zlib/amiga/Makefile.pup|20020319032513|19225|6a9ee8128d11541f miguel@hegel.local|zlib/amiga/Makefile.sas|20020319032513|25562|d7128ac7e0946f0b +miguel@hegel.local|zlib/compress.c|20020319032513|32512|70bccb304651dba9 +miguel@hegel.local|zlib/contrib/README.contrib|20020319032514|04353|24cb75bee0a061fb +miguel@hegel.local|zlib/contrib/asm386/gvmat32.asm|20020319032514|12654|31093c1a846dfdc7 +miguel@hegel.local|zlib/contrib/asm386/gvmat32c.c|20020319032514|19182|2a8eba5481c46eab +miguel@hegel.local|zlib/contrib/asm386/mkgvmt32.bat|20020319032514|25425|422cbe16a6e74695 +miguel@hegel.local|zlib/contrib/asm386/zlibvc.def|20020319032514|31637|605ee23b8a4a6a1a +miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsp|20020319032514|38372|a1c6749052ce48a +miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsw|20020319032514|44870|3209982720f131ab +miguel@hegel.local|zlib/contrib/asm586/match.s|20020319032514|51538|dc1a34b5eb2a7c11 +miguel@hegel.local|zlib/contrib/asm586/readme.586|20020319032514|57815|f60bfeefb27217d +miguel@hegel.local|zlib/contrib/asm686/match.s|20020319032514|64199|4164951e8e19f116 +miguel@hegel.local|zlib/contrib/asm686/readme.686|20020319032514|04933|15e2bf4653b71f3e +miguel@hegel.local|zlib/contrib/delphi/zlib.mak|20020319032514|11153|7b97eb8cf290a42 +miguel@hegel.local|zlib/contrib/delphi/zlibdef.pas|20020319032514|18918|658cb04db561e3db +miguel@hegel.local|zlib/contrib/delphi2/d_zlib.bpr|20020319032514|25335|c267d77cc2e2a2c8 +miguel@hegel.local|zlib/contrib/delphi2/d_zlib.cpp|20020319032514|31641|d6f37620ac7b27fa +miguel@hegel.local|zlib/contrib/delphi2/readme.txt|20020319032515|03494|65d16837f8579e23 +miguel@hegel.local|zlib/contrib/delphi2/zlib.bpg|20020319032515|09768|93c030edcca1838 +miguel@hegel.local|zlib/contrib/delphi2/zlib.bpr|20020319032515|16113|7a2fa98af2345144 +miguel@hegel.local|zlib/contrib/delphi2/zlib.cpp|20020319032515|22372|4257437d415259e2 +miguel@hegel.local|zlib/contrib/delphi2/zlib.pas|20020319032515|28965|3c94d3f5262cbbdd +miguel@hegel.local|zlib/contrib/delphi2/zlib32.bpr|20020319032515|35585|41ac53acb8008ff7 +miguel@hegel.local|zlib/contrib/delphi2/zlib32.cpp|20020319032515|41979|3b0f51435e880afe +miguel@hegel.local|zlib/contrib/iostream/test.cpp|20020319032515|48225|a2ea8d4d7c66cf71 +miguel@hegel.local|zlib/contrib/iostream/zfstream.cpp|20020319032515|55262|dce18d1a5d7096b7 +miguel@hegel.local|zlib/contrib/iostream/zfstream.h|20020319032515|61553|2b4d88acc2d3b714 +miguel@hegel.local|zlib/contrib/iostream2/zstream.h|20020319032515|02537|351f26518ea48196 +miguel@hegel.local|zlib/contrib/iostream2/zstream_test.cpp|20020319032515|08848|63f635d540de8c48 +miguel@hegel.local|zlib/contrib/minizip/ChangeLogUnzip|20020319032515|15183|50464416f4a3768f +miguel@hegel.local|zlib/contrib/minizip/miniunz.c|20020319032515|21943|6a80009b319b1b9e +miguel@hegel.local|zlib/contrib/minizip/minizip.c|20020319032515|28588|97181367a7bc47d8 +miguel@hegel.local|zlib/contrib/minizip/readme.txt|20020319032516|00611|7547b986c067c008 +miguel@hegel.local|zlib/contrib/minizip/unzip.c|20020319032516|07891|c66c95e17321206d +miguel@hegel.local|zlib/contrib/minizip/unzip.def|20020319032516|14456|b4162b8c833ab6c7 +miguel@hegel.local|zlib/contrib/minizip/unzip.h|20020319032516|21001|bac981086af91a30 +miguel@hegel.local|zlib/contrib/minizip/zip.c|20020319032516|27911|e82bf7774e1ece95 +miguel@hegel.local|zlib/contrib/minizip/zip.def|20020319032516|34413|e9bda2081d65c22e +miguel@hegel.local|zlib/contrib/minizip/zip.h|20020319032516|40925|17fd39ccb4ea294c +miguel@hegel.local|zlib/contrib/minizip/zlibvc.def|20020319032516|47259|6dc42f99d2d55cad +miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsp|20020319032516|54044|ec35fd54c9b49987 +miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsw|20020319032516|60515|17f28194a5cd80ea miguel@hegel.local|zlib/contrib/untgz/makefile.w32|20020319032516|01267|2c584f05a16db4ba +miguel@hegel.local|zlib/contrib/untgz/untgz.c|20020319032516|07726|b74e9dde74642756 +miguel@hegel.local|zlib/contrib/visual-basic.txt|20020319032516|14096|cd461e762199bb09 +miguel@hegel.local|zlib/crc32.c|20020319032516|20397|b327da5b8cf9eae8 +miguel@hegel.local|zlib/deflate.c|20020319032516|26978|e22894a54233bc25 +miguel@hegel.local|zlib/deflate.h|20020319032516|33700|3a012bc1f5dfbc74 +miguel@hegel.local|zlib/descrip.mms|20020319032517|08063|7d61d33062ef53ec +miguel@hegel.local|zlib/example.c|20020319032517|14327|490f57a4a9440dfa +miguel@hegel.local|zlib/faq|20020319032517|20799|b0d0840d3b9faf07 +miguel@hegel.local|zlib/gzio.c|20020319032517|27098|e02d23e656c19359 +miguel@hegel.local|zlib/index|20020319032517|33542|5443c9f841db4a47 +miguel@hegel.local|zlib/infblock.c|20020319032517|39853|540cc1b743be5f58 +miguel@hegel.local|zlib/infblock.h|20020319032517|46202|4526bc327b4160ab +miguel@hegel.local|zlib/infcodes.c|20020319032517|52620|dffb42fdf2fb2372 +miguel@hegel.local|zlib/infcodes.h|20020319032517|58960|3a02220a89c9a4fa +miguel@hegel.local|zlib/inffast.c|20020319032517|65269|bf247ff4aa2bf54b +miguel@hegel.local|zlib/inffast.h|20020319032517|06651|215e4a4ccfc886fc +miguel@hegel.local|zlib/inffixed.h|20020319032517|12923|e86ef8e2efe23f77 +miguel@hegel.local|zlib/inflate.c|20020319032517|19311|fb22a3a1ab6fb1a0 +miguel@hegel.local|zlib/inftrees.c|20020319032517|25758|4fcb97357cdbc40 +miguel@hegel.local|zlib/inftrees.h|20020319032517|32227|ffcbe51816466e5c +miguel@hegel.local|zlib/infutil.c|20020319032518|05244|a9b414f0f4ea0868 +miguel@hegel.local|zlib/infutil.h|20020319032518|12977|13089e09be34788c +miguel@hegel.local|zlib/maketree.c|20020319032518|19299|7f281aef3547fee +miguel@hegel.local|zlib/minigzip.c|20020319032518|25601|37f8eacb80c7f8fc miguel@hegel.local|zlib/msdos/Makefile.b32|20020319032518|33760|86772037f3344353 miguel@hegel.local|zlib/msdos/Makefile.bor|20020319032518|40099|7aa9edaac099cdb9 miguel@hegel.local|zlib/msdos/Makefile.dj2|20020319032518|46371|ca26f5fe96e3e999 @@ -302,11 +519,32 @@ miguel@hegel.local|zlib/msdos/Makefile.msc|20020319032518|59050|1bb69abdddf390f2 miguel@hegel.local|zlib/msdos/Makefile.tc|20020319032518|65341|2a9dff916115ae77 miguel@hegel.local|zlib/msdos/Makefile.w32|20020319032518|06083|8d84523c1dcdc0f7 miguel@hegel.local|zlib/msdos/Makefile.wat|20020319032518|12471|82f8714d825e97e3 +miguel@hegel.local|zlib/msdos/zlib.def|20020319032518|18787|165cd7dcff6ac9f +miguel@hegel.local|zlib/msdos/zlib.rc|20020319032518|25240|f8a286fa8371ee09 miguel@hegel.local|zlib/nt/Makefile.emx|20020319032518|31715|7e9fcf6f5ad2e51a miguel@hegel.local|zlib/nt/Makefile.gcc|20020319032519|03630|351fa8bd15c704b9 miguel@hegel.local|zlib/nt/Makefile.nt|20020319032519|09990|ee461a3dd393a061 +miguel@hegel.local|zlib/nt/zlib.dnt|20020319032519|16279|22a0ed3b86ff8c2 miguel@hegel.local|zlib/os2/Makefile.os2|20020319032519|22554|7a05f2a27812703a +miguel@hegel.local|zlib/os2/zlib.def|20020319032519|28842|1166a95d83c5f52c +miguel@hegel.local|zlib/readme|20020319032519|35257|80a41fc822f5f4 +miguel@hegel.local|zlib/trees.c|20020319032519|43770|4fbd4d005e26d38 +miguel@hegel.local|zlib/trees.h|20020319032519|50674|87161133bc2155fd +miguel@hegel.local|zlib/uncompr.c|20020319032519|57111|82eac43195d1222c +miguel@hegel.local|zlib/zconf.h|20020319032519|63437|c6b6b636c7e88d90 +miguel@hegel.local|zlib/zlib.3|20020319032519|04298|ec5cb4f64476f6a +miguel@hegel.local|zlib/zlib.dsp|20020319032519|12016|6eec436fab260061 +miguel@hegel.local|zlib/zlib.html|20020319032519|31060|7a635f4ac95fc56b +miguel@hegel.local|zlib/zlib.h|20020319032519|20598|fbec7833981c782f +miguel@hegel.local|zlib/zutil.c|20020319032520|05372|6f0d1763c5deb409 +miguel@hegel.local|zlib/zutil.h|20020319032520|12556|1e431b0173278fb2 +mikef@nslinux.bedford.progress.com|mysql-test/include/have_gemini.inc|20010321203410|40631|42f94f0dfd0f7b18 +mikef@nslinux.bedford.progress.com|mysql-test/r/have_gemini.require|20010321203410|47052|206702c48b2e206b +monty@donna.mysql.com|innobase/ib_config.h.in|20010217121901|07616|9e57db8504e55b7 +monty@donna.mysql.com|innobase/ib_config.h|20010217121901|04019|7539e26ffc614439 monty@donna.mysql.com|myisam/mi_debug.c|20000829092809|23459|873a6e7d6ff8297c +monty@donna.mysql.com|mysql-test/include/have_default_master.inc|20010104005638|23980|a54c86e65a6c4af +monty@donna.mysql.com|mysql-test/r/have_default_master.require|20010104005638|27332|1465255ffdaf82f monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|34755|45d7837423db243f monty@donna.mysql.com|sql-bench/Results-linux/ATIS-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|37262|2274651e29d38b07 monty@donna.mysql.com|sql-bench/Results-linux/RUN-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|39831|a6ef8229d40b75d1 @@ -325,7 +563,97 @@ monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug-Linux_2.2.14_my_ monty@donna.mysql.com|sql-bench/Results-linux/select-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|07610|cffd7d282a90113a monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug-Linux_2.2.14_my_SMP_i686|20001218140918|10615|8dcd7271a9137341 monty@donna.mysql.com|sql-bench/Results-linux/wisconsin-mysql_dbug_full-Linux_2.2.14_my_SMP_i686|20001218140918|13213|4398328883aa75da +monty@donna.mysql.com|sql-bench/Results/ATIS-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14134|cf0d806760eefef2 +monty@donna.mysql.com|sql-bench/Results/ATIS-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14777|e625af7f600bf930 +monty@donna.mysql.com|sql-bench/Results/RUN-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15344|d922a0fcc1009130 +monty@donna.mysql.com|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15933|840503a555e420ec +monty@donna.mysql.com|sql-bench/Results/alter-table-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|16525|2f516d2c108a9e05 +monty@donna.mysql.com|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17106|6e532c1936df1737 +monty@donna.mysql.com|sql-bench/Results/big-tables-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17709|6d8209bf72b663ed +monty@donna.mysql.com|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18309|c87333d6fe04433e +monty@donna.mysql.com|sql-bench/Results/connect-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18910|7ed15d6fd1a5944c +monty@donna.mysql.com|sql-bench/Results/connect-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|19522|ab58fffa30dce97e +monty@donna.mysql.com|sql-bench/Results/create-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20136|241c337935ae1524 +monty@donna.mysql.com|sql-bench/Results/create-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20766|4e5a2ab4907748d4 +monty@donna.mysql.com|sql-bench/Results/insert-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22042|27b7a557c3cb07a +monty@donna.mysql.com|sql-bench/Results/insert-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22723|a85a6f0477c13f83 +monty@donna.mysql.com|sql-bench/Results/select-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|23395|8ef771713f89e1 +monty@donna.mysql.com|sql-bench/Results/select-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24071|4f7795c27eaab86b +monty@donna.mysql.com|sql-bench/Results/wisconsin-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24748|6a468dcd3e6f5405 +monty@donna.mysql.com|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|25437|24a02e007a58bf73 +monty@donna.mysql.fi|sql/violite.c|20010523223654|08838|53d4251a69d3c +monty@hundin.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|32241|dd306b2e583ebde4 +monty@hundin.mysql.fi|sql-bench/Results/ATIS-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|59551|d002b0bc548ff8b3 +monty@hundin.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|35759|11038a44f73070e7 +monty@hundin.mysql.fi|sql-bench/Results/RUN-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|63204|e938a858bd12aa8d +monty@hundin.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|39143|662b96bc66bc91b6 +monty@hundin.mysql.fi|sql-bench/Results/alter-table-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|01419|14360865bbba479f +monty@hundin.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|42711|788ad492867b1226 +monty@hundin.mysql.fi|sql-bench/Results/big-tables-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|05113|b6be70bb51013cad +monty@hundin.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|46284|5316add301edb60 +monty@hundin.mysql.fi|sql-bench/Results/connect-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|08804|1b715c6fd72e913e +monty@hundin.mysql.fi|sql-bench/Results/create-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|49804|26e09af61f88d8c9 +monty@hundin.mysql.fi|sql-bench/Results/create-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|12309|f3b1d326092bf44 +monty@hundin.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|53328|fd2699adb3190d07 +monty@hundin.mysql.fi|sql-bench/Results/insert-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|15984|a0143553cccb54e2 +monty@hundin.mysql.fi|sql-bench/Results/select-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|56860|b01175ad38fd12b6 +monty@hundin.mysql.fi|sql-bench/Results/select-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|19688|4ffc9cf4be665ea2 +monty@hundin.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|60398|8ba598d217450157 +monty@hundin.mysql.fi|sql-bench/Results/wisconsin-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|23386|1ed1dc6abd24e7e3 +monty@hundin.mysql.fi|support-files/make_mysql_pkg.sh|20010915122456|03682|c616a18bed4b9c2 +monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|04677|f761da5546f0d362 +monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|07879|2ac8fe298953d43 +monty@narttu.mysql.com|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|09727|79ac0482599eace1 +monty@narttu.mysql.com|sql-bench/Results/RUN-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171904|13285|a88e954bc8de5460 +monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|11725|dfc480becae45236 +monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|13605|ee94f987797ca948 +monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|15583|a2a77f37b689cd63 +monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|17580|28b688e2cd4b6bb3 +monty@narttu.mysql.com|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|19531|7dd5ac726f86cf0b +monty@narttu.mysql.com|sql-bench/Results/connect-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|21574|1cf5d5f0d70a3fa0 +monty@narttu.mysql.com|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|23516|441a6aefd381e319 +monty@narttu.mysql.com|sql-bench/Results/create-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|25516|fc207468e871ff69 +monty@narttu.mysql.com|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|27509|d12a7edef05d7185 +monty@narttu.mysql.com|sql-bench/Results/insert-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|29606|975e26cac59161fa +monty@narttu.mysql.com|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|33684|ddcf36cdf3f72e8c +monty@narttu.mysql.com|sql-bench/Results/select-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|35818|34a39fbcb58d8945 +monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|37931|2db07249379f36 +monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|40155|8101a5823c17e58a +monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.13_SMP_alpha|20001014001004|08145|21ddf9425cbdd58 +monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|06287|d275df58a04737c8 +monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.13_SMP_alpha|20001014001004|13092|583091e05a25fb6 +monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|21374|d4766c7f8e70d7a2 +monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.13_SMP_alpha|20001014001004|15829|6c20c9ef46f82241 +monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|25875|155a83b53c0e9d6 +monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.13_SMP_alpha|20001014001004|18602|e8cc899bb933532f +monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|30548|f1127add9307098b +monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.13_SMP_alpha|20001014001004|21372|84df7c6446e51e26 +monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|00237|45d2cdf9bea9cc37 +monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.13_SMP_alpha|20001014001004|23947|2c9af91e9771f618 +monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|04134|d46860c29c5d51ee +monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.13_SMP_alpha|20001014001004|26814|688809eb8ea77b3d +monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|07880|e1771e0a164bc310 +monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.13_SMP_alpha|20001014001004|29737|db59425a7f4aa93f +monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|11605|ee2a063d66a183d +monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.13_SMP_alpha|20001014001004|32465|fc410754151d622c +monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|15116|b7552710d35202b6 +monty@work.mysql.com|fs/fsck.mysql|20010411110350|07619|87170d4358b50d60 +monty@work.mysql.com|libmysqld/README|20010411110351|24268|434e9cae5fa9a4c4 +monty@work.mysql.com|libmysqld/WHITEPAPER|20010411110351|28263|da1226799debcf3f +mwagner@cash.mwagner.org|Docs/include.de.texi|20020223092123|06028|112aac21b3489888 +mwagner@evoq.home.mwagner.org|Docs/Books/algor.eps|20001231203219|20480|481984607c98d715 +mwagner@evoq.home.mwagner.org|Docs/Books/dbi.eps|20001231203219|30594|6ad58f9457e2a564 +mwagner@evoq.home.mwagner.org|Docs/Books/dubois.eps|20001231203219|33725|aa3d9c08bbcc149b +mwagner@evoq.home.mwagner.org|Docs/Books/ecomm.eps|20001231203220|02445|58ae914b5d5ea49 +mwagner@evoq.home.mwagner.org|Docs/Books/in_21.eps|20001231203220|05743|83a7604251d68ebd +mwagner@evoq.home.mwagner.org|Docs/Books/manual.eps|20001231203220|09365|2a7145f88960c7ec +mwagner@evoq.home.mwagner.org|Docs/Books/msql.eps|20001231203220|12487|ffe7d62847663250 +mwagner@evoq.home.mwagner.org|Docs/Books/prof.eps|20001231203220|15779|dc69b039543a57d7 +mwagner@evoq.home.mwagner.org|Docs/Books/pthreads.eps|20001231203220|18899|d60ad51891ef4c49 +mwagner@evoq.home.mwagner.org|Docs/Books/realmen.eps|20001231203220|22075|1ceb4839e835dad4 +mwagner@evoq.home.mwagner.org|Docs/Books/sql-99.eps|20001231203220|25230|cec4ae16fee4c640 mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b93948768 +mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.tst|20001013104933|54568|2e626fa07144d2c8 mwagner@evoq.home.mwagner.org|mysql-test/mybin/start-mysqld|20001016055648|54840|9c8f21a7ab97793a mwagner@evoq.home.mwagner.org|mysql-test/mybin/stop-mysqld|20001016055653|20710|89a1194045f05d1c mwagner@evoq.home.mwagner.org|mysql-test/mybin/translate-tests|20001018130217|00206|3869c1fdf0a5ea1a @@ -365,7 +693,44 @@ mwagner@evoq.home.mwagner.org|mysql-test/var/lib/README|20001009213643|15351|3b6 mwagner@evoq.home.mwagner.org|mysql-test/var/log/README|20001009213643|16203|df5481fdbe6e5b6e mwagner@evoq.home.mwagner.org|mysql-test/var/run/README|20001009213643|17062|acb305e4c2ed5990 mwagner@evoq.home.mwagner.org|mysql-test/var/tmp/README|20001009213643|17904|b32d866bfd50e72e +mwagner@evoq.home.mwagner.org|mysql-test/xml/README|20001013051440|12362|877d76bcd19f7193 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000001.xml|20001013051507|22498|f0eb64c0346366db +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000002.xml|20001013074610|25702|8cd06da5293a7147 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000003.xml|20001013074610|26659|1a622b8d30d7ade8 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000004.xml|20001017133600|56955|515488ef221523d9 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000005.xml|20001017133618|09973|a6344e46ba572dc3 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000006.xml|20001017133623|51441|8ad8f44f49b21246 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000007.xml|20001017133625|48163|bfcb6d85276be7e8 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000008.xml|20001017133627|18273|1d6082f0905c51b6 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000009.xml|20001017133629|19814|8677613dc624cb0c +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000010.xml|20001017133713|64368|9b98c9cce8fac145 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000011.xml|20001017133713|00331|432156d127cbd22f +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000012.xml|20001017133713|01909|a410d08dc4cfee11 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000013.xml|20001017133713|03416|2717cbfbe5730174 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000014.xml|20001017133713|05036|bcf55df6a036bd8f +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000015.xml|20001017133749|30814|b72689a8f9b21372 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000016.xml|20001017133713|07087|32f1ef2e3d214be0 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000017.xml|20001017133713|08762|81423597605ff77f +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000018.xml|20001017133713|10435|82e2e7bde83f56d8 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000019.xml|20001017133713|12133|c0f0b05e481b90e7 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000020.xml|20001017133713|13843|8849bbf91a4fd5ec +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000021.xml|20001017133713|15460|2763b87c1549ba87 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000022.xml|20001017133713|17202|da2083ef423ae39a +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000023.xml|20001017133713|20719|11993b379b9838be +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000024.xml|20001017133713|22352|dd067aa28220fa4c +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000025.xml|20001017133713|24071|3e766aa1e43b303 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000026.xml|20001017133713|25860|15145e496417646f +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000027.xml|20001017133713|27519|95e7de3e9934b570 +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000028.xml|20001017133713|29282|c72bfec6600949b +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000029.xml|20001017133713|31058|3aba1eb23ef86c9e +mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000030.xml|20001017133600|63205|c2b25781eefaee9 +mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/README|20001013051514|26509|cd4bb681e5a0cd10 +mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/mysqltest.xsl|20001013051514|27425|1b8f6ec4f1b5f634 +nick@nick.leippe.com|mysql-test/r/rpl_empty_master_crash.result|20020531235552|47718|615f521be2132141 +nick@nick.leippe.com|mysql-test/t/rpl_empty_master_crash.test|20020531235552|52328|99464e737639ccc6 sasha@mysql.sashanet.com|BitKeeper/etc/logging_ok|20000801000905|12967|5b7d847a2158554 +sasha@mysql.sashanet.com|build-tags|20011125054855|05181|7afb7e785b80f97 +sasha@mysql.sashanet.com|build-tags|20011201050944|25384|b6f6fff142121618 sasha@mysql.sashanet.com|libmysql_r/acconfig.h|20001128060846|51084|65f1202b3b5c345f sasha@mysql.sashanet.com|mysql-test/README.gcov|20001012045950|28177|5a6da067a30780ce sasha@mysql.sashanet.com|mysql-test/README|20001010001022|12739|108667adaeabe3f5 @@ -377,1244 +742,881 @@ sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000004.b.result|20001118063528|520 sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000012.status.result|20001126062901|09395|bbbd650b5beea32f sasha@mysql.sashanet.com|mysql-test/r/3.23/rpl000013.status.result|20001202171150|06069|6bee190c298cc9fd sasha@mysql.sashanet.com|mysql-test/r/3.23/shw000001.result|20001121234128|16652|8b20b03d8319b9a5 +sasha@mysql.sashanet.com|mysql-test/r/binlog-backup-restore.result|20010424233926|16010|605de78abda64d27 +sasha@mysql.sashanet.com|mysql-test/r/df_crash.result|20010406010433|59989|4a3dbee64843953d +sasha@mysql.sashanet.com|mysql-test/r/identity.result|20010910233028|16331|e41453a364242503 +sasha@mysql.sashanet.com|mysql-test/r/mrg000002.result|20001212152450|11492|745be0854aaaaf5e +sasha@mysql.sashanet.com|mysql-test/std_data/m.MRG|20001212152450|17736|3f5632c37af00f18 +sasha@mysql.sashanet.com|mysql-test/std_data/m.frm|20001212152450|13897|e351dfe0b6824c0c sasha@mysql.sashanet.com|mysql-test/std_data/select-key.master|20001009234916|07315|e6b83af25df0ce5 sasha@mysql.sashanet.com|mysql-test/std_data/simple-select.master|20001009234916|08299|6f3eb98812926caf +sasha@mysql.sashanet.com|mysql-test/t/3.23/alt000001.test|20001122072330|31588|633aed61c4bad94c +sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000004.test|20001103140433|32471|daf9ad4a1a31cd3c +sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000005.test|20001103140433|36002|982fde89a4d6d886 sasha@mysql.sashanet.com|mysql-test/t/3.23/select-key.test|20001009234859|21197|5d785cef5c02c070 +sasha@mysql.sashanet.com|mysql-test/t/3.23/shw000001.test|20001121234128|21322|770d96a2c1c65b20 sasha@mysql.sashanet.com|mysql-test/t/3.23/simple-select.test|20001009234859|26291|71f98293e1dc65 +sasha@mysql.sashanet.com|mysql-test/t/binlog-backup-restore.test|20010424233926|25316|d5b0b9bd83738a9f +sasha@mysql.sashanet.com|mysql-test/t/df_crash.test|20010406010433|65180|4c365178fe437f6 +sasha@mysql.sashanet.com|mysql-test/t/fulltext_join.test|20010730234357|20865|e347c8f04405c916 +sasha@mysql.sashanet.com|mysql-test/t/identity.test|20010910233028|36116|326f469b59105404 sasha@mysql.sashanet.com|mysql-test/t/include/master-slave.inc|20001118030458|01636|556fd038c3a3d54 +sasha@mysql.sashanet.com|mysql-test/t/mrg000002.test|20001212152450|20137|16b3a176adc0f311 +sasha@mysql.sashanet.com|mysql-test/t/rpl000018-master.sh|20010127223331|13256|bc8072e13b26b005 +sasha@mysql.sashanet.com|sounds/compilation_finished.au.gz|20010814034002|63992|70bd14095a918139 +sasha@mysql.sashanet.com|vio/test-ssl|20010828000105|24508|ed0a50364f2a51d7 sasha@work.mysql.com|BitKeeper/etc/logging_ok|20001214015456|29919|32b6551b8288c2fa serg@serg.mysql.com|mysql-test/r/3.23/mrg000001.dummy.result|20001206231604|05053|bf7e6d609f22b897 serg@serg.mysql.com|mysql-test/r/3.23/mrg000001.result|20001206231609|46662|db2ef2e717ab8332 -BK|Docs/Attic/myisam.doc|19700101030959|00502|519bb06ecc870298 -BK|Docs/Flags/island.eps|19700101030959|00181|8cec5a55768bc59e -BK|libmysql/violite.c|19700101030959|02600|984c09cffe14a11b -BK|mysql.proj|19700101030959|00071|3e34edc585d18be8 -BK|sql-bench/Results-win32/wisconsin-mysql-win98|19700101030959|02547|8b3da9c5c5d2365b -BK|sql-bench/Results/connect-mysql-3.21-Linux_2.2.1_i686|19700101030959|02134|c0c26d4320182d85 -BK|sql-bench/Results/create-mysql_3.21-Linux_2.0.35_i686|19700101030959|02225|df1b037d17b33587 -BK|sql/share/estonia/errmsg.sys|19700101030959|01836|83b86d7ed4cdd5d0 -BK|sql/share/french/errmsg.sys|19700101030959|01838|9f024dc5e6fe50f5 -BK|sql/share/romania/errmsg.sys|19700101030959|01871|e08aa93bae96d25e -BK|strings/Attic/bootstrap-ctype.c|19700101030959|01360|6d2a8cda2d6a35ff -BK|strings/Attic/ctype-dos.c|19700101030959|01344|f77bd08acf13a8c1 -BK|strings/Attic/ctype-estonia.c|19700101030959|01345|fc8a69424f7cb66b -BK|strings/Attic/ctype-german1.c|19700101030959|01346|f7830c509bb358f7 -BK|strings/Attic/ctype-hp8.c|19700101030959|01349|749e1be0f028d349 -BK|strings/Attic/ctype-koi8_ru.c|19700101030959|01351|8ff4188c642c9bd -BK|strings/READ-ME|19700101030959|01362|ed6c5184d4bf6b7c -BK|support-files/Attic/my-large.cfg.sh|19700101030959|02586|842c8e76253c9396 -BK|vio/VioSSL.cc|19700101030959|00013|6e85340b11fa42a8 -BK|vio/VioSocket.h|19700101030959|00019|a26d535bd5a1a6 -BK|vio/viotypes.h|19700101030959|00027|f5a38e7326bd50f3 -Sinisa@sinisa.nasamreza.org|=6|20010818122920|53462|33f33b0a159dc5d5 -Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522133259|25000|4b5fbc60d0d9754f -Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133300|08911|21904fbd1c95cb1 -ccarkner@nslinuxw10.bedford.progress.com|mysql-test/r/isolation.result|20010327145543|25059|4da11e109a3d93a9 -jani@hynda.mysql.fi|client/mysqlcheck|20010419221207|26716|363e3278166d84ec -miguel@hegel.local|zlib/contrib/asm386/gvmat32.asm|20020319032514|12654|31093c1a846dfdc7 -miguel@hegel.local|zlib/contrib/asm386/gvmat32c.c|20020319032514|19182|2a8eba5481c46eab -miguel@hegel.local|zlib/contrib/asm586/match.s|20020319032514|51538|dc1a34b5eb2a7c11 -miguel@hegel.local|zlib/contrib/delphi2/d_zlib.cpp|20020319032514|31641|d6f37620ac7b27fa -miguel@hegel.local|zlib/contrib/delphi2/zlib.cpp|20020319032515|22372|4257437d415259e2 -miguel@hegel.local|zlib/crc32.c|20020319032516|20397|b327da5b8cf9eae8 -miguel@hegel.local|zlib/inffast.c|20020319032517|65269|bf247ff4aa2bf54b -miguel@hegel.local|zlib/inffixed.h|20020319032517|12923|e86ef8e2efe23f77 -miguel@hegel.local|zlib/msdos/zlib.def|20020319032518|18787|165cd7dcff6ac9f -miguel@hegel.local|zlib/trees.c|20020319032519|43770|4fbd4d005e26d38 -miguel@hegel.local|zlib/uncompr.c|20020319032519|57111|82eac43195d1222c -miguel@hegel.local|zlib/zlib.dsp|20020319032519|12016|6eec436fab260061 -miguel@hegel.local|zlib/zlib.html|20020319032519|31060|7a635f4ac95fc56b -monty@donna.mysql.com|mysql-test/include/have_default_master.inc|20010104005638|23980|a54c86e65a6c4af -monty@donna.mysql.com|sql-bench/Results/ATIS-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14777|e625af7f600bf930 -monty@donna.mysql.com|sql-bench/Results/create-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20766|4e5a2ab4907748d4 -monty@donna.mysql.fi|sql/violite.c|20010523223654|08838|53d4251a69d3c -monty@hundin.mysql.fi|sql-bench/Results/RUN-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|63204|e938a858bd12aa8d -monty@hundin.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|42711|788ad492867b1226 -monty@hundin.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|46284|5316add301edb60 -monty@narttu.mysql.com|sql-bench/Results/insert-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|29606|975e26cac59161fa -monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.13_SMP_alpha|20001014001004|18602|e8cc899bb933532f -mwagner@cash.mwagner.org|Docs/include.de.texi|20020223092123|06028|112aac21b3489888 -mwagner@evoq.home.mwagner.org|Docs/Books/dubois.eps|20001231203219|33725|aa3d9c08bbcc149b -mwagner@evoq.home.mwagner.org|Docs/Books/in_21.eps|20001231203220|05743|83a7604251d68ebd -mwagner@evoq.home.mwagner.org|Docs/Books/pthreads.eps|20001231203220|18899|d60ad51891ef4c49 -mwagner@evoq.home.mwagner.org|Docs/Books/realmen.eps|20001231203220|22075|1ceb4839e835dad4 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000006.xml|20001017133623|51441|8ad8f44f49b21246 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000013.xml|20001017133713|03416|2717cbfbe5730174 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000021.xml|20001017133713|15460|2763b87c1549ba87 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000026.xml|20001017133713|25860|15145e496417646f -nick@nick.leippe.com|mysql-test/t/rpl_empty_master_crash.test|20020531235552|52328|99464e737639ccc6 -sasha@mysql.sashanet.com|mysql-test/r/df_crash.result|20010406010433|59989|4a3dbee64843953d -sasha@mysql.sashanet.com|mysql-test/std_data/m.MRG|20001212152450|17736|3f5632c37af00f18 -sasha@mysql.sashanet.com|mysql-test/t/3.23/alt000001.test|20001122072330|31588|633aed61c4bad94c -sasha@mysql.sashanet.com|mysql-test/t/binlog-backup-restore.test|20010424233926|25316|d5b0b9bd83738a9f -sasha@mysql.sashanet.com|vio/test-ssl|20010828000105|24508|ed0a50364f2a51d7 +serg@serg.mysql.com|mysql-test/r/ft0000001.a.result|20001211130756|05199|3d17aff15fa5a9f1 +serg@serg.mysql.com|mysql-test/r/ft0000001.b.result|20001211130756|10153|505c4c00a0bddfc4 +serg@serg.mysql.com|mysql-test/r/ft0000001.c.result|20001211130756|14950|1040289a75243a92 serg@serg.mysql.com|mysql-test/r/ft0000001.d.result|20001211130756|19773|7c549555fbc7663e serg@serg.mysql.com|mysql-test/r/ft0000001.e.result|20001212121413|40468|c58d30fd7fe86f4f -serg@serg.mysql.com|mysql-test/t/sel000015.test|20001211130731|27841|7442bf9cbc96fe07 -serg@serg.mysql.com|mysql-test/t/sel000024.test|20001211130731|07099|849f47e6cbdc4fe3 -tim@threads.polyesthetic.msg|bdb/build_win32/db_int.h|20010305004134|30736|9ee5645850a336a0 -tim@threads.polyesthetic.msg|bdb/build_win32/ex_btrec.dsp|20010305004135|08710|c87137287d8d67dc -tim@threads.polyesthetic.msg|bdb/build_win32/ex_env.dsp|20010305004135|09533|1732d5e41efda77 -tim@threads.polyesthetic.msg|bdb/build_win32/excxx_lock.dsp|20010305004135|14943|257abf03544f6270 -tim@threads.polyesthetic.msg|bdb/dist/template/rec_qam|20010305004137|28066|6eecf6833de0af98 -tim@threads.polyesthetic.msg|bdb/dist/template/rec_txn|20010305004137|29072|1ff22b797deb0e1b -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_rename.html|20010305004144|37128|36796ad9e106c3f0 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_hash.html|20010305004144|09702|73f14897664d9d08 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_q_extentsize.html|20010305004144|13496|f2fe41a5d8c46658 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_pad.html|20010305004144|16373|8a1de721eb6fc53f -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_sync.html|20010305004144|19394|7a067029b6e1496b -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbt.html|20010305004144|04896|ae7a81c9c5f574f6 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_close.html|20010305004144|28399|a8e722cbb66c9d7b -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_conflicts.html|20010305004145|07137|58d9f7179bc864a3 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_server.html|20010305004145|31969|c13b793b525d504b -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tmp_dir.html|20010305004145|34771|b563e87af5431824 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_verbose.html|20010305004145|38421|344f5119536cae0 -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_file.html|20010305004145|48705|574444b46b801f9c -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_map.html|20010305004144|16369|d90bbc8462ef43a6 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_realloc.html|20010305004144|19375|e8e78e57c005c7c4 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_pindex.html|20010305004147|08181|9ff6b69b56f988dd -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_append_recno.html|20010305004146|08075|a158b1fdba756ce -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errcall.html|20010305004146|10727|28a7a1fa2b3b73ee -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_nelem.html|20010305004146|19017|1829bc583d9c7554 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_delim.html|20010305004146|22753|81d9df93c3511df3 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_len.html|20010305004146|23672|e09bb30e40208dfb -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_remove.html|20010305004146|38809|5efece7ecdfc4df7 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_region_init.html|20010305004146|59589|2d70678382bbbf9a -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lsn_class.html|20010305004145|24210|34809f73e15540ad -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fclose.html|20010305004146|22608|cc4a5776ac69d660 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_abort.html|20010305004147|01091|81177bcb2e5f4502 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_checkpoint.html|20010305004147|02999|173930473e76d008 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_key_range.html|20010305004147|31461|8834de5873a6acb5 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_stat.html|20010305004147|57008|bc253f0883e9c82b -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbenv_class.html|20010305004147|12326|92c7a4a6c22090c7 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errcall.html|20010305004147|07189|4e206d08cbb39ab7 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_detect.html|20010305004147|15549|9fc15a1a95b0dfa1 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_lockers.html|20010305004147|18755|7896265ea77829b3 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_rec_init.html|20010305004147|25237|1fdb2c5fc3b6407 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_recover.html|20010305004148|00983|40280da113fc9d2b -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_timestamp.html|20010305004148|02804|457eeb135f1f8bc0 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_strerror.html|20010305004148|04588|fceebaa94cf9aafd -tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_stat.html|20010305004148|10140|71b81d8567befc43 -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_flush.html|20010305004148|14794|1691d6a3c8cc284e -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fclose.html|20010305004148|20518|d08f0c134361f802 -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_prepare.html|20010305004148|33784|510a245c80e715c -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get.html|20010305004148|42753|127bd361ee695c71 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_is_byteswapped.html|20010305004148|45596|8fb9e2c58051c769 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_stat.html|20010305004148|51363|3bb57be2de907fd2 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_commit.html|20010305004148|64051|25150b20b84cd519 -tim@threads.polyesthetic.msg|bdb/docs/images/api.gif|20010305004148|02578|dec2d4fe5f39dffe -tim@threads.polyesthetic.msg|bdb/docs/images/ref.gif|20010305004148|06650|add30c753dc1972d -tim@threads.polyesthetic.msg|bdb/docs/ref/am/open.html|20010305004148|23468|c9a7e23579a5e93a -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_recnum.html|20010305004149|20770|f081f10254e86e75 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_hash.html|20010305004149|25978|3a0174586fbcfcdf -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_nelem.html|20010305004149|26871|979995db477052ad -tim@threads.polyesthetic.msg|bdb/docs/ref/arch/apis.html|20010305004149|36488|a84570e410b11a6a -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/intro.html|20010305004149|49652|f261022c26987d7f -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/osf1.html|20010305004149|53358|9d4ebabfe3af8970 -tim@threads.polyesthetic.msg|bdb/docs/ref/cam/intro.html|20010305004149|04558|4c497b1a18c4c7f5 -tim@threads.polyesthetic.msg|bdb/docs/ref/install/file.html|20010305004150|21159|d4ba2317db7c064b -tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.txt|20010305004150|21985|3894a46ea11ce25a -tim@threads.polyesthetic.msg|bdb/docs/ref/java/faq.html|20010305004150|27218|7ca2474ba1f6676f -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/cam_conv.html|20010305004150|31862|63844ff6fa95f0c -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/nondb.html|20010305004150|36156|863fe076a46378d7 -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/twopl.html|20010305004150|39650|b3f3aee667bc381d -tim@threads.polyesthetic.msg|bdb/docs/ref/log/limits.html|20010305004150|43198|26fac1e32387b7c9 -tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/intro.html|20010305004150|13549|ad16bc20623e1192 -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/errors.html|20010305004150|19994|be11ff6410e1db2c -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/app.html|20010305004151|42111|6dc3c82982164fa8 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/intro.html|20010305004151|49773|22096cea9fe159ac -tim@threads.polyesthetic.msg|bdb/docs/ref/txn/other.html|20010305004151|63311|4991722636b3a46d -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_register.html|20010305004151|23513|399320e965adf598 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_stat.html|20010305004151|33181|516f1870c6127351 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/value_set.html|20010305004151|34118|f0b0c770a81b90b6 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_paniccall.html|20010305004152|46636|8f9741244fb6e9f6 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tmp.html|20010305004152|50733|ef3450f6fa89f2dc -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/txn_check.html|20010305004152|51549|2405b25bc92cc476 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/renumber.html|20010305004152|60219|d6cd798434da81aa -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/toc.html|20010305004152|61902|9c94c533ada43c1a -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade/process.html|20010305004151|64704|78f9ca966a587234 -tim@threads.polyesthetic.msg|bdb/include/db_auto.h|20010305004137|26350|994ddc84db334345 -tim@threads.polyesthetic.msg|bdb/include/hash_auto.h|20010305004138|09216|1b79cdd426d7ef25 -tim@threads.polyesthetic.msg|bdb/include/rpc_client_ext.h|20010305004138|28220|85436ca9b5691338 -tim@threads.polyesthetic.msg|bdb/rpc_client/db_server_clnt.c|20010305004141|41933|b548b860f765c597 -tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_xdr.c|20010305004141|53794|336ef020b4a22c05 -tim@threads.polyesthetic.msg|bdb/txn/txn_auto.c|20010305004143|19863|6eb282f016f606d9 -BK|sql-bench/Results-win32/connect-mysql-win98|19700101030959|02535|2a11d5e3dfc0bc67 -BK|sql-bench/Results-win32/select-mysql-win98|19700101030959|02544|f370fac2d66a9faf -BK|sql-bench/Results/ATIS-mysql_3.21-Linux_2.0.35_i686|19700101030959|02036|c25425e045ca8dfc -BK|sql-bench/Results/alter-table-mysql_3.21-Linux_2.0.35_i686|19700101030959|02092|762639f2560976bd -BK|sql/Attic/mini_client.c|19700101030959|01910|9a3778c387d06a81 -BK|sql/Attic/mybinlogdump.cc|19700101030959|01908|5dbdd2bde98d6169 -BK|strings/Attic/ctype-croat.c|19700101030959|01341|d2d805ee6f10cbcc -BK|strings/Attic/ctype-hungarian.c|19700101030959|01350|5cf0bf7fa0312637 -BK|strings/Attic/ctype-latin1.c|19700101030959|01353|cc63880f19c2303e -BK|strings/Attic/ctype-latin2.c|19700101030959|01354|31895c4b83654342 -BK|strings/Attic/ctype-win1250.c|19700101030959|01357|1ce7a24255780a1 -BK|support-files/Attic/my-example.cnf.sh|19700101030959|02584|87a7e1f4d24b62a9 -BK|support-files/Attic/my-small.cfg.sh|19700101030959|02588|85023c559a1d96c -BK|vio/VioConnectorFd.cc|19700101030959|00007|ddbd7821c43c83a2 -BK|vio/VioSSLFactoriesFd.cc|19700101030959|00016|89f6bf5073937947 -Sinisa@sinisa.nasamreza.org|mysql-test/t/sel000004.test|20020522133624|23665|445526a8a20de101 -miguel@hegel.local|zlib/contrib/delphi2/readme.txt|20020319032515|03494|65d16837f8579e23 -miguel@hegel.local|zlib/contrib/iostream2/zstream.h|20020319032515|02537|351f26518ea48196 -miguel@hegel.local|zlib/infcodes.h|20020319032517|58960|3a02220a89c9a4fa -miguel@hegel.local|zlib/inflate.c|20020319032517|19311|fb22a3a1ab6fb1a0 -miguel@hegel.local|zlib/infutil.c|20020319032518|05244|a9b414f0f4ea0868 -miguel@hegel.local|zlib/nt/zlib.dnt|20020319032519|16279|22a0ed3b86ff8c2 -miguel@hegel.local|zlib/zlib.3|20020319032519|04298|ec5cb4f64476f6a -monty@donna.mysql.com|mysql-test/r/have_default_master.require|20010104005638|27332|1465255ffdaf82f -monty@hundin.mysql.fi|sql-bench/Results/ATIS-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|59551|d002b0bc548ff8b3 -monty@hundin.mysql.fi|sql-bench/Results/connect-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|08804|1b715c6fd72e913e -monty@hundin.mysql.fi|sql-bench/Results/create-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|49804|26e09af61f88d8c9 -monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|13605|ee94f987797ca948 -monty@narttu.mysql.com|sql-bench/Results/select-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|35818|34a39fbcb58d8945 -monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|37931|2db07249379f36 -monty@narttu.mysql.com|sql-bench/Results/wisconsin-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|40155|8101a5823c17e58a -monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.13_SMP_alpha|20001014001004|13092|583091e05a25fb6 -monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.13_SMP_alpha|20001014001004|15829|6c20c9ef46f82241 -monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|07880|e1771e0a164bc310 -monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.13_SMP_alpha|20001014001004|32465|fc410754151d622c -mwagner@evoq.home.mwagner.org|Docs/Books/dbi.eps|20001231203219|30594|6ad58f9457e2a564 -mwagner@evoq.home.mwagner.org|Docs/Books/ecomm.eps|20001231203220|02445|58ae914b5d5ea49 -mwagner@evoq.home.mwagner.org|Docs/Books/msql.eps|20001231203220|12487|ffe7d62847663250 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000009.xml|20001017133629|19814|8677613dc624cb0c -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000029.xml|20001017133713|31058|3aba1eb23ef86c9e -sasha@mysql.sashanet.com|mysql-test/t/rpl000018-master.sh|20010127223331|13256|bc8072e13b26b005 -serg@serg.mysql.com|mysql-test/t/sel000007.test|20001211130730|24336|f431e4f4739a24c3 -serg@serg.mysql.com|mysql-test/t/sel000021.test|20001211130731|57561|94dd47de2872264a -tim@threads.polyesthetic.msg|bdb/build_vxworks/db_int.h|20010305004134|18702|40ba51edce41403f -tim@threads.polyesthetic.msg|bdb/build_win32/db_tcl.dsp|20010305004135|02285|5ad951d774e41520 -tim@threads.polyesthetic.msg|bdb/build_win32/ex_lock.dsp|20010305004135|10303|286d2566e786dde -tim@threads.polyesthetic.msg|bdb/build_win32/excxx_env.dsp|20010305004135|14159|b0bf2649a4c797ac -tim@threads.polyesthetic.msg|bdb/build_win32/excxx_mpool.dsp|20010305004135|15715|d17a5d09f09f5217 -tim@threads.polyesthetic.msg|bdb/build_win32/include.tcl|20010305004135|17284|f8bffb5e2510f229 -tim@threads.polyesthetic.msg|bdb/db/db_auto.c|20010305004136|32432|3186e950cc321ae7 -tim@threads.polyesthetic.msg|bdb/dist/build/chk.tags|20010305004137|19101|7a5b14d33d4078cc -tim@threads.polyesthetic.msg|bdb/dist/config.guess|20010305004136|14678|ead1d91caeaa748c -tim@threads.polyesthetic.msg|bdb/dist/template/rec_btree|20010305004137|23131|65d6b0b2f5b7a6d2 -tim@threads.polyesthetic.msg|bdb/dist/template/rec_db|20010305004137|25141|52c5797539878fca -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_append_recno.html|20010305004144|38070|bdf0130e642f74fa -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_prefix.html|20010305004144|41420|d6e443a7e47c9b3a -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errpfx.html|20010305004144|05859|756b9b73dd28b8d9 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_feedback.html|20010305004144|06786|90d495e78318a332 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_source.html|20010305004144|17353|6d12ac12652acc31 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_stat.html|20010305004144|18351|578f6f99f8e247ff -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max.html|20010305004145|08849|a2dc11fa8b2f1c9 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_pageyield.html|20010305004145|28418|8aa4a6cb2f18cad7 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_rec_init.html|20010305004145|30192|bf7da051ef6689ba -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_max.html|20010305004145|35672|71a739e46faf33a9 -tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_vec.html|20010305004145|45892|cc79e33b82b7a275 -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_register.html|20010305004145|52499|5381c1fad82d6527 -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_stat.html|20010305004145|53440|36b87b19ee2c5bba -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_close.html|20010305004144|08984|8981d16589844161 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_seek.html|20010305004144|21048|fdf1b31d3f6c7473 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unlink.html|20010305004144|22800|c42b13fd26f2e90 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_cursor.html|20010305004145|29241|4f0225f98f4a11c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_del.html|20010305004145|31220|43fa05f2dfa86dbc -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_join.html|20010305004146|02717|9c4819679501ad6e -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_remove.html|20010305004146|06326|8c537fc5e326293b -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_ffactor.html|20010305004146|17155|a67084c644c38114 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_pad.html|20010305004146|24627|f2e0c2c2c3806a97 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_stat.html|20010305004146|26537|3473827de856d680 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_verify.html|20010305004146|29479|14db455da528229d -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_class.html|20010305004145|15353|2a31b398c37d674b -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_get.html|20010305004146|34739|36e2dbe65e3442e3 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_rec_init.html|20010305004146|58586|77916e00d1361c7b -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_server.html|20010305004146|60631|bb74806839e8eb58 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_max.html|20010305004146|01212|910d1c17dd000729 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/get_errno.html|20010305004145|22249|e1a57c1c5f1d2695 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_compare.html|20010305004146|13902|3225b4c32016c9b1 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_get.html|20010305004146|17104|aee6162219c71617 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_trickle.html|20010305004146|34409|c9df8540b9ebc898 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_begin.html|20010305004147|02053|3a2d1488ec9d8655 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_class.html|20010305004145|26179|5e57abe095aceca9 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_class.html|20010305004147|09609|b957a4d2b77acb1e -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_append_recno.html|20010305004147|36282|d28bf857803b93a2 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_len.html|20010305004147|53997|8448826ea78c630e -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_open.html|20010305004147|02873|2df0f0ef544da715 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_data_dir.html|20010305004147|06162|b7b3f35e96804650 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_dir.html|20010305004147|12366|484cad2123994e14 -tim@threads.polyesthetic.msg|bdb/docs/api_java/lsn_class.html|20010305004147|20619|b1458208b6c81016 -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fput.html|20010305004148|23268|6ba75e517a259703 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_del.html|20010305004148|41829|400c7a72fb10d6f4 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_join.html|20010305004148|43762|1c737805c2c49cf9 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/count.html|20010305004148|11236|8fd8daf2e2cbd7c7 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/curclose.html|20010305004148|12231|8b6b8442fc8382f7 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/curput.html|20010305004148|16324|c7e4fa0a68170c3d -tim@threads.polyesthetic.msg|bdb/docs/ref/am/cursor.html|20010305004148|17350|6dbcdb3b7d552f58 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/sync.html|20010305004148|33751|381722c07c9d8825 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/byteorder.html|20010305004149|21617|999a22f727e2dae0 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/dup.html|20010305004149|23371|523731632fca7343 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/extentsize.html|20010305004149|24263|fdcfb5572974545c -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/malloc.html|20010305004149|29537|cb0e6d7e9448d93e -tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.html|20010305004149|37519|ab5254bc99af0d5c -tim@threads.polyesthetic.msg|bdb/docs/ref/arch/script.html|20010305004149|39400|6796fd0a63161a0c -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/flags.html|20010305004149|46003|a739404f90eb8c3d -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/install.html|20010305004149|48752|660222dd1feffc4 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/irix.html|20010305004149|50564|95833aedc3a82f0 -tim@threads.polyesthetic.msg|bdb/docs/ref/debug/printlog.html|20010305004149|09591|9fa9894f839fad95 -tim@threads.polyesthetic.msg|bdb/docs/ref/debug/runtime.html|20010305004149|10629|d50f2fea4a8e58c -tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/format.html|20010305004149|13995|9fa10ca3c7ae6751 -tim@threads.polyesthetic.msg|bdb/docs/ref/env/intro.html|20010305004149|19435|96dd1090729e06b -tim@threads.polyesthetic.msg|bdb/docs/ref/env/remote.html|20010305004149|23518|52a3a79fdff8f7bd -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbisnot.html|20010305004149|29466|5ce7aed7ce41c9e6 -tim@threads.polyesthetic.msg|bdb/docs/ref/java/conf.html|20010305004150|26401|ef560bcf13a71cd5 -tim@threads.polyesthetic.msg|bdb/docs/ref/log/config.html|20010305004150|41449|aedc53caf49c51c9 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/scope.html|20010305004150|59326|2987f97781410bc1 -tim@threads.polyesthetic.msg|bdb/docs/ref/refs/embedded.html|20010305004150|03865|d25b9719d24df88c -tim@threads.polyesthetic.msg|bdb/docs/ref/refs/witold.html|20010305004150|65330|ad6c866cf48734b5 -tim@threads.polyesthetic.msg|bdb/docs/ref/sendmail/intro.html|20010305004150|16532|ecac45d7e2bcf51c -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/close.html|20010305004150|18046|1fe3a82f28e7ed32 -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/keydata.html|20010305004150|23810|530b1581aeba63ca -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/put.html|20010305004150|25774|bdd2629c212af471 -tim@threads.polyesthetic.msg|bdb/docs/ref/toc.html|20010305004148|08788|ab1fa294d5ef4b69 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/reclimit.html|20010305004151|53098|5f54174bf6026bd5 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/recovery.html|20010305004151|53956|6e3a0c07b997c3b2 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/throughput.html|20010305004151|55655|8a7d5a958df7f91a -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/intro.html|20010305004151|02261|8bfd3804a2da1598 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv_cxx.html|20010305004151|09872|7f4fd0ebace36d8e -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/disk.html|20010305004151|11685|eb79d1157ef44d3c -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/java.html|20010305004151|17120|300acccbb633e335 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/jump_set.html|20010305004151|18936|718c098a91db9dba -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_notheld.html|20010305004151|20761|ed6853b6daa5531b -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/open.html|20010305004151|27357|8b1e2a969e97069a -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/intro.html|20010305004152|41719|64592a50b1c634d6 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_tx_recover.html|20010305004152|47442|ada65907ba98eee8 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/toc.html|20010305004152|49908|af1a24798980ad1 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/incomplete.html|20010305004152|56914|af86a649a878a124 -tim@threads.polyesthetic.msg|bdb/hash/hash_auto.c|20010305004137|61459|d17c6a6ed4f181d1 -tim@threads.polyesthetic.msg|bdb/include/clib_ext.h|20010305004137|19207|ed9d9f7965f0e1d3 -tim@threads.polyesthetic.msg|bdb/rpc_server/gen_db_server.c|20010305004141|54931|d5602f9bd5c930e -BK|Docs/Flags/island.gif|19700101030959|00142|e274d5e96ee0975a -BK|Docs/Flags/south-africa1.txt|19700101030959|00232|87a53fdcd2149c6e -BK|client/Attic/net.c|19700101030959|00583|c18042da6fa4e693 -BK|extra/Attic/print_defaults.c|19700101030959|01513|362952979aa7b330 -BK|sql-bench/Results-win32/RUN-mysql-win98|19700101030959|02526|7f09e396772a8665 -BK|sql-bench/Results-win32/insert-mysql-win98|19700101030959|02541|6d6cafc85a6c837 -BK|sql-bench/Results/RUN-mysql-3.21-Linux_2.2.1_i686|19700101030959|02050|f6fdd64859e11de9 -BK|sql-bench/Results/big-tables-mysql_3.21-Linux_2.0.35_i686|19700101030959|02120|190e827e569c99a4 -BK|sql-bench/Results/create-mysql-3.21-Linux_2.2.1_i686|19700101030959|02158|51581b24f45e0f5c -Sinisa@sinisa.nasamreza.org|mysql-test/r/sel000004.result|20020522121240|20995|360af2095c88cb8c -arjen@co3064164-a.bitbike.com|Docs/section.Comparisons.texi|20011108043647|22614|692b647b -ccarkner@nslinuxw10.bedford.progress.com|mysql-test/t/isolation.test|20010327145543|39049|6a39e4138dd4a456 -miguel@hegel.local|zlib/algorithm.txt|20020319032513|12903|fbc4dda3d31c2005 -miguel@hegel.local|zlib/contrib/README.contrib|20020319032514|04353|24cb75bee0a061fb -miguel@hegel.local|zlib/contrib/asm386/zlibvc.def|20020319032514|31637|605ee23b8a4a6a1a -miguel@hegel.local|zlib/contrib/delphi2/zlib.bpg|20020319032515|09768|93c030edcca1838 -miguel@hegel.local|zlib/contrib/delphi2/zlib.bpr|20020319032515|16113|7a2fa98af2345144 -miguel@hegel.local|zlib/contrib/minizip/unzip.h|20020319032516|21001|bac981086af91a30 -miguel@hegel.local|zlib/contrib/minizip/zip.c|20020319032516|27911|e82bf7774e1ece95 -miguel@hegel.local|zlib/zutil.h|20020319032520|12556|1e431b0173278fb2 -monty@donna.mysql.com|innobase/ib_config.h.in|20010217121901|07616|9e57db8504e55b7 -monty@donna.mysql.com|innobase/ib_config.h|20010217121901|04019|7539e26ffc614439 -monty@narttu.mysql.com|sql-bench/Results/insert-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|27509|d12a7edef05d7185 -mwagner@evoq.home.mwagner.org|Docs/Books/manual.eps|20001231203220|09365|2a7145f88960c7ec -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000025.xml|20001017133713|24071|3e766aa1e43b303 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000030.xml|20001017133600|63205|c2b25781eefaee9 -serg@serg.mysql.com|mysql-test/t/sel000006.test|20001211130730|19922|291cc6c8d85e51df -serg@serg.mysql.com|mysql-test/t/sel000016.test|20001211130731|32739|f495235f14c47ec -tim@threads.polyesthetic.msg|bdb/build_win32/db_stat.dsp|20010305004135|00560|f77417f5d9984986 -tim@threads.polyesthetic.msg|bdb/dist/config.sub|20010305004136|16944|17e9990a298261a -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_remove.html|20010305004144|36184|668fa1d67a4f6941 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_malloc.html|20010305004144|01594|3581879fef5af695 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_flags.html|20010305004145|03778|b2a1f3c8498e6d95 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_detect.html|20010305004145|07983|d9ed73495defdc19 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_lockers.html|20010305004145|24923|f22d5d4640436efe -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_locks.html|20010305004145|09704|1baf2d63a6fb418d -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tas_spins.html|20010305004145|33848|91c7091deca3d97f -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fclose.html|20010305004145|55335|b52c7d599d83c26 -tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_abort.html|20010305004145|65162|a53425dd70214619 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_index.html|20010305004145|07331|a0bc165de8a0554c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_feedback.html|20010305004146|15263|a08620d86f05ec8c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_malloc.html|20010305004145|12423|b0aa5802da5bef4d -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_dup.html|20010305004146|33708|75df863b4bc13aaa -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_close.html|20010305004146|36778|5cc705b97b86972c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_cachesize.html|20010305004146|39807|b82ed49a47415fec -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_detect.html|20010305004146|49591|13e53300b722cf1e -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_panicstate.html|20010305004146|57577|ad2d38e398cafd31 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_get.html|20010305004146|61648|527d63a8526f336c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_put.html|20010305004146|18207|66077da9630fa8c2 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_sync.html|20010305004146|33235|253961279934d3c8 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_hash.html|20010305004147|48174|c6eb825c706a9548 -tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_detect.html|20010305004148|06490|14d4e7c7dca0dad7 -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fsync.html|20010305004148|25118|e767b233fe7730a2 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_put.html|20010305004148|57122|290ecb1275d4270 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_open.html|20010305004148|59088|39b63925d45a637e -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_pindex.html|20010305004148|00553|259f0e062eee63c7 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/ops.html|20010305004148|25566|9b24db9ba4f45724 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_compare.html|20010305004149|18156|c1e847e651704c89 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_minkey.html|20010305004149|19013|b4708e561be92b83 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/intro.html|20010305004149|27745|dd1647202258ee28 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/recno.html|20010305004149|32283|c2ae722138309e95 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/select.html|20010305004149|34120|57b1c99f6a8ea93f -tim@threads.polyesthetic.msg|bdb/docs/ref/distrib/layout.html|20010305004149|12589|5aeb292fbd987cf8 -tim@threads.polyesthetic.msg|bdb/docs/ref/env/error.html|20010305004149|18447|acbbdb848c9fe70f -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/terrain.html|20010305004149|33850|b396d6447a59435f -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/intro.html|20010305004150|34434|e1e07e71f3198be -tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/program.html|20010305004151|23138|2f5bf497ae226ed5 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/archival.html|20010305004151|42978|7631314d840be181 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/logfile.html|20010305004151|50590|1c3002fcb6581e8c -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/read.html|20010305004151|52265|fc8b056380e09887 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/func.html|20010305004151|15332|c06e5bc63ddf7a64 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/logalloc.html|20010305004152|43372|30563c544b8ddd54 -tim@threads.polyesthetic.msg|bdb/docs/sleepycat/contact.html|20010305004152|04402|55b4da3d7bf7655b -tim@threads.polyesthetic.msg|bdb/docs/utility/db_archive.html|20010305004152|07446|ab2c66e01b3e3626 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_recover.html|20010305004152|12771|1b63f2acdc0b0af7 -tim@threads.polyesthetic.msg|bdb/include/env_ext.h|20010305004138|05832|33a5fdef1aeecefd -tim@threads.polyesthetic.msg|bdb/include/txn_ext.h|20010305004138|34549|9db24c14f204890c -BK|Docs/Flags/kroatia.eps|19700101030959|00185|f50fcd444e7efceb -BK|Docs/Flags/south-africa1.gif|19700101030959|00154|1ea38de5a535f732 -BK|sql-bench/Results/insert-mysql_3.21-Linux_2.0.35_i686|19700101030959|02252|60c0965dff31db07 -BK|sql-bench/Results/select-mysql_3.21-Linux_2.0.35_i686|19700101030959|02278|5fadbac5f98696a -BK|sql/share/danish/errmsg.sys|19700101030959|01831|3a6d0fb8451a3313 -BK|sql/share/dutch/errmsg.sys|19700101030959|01833|b5aff4d08478bafd -BK|sql/share/italian/errmsg.sys|19700101030959|01846|c5108ecb850b79a -BK|sql/share/portuguese/errmsg.sys|19700101030959|01859|c0187322f8c9d805 -BK|vio/VioAcceptorFd.cc|19700101030959|00005|a5a08947a31f88de -BK|vio/vio-global.h|19700101030959|00021|c261412c01b2f4 -miguel@hegel.local|zlib/ChangeLog|20020319032513|28917|5d5425fc84737083 -miguel@hegel.local|zlib/compress.c|20020319032513|32512|70bccb304651dba9 -miguel@hegel.local|zlib/contrib/asm386/mkgvmt32.bat|20020319032514|25425|422cbe16a6e74695 -miguel@hegel.local|zlib/contrib/delphi2/zlib32.bpr|20020319032515|35585|41ac53acb8008ff7 -miguel@hegel.local|zlib/contrib/delphi2/zlib32.cpp|20020319032515|41979|3b0f51435e880afe -miguel@hegel.local|zlib/contrib/minizip/ChangeLogUnzip|20020319032515|15183|50464416f4a3768f -miguel@hegel.local|zlib/index|20020319032517|33542|5443c9f841db4a47 -miguel@hegel.local|zlib/infblock.c|20020319032517|39853|540cc1b743be5f58 -mikef@nslinux.bedford.progress.com|mysql-test/r/have_gemini.require|20010321203410|47052|206702c48b2e206b -monty@donna.mysql.com|sql-bench/Results/ATIS-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|14134|cf0d806760eefef2 -monty@donna.mysql.com|sql-bench/Results/big-tables-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18309|c87333d6fe04433e -monty@donna.mysql.com|sql-bench/Results/connect-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|19522|ab58fffa30dce97e -monty@donna.mysql.com|sql-bench/Results/insert-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22042|27b7a557c3cb07a -monty@donna.mysql.com|sql-bench/Results/wisconsin-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24748|6a468dcd3e6f5405 -monty@hundin.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|35759|11038a44f73070e7 -monty@hundin.mysql.fi|sql-bench/Results/big-tables-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|05113|b6be70bb51013cad -monty@hundin.mysql.fi|sql-bench/Results/select-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|19688|4ffc9cf4be665ea2 -monty@hundin.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|60398|8ba598d217450157 -monty@hundin.mysql.fi|support-files/make_mysql_pkg.sh|20010915122456|03682|c616a18bed4b9c2 -monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|04677|f761da5546f0d362 -monty@narttu.mysql.com|sql-bench/Results/RUN-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171904|13285|a88e954bc8de5460 -monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|17580|28b688e2cd4b6bb3 -monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.13_SMP_alpha|20001014001004|21372|84df7c6446e51e26 -monty@narttu.mysql.fi|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|00237|45d2cdf9bea9cc37 -monty@narttu.mysql.fi|sql-bench/Results/wisconsin-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|15116|b7552710d35202b6 -mwagner@evoq.home.mwagner.org|Docs/Books/sql-99.eps|20001231203220|25230|cec4ae16fee4c640 -mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.tst|20001013104933|54568|2e626fa07144d2c8 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000002.xml|20001013074610|25702|8cd06da5293a7147 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000008.xml|20001017133627|18273|1d6082f0905c51b6 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000018.xml|20001017133713|10435|82e2e7bde83f56d8 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000022.xml|20001017133713|17202|da2083ef423ae39a -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000027.xml|20001017133713|27519|95e7de3e9934b570 -sasha@mysql.sashanet.com|mysql-test/r/mrg000002.result|20001212152450|11492|745be0854aaaaf5e -sasha@mysql.sashanet.com|mysql-test/t/fulltext_join.test|20010730234357|20865|e347c8f04405c916 +serg@serg.mysql.com|mysql-test/r/ft0000002.a.result|20001212120058|27306|a89b4db1db19f944 serg@serg.mysql.com|mysql-test/r/ft0000002.b.result|20001212120058|34425|5de41ce15ae1cedb +serg@serg.mysql.com|mysql-test/r/ft0000002.c.result|20001212120059|07173|cd66b90918a87531 +serg@serg.mysql.com|mysql-test/t/3.23/mrg000001.test|20001206231615|27540|e0327f9d1e6cb4e +serg@serg.mysql.com|mysql-test/t/sel000006.test|20001211130730|19922|291cc6c8d85e51df +serg@serg.mysql.com|mysql-test/t/sel000007.test|20001211130730|24336|f431e4f4739a24c3 +serg@serg.mysql.com|mysql-test/t/sel000008.test|20001211130730|28581|b338ef585cadf7ae +serg@serg.mysql.com|mysql-test/t/sel000009.test|20001211130730|33139|a455c38f5c942cd1 +serg@serg.mysql.com|mysql-test/t/sel000010.test|20001211130731|03554|ca07085ae92255f1 +serg@serg.mysql.com|mysql-test/t/sel000011.test|20001211130731|08373|c2a971726c9d18d6 +serg@serg.mysql.com|mysql-test/t/sel000012.test|20001211130731|13215|ae64bff363c42e92 +serg@serg.mysql.com|mysql-test/t/sel000013.test|20001211130731|18090|ce8aa504ba4f74ba +serg@serg.mysql.com|mysql-test/t/sel000014.test|20001211130731|22977|74cb8c70f1d73fcc +serg@serg.mysql.com|mysql-test/t/sel000015.test|20001211130731|27841|7442bf9cbc96fe07 +serg@serg.mysql.com|mysql-test/t/sel000016.test|20001211130731|32739|f495235f14c47ec serg@serg.mysql.com|mysql-test/t/sel000017.test|20001211130731|37659|7c39f2b45a6aa780 serg@serg.mysql.com|mysql-test/t/sel000018.test|20001211130731|42584|16207f3ad74de75e -serg@serg.mysql.com|mysql-test/t/sel000022.test|20001211130731|62553|6e3e5435e66875e9 -serg@serg.mysql.com|mysql-test/t/sel000023.test|20001211130731|02042|7bdfcfaa278f837d -serg@serg.mysql.com|mysql-test/t/sel000025.test|20001211130731|12136|65b32b4b67e4c77 -tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.eps|20020228162345|64529|31ade79a89683616 -tim@cane.mysql.fi|mysql-test/r/delete.result|20001221095802|20463|e866a6678e29f186 -tim@threads.polyesthetic.msg|bdb/build_win32/db_deadlock.dsp|20010305004134|28374|befd45d29eaeb672 -tim@threads.polyesthetic.msg|bdb/build_win32/db_dump.dsp|20010305004134|29985|e07d2a82708b61 -tim@threads.polyesthetic.msg|bdb/build_win32/db_recover.dsp|20010305004134|34274|835c32ab73359256 -tim@threads.polyesthetic.msg|bdb/build_win32/db_static.dsp|20010305004135|01425|78ea414467defc70 -tim@threads.polyesthetic.msg|bdb/build_win32/ex_access.dsp|20010305004135|07926|8dd6017efffae14e -tim@threads.polyesthetic.msg|bdb/build_win32/ex_mpool.dsp|20010305004135|11076|9eb937bc70c1573 -tim@threads.polyesthetic.msg|bdb/build_win32/excxx_access.dsp|20010305004135|12614|31e87b6228470681 -tim@threads.polyesthetic.msg|bdb/dist/build/chk.def|20010305004137|13920|bb65b471d09f7c58 -tim@threads.polyesthetic.msg|bdb/dist/build/chk.srcfiles|20010305004137|18056|ae884700cd110cbf -tim@threads.polyesthetic.msg|bdb/dist/template/rec_crdel|20010305004137|24191|58795c0c5232f80d -tim@threads.polyesthetic.msg|bdb/docs/api_c/c_index.html|20010305004143|28133|1a854fa55012906 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_del.html|20010305004144|11427|e8bffcf9be371317 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get.html|20010305004144|29265|7e0018b93ee31eba -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_type.html|20010305004144|31538|d66aa1642a4d20e2 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_open.html|20010305004144|34314|59dfa6e5198c382e -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_realloc.html|20010305004144|03204|a9be244baf966892 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_verify.html|20010305004144|21372|cf80f5ba845eac2e -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_remove.html|20010305004144|31547|a71d5e1ca41324a7 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_cachesize.html|20010305004144|32567|f4c341d3f2c09469 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errcall.html|20010305004145|00341|ba09eec1ba15f15f -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_objects.html|20010305004145|25791|1a428bbee06cb5cc -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mp_mmapsize.html|20010305004145|26668|21f27997f00accfe -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mutexlocks.html|20010305004145|27540|85bbd53b877cafe1 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_paniccall.html|20010305004144|07360|97a1d58189199453 -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fget.html|20010305004145|56294|460714b5c2e3e1c5 -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_register.html|20010305004145|61165|8b9dff9b5043da58 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_malloc.html|20010305004144|15535|5579a0604e14e1e7 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_rename.html|20010305004144|20199|3f8c7b6674cda105 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_write.html|20010305004144|24518|63567be42d586fde -tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_commit.html|20010305004145|02592|8950b5e11c8b0778 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errpfx.html|20010305004146|14381|1f26e7b0bb5a067f -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_sync.html|20010305004146|27538|dadf1f745e44faa7 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errpfx.html|20010305004146|42728|d26da4bab9538234 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_dir.html|20010305004146|46674|c08aac264e7faa97 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_pageyield.html|20010305004146|56583|db4e5bdf71e171c0 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_version.html|20010305004146|06444|1cff25c44cbea934 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/pindex.src|20010305004145|09392|d65361c4acfcef06 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_commit.html|20010305004147|03924|65afb8caf9c470ae -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/what.html|20010305004145|27185|a64f42c697273c44 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_close.html|20010305004147|24101|21595167f4fdbe88 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_del.html|20010305004147|25922|f4f15b362b114506 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_remove.html|20010305004147|34343|49d3b8c7e5a5b000 -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_class.html|20010305004147|11473|8ee03c40ae0dbcb8 -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_put.html|20010305004147|00700|da0f0fa974385abd -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_shm_key.html|20010305004147|28699|8c576698882f0edc -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tas_spins.html|20010305004147|30425|2f9963827fbcb3f -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_archive.html|20010305004148|11996|b4a9483dbb5a2b58 -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_compare.html|20010305004148|12947|756622b42572ecb -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_put.html|20010305004148|16729|ad7e9f382abde491 -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_stat.html|20010305004148|18608|d186a08662046aba -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_join.html|20010305004148|46525|cb3eb61ed17a1f8 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_remove.html|20010305004148|60117|9090900413ff0280 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/pindex.src|20010305004148|39123|f8754fff24f2cb24 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/error.html|20010305004148|19390|45ac854e68196844 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/verify.html|20010305004149|01382|badaeba91bda50e1 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_prefix.html|20010305004149|19903|4e7602aa68d50fe1 -tim@threads.polyesthetic.msg|bdb/docs/ref/arch/utilities.html|20010305004149|40326|54d7014fab332c7a -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sco.html|20010305004149|55174|e25f6271a1b753d0 -tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/utility.html|20010305004149|15969|8fc100fdb58adb3c -tim@threads.polyesthetic.msg|bdb/docs/ref/env/create.html|20010305004149|17402|9f454cb1910df0b8 -tim@threads.polyesthetic.msg|bdb/docs/ref/env/naming.html|20010305004149|20447|1f041789686cc8a0 -tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.le.txt|20010305004150|23615|528ef76418c8b45c -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/data.html|20010305004149|26092|33fbf7496c58cf63 -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/distrib.html|20010305004149|30742|84b56709310017f2 -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/products.html|20010305004149|32785|f37221772a3b589d -tim@threads.polyesthetic.msg|bdb/docs/ref/java/compat.html|20010305004150|25581|b39d173789bbf70d -tim@threads.polyesthetic.msg|bdb/docs/ref/program/dbsizes.html|20010305004150|52571|d70da530573b9b38 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/errorret.html|20010305004150|55412|23491397d7e704e9 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/recimp.html|20010305004150|60288|bbdb0feb7d467a80 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/version.html|20010305004150|62172|d266e819d1531df8 -tim@threads.polyesthetic.msg|bdb/docs/ref/refs/hash_usenix.ps|20010305004150|05408|11cad226b0aa012b -tim@threads.polyesthetic.msg|bdb/docs/ref/refs/refs.html|20010305004150|64422|30490b237ba9b61 -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/handles.html|20010305004150|21935|18a14f4a50e7bad0 -tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/using.html|20010305004151|23908|28856d8c72d0660b -tim@threads.polyesthetic.msg|bdb/docs/ref/test/run.html|20010305004151|39305|63c0398e7e2a29e2 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/toc.html|20010305004151|04069|670791f294a61494 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db.html|20010305004151|07207|e7d63f4bb8e989e8 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_stat.html|20010305004151|24428|20b5898ba061557d -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/memp_stat.html|20010305004151|25363|79e1141c63f7357 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/xa.html|20010305004152|00602|1af042e462ab829 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/config.html|20010305004152|38401|d2ace28f39ab0f8d -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/sysmem.html|20010305004152|48282|3d088eb0ef1b27e0 -tim@threads.polyesthetic.msg|bdb/docs/sleepycat/legal.html|20010305004152|02616|7388af4c578cacf6 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_checkpoint.html|20010305004152|08309|c040e4424edcc451 -tim@threads.polyesthetic.msg|bdb/include/common_ext.h|20010305004137|20146|35c8aab64ee3b8fd -tim@threads.polyesthetic.msg|bdb/include/log_auto.h|20010305004138|13513|8d52dd0884d03051 -tim@threads.polyesthetic.msg|bdb/include/os_ext.h|20010305004138|20730|a1771032b4d2d53b -tim@threads.polyesthetic.msg|bdb/include/rpc_server_ext.h|20010305004138|29091|952741fb85de2b80 -tonu@x3.internalnet|include/vio.h|20010520213124|42404|c62fd2b86c03da7d -BK|Docs/Flags/kroatia.gif|19700101030959|00146|bea7bbe0316d462d -BK|Docs/Flags/kroatia.txt|19700101030959|00224|dde7f89f25d616b2 -BK|mit-pthreads/pgcc|19700101030959|00596|154a03d0c1a0a600 -BK|sql-bench/Results-win32/ATIS-mysql-win98|19700101030959|02523|cd0705815d3af451 -BK|sql-bench/Results-win32/big-tables-mysql-win98|19700101030959|02532|99a1882effebbdf2 -BK|sql-bench/Results/ATIS-mysql-3.21-Linux_2.2.1_i686|19700101030959|02022|660fb76ed6ccfb6f -BK|sql-bench/Results/RUN-mysql_3.21-Linux_2.0.35_i686|19700101030959|02064|ea8672d8473435 -BK|sql-bench/Results/big-tables-mysql-3.21-Linux_2.2.1_i686|19700101030959|02106|baa649caba113497 -BK|sql-bench/Results/select-mysql-3.21-Linux_2.2.1_i686|19700101030959|02265|ed3687e713ff0571 -BK|sql/Attic/lex_hash.h|19700101030959|01912|14f912771118b50c -BK|sql/share/czech/errmsg.sys|19700101030959|01828|93104a2bd5c732a -BK|sql/share/greek/errmsg.sys|19700101030959|01842|fedf585fa73e7cf1 -BK|sql/share/slovak/errmsg.sys|19700101030959|01862|148510616ae825cf -BK|sql/violite.c|19700101030959|01738|d7b85be615595ace -BK|strings/Attic/ctype-cp1251.c|19700101030959|01339|cdf74b9168408b3 -BK|strings/Attic/ctype-dec8.c|19700101030959|01343|68f257dd2202d0c7 -BK|vio/VioConnectorFd.h|19700101030959|00008|58bc11cdc885b951 -BK|vio/VioPipe.cc|19700101030959|00011|12cf83b9a2f48f6c -BK|vio/VioSSLAcceptorFd.cc|19700101030959|00015|4c828f3688ed74ec -BK|vio/version.cc|19700101030959|00020|7237acf12bed4a97 -arjen@fred.bitbike.com|scripts/mysql_fix_extensions.sh|20020516001337|12363|f1048a78f4759b4d -miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsw|20020319032514|44870|3209982720f131ab -miguel@hegel.local|zlib/contrib/asm686/match.s|20020319032514|64199|4164951e8e19f116 -miguel@hegel.local|zlib/contrib/iostream/zfstream.h|20020319032515|61553|2b4d88acc2d3b714 -miguel@hegel.local|zlib/contrib/minizip/zip.def|20020319032516|34413|e9bda2081d65c22e -miguel@hegel.local|zlib/contrib/minizip/zlibvc.def|20020319032516|47259|6dc42f99d2d55cad -miguel@hegel.local|zlib/contrib/untgz/untgz.c|20020319032516|07726|b74e9dde74642756 -miguel@hegel.local|zlib/contrib/visual-basic.txt|20020319032516|14096|cd461e762199bb09 -miguel@hegel.local|zlib/deflate.h|20020319032516|33700|3a012bc1f5dfbc74 -miguel@hegel.local|zlib/inftrees.c|20020319032517|25758|4fcb97357cdbc40 -miguel@hegel.local|zlib/trees.h|20020319032519|50674|87161133bc2155fd -monty@hundin.mysql.fi|sql-bench/Results/alter-table-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|01419|14360865bbba479f -monty@narttu.mysql.com|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|23516|441a6aefd381e319 -monty@narttu.mysql.fi|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|21374|d4766c7f8e70d7a2 -monty@narttu.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|25875|155a83b53c0e9d6 -monty@narttu.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.2.13_SMP_alpha|20001014001004|26814|688809eb8ea77b3d -monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|11605|ee2a063d66a183d -monty@work.mysql.com|fs/fsck.mysql|20010411110350|07619|87170d4358b50d60 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000001.xml|20001013051507|22498|f0eb64c0346366db -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000004.xml|20001017133600|56955|515488ef221523d9 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000005.xml|20001017133618|09973|a6344e46ba572dc3 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000014.xml|20001017133713|05036|bcf55df6a036bd8f -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000019.xml|20001017133713|12133|c0f0b05e481b90e7 -mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/README|20001013051514|26509|cd4bb681e5a0cd10 -sasha@mysql.sashanet.com|mysql-test/std_data/m.frm|20001212152450|13897|e351dfe0b6824c0c -sasha@mysql.sashanet.com|mysql-test/t/3.23/shw000001.test|20001121234128|21322|770d96a2c1c65b20 -sasha@mysql.sashanet.com|mysql-test/t/mrg000002.test|20001212152450|20137|16b3a176adc0f311 -serg@serg.mysql.com|mysql-test/r/ft0000002.c.result|20001212120059|07173|cd66b90918a87531 -serg@serg.mysql.com|mysql-test/t/sel000026.test|20001211130731|17211|d8aa2d614f23b1 -serg@serg.mysql.com|mysql-test/t/sel000029.test|20001211130731|32917|6aae34dbb3ee86d9 -tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.gif|20020228162348|36945|364ca7338682f71 -tim@threads.polyesthetic.msg|bdb/build_win32/db_archive.dsp|20010305004134|25535|e3da826e91bb086 -tim@threads.polyesthetic.msg|bdb/build_win32/db_printlog.dsp|20010305004134|32975|163f6e1073a5f396 -tim@threads.polyesthetic.msg|bdb/build_win32/db_verify.dsp|20010305004135|04464|e9a4938542f86cea -tim@threads.polyesthetic.msg|bdb/build_win32/ex_tpcb.dsp|20010305004135|11838|644b38dae8b38152 -tim@threads.polyesthetic.msg|bdb/build_win32/libdb.rc|20010305004135|20964|906f4936ec6a8398 -tim@threads.polyesthetic.msg|bdb/dist/template/db_server_proc|20010305004137|21042|2e8b49d42aefab55 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_err.html|20010305004143|33003|3696088bd85eeda3 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_byteswapped.html|20010305004144|30478|bcab4145183a7be2 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_put.html|20010305004144|35267|ea78709ffb6cd7e8 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_cachesize.html|20010305004144|02131|47a3c8ca486eb013 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errcall.html|20010305004144|04030|faf92be4ee8bc634 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_flags.html|20010305004144|07758|4cd3700ae4387d22 -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_close.html|20010305004144|22419|a3ad4ea563bafc42 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_create.html|20010305004144|05736|3e73dd35fe5dcc8 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_data_dir.html|20010305004144|33569|437cec65e441c60 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_bsize.html|20010305004145|04625|1eb03c137a42e80f -tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_get.html|20010305004145|42084|63399d204f1885fa -tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_put.html|20010305004145|44022|f5bc2f52e55f16e1 -tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_stat.html|20010305004145|44954|d9a98bb949070b -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fput.html|20010305004145|58291|4a7aace7db01ee15 -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fset.html|20010305004145|59241|ecb97931b222568d -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fsync.html|20010305004145|60192|a95ab802bb28646f -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_free.html|20010305004144|13076|ed61d2dfea9e069e -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_open.html|20010305004144|17474|8c812591efc8abe6 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unmap.html|20010305004144|23658|d85790692f3b536e -tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_stat.html|20010305004145|04637|f57a656bfbac12bf -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_type.html|20010305004146|01846|398668783c4070db -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_compare.html|20010305004146|08946|d888d1ebe056bc6b -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_minkey.html|20010305004146|09837|d6181e52342005c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_lorder.html|20010305004146|19980|a46750a29588268c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_del.html|20010305004146|32671|424fc0ebb3b4c5cf -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_data_dir.html|20010305004146|40779|9176f081597e4f27 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errfile.html|20010305004145|18322|f9543c9e65ed6a1d -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_error_stream.html|20010305004145|19317|a4101c1d68559fa2 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max.html|20010305004146|50580|52ac3c4ca2876de -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_id.html|20010305004146|08539|b3c7995efbe12c16 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_stat.html|20010305004146|10635|2112ceb0894b34d8 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_vec.html|20010305004146|11739|c55deaa5173a3323 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_unregister.html|20010305004146|21535|8fa1fe691751d6ad -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_type.html|20010305004147|29592|4cfb6f09cbe0b8ae -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_open.html|20010305004147|32409|bfc13736b96ac509 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_put.html|20010305004147|33389|c476abe5599f21cf -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_compare.html|20010305004147|37206|e972f964d042b35e -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_minkey.html|20010305004147|38144|c7e1f184bdca25fa -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_feedback.html|20010305004147|45141|69b4c07b3dbe383 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_ffactor.html|20010305004147|47226|edcc10024104d57e -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_q_extentsize.html|20010305004147|52035|6ac26239fc538cb -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_sync.html|20010305004147|58064|42391f7d5f200b90 -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_count.html|20010305004147|62108|9c239575f4550756 -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_dup.html|20010305004147|64103|aa141014c4d7f9b0 -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_get.html|20010305004147|65144|e66e387b83681e73 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_close.html|20010305004147|01809|c4e2ec77d7d14d4f -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_remove.html|20010305004147|04039|e92277e3dfd9bba1 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_conflicts.html|20010305004147|14497|8951eb975a90918b -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mp_mmapsize.html|20010305004147|20894|b7dea9108fa65dfa -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_server.html|20010305004147|27545|d901cdab9698605d -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_max.html|20010305004147|33999|70f356b8b67782fe -tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_class.html|20010305004147|19738|880aa614d1469304 -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_register.html|20010305004148|17668|c68fc6fb22dd594a -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_stat.html|20010305004148|27008|4628462474db62b4 -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_sync.html|20010305004148|27969|5b401daadc7261eb -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_checkpoint.html|20010305004148|31832|2565ac892d04b63d -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_open.html|20010305004148|47486|f588cc9bc694cbf0 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_put.html|20010305004148|48549|380c7caeced55512 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_dup.html|20010305004148|55139|325121689412d70b -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_index.html|20010305004148|61088|443e6b9a10ef4139 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_abort.html|20010305004148|63068|8cc23b6ef6f457d2 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/version.html|20010305004148|65038|eeb51f4de1bbfe8e -tim@threads.polyesthetic.msg|bdb/docs/index.html|20010305004143|26935|450dd5db21a9bb64 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/close.html|20010305004148|10227|ed6f7427edc0431 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/curget.html|20010305004148|15271|d7dd42affcd54073 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_ffactor.html|20010305004149|25120|5eb87b7ce99f3362 -tim@threads.polyesthetic.msg|bdb/docs/ref/arch/smallpic.gif|20010305004149|42169|fdf77055d7e711 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/hpux.html|20010305004149|47818|d34942564699608 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/linux.html|20010305004149|51464|f9f2d09dc6df75e -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/notes.html|20010305004149|52391|97e9b52853db15ea -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sunos.html|20010305004149|58008|fc41965e9d95985c -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/ultrix.html|20010305004149|59865|a1dd780edcde11f6 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/notes.html|20010305004149|01764|4058bf968f287f7 -tim@threads.polyesthetic.msg|bdb/docs/ref/debug/intro.html|20010305004149|06616|57ef29f26341ea -tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.be.txt|20010305004150|22805|cf7d25e758432ab6 -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/what.html|20010305004150|00539|dd70b9e6e085725d -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/dead.html|20010305004150|33535|f5c7debd9ba739bb -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/max.html|20010305004150|35299|f0fb32ebc251f636 -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/notxn.html|20010305004150|37003|beec805d9f05e2bc -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/stdmode.html|20010305004150|38797|4048a052ea129ca3 -tim@threads.polyesthetic.msg|bdb/docs/ref/mp/intro.html|20010305004150|45138|34937731cafcf1b1 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/mt.html|20010305004150|57429|552ab570b657fc0e -tim@threads.polyesthetic.msg|bdb/docs/ref/program/namespace.html|20010305004150|58394|182f8f762343bdc1 -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/intro.html|20010305004150|22878|7544c4688623a54c -tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/error.html|20010305004151|21581|37b817c57777b460 -tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/intro.html|20010305004151|20749|d66c6c398e2ace0b -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/deadlock.html|20010305004151|46421|34914b9dc6b01703 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/put.html|20010305004151|51420|8cc785aeecff8535 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/term.html|20010305004151|54819|d6f3fa4fc5a630ec -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/transapp.txt|20010305004151|57368|337576ea2aae23b0 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/why.html|20010305004151|56525|c941c1a56a0adbaf -tim@threads.polyesthetic.msg|bdb/docs/ref/txn/config.html|20010305004151|59874|c7337cb30f9bf66 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/system.html|20010305004151|03146|eae0256a127c3c89 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/close.html|20010305004151|05457|c79c866b393785cc -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbinfo.html|20010305004151|10780|7529af7145c0680a -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/envopen.html|20010305004151|14369|5e768fd180f471e4 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_detect.html|20010305004151|19846|fb307b10156762ca -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_commit.html|20010305004151|32241|e1debf9ea769426c -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/disk.html|20010305004152|39192|2abdaf9059265ba9 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/callback.html|20010305004152|53656|64a2b2b85cc253c1 -tim@threads.polyesthetic.msg|bdb/docs/sleepycat/license.html|20010305004152|03483|9371001bbf0ba2dd -tim@threads.polyesthetic.msg|bdb/docs/utility/index.html|20010305004152|05717|66c82ee036c1b369 -tim@threads.polyesthetic.msg|bdb/qam/qam_auto.c|20010305004141|31764|361954d3f149feb0 -tim@threads.polyesthetic.msg|bdb/test/logtrack.list|20010305004142|05743|7f4f1382b37d98e5 -BK|Docs/Flags/south-africa1.eps|19700101030959|00193|111e4f92f4562e9d -BK|sql-bench/Results-win32/create-mysql-win98|19700101030959|02538|f66c2cb2909c4792 -BK|sql-bench/Results/wisconsin-mysql_3.21-Linux_2.0.35_i686|19700101030959|02302|31703d40ea6b4f66 -BK|sql/share/english/errmsg.sys|19700101030959|01834|f29bd4ea5aaf54c8 -BK|sql/share/german/errmsg.sys|19700101030959|01840|1ea60675399c84c -BK|sql/share/korean/errmsg.sys|19700101030959|01850|a30e3687ae75a7c9 -miguel@hegel.local|zlib/contrib/delphi/zlib.mak|20020319032514|11153|7b97eb8cf290a42 -miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsp|20020319032516|54044|ec35fd54c9b49987 -miguel@hegel.local|zlib/faq|20020319032517|20799|b0d0840d3b9faf07 -miguel@hegel.local|zlib/zlib.h|20020319032519|20598|fbec7833981c782f -monty@donna.mysql.com|sql-bench/Results/big-tables-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17709|6d8209bf72b663ed -monty@hundin.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|32241|dd306b2e583ebde4 -monty@hundin.mysql.fi|sql-bench/Results/select-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|56860|b01175ad38fd12b6 -monty@hundin.mysql.fi|sql-bench/Results/wisconsin-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|23386|1ed1dc6abd24e7e3 -monty@narttu.mysql.com|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|15583|a2a77f37b689cd63 -monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.14_my_SMP_i686|20001218015323|04134|d46860c29c5d51ee -monty@work.mysql.com|libmysqld/WHITEPAPER|20010411110351|28263|da1226799debcf3f -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000007.xml|20001017133625|48163|bfcb6d85276be7e8 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000016.xml|20001017133713|07087|32f1ef2e3d214be0 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000023.xml|20001017133713|20719|11993b379b9838be -sasha@mysql.sashanet.com|mysql-test/t/identity.test|20010910233028|36116|326f469b59105404 -serg@serg.mysql.com|mysql-test/r/ft0000001.a.result|20001211130756|05199|3d17aff15fa5a9f1 -serg@serg.mysql.com|mysql-test/r/ft0000001.c.result|20001211130756|14950|1040289a75243a92 -serg@serg.mysql.com|mysql-test/t/3.23/mrg000001.test|20001206231615|27540|e0327f9d1e6cb4e -serg@serg.mysql.com|mysql-test/t/sel000009.test|20001211130730|33139|a455c38f5c942cd1 serg@serg.mysql.com|mysql-test/t/sel000019.test|20001211130731|47552|8fd63c8dc6be8dbc serg@serg.mysql.com|mysql-test/t/sel000020.test|20001211130731|52532|c5758ad18a6dff1e -tim@threads.polyesthetic.msg|bdb/dist/build/chk.offt|20010305004137|16371|25759c9294db634e -tim@threads.polyesthetic.msg|bdb/dist/template/rec_log|20010305004137|27185|3fe6d62c43bc553a -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_fd.html|20010305004144|28004|15a01776b340a959 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_key_range.html|20010305004144|33389|1060761b1e359d85 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_paniccall.html|20010305004144|02405|ac7f63325b4499ce -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_del.html|20010305004144|24335|2685f75d28e4ad99 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_open.html|20010305004144|29421|e4c9706220a4cd9b -tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_id.html|20010305004145|43025|c9ee776f928a38f -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_archive.html|20010305004145|46850|490428ce45f9f918 -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_flush.html|20010305004145|49632|bb8bc4fc43c9f63d -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fopen.html|20010305004145|57267|d032a963a0103472 -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_stat.html|20010305004145|62160|55a9521fe04b03bd -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_sync.html|20010305004145|63168|b387035a94c20c50 -tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_begin.html|20010305004145|00608|557b34fd3e7363 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_close.html|20010305004145|28189|cc570e65ac7d22f -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get.html|20010305004145|34357|3b6e6005f3f17f2a -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_cachesize.html|20010305004146|12541|3befdbaf98d5a04e -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_dup_compare.html|20010305004146|13472|91f36955a213e0f4 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_pagesize.html|20010305004146|20914|b8d544ec3e102c6c -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_count.html|20010305004146|31395|bc025b8894450525 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbenv_class.html|20010305004145|16297|5ab8aaf8a531f76b -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_open.html|20010305004146|37756|66ac1ae7fa67ca4a -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errcall.html|20010305004146|41745|bae25b45b0196773 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_locks.html|20010305004146|51576|bbde4ffbcc607f61 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_objects.html|20010305004146|53572|c47424e4d13d5327 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_stat.html|20010305004146|20379|dc2d4ffe7950fc09 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fput.html|20010305004146|26004|7ee8cda6287dee81 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_stat.html|20010305004146|31867|d370717a78971be1 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_stat.html|20010305004147|06751|e8e25f86f8541696 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_max.html|20010305004147|13429|c9f705492162e175 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_region_init.html|20010305004147|26379|30534afa94cbf54e -tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_put.html|20010305004148|09226|5af89e4cbf29c694 -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_trickle.html|20010305004148|28912|4d5c4e83a4a5c638 -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_class.html|20010305004147|23221|c7bb2a3393ca9488 -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_stat.html|20010305004148|34772|9a6ef8c262f218f9 -tim@threads.polyesthetic.msg|bdb/docs/images/sleepycat.gif|20010305004148|07668|ea63aaaa508ef096 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/get.html|20010305004148|20425|96c9c9a01c32d16 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/put.html|20010305004148|28752|8e18b0af61eb7f0f -tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.gif|20010305004149|41251|fe43e7415b3bbdb0 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/freebsd.html|20010305004149|46918|8ed2a42e1668004c -tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/text.html|20010305004149|14998|88b57a73860b423 -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/page.html|20010305004150|37863|d56876b2565cbee -tim@threads.polyesthetic.msg|bdb/docs/ref/perl/intro.html|20010305004150|47570|ce7e794e619e1e1d -tim@threads.polyesthetic.msg|bdb/docs/ref/pindex.src|20010305004149|02223|7d74723f9fd25801 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/environ.html|20010305004150|54494|dc4a48aa531bd399 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/solaris.txt|20010305004150|63135|8b6bb29de0d58ffe -tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/faq.html|20010305004151|22367|f8433900f7f85400 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/disk.html|20010305004151|01410|94dc4e6e3668e613 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/cxx.html|20010305004151|06323|7f3bfc9bba854d48 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/btstat.html|20010305004152|37584|40a76aef8b25a948 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tcl.html|20010305004152|49096|f5c85b09c33bda4 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/intro.html|20010305004152|57734|984a9f7dd07e0c14 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/set_flags.html|20010305004152|61061|213809ca8d7802d0 -tim@threads.polyesthetic.msg|bdb/docs/ref/xa/intro.html|20010305004152|00728|8ac020ffb869e9a8 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_deadlock.html|20010305004152|09191|f23f99911c3e5784 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_verify.html|20010305004152|15424|4fee9bfa2f9ab41a -tim@threads.polyesthetic.msg|bdb/include/hash_ext.h|20010305004138|10079|5b31ff8413481606 -tim@threads.polyesthetic.msg|bdb/include/qam_auto.h|20010305004138|24568|96f6c045fd0d6cab -tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_svc.c|20010305004141|50897|35804eb82b953f49 -BK|Docs/Flags/island.txt|19700101030959|00220|301ede0f81c5f3e1 -BK|client/violite.c|19700101030959|00561|afa871b4aab14371 -BK|include/Attic/config-win32.h|19700101030959|00116|65db818ec7e8f21b -BK|sql-bench/Results/connect-mysql_3.21-Linux_2.0.35_i686|19700101030959|02146|650abd213e6828c6 -BK|sql-bench/Results/insert-mysql-3.21-Linux_2.2.1_i686|19700101030959|02239|fd082017c7c57a6 -BK|sql-bench/Results/wisconsin-mysql-3.21-Linux_2.2.1_i686|19700101030959|02290|8147dc16a1dc6c47 -BK|sql/ha_hash.h|19700101030959|01902|27e36916116beb3e -BK|sql/share/hungarian/errmsg.sys|19700101030959|01845|aff82c16a77fc800 -BK|sql/share/japanese/errmsg.sys|19700101030959|01848|302478c84697dc00 -BK|sql/share/norwegian/.cvsignore|19700101030959|01853|a91d63182f0b2366 -BK|sql/share/russian/errmsg.sys|19700101030959|01860|72688df0beeabcb3 -BK|sql/share/spanish/errmsg.sys|19700101030959|01865|10c8f32da39070b2 -BK|strings/Attic/ctype-cp1257.c|19700101030959|01340|732611cbc74aeafc -BK|strings/Attic/ctype-hebrew.c|19700101030959|01348|d3b4a000d51e76dc -BK|strings/Attic/ctype-win1251ukr.c|19700101030959|01359|b5a7cca889bbef58 -BK|strings/Attic/memory.h|19700101030959|01336|450f586e82a26d99 -BK|tests/fork_test.pl|19700101030959|01945|3d3535329ed8cd5e -BK|vio/VioAcceptorFd.h|19700101030959|00006|7f9c4358477ba9a3 -BK|vio/VioFd.h|19700101030959|00010|8294293a88c7b4b8 -BK|vio/VioPipe.h|19700101030959|00012|21cebbe61a1da546 -miguel@hegel.local|zlib/contrib/iostream/zfstream.cpp|20020319032515|55262|dce18d1a5d7096b7 -miguel@hegel.local|zlib/contrib/minizip/miniunz.c|20020319032515|21943|6a80009b319b1b9e -miguel@hegel.local|zlib/contrib/minizip/unzip.def|20020319032516|14456|b4162b8c833ab6c7 -miguel@hegel.local|zlib/descrip.mms|20020319032517|08063|7d61d33062ef53ec -miguel@hegel.local|zlib/minigzip.c|20020319032518|25601|37f8eacb80c7f8fc -miguel@hegel.local|zlib/os2/zlib.def|20020319032519|28842|1166a95d83c5f52c -monty@donna.mysql.com|sql-bench/Results/alter-table-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|17106|6e532c1936df1737 -monty@donna.mysql.com|sql-bench/Results/connect-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|18910|7ed15d6fd1a5944c -monty@donna.mysql.com|sql-bench/Results/select-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|24071|4f7795c27eaab86b -monty@hundin.mysql.fi|sql-bench/Results/alter-table-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|39143|662b96bc66bc91b6 -monty@hundin.mysql.fi|sql-bench/Results/create-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|12309|f3b1d326092bf44 -monty@narttu.mysql.com|sql-bench/Results/ATIS-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|07879|2ac8fe298953d43 -monty@narttu.mysql.com|sql-bench/Results/RUN-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|09727|79ac0482599eace1 -monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.13_SMP_alpha|20001014001004|08145|21ddf9425cbdd58 -monty@narttu.mysql.fi|sql-bench/Results/big-tables-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|30548|f1127add9307098b -monty@narttu.mysql.fi|sql-bench/Results/create-mysql-Linux_2.2.13_SMP_alpha|20001014001004|23947|2c9af91e9771f618 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000003.xml|20001013074610|26659|1a622b8d30d7ade8 -sasha@mysql.sashanet.com|build-tags|20011201050944|25384|b6f6fff142121618 -sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000004.test|20001103140433|32471|daf9ad4a1a31cd3c -sasha@mysql.sashanet.com|sounds/compilation_finished.au.gz|20010814034002|63992|70bd14095a918139 -serg@serg.mysql.com|mysql-test/t/sel000013.test|20001211130731|18090|ce8aa504ba4f74ba +serg@serg.mysql.com|mysql-test/t/sel000021.test|20001211130731|57561|94dd47de2872264a +serg@serg.mysql.com|mysql-test/t/sel000022.test|20001211130731|62553|6e3e5435e66875e9 +serg@serg.mysql.com|mysql-test/t/sel000023.test|20001211130731|02042|7bdfcfaa278f837d +serg@serg.mysql.com|mysql-test/t/sel000024.test|20001211130731|07099|849f47e6cbdc4fe3 +serg@serg.mysql.com|mysql-test/t/sel000025.test|20001211130731|12136|65b32b4b67e4c77 +serg@serg.mysql.com|mysql-test/t/sel000026.test|20001211130731|17211|d8aa2d614f23b1 +serg@serg.mysql.com|mysql-test/t/sel000027.test|20001211130731|23677|ab44bb57a580de9 serg@serg.mysql.com|mysql-test/t/sel000028.test|20001211130731|28317|db9bfc0a808fb629 +serg@serg.mysql.com|mysql-test/t/sel000029.test|20001211130731|32917|6aae34dbb3ee86d9 serg@serg.mysql.com|mysql-test/t/sel000030.test|20001211130732|03110|a29683eac3e7b706 +tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.eps|20020228162345|64529|31ade79a89683616 +tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.gif|20020228162348|36945|364ca7338682f71 +tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.txt|20020228162350|33044|e155c53c10374ff +tim@cane.mysql.fi|mysql-test/r/delete.result|20001221095802|20463|e866a6678e29f186 tim@cane.mysql.fi|mysql-test/t/delete.test|20001221095802|36821|389410e29f2cebe5 tim@threads.polyesthetic.msg|bdb/btree/btree_auto.c|20010305004134|12592|a683156a176761f +tim@threads.polyesthetic.msg|bdb/build_vxworks/db_int.h|20010305004134|18702|40ba51edce41403f +tim@threads.polyesthetic.msg|bdb/build_win32/db_archive.dsp|20010305004134|25535|e3da826e91bb086 tim@threads.polyesthetic.msg|bdb/build_win32/db_checkpoint.dsp|20010305004134|26943|8071af22db95b1db +tim@threads.polyesthetic.msg|bdb/build_win32/db_deadlock.dsp|20010305004134|28374|befd45d29eaeb672 +tim@threads.polyesthetic.msg|bdb/build_win32/db_dll.dsp|20010305004134|29137|4e9dda53c84511b6 +tim@threads.polyesthetic.msg|bdb/build_win32/db_dump.dsp|20010305004134|29985|e07d2a82708b61 +tim@threads.polyesthetic.msg|bdb/build_win32/db_int.h|20010305004134|30736|9ee5645850a336a0 +tim@threads.polyesthetic.msg|bdb/build_win32/db_java.dsp|20010305004134|31520|e3941d5a9810b360 +tim@threads.polyesthetic.msg|bdb/build_win32/db_load.dsp|20010305004134|32237|e83a2af8e24a715d +tim@threads.polyesthetic.msg|bdb/build_win32/db_printlog.dsp|20010305004134|32975|163f6e1073a5f396 +tim@threads.polyesthetic.msg|bdb/build_win32/db_recover.dsp|20010305004134|34274|835c32ab73359256 +tim@threads.polyesthetic.msg|bdb/build_win32/db_stat.dsp|20010305004135|00560|f77417f5d9984986 +tim@threads.polyesthetic.msg|bdb/build_win32/db_static.dsp|20010305004135|01425|78ea414467defc70 +tim@threads.polyesthetic.msg|bdb/build_win32/db_tcl.dsp|20010305004135|02285|5ad951d774e41520 tim@threads.polyesthetic.msg|bdb/build_win32/db_upgrade.dsp|20010305004135|03711|90fd250190af4984 +tim@threads.polyesthetic.msg|bdb/build_win32/db_verify.dsp|20010305004135|04464|e9a4938542f86cea +tim@threads.polyesthetic.msg|bdb/build_win32/ex_access.dsp|20010305004135|07926|8dd6017efffae14e +tim@threads.polyesthetic.msg|bdb/build_win32/ex_btrec.dsp|20010305004135|08710|c87137287d8d67dc +tim@threads.polyesthetic.msg|bdb/build_win32/ex_env.dsp|20010305004135|09533|1732d5e41efda77 +tim@threads.polyesthetic.msg|bdb/build_win32/ex_lock.dsp|20010305004135|10303|286d2566e786dde +tim@threads.polyesthetic.msg|bdb/build_win32/ex_mpool.dsp|20010305004135|11076|9eb937bc70c1573 +tim@threads.polyesthetic.msg|bdb/build_win32/ex_tpcb.dsp|20010305004135|11838|644b38dae8b38152 +tim@threads.polyesthetic.msg|bdb/build_win32/excxx_access.dsp|20010305004135|12614|31e87b6228470681 +tim@threads.polyesthetic.msg|bdb/build_win32/excxx_btrec.dsp|20010305004135|13384|61b563f4ac1f73eb +tim@threads.polyesthetic.msg|bdb/build_win32/excxx_env.dsp|20010305004135|14159|b0bf2649a4c797ac +tim@threads.polyesthetic.msg|bdb/build_win32/excxx_lock.dsp|20010305004135|14943|257abf03544f6270 +tim@threads.polyesthetic.msg|bdb/build_win32/excxx_mpool.dsp|20010305004135|15715|d17a5d09f09f5217 +tim@threads.polyesthetic.msg|bdb/build_win32/excxx_tpcb.dsp|20010305004135|16510|159c727e2c15105e +tim@threads.polyesthetic.msg|bdb/build_win32/include.tcl|20010305004135|17284|f8bffb5e2510f229 +tim@threads.polyesthetic.msg|bdb/build_win32/libdb.rc|20010305004135|20964|906f4936ec6a8398 +tim@threads.polyesthetic.msg|bdb/db/crdel_auto.c|20010305004136|27298|ee4146a08fd175c1 +tim@threads.polyesthetic.msg|bdb/db/db_auto.c|20010305004136|32432|3186e950cc321ae7 +tim@threads.polyesthetic.msg|bdb/dist/build/chk.define|20010305004137|15254|aa9a626e58631003 +tim@threads.polyesthetic.msg|bdb/dist/build/chk.def|20010305004137|13920|bb65b471d09f7c58 +tim@threads.polyesthetic.msg|bdb/dist/build/chk.offt|20010305004137|16371|25759c9294db634e +tim@threads.polyesthetic.msg|bdb/dist/build/chk.srcfiles|20010305004137|18056|ae884700cd110cbf +tim@threads.polyesthetic.msg|bdb/dist/build/chk.tags|20010305004137|19101|7a5b14d33d4078cc +tim@threads.polyesthetic.msg|bdb/dist/config.guess|20010305004136|14678|ead1d91caeaa748c +tim@threads.polyesthetic.msg|bdb/dist/config.hin|20010305004136|15955|fdecb7a06fa137a7 +tim@threads.polyesthetic.msg|bdb/dist/config.sub|20010305004136|16944|17e9990a298261a tim@threads.polyesthetic.msg|bdb/dist/install-sh|20010305004136|21695|1858c24340b72628 +tim@threads.polyesthetic.msg|bdb/dist/template/db_server_proc|20010305004137|21042|2e8b49d42aefab55 tim@threads.polyesthetic.msg|bdb/dist/template/gen_client_ret|20010305004137|22087|786a5e65119b3991 +tim@threads.polyesthetic.msg|bdb/dist/template/rec_btree|20010305004137|23131|65d6b0b2f5b7a6d2 +tim@threads.polyesthetic.msg|bdb/dist/template/rec_crdel|20010305004137|24191|58795c0c5232f80d +tim@threads.polyesthetic.msg|bdb/dist/template/rec_db|20010305004137|25141|52c5797539878fca +tim@threads.polyesthetic.msg|bdb/dist/template/rec_hash|20010305004137|26120|dcbdd106ae17b865 +tim@threads.polyesthetic.msg|bdb/dist/template/rec_log|20010305004137|27185|3fe6d62c43bc553a +tim@threads.polyesthetic.msg|bdb/dist/template/rec_qam|20010305004137|28066|6eecf6833de0af98 +tim@threads.polyesthetic.msg|bdb/dist/template/rec_txn|20010305004137|29072|1ff22b797deb0e1b +tim@threads.polyesthetic.msg|bdb/docs/api_c/c_index.html|20010305004143|28133|1a854fa55012906 +tim@threads.polyesthetic.msg|bdb/docs/api_c/c_pindex.html|20010305004145|05766|697acebf58a8db4 tim@threads.polyesthetic.msg|bdb/docs/api_c/db_close.html|20010305004144|26254|fda0b4dfa946f44e tim@threads.polyesthetic.msg|bdb/docs/api_c/db_create.html|20010305004143|29368|a87157ea60c82ee2 tim@threads.polyesthetic.msg|bdb/docs/api_c/db_cursor.html|20010305004144|27133|7431dd96ed3492c +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_del.html|20010305004144|11427|e8bffcf9be371317 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_err.html|20010305004143|33003|3696088bd85eeda3 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_fd.html|20010305004144|28004|15a01776b340a959 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get.html|20010305004144|29265|7e0018b93ee31eba +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_byteswapped.html|20010305004144|30478|bcab4145183a7be2 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_get_type.html|20010305004144|31538|d66aa1642a4d20e2 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_join.html|20010305004144|32446|a58c2d81ecfea5b +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_key_range.html|20010305004144|33389|1060761b1e359d85 tim@threads.polyesthetic.msg|bdb/docs/api_c/db_lsn.html|20010305004143|34135|5edb9bce1118feae +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_open.html|20010305004144|34314|59dfa6e5198c382e +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_put.html|20010305004144|35267|ea78709ffb6cd7e8 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_remove.html|20010305004144|36184|668fa1d67a4f6941 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_rename.html|20010305004144|37128|36796ad9e106c3f0 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_append_recno.html|20010305004144|38070|bdf0130e642f74fa tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_compare.html|20010305004144|39551|e55a311bb0be93a8 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_dup_compare.html|20010305004144|03068|a833bfc727a794e7 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errfile.html|20010305004144|00766|f07d3c57bb3c8fbd -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_pagesize.html|20010305004144|12535|9644fa0f538cde17 -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_count.html|20010305004144|23385|c3cd00c48b4babf5 -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_dup.html|20010305004144|25301|3bdf8b0a687b43f3 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errpfx.html|20010305004145|01527|806c8c438d0ee36c -tim@threads.polyesthetic.msg|bdb/docs/api_c/hsearch.html|20010305004144|08165|a8b76d897a8216d8 -tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_detect.html|20010305004145|41159|8fe406dce10e0bb -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_put.html|20010305004145|51546|11a1bec49bb90419 -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_unregister.html|20010305004145|54401|45b8f9d3f8eb3d80 -tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_trickle.html|20010305004145|64180|8b1adf1404d7a5f -tim@threads.polyesthetic.msg|bdb/docs/api_c/pindex.src|20010305004143|31726|d1ecd116c42e0e23 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_class.html|20010305004145|08391|3129ff8c53721fe8 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_fd.html|20010305004145|33050|99ec316575f80428 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_rename.html|20010305004146|07200|9c0a820e864220b3 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_prefix.html|20010305004146|11627|ecd8f927371a5dbd -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_hash.html|20010305004146|18078|afe952f65389d93b -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_paniccall.html|20010305004145|13411|6bc911c9d64e9237 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_flags.html|20010305004146|44734|8136e8e1ae16dc02 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_bsize.html|20010305004146|45706|7fd917bea6b163bf -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_max.html|20010305004146|47638|4f7ba5f02c66c0de -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mp_mmapsize.html|20010305004146|54573|c21e3f9c5a29b0ab -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_strerror.html|20010305004146|05414|7e1cbfbd096ca -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_archive.html|20010305004146|12836|d47f39e6dad7ee50 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_register.html|20010305004146|19292|55470e0d79382beb -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fget.html|20010305004146|23710|bfe74f8c299c2995 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fset.html|20010305004146|27124|e52fa0488faa893 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_register.html|20010305004146|29358|cba6f572fe27c7a -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_byteswapped.html|20010305004147|28706|edbc66a9d5491a1 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_join.html|20010305004147|30506|a3a6dead9cae65f9 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_rename.html|20010305004147|35341|19b20feaa815bc27 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_nelem.html|20010305004147|49144|fc6f22a4c285fcef -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_source.html|20010305004147|55969|b29827dbf47537d1 -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_close.html|20010305004147|61116|e3bf1f36bc0e8e7e -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbt_class.html|20010305004147|13192|f6b04ff142e332f8 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_error_stream.html|20010305004147|15677|a738119910b452b8 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_feedback.html|20010305004147|09255|9748745e65f070d5 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_locks.html|20010305004147|17677|f0114205b169de39 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_pageyield.html|20010305004147|23054|774b3da0306a6767 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_panicstate.html|20010305004147|24142|72846d9a97cb80bb -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tmp_dir.html|20010305004147|32251|f23e4f614f6d975a -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_verbose.html|20010305004148|03690|9dcda0399c8256e7 -tim@threads.polyesthetic.msg|bdb/docs/api_java/except_class.html|20010305004147|16978|195c00e4a7cbe648 -tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_id.html|20010305004148|08326|737cf8d8dc74084e -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_get.html|20010305004148|15736|5fbbbd4baa60e052 -tim@threads.polyesthetic.msg|bdb/docs/api_java/mem_class.html|20010305004147|21486|2e5052b5b2bea584 -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fopen.html|20010305004148|22355|f7cf58725aa1c406 -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_register.html|20010305004148|26052|8331390a1c66fefd -tim@threads.polyesthetic.msg|bdb/docs/api_java/pindex.src|20010305004147|10521|de828917f041d27b -tim@threads.polyesthetic.msg|bdb/docs/api_java/runrec_class.html|20010305004147|22358|49c5cb3efe0c201 -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_commit.html|20010305004148|32812|c265042f3340baa1 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_close.html|20010305004148|38213|f40794b17e0fe443 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_remove.html|20010305004148|50431|3b2be4b0b1b3dc98 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_sync.html|20010305004148|52310|3b615ca64d934602 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_close.html|20010305004148|58109|bf191b2673a2b19e -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/pagesize.html|20010305004149|30437|eb4800704ae1131b -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/renumber.html|20010305004149|33199|b7df79bf32240b5c -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/qnx.html|20010305004149|54263|6d2849a8e8038dc9 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/intro.html|20010305004149|62808|2eed15d25078711 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/notes.html|20010305004149|63758|7e53a042c5c4d350 -tim@threads.polyesthetic.msg|bdb/docs/ref/java/program.html|20010305004150|28026|e9bbc08bccf5d396 -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/am_conv.html|20010305004150|30986|3bab32d969f21b77 -tim@threads.polyesthetic.msg|bdb/docs/ref/lock/config.html|20010305004150|32692|a593ea4c87467ddd -tim@threads.polyesthetic.msg|bdb/docs/ref/log/intro.html|20010305004150|42339|31e7055d83ca8757 -tim@threads.polyesthetic.msg|bdb/docs/ref/mp/config.html|20010305004150|46018|771c2c91fc0b6b17 -tim@threads.polyesthetic.msg|bdb/docs/ref/txn/nested.html|20010305004151|62443|6860bbf2f29aa93b -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/dup.html|20010305004152|40004|911018877c118b45 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/tx_recover.html|20010305004152|62754|132a354cde7a8286 -tim@threads.polyesthetic.msg|bdb/docs/ref/xa/config.html|20010305004152|64479|3f3f449c305e66b4 -tim@threads.polyesthetic.msg|bdb/docs/ref/xa/faq.html|20010305004152|65373|7aa890c7b70f1293 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_upgrade.html|20010305004152|14532|6444f26a93f77ea -tim@threads.polyesthetic.msg|bdb/include/crdel_auto.h|20010305004137|21088|1b8255da47550ece -tim@threads.polyesthetic.msg|bdb/include/db_server.h|20010305004137|34247|61a33aa05bf368a7 -tim@threads.polyesthetic.msg|bdb/include/mutex_ext.h|20010305004138|19006|f20f47ddc346598b -tim@threads.polyesthetic.msg|bdb/include/qam_ext.h|20010305004138|25430|9993db1fb3428b6d -tim@threads.polyesthetic.msg|bdb/include/tcl_ext.h|20010305004138|31857|6759d22aa2ff5f39 -tim@threads.polyesthetic.msg|bdb/include/txn_auto.h|20010305004138|33645|e3f49e94fd291c45 -tim@threads.polyesthetic.msg|bdb/rpc_client/gen_client.c|20010305004141|43060|ad86f092d0996a68 -tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_proc.sed|20010305004141|49906|1a9af8e5b051acbd -tim@threads.polyesthetic.msg|bdb/test/include.tcl|20010305004141|34016|20fc297b040cbe2 -BK|client/Attic/libmysql.c|19700101030959|00582|72949a7043113807 -BK|mit-pthreads/pg++|19700101030959|00597|3beac0502025d766 -BK|myisam/ft_search.c|19700101030959|01642|c011cb6e8041bb59 -BK|mysys/test_vsnprintf.c|19700101030959|01502|e3d568aca62dc81e -BK|strings/Attic/ctype-usa7.c|19700101030959|01356|d19d859dca5675f -BK|strings/Attic/ctype-win1251.c|19700101030959|01358|762607f4fd7d52ad -BK|tests/fork3_test.pl|19700101030959|01947|c4a7bffb4f8e813c -BK|vio/VioSSLFactoriesFd.h|19700101030959|00017|1d63ae149a63f85 -BK|vio/VioSocket.cc|19700101030959|00018|71c615783f29b5e1 -Sinisa@sinisa.nasamreza.org|scripts/mysql_new_fix_privilege_tables.sh|20011226144909|43765|b1664b401375eece -miguel@hegel.local|zlib/contrib/iostream/test.cpp|20020319032515|48225|a2ea8d4d7c66cf71 -miguel@hegel.local|zlib/contrib/minizip/unzip.c|20020319032516|07891|c66c95e17321206d -miguel@hegel.local|zlib/deflate.c|20020319032516|26978|e22894a54233bc25 -miguel@hegel.local|zlib/infcodes.c|20020319032517|52620|dffb42fdf2fb2372 -miguel@hegel.local|zlib/inffast.h|20020319032517|06651|215e4a4ccfc886fc -miguel@hegel.local|zlib/maketree.c|20020319032518|19299|7f281aef3547fee -miguel@hegel.local|zlib/msdos/zlib.rc|20020319032518|25240|f8a286fa8371ee09 -miguel@hegel.local|zlib/zutil.c|20020319032520|05372|6f0d1763c5deb409 -monty@donna.mysql.com|sql-bench/Results/alter-table-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|16525|2f516d2c108a9e05 -monty@donna.mysql.com|sql-bench/Results/insert-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|22723|a85a6f0477c13f83 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000017.xml|20001017133713|08762|81423597605ff77f -sasha@mysql.sashanet.com|build-tags|20011125054855|05181|7afb7e785b80f97 -sasha@mysql.sashanet.com|mysql-test/r/binlog-backup-restore.result|20010424233926|16010|605de78abda64d27 -sasha@mysql.sashanet.com|mysql-test/r/identity.result|20010910233028|16331|e41453a364242503 -serg@serg.mysql.com|mysql-test/t/sel000010.test|20001211130731|03554|ca07085ae92255f1 -tim@threads.polyesthetic.msg|bdb/build_win32/excxx_tpcb.dsp|20010305004135|16510|159c727e2c15105e -tim@threads.polyesthetic.msg|bdb/dist/build/chk.define|20010305004137|15254|aa9a626e58631003 -tim@threads.polyesthetic.msg|bdb/dist/template/rec_hash|20010305004137|26120|dcbdd106ae17b865 tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_minkey.html|20010305004144|40498|e2d52ba2d0174432 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_delim.html|20010305004144|14446|e0a7face764111b9 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_upgrade.html|20010305004144|20363|5e6210d6f09a0c3e -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errfile.html|20010305004144|06564|3b6b0822f29fc3d4 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_panicstate.html|20010305004145|29311|43228366ca64363c -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirfree.html|20010305004144|09784|d59f36547c7b5384 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirlist.html|20010305004144|10606|24e75ccc86809023 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_ioinfo.html|20010305004144|14713|80365bb8c66ae84c -tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_checkpoint.html|20010305004145|01607|4a1704dbfcaad5dc -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_byteswapped.html|20010305004146|00979|a44d5d57d050b466 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_put.html|20010305004146|05435|2792034e8c83c56 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errfile.html|20010305004145|11465|f6eddb9ab7ef07d0 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_flags.html|20010305004146|16174|1146625feeb3bb0b -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_source.html|20010305004146|25550|46998978715ccc1 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_conflicts.html|20010305004146|48615|5bba88df4cc6dfba -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_lockers.html|20010305004146|52578|ebb61fd669c2eefb -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_timestamp.html|20010305004146|03286|6396a1145f8e41c1 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_class.html|20010305004145|23233|ed88ab78cccbef8d -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/mempfile_class.html|20010305004145|25191|672b4aa787b4aeca -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_id.html|20010305004147|04873|162661f4c2dc09d6 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_prepare.html|20010305004147|05797|818b4163518bace5 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_cursor.html|20010305004147|25020|2181d652bd1c1ff -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_fd.html|20010305004147|26830|1f70020c37023baa -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_prefix.html|20010305004147|39088|a3269aad23e6dbc -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_dup_compare.html|20010305004147|40992|3dabd840a1d9e5f3 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_errcall.html|20010305004147|41930|4e4743f5b4277199 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_delim.html|20010305004147|53019|78fcf2d750fb26ef -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_cachesize.html|20010305004147|05132|f3700cd19856f14e -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_objects.html|20010305004147|19812|d1ed194631ffeb2a -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mutexlocks.html|20010305004147|21961|aad8e4a059075bb6 -tim@threads.polyesthetic.msg|bdb/docs/api_java/java_index.html|20010305004147|18736|8ecfcef4a702011d -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_unregister.html|20010305004148|19590|eee284e0da176d0a -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_count.html|20010305004148|40010|4812f3756a75437 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_rename.html|20010305004148|49486|909bc643d5455b54 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_del.html|20010305004148|54185|7e94f9f01e7e4453 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_get.html|20010305004148|56098|5bbb80cf51aff594 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/join.html|20010305004148|22331|acc16686a78a732 -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/cachesize.html|20010305004149|22486|99dcd466dc881093 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/aix.html|20010305004149|44137|e8ae448bdb85fa22 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/conf.html|20010305004149|45053|d0378c69618b790b -tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/faq.html|20010305004149|65331|34704a907168cea7 -tim@threads.polyesthetic.msg|bdb/docs/ref/debug/common.html|20010305004149|07598|607061232e2532df -tim@threads.polyesthetic.msg|bdb/docs/ref/debug/compile.html|20010305004149|08609|12785e3091b78bfd -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/where.html|20010305004150|01442|6cb9ec27f19ecbbb -tim@threads.polyesthetic.msg|bdb/docs/ref/program/diskspace.html|20010305004150|53502|959508f155721ee8 -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/example.txt|20010305004150|28042|9ff88f22565208bf -tim@threads.polyesthetic.msg|bdb/docs/ref/txn/limits.html|20010305004151|61583|3004b7a93dab148b -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/convert.html|20010305004151|00512|d7f18eb34c1b6ae -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db_cxx.html|20010305004151|08078|5c17d6a360205140 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_stat.html|20010305004151|22568|c49716e693ce225b -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/log_register.html|20010305004152|42524|7177eeb2fc099317 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/memp_register.html|20010305004152|44171|7d92464a1029d53e -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/put.html|20010305004152|44997|961a1a689be6ce -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_feedback.html|20010305004152|45815|6d7de50be92a5488 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/db_dump.html|20010305004152|54477|7d1cac3358c0482e -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/handle.html|20010305004152|56086|bb8a73b74d4399ae -tim@threads.polyesthetic.msg|bdb/docs/utility/berkeley_db_svc.html|20010305004152|06576|91fe012778882ce4 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_dump.html|20010305004152|10062|5de7ade427f20332 -tim@threads.polyesthetic.msg|bdb/include/btree_ext.h|20010305004137|18246|5d53d710f170c6b6 -tim@threads.polyesthetic.msg|bdb/include/gen_server_ext.h|20010305004138|07539|fd7bcfe6bbca8bcb -tim@threads.polyesthetic.msg|bdb/include/mp_ext.h|20010305004138|17070|a528b772d42d6455 -BK|include/Attic/mysql_com.h.in|19700101030959|00115|85b1ea7ced528c32 -BK|libmysql/configure.in|19700101030959|02603|c6fc04d4e3d6e291 -BK|myisam/Attic/ft_global.h|19700101030959|01673|fe46fb515f1e375 -BK|sql-bench/Results-win32/alter-table-mysql-win98|19700101030959|02529|e8743982f790462 -BK|sql-bench/Results/alter-table-mysql-3.21-Linux_2.2.1_i686|19700101030959|02073|f6f7ccd7b3c35f97 -BK|sql/Attic/mini_client_errors.c|19700101030959|01909|29edad51a5d0b068 -BK|sql/Attic/net_serv.c|19700101030959|01911|52dabcd773a39e10 -BK|strings/Attic/ctype-greek.c|19700101030959|01347|90acdff1195209ca -BK|strings/Attic/ctype-koi8_ukr.c|19700101030959|01352|a04aa14a6d62335a -BK|support-files/Attic/my-huge.cfg.sh|19700101030959|02585|589bdcd2d2c4360b -BK|support-files/Attic/my-medium.cfg.sh|19700101030959|02587|c49880d26ef0648e -BK|vio/Vio.cc|19700101030959|00003|60737ce02ab2bc25 -miguel@hegel.local|zlib/contrib/asm686/readme.686|20020319032514|04933|15e2bf4653b71f3e -miguel@hegel.local|zlib/contrib/minizip/minizip.c|20020319032515|28588|97181367a7bc47d8 -miguel@hegel.local|zlib/inftrees.h|20020319032517|32227|ffcbe51816466e5c -miguel@hegel.local|zlib/zconf.h|20020319032519|63437|c6b6b636c7e88d90 -monty@donna.mysql.com|sql-bench/Results/wisconsin-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|25437|24a02e007a58bf73 -monty@hundin.mysql.fi|sql-bench/Results/insert-mysql-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010605132759|53328|fd2699adb3190d07 -monty@narttu.mysql.com|sql-bench/Results/connect-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|19531|7dd5ac726f86cf0b -monty@narttu.mysql.com|sql-bench/Results/connect-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|21574|1cf5d5f0d70a3fa0 -monty@narttu.mysql.com|sql-bench/Results/create-mysql_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|25516|fc207468e871ff69 -monty@narttu.mysql.com|sql-bench/Results/select-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|33684|ddcf36cdf3f72e8c -mwagner@evoq.home.mwagner.org|Docs/Books/prof.eps|20001231203220|15779|dc69b039543a57d7 -mwagner@evoq.home.mwagner.org|mysql-test/xml/README|20001013051440|12362|877d76bcd19f7193 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000020.xml|20001017133713|13843|8849bbf91a4fd5ec -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000028.xml|20001017133713|29282|c72bfec6600949b -nick@nick.leippe.com|mysql-test/r/rpl_empty_master_crash.result|20020531235552|47718|615f521be2132141 -sasha@mysql.sashanet.com|mysql-test/t/3.23/sel000005.test|20001103140433|36002|982fde89a4d6d886 -serg@serg.mysql.com|mysql-test/r/ft0000001.b.result|20001211130756|10153|505c4c00a0bddfc4 -serg@serg.mysql.com|mysql-test/t/sel000011.test|20001211130731|08373|c2a971726c9d18d6 -tfr@sarvik.tfr.cafe.ee|Docs/Flags/costarica.txt|20020228162350|33044|e155c53c10374ff -tim@threads.polyesthetic.msg|bdb/build_win32/db_java.dsp|20010305004134|31520|e3941d5a9810b360 -tim@threads.polyesthetic.msg|bdb/build_win32/excxx_btrec.dsp|20010305004135|13384|61b563f4ac1f73eb -tim@threads.polyesthetic.msg|bdb/docs/api_c/c_pindex.html|20010305004145|05766|697acebf58a8db4 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_bt_prefix.html|20010305004144|41420|d6e443a7e47c9b3a +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_cachesize.html|20010305004144|02131|47a3c8ca486eb013 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_dup_compare.html|20010305004144|03068|a833bfc727a794e7 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errcall.html|20010305004144|04030|faf92be4ee8bc634 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errfile.html|20010305004144|00766|f07d3c57bb3c8fbd +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_errpfx.html|20010305004144|05859|756b9b73dd28b8d9 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_feedback.html|20010305004144|06786|90d495e78318a332 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_flags.html|20010305004144|07758|4cd3700ae4387d22 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_ffactor.html|20010305004144|08766|41352ddf74ccc338 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_hash.html|20010305004144|09702|73f14897664d9d08 tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_nelem.html|20010305004144|10635|bd8371e033b15c8f +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_lorder.html|20010305004144|11587|e24ae76325374653 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_malloc.html|20010305004144|01594|3581879fef5af695 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_pagesize.html|20010305004144|12535|9644fa0f538cde17 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_paniccall.html|20010305004144|02405|ac7f63325b4499ce +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_q_extentsize.html|20010305004144|13496|f2fe41a5d8c46658 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_delim.html|20010305004144|14446|e0a7face764111b9 tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_len.html|20010305004144|15420|f30d68257bd60e1e +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_pad.html|20010305004144|16373|8a1de721eb6fc53f +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_source.html|20010305004144|17353|6d12ac12652acc31 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_realloc.html|20010305004144|03204|a9be244baf966892 +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_stat.html|20010305004144|18351|578f6f99f8e247ff +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_sync.html|20010305004144|19394|7a067029b6e1496b +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_upgrade.html|20010305004144|20363|5e6210d6f09a0c3e +tim@threads.polyesthetic.msg|bdb/docs/api_c/db_verify.html|20010305004144|21372|cf80f5ba845eac2e +tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_close.html|20010305004144|22419|a3ad4ea563bafc42 +tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_count.html|20010305004144|23385|c3cd00c48b4babf5 +tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_del.html|20010305004144|24335|2685f75d28e4ad99 +tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_dup.html|20010305004144|25301|3bdf8b0a687b43f3 +tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_get.html|20010305004144|26284|4bf7579a92c35195 tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_put.html|20010305004144|27355|a2c4a52329376657 +tim@threads.polyesthetic.msg|bdb/docs/api_c/dbm.html|20010305004144|04019|ebf1d8e329b06bba +tim@threads.polyesthetic.msg|bdb/docs/api_c/dbt.html|20010305004144|04896|ae7a81c9c5f574f6 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_close.html|20010305004144|28399|a8e722cbb66c9d7b +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_create.html|20010305004144|05736|3e73dd35fe5dcc8 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_open.html|20010305004144|29421|e4c9706220a4cd9b +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_remove.html|20010305004144|31547|a71d5e1ca41324a7 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_cachesize.html|20010305004144|32567|f4c341d3f2c09469 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_data_dir.html|20010305004144|33569|437cec65e441c60 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errcall.html|20010305004145|00341|ba09eec1ba15f15f +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errfile.html|20010305004144|06564|3b6b0822f29fc3d4 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_errpfx.html|20010305004145|01527|806c8c438d0ee36c +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_feedback.html|20010305004145|02860|87a78f97ba545aba +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_flags.html|20010305004145|03778|b2a1f3c8498e6d95 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_bsize.html|20010305004145|04625|1eb03c137a42e80f +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_dir.html|20010305004145|05444|26be310214a2ff8f +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_max.html|20010305004145|06288|319c24b5245b0685 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_conflicts.html|20010305004145|07137|58d9f7179bc864a3 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_detect.html|20010305004145|07983|d9ed73495defdc19 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max.html|20010305004145|08849|a2dc11fa8b2f1c9 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_lockers.html|20010305004145|24923|f22d5d4640436efe +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_locks.html|20010305004145|09704|1baf2d63a6fb418d +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lk_max_objects.html|20010305004145|25791|1a428bbee06cb5cc +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mp_mmapsize.html|20010305004145|26668|21f27997f00accfe +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_mutexlocks.html|20010305004145|27540|85bbd53b877cafe1 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_pageyield.html|20010305004145|28418|8aa4a6cb2f18cad7 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_paniccall.html|20010305004144|07360|97a1d58189199453 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_panicstate.html|20010305004145|29311|43228366ca64363c +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_rec_init.html|20010305004145|30192|bf7da051ef6689ba +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_region_init.html|20010305004145|31081|2ca19f76ee1ae790 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_server.html|20010305004145|31969|c13b793b525d504b +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_shm_key.html|20010305004145|32880|cf5aaa6a995cbf55 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tas_spins.html|20010305004145|33848|91c7091deca3d97f +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tmp_dir.html|20010305004145|34771|b563e87af5431824 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_max.html|20010305004145|35672|71a739e46faf33a9 tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_recover.html|20010305004145|36580|8dd351545b444a24 tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_tx_timestamp.html|20010305004145|37492|ddb77d7dfb531085 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_verbose.html|20010305004145|38421|344f5119536cae0 tim@threads.polyesthetic.msg|bdb/docs/api_c/env_strerror.html|20010305004145|39331|7f090bf26bdd4dc -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_exists.html|20010305004144|12261|23f077e82ca8f827 -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_fsync.html|20010305004144|13884|f59339ff63d95e7d -tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_read.html|20010305004144|18372|c8f6ece1ed408bf8 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_key_range.html|20010305004146|03630|d79b373af096cb7 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_upgrade.html|20010305004146|28493|c6231eb2f9989284 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_put.html|20010305004146|35761|11e6aa2492dd1032 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbt_class.html|20010305004145|17281|fb91648586c1aa77 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_paniccall.html|20010305004145|20292|2080056f15faa516 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_recover.html|20010305004146|02235|cdf13797131b2d97 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/except_class.html|20010305004145|21277|59839667e43592e -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_flush.html|20010305004146|16027|3976f77e905f35eb -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get.html|20010305004147|27733|87b8316c55b24739 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_verify.html|20010305004147|60082|20873ab17f6ed922 -tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_del.html|20010305004147|63111|6ec2b8a4b8dde996 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_bsize.html|20010305004147|11335|6c67beed877df84c -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max.html|20010305004147|16607|12b6e34ac5a53281 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_version.html|20010305004148|05599|854d26806930cab6 -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fset.html|20010305004148|24178|5c5371a93b83275 -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_begin.html|20010305004148|30859|553bf78bd7fc3e0a -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_cursor.html|20010305004148|40924|e035b3c11a91c5d6 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_type.html|20010305004148|44686|7202f3ca793e6ec3 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn.html|20010305004148|62085|8e345950e6029230 -tim@threads.polyesthetic.msg|bdb/docs/images/prev.gif|20010305004148|04639|9448d24755d708a0 -tim@threads.polyesthetic.msg|bdb/docs/images/ps.gif|20010305004148|05648|f6b1b372cb2cda4c -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/logrec.html|20010305004149|28646|5edeb34d63936e2 -tim@threads.polyesthetic.msg|bdb/docs/ref/arch/progmodel.html|20010305004149|38491|caa422dc155b6370 -tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/intro.html|20010305004149|00770|2975a07b53b12046 -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/need.html|20010305004149|31743|43950806e35d71f -tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.ps|20010305004150|02162|9851f6cdeff17481 -tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/server.html|20010305004150|14510|79f560205494295 -tim@threads.polyesthetic.msg|bdb/docs/ref/test/faq.html|20010305004151|38444|f95038006d18229 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/admin.html|20010305004151|41323|cf867ed0b00cccef -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/data_open.html|20010305004151|45592|413c1d8aba9d8018 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv.html|20010305004151|08972|f9863847dc1ed617 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/join.html|20010305004151|18031|ec21d874caa0654 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/stat.html|20010305004151|29377|775d75e3ba02d15c -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/toc.html|20010305004151|30301|16e7d8e76496cbc9 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/env.html|20010305004152|40827|381e366a9c9c9a37 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/disk.html|20010305004152|55280|61799ebebe78ebb2 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/mutexlock.html|20010305004152|58567|972b710c5bdba67c -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/notfound.html|20010305004152|59393|dc91c094aba92838 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_load.html|20010305004152|10976|981095940db0197 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_printlog.html|20010305004152|11895|fcc4075ad0232842 -tim@threads.polyesthetic.msg|bdb/include/db_ext.h|20010305004137|29469|a1e210bbd0de0a48 -tim@threads.polyesthetic.msg|bdb/include/gen_client_ext.h|20010305004138|06647|5c621cacb18b38 -tim@threads.polyesthetic.msg|bdb/include/lock_ext.h|20010305004138|11814|ccd0785bb206933f -tim@threads.polyesthetic.msg|bdb/log/log_auto.c|20010305004137|49459|fe8c0369965f7151 -tim@threads.polyesthetic.msg|bdb/rpc_server/db_server.x|20010305004141|47705|811aeb6b630fe7aa -BK|include/Attic/m_ctype.h.in|19700101030959|00114|f671e3c2d611ba97 -BK|sql/share/norwegian-ny/.cvsignore|19700101030959|01855|469064b5190d703d -BK|sql/share/swedish/errmsg.sys|19700101030959|01866|dd772e93db859993 -BK|strings/Attic/ctype-danish.c|19700101030959|01342|dc5451066eb272ae -BK|strings/Attic/ctype-swe7.c|19700101030959|01355|bb1b012225d7d02c -BK|strings/Attic/ptr_cmp.c|19700101030959|01337|57e682a26e769597 -BK|vio/VioFd.cc|19700101030959|00009|6e444647affef63b -BK|vio/vioelitexx.cc|19700101030959|00022|3eaba70da792a7fc -miguel@hegel.local|zlib/adler32.c|20020319032513|04487|f98728c6da1ac164 -miguel@hegel.local|zlib/contrib/asm386/zlibvc.dsp|20020319032514|38372|a1c6749052ce48a -miguel@hegel.local|zlib/contrib/delphi2/zlib.pas|20020319032515|28965|3c94d3f5262cbbdd -miguel@hegel.local|zlib/contrib/iostream2/zstream_test.cpp|20020319032515|08848|63f635d540de8c48 -miguel@hegel.local|zlib/contrib/minizip/readme.txt|20020319032516|00611|7547b986c067c008 -miguel@hegel.local|zlib/contrib/minizip/zlibvc.dsw|20020319032516|60515|17f28194a5cd80ea -miguel@hegel.local|zlib/example.c|20020319032517|14327|490f57a4a9440dfa -miguel@hegel.local|zlib/infblock.h|20020319032517|46202|4526bc327b4160ab -miguel@hegel.local|zlib/infutil.h|20020319032518|12977|13089e09be34788c -miguel@hegel.local|zlib/readme|20020319032519|35257|80a41fc822f5f4 -mikef@nslinux.bedford.progress.com|mysql-test/include/have_gemini.inc|20010321203410|40631|42f94f0dfd0f7b18 -monty@donna.mysql.com|sql-bench/Results/RUN-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15344|d922a0fcc1009130 -monty@donna.mysql.com|sql-bench/Results/RUN-pg_fast-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|15933|840503a555e420ec -monty@donna.mysql.com|sql-bench/Results/create-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|20136|241c337935ae1524 -monty@hundin.mysql.fi|sql-bench/Results/insert-pg-Linux_2.4.0_64GB_SMP_i686-cmp-mysql,pg|20010603134548|15984|a0143553cccb54e2 -monty@narttu.mysql.fi|sql-bench/Results/select-mysql-Linux_2.2.13_SMP_alpha|20001014001004|29737|db59425a7f4aa93f -monty@work.mysql.com|libmysqld/README|20010411110351|24268|434e9cae5fa9a4c4 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000010.xml|20001017133713|64368|9b98c9cce8fac145 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000012.xml|20001017133713|01909|a410d08dc4cfee11 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000024.xml|20001017133713|22352|dd067aa28220fa4c -serg@serg.mysql.com|mysql-test/r/ft0000002.a.result|20001212120058|27306|a89b4db1db19f944 -serg@serg.mysql.com|mysql-test/t/sel000014.test|20001211130731|22977|74cb8c70f1d73fcc -tim@threads.polyesthetic.msg|bdb/build_win32/db_dll.dsp|20010305004134|29137|4e9dda53c84511b6 -tim@threads.polyesthetic.msg|bdb/build_win32/db_load.dsp|20010305004134|32237|e83a2af8e24a715d -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_get.html|20010305004144|26284|4bf7579a92c35195 -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbm.html|20010305004144|04019|ebf1d8e329b06bba -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_feedback.html|20010305004145|02860|87a78f97ba545aba -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_max.html|20010305004145|06288|319c24b5245b0685 +tim@threads.polyesthetic.msg|bdb/docs/api_c/env_version.html|20010305004145|40251|9bf7f99fefacc2bf +tim@threads.polyesthetic.msg|bdb/docs/api_c/hsearch.html|20010305004144|08165|a8b76d897a8216d8 +tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_detect.html|20010305004145|41159|8fe406dce10e0bb +tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_get.html|20010305004145|42084|63399d204f1885fa +tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_id.html|20010305004145|43025|c9ee776f928a38f +tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_put.html|20010305004145|44022|f5bc2f52e55f16e1 +tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_stat.html|20010305004145|44954|d9a98bb949070b +tim@threads.polyesthetic.msg|bdb/docs/api_c/lock_vec.html|20010305004145|45892|cc79e33b82b7a275 +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_archive.html|20010305004145|46850|490428ce45f9f918 tim@threads.polyesthetic.msg|bdb/docs/api_c/log_compare.html|20010305004145|47782|4f12fdf04d30ab94 +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_file.html|20010305004145|48705|574444b46b801f9c +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_flush.html|20010305004145|49632|bb8bc4fc43c9f63d +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_get.html|20010305004145|50583|24cdf17ba55cbecf +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_put.html|20010305004145|51546|11a1bec49bb90419 +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_register.html|20010305004145|52499|5381c1fad82d6527 +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_stat.html|20010305004145|53440|36b87b19ee2c5bba +tim@threads.polyesthetic.msg|bdb/docs/api_c/log_unregister.html|20010305004145|54401|45b8f9d3f8eb3d80 +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fclose.html|20010305004145|55335|b52c7d599d83c26 +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fget.html|20010305004145|56294|460714b5c2e3e1c5 +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fopen.html|20010305004145|57267|d032a963a0103472 +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fput.html|20010305004145|58291|4a7aace7db01ee15 +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fset.html|20010305004145|59241|ecb97931b222568d +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_fsync.html|20010305004145|60192|a95ab802bb28646f +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_register.html|20010305004145|61165|8b9dff9b5043da58 +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_stat.html|20010305004145|62160|55a9521fe04b03bd +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_sync.html|20010305004145|63168|b387035a94c20c50 +tim@threads.polyesthetic.msg|bdb/docs/api_c/memp_trickle.html|20010305004145|64180|8b1adf1404d7a5f +tim@threads.polyesthetic.msg|bdb/docs/api_c/pindex.src|20010305004143|31726|d1ecd116c42e0e23 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_close.html|20010305004144|08984|8981d16589844161 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirfree.html|20010305004144|09784|d59f36547c7b5384 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_dirlist.html|20010305004144|10606|24e75ccc86809023 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_exists.html|20010305004144|12261|23f077e82ca8f827 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_free.html|20010305004144|13076|ed61d2dfea9e069e +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_fsync.html|20010305004144|13884|f59339ff63d95e7d +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_ioinfo.html|20010305004144|14713|80365bb8c66ae84c +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_malloc.html|20010305004144|15535|5579a0604e14e1e7 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_map.html|20010305004144|16369|d90bbc8462ef43a6 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_open.html|20010305004144|17474|8c812591efc8abe6 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_read.html|20010305004144|18372|c8f6ece1ed408bf8 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_realloc.html|20010305004144|19375|e8e78e57c005c7c4 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_rename.html|20010305004144|20199|3f8c7b6674cda105 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_seek.html|20010305004144|21048|fdf1b31d3f6c7473 tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_sleep.html|20010305004144|21928|4b962c8b82989d8c +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unlink.html|20010305004144|22800|c42b13fd26f2e90 +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_unmap.html|20010305004144|23658|d85790692f3b536e +tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_write.html|20010305004144|24518|63567be42d586fde tim@threads.polyesthetic.msg|bdb/docs/api_c/set_func_yield.html|20010305004144|25375|ca5e359bcbeca7fd +tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_abort.html|20010305004145|65162|a53425dd70214619 +tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_begin.html|20010305004145|00608|557b34fd3e7363 +tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_checkpoint.html|20010305004145|01607|4a1704dbfcaad5dc +tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_commit.html|20010305004145|02592|8950b5e11c8b0778 tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_id.html|20010305004144|04952|1e71088a7e8f6678 tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_prepare.html|20010305004145|03605|19f84203db4e6608 +tim@threads.polyesthetic.msg|bdb/docs/api_c/txn_stat.html|20010305004145|04637|f57a656bfbac12bf +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_index.html|20010305004145|07331|a0bc165de8a0554c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/cxx_pindex.html|20010305004147|08181|9ff6b69b56f988dd +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_class.html|20010305004145|08391|3129ff8c53721fe8 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_close.html|20010305004145|28189|cc570e65ac7d22f +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_cursor.html|20010305004145|29241|4f0225f98f4a11c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_del.html|20010305004145|31220|43fa05f2dfa86dbc tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_err.html|20010305004145|10496|77022bd5af575696 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_fd.html|20010305004145|33050|99ec316575f80428 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get.html|20010305004145|34357|3b6e6005f3f17f2a +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_byteswapped.html|20010305004146|00979|a44d5d57d050b466 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_get_type.html|20010305004146|01846|398668783c4070db +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_join.html|20010305004146|02717|9c4819679501ad6e +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_key_range.html|20010305004146|03630|d79b373af096cb7 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_open.html|20010305004146|04518|ab95c48ac26ad3f7 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_put.html|20010305004146|05435|2792034e8c83c56 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_remove.html|20010305004146|06326|8c537fc5e326293b +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_rename.html|20010305004146|07200|9c0a820e864220b3 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_append_recno.html|20010305004146|08075|a158b1fdba756ce +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_compare.html|20010305004146|08946|d888d1ebe056bc6b +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_minkey.html|20010305004146|09837|d6181e52342005c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_bt_prefix.html|20010305004146|11627|ecd8f927371a5dbd +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_cachesize.html|20010305004146|12541|3befdbaf98d5a04e +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_dup_compare.html|20010305004146|13472|91f36955a213e0f4 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errcall.html|20010305004146|10727|28a7a1fa2b3b73ee +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errfile.html|20010305004145|11465|f6eddb9ab7ef07d0 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_errpfx.html|20010305004146|14381|1f26e7b0bb5a067f +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_feedback.html|20010305004146|15263|a08620d86f05ec8c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_flags.html|20010305004146|16174|1146625feeb3bb0b +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_ffactor.html|20010305004146|17155|a67084c644c38114 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_hash.html|20010305004146|18078|afe952f65389d93b +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_h_nelem.html|20010305004146|19017|1829bc583d9c7554 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_lorder.html|20010305004146|19980|a46750a29588268c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_malloc.html|20010305004145|12423|b0aa5802da5bef4d +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_pagesize.html|20010305004146|20914|b8d544ec3e102c6c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_paniccall.html|20010305004145|13411|6bc911c9d64e9237 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_q_extentsize.html|20010305004146|21826|b17e340a68ede3ac +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_delim.html|20010305004146|22753|81d9df93c3511df3 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_len.html|20010305004146|23672|e09bb30e40208dfb +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_pad.html|20010305004146|24627|f2e0c2c2c3806a97 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_re_source.html|20010305004146|25550|46998978715ccc1 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_realloc.html|20010305004145|14370|64d967a58c328957 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_stat.html|20010305004146|26537|3473827de856d680 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_sync.html|20010305004146|27538|dadf1f745e44faa7 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_upgrade.html|20010305004146|28493|c6231eb2f9989284 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_verify.html|20010305004146|29479|14db455da528229d +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_class.html|20010305004145|15353|2a31b398c37d674b tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_close.html|20010305004146|30462|2adba79b482ee157 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_count.html|20010305004146|31395|bc025b8894450525 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_del.html|20010305004146|32671|424fc0ebb3b4c5cf +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_dup.html|20010305004146|33708|75df863b4bc13aaa +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_get.html|20010305004146|34739|36e2dbe65e3442e3 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_put.html|20010305004146|35761|11e6aa2492dd1032 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbenv_class.html|20010305004145|16297|5ab8aaf8a531f76b +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbt_class.html|20010305004145|17281|fb91648586c1aa77 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_close.html|20010305004146|36778|5cc705b97b86972c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_open.html|20010305004146|37756|66ac1ae7fa67ca4a +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_remove.html|20010305004146|38809|5efece7ecdfc4df7 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_cachesize.html|20010305004146|39807|b82ed49a47415fec +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_data_dir.html|20010305004146|40779|9176f081597e4f27 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errcall.html|20010305004146|41745|bae25b45b0196773 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errfile.html|20010305004145|18322|f9543c9e65ed6a1d +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_error_stream.html|20010305004145|19317|a4101c1d68559fa2 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_errpfx.html|20010305004146|42728|d26da4bab9538234 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_feedback.html|20010305004146|43755|1d5bd8dfe2d8034e +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_flags.html|20010305004146|44734|8136e8e1ae16dc02 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_bsize.html|20010305004146|45706|7fd917bea6b163bf +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_dir.html|20010305004146|46674|c08aac264e7faa97 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lg_max.html|20010305004146|47638|4f7ba5f02c66c0de +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_conflicts.html|20010305004146|48615|5bba88df4cc6dfba +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_detect.html|20010305004146|49591|13e53300b722cf1e +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max.html|20010305004146|50580|52ac3c4ca2876de +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_lockers.html|20010305004146|52578|ebb61fd669c2eefb +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_locks.html|20010305004146|51576|bbde4ffbcc607f61 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_lk_max_objects.html|20010305004146|53572|c47424e4d13d5327 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mp_mmapsize.html|20010305004146|54573|c21e3f9c5a29b0ab +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mutexlocks.html|20010305004146|55575|f73e7ffdd2d8d62f +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_pageyield.html|20010305004146|56583|db4e5bdf71e171c0 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_paniccall.html|20010305004145|20292|2080056f15faa516 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_panicstate.html|20010305004146|57577|ad2d38e398cafd31 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_rec_init.html|20010305004146|58586|77916e00d1361c7b +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_region_init.html|20010305004146|59589|2d70678382bbbf9a +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_server.html|20010305004146|60631|bb74806839e8eb58 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_shm_key.html|20010305004146|62685|65b2c2f848ddf31e tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tas_spins.html|20010305004146|64671|a107049f4776b358 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tmp_dir.html|20010305004146|00169|6c815da1fad27537 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_max.html|20010305004146|01212|910d1c17dd000729 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_recover.html|20010305004146|02235|cdf13797131b2d97 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tx_timestamp.html|20010305004146|03286|6396a1145f8e41c1 tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_verbose.html|20010305004146|04365|e804a65368b5cdc1 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_strerror.html|20010305004146|05414|7e1cbfbd096ca +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_version.html|20010305004146|06444|1cff25c44cbea934 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/except_class.html|20010305004145|21277|59839667e43592e +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/get_errno.html|20010305004145|22249|e1a57c1c5f1d2695 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_class.html|20010305004145|23233|ed88ab78cccbef8d +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_detect.html|20010305004146|07495|bb50519c431233ed +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_get.html|20010305004146|61648|527d63a8526f336c +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_id.html|20010305004146|08539|b3c7995efbe12c16 tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_put.html|20010305004146|09587|9eb85a1c9e88621 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_stat.html|20010305004146|10635|2112ceb0894b34d8 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_vec.html|20010305004146|11739|c55deaa5173a3323 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_archive.html|20010305004146|12836|d47f39e6dad7ee50 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_compare.html|20010305004146|13902|3225b4c32016c9b1 tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_file.html|20010305004146|14965|9a724b41d84e0c31 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_flush.html|20010305004146|16027|3976f77e905f35eb +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_get.html|20010305004146|17104|aee6162219c71617 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_put.html|20010305004146|18207|66077da9630fa8c2 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_register.html|20010305004146|19292|55470e0d79382beb +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_stat.html|20010305004146|20379|dc2d4ffe7950fc09 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_unregister.html|20010305004146|21535|8fa1fe691751d6ad +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lsn_class.html|20010305004145|24210|34809f73e15540ad +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fclose.html|20010305004146|22608|cc4a5776ac69d660 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fget.html|20010305004146|23710|bfe74f8c299c2995 tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fopen.html|20010305004146|24842|abfef0a4db99c8e1 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fput.html|20010305004146|26004|7ee8cda6287dee81 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fset.html|20010305004146|27124|e52fa0488faa893 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fsync.html|20010305004146|28227|76d47da7c5dc8932 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_register.html|20010305004146|29358|cba6f572fe27c7a +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_stat.html|20010305004146|31867|d370717a78971be1 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_sync.html|20010305004146|33235|253961279934d3c8 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_trickle.html|20010305004146|34409|c9df8540b9ebc898 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/mempfile_class.html|20010305004145|25191|672b4aa787b4aeca +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/pindex.src|20010305004145|09392|d65361c4acfcef06 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_abort.html|20010305004147|01091|81177bcb2e5f4502 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_begin.html|20010305004147|02053|3a2d1488ec9d8655 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_checkpoint.html|20010305004147|02999|173930473e76d008 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_class.html|20010305004145|26179|5e57abe095aceca9 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_commit.html|20010305004147|03924|65afb8caf9c470ae +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_id.html|20010305004147|04873|162661f4c2dc09d6 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_prepare.html|20010305004147|05797|818b4163518bace5 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/txn_stat.html|20010305004147|06751|e8e25f86f8541696 +tim@threads.polyesthetic.msg|bdb/docs/api_cxx/what.html|20010305004145|27185|a64f42c697273c44 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_class.html|20010305004147|09609|b957a4d2b77acb1e +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_close.html|20010305004147|24101|21595167f4fdbe88 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_cursor.html|20010305004147|25020|2181d652bd1c1ff +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_del.html|20010305004147|25922|f4f15b362b114506 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_fd.html|20010305004147|26830|1f70020c37023baa +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get.html|20010305004147|27733|87b8316c55b24739 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_byteswapped.html|20010305004147|28706|edbc66a9d5491a1 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_get_type.html|20010305004147|29592|4cfb6f09cbe0b8ae +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_join.html|20010305004147|30506|a3a6dead9cae65f9 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_key_range.html|20010305004147|31461|8834de5873a6acb5 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_open.html|20010305004147|32409|bfc13736b96ac509 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_put.html|20010305004147|33389|c476abe5599f21cf +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_remove.html|20010305004147|34343|49d3b8c7e5a5b000 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_rename.html|20010305004147|35341|19b20feaa815bc27 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_append_recno.html|20010305004147|36282|d28bf857803b93a2 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_compare.html|20010305004147|37206|e972f964d042b35e +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_minkey.html|20010305004147|38144|c7e1f184bdca25fa +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_bt_prefix.html|20010305004147|39088|a3269aad23e6dbc +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_cachesize.html|20010305004147|40035|22d172a2d29f276b +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_dup_compare.html|20010305004147|40992|3dabd840a1d9e5f3 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_errcall.html|20010305004147|41930|4e4743f5b4277199 tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_errpfx.html|20010305004147|42881|c446da51277796df +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_feedback.html|20010305004147|45141|69b4c07b3dbe383 tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_flags.html|20010305004147|46212|b6b9d271bd42a94e +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_ffactor.html|20010305004147|47226|edcc10024104d57e +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_hash.html|20010305004147|48174|c6eb825c706a9548 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_h_nelem.html|20010305004147|49144|fc6f22a4c285fcef +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_lorder.html|20010305004147|50103|f64cbdd62bbbdd7c +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_pagesize.html|20010305004147|51079|d899ea90b20b7b31 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_q_extentsize.html|20010305004147|52035|6ac26239fc538cb +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_delim.html|20010305004147|53019|78fcf2d750fb26ef +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_len.html|20010305004147|53997|8448826ea78c630e +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_pad.html|20010305004147|54985|2729c192747ac7af +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_source.html|20010305004147|55969|b29827dbf47537d1 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_stat.html|20010305004147|57008|bc253f0883e9c82b +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_sync.html|20010305004147|58064|42391f7d5f200b90 tim@threads.polyesthetic.msg|bdb/docs/api_java/db_upgrade.html|20010305004147|59076|782fa4cc6c633990 +tim@threads.polyesthetic.msg|bdb/docs/api_java/db_verify.html|20010305004147|60082|20873ab17f6ed922 +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_class.html|20010305004147|11473|8ee03c40ae0dbcb8 +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_close.html|20010305004147|61116|e3bf1f36bc0e8e7e +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_count.html|20010305004147|62108|9c239575f4550756 +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_del.html|20010305004147|63111|6ec2b8a4b8dde996 +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_dup.html|20010305004147|64103|aa141014c4d7f9b0 +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_get.html|20010305004147|65144|e66e387b83681e73 +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbc_put.html|20010305004147|00700|da0f0fa974385abd +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbenv_class.html|20010305004147|12326|92c7a4a6c22090c7 +tim@threads.polyesthetic.msg|bdb/docs/api_java/dbt_class.html|20010305004147|13192|f6b04ff142e332f8 tim@threads.polyesthetic.msg|bdb/docs/api_java/deadlock_class.html|20010305004147|14282|b587b2d8c9e5d0b0 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_close.html|20010305004147|01809|c4e2ec77d7d14d4f +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_open.html|20010305004147|02873|2df0f0ef544da715 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_remove.html|20010305004147|04039|e92277e3dfd9bba1 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_cachesize.html|20010305004147|05132|f3700cd19856f14e +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_data_dir.html|20010305004147|06162|b7b3f35e96804650 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errcall.html|20010305004147|07189|4e206d08cbb39ab7 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_error_stream.html|20010305004147|15677|a738119910b452b8 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errpfx.html|20010305004147|08227|a3b9a09670f6912 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_feedback.html|20010305004147|09255|9748745e65f070d5 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_flags.html|20010305004147|10283|690847bb5e205c21 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_bsize.html|20010305004147|11335|6c67beed877df84c +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_dir.html|20010305004147|12366|484cad2123994e14 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lg_max.html|20010305004147|13429|c9f705492162e175 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_conflicts.html|20010305004147|14497|8951eb975a90918b +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_detect.html|20010305004147|15549|9fc15a1a95b0dfa1 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max.html|20010305004147|16607|12b6e34ac5a53281 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_lockers.html|20010305004147|18755|7896265ea77829b3 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_locks.html|20010305004147|17677|f0114205b169de39 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_lk_max_objects.html|20010305004147|19812|d1ed194631ffeb2a +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mp_mmapsize.html|20010305004147|20894|b7dea9108fa65dfa +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_mutexlocks.html|20010305004147|21961|aad8e4a059075bb6 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_pageyield.html|20010305004147|23054|774b3da0306a6767 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_panicstate.html|20010305004147|24142|72846d9a97cb80bb +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_rec_init.html|20010305004147|25237|1fdb2c5fc3b6407 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_region_init.html|20010305004147|26379|30534afa94cbf54e +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_server.html|20010305004147|27545|d901cdab9698605d +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_shm_key.html|20010305004147|28699|8c576698882f0edc +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tas_spins.html|20010305004147|30425|2f9963827fbcb3f +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tmp_dir.html|20010305004147|32251|f23e4f614f6d975a +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_max.html|20010305004147|33999|70f356b8b67782fe +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_recover.html|20010305004148|00983|40280da113fc9d2b +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_tx_timestamp.html|20010305004148|02804|457eeb135f1f8bc0 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_verbose.html|20010305004148|03690|9dcda0399c8256e7 +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_strerror.html|20010305004148|04588|fceebaa94cf9aafd +tim@threads.polyesthetic.msg|bdb/docs/api_java/env_version.html|20010305004148|05599|854d26806930cab6 +tim@threads.polyesthetic.msg|bdb/docs/api_java/except_class.html|20010305004147|16978|195c00e4a7cbe648 tim@threads.polyesthetic.msg|bdb/docs/api_java/get_errno.html|20010305004147|17836|89a89f8efe3a9360 +tim@threads.polyesthetic.msg|bdb/docs/api_java/java_index.html|20010305004147|18736|8ecfcef4a702011d tim@threads.polyesthetic.msg|bdb/docs/api_java/java_pindex.html|20010305004148|35859|f8bc0811d8eda8e9 +tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_class.html|20010305004147|19738|880aa614d1469304 +tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_detect.html|20010305004148|06490|14d4e7c7dca0dad7 tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_get.html|20010305004148|07401|fd52de261831f9b5 +tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_id.html|20010305004148|08326|737cf8d8dc74084e +tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_put.html|20010305004148|09226|5af89e4cbf29c694 +tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_stat.html|20010305004148|10140|71b81d8567befc43 tim@threads.polyesthetic.msg|bdb/docs/api_java/lock_vec.html|20010305004148|11077|df5eb838fdbe1eab +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_archive.html|20010305004148|11996|b4a9483dbb5a2b58 +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_compare.html|20010305004148|12947|756622b42572ecb +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_file.html|20010305004148|13857|74a49bae2532199a +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_flush.html|20010305004148|14794|1691d6a3c8cc284e +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_get.html|20010305004148|15736|5fbbbd4baa60e052 +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_put.html|20010305004148|16729|ad7e9f382abde491 +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_register.html|20010305004148|17668|c68fc6fb22dd594a +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_stat.html|20010305004148|18608|d186a08662046aba +tim@threads.polyesthetic.msg|bdb/docs/api_java/log_unregister.html|20010305004148|19590|eee284e0da176d0a +tim@threads.polyesthetic.msg|bdb/docs/api_java/lsn_class.html|20010305004147|20619|b1458208b6c81016 +tim@threads.polyesthetic.msg|bdb/docs/api_java/mem_class.html|20010305004147|21486|2e5052b5b2bea584 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fclose.html|20010305004148|20518|d08f0c134361f802 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fget.html|20010305004148|21431|ca84dee01997eb89 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fopen.html|20010305004148|22355|f7cf58725aa1c406 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fput.html|20010305004148|23268|6ba75e517a259703 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fset.html|20010305004148|24178|5c5371a93b83275 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fsync.html|20010305004148|25118|e767b233fe7730a2 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_register.html|20010305004148|26052|8331390a1c66fefd +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_stat.html|20010305004148|27008|4628462474db62b4 +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_sync.html|20010305004148|27969|5b401daadc7261eb +tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_trickle.html|20010305004148|28912|4d5c4e83a4a5c638 +tim@threads.polyesthetic.msg|bdb/docs/api_java/pindex.src|20010305004147|10521|de828917f041d27b +tim@threads.polyesthetic.msg|bdb/docs/api_java/runrec_class.html|20010305004147|22358|49c5cb3efe0c201 +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_abort.html|20010305004148|29858|ec9a3517748bfa3 +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_begin.html|20010305004148|30859|553bf78bd7fc3e0a +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_checkpoint.html|20010305004148|31832|2565ac892d04b63d +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_class.html|20010305004147|23221|c7bb2a3393ca9488 +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_commit.html|20010305004148|32812|c265042f3340baa1 +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_id.html|20010305004148|01920|798720b73cc9391 +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_prepare.html|20010305004148|33784|510a245c80e715c +tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_stat.html|20010305004148|34772|9a6ef8c262f218f9 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_close.html|20010305004148|38213|f40794b17e0fe443 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_count.html|20010305004148|40010|4812f3756a75437 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_cursor.html|20010305004148|40924|e035b3c11a91c5d6 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_del.html|20010305004148|41829|400c7a72fb10d6f4 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get.html|20010305004148|42753|127bd361ee695c71 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_join.html|20010305004148|43762|1c737805c2c49cf9 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_get_type.html|20010305004148|44686|7202f3ca793e6ec3 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_is_byteswapped.html|20010305004148|45596|8fb9e2c58051c769 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_join.html|20010305004148|46525|cb3eb61ed17a1f8 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_open.html|20010305004148|47486|f588cc9bc694cbf0 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_put.html|20010305004148|48549|380c7caeced55512 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_remove.html|20010305004148|50431|3b2be4b0b1b3dc98 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_rename.html|20010305004148|49486|909bc643d5455b54 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_stat.html|20010305004148|51363|3bb57be2de907fd2 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/db_sync.html|20010305004148|52310|3b615ca64d934602 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_close.html|20010305004148|53244|ef431e58d72accc3 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_del.html|20010305004148|54185|7e94f9f01e7e4453 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_dup.html|20010305004148|55139|325121689412d70b +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_get.html|20010305004148|56098|5bbb80cf51aff594 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_put.html|20010305004148|57122|290ecb1275d4270 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_close.html|20010305004148|58109|bf191b2673a2b19e +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_open.html|20010305004148|59088|39b63925d45a637e +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/env_remove.html|20010305004148|60117|9090900413ff0280 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/pindex.src|20010305004148|39123|f8754fff24f2cb24 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_index.html|20010305004148|61088|443e6b9a10ef4139 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/tcl_pindex.html|20010305004148|00553|259f0e062eee63c7 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn.html|20010305004148|62085|8e345950e6029230 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_abort.html|20010305004148|63068|8cc23b6ef6f457d2 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/txn_commit.html|20010305004148|64051|25150b20b84cd519 +tim@threads.polyesthetic.msg|bdb/docs/api_tcl/version.html|20010305004148|65038|eeb51f4de1bbfe8e +tim@threads.polyesthetic.msg|bdb/docs/images/api.gif|20010305004148|02578|dec2d4fe5f39dffe +tim@threads.polyesthetic.msg|bdb/docs/images/next.gif|20010305004148|03600|ddab96466674135b +tim@threads.polyesthetic.msg|bdb/docs/images/prev.gif|20010305004148|04639|9448d24755d708a0 +tim@threads.polyesthetic.msg|bdb/docs/images/ps.gif|20010305004148|05648|f6b1b372cb2cda4c +tim@threads.polyesthetic.msg|bdb/docs/images/ref.gif|20010305004148|06650|add30c753dc1972d +tim@threads.polyesthetic.msg|bdb/docs/images/sleepycat.gif|20010305004148|07668|ea63aaaa508ef096 +tim@threads.polyesthetic.msg|bdb/docs/index.html|20010305004143|26935|450dd5db21a9bb64 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/close.html|20010305004148|10227|ed6f7427edc0431 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/count.html|20010305004148|11236|8fd8daf2e2cbd7c7 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/curclose.html|20010305004148|12231|8b6b8442fc8382f7 tim@threads.polyesthetic.msg|bdb/docs/ref/am/curdel.html|20010305004148|13236|39bf0a8cba99c064 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/curdup.html|20010305004148|14243|5c855e1f5b99d990 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/curget.html|20010305004148|15271|d7dd42affcd54073 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/curput.html|20010305004148|16324|c7e4fa0a68170c3d +tim@threads.polyesthetic.msg|bdb/docs/ref/am/cursor.html|20010305004148|17350|6dbcdb3b7d552f58 tim@threads.polyesthetic.msg|bdb/docs/ref/am/delete.html|20010305004148|18364|9195664374690b24 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/error.html|20010305004148|19390|45ac854e68196844 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/get.html|20010305004148|20425|96c9c9a01c32d16 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/join.html|20010305004148|22331|acc16686a78a732 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/open.html|20010305004148|23468|c9a7e23579a5e93a tim@threads.polyesthetic.msg|bdb/docs/ref/am/opensub.html|20010305004148|24500|81c79cce793fb343 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/ops.html|20010305004148|25566|9b24db9ba4f45724 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/partial.html|20010305004148|26629|db4a970c839b3051 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/put.html|20010305004148|28752|8e18b0af61eb7f0f tim@threads.polyesthetic.msg|bdb/docs/ref/am/stability.html|20010305004148|30129|a92faac934d69cef +tim@threads.polyesthetic.msg|bdb/docs/ref/am/stat.html|20010305004148|32050|fafc0f88571d9395 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/sync.html|20010305004148|33751|381722c07c9d8825 +tim@threads.polyesthetic.msg|bdb/docs/ref/am/upgrade.html|20010305004149|00532|c7499736f03c1a1c +tim@threads.polyesthetic.msg|bdb/docs/ref/am/verify.html|20010305004149|01382|badaeba91bda50e1 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_compare.html|20010305004149|18156|c1e847e651704c89 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_minkey.html|20010305004149|19013|b4708e561be92b83 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_prefix.html|20010305004149|19903|4e7602aa68d50fe1 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/bt_recnum.html|20010305004149|20770|f081f10254e86e75 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/byteorder.html|20010305004149|21617|999a22f727e2dae0 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/cachesize.html|20010305004149|22486|99dcd466dc881093 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/dup.html|20010305004149|23371|523731632fca7343 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/extentsize.html|20010305004149|24263|fdcfb5572974545c +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_ffactor.html|20010305004149|25120|5eb87b7ce99f3362 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_hash.html|20010305004149|25978|3a0174586fbcfcdf +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/h_nelem.html|20010305004149|26871|979995db477052ad +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/intro.html|20010305004149|27745|dd1647202258ee28 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/logrec.html|20010305004149|28646|5edeb34d63936e2 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/malloc.html|20010305004149|29537|cb0e6d7e9448d93e +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/pagesize.html|20010305004149|30437|eb4800704ae1131b +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/re_source.html|20010305004149|31346|b000d11ca4a0f9a +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/recno.html|20010305004149|32283|c2ae722138309e95 +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/renumber.html|20010305004149|33199|b7df79bf32240b5c +tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/select.html|20010305004149|34120|57b1c99f6a8ea93f +tim@threads.polyesthetic.msg|bdb/docs/ref/arch/apis.html|20010305004149|36488|a84570e410b11a6a +tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.gif|20010305004149|41251|fe43e7415b3bbdb0 +tim@threads.polyesthetic.msg|bdb/docs/ref/arch/bigpic.html|20010305004149|37519|ab5254bc99af0d5c +tim@threads.polyesthetic.msg|bdb/docs/ref/arch/progmodel.html|20010305004149|38491|caa422dc155b6370 +tim@threads.polyesthetic.msg|bdb/docs/ref/arch/script.html|20010305004149|39400|6796fd0a63161a0c +tim@threads.polyesthetic.msg|bdb/docs/ref/arch/smallpic.gif|20010305004149|42169|fdf77055d7e711 +tim@threads.polyesthetic.msg|bdb/docs/ref/arch/utilities.html|20010305004149|40326|54d7014fab332c7a +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/aix.html|20010305004149|44137|e8ae448bdb85fa22 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/conf.html|20010305004149|45053|d0378c69618b790b +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/flags.html|20010305004149|46003|a739404f90eb8c3d +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/freebsd.html|20010305004149|46918|8ed2a42e1668004c +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/hpux.html|20010305004149|47818|d34942564699608 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/install.html|20010305004149|48752|660222dd1feffc4 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/intro.html|20010305004149|49652|f261022c26987d7f +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/irix.html|20010305004149|50564|95833aedc3a82f0 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/linux.html|20010305004149|51464|f9f2d09dc6df75e +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/notes.html|20010305004149|52391|97e9b52853db15ea +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/osf1.html|20010305004149|53358|9d4ebabfe3af8970 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/qnx.html|20010305004149|54263|6d2849a8e8038dc9 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sco.html|20010305004149|55174|e25f6271a1b753d0 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/shlib.html|20010305004149|56099|7168ed40f2e1155d tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/solaris.html|20010305004149|57063|3a85fb541538d0d7 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/sunos.html|20010305004149|58008|fc41965e9d95985c tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/test.html|20010305004149|58940|b2c2f275a0c3e783 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/ultrix.html|20010305004149|59865|a1dd780edcde11f6 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/faq.html|20010305004149|61835|cdb7646d3d2e6374 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/intro.html|20010305004149|62808|2eed15d25078711 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/notes.html|20010305004149|63758|7e53a042c5c4d350 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/faq.html|20010305004149|65331|34704a907168cea7 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/intro.html|20010305004149|00770|2975a07b53b12046 +tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/notes.html|20010305004149|01764|4058bf968f287f7 tim@threads.polyesthetic.msg|bdb/docs/ref/build_win/test.html|20010305004149|02729|84090b57cb7f0cf8 +tim@threads.polyesthetic.msg|bdb/docs/ref/cam/intro.html|20010305004149|04558|4c497b1a18c4c7f5 +tim@threads.polyesthetic.msg|bdb/docs/ref/debug/common.html|20010305004149|07598|607061232e2532df +tim@threads.polyesthetic.msg|bdb/docs/ref/debug/compile.html|20010305004149|08609|12785e3091b78bfd +tim@threads.polyesthetic.msg|bdb/docs/ref/debug/intro.html|20010305004149|06616|57ef29f26341ea +tim@threads.polyesthetic.msg|bdb/docs/ref/debug/printlog.html|20010305004149|09591|9fa9894f839fad95 +tim@threads.polyesthetic.msg|bdb/docs/ref/debug/runtime.html|20010305004149|10629|d50f2fea4a8e58c +tim@threads.polyesthetic.msg|bdb/docs/ref/distrib/layout.html|20010305004149|12589|5aeb292fbd987cf8 +tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/format.html|20010305004149|13995|9fa10ca3c7ae6751 +tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/text.html|20010305004149|14998|88b57a73860b423 +tim@threads.polyesthetic.msg|bdb/docs/ref/dumpload/utility.html|20010305004149|15969|8fc100fdb58adb3c +tim@threads.polyesthetic.msg|bdb/docs/ref/env/create.html|20010305004149|17402|9f454cb1910df0b8 +tim@threads.polyesthetic.msg|bdb/docs/ref/env/error.html|20010305004149|18447|acbbdb848c9fe70f +tim@threads.polyesthetic.msg|bdb/docs/ref/env/intro.html|20010305004149|19435|96dd1090729e06b +tim@threads.polyesthetic.msg|bdb/docs/ref/env/naming.html|20010305004149|20447|1f041789686cc8a0 tim@threads.polyesthetic.msg|bdb/docs/ref/env/open.html|20010305004149|21520|37a6e67d520d6c00 +tim@threads.polyesthetic.msg|bdb/docs/ref/env/region.html|20010305004149|22506|cc94139c8daa7f6a +tim@threads.polyesthetic.msg|bdb/docs/ref/env/remote.html|20010305004149|23518|52a3a79fdff8f7bd +tim@threads.polyesthetic.msg|bdb/docs/ref/env/security.html|20010305004149|24507|e455f95aee7f5cd2 +tim@threads.polyesthetic.msg|bdb/docs/ref/install/file.html|20010305004150|21159|d4ba2317db7c064b +tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.be.txt|20010305004150|22805|cf7d25e758432ab6 +tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.s5.le.txt|20010305004150|23615|528ef76418c8b45c +tim@threads.polyesthetic.msg|bdb/docs/ref/install/magic.txt|20010305004150|21985|3894a46ea11ce25a +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/data.html|20010305004149|26092|33fbf7496c58cf63 +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbis.html|20010305004149|28303|e672b7615d70be2c +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbisnot.html|20010305004149|29466|5ce7aed7ce41c9e6 +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/distrib.html|20010305004149|30742|84b56709310017f2 +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/need.html|20010305004149|31743|43950806e35d71f +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/products.html|20010305004149|32785|f37221772a3b589d +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/terrain.html|20010305004149|33850|b396d6447a59435f +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/what.html|20010305004150|00539|dd70b9e6e085725d +tim@threads.polyesthetic.msg|bdb/docs/ref/intro/where.html|20010305004150|01442|6cb9ec27f19ecbbb +tim@threads.polyesthetic.msg|bdb/docs/ref/java/compat.html|20010305004150|25581|b39d173789bbf70d +tim@threads.polyesthetic.msg|bdb/docs/ref/java/conf.html|20010305004150|26401|ef560bcf13a71cd5 +tim@threads.polyesthetic.msg|bdb/docs/ref/java/faq.html|20010305004150|27218|7ca2474ba1f6676f +tim@threads.polyesthetic.msg|bdb/docs/ref/java/program.html|20010305004150|28026|e9bbc08bccf5d396 +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/am_conv.html|20010305004150|30986|3bab32d969f21b77 +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/cam_conv.html|20010305004150|31862|63844ff6fa95f0c +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/config.html|20010305004150|32692|a593ea4c87467ddd +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/dead.html|20010305004150|33535|f5c7debd9ba739bb +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/intro.html|20010305004150|34434|e1e07e71f3198be +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/max.html|20010305004150|35299|f0fb32ebc251f636 +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/nondb.html|20010305004150|36156|863fe076a46378d7 +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/notxn.html|20010305004150|37003|beec805d9f05e2bc +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/page.html|20010305004150|37863|d56876b2565cbee +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/stdmode.html|20010305004150|38797|4048a052ea129ca3 +tim@threads.polyesthetic.msg|bdb/docs/ref/lock/twopl.html|20010305004150|39650|b3f3aee667bc381d +tim@threads.polyesthetic.msg|bdb/docs/ref/log/config.html|20010305004150|41449|aedc53caf49c51c9 +tim@threads.polyesthetic.msg|bdb/docs/ref/log/intro.html|20010305004150|42339|31e7055d83ca8757 +tim@threads.polyesthetic.msg|bdb/docs/ref/log/limits.html|20010305004150|43198|26fac1e32387b7c9 +tim@threads.polyesthetic.msg|bdb/docs/ref/mp/config.html|20010305004150|46018|771c2c91fc0b6b17 +tim@threads.polyesthetic.msg|bdb/docs/ref/mp/intro.html|20010305004150|45138|34937731cafcf1b1 +tim@threads.polyesthetic.msg|bdb/docs/ref/perl/intro.html|20010305004150|47570|ce7e794e619e1e1d +tim@threads.polyesthetic.msg|bdb/docs/ref/pindex.src|20010305004149|02223|7d74723f9fd25801 tim@threads.polyesthetic.msg|bdb/docs/ref/program/appsignals.html|20010305004150|48930|3ab63bf9399d7ead tim@threads.polyesthetic.msg|bdb/docs/ref/program/byteorder.html|20010305004150|49835|f7fa52b53e4c8838 tim@threads.polyesthetic.msg|bdb/docs/ref/program/compatible.html|20010305004150|50729|237b98e6a6d7ed35 -tim@threads.polyesthetic.msg|bdb/docs/ref/program/extending.html|20010305004150|56407|6a86a40872d6b8bc -tim@threads.polyesthetic.msg|bdb/docs/ref/program/runtime.html|20010305004150|61233|6853fdbfe15df788 -tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.html|20010305004150|00758|bad2247b4f8c582b -tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/client.html|20010305004150|12568|824178f8626e45b7 -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/del.html|20010305004150|19030|514a1bd568ed4c1d -tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/get.html|20010305004150|20970|211de230d6a6cbc5 -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/env_open.html|20010305004151|47233|c8d61102658c3bbf -tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/filesys.html|20010305004151|48077|ebee24f726f99bf6 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/intro.html|20010305004151|16219|7ecd16967b0bc868 -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_put.html|20010305004151|21664|fd9ed0b04b465af -tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/rmw.html|20010305004151|28431|992b0143d13a3ec0 -tim@threads.polyesthetic.msg|bdb/docs/utility/db_stat.html|20010305004152|13652|9582c327964e1f9 -tim@threads.polyesthetic.msg|bdb/include/btree_auto.h|20010305004137|17274|84d4451c78faf67e -BK|sql/share/polish/errmsg.sys|19700101030959|01857|126b03af92054f0f -BK|strings/Attic/ct_init.c|19700101030959|01338|f0948bdd35ceedc3 -BK|strings/Attic/ctype.c.in|19700101030959|01361|8bf48d4bcbc5f675 -BK|vio/Vio.h|19700101030959|00004|f4416b2949647602 -BK|vio/VioSSL.h|19700101030959|00014|70d367b7ec8cac3e -BK|vio/violite.h|19700101030959|00023|58d2942a52ea7a83 -miguel@hegel.local|zlib/contrib/asm586/readme.586|20020319032514|57815|f60bfeefb27217d -miguel@hegel.local|zlib/contrib/delphi/zlibdef.pas|20020319032514|18918|658cb04db561e3db -miguel@hegel.local|zlib/contrib/delphi2/d_zlib.bpr|20020319032514|25335|c267d77cc2e2a2c8 -miguel@hegel.local|zlib/contrib/minizip/zip.h|20020319032516|40925|17fd39ccb4ea294c -miguel@hegel.local|zlib/gzio.c|20020319032517|27098|e02d23e656c19359 -monty@donna.mysql.com|sql-bench/Results/select-pg-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817132749|23395|8ef771713f89e1 -monty@narttu.mysql.com|sql-bench/Results/alter-table-mysql-Linux_2.2.14_my_SMP_i686-cmp-mysql,pg|20000817171625|11725|dfc480becae45236 -monty@narttu.mysql.fi|sql-bench/Results/ATIS-mysql-Linux_2.2.14_my_SMP_i686|20001218015322|06287|d275df58a04737c8 -mwagner@evoq.home.mwagner.org|Docs/Books/algor.eps|20001231203219|20480|481984607c98d715 -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000011.xml|20001017133713|00331|432156d127cbd22f -mwagner@evoq.home.mwagner.org|mysql-test/xml/tests/sel000015.xml|20001017133749|30814|b72689a8f9b21372 -mwagner@evoq.home.mwagner.org|mysql-test/xml/xsl/mysqltest.xsl|20001013051514|27425|1b8f6ec4f1b5f634 -sasha@mysql.sashanet.com|mysql-test/t/df_crash.test|20010406010433|65180|4c365178fe437f6 -serg@serg.mysql.com|mysql-test/t/sel000008.test|20001211130730|28581|b338ef585cadf7ae -serg@serg.mysql.com|mysql-test/t/sel000012.test|20001211130731|13215|ae64bff363c42e92 -serg@serg.mysql.com|mysql-test/t/sel000027.test|20001211130731|23677|ab44bb57a580de9 -tim@threads.polyesthetic.msg|bdb/db/crdel_auto.c|20010305004136|27298|ee4146a08fd175c1 -tim@threads.polyesthetic.msg|bdb/dist/config.hin|20010305004136|15955|fdecb7a06fa137a7 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_join.html|20010305004144|32446|a58c2d81ecfea5b -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_h_ffactor.html|20010305004144|08766|41352ddf74ccc338 -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_lorder.html|20010305004144|11587|e24ae76325374653 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_lg_dir.html|20010305004145|05444|26be310214a2ff8f -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_region_init.html|20010305004145|31081|2ca19f76ee1ae790 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_set_shm_key.html|20010305004145|32880|cf5aaa6a995cbf55 -tim@threads.polyesthetic.msg|bdb/docs/api_c/env_version.html|20010305004145|40251|9bf7f99fefacc2bf -tim@threads.polyesthetic.msg|bdb/docs/api_c/log_get.html|20010305004145|50583|24cdf17ba55cbecf -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_open.html|20010305004146|04518|ab95c48ac26ad3f7 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_q_extentsize.html|20010305004146|21826|b17e340a68ede3ac -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/db_set_realloc.html|20010305004145|14370|64d967a58c328957 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_feedback.html|20010305004146|43755|1d5bd8dfe2d8034e -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_mutexlocks.html|20010305004146|55575|f73e7ffdd2d8d62f -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_shm_key.html|20010305004146|62685|65b2c2f848ddf31e -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/env_set_tmp_dir.html|20010305004146|00169|6c815da1fad27537 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_detect.html|20010305004146|07495|bb50519c431233ed -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fsync.html|20010305004146|28227|76d47da7c5dc8932 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_cachesize.html|20010305004147|40035|22d172a2d29f276b -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_lorder.html|20010305004147|50103|f64cbdd62bbbdd7c -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_pagesize.html|20010305004147|51079|d899ea90b20b7b31 -tim@threads.polyesthetic.msg|bdb/docs/api_java/db_set_re_pad.html|20010305004147|54985|2729c192747ac7af -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_errpfx.html|20010305004147|08227|a3b9a09670f6912 -tim@threads.polyesthetic.msg|bdb/docs/api_java/env_set_flags.html|20010305004147|10283|690847bb5e205c21 -tim@threads.polyesthetic.msg|bdb/docs/api_java/log_file.html|20010305004148|13857|74a49bae2532199a -tim@threads.polyesthetic.msg|bdb/docs/api_java/memp_fget.html|20010305004148|21431|ca84dee01997eb89 -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_abort.html|20010305004148|29858|ec9a3517748bfa3 -tim@threads.polyesthetic.msg|bdb/docs/api_java/txn_id.html|20010305004148|01920|798720b73cc9391 -tim@threads.polyesthetic.msg|bdb/docs/api_tcl/dbc_close.html|20010305004148|53244|ef431e58d72accc3 -tim@threads.polyesthetic.msg|bdb/docs/images/next.gif|20010305004148|03600|ddab96466674135b -tim@threads.polyesthetic.msg|bdb/docs/ref/am/curdup.html|20010305004148|14243|5c855e1f5b99d990 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/partial.html|20010305004148|26629|db4a970c839b3051 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/stat.html|20010305004148|32050|fafc0f88571d9395 -tim@threads.polyesthetic.msg|bdb/docs/ref/am/upgrade.html|20010305004149|00532|c7499736f03c1a1c -tim@threads.polyesthetic.msg|bdb/docs/ref/am_conf/re_source.html|20010305004149|31346|b000d11ca4a0f9a -tim@threads.polyesthetic.msg|bdb/docs/ref/build_unix/shlib.html|20010305004149|56099|7168ed40f2e1155d -tim@threads.polyesthetic.msg|bdb/docs/ref/build_vxworks/faq.html|20010305004149|61835|cdb7646d3d2e6374 -tim@threads.polyesthetic.msg|bdb/docs/ref/env/region.html|20010305004149|22506|cc94139c8daa7f6a -tim@threads.polyesthetic.msg|bdb/docs/ref/env/security.html|20010305004149|24507|e455f95aee7f5cd2 -tim@threads.polyesthetic.msg|bdb/docs/ref/intro/dbis.html|20010305004149|28303|e672b7615d70be2c tim@threads.polyesthetic.msg|bdb/docs/ref/program/copy.html|20010305004150|51641|bcf5ff9656fafcd3 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/dbsizes.html|20010305004150|52571|d70da530573b9b38 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/diskspace.html|20010305004150|53502|959508f155721ee8 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/environ.html|20010305004150|54494|dc4a48aa531bd399 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/errorret.html|20010305004150|55412|23491397d7e704e9 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/extending.html|20010305004150|56407|6a86a40872d6b8bc +tim@threads.polyesthetic.msg|bdb/docs/ref/program/mt.html|20010305004150|57429|552ab570b657fc0e +tim@threads.polyesthetic.msg|bdb/docs/ref/program/namespace.html|20010305004150|58394|182f8f762343bdc1 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/recimp.html|20010305004150|60288|bbdb0feb7d467a80 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/runtime.html|20010305004150|61233|6853fdbfe15df788 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/scope.html|20010305004150|59326|2987f97781410bc1 +tim@threads.polyesthetic.msg|bdb/docs/ref/program/solaris.txt|20010305004150|63135|8b6bb29de0d58ffe +tim@threads.polyesthetic.msg|bdb/docs/ref/program/version.html|20010305004150|62172|d266e819d1531df8 +tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.html|20010305004150|00758|bad2247b4f8c582b +tim@threads.polyesthetic.msg|bdb/docs/ref/refs/bdb_usenix.ps|20010305004150|02162|9851f6cdeff17481 +tim@threads.polyesthetic.msg|bdb/docs/ref/refs/embedded.html|20010305004150|03865|d25b9719d24df88c +tim@threads.polyesthetic.msg|bdb/docs/ref/refs/hash_usenix.ps|20010305004150|05408|11cad226b0aa012b tim@threads.polyesthetic.msg|bdb/docs/ref/refs/libtp_usenix.ps|20010305004150|08667|73329b041f7e8c41 +tim@threads.polyesthetic.msg|bdb/docs/ref/refs/refs.html|20010305004150|64422|30490b237ba9b61 +tim@threads.polyesthetic.msg|bdb/docs/ref/refs/witold.html|20010305004150|65330|ad6c866cf48734b5 +tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/client.html|20010305004150|12568|824178f8626e45b7 +tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/intro.html|20010305004150|13549|ad16bc20623e1192 +tim@threads.polyesthetic.msg|bdb/docs/ref/rpc/server.html|20010305004150|14510|79f560205494295 +tim@threads.polyesthetic.msg|bdb/docs/ref/sendmail/intro.html|20010305004150|16532|ecac45d7e2bcf51c +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/close.html|20010305004150|18046|1fe3a82f28e7ed32 +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/del.html|20010305004150|19030|514a1bd568ed4c1d +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/errors.html|20010305004150|19994|be11ff6410e1db2c +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/example.txt|20010305004150|28042|9ff88f22565208bf +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/get.html|20010305004150|20970|211de230d6a6cbc5 +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/handles.html|20010305004150|21935|18a14f4a50e7bad0 +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/intro.html|20010305004150|22878|7544c4688623a54c +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/keydata.html|20010305004150|23810|530b1581aeba63ca tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/open.html|20010305004150|24776|5d6eb5c3df68eeee +tim@threads.polyesthetic.msg|bdb/docs/ref/simple_tut/put.html|20010305004150|25774|bdd2629c212af471 +tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/error.html|20010305004151|21581|37b817c57777b460 +tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/faq.html|20010305004151|22367|f8433900f7f85400 +tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/intro.html|20010305004151|20749|d66c6c398e2ace0b +tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/program.html|20010305004151|23138|2f5bf497ae226ed5 +tim@threads.polyesthetic.msg|bdb/docs/ref/tcl/using.html|20010305004151|23908|28856d8c72d0660b +tim@threads.polyesthetic.msg|bdb/docs/ref/test/faq.html|20010305004151|38444|f95038006d18229 +tim@threads.polyesthetic.msg|bdb/docs/ref/test/run.html|20010305004151|39305|63c0398e7e2a29e2 +tim@threads.polyesthetic.msg|bdb/docs/ref/toc.html|20010305004148|08788|ab1fa294d5ef4b69 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/admin.html|20010305004151|41323|cf867ed0b00cccef +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/app.html|20010305004151|42111|6dc3c82982164fa8 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/archival.html|20010305004151|42978|7631314d840be181 tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/checkpoint.html|20010305004151|43948|29e077c954369ed tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/cursor.html|20010305004151|44775|824b2f28c9e8d610 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/data_open.html|20010305004151|45592|413c1d8aba9d8018 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/deadlock.html|20010305004151|46421|34914b9dc6b01703 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/env_open.html|20010305004151|47233|c8d61102658c3bbf +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/filesys.html|20010305004151|48077|ebee24f726f99bf6 tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/inc.html|20010305004151|48911|5ea32b4e2a2107b3 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/intro.html|20010305004151|49773|22096cea9fe159ac +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/logfile.html|20010305004151|50590|1c3002fcb6581e8c +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/put.html|20010305004151|51420|8cc785aeecff8535 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/read.html|20010305004151|52265|fc8b056380e09887 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/reclimit.html|20010305004151|53098|5f54174bf6026bd5 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/recovery.html|20010305004151|53956|6e3a0c07b997c3b2 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/term.html|20010305004151|54819|d6f3fa4fc5a630ec +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/throughput.html|20010305004151|55655|8a7d5a958df7f91a +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/transapp.txt|20010305004151|57368|337576ea2aae23b0 +tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/why.html|20010305004151|56525|c941c1a56a0adbaf tim@threads.polyesthetic.msg|bdb/docs/ref/transapp/writetest.txt|20010305004151|58289|4de1fc39894cd760 +tim@threads.polyesthetic.msg|bdb/docs/ref/txn/config.html|20010305004151|59874|c7337cb30f9bf66 tim@threads.polyesthetic.msg|bdb/docs/ref/txn/intro.html|20010305004151|60722|85fabd5518fb26be +tim@threads.polyesthetic.msg|bdb/docs/ref/txn/limits.html|20010305004151|61583|3004b7a93dab148b +tim@threads.polyesthetic.msg|bdb/docs/ref/txn/nested.html|20010305004151|62443|6860bbf2f29aa93b +tim@threads.polyesthetic.msg|bdb/docs/ref/txn/other.html|20010305004151|63311|4991722636b3a46d +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/convert.html|20010305004151|00512|d7f18eb34c1b6ae +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/disk.html|20010305004151|01410|94dc4e6e3668e613 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/intro.html|20010305004151|02261|8bfd3804a2da1598 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/system.html|20010305004151|03146|eae0256a127c3c89 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.2.0/toc.html|20010305004151|04069|670791f294a61494 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/close.html|20010305004151|05457|c79c866b393785cc +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/cxx.html|20010305004151|06323|7f3bfc9bba854d48 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db.html|20010305004151|07207|e7d63f4bb8e989e8 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/db_cxx.html|20010305004151|08078|5c17d6a360205140 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv.html|20010305004151|08972|f9863847dc1ed617 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbenv_cxx.html|20010305004151|09872|7f4fd0ebace36d8e +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/dbinfo.html|20010305004151|10780|7529af7145c0680a +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/disk.html|20010305004151|11685|eb79d1157ef44d3c tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/eacces.html|20010305004151|12569|f0299373d8b2f65c tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/eagain.html|20010305004151|13462|920800d8eb450f79 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/envopen.html|20010305004151|14369|5e768fd180f471e4 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/func.html|20010305004151|15332|c06e5bc63ddf7a64 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/intro.html|20010305004151|16219|7ecd16967b0bc868 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/java.html|20010305004151|17120|300acccbb633e335 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/join.html|20010305004151|18031|ec21d874caa0654 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/jump_set.html|20010305004151|18936|718c098a91db9dba +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_detect.html|20010305004151|19846|fb307b10156762ca +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_notheld.html|20010305004151|20761|ed6853b6daa5531b +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_put.html|20010305004151|21664|fd9ed0b04b465af +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/lock_stat.html|20010305004151|22568|c49716e693ce225b +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_register.html|20010305004151|23513|399320e965adf598 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/log_stat.html|20010305004151|24428|20b5898ba061557d +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/memp_stat.html|20010305004151|25363|79e1141c63f7357 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/open.html|20010305004151|27357|8b1e2a969e97069a +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/rmw.html|20010305004151|28431|992b0143d13a3ec0 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/stat.html|20010305004151|29377|775d75e3ba02d15c +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/toc.html|20010305004151|30301|16e7d8e76496cbc9 tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_begin.html|20010305004151|31307|53512180de5fec80 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_commit.html|20010305004151|32241|e1debf9ea769426c +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/txn_stat.html|20010305004151|33181|516f1870c6127351 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/value_set.html|20010305004151|34118|f0b0c770a81b90b6 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.0/xa.html|20010305004152|00602|1af042e462ab829 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/btstat.html|20010305004152|37584|40a76aef8b25a948 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/config.html|20010305004152|38401|d2ace28f39ab0f8d +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/disk.html|20010305004152|39192|2abdaf9059265ba9 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/dup.html|20010305004152|40004|911018877c118b45 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/env.html|20010305004152|40827|381e366a9c9c9a37 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/intro.html|20010305004152|41719|64592a50b1c634d6 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/log_register.html|20010305004152|42524|7177eeb2fc099317 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/logalloc.html|20010305004152|43372|30563c544b8ddd54 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/memp_register.html|20010305004152|44171|7d92464a1029d53e +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/put.html|20010305004152|44997|961a1a689be6ce +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_feedback.html|20010305004152|45815|6d7de50be92a5488 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_paniccall.html|20010305004152|46636|8f9741244fb6e9f6 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/set_tx_recover.html|20010305004152|47442|ada65907ba98eee8 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/sysmem.html|20010305004152|48282|3d088eb0ef1b27e0 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tcl.html|20010305004152|49096|f5c85b09c33bda4 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/tmp.html|20010305004152|50733|ef3450f6fa89f2dc +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/toc.html|20010305004152|49908|af1a24798980ad1 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.1/txn_check.html|20010305004152|51549|2405b25bc92cc476 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/callback.html|20010305004152|53656|64a2b2b85cc253c1 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/db_dump.html|20010305004152|54477|7d1cac3358c0482e +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/disk.html|20010305004152|55280|61799ebebe78ebb2 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/handle.html|20010305004152|56086|bb8a73b74d4399ae +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/incomplete.html|20010305004152|56914|af86a649a878a124 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/intro.html|20010305004152|57734|984a9f7dd07e0c14 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/mutexlock.html|20010305004152|58567|972b710c5bdba67c +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/notfound.html|20010305004152|59393|dc91c094aba92838 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/renumber.html|20010305004152|60219|d6cd798434da81aa +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/set_flags.html|20010305004152|61061|213809ca8d7802d0 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/toc.html|20010305004152|61902|9c94c533ada43c1a +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade.3.2/tx_recover.html|20010305004152|62754|132a354cde7a8286 +tim@threads.polyesthetic.msg|bdb/docs/ref/upgrade/process.html|20010305004151|64704|78f9ca966a587234 +tim@threads.polyesthetic.msg|bdb/docs/ref/xa/config.html|20010305004152|64479|3f3f449c305e66b4 +tim@threads.polyesthetic.msg|bdb/docs/ref/xa/faq.html|20010305004152|65373|7aa890c7b70f1293 +tim@threads.polyesthetic.msg|bdb/docs/ref/xa/intro.html|20010305004152|00728|8ac020ffb869e9a8 +tim@threads.polyesthetic.msg|bdb/docs/sleepycat/contact.html|20010305004152|04402|55b4da3d7bf7655b +tim@threads.polyesthetic.msg|bdb/docs/sleepycat/legal.html|20010305004152|02616|7388af4c578cacf6 +tim@threads.polyesthetic.msg|bdb/docs/sleepycat/license.html|20010305004152|03483|9371001bbf0ba2dd +tim@threads.polyesthetic.msg|bdb/docs/utility/berkeley_db_svc.html|20010305004152|06576|91fe012778882ce4 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_archive.html|20010305004152|07446|ab2c66e01b3e3626 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_checkpoint.html|20010305004152|08309|c040e4424edcc451 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_deadlock.html|20010305004152|09191|f23f99911c3e5784 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_dump.html|20010305004152|10062|5de7ade427f20332 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_load.html|20010305004152|10976|981095940db0197 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_printlog.html|20010305004152|11895|fcc4075ad0232842 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_recover.html|20010305004152|12771|1b63f2acdc0b0af7 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_stat.html|20010305004152|13652|9582c327964e1f9 +tim@threads.polyesthetic.msg|bdb/docs/utility/db_upgrade.html|20010305004152|14532|6444f26a93f77ea +tim@threads.polyesthetic.msg|bdb/docs/utility/db_verify.html|20010305004152|15424|4fee9bfa2f9ab41a +tim@threads.polyesthetic.msg|bdb/docs/utility/index.html|20010305004152|05717|66c82ee036c1b369 +tim@threads.polyesthetic.msg|bdb/hash/hash_auto.c|20010305004137|61459|d17c6a6ed4f181d1 +tim@threads.polyesthetic.msg|bdb/include/btree_auto.h|20010305004137|17274|84d4451c78faf67e +tim@threads.polyesthetic.msg|bdb/include/btree_ext.h|20010305004137|18246|5d53d710f170c6b6 +tim@threads.polyesthetic.msg|bdb/include/clib_ext.h|20010305004137|19207|ed9d9f7965f0e1d3 +tim@threads.polyesthetic.msg|bdb/include/common_ext.h|20010305004137|20146|35c8aab64ee3b8fd +tim@threads.polyesthetic.msg|bdb/include/crdel_auto.h|20010305004137|21088|1b8255da47550ece +tim@threads.polyesthetic.msg|bdb/include/db_auto.h|20010305004137|26350|994ddc84db334345 +tim@threads.polyesthetic.msg|bdb/include/db_ext.h|20010305004137|29469|a1e210bbd0de0a48 +tim@threads.polyesthetic.msg|bdb/include/db_server.h|20010305004137|34247|61a33aa05bf368a7 +tim@threads.polyesthetic.msg|bdb/include/env_ext.h|20010305004138|05832|33a5fdef1aeecefd +tim@threads.polyesthetic.msg|bdb/include/gen_client_ext.h|20010305004138|06647|5c621cacb18b38 +tim@threads.polyesthetic.msg|bdb/include/gen_server_ext.h|20010305004138|07539|fd7bcfe6bbca8bcb +tim@threads.polyesthetic.msg|bdb/include/hash_auto.h|20010305004138|09216|1b79cdd426d7ef25 +tim@threads.polyesthetic.msg|bdb/include/hash_ext.h|20010305004138|10079|5b31ff8413481606 +tim@threads.polyesthetic.msg|bdb/include/lock_ext.h|20010305004138|11814|ccd0785bb206933f +tim@threads.polyesthetic.msg|bdb/include/log_auto.h|20010305004138|13513|8d52dd0884d03051 tim@threads.polyesthetic.msg|bdb/include/log_ext.h|20010305004138|14339|2988f11d4545c76b +tim@threads.polyesthetic.msg|bdb/include/mp_ext.h|20010305004138|17070|a528b772d42d6455 +tim@threads.polyesthetic.msg|bdb/include/mutex_ext.h|20010305004138|19006|f20f47ddc346598b +tim@threads.polyesthetic.msg|bdb/include/os_ext.h|20010305004138|20730|a1771032b4d2d53b +tim@threads.polyesthetic.msg|bdb/include/qam_auto.h|20010305004138|24568|96f6c045fd0d6cab +tim@threads.polyesthetic.msg|bdb/include/qam_ext.h|20010305004138|25430|9993db1fb3428b6d +tim@threads.polyesthetic.msg|bdb/include/rpc_client_ext.h|20010305004138|28220|85436ca9b5691338 +tim@threads.polyesthetic.msg|bdb/include/rpc_server_ext.h|20010305004138|29091|952741fb85de2b80 +tim@threads.polyesthetic.msg|bdb/include/tcl_ext.h|20010305004138|31857|6759d22aa2ff5f39 +tim@threads.polyesthetic.msg|bdb/include/txn_auto.h|20010305004138|33645|e3f49e94fd291c45 +tim@threads.polyesthetic.msg|bdb/include/txn_ext.h|20010305004138|34549|9db24c14f204890c tim@threads.polyesthetic.msg|bdb/include/xa_ext.h|20010305004138|36449|50918e5ef9f095b6 tim@threads.polyesthetic.msg|bdb/java/src/com/sleepycat/db/DbConstants.java|20010305004138|56622|15fa87eda6b72302 +tim@threads.polyesthetic.msg|bdb/log/log_auto.c|20010305004137|49459|fe8c0369965f7151 +tim@threads.polyesthetic.msg|bdb/qam/qam_auto.c|20010305004141|31764|361954d3f149feb0 +tim@threads.polyesthetic.msg|bdb/rpc_client/db_server_clnt.c|20010305004141|41933|b548b860f765c597 +tim@threads.polyesthetic.msg|bdb/rpc_client/gen_client.c|20010305004141|43060|ad86f092d0996a68 +tim@threads.polyesthetic.msg|bdb/rpc_server/db_server.x|20010305004141|47705|811aeb6b630fe7aa +tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_proc.sed|20010305004141|49906|1a9af8e5b051acbd +tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_svc.c|20010305004141|50897|35804eb82b953f49 +tim@threads.polyesthetic.msg|bdb/rpc_server/db_server_xdr.c|20010305004141|53794|336ef020b4a22c05 +tim@threads.polyesthetic.msg|bdb/rpc_server/gen_db_server.c|20010305004141|54931|d5602f9bd5c930e +tim@threads.polyesthetic.msg|bdb/test/include.tcl|20010305004141|34016|20fc297b040cbe2 +tim@threads.polyesthetic.msg|bdb/test/logtrack.list|20010305004142|05743|7f4f1382b37d98e5 +tim@threads.polyesthetic.msg|bdb/txn/txn_auto.c|20010305004143|19863|6eb282f016f606d9 +tonu@x3.internalnet|include/vio.h|20010520213124|42404|c62fd2b86c03da7d diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index faa87511acc..b9c5702b08d 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -13,6 +13,7 @@ bar@bar.mysql.r18.ru bar@bar.udmsearch.izhnet.ru bar@gw.udmsearch.izhnet.ru bell@sanja.is.com.ua +bk@admin.bk davida@isil.mysql.com heikki@donna.mysql.fi heikki@hundin.mysql.fi @@ -49,10 +50,12 @@ monty@tramp.mysql.fi monty@work.mysql.com mwagner@cash.mwagner.org mwagner@evoq.mwagner.org +mwagner@work.mysql.com nick@mysql.com nick@nick.leippe.com paul@central.snake.net paul@teton.kitebird.com +pem@mysql.com peter@linux.local peter@mysql.com ram@gw.udmsearch.izhnet.ru @@ -88,5 +91,3 @@ worm@altair.is.lan zak@balfor.local zak@linux.local zgreant@mysql.com -mwagner@work.mysql.com -pem@mysql.com diff --git a/BitKeeper/etc/skipkeys b/BitKeeper/etc/skipkeys new file mode 100644 index 00000000000..36b38ab1c21 --- /dev/null +++ b/BitKeeper/etc/skipkeys @@ -0,0 +1,7 @@ +BK|scripts/safe_mysqld.sh|19700101030959|01930|d0a3cc73fd1b0d8d tim@localhost.polyesthetic.msg|scripts/safe_mysqld.sh|20000802235627|38519 +bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe arjen@co3064164-a.bitbike.com|BitKeeper/etc/logging_ok|20011212060636|33009 +bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe jcole@tetra.bedford.progress.com|BitKeeper/etc/logging_ok|20001004201211|30554 +bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe sasha@work.mysql.com|BitKeeper/etc/logging_ok|20000802223223|24242 +bk@work.mysql.com|BitKeeper/etc/logging_ok|20000731192914|03271|5e19f6258f804ffe tim@localhost.polyesthetic.msg|BitKeeper/etc/logging_ok|20000802235640|27343 +bk@work.mysql.com|ChangeSet|20000731191004|44203|eae70093a6122e66+ sasha@work.mysql.com|ChangeSet|20000802223249|54774 +bk@work.mysql.com|ChangeSet|20000731191004|44203|eae70093a6122e66+ tim@localhost.polyesthetic.msg|ChangeSet|20000802235645|56533 From 78fba6ef4fdb9c719ba128a8cbc72c71d7cf609b Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 29 Nov 2002 19:21:52 +0100 Subject: [PATCH 04/83] Post-merge fix. --- sql/sql_yacc.yy | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e70b4423c4d..2a82d13955c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3305,7 +3305,6 @@ truncate: lex->sql_command= SQLCOM_TRUNCATE; lex->select_lex.options= 0; lex->select_lex.init_order(); - lex->lock_option= lex->thd->update_lock_default; } ; From 7bffc43f1d5fe1d29e85d3234f8cca711ba384fe Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sat, 30 Nov 2002 13:02:54 +0100 Subject: [PATCH 05/83] Another post-merge fix. --- sql/sql_yacc.yy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2a82d13955c..4b409f5f41d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1289,7 +1289,7 @@ opt_binary: | BYTE_SYM { Lex->charset=my_charset_bin; } | BINARY { Lex->charset=my_charset_bin; } | CHAR_SYM SET charset_name { Lex->charset=$3; } - + ; opt_primary: /* empty */ @@ -1723,6 +1723,7 @@ select_init: } /* select in braces, can't contain global parameters */ sel->master_unit()->global_parameters= + sel->master_unit(); } union_opt; select_init2: From 4ef16b5eb6683c47b25696aebacb6a0ff00610d0 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sat, 30 Nov 2002 15:58:06 +0100 Subject: [PATCH 06/83] Undid earlier attempt to clean up this code, as it made merging from 4.1 a really painful exprience. --- sql/sql_yacc.yy | 719 +++++++++++++++++------------------------------- 1 file changed, 254 insertions(+), 465 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4b409f5f41d..13836902736 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -688,8 +688,7 @@ query: thd->lex.sql_command = SQLCOM_EMPTY_QUERY; } } - | verb_clause END_OF_INPUT {} - ; + | verb_clause END_OF_INPUT {}; verb_clause: alter @@ -728,8 +727,7 @@ verb_clause: | unlock | update | use - | help - ; + | help; /* help */ @@ -739,8 +737,7 @@ help: LEX *lex= Lex; lex->sql_command= SQLCOM_HELP; lex->help_arg= $2.str; - } - ; + }; /* change master */ @@ -750,13 +747,11 @@ change: LEX *lex = Lex; lex->sql_command = SQLCOM_CHANGE_MASTER; bzero((char*) &lex->mi, sizeof(lex->mi)); - } master_defs - ; + } master_defs; master_defs: master_def - | master_defs ',' master_def - ; + | master_defs ',' master_def; master_def: MASTER_HOST_SYM EQ TEXT_STRING @@ -805,6 +800,7 @@ master_def: } ; + /* create a table */ create: @@ -873,7 +869,7 @@ create: lex->udf.returns=(Item_result) $7; lex->udf.dl=$9.str; } - ; + ; create2: '(' field_list ')' opt_create_table_options create3 {} @@ -889,36 +885,30 @@ create3: mysql_init_select(lex); } select_options select_item_list opt_select_from union_clause {} - ; + ; opt_as: /* empty */ {} - | AS {} - ; + | AS {}; opt_table_options: /* empty */ { $$= 0; } - | table_options { $$= $1;} - ; + | table_options { $$= $1;}; table_options: table_option { $$=$1; } - | table_option table_options { $$= $1 | $2; } - ; + | table_option table_options { $$= $1 | $2; }; table_option: - TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; } - ; + TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }; opt_if_not_exists: /* empty */ { $$= 0; } - | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; } - ; + | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }; opt_create_table_options: /* empty */ - | create_table_options - ; + | create_table_options; create_table_options_space_separated: create_table_option @@ -926,9 +916,8 @@ create_table_options_space_separated: create_table_options: create_table_option - | create_table_option create_table_options - | create_table_option ',' create_table_options - ; + | create_table_option create_table_options; + | create_table_option ',' create_table_options; create_table_option: TYPE_SYM opt_equal table_types { Lex->create_info.db_type= $3; } @@ -979,48 +968,41 @@ table_types: | MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; } | HEAP_SYM { $$= DB_TYPE_HEAP; } | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } - | INNOBASE_SYM { $$= DB_TYPE_INNODB; } - ; + | INNOBASE_SYM { $$= DB_TYPE_INNODB; }; row_types: DEFAULT { $$= ROW_TYPE_DEFAULT; } | FIXED_SYM { $$= ROW_TYPE_FIXED; } | DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; } - | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; } - ; + | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }; raid_types: RAID_STRIPED_SYM { $$= RAID_TYPE_0; } | RAID_0_SYM { $$= RAID_TYPE_0; } - | ULONG_NUM { $$=$1; } - ; + | ULONG_NUM { $$=$1;}; merge_insert_types: NO_SYM { $$= MERGE_INSERT_DISABLED; } | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; } - | LAST_SYM { $$= MERGE_INSERT_TO_LAST; } - ; + | LAST_SYM { $$= MERGE_INSERT_TO_LAST; }; opt_select_from: opt_limit_clause {} - | select_from select_lock_type - ; + | select_from select_lock_type; udf_func_type: /* empty */ { $$ = UDFTYPE_FUNCTION; } - | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; } - ; + | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; }; udf_type: STRING_SYM {$$ = (int) STRING_RESULT; } | REAL {$$ = (int) REAL_RESULT; } - | INT_SYM {$$ = (int) INT_RESULT; } - ; + | INT_SYM {$$ = (int) INT_RESULT; }; field_list: field_list_item - | field_list ',' field_list_item - ; + | field_list ',' field_list_item; + field_list_item: field_spec check_constraint @@ -1058,8 +1040,7 @@ check_constraint: opt_constraint: /* empty */ - | CONSTRAINT opt_ident - ; + | CONSTRAINT opt_ident; field_spec: field_ident @@ -1078,8 +1059,7 @@ field_spec: lex->default_value, lex->comment, lex->change,lex->interval,lex->charset)) YYABORT; - } - ; + }; type: int_type opt_len field_options { $$=$1; } @@ -1161,76 +1141,64 @@ type: char: CHAR_SYM {} | NCHAR_SYM {} - | NATIONAL_SYM CHAR_SYM {} - ; + | NATIONAL_SYM CHAR_SYM {}; varchar: char VARYING {} | VARCHAR {} | NATIONAL_SYM VARCHAR {} - | NCHAR_SYM VARCHAR {} - ; + | NCHAR_SYM VARCHAR {}; int_type: INT_SYM { $$=FIELD_TYPE_LONG; } | TINYINT { $$=FIELD_TYPE_TINY; } | SMALLINT { $$=FIELD_TYPE_SHORT; } | MEDIUMINT { $$=FIELD_TYPE_INT24; } - | BIGINT { $$=FIELD_TYPE_LONGLONG; } - ; + | BIGINT { $$=FIELD_TYPE_LONGLONG; }; real_type: REAL { $$= YYTHD->sql_mode & MODE_REAL_AS_FLOAT ? FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } - | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; } - ; + | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; float_options: /* empty */ {} | '(' NUM ')' { Lex->length=$2.str; } - | precision {} - ; + | precision {}; precision: '(' NUM ',' NUM ')' { LEX *lex=Lex; lex->length=$2.str; lex->dec=$4.str; - } - ; + }; field_options: /* empty */ {} - | field_opt_list {} - ; + | field_opt_list {}; field_opt_list: field_opt_list field_option {} - | field_option {} - ; + | field_option {}; field_option: SIGNED_SYM {} | UNSIGNED { Lex->type|= UNSIGNED_FLAG;} - | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; } - ; + | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }; opt_len: /* empty */ { Lex->length=(char*) 0; } /* use default length */ - | '(' NUM ')' { Lex->length= $2.str; } - ; + | '(' NUM ')' { Lex->length= $2.str; }; opt_precision: /* empty */ {} - | precision {} - ; + | precision {}; opt_attribute: /* empty */ {} - | opt_attribute_list {} - ; + | opt_attribute_list {}; opt_attribute_list: opt_attribute_list attribute {} @@ -1246,8 +1214,8 @@ attribute: | opt_primary KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; } | UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; } | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } - | COMMENT_SYM text_literal { Lex->comment= $2; } - ; + | COMMENT_SYM text_literal { Lex->comment= $2; }; + charset_name: BINARY @@ -1265,31 +1233,27 @@ charset_name: net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; } - } - ; + }; charset_name_or_default: charset_name { $$=$1; } - | DEFAULT { $$=NULL; } - ; + | DEFAULT { $$=NULL; } ; opt_default: /* empty */ {} - | DEFAULT {} - ; + | DEFAULT {}; opt_db_default_character_set: /* empty */ { $$=default_charset_info; } | opt_default CHAR_SYM SET charset_name_or_default { $$=$4; } - | opt_default CHARSET charset_name_or_default { $$=$3; } - ; + | opt_default CHARSET charset_name_or_default { $$=$3; }; opt_binary: /* empty */ { Lex->charset=NULL; } | BYTE_SYM { Lex->charset=my_charset_bin; } | BINARY { Lex->charset=my_charset_bin; } - | CHAR_SYM SET charset_name { Lex->charset=$3; } - ; + | CHAR_SYM SET charset_name { Lex->charset=$3; } ; + opt_primary: /* empty */ @@ -1306,45 +1270,38 @@ references: opt_ref_list { $$=$2; - } - ; + }; opt_ref_list: /* empty */ opt_on_delete {} - | '(' ref_list ')' opt_on_delete {} - ; + | '(' ref_list ')' opt_on_delete {}; ref_list: ref_list ',' ident { Lex->ref_list.push_back(new key_part_spec($3.str)); } - | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); } - ; + | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); }; opt_on_delete: /* empty */ {} - | opt_on_delete_list {} - ; + | opt_on_delete_list {}; opt_on_delete_list: opt_on_delete_list opt_on_delete_item {} - | opt_on_delete_item {} - ; + | opt_on_delete_item {}; opt_on_delete_item: ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; } | ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; } | MATCH FULL { Lex->fk_match_option= foreign_key::FK_MATCH_FULL; } | MATCH PARTIAL { Lex->fk_match_option= foreign_key::FK_MATCH_PARTIAL; } - | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; } - ; + | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; }; delete_option: RESTRICT { $$= (int) foreign_key::FK_OPTION_RESTRICT; } | CASCADE { $$= (int) foreign_key::FK_OPTION_CASCADE; } | SET NULL_SYM { $$= (int) foreign_key::FK_OPTION_SET_NULL; } | NO_SYM ACTION { $$= (int) foreign_key::FK_OPTION_NO_ACTION; } - | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; } - ; + | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; }; key_type: opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } @@ -1354,56 +1311,46 @@ key_type: | SPATIAL_SYM { $$= Key::SPATIAL; } | SPATIAL_SYM key_or_index { $$= Key::SPATIAL; } | opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; } - | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; } - ; + | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; }; key_or_index: KEY_SYM {} - | INDEX {} - ; + | INDEX {}; keys_or_index: KEYS {} | INDEX {} - | INDEXES {} - ; + | INDEXES {}; opt_unique_or_fulltext: /* empty */ { $$= Key::MULTIPLE; } | UNIQUE_SYM { $$= Key::UNIQUE; } - | SPATIAL_SYM { $$= Key::SPATIAL; } - ; + | SPATIAL_SYM { $$= Key::SPATIAL; }; key_alg: /* empty */ { $$= HA_KEY_ALG_UNDEF; } - | USING opt_btree_or_rtree { $$= $2; } - ; + | USING opt_btree_or_rtree { $$= $2; }; opt_btree_or_rtree: BTREE_SYM { $$= HA_KEY_ALG_BTREE; } | RTREE_SYM { $$= HA_KEY_ALG_RTREE; } - | HASH_SYM { $$= HA_KEY_ALG_HASH; } - ; + | HASH_SYM { $$= HA_KEY_ALG_HASH; }; key_list: key_list ',' key_part order_dir { Lex->col_list.push_back($3); } - | key_part order_dir { Lex->col_list.push_back($1); } - ; + | key_part order_dir { Lex->col_list.push_back($1); }; key_part: ident { $$=new key_part_spec($1.str); } - | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); } - ; + | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); }; opt_ident: /* empty */ { $$=(char*) 0; } /* Defaultlength */ - | field_ident { $$=$1.str; } - ; + | field_ident { $$=$1.str; }; string_list: text_string { Lex->interval_list.push_back($1); } - | string_list ',' text_string { Lex->interval_list.push_back($3); } - ; + | string_list ',' text_string { Lex->interval_list.push_back($3); }; /* ** Alter table @@ -1433,24 +1380,23 @@ alter: lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } - alter_list + alter_list; + | ALTER DATABASE ident opt_db_default_character_set { LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; lex->create_info.table_charset=$4; - } - ; + }; + alter_list: | alter_list_item - | alter_list ',' alter_list_item - ; + | alter_list ',' alter_list_item; add_column: - ADD opt_column { Lex->change=0; } - ; + ADD opt_column { Lex->change=0; }; alter_list_item: add_column field_list_item opt_place { Lex->simple_alter=0; } @@ -1519,37 +1465,32 @@ alter_list_item: lex->name= $3->table.str; } | create_table_options_space_separated { Lex->simple_alter=0; } - | order_clause { Lex->simple_alter=0; } - ; + | order_clause { Lex->simple_alter=0; }; opt_column: /* empty */ {} - | COLUMN_SYM {} - ; + | COLUMN_SYM {}; opt_ignore: /* empty */ { Lex->duplicates=DUP_ERROR; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; } - ; + | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; opt_restrict: /* empty */ {} | RESTRICT {} - | CASCADE {} - ; + | CASCADE {}; opt_place: /* empty */ {} | AFTER_SYM ident { store_position_for_column($2.str); } - | FIRST_SYM { store_position_for_column(first_keyword); } - ; + | FIRST_SYM { store_position_for_column(first_keyword); }; opt_to: /* empty */ {} | TO_SYM {} | EQ {} - | AS {} - ; + | AS {}; + /* The first two deprecate the last two--delete the last two for 4.1 release */ @@ -1571,8 +1512,7 @@ slave: slave_thread_opts: slave_thread_opt - | slave_thread_opts ',' slave_thread_opt - ; + | slave_thread_opts ',' slave_thread_opt; slave_thread_opt: /*empty*/ {} @@ -1588,8 +1528,7 @@ restore: table_list FROM TEXT_STRING { Lex->backup_dir = $6.str; - } - ; + }; backup: BACKUP_SYM table_or_tables @@ -1599,8 +1538,7 @@ backup: table_list TO_SYM TEXT_STRING { Lex->backup_dir = $6.str; - } - ; + }; repair: REPAIR table_or_tables @@ -1609,24 +1547,20 @@ repair: lex->sql_command = SQLCOM_REPAIR; lex->check_opt.init(); } - table_list opt_mi_repair_type - ; + table_list opt_mi_repair_type; opt_mi_repair_type: /* empty */ { Lex->check_opt.flags = T_MEDIUM; } - | mi_repair_types {} - ; + | mi_repair_types {}; mi_repair_types: mi_repair_type {} - | mi_repair_type mi_repair_types {} - ; + | mi_repair_type mi_repair_types {}; mi_repair_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } - | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; } - ; + | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; }; analyze: ANALYZE_SYM table_or_tables @@ -1635,8 +1569,7 @@ analyze: lex->sql_command = SQLCOM_ANALYZE; lex->check_opt.init(); } - table_list opt_mi_check_type - ; + table_list opt_mi_check_type; check: CHECK_SYM table_or_tables @@ -1645,26 +1578,22 @@ check: lex->sql_command = SQLCOM_CHECK; lex->check_opt.init(); } - table_list opt_mi_check_type - ; + table_list opt_mi_check_type; opt_mi_check_type: /* empty */ { Lex->check_opt.flags = T_MEDIUM; } - | mi_check_types {} - ; + | mi_check_types {}; mi_check_types: mi_check_type {} - | mi_check_type mi_check_types {} - ; + | mi_check_type mi_check_types {}; mi_check_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | FAST_SYM { Lex->check_opt.flags|= T_FAST; } | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } - | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; } - ; + | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }; optimize: OPTIMIZE table_or_tables @@ -1673,21 +1602,18 @@ optimize: lex->sql_command = SQLCOM_OPTIMIZE; lex->check_opt.init(); } - table_list opt_mi_check_type - ; + table_list opt_mi_check_type; rename: RENAME table_or_tables { Lex->sql_command=SQLCOM_RENAME_TABLE; } - table_to_table_list - ; + table_to_table_list; table_to_table_list: table_to_table - | table_to_table_list ',' table_to_table - ; + | table_to_table_list ',' table_to_table; table_to_table: table_ident TO_SYM table_ident @@ -1696,8 +1622,7 @@ table_to_table: if (!sl->add_table_to_list($1,NULL,1,TL_IGNORE) || !sl->add_table_to_list($3,NULL,1,TL_IGNORE)) YYABORT; - } - ; + }; /* Select : retrieve data from table @@ -1705,8 +1630,7 @@ table_to_table: select: - select_init { Lex->sql_command=SQLCOM_SELECT; } - ; + select_init { Lex->sql_command=SQLCOM_SELECT; }; /* Need select_init2 for subselects. */ select_init: @@ -1746,8 +1670,7 @@ select_part2: lex->lock_option= TL_READ; /* Only for global SELECT */ mysql_init_select(lex); } - select_options select_item_list select_into select_lock_type - ; + select_options select_item_list select_into select_lock_type; select_into: opt_limit_clause {} @@ -1758,22 +1681,18 @@ select_into: | into | select_from | into select_from - | select_from into - ; + | select_from into; select_from: - FROM join_table_list where_clause group_clause having_clause opt_order_clause opt_limit_clause procedure_clause - ; + FROM join_table_list where_clause group_clause having_clause opt_order_clause opt_limit_clause procedure_clause; select_options: /* empty*/ - | select_option_list - ; + | select_option_list; select_option_list: select_option_list select_option - | select_option - ; + | select_option; select_option: STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } @@ -1827,8 +1746,8 @@ select_item_list: { if (add_item_to_list(new Item_field(NULL,NULL,"*"))) YYABORT; - } - ; + }; + select_item: remember_name select_item2 remember_end select_alias @@ -1839,39 +1758,32 @@ select_item: $2->set_name($4.str); else if (!$2->name) $2->set_name($1,(uint) ($3 - $1)); - } - ; + }; remember_name: - { $$=(char*) Lex->tok_start; } - ; + { $$=(char*) Lex->tok_start; }; remember_end: - { $$=(char*) Lex->tok_end; } - ; + { $$=(char*) Lex->tok_end; }; select_item2: table_wild { $$=$1; } /* table.* */ - | expr { $$=$1; } - ; + | expr { $$=$1; }; select_alias: { $$.str=0;} | AS ident { $$=$2; } | AS TEXT_STRING { $$=$2; } | ident { $$=$1; } - | TEXT_STRING { $$=$1; } - ; + | TEXT_STRING { $$=$1; }; optional_braces: /* empty */ {} - | '(' ')' {} - ; + | '(' ')' {}; /* all possible expressions */ expr: expr_expr { $$= $1; } - | simple_expr { $$= $1; } - ; + | simple_expr { $$= $1; }; comp_op: EQ { $$ = &comp_eq_creator; } | GE { $$ = &comp_ge_creator; } @@ -1939,8 +1851,7 @@ expr_expr: | expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } | expr COLLATE_SYM charset_name - { $$= new Item_func_set_collation($1,$3); } - ; + { $$= new Item_func_set_collation($1,$3); }; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ no_in_expr: @@ -1985,8 +1896,7 @@ no_in_expr: { $$= new Item_date_add_interval($1,$4,$5,0); } | no_in_expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } - | simple_expr - ; + | simple_expr; /* expressions that begin with 'expr' that does NOT follow AND */ no_and_expr: @@ -2040,8 +1950,7 @@ no_and_expr: { $$= new Item_date_add_interval($1,$4,$5,0); } | no_and_expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } - | simple_expr - ; + | simple_expr; simple_expr: simple_ident @@ -2381,13 +2290,11 @@ simple_expr: Lex->safe_to_cache_query=0; } | EXTRACT_SYM '(' interval FROM expr ')' - { $$=new Item_extract( $3, $5); } - ; + { $$=new Item_extract( $3, $5); }; udf_expr_list: /* empty */ { $$= NULL; } - | expr_list { $$= $1; } - ; + | expr_list { $$= $1;}; sum_expr: AVG_SYM '(' in_sum_expr ')' @@ -2411,8 +2318,7 @@ sum_expr: | STD_SYM '(' in_sum_expr ')' { $$=new Item_sum_std($3); } | SUM_SYM '(' in_sum_expr ')' - { $$=new Item_sum_sum($3); } - ; + { $$=new Item_sum_sum($3); }; in_sum_expr: { @@ -2427,8 +2333,7 @@ in_sum_expr: { Select->select_lex()->in_sum_expr--; $$=$2; - } - ; + }; cast_type: BINARY { $$=ITEM_CAST_BINARY; } @@ -2445,45 +2350,37 @@ cast_type: expr_list: { Select->expr_list.push_front(new List); } expr_list2 - { $$= Select->expr_list.pop(); } - ; + { $$= Select->expr_list.pop(); }; expr_list2: expr { Select->expr_list.head()->push_back($1); } - | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); } - ; + | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); }; ident_list_arg: ident_list { $$= $1; } - | '(' ident_list ')' { $$= $2; } - ; + | '(' ident_list ')' { $$= $2; }; ident_list: { Select->expr_list.push_front(new List); } ident_list2 - { $$= Select->expr_list.pop(); } - ; + { $$= Select->expr_list.pop(); }; ident_list2: simple_ident { Select->expr_list.head()->push_back($1); } - | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); } - ; + | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); }; opt_expr: /* empty */ { $$= NULL; } - | expr { $$= $1; } - ; + | expr { $$= $1; }; opt_else: /* empty */ { $$= NULL; } - | ELSE expr { $$= $2; } - ; + | ELSE expr { $$= $2; }; when_list: { Select->when_list.push_front(new List); } when_list2 - { $$= Select->when_list.pop(); } - ; + { $$= Select->when_list.pop(); }; when_list2: expr THEN_SYM expr @@ -2497,13 +2394,11 @@ when_list2: SELECT_LEX_NODE *sel=Select; sel->when_list.head()->push_back($3); sel->when_list.head()->push_back($5); - } - ; + }; opt_pad: /* empty */ { $$=new Item_string(" ",1,default_charset_info); } - | expr { $$=$1; } - ; + | expr { $$=$1; }; join_table_list: '(' join_table_list ')' { $$=$2; } @@ -2546,14 +2441,12 @@ join_table_list: | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table_list { add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } | join_table_list NATURAL JOIN_SYM join_table_list - { add_join_natural($1,$4); $$=$4; } - ; + { add_join_natural($1,$4); $$=$4; }; normal_join: ',' {} | JOIN_SYM {} - | CROSS JOIN_SYM {} - ; + | CROSS JOIN_SYM {}; join_table: { @@ -2580,8 +2473,7 @@ join_table: add_table_to_list(new Table_ident(unit), $5, 0, lex->lock_option))) YYABORT; - } - ; + }; select_derived: { @@ -2598,8 +2490,7 @@ select_derived: opt_outer: /* empty */ {} - | OUTER {} - ; + | OUTER {}; opt_key_definition: /* empty */ {} @@ -2614,14 +2505,12 @@ opt_key_definition: SELECT_LEX *sel= Select->select_lex(); sel->ignore_index= *$2; sel->ignore_index_ptr= &sel->ignore_index; - } - ; + }; key_usage_list: key_or_index { Select->select_lex()->interval_list.empty(); } '(' key_usage_list2 ')' - { $$= &Select->select_lex()->interval_list; } - ; + { $$= &Select->select_lex()->interval_list; }; key_usage_list2: key_usage_list2 ',' ident @@ -2635,8 +2524,7 @@ key_usage_list2: | PRIMARY_SYM { Select->select_lex()-> interval_list.push_back(new String("PRIMARY", 7, - default_charset_info)); } - ; + default_charset_info)); }; using_list: ident @@ -2653,8 +2541,7 @@ using_list: SELECT_LEX *sel= Select->select_lex(); if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1))) YYABORT; - } - ; + }; interval: DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; } @@ -2669,20 +2556,18 @@ interval: | MONTH_SYM { $$=INTERVAL_MONTH; } | SECOND_SYM { $$=INTERVAL_SECOND; } | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } - | YEAR_SYM { $$=INTERVAL_YEAR; } - ; + | YEAR_SYM { $$=INTERVAL_YEAR; }; table_alias: /* empty */ | AS - | EQ - ; + | EQ; opt_table_alias: /* empty */ { $$=0; } | table_alias ident - { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); } - ; + { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); }; + where_clause: /* empty */ { Select->select_lex()->where= 0; } @@ -2707,8 +2592,7 @@ having_clause: opt_escape: ESCAPE_SYM TEXT_STRING { $$= $2.str; } - | /* empty */ { $$= (char*) "\\"; } - ; + | /* empty */ { $$= (char*) "\\"; }; /* @@ -2717,15 +2601,13 @@ opt_escape: group_clause: /* empty */ - | GROUP BY group_list olap_opt - ; + | GROUP BY group_list olap_opt; group_list: group_list ',' order_ident order_dir { if (add_group_to_list($3,(bool) $4)) YYABORT; } | order_ident order_dir - { if (add_group_to_list($1,(bool) $2)) YYABORT; } - ; + { if (add_group_to_list($1,(bool) $2)) YYABORT; }; olap_opt: /* empty */ {} @@ -2765,8 +2647,7 @@ olap_opt: opt_order_clause: /* empty */ - | order_clause - ; + | order_clause; order_clause: ORDER_SYM BY @@ -2781,21 +2662,19 @@ order_clause: "ORDER BY"); YYABORT; } - } order_list - ; + } order_list; order_list: order_list ',' order_ident order_dir { if (add_order_to_list($3,(bool) $4)) YYABORT; } | order_ident order_dir - { if (add_order_to_list($1,(bool) $2)) YYABORT; } - ; + { if (add_order_to_list($1,(bool) $2)) YYABORT; }; order_dir: /* empty */ { $$ = 1; } | ASC { $$ =1; } - | DESC { $$ =0; } - ; + | DESC { $$ =0; }; + opt_limit_clause: /* empty */ {} @@ -2835,6 +2714,7 @@ limit_options: } ; + delete_limit_clause: /* empty */ { @@ -2842,23 +2722,20 @@ delete_limit_clause: lex->current_select->select_limit= HA_POS_ERROR; } | LIMIT ulonglong_num - { Select->select_limit= (ha_rows) $2; } - ; + { Select->select_limit= (ha_rows) $2; }; ULONG_NUM: NUM { $$= strtoul($1.str,NULL,10); } | ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); } | REAL_NUM { $$= strtoul($1.str,NULL,10); } - | FLOAT_NUM { $$= strtoul($1.str,NULL,10); } - ; + | FLOAT_NUM { $$= strtoul($1.str,NULL,10); }; ulonglong_num: NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } | ULONGLONG_NUM { $$= strtoull($1.str,NULL,10); } | LONG_NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } | REAL_NUM { $$= strtoull($1.str,NULL,10); } - | FLOAT_NUM { $$= strtoull($1.str,NULL,10); } - ; + | FLOAT_NUM { $$= strtoull($1.str,NULL,10); }; procedure_clause: /* empty */ @@ -2872,18 +2749,16 @@ procedure_clause: YYABORT; Lex->safe_to_cache_query=0; } - '(' procedure_list ')' - ; + '(' procedure_list ')'; + procedure_list: /* empty */ {} - | procedure_list2 {} - ; + | procedure_list2 {}; procedure_list2: procedure_list2 ',' procedure_item - | procedure_item - ; + | procedure_item; procedure_item: remember_name expr @@ -2959,9 +2834,7 @@ do: DO_SYM if (!(lex->insert_list = new List_item)) YYABORT; } - values - ; - + values; /* Drop : delete tables or index */ @@ -2996,19 +2869,16 @@ drop: LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_FUNCTION; lex->udf.name=$3.str; - } - ; + }; table_list: table_name - | table_list ',' table_name - ; + | table_list ',' table_name; table_name: table_ident - { if (!Select->add_table_to_list($1, NULL, 1)) YYABORT; } - ; + { if (!Select->add_table_to_list($1, NULL, 1)) YYABORT; }; if_exists: /* empty */ { $$= 0; } @@ -3065,8 +2935,7 @@ replace_lock_option: insert2: INTO insert_table {} - | insert_table {} - ; + | insert_table {}; insert_table: table_name @@ -3075,8 +2944,7 @@ insert_table: lex->field_list.empty(); lex->many_values.empty(); lex->insert_list=0; - } - ; + }; insert_field_spec: opt_field_spec insert_values {} @@ -3087,19 +2955,16 @@ insert_field_spec: lex->many_values.push_back(lex->insert_list)) YYABORT; } - ident_eq_list - ; + ident_eq_list; opt_field_spec: /* empty */ { } | '(' fields ')' { } - | '(' ')' { } - ; + | '(' ')' { }; fields: fields ',' insert_ident { Lex->field_list.push_back($3); } - | insert_ident { Lex->field_list.push_back($1); } - ; + | insert_ident { Lex->field_list.push_back($1); }; insert_values: VALUES values_list {} @@ -3118,24 +2983,21 @@ insert_values: values_list: values_list ',' no_braces - | no_braces - ; + | no_braces; ident_eq_list: ident_eq_list ',' ident_eq_value | - ident_eq_value - ; + ident_eq_value; ident_eq_value: simple_ident equal expr_or_default - { + { LEX *lex=Lex; if (lex->field_list.push_back($1) || lex->insert_list->push_back($3)) YYABORT; - } - ; + }; equal: EQ {} | SET_VAR {} @@ -3157,13 +3019,11 @@ no_braces: LEX *lex=Lex; if (lex->many_values.push_back(lex->insert_list)) YYABORT; - } - ; + }; opt_values: /* empty */ {} - | values - ; + | values; values: values ',' expr_or_default @@ -3226,8 +3086,7 @@ update_list: { if (add_item_to_list($1) || add_value_to_list($3)) YYABORT; - } - ; + }; opt_low_priority: /* empty */ { $$= YYTHD->update_lock_default; } @@ -3260,13 +3119,11 @@ single_multi: FROM join_table_list where_clause | FROM table_wild_list { mysql_init_multi_delete(Lex); } - USING join_table_list where_clause - ; + USING join_table_list where_clause; table_wild_list: table_wild_one {} - | table_wild_list ',' table_wild_one {} - ; + | table_wild_list ',' table_wild_one {}; table_wild_one: ident opt_wild @@ -3285,19 +3142,16 @@ table_wild_one: opt_wild: /* empty */ {} - | '.' '*' {} - ; + | '.' '*' {}; opt_delete_options: /* empty */ {} - | opt_delete_option opt_delete_options {} - ; + | opt_delete_option opt_delete_options {}; opt_delete_option: QUICK { Select->options|= OPTION_QUICK; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } - ; + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; truncate: TRUNCATE_SYM opt_table_sym table_name @@ -3311,8 +3165,7 @@ truncate: opt_table_sym: /* empty */ - | TABLE_SYM - ; + | TABLE_SYM; /* Show things */ @@ -3322,9 +3175,7 @@ show: SHOW lex->wild=0; bzero((char*) &lex->create_info,sizeof(lex->create_info)); } - show_param - ; - + show_param; show_param: DATABASES wild @@ -3456,38 +3307,31 @@ show_param: | SLAVE STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - } - ; + }; opt_db: /* empty */ { $$= 0; } - | from_or_in ident { $$= $2.str; } - ; + | from_or_in ident { $$= $2.str; }; wild: /* empty */ - | LIKE text_string { Lex->wild= $2; } - ; + | LIKE text_string { Lex->wild= $2; }; opt_full: /* empty */ { Lex->verbose=0; } - | FULL { Lex->verbose=1; } - ; + | FULL { Lex->verbose=1; }; from_or_in: FROM - | IN_SYM - ; + | IN_SYM; binlog_in: /* empty */ { Lex->mi.log_file_name = 0; } - | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; } - ; + | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; }; binlog_from: /* empty */ { Lex->mi.pos = 4; /* skip magic number */ } - | FROM ulonglong_num { Lex->mi.pos = $2; } - ; + | FROM ulonglong_num { Lex->mi.pos = $2; }; /* A Oracle compatible synonym for show */ @@ -3506,21 +3350,18 @@ describe: { LEX *lex=Lex; lex->select_lex.options|= SELECT_DESCRIBE; - } - ; + }; describe_command: DESC - | DESCRIBE - ; + | DESCRIBE; opt_describe_column: /* empty */ {} | text_string { Lex->wild= $1; } | ident - { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); } - ; + { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); }; /* flush things */ @@ -3531,13 +3372,11 @@ flush: LEX *lex=Lex; lex->sql_command= SQLCOM_FLUSH; lex->type=0; } - flush_options - ; + flush_options; flush_options: flush_options ',' flush_option - | flush_option - ; + | flush_option; flush_option: table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list @@ -3550,32 +3389,26 @@ flush_option: | SLAVE { Lex->type|= REFRESH_SLAVE; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; } - | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; } - ; + | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }; opt_table_list: - /* empty */ {} - | table_list {} - ; + /* empty */ {;} + | table_list {;}; reset: RESET_SYM { LEX *lex=Lex; lex->sql_command= SQLCOM_RESET; lex->type=0; - } reset_options - ; - + } reset_options; reset_options: reset_options ',' reset_option - | reset_option - ; + | reset_option; reset_option: SLAVE { Lex->type|= REFRESH_SLAVE; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } - | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;} - ; + | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}; purge: PURGE @@ -3585,10 +3418,9 @@ purge: lex->type=0; } MASTER_SYM LOGS_SYM TO_SYM TEXT_STRING - { + { Lex->to_log = $6.str; - } - ; + } ; /* kill threads */ @@ -3603,8 +3435,7 @@ kill: } lex->sql_command=SQLCOM_KILL; lex->thread_id= (ulong) $2->val_int(); - } - ; + }; /* change database */ @@ -3613,8 +3444,7 @@ use: USE_SYM ident LEX *lex=Lex; lex->sql_command=SQLCOM_CHANGE_DB; lex->select_lex.db= $2.str; - } - ; + }; /* import, export of files */ @@ -3646,13 +3476,11 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING LOAD DATA_SYM FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_DATA; - } - ; + }; opt_local: - /* empty */ { $$=0; } - | LOCAL_SYM { $$=1; } - ; + /* empty */ { $$=0;} + | LOCAL_SYM { $$=1;}; load_data_lock: /* empty */ { $$= YYTHD->update_lock_default; } @@ -3663,18 +3491,15 @@ load_data_lock: opt_duplicate: /* empty */ { Lex->duplicates=DUP_ERROR; } | REPLACE { Lex->duplicates=DUP_REPLACE; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; } - ; + | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; opt_field_term: /* empty */ - | COLUMNS field_term_list - ; + | COLUMNS field_term_list; field_term_list: field_term_list field_term - | field_term - ; + | field_term; field_term: TERMINATED BY text_string { Lex->exchange->field_term= $3;} @@ -3684,30 +3509,25 @@ field_term: lex->exchange->enclosed= $4; lex->exchange->opt_enclosed=1; } - | ENCLOSED BY text_string { Lex->exchange->enclosed= $3; } - | ESCAPED BY text_string { Lex->exchange->escaped= $3; } - ; + | ENCLOSED BY text_string { Lex->exchange->enclosed= $3;} + | ESCAPED BY text_string { Lex->exchange->escaped= $3;}; opt_line_term: /* empty */ - | LINES line_term_list - ; + | LINES line_term_list; line_term_list: line_term_list line_term - | line_term - ; + | line_term; line_term: - TERMINATED BY text_string { Lex->exchange->line_term= $3; } - | STARTING BY text_string { Lex->exchange->line_start= $3; } - ; + TERMINATED BY text_string { Lex->exchange->line_term= $3;} + | STARTING BY text_string { Lex->exchange->line_start= $3;}; opt_ignore_lines: /* empty */ | IGNORE_SYM NUM LINES - { Lex->exchange->skip_lines=atol($2.str); } - ; + { Lex->exchange->skip_lines=atol($2.str); }; /* Common definitions */ @@ -3715,8 +3535,7 @@ text_literal: TEXT_STRING { $$ = new Item_string($1.str,$1.length,YYTHD->thd_charset); } | UNDERSCORE_CHARSET TEXT_STRING { $$ = new Item_string($2.str,$2.length,Lex->charset); } | text_literal TEXT_STRING - { ((Item_string*) $1)->append($2.str,$2.length); } - ; + { ((Item_string*) $1)->append($2.str,$2.length); }; text_string: TEXT_STRING { $$= new String($1.str,$1.length,YYTHD->thd_charset); } @@ -3724,9 +3543,7 @@ text_string: { Item *tmp = new Item_varbinary($1.str,$1.length); $$= tmp ? tmp->val_str((String*) 0) : (String*) 0; - } - ; - + }; param_marker: '?' { @@ -3741,9 +3558,7 @@ param_marker: yyerror("You have an error in your SQL syntax"); YYABORT; } - } - ; - + }; literal: text_literal { $$ = $1; } | NUM { $$ = new Item_int($1.str, (longlong) atol($1.str),$1.length); } @@ -3756,8 +3571,7 @@ literal: | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);} | DATE_SYM text_literal { $$ = $2; } | TIME_SYM text_literal { $$ = $2; } - | TIMESTAMP text_literal { $$ = $2; } - ; + | TIMESTAMP text_literal { $$ = $2; }; /********************************************************************** ** Createing different items. @@ -3765,19 +3579,16 @@ literal: insert_ident: simple_ident { $$=$1; } - | table_wild { $$=$1; } - ; + | table_wild { $$=$1; }; table_wild: ident '.' '*' { $$ = new Item_field(NullS,$1.str,"*"); } | ident '.' ident '.' '*' { $$ = new Item_field((YYTHD->client_capabilities & - CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); } - ; + CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); }; order_ident: - expr { $$=$1; } - ; + expr { $$=$1; }; simple_ident: ident @@ -3799,20 +3610,19 @@ simple_ident: { SELECT_LEX_NODE *sel=Select; $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); - } - ; + }; + field_ident: ident { $$=$1;} | ident '.' ident { $$=$3;} /* Skipp schema name in create*/ - | '.' ident { $$=$2;} /* For Delphi */ - ; + | '.' ident { $$=$2;} /* For Delphi */; table_ident: ident { $$=new Table_ident($1); } | ident '.' ident { $$=new Table_ident($1,$3,0);} - | '.' ident { $$=new Table_ident($2);} /* For Delphi */ - ; + | '.' ident { $$=new Table_ident($2);} + /* For Delphi */; ident: IDENT { $$=$1; } @@ -3829,8 +3639,7 @@ ident: ident_or_text: ident { $$=$1;} | TEXT_STRING { $$=$1;} - | LEX_HOSTNAME { $$=$1;} - ; + | LEX_HOSTNAME { $$=$1;}; user: ident_or_text @@ -3844,8 +3653,7 @@ user: if (!($$=(LEX_USER*) sql_alloc(sizeof(st_lex_user)))) YYABORT; $$->user = $1; $$->host=$3; - } - ; + }; /* Keyword that we allow for identifiers */ @@ -4023,18 +3831,15 @@ set: lex->option_type=OPT_DEFAULT; lex->var_list.empty(); } - option_value_list - ; + option_value_list; opt_option: /* empty */ {} - | OPTION {} - ; + | OPTION {}; option_value_list: option_type option_value - | option_value_list ',' option_type option_value - ; + | option_value_list ',' option_type option_value; option_type: /* empty */ {} @@ -4110,8 +3915,7 @@ internal_variable_name: YYABORT; $$=tmp; } - ; - + ; isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } @@ -4133,7 +3937,8 @@ text_or_password: $$=buff; } } - ; + ; + set_expr_or_default: expr { $$=$1; } @@ -4150,18 +3955,15 @@ lock: { Lex->sql_command=SQLCOM_LOCK_TABLES; } - table_lock_list - ; + table_lock_list; table_or_tables: TABLE_SYM - | TABLES - ; + | TABLES; table_lock_list: table_lock - | table_lock_list ',' table_lock - ; + | table_lock_list ',' table_lock; table_lock: table_ident opt_table_alias lock_option @@ -4263,8 +4065,7 @@ revoke: lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; bzero((char*) &lex->mqh, sizeof(lex->mqh)); } - grant_privileges ON opt_table FROM user_list - ; + grant_privileges ON opt_table FROM user_list; grant: GRANT @@ -4280,8 +4081,7 @@ grant: bzero(&(lex->mqh),sizeof(lex->mqh)); } grant_privileges ON opt_table TO_SYM user_list - require_clause grant_options - ; + require_clause grant_options; grant_privileges: grant_privilege_list {} @@ -4291,8 +4091,7 @@ grant_privileges: grant_privilege_list: grant_privilege - | grant_privilege_list ',' grant_privilege - ; + | grant_privilege_list ',' grant_privilege; grant_privilege: SELECT_SYM { Lex->which_columns = SELECT_ACL;} opt_column_list @@ -4319,6 +4118,7 @@ grant_privilege: | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;} ; + opt_and: /* empty */ {} | AND {} @@ -4407,7 +4207,8 @@ opt_table: if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; } - ; + ; + user_list: grant_user { if (Lex->users_list.push_back($1)) YYABORT;} @@ -4418,6 +4219,7 @@ user_list: } ; + grant_user: user IDENTIFIED_SYM BY TEXT_STRING { @@ -4446,13 +4248,11 @@ opt_column_list: LEX *lex=Lex; lex->grant |= lex->which_columns; } - | '(' column_list ')' - ; + | '(' column_list ')'; column_list: column_list ',' column_list_id - | column_list_id - ; + | column_list_id; column_list_id: ident @@ -4493,13 +4293,11 @@ require_clause: /* empty */ { Lex->ssl_type=SSL_TYPE_NONE; } - ; - + ; grant_options: /* empty */ {} - | WITH grant_option_list - ; + | WITH grant_option_list; grant_option_list: grant_option_list grant_option {} @@ -4526,8 +4324,7 @@ grant_option: ; begin: - BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work - ; + BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work; opt_work: /* empty */ {} @@ -4535,12 +4332,10 @@ opt_work: ; commit: - COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT; } - ; + COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}; rollback: - ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK; } - ; + ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;}; /* @@ -4605,16 +4400,14 @@ optional_order_or_limit: union_option: /* empty */ {} - | ALL {Select->master_unit()->union_option= 1;} - ; + | ALL {Select->master_unit()->union_option= 1;}; singleval_subselect: subselect_start singleval_subselect_init subselect_end { $$= $2; - } - ; + }; singleval_subselect_init: select_init2 @@ -4622,16 +4415,14 @@ singleval_subselect_init: $$= new Item_singleval_subselect(YYTHD, Lex->current_select->master_unit()-> first_select()); - } - ; + }; exists_subselect: subselect_start exists_subselect_init subselect_end { $$= $2; - } - ; + }; exists_subselect_init: select_init2 @@ -4659,13 +4450,11 @@ subselect_start: { if (mysql_new_select(Lex, 1)) YYABORT; - } - ; + }; subselect_end: ')' { LEX *lex=Lex; lex->current_select = lex->current_select->outer_select(); - } - ; + }; From aae07a4d45989b1b2a57ee01002e4a101511b512 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 8 Dec 2002 19:59:22 +0100 Subject: [PATCH 07/83] Simplistic, experimental framework for Stored Procedures (SPs). Implements creation and dropping of PROCEDUREs, IN, OUT, and INOUT parameters, single-statement procedures, rudimentary multi-statement (begin-end) prodedures (when the client can handle it), and local variables. Missing most of the embedded SQL language, all attributes, FUNCTIONs, error handling, reparses procedures at each call (no caching), etc, etc. Certainly buggy too, but procedures can actually be created and called.... --- sql/Makefile.am | 6 +- sql/item.cc | 19 +++ sql/item.h | 53 +++++++ sql/lex.h | 6 + sql/sp_head.cc | 384 +++++++++++++++++++++++++++++++++++++++++++++ sql/sp_head.h | 200 +++++++++++++++++++++++ sql/sp_pcontext.cc | 91 +++++++++++ sql/sp_pcontext.h | 127 +++++++++++++++ sql/sp_rcontext.h | 82 ++++++++++ sql/sql_class.cc | 2 +- sql/sql_class.h | 2 + sql/sql_lex.cc | 3 + sql/sql_lex.h | 8 + sql/sql_parse.cc | 80 ++++++++++ sql/sql_yacc.yy | 249 ++++++++++++++++++++++++++++- 15 files changed, 1302 insertions(+), 10 deletions(-) create mode 100644 sql/sp_head.cc create mode 100644 sql/sp_head.h create mode 100644 sql/sp_pcontext.cc create mode 100644 sql/sp_pcontext.h create mode 100644 sql/sp_rcontext.h diff --git a/sql/Makefile.am b/sql/Makefile.am index c5af51e8397..1cdfc05ffdc 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -57,7 +57,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ lex.h lex_symbol.h sql_acl.h sql_crypt.h \ log_event.h mini_client.h sql_repl.h slave.h \ stacktrace.h sql_sort.h sql_cache.h set_var.h \ - spatial.h gstream.h + spatial.h gstream.h sp_head.h sp_pcontext.h \ + sp_rcontext.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ @@ -85,7 +86,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ slave.cc sql_repl.cc sql_union.cc sql_derived.cc \ mini_client.cc mini_client_errors.c \ stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc\ - gstream.cc spatial.cc sql_help.cc + gstream.cc spatial.cc sql_help.cc \ + sp_head.cc sp_pcontext.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/item.cc b/sql/item.cc index f21cd0fc0f3..867b7f2174e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -22,6 +22,7 @@ #include "mysql_priv.h" #include #include "my_dir.h" +#include "sp_rcontext.h" /***************************************************************************** ** Item functions @@ -147,6 +148,24 @@ CHARSET_INFO * Item::thd_charset() const return current_thd->thd_charset; } + +Item * +Item_splocal::this_item() +{ + THD *thd= current_thd; + + return thd->spcont->get_item(m_offset); +} + +Item * +Item_splocal::this_const_item() const +{ + THD *thd= current_thd; + + return thd->spcont->get_item(m_offset); +} + + Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) { set_field(f); diff --git a/sql/item.h b/sql/item.h index a189789ba24..bffb9212e3d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -94,6 +94,8 @@ public: CHARSET_INFO *thd_charset() const; CHARSET_INFO *charset() const { return str_value.charset(); }; void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); } + virtual Item *this_item() { return this; } /* For SPs mostly. */ + virtual Item *this_const_item() const { return const_cast(this); } /* For SPs mostly. */ // Row emulation virtual uint cols() { return 1; } @@ -103,6 +105,57 @@ public: }; +// A local SP variable (incl. parameters), used in runtime +class Item_splocal : public Item +{ +private: + + uint m_offset; + +public: + + Item_splocal(uint offset) + : m_offset(offset) + {} + + Item *this_item(); + Item *this_const_item() const; + + inline uint get_offset() + { + return m_offset; + } + + // Abstract methods inherited from Item. Just defer the call to + // the item in the frame + inline enum Type type() const + { + return this_const_item()->type(); + } + + inline double val() + { + return this_item()->val(); + } + + inline longlong val_int() + { + return this_item()->val_int(); + } + + inline String *val_str(String *sp) + { + return this_item()->val_str(sp); + } + + inline void make_field(Send_field *field) + { + this_item()->make_field(field); + } + +}; + + /* Wrapper base class */ diff --git a/sql/lex.h b/sql/lex.h index eb03c0b36ec..bce68540b55 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -79,6 +79,7 @@ static SYMBOL symbols[] = { { "BY", SYM(BY),0,0}, { "BYTE", SYM(BYTE_SYM), 0, 0}, { "CACHE", SYM(CACHE_SYM),0,0}, + { "CALL", SYM(CALL_SYM),0,0}, { "CASCADE", SYM(CASCADE),0,0}, { "CASE", SYM(CASE_SYM),0,0}, { "CHAR", SYM(CHAR_SYM),0,0}, @@ -117,6 +118,7 @@ static SYMBOL symbols[] = { { "DAY_SECOND", SYM(DAY_SECOND_SYM),0,0}, { "DEC", SYM(DECIMAL_SYM),0,0}, { "DECIMAL", SYM(DECIMAL_SYM),0,0}, + { "DECLARE", SYM(DECLARE_SYM),0,0}, { "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0}, { "DEFAULT", SYM(DEFAULT),0,0}, { "DELAYED", SYM(DELAYED_SYM),0,0}, @@ -193,6 +195,7 @@ static SYMBOL symbols[] = { { "INNER", SYM(INNER_SYM),0,0}, { "INNOBASE", SYM(INNOBASE_SYM),0,0}, { "INNODB", SYM(INNOBASE_SYM),0,0}, + { "INOUT", SYM(INOUT_SYM),0,0}, { "INSERT", SYM(INSERT),0,0}, { "INSERT_METHOD", SYM(INSERT_METHOD),0,0}, { "INT", SYM(INT_SYM),0,0}, @@ -279,6 +282,7 @@ static SYMBOL symbols[] = { { "OPTIONALLY", SYM(OPTIONALLY),0,0}, { "OR", SYM(OR),0,0}, { "ORDER", SYM(ORDER_SYM),0,0}, + { "OUT", SYM(OUT_SYM),0,0}, { "OUTER", SYM(OUTER),0,0}, { "OUTFILE", SYM(OUTFILE),0,0}, { "PACK_KEYS", SYM(PACK_KEYS_SYM),0,0}, @@ -337,6 +341,8 @@ static SYMBOL symbols[] = { { "SOME", SYM(ANY_SYM),0,0}, { "SONAME", SYM(UDF_SONAME_SYM),0,0}, { "SPATIAL", SYM(SPATIAL_SYM),0,0}, + { "SPECIFIC", SYM(SPECIFIC_SYM),0,0}, + { "SPSET", SYM(SPSET_SYM),0,0}, { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0}, { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0}, { "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0}, diff --git a/sql/sp_head.cc b/sql/sp_head.cc new file mode 100644 index 00000000000..fcf3652095d --- /dev/null +++ b/sql/sp_head.cc @@ -0,0 +1,384 @@ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include "mysql_priv.h" +#include "sp_head.h" +#include "sp_pcontext.h" +#include "sp_rcontext.h" + +/* Evaluate a (presumed) func item. Always returns an item, the parameter +** if nothing else. +*/ +static Item * +eval_func_item(Item *it, enum enum_field_types type) +{ + it= it->this_item(); + + /* QQ Which way do we do this? Or is there some even better way? */ +#if 1 + /* QQ Obey the declared type of the variable */ + switch (type) + { + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_INT24: + it= new Item_int(it->val_int()); + break; + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + it= new Item_real(it->val()); + break; + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_NEWDATE: + { + char buffer[MAX_FIELD_WIDTH]; + String tmp(buffer, sizeof(buffer), default_charset_info); + + (void)it->val_str(&tmp); + it= new Item_string(buffer, sizeof(buffer), default_charset_info); + break; + } + case MYSQL_TYPE_NULL: + it= new Item_null(); // A NULL is a NULL is a NULL... + break; + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_GEOMETRY: + /* QQ Don't know what to do with the rest. */ + break; + } +#else + /* QQ This looks simpler, but is wrong? It disregards the variable's type. */ + switch (it->result_type()) + { + case REAL_RESULT: + it= new Item_real(it->val()); + break; + case INT_RESULT: + it= new Item_int(it->val_int()); + break; + case STRING_RESULT: + { + char buffer[MAX_FIELD_WIDTH]; + String tmp(buffer, sizeof(buffer), default_charset_info); + + (void)it->val_str(&tmp); + it= new Item_string(buffer, sizeof(buffer), default_charset_info); + break; + } + default: + /* QQ Don't know what to do with the rest. */ + break; + } +#endif + return it; +} + +sp_head::sp_head(LEX_STRING *name, LEX *lex) +{ + const char *dstr = (const char*)lex->buf; + + m_mylex= lex; + m_name= new Item_string(name->str, name->length, default_charset_info); + m_defstr= new Item_string(dstr, lex->end_of_query - lex->buf, + default_charset_info); + my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); +} + +int +sp_head::create(THD *thd) +{ + String *name= m_name->const_string(); + String *def= m_defstr->const_string(); + + return sp_create_procedure(thd, + name->c_ptr(), name->length(), + def->c_ptr(), def->length()); +} + +int +sp_head::execute(THD *thd) +{ + int ret= 0; + sp_instr *p; + sp_pcontext *pctx = m_mylex->spcont; + uint csize = pctx->max_framesize(); + uint params = pctx->params(); + sp_rcontext *octx = thd->spcont; + sp_rcontext *nctx = NULL; + + if (csize > 0) + { + uint i; + List_iterator_fast li(m_mylex->value_list); + Item *it = li++; // Skip first one, it's the procedure name + + nctx = new sp_rcontext(csize); + // QQ: No error checking whatsoever right now + for (i = 0 ; (it= li++) && i < params ; i++) + { + sp_pvar_t *pvar = pctx->find_pvar(i); + + // QQ Passing an argument is, in a sense, a "SET". We have to evaluate + // any expression at this point. + nctx->push_item(it->this_item()); + // Note: If it's OUT or INOUT, it must be a variable. + // QQ: Need to handle "global" user/host variables too!!! + if (!pvar || pvar->mode == sp_param_in) + nctx->set_oindex(i, -1); + else + nctx->set_oindex(i, static_cast(it)->get_offset()); + } + // The rest of the frame are local variables which are all IN. + // QQ We haven't found any hint of what the value is when unassigned, + // so we set it to NULL for now. It's an error to refer to an + // unassigned variable (which should be detected by the parser). + for (; i < csize ; i++) + nctx->push_item(NULL); + thd->spcont= nctx; + } + + { // Execute instructions... + uint ip= 0; + my_bool nsok= thd->net.no_send_ok; + + thd->net.no_send_ok= TRUE; // Don't send_ok() during execution + + while (ret == 0) + { + int offset; + sp_instr *i; + + i = get_instr(ip); // Returns NULL when we're done. + if (i == NULL) + break; + ret= i->execute(thd, &offset); + ip += offset; + } + + thd->net.no_send_ok= nsok; + } + + // Don't copy back OUT values if we got an error + if (ret == 0 && csize > 0) + { + // Copy back all OUT or INOUT values to the previous frame + for (uint i = 0 ; i < params ; i++) + { + int oi = nctx->get_oindex(i); + + if (oi >= 0) + octx->set_item(nctx->get_oindex(i), nctx->get_item(i)); + } + + thd->spcont= octx; + } + + return ret; +} + + +void +sp_head::reset_lex(THD *thd) +{ + memcpy(&m_lex, &thd->lex, sizeof(LEX)); // Save old one + /* Reset most stuff. The length arguments doesn't matter here. */ + lex_start(thd, m_lex.buf, m_lex.end_of_query - m_lex.ptr); + /* We must reset ptr and end_of_query again */ + thd->lex.ptr= m_lex.ptr; + thd->lex.end_of_query= m_lex.end_of_query; + /* And keep the SP stuff too */ + thd->lex.sphead = m_lex.sphead; + thd->lex.spcont = m_lex.spcont; + /* QQ Why isn't this reset by lex_start() ??? */ + thd->lex.col_list.empty(); + thd->lex.ref_list.empty(); + thd->lex.drop_list.empty(); + thd->lex.alter_list.empty(); + thd->lex.interval_list.empty(); + thd->lex.users_list.empty(); + thd->lex.columns.empty(); + thd->lex.key_list.empty(); + thd->lex.create_list.empty(); + thd->lex.insert_list= NULL; + thd->lex.field_list.empty(); + thd->lex.value_list.empty(); + thd->lex.many_values.empty(); + thd->lex.var_list.empty(); + thd->lex.param_list.empty(); + thd->lex.proc_list.empty(); + thd->lex.auxilliary_table_list.empty(); +} + +void +sp_head::restore_lex(THD *thd) +{ + // Update some state in the old one first + m_lex.ptr= thd->lex.ptr; + m_lex.next_state= thd->lex.next_state; + // QQ Append tables, fields, etc. from the current lex to mine + memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex +} + +// Finds the SP 'name'. Currently this always reads from the database +// and prepares (parse) it, but in the future it will first look in +// the in-memory cache for SPs. (And store newly prepared SPs there of +// course.) +sp_head * +sp_find(THD *thd, Item_string *iname) +{ + extern int yyparse(void *thd); + LEX *tmplex; + TABLE *table; + TABLE_LIST tables; + const char *defstr; + String *name; + sp_head *sp = NULL; + + name = iname->const_string(); + memset(&tables, 0, sizeof(tables)); + tables.db= (char*)"mysql"; + tables.real_name= tables.alias= (char*)"proc"; + if (! (table= open_ltable(thd, &tables, TL_READ))) + return NULL; + + if (table->file->index_read_idx(table->record[0], 0, + (byte*)name->c_ptr(), name->length(), + HA_READ_KEY_EXACT)) + goto done; + + if ((defstr= get_field(&thd->mem_root, table, 1)) == NULL) + goto done; + + // QQ Set up our own mem_root here??? + tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); + if (yyparse(thd) || thd->fatal_error || tmplex->sphead == NULL) + goto done; // Error + else + sp = tmplex->sphead; + + done: + if (table) + close_thread_tables(thd); + return sp; +} + +int +sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) +{ + int ret= 0; + TABLE *table; + TABLE_LIST tables; + + memset(&tables, 0, sizeof(tables)); + tables.db= (char*)"mysql"; + tables.real_name= tables.alias= (char*)"proc"; + /* Allow creation of procedures even if we can't open proc table */ + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + { + ret= -1; + goto done; + } + + restore_record(table, 2); // Get default values for fields + + table->field[0]->store(name, namelen, default_charset_info); + table->field[1]->store(def, deflen, default_charset_info); + + ret= table->file->write_row(table->record[0]); + + done: + close_thread_tables(thd); + return ret; +} + +int +sp_drop(THD *thd, char *name, uint namelen) +{ + TABLE *table; + TABLE_LIST tables; + + tables.db= (char *)"mysql"; + tables.real_name= tables.alias= (char *)"proc"; + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + goto err; + if (! table->file->index_read_idx(table->record[0], 0, + (byte *)name, namelen, + HA_READ_KEY_EXACT)) + { + int error; + + if ((error= table->file->delete_row(table->record[0]))) + table->file->print_error(error, MYF(0)); + } + close_thread_tables(thd); + return 0; + + err: + close_thread_tables(thd); + return -1; +} + + + +// +// sp_instr_stmt +// +int +sp_instr_stmt::execute(THD *thd, int *offsetp) +{ + LEX olex; // The other lex + + memcpy(&olex, &thd->lex, sizeof(LEX)); // Save the other lex + + memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Use my own lex + thd->lex.thd = thd; + + mysql_execute_command(thd); + + memcpy(&thd->lex, &olex, sizeof(LEX)); // Restore the other lex + + *offsetp = 1; + return 0; +} + +// +// sp_instr_set +// +int +sp_instr_set::execute(THD *thd, int *offsetp) +{ + thd->spcont->set_item(m_offset, eval_func_item(m_value, m_type)); + *offsetp = 1; + return 0; +} diff --git a/sql/sp_head.h b/sql/sp_head.h new file mode 100644 index 00000000000..72a5c90b011 --- /dev/null +++ b/sql/sp_head.h @@ -0,0 +1,200 @@ +/* -*- C++ -*- */ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _SP_HEAD_H_ +#define _SP_HEAD_H_ + +#ifdef __GNUC__ +#pragma interface /* gcc class implementation */ +#endif + +#include + +class sp_instr; + +class sp_head : public Sql_alloc +{ + sp_head(const sp_head &); /* Prevent use of these */ + void operator=(sp_head &); + +public: + + static void *operator new(size_t size) + { + return (void*) sql_alloc((uint) size); + } + + static void operator delete(void *ptr, size_t size) + { + /* Empty */ + } + + sp_head(LEX_STRING *name, LEX* lex); + + int + create(THD *thd); + + int + execute(THD *thd); + + inline void + add_instr(sp_instr *i) + { + insert_dynamic(&m_instr, (gptr)&i); + } + + inline uint + instructions() + { + return m_instr.elements; + } + + // Resets lex in 'thd' and keeps a copy of the old one. + void + reset_lex(THD *thd); + + // Restores lex in 'thd' from our copy, but keeps some status from the + // one in 'thd', like ptr, tables, fields, etc. + void + restore_lex(THD *thd); + +private: + + Item_string *m_name; + Item_string *m_defstr; + LEX *m_mylex; // My own lex + LEX m_lex; // Temp. store for the other lex + DYNAMIC_ARRAY m_instr; // The "instructions" + + inline sp_instr * + get_instr(uint i) + { + sp_instr *in= NULL; + + get_dynamic(&m_instr, (gptr)&in, i); + return in; + } + +}; // class sp_head : public Sql_alloc + + +// +// Find a stored procedure given its name. Returns NULL if not +// found. +// +sp_head * +sp_find(THD *thd, Item_string *name); + +int +sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen); + +int +sp_drop(THD *thd, char *name, uint namelen); + + +class sp_instr : public Sql_alloc +{ + sp_instr(const sp_instr &); /* Prevent use of these */ + void operator=(sp_instr &); + +public: + + // Should give each a name or type code for debugging purposes? + sp_instr() + : Sql_alloc() + {} + + virtual ~sp_instr() + {} + + // Execute this instrution. '*offsetp' will be set to an offset to the + // next instruction to execute. (For most instruction this will be 1, + // i.e. the following instruction.) + // Returns 0 on success, non-zero if some error occured. + virtual int + execute(THD *thd, int *offsetp) + { // Default is a no-op. + *offsetp = 1; // Next instruction + return 0; + } + +}; // class sp_instr : public Sql_alloc + + +// +// Call out to some prepared SQL statement. +// +class sp_instr_stmt : public sp_instr +{ + sp_instr_stmt(const sp_instr_stmt &); /* Prevent use of these */ + void operator=(sp_instr_stmt &); + +public: + + sp_instr_stmt() + : sp_instr() + {} + + virtual ~sp_instr_stmt() + {} + + virtual int execute(THD *thd, int *offsetp); + + inline void + set_lex(LEX *lex) + { + memcpy(&m_lex, lex, sizeof(LEX)); + } + + inline LEX * + get_lex() + { + return &m_lex; + } + +private: + + LEX m_lex; // My own lex + +}; // class sp_instr_stmt : public sp_instr + + +class sp_instr_set : public sp_instr +{ + sp_instr_set(const sp_instr_set &); /* Prevent use of these */ + void operator=(sp_instr_set &); + +public: + + sp_instr_set(uint offset, Item *val, enum enum_field_types type) + : sp_instr(), m_offset(offset), m_value(val), m_type(type) + {} + + virtual ~sp_instr_set() + {} + + virtual int execute(THD *thd, int *offsetp); + +private: + + uint m_offset; + Item *m_value; + enum enum_field_types m_type; // The declared type + +}; // class sp_instr_set : public sp_instr + +#endif /* _SP_HEAD_H_ */ diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc new file mode 100644 index 00000000000..d2ab8cb93ac --- /dev/null +++ b/sql/sp_pcontext.cc @@ -0,0 +1,91 @@ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef __GNUC__ +#pragma implementation +#endif + +#if defined(WIN32) || defined(__WIN__) +#undef SAFEMALLOC /* Problems with threads */ +#endif + +#include "mysql_priv.h" +#include "sp_pcontext.h" + +sp_pcontext::sp_pcontext() + : m_params(0), m_framesize(0), m_i(0) +{ + m_pvar_size = 16; + m_pvar = (sp_pvar_t *)my_malloc(m_pvar_size * sizeof(sp_pvar_t), MYF(MY_WME)); + if (m_pvar) + memset(m_pvar, 0, m_pvar_size * sizeof(sp_pvar_t)); +} + +void +sp_pcontext::grow() +{ + uint sz = m_pvar_size + 8; + sp_pvar_t *a = (sp_pvar_t *)my_realloc((char *)m_pvar, + sz * sizeof(sp_pvar_t), + MYF(MY_WME | MY_ALLOW_ZERO_PTR)); + + if (a) + { + m_pvar_size = sz; + m_pvar = a; + } +} + +/* This does a linear search (from newer to older variables, in case +** we have shadowed names). +** It's possible to have a more efficient allocation and search method, +** but it might not be worth it. The typical number of parameters and +** variables will in most cases be low (a handfull). +** And this is only called during parsing. +*/ +sp_pvar_t * +sp_pcontext::find_pvar(LEX_STRING *name) +{ + String n(name->str, name->length, default_charset_info); + uint i = m_i; + + while (i-- > 0) + { + if (stringcmp(&n, m_pvar[i].name->const_string()) == 0) + return m_pvar + i; + } + return NULL; +} + +void +sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, + sp_param_mode_t mode) +{ + if (m_i >= m_pvar_size) + grow(); + if (m_i < m_pvar_size) + { + if (m_i == m_framesize) + m_framesize += 1; + m_pvar[m_i].name= new Item_string(name->str, name->length, + default_charset_info); + m_pvar[m_i].type= type; + m_pvar[m_i].mode= mode; + m_pvar[m_i].offset= m_i; + m_pvar[m_i].isset= (mode == sp_param_out ? FALSE : TRUE); + m_i += 1; + } +} diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h new file mode 100644 index 00000000000..956b8d99d4d --- /dev/null +++ b/sql/sp_pcontext.h @@ -0,0 +1,127 @@ +/* -*- C++ -*- */ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _SP_PCONTEXT_H_ +#define _SP_PCONTEXT_H_ + +#ifdef __GNUC__ +#pragma interface /* gcc class implementation */ +#endif + +typedef enum +{ + sp_param_in, + sp_param_out, + sp_param_inout +} sp_param_mode_t; + +typedef struct +{ + Item_string *name; + enum enum_field_types type; + sp_param_mode_t mode; + uint offset; // Offset in current frame + my_bool isset; +} sp_pvar_t; + +class sp_pcontext : public Sql_alloc +{ + sp_pcontext(const sp_pcontext &); /* Prevent use of these */ + void operator=(sp_pcontext &); + + public: + + sp_pcontext(); + + inline uint + max_framesize() + { + return m_framesize; + } + + inline uint + current_framesize() + { + return m_i; + } + + inline uint + params() + { + return m_params; + } + + // Set the number of parameters to the current esize + inline void + set_params() + { + m_params= m_i; + } + + inline void + set_type(uint i, enum enum_field_types type) + { + if (i < m_i) + m_pvar[i].type= type; + } + + inline void + set_isset(uint i, my_bool val) + { + if (i < m_i) + m_pvar[i].isset= val; + } + + void + push(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode); + + inline void + pop(uint num = 1) + { + if (num >= m_i) + m_i -= num; + } + + // Find by name + sp_pvar_t * + find_pvar(LEX_STRING *name); + + // Find by index + sp_pvar_t * + find_pvar(uint i) + { + if (i >= m_i) + return NULL; + return m_pvar+i; + } + +private: + + uint m_params; // The number of parameters + uint m_framesize; // The maximum framesize + uint m_i; // The current index (during parsing) + + sp_pvar_t *m_pvar; + uint m_pvar_size; // Current size of m_pvar. + + void + grow(); + +}; // class sp_pcontext : public Sql_alloc + + +#endif /* _SP_PCONTEXT_H_ */ diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h new file mode 100644 index 00000000000..5ffbb0266e6 --- /dev/null +++ b/sql/sp_rcontext.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _SP_RCONTEXT_H_ +#define _SP_RCONTEXT_H_ + +class sp_rcontext : public Sql_alloc +{ + sp_rcontext(const sp_rcontext &); /* Prevent use of these */ + void operator=(sp_rcontext &); + + public: + + sp_rcontext(uint size) + : m_count(0), m_size(size) + { + m_frame = (Item **)sql_alloc(size * sizeof(Item*)); + m_outs = (int *)sql_alloc(size * sizeof(int)); + } + + ~sp_rcontext() + { + // Not needed? + //sql_element_free(m_frame); + } + + inline void + push_item(Item *i) + { + if (m_count < m_size) + m_frame[m_count++] = i; + } + + inline void + set_item(uint idx, Item *i) + { + if (idx < m_count) + m_frame[idx] = i; + } + + inline Item * + get_item(uint idx) + { + return m_frame[idx]; + } + + inline void + set_oindex(uint idx, int oidx) + { + m_outs[idx] = oidx; + } + + inline int + get_oindex(uint idx) + { + return m_outs[idx]; + } + +private: + + uint m_count; + uint m_size; + Item **m_frame; + int *m_outs; + +}; // class sp_rcontext : public Sql_alloc + +#endif /* _SP_RCONTEXT_H_ */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ebd1d9d2b3c..855c97715ea 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -81,7 +81,7 @@ extern "C" void free_user_var(user_var_entry *entry) THD::THD():user_time(0), fatal_error(0), last_insert_id_used(0), insert_id_used(0), rand_used(0), in_lock_tables(0), - global_read_lock(0), bootstrap(0) + global_read_lock(0), bootstrap(0), spcont(NULL) { host=user=priv_user=db=query=ip=0; host_or_ip="unknown ip"; diff --git a/sql/sql_class.h b/sql/sql_class.h index ca56d2dcdf5..00236aee176 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -26,6 +26,7 @@ class Query_log_event; class Load_log_event; class Slave_log_event; +class sp_rcontext; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY }; @@ -515,6 +516,7 @@ public: bool query_error, bootstrap, cleanup_done; bool volatile killed; bool prepare_command; + sp_rcontext *spcont; // SP runtime context /* If we do a purge of binary logs, log index info of the threads diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 833f36dbe9f..d40d968225f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -155,6 +155,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) { LEX *lex= &thd->lex; lex->next_state=STATE_START; + lex->buf= buf; lex->end_of_query=(lex->ptr=buf)+length; lex->yylineno = 1; lex->select_lex.create_refs=lex->in_comment=0; @@ -170,6 +171,8 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->slave_thd_opt=0; lex->sql_command=SQLCOM_END; lex->safe_to_cache_query= 1; + lex->sphead= NULL; + lex->spcont= NULL; bzero(&lex->mi,sizeof(lex->mi)); return lex; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0c761baffa3..467ff26d5ab 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -21,6 +21,9 @@ class Table_ident; class sql_exchange; class LEX_COLUMN; +class sp_head; +class sp_instr; +class sp_pcontext; /* The following hack is needed because mysql_yacc.cc does not define @@ -72,6 +75,8 @@ enum enum_sql_command { SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, SQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_TABLE_TYPES, SQLCOM_SHOW_PRIVILEGES, SQLCOM_HELP, + SQLCOM_CREATE_PROCEDURE, SQLCOM_CALL, SQLCOM_DROP_PROCEDURE, + SQLCOM_ALTER_PROCEDURE, /* This should be the last !!! */ SQLCOM_END @@ -402,6 +407,7 @@ typedef struct st_lex SELECT_LEX_NODE *current_select; /* list of all SELECT_LEX */ SELECT_LEX *all_selects_list; + uchar *buf; /* The beginning of string, used by SPs */ uchar *ptr,*tok_start,*tok_end,*end_of_query; char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ @@ -459,6 +465,8 @@ typedef struct st_lex uint slave_thd_opt; CHARSET_INFO *charset; char *help_arg; + sp_head *sphead; + sp_pcontext *spcont; } LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 660fd545bb6..fba726c95b6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -27,6 +27,8 @@ #include "ha_innodb.h" #endif +#include "sp_head.h" + #ifdef HAVE_OPENSSL /* Without SSL the handshake consists of one packet. This packet @@ -2739,6 +2741,84 @@ mysql_execute_command(THD *thd) res= -1; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; + case SQLCOM_CREATE_PROCEDURE: + if (!lex->sphead) + res= -1; + else + { + res= lex->sphead->create(thd); + if (res < 0) + { + // QQ Error! + } + send_ok(thd); + } + break; + case SQLCOM_CALL: + { + Item_string *s; + sp_head *sp; + + s= (Item_string*)lex->value_list.head(); + sp= sp_find(thd, s); + if (! sp) + { + // QQ Error! + res= -1; + } + else + { + res= sp->execute(thd); + if (res == 0) + send_ok(thd); + } + } + break; + case SQLCOM_ALTER_PROCEDURE: + { + Item_string *s; + sp_head *sp; + + s= (Item_string*)lex->value_list.head(); + sp= sp_find(thd, s); + if (! sp) + { + // QQ Error! + res= -1; + } + else + { + /* QQ This is an no-op right now, since we haven't + put the characteristics in yet. */ + send_ok(thd); + } + } + break; + case SQLCOM_DROP_PROCEDURE: + { + Item_string *s; + sp_head *sp; + + s = (Item_string*)lex->value_list.head(); + sp = sp_find(thd, s); + if (! sp) + { + // QQ Error! + res= -1; + } + else + { + String *name = s->const_string(); + + res= sp_drop(thd, name->c_ptr(), name->length()); + if (res < 0) + { + // QQ Error! + } + send_ok(thd); + } + } + break; default: /* Impossible */ send_ok(thd); break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ed8e8f0fb51..33f928f2efe 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -35,6 +35,8 @@ #include "sql_acl.h" #include "lex_symbol.h" #include "item_create.h" +#include "sp_head.h" +#include "sp_pcontext.h" #include #include @@ -120,6 +122,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token AVG_SYM %token BEGIN_SYM %token BINLOG_SYM +%token CALL_SYM %token CHANGE %token CLIENT_SYM %token COMMENT_SYM @@ -198,6 +201,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CONVERT_SYM %token DATABASES %token DATA_SYM +%token DECLARE_SYM %token DEFAULT %token DELAYED_SYM %token DELAY_KEY_WRITE_SYM @@ -242,6 +246,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token INFILE %token INNER_SYM %token INNOBASE_SYM +%token INOUT_SYM %token INTO %token IN_SYM %token ISOLATION @@ -256,6 +261,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token LIKE %token LINES %token LOCAL_SYM +%token LOCATOR_SYM %token LOG_SYM %token LOGS_SYM %token LONG_NUM @@ -296,6 +302,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token OR %token OR_OR_CONCAT %token ORDER_SYM +%token OUT_SYM %token OUTER %token OUTFILE %token DUMPFILE @@ -334,6 +341,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SIMPLE_SYM %token SHUTDOWN %token SPATIAL_SYM +%token SPECIFIC_SYM %token SSL_SYM %token STARTING %token STATUS_SYM @@ -518,6 +526,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SQL_SMALL_RESULT %token SQL_BUFFER_RESULT +/* QQ This is a dummy, until we have solved the SET syntax problem. */ +%token SPSET_SYM + %token ISSUER_SYM %token SUBJECT_SYM %token CIPHER_SYM @@ -666,8 +677,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); union_clause union_list union_option precision subselect_start opt_and subselect_end select_var_list select_var_list_init help opt_len + statement END_OF_INPUT +%type call sp_proc_body sp_proc_stmts sp_proc_stmt +%type sp_decls sp_decl sp_decl_idents sp_opt_inout + %type '-' '+' '*' '/' '%' '(' ')' ',' '!' '{' '}' '&' '|' AND OR OR_OR_CONCAT BETWEEN_SYM CASE_SYM @@ -693,10 +708,16 @@ query: | verb_clause END_OF_INPUT {}; verb_clause: + statement + | begin + ; + +/* Verb clauses, except begin */ +statement: alter | analyze | backup - | begin + | call | change | check | commit @@ -874,7 +895,177 @@ create: lex->udf.returns=(Item_result) $7; lex->udf.dl=$9.str; } - ; + | CREATE PROCEDURE ident + { + LEX *lex= Lex; + + lex->spcont = new sp_pcontext(); + lex->sphead = new sp_head(&$3, lex); + } + '(' sp_dparam_list ')' + { + Lex->spcont->set_params(); + } + sp_proc_body + { + Lex->sql_command= SQLCOM_CREATE_PROCEDURE; + } + ; + +call: + CALL_SYM ident + { + LEX *lex = Lex; + + lex->sql_command= SQLCOM_CALL; + lex->value_list.empty(); + lex->value_list.push_back( + (Item*)new Item_string($2.str, $2.length, default_charset_info)); + } + '(' sp_cparam_list ')' {} + ; + +/* CALL parameters */ +sp_cparam_list: + /* Empty */ + | sp_cparams + ; + +sp_cparams: + sp_cparams ',' expr + { + Lex->value_list.push_back($3); + } + | expr + { + Lex->value_list.push_back($1); + } + ; + +/* SP parameter declaration list */ +sp_dparam_list: + /* Empty */ + | sp_dparams + ; + +sp_dparams: + sp_dparams ',' sp_dparam + | sp_dparam + ; + +sp_dparam: + sp_opt_inout ident type sp_opt_locator + { + Lex->spcont->push(&$2, + (enum enum_field_types)$3, + (sp_param_mode_t)$1); + } + ; + +sp_opt_inout: + /* Empty */ { $$= sp_param_in; } + | IN_SYM { $$= sp_param_in; } + | OUT_SYM { $$= sp_param_out; } + | INOUT_SYM { $$= sp_param_inout; } + ; + +sp_opt_locator: + /* Empty */ + | AS LOCATOR_SYM + ; + +sp_proc_body: + { + Lex->sphead->reset_lex(YYTHD); + } + sp_proc_stmt + { + Lex->sphead->restore_lex(YYTHD); + } + | begin + sp_decls + sp_proc_stmts + END + { + Lex->spcont->pop($2); + } + ; + +sp_proc_stmts: + sp_proc_body ';' + | sp_proc_stmts sp_proc_body ';' + ; + +sp_decls: + /* Empty */ + { + $$= 0; + } + | sp_decls sp_decl ';' + { + $$= $1 + $2; + } + ; + +sp_decl: + DECLARE_SYM sp_decl_idents type + { + LEX *lex= Lex; + uint max= lex->spcont->current_framesize(); + + for (uint i = max-$2 ; i < max ; i++) + { + lex->spcont->set_type(i, (enum enum_field_types)$3); + lex->spcont->set_isset(i, FALSE); + } + $$= $2; + } + ; + +sp_decl_idents: + ident + { + Lex->spcont->push(&$1, (enum_field_types)0, sp_param_in); + $$= 1; + } + | sp_decl_idents ',' ident + { + Lex->spcont->push(&$3, (enum_field_types)0, sp_param_in); + $$= $1 + 1; + } + ; + +/* Dummy for the spset thing. Will go away when the SET problem is fixed. */ +sp_proc_stmt: + statement + { + LEX *lex= Lex; + sp_instr_stmt *i= new sp_instr_stmt(); + + i->set_lex(lex); + lex->sphead->add_instr(i); + } + | + /* QQ Dummy. We need to fix the old SET syntax to make it work for + local SP variables as well. */ + SPSET_SYM ident EQ expr + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + if (!spc || !(spv = spc->find_pvar(&$2))) + YYABORT; /* Unknow variable */ + else + { + /* QQ Check type match! */ + sp_instr_set *i = new sp_instr_set(spv->offset, $4, spv->type); + + lex->sphead->add_instr(i); + spv->isset= TRUE; + } + } + ; create2: '(' field_list ')' opt_create_table_options create3 {} @@ -1393,8 +1584,27 @@ alter: lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; lex->create_info.table_charset=$4; - }; + } + | ALTER PROCEDURE opt_specific ident + /* QQ Characteristics missing for now */ + opt_restrict + { + LEX *lex=Lex; + /* This is essensially an no-op right now, since we haven't + put the characteristics in yet. */ + lex->sql_command= SQLCOM_ALTER_PROCEDURE; + lex->value_list.empty(); + lex->value_list.push_back( + (Item*)new Item_string($4.str, $4.length, default_charset_info)); + } + ; + +opt_specific: + /* Empty */ + | + SPECIFIC_SYM + ; alter_list: | alter_list_item @@ -2905,7 +3115,16 @@ drop: LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_FUNCTION; lex->udf.name=$3.str; - }; + } + | DROP PROCEDURE ident opt_restrict + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_DROP_PROCEDURE; + lex->value_list.empty(); + lex->value_list.push_back( + (Item*)new Item_string($3.str, $3.length, default_charset_info)); + } + ; table_list: @@ -2958,7 +3177,6 @@ replace: } insert_field_spec {} - {} ; insert_lock_option: @@ -3642,8 +3860,25 @@ order_ident: simple_ident: ident { - SELECT_LEX_NODE *sel=Select; - $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); + sp_pvar_t *spv; + LEX *lex = Lex; + sp_pcontext *spc = lex->spcont; + + if (spc && (spv = spc->find_pvar(&$1))) + { /* We're compiling a stored procedure and found a variable */ + if (lex->sql_command != SQLCOM_CALL && ! spv->isset) + { + printf("QQ Referring to an unitialized variable\n"); + YYABORT; /* QQ Referring to an unitialized variable */ + } + else + $$ = (Item*) new Item_splocal(spv->offset); + } + else + { + SELECT_LEX_NODE *sel=Select; + $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); + } } | ident '.' ident { From f0137bcd686fbfe51fadb681713f61e0559c84da Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 11 Dec 2002 14:24:29 +0100 Subject: [PATCH 08/83] Fixed bugs in the parameter evaluation and modified the execution engine for better jump support. Some flow control support added too (but not complete). --- sql/lex.h | 10 +++ sql/sp_head.cc | 92 ++++++++++++++++++++++----- sql/sp_head.h | 136 +++++++++++++++++++++++++++++++++++----- sql/sp_pcontext.cc | 42 ++++++++++++- sql/sp_pcontext.h | 25 ++++++++ sql/sql_yacc.yy | 152 ++++++++++++++++++++++++++++++++++++++------- 6 files changed, 402 insertions(+), 55 deletions(-) diff --git a/sql/lex.h b/sql/lex.h index bce68540b55..829c16a3b74 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -59,6 +59,7 @@ static SYMBOL symbols[] = { { "ANY", SYM(ANY_SYM),0,0}, { "AS", SYM(AS),0,0}, { "ASC", SYM(ASC),0,0}, + { "ASENSITIVE", SYM(ASENSITIVE_SYM),0,0}, { "AVG", SYM(AVG_SYM),0,0}, { "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH),0,0}, { "AUTO_INCREMENT", SYM(AUTO_INC),0,0}, @@ -107,6 +108,7 @@ static SYMBOL symbols[] = { { "CURRENT_DATE", SYM(CURDATE),0,0}, { "CURRENT_TIME", SYM(CURTIME),0,0}, { "CURRENT_TIMESTAMP", SYM(NOW_SYM),0,0}, + { "CURSOR", SYM(CURSOR_SYM),0,0}, { "DATA", SYM(DATA_SYM),0,0}, { "DATABASE", SYM(DATABASE),0,0}, { "DATABASES", SYM(DATABASES),0,0}, @@ -141,6 +143,7 @@ static SYMBOL symbols[] = { { "ERRORS", SYM(ERRORS),0,0}, { "END", SYM(END),0,0}, { "ELSE", SYM(ELSE),0,0}, + { "ELSEIF", SYM(ELSEIF_SYM),0,0}, { "ESCAPE", SYM(ESCAPE_SYM),0,0}, { "ESCAPED", SYM(ESCAPED),0,0}, { "ENABLE", SYM(ENABLE_SYM),0,0}, @@ -196,6 +199,7 @@ static SYMBOL symbols[] = { { "INNOBASE", SYM(INNOBASE_SYM),0,0}, { "INNODB", SYM(INNOBASE_SYM),0,0}, { "INOUT", SYM(INOUT_SYM),0,0}, + { "INSENSITIVE", SYM(INSENSITIVE_SYM),0,0}, { "INSERT", SYM(INSERT),0,0}, { "INSERT_METHOD", SYM(INSERT_METHOD),0,0}, { "INT", SYM(INT_SYM),0,0}, @@ -213,12 +217,14 @@ static SYMBOL symbols[] = { { "ISOLATION", SYM(ISOLATION),0,0}, { "ISAM", SYM(ISAM_SYM),0,0}, { "ISSUER", SYM(ISSUER_SYM),0,0}, + { "ITERATE", SYM(ITERATE_SYM),0,0}, { "JOIN", SYM(JOIN_SYM),0,0}, { "KEY", SYM(KEY_SYM),0,0}, { "KEYS", SYM(KEYS),0,0}, { "KILL", SYM(KILL_SYM),0,0}, { "LAST", SYM(LAST_SYM),0,0}, { "LEADING", SYM(LEADING),0,0}, + { "LEAVE", SYM(LEAVE_SYM),0,0}, { "LEFT", SYM(LEFT),0,0}, { "LEVEL", SYM(LEVEL_SYM),0,0}, { "LIKE", SYM(LIKE),0,0}, @@ -233,6 +239,7 @@ static SYMBOL symbols[] = { { "LOGS", SYM(LOGS_SYM),0,0}, { "LONG", SYM(LONG_SYM),0,0}, { "LONGBLOB", SYM(LONGBLOB),0,0}, + { "LOOP", SYM(LOOP_SYM),0,0}, { "LONGTEXT", SYM(LONGTEXT),0,0}, { "LOW_PRIORITY", SYM(LOW_PRIORITY),0,0}, { "MASTER", SYM(MASTER_SYM),0,0}, @@ -313,6 +320,7 @@ static SYMBOL symbols[] = { { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, { "REQUIRE", SYM(REQUIRE_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0}, + { "UNTIL", SYM(UNTIL_SYM),0,0}, { "USER_RESOURCES", SYM(RESOURCES),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTRICT", SYM(RESTRICT),0,0}, @@ -327,6 +335,7 @@ static SYMBOL symbols[] = { { "RTREE", SYM(RTREE_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0}, { "SELECT", SYM(SELECT_SYM),0,0}, + { "SENSITIVE", SYM(SENSITIVE_SYM),0,0}, { "SERIAL", SYM(SERIAL_SYM),0,0}, { "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0}, { "SESSION", SYM(SESSION_SYM),0,0}, @@ -401,6 +410,7 @@ static SYMBOL symbols[] = { { "WRITE", SYM(WRITE_SYM),0,0}, { "WHEN", SYM(WHEN_SYM),0,0}, { "WHERE", SYM(WHERE),0,0}, + { "WHILE", SYM(WHILE_SYM),0,0}, { "XOR", SYM(XOR),0,0}, { "X509", SYM(X509_SYM),0,0}, { "YEAR", SYM(YEAR_SYM),0,0}, diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fcf3652095d..ed93f005db3 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -59,9 +59,9 @@ eval_func_item(Item *it, enum enum_field_types type) { char buffer[MAX_FIELD_WIDTH]; String tmp(buffer, sizeof(buffer), default_charset_info); + String *s= it->val_str(&tmp); - (void)it->val_str(&tmp); - it= new Item_string(buffer, sizeof(buffer), default_charset_info); + it= new Item_string(s->c_ptr_quick(), s->length(), default_charset_info); break; } case MYSQL_TYPE_NULL: @@ -149,15 +149,21 @@ sp_head::execute(THD *thd) { sp_pvar_t *pvar = pctx->find_pvar(i); - // QQ Passing an argument is, in a sense, a "SET". We have to evaluate - // any expression at this point. - nctx->push_item(it->this_item()); - // Note: If it's OUT or INOUT, it must be a variable. - // QQ: Need to handle "global" user/host variables too!!! - if (!pvar || pvar->mode == sp_param_in) - nctx->set_oindex(i, -1); + if (! pvar) + nctx->set_oindex(i, -1); // Shouldn't happen else - nctx->set_oindex(i, static_cast(it)->get_offset()); + { + if (pvar->mode == sp_param_out) + nctx->push_item(it->this_item()); // OUT + else + nctx->push_item(eval_func_item(it, pvar->type)); // IN or INOUT + // Note: If it's OUT or INOUT, it must be a variable. + // QQ: Need to handle "global" user/host variables too!!! + if (pvar->mode == sp_param_in) + nctx->set_oindex(i, -1); // IN + else // OUT or INOUT + nctx->set_oindex(i, static_cast(it)->get_offset()); + } } // The rest of the frame are local variables which are all IN. // QQ We haven't found any hint of what the value is when unassigned, @@ -176,14 +182,12 @@ sp_head::execute(THD *thd) while (ret == 0) { - int offset; sp_instr *i; i = get_instr(ip); // Returns NULL when we're done. if (i == NULL) break; - ret= i->execute(thd, &offset); - ip += offset; + ret= i->execute(thd, &ip); } thd->net.no_send_ok= nsok; @@ -250,6 +254,27 @@ sp_head::restore_lex(THD *thd) memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex } +void +sp_head::push_backpatch(uint ip) +{ + (void)m_backpatch.push_front(&ip); +} + +void +sp_head::backpatch(uint dest) +{ + while (! m_backpatch.is_empty()) + { + uint *ip= m_backpatch.pop(); + sp_instr_jump *i= static_cast(get_instr(*ip)); + + i->set_destination(dest); + } +} + + +// ------------------------------------------------------------------ + // Finds the SP 'name'. Currently this always reads from the database // and prepares (parse) it, but in the future it will first look in // the in-memory cache for SPs. (And store newly prepared SPs there of @@ -350,12 +375,13 @@ sp_drop(THD *thd, char *name, uint namelen) } +// ------------------------------------------------------------------ // // sp_instr_stmt // int -sp_instr_stmt::execute(THD *thd, int *offsetp) +sp_instr_stmt::execute(THD *thd, uint *nextp) { LEX olex; // The other lex @@ -368,7 +394,7 @@ sp_instr_stmt::execute(THD *thd, int *offsetp) memcpy(&thd->lex, &olex, sizeof(LEX)); // Restore the other lex - *offsetp = 1; + *nextp = m_ip+1; return 0; } @@ -376,9 +402,41 @@ sp_instr_stmt::execute(THD *thd, int *offsetp) // sp_instr_set // int -sp_instr_set::execute(THD *thd, int *offsetp) +sp_instr_set::execute(THD *thd, uint *nextp) { thd->spcont->set_item(m_offset, eval_func_item(m_value, m_type)); - *offsetp = 1; + *nextp = m_ip+1; + return 0; +} + +// +// sp_instr_jump_if +// + +int +sp_instr_jump_if::execute(THD *thd, uint *nextp) +{ + Item *it= eval_func_item(m_expr, MYSQL_TYPE_TINY); + + if (it->val_int()) + *nextp = m_dest; + else + *nextp = m_ip+1; + return 0; +} + +// +// sp_instr_jump_if_not +// + +int +sp_instr_jump_if_not::execute(THD *thd, uint *nextp) +{ + Item *it= eval_func_item(m_expr, MYSQL_TYPE_TINY); + + if (! it->val_int()) + *nextp = m_dest; + else + *nextp = m_ip+1; return 0; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 72a5c90b011..53130bffdf1 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -72,6 +72,12 @@ public: void restore_lex(THD *thd); + void + push_backpatch(uint ip); + + void + backpatch(uint dest); + private: Item_string *m_name; @@ -79,6 +85,7 @@ private: LEX *m_mylex; // My own lex LEX m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" + List m_backpatch; // Instructions needing backpaching inline sp_instr * get_instr(uint i) @@ -106,6 +113,10 @@ int sp_drop(THD *thd, char *name, uint namelen); +// +// "Instructions"... +// + class sp_instr : public Sql_alloc { sp_instr(const sp_instr &); /* Prevent use of these */ @@ -114,24 +125,28 @@ class sp_instr : public Sql_alloc public: // Should give each a name or type code for debugging purposes? - sp_instr() - : Sql_alloc() + sp_instr(uint ip) + : Sql_alloc(), m_ip(ip) {} virtual ~sp_instr() {} - // Execute this instrution. '*offsetp' will be set to an offset to the - // next instruction to execute. (For most instruction this will be 1, - // i.e. the following instruction.) + // Execute this instrution. '*nextp' will be set to the index of the next + // instruction to execute. (For most instruction this will be the + // instruction following this one.) // Returns 0 on success, non-zero if some error occured. virtual int - execute(THD *thd, int *offsetp) + execute(THD *thd, uint *nextp) { // Default is a no-op. - *offsetp = 1; // Next instruction + *nextp = m_ip+1; // Next instruction return 0; } +protected: + + uint m_ip; // My index + }; // class sp_instr : public Sql_alloc @@ -145,14 +160,14 @@ class sp_instr_stmt : public sp_instr public: - sp_instr_stmt() - : sp_instr() + sp_instr_stmt(uint ip) + : sp_instr(ip) {} virtual ~sp_instr_stmt() {} - virtual int execute(THD *thd, int *offsetp); + virtual int execute(THD *thd, uint *nextp); inline void set_lex(LEX *lex) @@ -180,21 +195,114 @@ class sp_instr_set : public sp_instr public: - sp_instr_set(uint offset, Item *val, enum enum_field_types type) - : sp_instr(), m_offset(offset), m_value(val), m_type(type) + sp_instr_set(uint ip, uint offset, Item *val, enum enum_field_types type) + : sp_instr(ip), m_offset(offset), m_value(val), m_type(type) {} virtual ~sp_instr_set() {} - virtual int execute(THD *thd, int *offsetp); + virtual int execute(THD *thd, uint *nextp); private: - uint m_offset; + uint m_offset; // Frame offset Item *m_value; enum enum_field_types m_type; // The declared type }; // class sp_instr_set : public sp_instr + +class sp_instr_jump : public sp_instr +{ + sp_instr_jump(const sp_instr_jump &); /* Prevent use of these */ + void operator=(sp_instr_jump &); + +public: + + sp_instr_jump(uint ip) + : sp_instr(ip) + {} + + sp_instr_jump(uint ip, uint dest) + : sp_instr(ip), m_dest(dest) + {} + + virtual ~sp_instr_jump() + {} + + virtual int execute(THD *thd, uint *nextp) + { + *nextp= m_dest; + return 0; + } + + virtual void + set_destination(uint dest) + { + m_dest= dest; + } + +private: + + int m_dest; // Where we will go + +}; // class sp_instr_jump : public sp_instr + + +class sp_instr_jump_if : public sp_instr_jump +{ + sp_instr_jump_if(const sp_instr_jump_if &); /* Prevent use of these */ + void operator=(sp_instr_jump_if &); + +public: + + sp_instr_jump_if(uint ip, Item *i) + : sp_instr_jump(ip), m_expr(i) + {} + + sp_instr_jump_if(uint ip, Item *i, uint dest) + : sp_instr_jump(ip, dest), m_expr(i) + {} + + virtual ~sp_instr_jump_if() + {} + + virtual int execute(THD *thd, uint *nextp); + +private: + + int m_dest; // Where we will go + Item *m_expr; // The condition + +}; // class sp_instr_jump_if : public sp_instr_jump + + +class sp_instr_jump_if_not : public sp_instr_jump +{ + sp_instr_jump_if_not(const sp_instr_jump_if_not &); /* Prevent use of these */ + void operator=(sp_instr_jump_if_not &); + +public: + + sp_instr_jump_if_not(uint ip, Item *i) + : sp_instr_jump(ip), m_expr(i) + {} + + sp_instr_jump_if_not(uint ip, Item *i, uint dest) + : sp_instr_jump(ip, dest), m_expr(i) + {} + + virtual ~sp_instr_jump_if_not() + {} + + virtual int execute(THD *thd, uint *nextp); + +private: + + int m_dest; // Where we will go + Item *m_expr; // The condition + +}; // class sp_instr_jump_if_not : public sp_instr_jump + #endif /* _SP_HEAD_H_ */ diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index d2ab8cb93ac..9dc995f582f 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -24,14 +24,16 @@ #include "mysql_priv.h" #include "sp_pcontext.h" +#include "sp_head.h" sp_pcontext::sp_pcontext() - : m_params(0), m_framesize(0), m_i(0) + : m_params(0), m_framesize(0), m_i(0), m_genlab(0) { m_pvar_size = 16; m_pvar = (sp_pvar_t *)my_malloc(m_pvar_size * sizeof(sp_pvar_t), MYF(MY_WME)); if (m_pvar) memset(m_pvar, 0, m_pvar_size * sizeof(sp_pvar_t)); + m_label.empty(); } void @@ -89,3 +91,41 @@ sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, m_i += 1; } } + +void +sp_pcontext::push_label(char *name, uint ip) +{ + sp_label_t *lab = (sp_label_t *)my_malloc(sizeof(sp_label_t), MYF(MY_WME)); + + if (lab) + { + lab->name= name; + lab->ip= ip; + m_label.push_front(lab); + } +} + +void +sp_pcontext::push_gen_label(uint ip) +{ + char *s= my_malloc(10, MYF(MY_WME)); // 10=... + + if (s) + { + sprintf(s, ".%08x", m_genlab++); // ...9+1 + push_label(s, ip); + } +} + +sp_label_t * +sp_pcontext::find_label(char *name) +{ + List_iterator_fast li(m_label); + sp_label_t *lab; + + while ((lab= li++)) + if (strcasecmp(name, lab->name) == 0) + return lab; + + return NULL; +} diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 956b8d99d4d..8a37adcf427 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -38,6 +38,12 @@ typedef struct my_bool isset; } sp_pvar_t; +typedef struct +{ + char *name; + uint ip; // Instruction index +} sp_label_t; + class sp_pcontext : public Sql_alloc { sp_pcontext(const sp_pcontext &); /* Prevent use of these */ @@ -89,6 +95,7 @@ class sp_pcontext : public Sql_alloc void push(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode); + // Pop the last 'num' slots of the frame inline void pop(uint num = 1) { @@ -109,6 +116,21 @@ class sp_pcontext : public Sql_alloc return m_pvar+i; } + void + push_label(char *name, uint ip); + + void + push_gen_label(uint ip); + + sp_label_t * + find_label(char *name); + + inline void + pop_label() + { + m_label.pop(); + } + private: uint m_params; // The number of parameters @@ -121,6 +143,9 @@ private: void grow(); + List m_label; // The label list + uint m_genlab; // Gen. label counter + }; // class sp_pcontext : public Sql_alloc diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 33f928f2efe..bc19560ea77 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -526,6 +526,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SQL_SMALL_RESULT %token SQL_BUFFER_RESULT +%token CURSOR_SYM +%token ELSEIF_SYM +%token ITERATE_SYM +%token LEAVE_SYM +%token LOOP_SYM +%token UNTIL_SYM +%token WHILE_SYM +%token ASENSITIVE_SYM +%token INSENSITIVE_SYM +%token SENSITIVE_SYM /* QQ This is a dummy, until we have solved the SET syntax problem. */ %token SPSET_SYM @@ -680,7 +690,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); statement END_OF_INPUT -%type call sp_proc_body sp_proc_stmts sp_proc_stmt +%type call sp_proc_stmts sp_proc_stmt %type sp_decls sp_decl sp_decl_idents sp_opt_inout %type @@ -906,7 +916,7 @@ create: { Lex->spcont->set_params(); } - sp_proc_body + sp_proc_stmt { Lex->sql_command= SQLCOM_CREATE_PROCEDURE; } @@ -974,26 +984,9 @@ sp_opt_locator: | AS LOCATOR_SYM ; -sp_proc_body: - { - Lex->sphead->reset_lex(YYTHD); - } - sp_proc_stmt - { - Lex->sphead->restore_lex(YYTHD); - } - | begin - sp_decls - sp_proc_stmts - END - { - Lex->spcont->pop($2); - } - ; - sp_proc_stmts: - sp_proc_body ';' - | sp_proc_stmts sp_proc_body ';' + sp_proc_stmt ';' + | sp_proc_stmts sp_proc_stmt ';' ; sp_decls: @@ -1037,14 +1030,69 @@ sp_decl_idents: /* Dummy for the spset thing. Will go away when the SET problem is fixed. */ sp_proc_stmt: + { + Lex->sphead->reset_lex(YYTHD); + } statement { LEX *lex= Lex; - sp_instr_stmt *i= new sp_instr_stmt(); + sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); i->set_lex(lex); lex->sphead->add_instr(i); + lex->sphead->restore_lex(YYTHD); } +/* | sp_if + | sp_case */ + | sp_labeled_control + {} + | { /* Unlabeled controls get a secret label. */ + LEX *lex= Lex; + + Lex->spcont->push_gen_label(lex->sphead->instructions()); + } + sp_unlabeled_control + { + /* QQ backpatch here */ + Lex->spcont->pop_label(); + } + | LEAVE_SYM IDENT + { + LEX *lex= Lex; + sp_label_t *lab= lex->spcont->find_label($2.str); + + if (! lab) + { + printf("QQ LEAVE with no matching label\n"); + YYABORT; + } + else + { + uint ip= lex->sphead->instructions(); + sp_instr_jump *i= new sp_instr_jump(ip, 0); + + lex->sphead->push_backpatch(ip); + lex->sphead->add_instr(i); + } + } + | ITERATE_SYM IDENT + { + LEX *lex= Lex; + sp_label_t *lab= lex->spcont->find_label($2.str); + + if (! lab) + { + printf("QQ ITERATE with no matching label\n"); + YYABORT; + } + else + { + uint ip= lex->sphead->instructions(); + sp_instr_jump *i= new sp_instr_jump(ip, lab->ip); + + lex->sphead->add_instr(i); + } + } | /* QQ Dummy. We need to fix the old SET syntax to make it work for local SP variables as well. */ @@ -1059,7 +1107,8 @@ sp_proc_stmt: else { /* QQ Check type match! */ - sp_instr_set *i = new sp_instr_set(spv->offset, $4, spv->type); + sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(), + spv->offset, $4, spv->type); lex->sphead->add_instr(i); spv->isset= TRUE; @@ -1067,6 +1116,63 @@ sp_proc_stmt: } ; +sp_labeled_control: + IDENT ':' + { + LEX *lex= Lex; + sp_label_t *lab= lex->spcont->find_label($1.str); + + if (lab) + { + printf("QQ Redefining label\n"); + YYABORT; + } + else + lex->spcont->push_label($1.str, + lex->sphead->instructions()); + } + sp_unlabeled_control IDENT + { + LEX *lex= Lex; + sp_label_t *lab= lex->spcont->find_label($5.str); + + if (! lab) + { + printf("QQ end-label without match\n"); + YYABORT; + } + else if (strcasecmp($5.str, lab->name) != 0) + { + printf("QQ mismatching labels\n"); + YYABORT; + } + else + { + /* QQ backpatch here */ + lex->spcont->pop_label(); + } + } + ; + +sp_unlabeled_control: + begin + sp_decls + sp_proc_stmts + END + { + Lex->spcont->pop($2); + } + | LOOP_SYM + sp_proc_stmts + END LOOP_SYM + | WHILE_SYM expr DO_SYM + sp_proc_stmts + END WHILE_SYM + | FUNC_ARG2 /* "REPEAT" actually... */ + sp_proc_stmts + UNTIL_SYM expr END FUNC_ARG2 + ; + create2: '(' field_list ')' opt_create_table_options create3 {} | opt_create_table_options create3 {} From 77b671f5949726ae1444421694b1c3496f99af67 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 12 Dec 2002 13:14:23 +0100 Subject: [PATCH 09/83] Moved create/find/drop functions to a separate files (sp.cc,sp.h). Fixed backpatching of forward jumps. Implemented LOOP, WHILE, REPEAT (temporarily known as SPREPEAT). Known bug: Expression evaluation still not quite ok (e.g. "x > 0"), which is why IF and CASE is not yet implemented. --- sql/Makefile.am | 4 +- sql/item.h | 5 ++ sql/lex.h | 5 +- sql/sp.cc | 119 +++++++++++++++++++++++++++++++++++ sql/sp.h | 33 ++++++++++ sql/sp_head.cc | 155 +++++----------------------------------------- sql/sp_head.h | 24 ++----- sql/sp_pcontext.h | 6 ++ sql/sql_parse.cc | 1 + sql/sql_yacc.yy | 65 ++++++++++++++----- 10 files changed, 239 insertions(+), 178 deletions(-) create mode 100644 sql/sp.cc create mode 100644 sql/sp.h diff --git a/sql/Makefile.am b/sql/Makefile.am index 1cdfc05ffdc..116c094aa04 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -58,7 +58,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ log_event.h mini_client.h sql_repl.h slave.h \ stacktrace.h sql_sort.h sql_cache.h set_var.h \ spatial.h gstream.h sp_head.h sp_pcontext.h \ - sp_rcontext.h + sp_rcontext.h sp.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ @@ -87,7 +87,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ mini_client.cc mini_client_errors.c \ stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc\ gstream.cc spatial.cc sql_help.cc \ - sp_head.cc sp_pcontext.cc + sp_head.cc sp_pcontext.cc sp.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/item.h b/sql/item.h index bffb9212e3d..366eb8f2e32 100644 --- a/sql/item.h +++ b/sql/item.h @@ -126,6 +126,11 @@ public: return m_offset; } + virtual Item_result result_type() const + { + return this_const_item()->result_type(); + } + // Abstract methods inherited from Item. Just defer the call to // the item in the frame inline enum Type type() const diff --git a/sql/lex.h b/sql/lex.h index 829c16a3b74..606bb0eaf6c 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -317,10 +317,10 @@ static SYMBOL symbols[] = { { "REPAIR", SYM(REPAIR),0,0}, { "REPLACE", SYM(REPLACE),0,0}, { "REPLICATION", SYM(REPLICATION),0,0}, + { "SPREPEAT", SYM(SPREPEAT_SYM),0,0}, /* QQ Temp. until conflict solved */ { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, { "REQUIRE", SYM(REQUIRE_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0}, - { "UNTIL", SYM(UNTIL_SYM),0,0}, { "USER_RESOURCES", SYM(RESOURCES),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTRICT", SYM(RESTRICT),0,0}, @@ -351,7 +351,7 @@ static SYMBOL symbols[] = { { "SONAME", SYM(UDF_SONAME_SYM),0,0}, { "SPATIAL", SYM(SPATIAL_SYM),0,0}, { "SPECIFIC", SYM(SPECIFIC_SYM),0,0}, - { "SPSET", SYM(SPSET_SYM),0,0}, + { "SPSET", SYM(SPSET_SYM),0,0}, /* Temp. until SET parsing solved. */ { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0}, { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0}, { "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0}, @@ -392,6 +392,7 @@ static SYMBOL symbols[] = { { "UNIQUE", SYM(UNIQUE_SYM),0,0}, { "UNLOCK", SYM(UNLOCK_SYM),0,0}, { "UNSIGNED", SYM(UNSIGNED),0,0}, + { "UNTIL", SYM(UNTIL_SYM),0,0}, { "USE", SYM(USE_SYM),0,0}, { "USE_FRM", SYM(USE_FRM),0,0}, { "USING", SYM(USING),0,0}, diff --git a/sql/sp.cc b/sql/sp.cc new file mode 100644 index 00000000000..caeb01200ff --- /dev/null +++ b/sql/sp.cc @@ -0,0 +1,119 @@ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#include "mysql_priv.h" +#include "sp.h" +#include "sp_head.h" + +// Finds the SP 'name'. Currently this always reads from the database +// and prepares (parse) it, but in the future it will first look in +// the in-memory cache for SPs. (And store newly prepared SPs there of +// course.) +sp_head * +sp_find(THD *thd, Item_string *iname) +{ + extern int yyparse(void *thd); + LEX *tmplex; + TABLE *table; + TABLE_LIST tables; + const char *defstr; + String *name; + sp_head *sp = NULL; + + name = iname->const_string(); + memset(&tables, 0, sizeof(tables)); + tables.db= (char*)"mysql"; + tables.real_name= tables.alias= (char*)"proc"; + if (! (table= open_ltable(thd, &tables, TL_READ))) + return NULL; + + if (table->file->index_read_idx(table->record[0], 0, + (byte*)name->c_ptr(), name->length(), + HA_READ_KEY_EXACT)) + goto done; + + if ((defstr= get_field(&thd->mem_root, table, 1)) == NULL) + goto done; + + // QQ Set up our own mem_root here??? + tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); + if (yyparse(thd) || thd->fatal_error || tmplex->sphead == NULL) + goto done; // Error + else + sp = tmplex->sphead; + + done: + if (table) + close_thread_tables(thd); + return sp; +} + +int +sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) +{ + int ret= 0; + TABLE *table; + TABLE_LIST tables; + + memset(&tables, 0, sizeof(tables)); + tables.db= (char*)"mysql"; + tables.real_name= tables.alias= (char*)"proc"; + /* Allow creation of procedures even if we can't open proc table */ + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + { + ret= -1; + goto done; + } + + restore_record(table, 2); // Get default values for fields + + table->field[0]->store(name, namelen, default_charset_info); + table->field[1]->store(def, deflen, default_charset_info); + + ret= table->file->write_row(table->record[0]); + + done: + close_thread_tables(thd); + return ret; +} + +int +sp_drop(THD *thd, char *name, uint namelen) +{ + TABLE *table; + TABLE_LIST tables; + + tables.db= (char *)"mysql"; + tables.real_name= tables.alias= (char *)"proc"; + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + goto err; + if (! table->file->index_read_idx(table->record[0], 0, + (byte *)name, namelen, + HA_READ_KEY_EXACT)) + { + int error; + + if ((error= table->file->delete_row(table->record[0]))) + table->file->print_error(error, MYF(0)); + } + close_thread_tables(thd); + return 0; + + err: + close_thread_tables(thd); + return -1; +} diff --git a/sql/sp.h b/sql/sp.h new file mode 100644 index 00000000000..cb3343a4e92 --- /dev/null +++ b/sql/sp.h @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _SP_H_ +#define _SP_H_ + +// +// Finds a stored procedure given its name. Returns NULL if not found. +// +sp_head * +sp_find(THD *thd, Item_string *name); + +int +sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen); + +int +sp_drop(THD *thd, char *name, uint namelen); + +#endif /* _SP_H_ */ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ed93f005db3..8025fe3ef4c 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -20,6 +20,7 @@ #include "mysql_priv.h" #include "sp_head.h" +#include "sp.h" #include "sp_pcontext.h" #include "sp_rcontext.h" @@ -31,9 +32,7 @@ eval_func_item(Item *it, enum enum_field_types type) { it= it->this_item(); - /* QQ Which way do we do this? Or is there some even better way? */ -#if 1 - /* QQ Obey the declared type of the variable */ + /* QQ How do we do this? Is there some better way? */ switch (type) { case MYSQL_TYPE_TINY: @@ -77,30 +76,7 @@ eval_func_item(Item *it, enum enum_field_types type) /* QQ Don't know what to do with the rest. */ break; } -#else - /* QQ This looks simpler, but is wrong? It disregards the variable's type. */ - switch (it->result_type()) - { - case REAL_RESULT: - it= new Item_real(it->val()); - break; - case INT_RESULT: - it= new Item_int(it->val_int()); - break; - case STRING_RESULT: - { - char buffer[MAX_FIELD_WIDTH]; - String tmp(buffer, sizeof(buffer), default_charset_info); - (void)it->val_str(&tmp); - it= new Item_string(buffer, sizeof(buffer), default_charset_info); - break; - } - default: - /* QQ Don't know what to do with the rest. */ - break; - } -#endif return it; } @@ -113,6 +89,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) m_defstr= new Item_string(dstr, lex->end_of_query - lex->buf, default_charset_info); my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); + m_backpatch.empty(); } int @@ -144,7 +121,7 @@ sp_head::execute(THD *thd) Item *it = li++; // Skip first one, it's the procedure name nctx = new sp_rcontext(csize); - // QQ: No error checking whatsoever right now + // QQ: No error checking whatsoever right now. Should do type checking? for (i = 0 ; (it= li++) && i < params ; i++) { sp_pvar_t *pvar = pctx->find_pvar(i); @@ -168,7 +145,7 @@ sp_head::execute(THD *thd) // The rest of the frame are local variables which are all IN. // QQ We haven't found any hint of what the value is when unassigned, // so we set it to NULL for now. It's an error to refer to an - // unassigned variable (which should be detected by the parser). + // unassigned variable anyway (which should be detected by the parser). for (; i < csize ; i++) nctx->push_item(NULL); thd->spcont= nctx; @@ -212,6 +189,7 @@ sp_head::execute(THD *thd) } +// Reset lex during parsing, before we parse a sub statement. void sp_head::reset_lex(THD *thd) { @@ -244,6 +222,7 @@ sp_head::reset_lex(THD *thd) thd->lex.auxilliary_table_list.empty(); } +// Restore lex during parsing, after we have parsed a sub statement. void sp_head::restore_lex(THD *thd) { @@ -255,123 +234,25 @@ sp_head::restore_lex(THD *thd) } void -sp_head::push_backpatch(uint ip) +sp_head::push_backpatch(sp_instr *i) { - (void)m_backpatch.push_front(&ip); + (void)m_backpatch.push_front(i); } void -sp_head::backpatch(uint dest) +sp_head::backpatch() { - while (! m_backpatch.is_empty()) + sp_instr *ip; + uint dest= instructions(); + List_iterator_fast li(m_backpatch); + + while ((ip= li++)) { - uint *ip= m_backpatch.pop(); - sp_instr_jump *i= static_cast(get_instr(*ip)); + sp_instr_jump *i= static_cast(ip); i->set_destination(dest); } -} - - -// ------------------------------------------------------------------ - -// Finds the SP 'name'. Currently this always reads from the database -// and prepares (parse) it, but in the future it will first look in -// the in-memory cache for SPs. (And store newly prepared SPs there of -// course.) -sp_head * -sp_find(THD *thd, Item_string *iname) -{ - extern int yyparse(void *thd); - LEX *tmplex; - TABLE *table; - TABLE_LIST tables; - const char *defstr; - String *name; - sp_head *sp = NULL; - - name = iname->const_string(); - memset(&tables, 0, sizeof(tables)); - tables.db= (char*)"mysql"; - tables.real_name= tables.alias= (char*)"proc"; - if (! (table= open_ltable(thd, &tables, TL_READ))) - return NULL; - - if (table->file->index_read_idx(table->record[0], 0, - (byte*)name->c_ptr(), name->length(), - HA_READ_KEY_EXACT)) - goto done; - - if ((defstr= get_field(&thd->mem_root, table, 1)) == NULL) - goto done; - - // QQ Set up our own mem_root here??? - tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); - if (yyparse(thd) || thd->fatal_error || tmplex->sphead == NULL) - goto done; // Error - else - sp = tmplex->sphead; - - done: - if (table) - close_thread_tables(thd); - return sp; -} - -int -sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) -{ - int ret= 0; - TABLE *table; - TABLE_LIST tables; - - memset(&tables, 0, sizeof(tables)); - tables.db= (char*)"mysql"; - tables.real_name= tables.alias= (char*)"proc"; - /* Allow creation of procedures even if we can't open proc table */ - if (! (table= open_ltable(thd, &tables, TL_WRITE))) - { - ret= -1; - goto done; - } - - restore_record(table, 2); // Get default values for fields - - table->field[0]->store(name, namelen, default_charset_info); - table->field[1]->store(def, deflen, default_charset_info); - - ret= table->file->write_row(table->record[0]); - - done: - close_thread_tables(thd); - return ret; -} - -int -sp_drop(THD *thd, char *name, uint namelen) -{ - TABLE *table; - TABLE_LIST tables; - - tables.db= (char *)"mysql"; - tables.real_name= tables.alias= (char *)"proc"; - if (! (table= open_ltable(thd, &tables, TL_WRITE))) - goto err; - if (! table->file->index_read_idx(table->record[0], 0, - (byte *)name, namelen, - HA_READ_KEY_EXACT)) - { - int error; - - if ((error= table->file->delete_row(table->record[0]))) - table->file->print_error(error, MYF(0)); - } - close_thread_tables(thd); - return 0; - - err: - close_thread_tables(thd); - return -1; + m_backpatch.empty(); } @@ -412,7 +293,6 @@ sp_instr_set::execute(THD *thd, uint *nextp) // // sp_instr_jump_if // - int sp_instr_jump_if::execute(THD *thd, uint *nextp) { @@ -428,7 +308,6 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp) // // sp_instr_jump_if_not // - int sp_instr_jump_if_not::execute(THD *thd, uint *nextp) { diff --git a/sql/sp_head.h b/sql/sp_head.h index 53130bffdf1..87f2b78b9fd 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -73,10 +73,10 @@ public: restore_lex(THD *thd); void - push_backpatch(uint ip); + push_backpatch(sp_instr *i); void - backpatch(uint dest); + backpatch(); private: @@ -85,7 +85,7 @@ private: LEX *m_mylex; // My own lex LEX m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" - List m_backpatch; // Instructions needing backpaching + List m_backpatch; // Instructions needing backpaching inline sp_instr * get_instr(uint i) @@ -99,20 +99,6 @@ private: }; // class sp_head : public Sql_alloc -// -// Find a stored procedure given its name. Returns NULL if not -// found. -// -sp_head * -sp_find(THD *thd, Item_string *name); - -int -sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen); - -int -sp_drop(THD *thd, char *name, uint namelen); - - // // "Instructions"... // @@ -243,7 +229,7 @@ public: m_dest= dest; } -private: +protected: int m_dest; // Where we will go @@ -272,7 +258,6 @@ public: private: - int m_dest; // Where we will go Item *m_expr; // The condition }; // class sp_instr_jump_if : public sp_instr_jump @@ -300,7 +285,6 @@ public: private: - int m_dest; // Where we will go Item *m_expr; // The condition }; // class sp_instr_jump_if_not : public sp_instr_jump diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 8a37adcf427..7c8e2ba0c43 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -125,6 +125,12 @@ class sp_pcontext : public Sql_alloc sp_label_t * find_label(char *name); + inline sp_label_t * + last_label() + { + return m_label.head(); + } + inline void pop_label() { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fba726c95b6..ac18b3369ac 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -28,6 +28,7 @@ #endif #include "sp_head.h" +#include "sp.h" #ifdef HAVE_OPENSSL /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bc19560ea77..30f9fe97ec5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -531,6 +531,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ITERATE_SYM %token LEAVE_SYM %token LOOP_SYM +/* QQ This is temporary, until the REPEAT conflict is solved. */ +%token SPREPEAT_SYM %token UNTIL_SYM %token WHILE_SYM %token ASENSITIVE_SYM @@ -1053,8 +1055,10 @@ sp_proc_stmt: } sp_unlabeled_control { - /* QQ backpatch here */ - Lex->spcont->pop_label(); + LEX *lex= Lex; + + lex->spcont->pop_label(); + lex->sphead->backpatch(); } | LEAVE_SYM IDENT { @@ -1068,10 +1072,9 @@ sp_proc_stmt: } else { - uint ip= lex->sphead->instructions(); - sp_instr_jump *i= new sp_instr_jump(ip, 0); + sp_instr_jump *i= new sp_instr_jump(lex->sphead->instructions()); - lex->sphead->push_backpatch(ip); + lex->sphead->push_backpatch(i); /* Jumping forward */ lex->sphead->add_instr(i); } } @@ -1088,7 +1091,7 @@ sp_proc_stmt: else { uint ip= lex->sphead->instructions(); - sp_instr_jump *i= new sp_instr_jump(ip, lab->ip); + sp_instr_jump *i= new sp_instr_jump(ip, lab->ip); /* Jump back */ lex->sphead->add_instr(i); } @@ -1148,29 +1151,59 @@ sp_labeled_control: } else { - /* QQ backpatch here */ lex->spcont->pop_label(); + lex->sphead->backpatch(); } } ; sp_unlabeled_control: - begin + BEGIN_SYM sp_decls sp_proc_stmts END - { + { /* QQ This is just a dummy for grouping declarations and statements + together. No [[NOT] ATOMIC] yet, and we need to figure out how + make it coexist with the existing BEGIN COMMIT/ROLLBACK. */ Lex->spcont->pop($2); } | LOOP_SYM - sp_proc_stmts - END LOOP_SYM + sp_proc_stmts END LOOP_SYM + { + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump *i = new sp_instr_jump(ip, lab->ip); + + lex->sphead->add_instr(i); + } | WHILE_SYM expr DO_SYM - sp_proc_stmts - END WHILE_SYM - | FUNC_ARG2 /* "REPEAT" actually... */ - sp_proc_stmts - UNTIL_SYM expr END FUNC_ARG2 + { + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $2); + + lex->sphead->push_backpatch(i); /* Jumping forward */ + lex->sphead->add_instr(i); + } + sp_proc_stmts END WHILE_SYM + { + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump *i = new sp_instr_jump(ip, lab->ip); + + lex->sphead->add_instr(i); + } + | SPREPEAT_SYM sp_proc_stmts UNTIL_SYM expr END SPREPEAT_SYM + { /* ^^ QQ temp. until conflict solved ^^ */ + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $4, lab->ip); + + lex->sphead->add_instr(i); + } ; create2: From 113b9240d1226c3934890144abfa9682cb4d8b8e Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 13 Dec 2002 18:25:36 +0100 Subject: [PATCH 10/83] Added collection of called procedures in a list. Fixed eval bug; now conditions with local variables work in WHILE et al. Made mysql_install_db.sh create proc table. --- scripts/mysql_install_db.sh | 13 ++++++++++++ sql/item.h | 5 ----- sql/sp_head.cc | 40 ++++++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 5e139dc652b..6029ac2518a 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -306,6 +306,18 @@ then c_c="$c_c comment='Column privileges';" fi +if test ! -f $mdata/proc.frm +then + echo "Preparing proc table" + + c_p="$c_p CREATE TABLE proc (" + c_p="$c_p name char(64) binary DEFAULT '' NOT NULL," + c_p="$c_p body blob DEFAULT '' NOT NULL," + c_p="$c_p PRIMARY KEY (name)" + c_p="$c_p )" + c_p="$c_p comment='Stored Procedures';" +fi + echo "Installing all prepared tables" if ( cat << END_OF_DATA @@ -324,6 +336,7 @@ $i_f $c_t $c_c +$c_p END_OF_DATA cat fill_func_tables.sql ) | eval "$execdir/mysqld $defaults --bootstrap --skip-grant-tables \ diff --git a/sql/item.h b/sql/item.h index 366eb8f2e32..bffb9212e3d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -126,11 +126,6 @@ public: return m_offset; } - virtual Item_result result_type() const - { - return this_const_item()->result_type(); - } - // Abstract methods inherited from Item. Just defer the call to // the item in the frame inline enum Type type() const diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8025fe3ef4c..a2a40d08ecb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -28,10 +28,13 @@ ** if nothing else. */ static Item * -eval_func_item(Item *it, enum enum_field_types type) +eval_func_item(THD *thd, Item *it, enum enum_field_types type) { it= it->this_item(); + if (it->fix_fields(thd, 0, NULL)) + return it; // Shouldn't happen? + /* QQ How do we do this? Is there some better way? */ switch (type) { @@ -133,7 +136,7 @@ sp_head::execute(THD *thd) if (pvar->mode == sp_param_out) nctx->push_item(it->this_item()); // OUT else - nctx->push_item(eval_func_item(it, pvar->type)); // IN or INOUT + nctx->push_item(eval_func_item(thd, it, pvar->type)); // IN or INOUT // Note: If it's OUT or INOUT, it must be a variable. // QQ: Need to handle "global" user/host variables too!!! if (pvar->mode == sp_param_in) @@ -202,7 +205,9 @@ sp_head::reset_lex(THD *thd) /* And keep the SP stuff too */ thd->lex.sphead = m_lex.sphead; thd->lex.spcont = m_lex.spcont; - /* QQ Why isn't this reset by lex_start() ??? */ + /* Clear all lists. (QQ Why isn't this reset by lex_start()?). + We may be overdoing this, but we know for sure that value_list must + be cleared at least. */ thd->lex.col_list.empty(); thd->lex.ref_list.empty(); thd->lex.drop_list.empty(); @@ -229,7 +234,28 @@ sp_head::restore_lex(THD *thd) // Update some state in the old one first m_lex.ptr= thd->lex.ptr; m_lex.next_state= thd->lex.next_state; - // QQ Append tables, fields, etc. from the current lex to mine + // Collect some data from the sub statement lex. + // We reuse some lists in lex instead of adding new ones to this already + // quite large structure. + + // CALL puts the proc. name and parameters in value_list, so we might as + // collect called procedures there. + if (thd->lex.sql_command == SQLCOM_CALL) + { + // Assuming we will rarely have more than, say, 10 calls to other + // procedures, this is probably fastest. + Item *proc= thd->lex.value_list.head(); + List_iterator_fast li(m_lex.value_list); + Item *it; + + while ((it= li++)) + if (proc->eq(it, FALSE)) + break; + if (! it) + m_lex.value_list.push_back(proc); // Got a new one. + } + // QQ Copy select_lex.table_list. + memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex } @@ -285,7 +311,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) int sp_instr_set::execute(THD *thd, uint *nextp) { - thd->spcont->set_item(m_offset, eval_func_item(m_value, m_type)); + thd->spcont->set_item(m_offset, eval_func_item(thd, m_value, m_type)); *nextp = m_ip+1; return 0; } @@ -296,7 +322,7 @@ sp_instr_set::execute(THD *thd, uint *nextp) int sp_instr_jump_if::execute(THD *thd, uint *nextp) { - Item *it= eval_func_item(m_expr, MYSQL_TYPE_TINY); + Item *it= eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (it->val_int()) *nextp = m_dest; @@ -311,7 +337,7 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp) int sp_instr_jump_if_not::execute(THD *thd, uint *nextp) { - Item *it= eval_func_item(m_expr, MYSQL_TYPE_TINY); + Item *it= eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (! it->val_int()) *nextp = m_dest; From b1593c9a692141cadb345d5da6836e503f0e1dbf Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Mon, 16 Dec 2002 15:40:44 +0100 Subject: [PATCH 11/83] Fixed the broken backpatching implementation. Implemented IF-THEN-ELSE. --- sql/sp_head.cc | 29 ++++++++++++-------- sql/sp_head.h | 16 ++++++++--- sql/sp_pcontext.cc | 9 ++++--- sql/sp_pcontext.h | 10 +++---- sql/sql_yacc.yy | 66 +++++++++++++++++++++++++++++++++++++--------- 5 files changed, 96 insertions(+), 34 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a2a40d08ecb..226701bafe4 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -260,25 +260,32 @@ sp_head::restore_lex(THD *thd) } void -sp_head::push_backpatch(sp_instr *i) +sp_head::push_backpatch(sp_instr *i, sp_label_t *lab) { - (void)m_backpatch.push_front(i); + bp_t *bp= (bp_t *)my_malloc(sizeof(bp_t), MYF(MY_WME)); + + if (bp) + { + bp->lab= lab; + bp->instr= i; + (void)m_backpatch.push_front(bp); + } } void -sp_head::backpatch() +sp_head::backpatch(sp_label_t *lab) { - sp_instr *ip; + bp_t *bp; uint dest= instructions(); - List_iterator_fast li(m_backpatch); + List_iterator_fast li(m_backpatch); - while ((ip= li++)) - { - sp_instr_jump *i= static_cast(ip); + while ((bp= li++)) + if (bp->lab == lab) + { + sp_instr_jump *i= static_cast(bp->instr); - i->set_destination(dest); - } - m_backpatch.empty(); + i->set_destination(dest); + } } diff --git a/sql/sp_head.h b/sql/sp_head.h index 87f2b78b9fd..097eb6718e6 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -24,6 +24,8 @@ #include +struct sp_label; + class sp_instr; class sp_head : public Sql_alloc @@ -72,11 +74,14 @@ public: void restore_lex(THD *thd); + // Put the instruction on the backpatch list, associated with the label. void - push_backpatch(sp_instr *i); + push_backpatch(sp_instr *, struct sp_label *); + // Update all instruction with this label in the backpatch list to + // the current position. void - backpatch(); + backpatch(struct sp_label *); private: @@ -85,7 +90,12 @@ private: LEX *m_mylex; // My own lex LEX m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" - List m_backpatch; // Instructions needing backpaching + typedef struct + { + struct sp_label *lab; + sp_instr *instr; + } bp_t; + List m_backpatch; // Instructions needing backpaching inline sp_instr * get_instr(uint i) diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 9dc995f582f..96296e54184 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -92,7 +92,7 @@ sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, } } -void +sp_label_t * sp_pcontext::push_label(char *name, uint ip) { sp_label_t *lab = (sp_label_t *)my_malloc(sizeof(sp_label_t), MYF(MY_WME)); @@ -103,18 +103,21 @@ sp_pcontext::push_label(char *name, uint ip) lab->ip= ip; m_label.push_front(lab); } + return lab; } -void +sp_label_t * sp_pcontext::push_gen_label(uint ip) { + sp_label_t *lab= NULL; char *s= my_malloc(10, MYF(MY_WME)); // 10=... if (s) { sprintf(s, ".%08x", m_genlab++); // ...9+1 - push_label(s, ip); + lab= push_label(s, ip); } + return lab; } sp_label_t * diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 7c8e2ba0c43..2eb59172365 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -38,7 +38,7 @@ typedef struct my_bool isset; } sp_pvar_t; -typedef struct +typedef struct sp_label { char *name; uint ip; // Instruction index @@ -116,10 +116,10 @@ class sp_pcontext : public Sql_alloc return m_pvar+i; } - void + sp_label_t * push_label(char *name, uint ip); - void + sp_label_t * push_gen_label(uint ip); sp_label_t * @@ -131,10 +131,10 @@ class sp_pcontext : public Sql_alloc return m_label.head(); } - inline void + inline sp_label_t * pop_label() { - m_label.pop(); + return m_label.pop(); } private: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 30f9fe97ec5..3d562dcfdbe 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1044,25 +1044,25 @@ sp_proc_stmt: lex->sphead->add_instr(i); lex->sphead->restore_lex(YYTHD); } -/* | sp_if - | sp_case */ + | IF sp_if END IF {} +/* | sp_case */ | sp_labeled_control {} | { /* Unlabeled controls get a secret label. */ LEX *lex= Lex; - Lex->spcont->push_gen_label(lex->sphead->instructions()); + lex->spcont->push_gen_label(lex->sphead->instructions()); } sp_unlabeled_control { LEX *lex= Lex; - lex->spcont->pop_label(); - lex->sphead->backpatch(); + lex->sphead->backpatch(lex->spcont->pop_label()); } | LEAVE_SYM IDENT { LEX *lex= Lex; + sp_head *sp = lex->sphead; sp_label_t *lab= lex->spcont->find_label($2.str); if (! lab) @@ -1072,10 +1072,10 @@ sp_proc_stmt: } else { - sp_instr_jump *i= new sp_instr_jump(lex->sphead->instructions()); + sp_instr_jump *i= new sp_instr_jump(sp->instructions()); - lex->sphead->push_backpatch(i); /* Jumping forward */ - lex->sphead->add_instr(i); + sp->push_backpatch(i, lab); /* Jumping forward */ + sp->add_instr(i); } } | ITERATE_SYM IDENT @@ -1119,6 +1119,44 @@ sp_proc_stmt: } ; +sp_if: + expr THEN_SYM + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $1); + + sp->push_backpatch(i, ctx->push_gen_label(0)); /* Forward only */ + sp->add_instr(i); + } + sp_proc_stmts + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump *i = new sp_instr_jump(ip); + + sp->add_instr(i); + sp->backpatch(ctx->pop_label()); + sp->push_backpatch(i, ctx->push_gen_label(0)); /* Forward only */ + } + sp_elseifs + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + + sp->backpatch(ctx->pop_label()); + } + ; + +sp_elseifs: + /* Empty */ + | ELSEIF_SYM sp_if + | ELSE sp_proc_stmts + ; + sp_labeled_control: IDENT ':' { @@ -1131,8 +1169,10 @@ sp_labeled_control: YYABORT; } else + { lex->spcont->push_label($1.str, lex->sphead->instructions()); + } } sp_unlabeled_control IDENT { @@ -1152,7 +1192,7 @@ sp_labeled_control: else { lex->spcont->pop_label(); - lex->sphead->backpatch(); + lex->sphead->backpatch(lab); } } ; @@ -1180,11 +1220,13 @@ sp_unlabeled_control: | WHILE_SYM expr DO_SYM { LEX *lex= Lex; - uint ip= lex->sphead->instructions(); + sp_head *sp= lex->sphead; + uint ip= sp->instructions(); sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $2); - lex->sphead->push_backpatch(i); /* Jumping forward */ - lex->sphead->add_instr(i); + /* Jumping forward */ + sp->push_backpatch(i, lex->spcont->last_label()); + sp->add_instr(i); } sp_proc_stmts END WHILE_SYM { From 58d3dda33f46348b3df51af8b3c04115d340e2b6 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 17 Dec 2002 10:01:52 +0100 Subject: [PATCH 12/83] Added parsing of CASE (both generic and "simple"). --- sql/sp_head.cc | 1 + sql/sp_head.h | 2 ++ sql/sp_pcontext.cc | 14 -------- sql/sp_pcontext.h | 5 +-- sql/sql_yacc.yy | 84 +++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 226701bafe4..c61256e5edb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -84,6 +84,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) } sp_head::sp_head(LEX_STRING *name, LEX *lex) + : m_simple_case(FALSE) { const char *dstr = (const char*)lex->buf; diff --git a/sql/sp_head.h b/sql/sp_head.h index 097eb6718e6..f6d06b61f43 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -35,6 +35,8 @@ class sp_head : public Sql_alloc public: + my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise + static void *operator new(size_t size) { return (void*) sql_alloc((uint) size); diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 96296e54184..407151c3e38 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -106,20 +106,6 @@ sp_pcontext::push_label(char *name, uint ip) return lab; } -sp_label_t * -sp_pcontext::push_gen_label(uint ip) -{ - sp_label_t *lab= NULL; - char *s= my_malloc(10, MYF(MY_WME)); // 10=... - - if (s) - { - sprintf(s, ".%08x", m_genlab++); // ...9+1 - lab= push_label(s, ip); - } - return lab; -} - sp_label_t * sp_pcontext::find_label(char *name) { diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 2eb59172365..6ab38e77017 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -99,7 +99,7 @@ class sp_pcontext : public Sql_alloc inline void pop(uint num = 1) { - if (num >= m_i) + if (num < m_i) m_i -= num; } @@ -119,9 +119,6 @@ class sp_pcontext : public Sql_alloc sp_label_t * push_label(char *name, uint ip); - sp_label_t * - push_gen_label(uint ip); - sp_label_t * find_label(char *name); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3d562dcfdbe..dff59520149 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1030,7 +1030,6 @@ sp_decl_idents: } ; -/* Dummy for the spset thing. Will go away when the SET problem is fixed. */ sp_proc_stmt: { Lex->sphead->reset_lex(YYTHD); @@ -1045,13 +1044,39 @@ sp_proc_stmt: lex->sphead->restore_lex(YYTHD); } | IF sp_if END IF {} -/* | sp_case */ + | CASE_SYM WHEN_SYM + { + Lex->sphead->m_simple_case= FALSE; + } + sp_case END CASE_SYM {} + | CASE_SYM expr WHEN_SYM + { + /* We "fake" this by using an anonymous variable which we + set to the expression. Note that all WHENs are evaluate + at the same frame level, so we then know that it's the + top-most variable in the frame. */ + LEX *lex= Lex; + uint offset= lex->spcont->current_framesize(); + sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(), + offset, $2, MYSQL_TYPE_STRING); + LEX_STRING dummy; + + dummy.str= (char *)""; + dummy.length= 0; + lex->spcont->push(&dummy, MYSQL_TYPE_STRING, sp_param_in); + lex->sphead->add_instr(i); + lex->sphead->m_simple_case= TRUE; + } + sp_case END CASE_SYM + { + Lex->spcont->pop(); + } | sp_labeled_control {} | { /* Unlabeled controls get a secret label. */ LEX *lex= Lex; - lex->spcont->push_gen_label(lex->sphead->instructions()); + lex->spcont->push_label((char *)"", lex->sphead->instructions()); } sp_unlabeled_control { @@ -1127,7 +1152,7 @@ sp_if: uint ip= sp->instructions(); sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, $1); - sp->push_backpatch(i, ctx->push_gen_label(0)); /* Forward only */ + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); sp->add_instr(i); } sp_proc_stmts @@ -1139,15 +1164,13 @@ sp_if: sp->add_instr(i); sp->backpatch(ctx->pop_label()); - sp->push_backpatch(i, ctx->push_gen_label(0)); /* Forward only */ + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); } sp_elseifs { LEX *lex= Lex; - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - sp->backpatch(ctx->pop_label()); + lex->sphead->backpatch(lex->spcont->pop_label()); } ; @@ -1157,6 +1180,51 @@ sp_elseifs: | ELSE sp_proc_stmts ; +sp_case: + expr THEN_SYM + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i; + + if (! sp->m_simple_case) + i= new sp_instr_jump_if_not(ip, $1); + else + { /* Simple case: = */ + Item *var= (Item*) new Item_splocal(ctx->current_framesize()-1); + Item *expr= Item_bool_func2::eq_creator(var, $1); + + i= new sp_instr_jump_if_not(ip, expr); + } + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + sp->add_instr(i); + } + sp_proc_stmts + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump *i = new sp_instr_jump(ip); + + sp->add_instr(i); + sp->backpatch(ctx->pop_label()); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + } + sp_whens + { + LEX *lex= Lex; + + lex->sphead->backpatch(lex->spcont->pop_label()); + } + ; + +sp_whens: + /* Empty */ + | WHEN_SYM sp_case + | ELSE sp_proc_stmts + ; + sp_labeled_control: IDENT ':' { From 204aa97280e594a969783c7e251ba7c3bfc9dba6 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 19 Dec 2002 18:43:25 +0100 Subject: [PATCH 13/83] Fixed some of the data collection during parsing. --- sql/sp_head.cc | 56 +++++++++++++++++++++++++++++++++++--------------- sql/sp_head.h | 4 +++- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c61256e5edb..fdccedc788f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -88,7 +88,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) { const char *dstr = (const char*)lex->buf; - m_mylex= lex; + m_call_lex= lex; m_name= new Item_string(name->str, name->length, default_charset_info); m_defstr= new Item_string(dstr, lex->end_of_query - lex->buf, default_charset_info); @@ -112,7 +112,7 @@ sp_head::execute(THD *thd) { int ret= 0; sp_instr *p; - sp_pcontext *pctx = m_mylex->spcont; + sp_pcontext *pctx = m_call_lex->spcont; uint csize = pctx->max_framesize(); uint params = pctx->params(); sp_rcontext *octx = thd->spcont; @@ -121,7 +121,7 @@ sp_head::execute(THD *thd) if (csize > 0) { uint i; - List_iterator_fast li(m_mylex->value_list); + List_iterator_fast li(m_call_lex->value_list); Item *it = li++; // Skip first one, it's the procedure name nctx = new sp_rcontext(csize); @@ -235,27 +235,51 @@ sp_head::restore_lex(THD *thd) // Update some state in the old one first m_lex.ptr= thd->lex.ptr; m_lex.next_state= thd->lex.next_state; - // Collect some data from the sub statement lex. - // We reuse some lists in lex instead of adding new ones to this already - // quite large structure. - // CALL puts the proc. name and parameters in value_list, so we might as - // collect called procedures there. + // Collect some data from the sub statement lex. if (thd->lex.sql_command == SQLCOM_CALL) { - // Assuming we will rarely have more than, say, 10 calls to other - // procedures, this is probably fastest. - Item *proc= thd->lex.value_list.head(); - List_iterator_fast li(m_lex.value_list); - Item *it; + // We know they are Item_strings (since we put them there ourselves) + // It would be slightly faster to keep the list sorted, but we need + // an "insert before" method to do that. + Item_string *proc= static_cast(thd->lex.value_list.head()); + String *snew= proc->val_str(NULL); + List_iterator_fast li(m_calls); + Item_string *it; while ((it= li++)) - if (proc->eq(it, FALSE)) + { + String *sold= it->val_str(NULL); + + if (stringcmp(snew, sold) == 0) break; + } if (! it) - m_lex.value_list.push_back(proc); // Got a new one. + m_calls.push_back(proc); + + } + // Merge used tables + // QQ ...or just open tables in thd->open_tables? + // This is not entirerly clear at the moment, but for now, we collect + // tables here. + for (SELECT_LEX *sl= thd->lex.all_selects_list ; + sl ; + sl= sl->next_select()) + { + for (TABLE_LIST *tables= sl->get_table_list() ; + tables ; + tables= tables->next) + { + List_iterator_fast li(m_tables); + char **tb; + + while ((tb= li++)) + if (strcasecmp(tables->real_name, *tb) == 0) + break; + if (! tb) + m_tables.push_back(&tables->real_name); + } } - // QQ Copy select_lex.table_list. memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex } diff --git a/sql/sp_head.h b/sql/sp_head.h index f6d06b61f43..820193e8184 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -36,6 +36,8 @@ class sp_head : public Sql_alloc public: my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise + List m_calls; // Called procedures. + List m_tables; // Used tables. static void *operator new(size_t size) { @@ -89,7 +91,7 @@ private: Item_string *m_name; Item_string *m_defstr; - LEX *m_mylex; // My own lex + LEX *m_call_lex; // The CALL's own lex LEX m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" typedef struct From b88ef166563742202f97974db8137d5cefa50b3b Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 9 Jan 2003 18:30:58 +0100 Subject: [PATCH 14/83] Post-merge fix. --- mysql-test/r/rpl_temporary.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result index 470a6302a2b..f2da93b0e70 100644 --- a/mysql-test/r/rpl_temporary.result +++ b/mysql-test/r/rpl_temporary.result @@ -22,7 +22,7 @@ f 7 show binlog events; Log_name Pos Event_type Server_id Orig_log_pos Info -master-bin.000001 4 Start 1 4 Server ver: 4.1.0-alpha-debug-log, Binlog ver: 3 +master-bin.000001 4 Start 1 4 Server ver: 5.0.0-alpha-debug-log, Binlog ver: 3 master-bin.000001 79 Query 1 79 use `test`; create table t1(f int) master-bin.000001 136 Query 1 136 use `test`; create table t2(f int) master-bin.000001 193 Query 1 193 use `test`; insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10) From d0bcc9dc0fe2b666448416d669e3dbeda78a0b38 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 10 Jan 2003 17:14:26 +0100 Subject: [PATCH 15/83] Removed dummy SPSET construct. Setting of SP local variables is now part of the existing SET syntax. Note: This has the result that a somewhat extended syntax (from SQL-99) is allowed. We allow a list of settings ("SET a=1, b=2, ...;"), where the different variables can be of different types (SP local, system or user (@)). This also means that certain optional modifiers, such as GLOBAL, are allowed when setting an SP local variable, but then has no meaning and is ignored. --- sql/lex.h | 1 - sql/sql_yacc.yy | 72 ++++++++++++++++++++++++------------------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/sql/lex.h b/sql/lex.h index d75b63fe8d0..ccbd78dfe15 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -352,7 +352,6 @@ static SYMBOL symbols[] = { { "SONAME", SYM(UDF_SONAME_SYM),0,0}, { "SPATIAL", SYM(SPATIAL_SYM),0,0}, { "SPECIFIC", SYM(SPECIFIC_SYM),0,0}, - { "SPSET", SYM(SPSET_SYM),0,0}, /* Temp. until SET parsing solved. */ { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0}, { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0}, { "SQL_CACHE", SYM(SQL_CACHE_SYM), 0, 0}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2b7fc1dfeab..4f05d1c475b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -542,8 +542,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ASENSITIVE_SYM %token INSENSITIVE_SYM %token SENSITIVE_SYM -/* QQ This is a dummy, until we have solved the SET syntax problem. */ -%token SPSET_SYM %token ISSUER_SYM %token SUBJECT_SYM @@ -1128,27 +1126,6 @@ sp_proc_stmt: lex->sphead->add_instr(i); } } - | - /* QQ Dummy. We need to fix the old SET syntax to make it work for - local SP variables as well. */ - SPSET_SYM ident EQ expr - { - LEX *lex= Lex; - sp_pcontext *spc= lex->spcont; - sp_pvar_t *spv; - - if (!spc || !(spv = spc->find_pvar(&$2))) - YYABORT; /* Unknow variable */ - else - { - /* QQ Check type match! */ - sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(), - spv->offset, $4, spv->type); - - lex->sphead->add_instr(i); - spv->isset= TRUE; - } - } ; sp_if: @@ -4467,15 +4444,12 @@ opt_var_ident_type: ; option_value: - '@' ident_or_text equal expr - { - Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); - } - | internal_variable_name equal set_expr_or_default + '@' ident_or_text equal expr { - LEX *lex=Lex; - lex->var_list.push_back(new set_var(lex->option_type, $1, $3)); + Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); } + | internal_or_splocal + {} | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default { LEX *lex=Lex; @@ -4489,12 +4463,12 @@ option_value: new Item_int((int32) $4))); } | CHAR_SYM SET opt_equal set_expr_or_default - { - LEX *lex=Lex; - lex->var_list.push_back(new set_var(lex->option_type, - find_sys_var("convert_character_set"), - $4)); - } + { + LEX *lex=Lex; + lex->var_list.push_back(new set_var(lex->option_type, + find_sys_var("convert_character_set"), + $4)); + } | PASSWORD equal text_or_password { THD *thd=YYTHD; @@ -4521,6 +4495,32 @@ internal_variable_name: } ; +internal_or_splocal: + ident equal set_expr_or_default + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + if (!spc || !(spv = spc->find_pvar(&$1))) + { /* Not an SP local variable */ + sys_var *tmp= find_sys_var($1.str, $1.length); + + if (!tmp) + YYABORT; + lex->var_list.push_back(new set_var(lex->option_type, tmp, $3)); + } + else + { /* An SP local variable */ + sp_instr_set *i= new sp_instr_set(lex->sphead->instructions(), + spv->offset, $3, spv->type); + + lex->sphead->add_instr(i); + spv->isset= TRUE; + } + } + ; + isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; } From b863798a7ccd1829a88459748d153f547f0298b8 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 15 Jan 2003 15:39:36 +0100 Subject: [PATCH 16/83] Fixed some basic error handling for SP functions in mysql_execute_command(). --- include/mysqld_error.h | 6 ++- sql/mysql_priv.h | 2 +- sql/share/czech/errmsg.txt | 6 ++- sql/share/danish/errmsg.txt | 6 ++- sql/share/dutch/errmsg.txt | 6 ++- sql/share/english/errmsg.txt | 7 ++- sql/share/estonian/errmsg.txt | 6 ++- sql/share/french/errmsg.txt | 6 ++- sql/share/german/errmsg.txt | 6 ++- sql/share/greek/errmsg.txt | 6 ++- sql/share/hungarian/errmsg.txt | 6 ++- sql/share/italian/errmsg.txt | 6 ++- sql/share/japanese/errmsg.txt | 6 ++- sql/share/korean/errmsg.txt | 6 ++- sql/share/norwegian-ny/errmsg.txt | 6 ++- sql/share/norwegian/errmsg.txt | 6 ++- sql/share/polish/errmsg.txt | 6 ++- sql/share/portuguese/errmsg.txt | 6 ++- sql/share/romanian/errmsg.txt | 6 ++- sql/share/russian/errmsg.txt | 6 ++- sql/share/serbian/errmsg.txt | 6 ++- sql/share/slovak/errmsg.txt | 6 ++- sql/share/spanish/errmsg.txt | 6 ++- sql/share/swedish/errmsg.txt | 6 ++- sql/share/ukrainian/errmsg.txt | 6 ++- sql/sp_head.cc | 10 ++-- sql/sql_parse.cc | 81 +++++++++++++++++++------------ 27 files changed, 175 insertions(+), 63 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 377f714bfff..a339f44b258 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -266,4 +266,8 @@ #define ER_SELECT_REDUCED 1247 #define ER_TABLENAME_NOT_ALLOWED_HERE 1248 #define ER_NOT_SUPPORTED_AUTH_MODE 1249 -#define ER_ERROR_MESSAGES 250 +#define ER_SP_NO_RECURSIVE_CREATE 1250 +#define ER_SP_ALREADY_EXISTS 1251 +#define ER_SP_DOES_NOT_EXIST 1252 +#define ER_SP_DROP_FAILED 1253 +#define ER_ERROR_MESSAGES 254 diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 655e4d7b972..27115a2c252 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -349,7 +349,7 @@ extern "C" pthread_handler_decl(handle_one_connection,arg); extern "C" pthread_handler_decl(handle_bootstrap,arg); void end_thread(THD *thd,bool put_in_cache); void flush_thread_cache(); -void mysql_execute_command(THD *thd); +int mysql_execute_command(THD *thd); bool do_command(THD *thd); bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length); diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 6c3196bfeba..d56f043b78f 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -259,4 +259,8 @@ v/* "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index dcc016511dd..9eea7e96e90 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -253,4 +253,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 6091616fc4a..8ae5806594a 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -261,4 +261,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 465992e63b2..76acfc558ff 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -250,4 +250,9 @@ "Every derived table must have it's own alias", "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 43eb5de89a5..5caa6e8206c 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -255,4 +255,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index d7bb19c2876..eb5c147b35a 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -250,4 +250,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 765fbd875e2..a13e2988335 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -260,4 +260,8 @@ "Für jede abgeleitete Tabelle muss ein eigener Alias angegeben werden.", "Select %u wurde während der Optimierung reduziert.", "Tabelle '%-.64s', die in einem der SELECT-Befehle verwendet wurde kann nicht in %-.32s verwendet werden." -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 8831d4e47b9..c71559ba363 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -250,4 +250,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 8d6c321d316..0a570ea4879 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -252,4 +252,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 451ad3e058b..9a1f7bd5e7f 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -250,4 +250,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 70ab2d6d42d..d110d9a766a 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -252,4 +252,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index c18c3ed3873..896f359a30a 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -250,4 +250,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 9cd99613f52..d2f6c4816c2 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -252,4 +252,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 32fe6c30b34..7132e49b00b 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -252,4 +252,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 4b59a62f991..f7657e67dfa 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -254,4 +254,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 7236bd86652..8b7d9c76d14 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -250,4 +250,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 0b8bbe1c219..4bd79d1b905 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -254,4 +254,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 2f1eedd207c..dd941428dfc 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -253,4 +253,8 @@ "Every derived table must have it's own alias" "Select %u ÂÙÌ ÕÐÒÁÚÄÎÅÎ × ÐÒÏÃÅÓÓÅ ÏÐÔÉÍÉÚÁÃÉÉ", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 75cfd73f3f0..8739f7bfa34 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -246,4 +246,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index de354f234c7..212ea72c727 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -258,4 +258,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index a528c3e6b36..87934beb754 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -251,4 +251,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 5473f4e8e42..c4964688102 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -250,4 +250,8 @@ "Every derived table must have it's own alias" "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 0b91786d1f3..0d8f89ac431 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -255,4 +255,8 @@ "Every derived table must have it's own alias" "Select %u was ÓËÁÓÏ×ÁÎÏ ÐÒÉ ÏÐÔÉÍiÚÁÃii", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" \ No newline at end of file +"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" +"Can't create a PROCEDURE from within a PROCEDURE" +"PROCEDURE already exists" +"PROCEDURE does not exist" +"Failed to DROP PROCEDURE" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fdccedc788f..621b31f5e11 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -157,9 +157,6 @@ sp_head::execute(THD *thd) { // Execute instructions... uint ip= 0; - my_bool nsok= thd->net.no_send_ok; - - thd->net.no_send_ok= TRUE; // Don't send_ok() during execution while (ret == 0) { @@ -170,8 +167,6 @@ sp_head::execute(THD *thd) break; ret= i->execute(thd, &ip); } - - thd->net.no_send_ok= nsok; } // Don't copy back OUT values if we got an error @@ -323,18 +318,19 @@ int sp_instr_stmt::execute(THD *thd, uint *nextp) { LEX olex; // The other lex + int res; memcpy(&olex, &thd->lex, sizeof(LEX)); // Save the other lex memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Use my own lex thd->lex.thd = thd; - mysql_execute_command(thd); + res= mysql_execute_command(thd); memcpy(&thd->lex, &olex, sizeof(LEX)); // Restore the other lex *nextp = m_ip+1; - return 0; + return res; } // diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0c32aca4b37..b82846706a8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1482,7 +1482,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) ** Execute command saved in thd and current_lex->sql_command ****************************************************************************/ -void +int mysql_execute_command(THD *thd) { int res= 0; @@ -1513,7 +1513,7 @@ mysql_execute_command(THD *thd) given and the table list says the query should not be replicated */ if (table_rules_on && tables && !tables_ok(thd,tables)) - DBUG_VOID_RETURN; + return 0; #ifndef TO_BE_DELETED /* This is a workaround to deal with the shortcoming in 3.23.44-3.23.46 @@ -1549,7 +1549,7 @@ mysql_execute_command(THD *thd) { if (res < 0 || thd->net.report_error) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); - DBUG_VOID_RETURN; + return res; } } } @@ -1558,7 +1558,7 @@ mysql_execute_command(THD *thd) lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) - DBUG_VOID_RETURN; + return 0; statistic_increment(com_stat[lex->sql_command],&LOCK_status); switch (lex->sql_command) { @@ -1597,7 +1597,7 @@ mysql_execute_command(THD *thd) if (!(result= new select_send())) { send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_VOID_RETURN; + goto error; } else thd->send_explain_fields(result); @@ -1838,7 +1838,7 @@ mysql_execute_command(THD *thd) find_real_table_in_list(tables->next, tables->db, tables->real_name)) { net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name); - DBUG_VOID_RETURN; + return -1; } if (tables->next) { @@ -1918,7 +1918,7 @@ mysql_execute_command(THD *thd) if (thd->locked_tables || thd->active_transaction()) { send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); - break; + goto error; } { LOCK_ACTIVE_MI; @@ -1929,7 +1929,7 @@ mysql_execute_command(THD *thd) case SQLCOM_ALTER_TABLE: #if defined(DONT_ALLOW_SHOW_COMMANDS) send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - break; + goto error; #else { ulong priv=0; @@ -2019,7 +2019,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_BINLOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { if (check_global_access(thd, SUPER_ACL)) @@ -2031,7 +2031,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_CREATE: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { if (check_db_used(thd, tables) || @@ -2103,7 +2103,7 @@ mysql_execute_command(THD *thd) if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); - DBUG_VOID_RETURN; + goto error; } res= mysql_update(thd,tables, select_lex->item_list, @@ -2123,7 +2123,7 @@ mysql_execute_command(THD *thd) if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); - DBUG_VOID_RETURN; + goto error; } { const char *msg= 0; @@ -2159,7 +2159,7 @@ mysql_execute_command(THD *thd) if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); - DBUG_VOID_RETURN; + goto error; } res = mysql_insert(thd,tables,lex->field_list,lex->many_values, select_lex->item_list, lex->value_list, @@ -2199,7 +2199,7 @@ mysql_execute_command(THD *thd) if (find_real_table_in_list(tables->next, tables->db, tables->real_name)) { net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name); - DBUG_VOID_RETURN; + return -1; } /* Skip first table, which is the table we are inserting in */ @@ -2357,7 +2357,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_DATABASES: #if defined(DONT_ALLOW_SHOW_COMMANDS) send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else if ((specialflag & SPECIAL_SKIP_SHOW_DB) && check_global_access(thd, SHOW_DB_ACL)) @@ -2391,7 +2391,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_LOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { if (grant_option && check_access(thd, FILE_ACL, any_db)) @@ -2404,7 +2404,7 @@ mysql_execute_command(THD *thd) /* FALL THROUGH */ #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { char *db=select_lex->db ? select_lex->db : thd->db; @@ -2440,7 +2440,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_FIELDS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { char *db=tables->db; @@ -2465,7 +2465,7 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_KEYS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { char *db=tables->db; @@ -2813,13 +2813,17 @@ mysql_execute_command(THD *thd) break; case SQLCOM_CREATE_PROCEDURE: if (!lex->sphead) - res= -1; + { + send_error(thd, ER_SP_NO_RECURSIVE_CREATE); + goto error; + } else { res= lex->sphead->create(thd); - if (res < 0) + if (res != 0) { - // QQ Error! + send_error(thd, ER_SP_ALREADY_EXISTS); + goto error; } send_ok(thd); } @@ -2833,14 +2837,23 @@ mysql_execute_command(THD *thd) sp= sp_find(thd, s); if (! sp) { - // QQ Error! - res= -1; + send_error(thd, ER_SP_DOES_NOT_EXIST); + goto error; } else { + // When executing substatements, they're assumed to send_error when + // it happens, but not to send_ok. + my_bool nsok= thd->net.no_send_ok; + + thd->net.no_send_ok= TRUE; res= sp->execute(thd); + thd->net.no_send_ok= nsok; + if (res == 0) send_ok(thd); + else + goto error; // Substatement should already have sent error } } break; @@ -2853,8 +2866,8 @@ mysql_execute_command(THD *thd) sp= sp_find(thd, s); if (! sp) { - // QQ Error! - res= -1; + send_error(thd, ER_SP_DOES_NOT_EXIST); + goto error; } else { @@ -2873,17 +2886,18 @@ mysql_execute_command(THD *thd) sp = sp_find(thd, s); if (! sp) { - // QQ Error! - res= -1; + send_error(thd, ER_SP_DOES_NOT_EXIST); + goto error; } else { String *name = s->const_string(); res= sp_drop(thd, name->c_ptr(), name->length()); - if (res < 0) + if (res != 0) { - // QQ Error! + send_error(thd, ER_SP_DROP_FAILED); + goto error; } send_ok(thd); } @@ -2894,11 +2908,16 @@ mysql_execute_command(THD *thd) break; } thd->proc_info="query end"; // QQ + + // We end up here if res == 0 and send_ok() has been done, + // or res != 0 and no send_error() has yet been done. if (res < 0) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + return res; error: - DBUG_VOID_RETURN; + // We end up here if send_error() has already been done. + return -1; } From 0f9e2c36c33c13d58b82daa5895fe13114e46903 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 15 Jan 2003 18:06:07 +0100 Subject: [PATCH 17/83] Fixed some error handling in the SP parts of the parser. --- include/mysqld_error.h | 9 ++++++++- sql/share/czech/errmsg.txt | 6 ++++++ sql/share/danish/errmsg.txt | 6 ++++++ sql/share/dutch/errmsg.txt | 6 ++++++ sql/share/english/errmsg.txt | 7 ++++++- sql/share/estonian/errmsg.txt | 6 ++++++ sql/share/french/errmsg.txt | 6 ++++++ sql/share/german/errmsg.txt | 6 ++++++ sql/share/greek/errmsg.txt | 6 ++++++ sql/share/hungarian/errmsg.txt | 6 ++++++ sql/share/italian/errmsg.txt | 6 ++++++ sql/share/japanese/errmsg.txt | 6 ++++++ sql/share/korean/errmsg.txt | 6 ++++++ sql/share/norwegian-ny/errmsg.txt | 6 ++++++ sql/share/norwegian/errmsg.txt | 6 ++++++ sql/share/polish/errmsg.txt | 6 ++++++ sql/share/portuguese/errmsg.txt | 6 ++++++ sql/share/romanian/errmsg.txt | 6 ++++++ sql/share/russian/errmsg.txt | 6 ++++++ sql/share/serbian/errmsg.txt | 6 ++++++ sql/share/slovak/errmsg.txt | 6 ++++++ sql/share/spanish/errmsg.txt | 6 ++++++ sql/share/swedish/errmsg.txt | 6 ++++++ sql/share/ukrainian/errmsg.txt | 6 ++++++ sql/sql_yacc.yy | 19 +++++++------------ 25 files changed, 153 insertions(+), 14 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index a339f44b258..e540b8371d8 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -270,4 +270,11 @@ #define ER_SP_ALREADY_EXISTS 1251 #define ER_SP_DOES_NOT_EXIST 1252 #define ER_SP_DROP_FAILED 1253 -#define ER_ERROR_MESSAGES 254 +#define ER_SP_STORE_FAILED 1254 +#define ER_SP_LEAVE_MISMATCH 1255 +#define ER_SP_ITERATE_MISMATCH 1256 +#define ER_SP_LABEL_REDEFINE 1257 +#define ER_SP_LABEL_MISMATCH 1258 +#define ER_SP_UNINIT_VAR 1259 +#define ER_ERROR_MESSAGES 260 + diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index d56f043b78f..79dae19dbc8 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -264,3 +264,9 @@ v/* "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 9eea7e96e90..a77c2b59622 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -258,3 +258,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 8ae5806594a..5f78ba6c21d 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -266,3 +266,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 76acfc558ff..9fe52f075dc 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -255,4 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" +"Failed to CREATE PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 5caa6e8206c..8202d782408 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -260,3 +260,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index eb5c147b35a..799cb76d8c0 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -255,3 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index a13e2988335..d6c9a2fb8ed 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -265,3 +265,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index c71559ba363..c78d410df83 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -255,3 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 0a570ea4879..b42c4a87c4f 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -257,3 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 9a1f7bd5e7f..937f2d41379 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -255,3 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index d110d9a766a..136e4c77fb6 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -257,3 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 896f359a30a..08c496984a8 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -255,3 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index d2f6c4816c2..7c7387da2fe 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -257,3 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 7132e49b00b..fc42860af0d 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -257,3 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index f7657e67dfa..f907222ea28 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -259,3 +259,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 8b7d9c76d14..a26d6dae971 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -255,3 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 4bd79d1b905..e2ac7eade01 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -259,3 +259,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index dd941428dfc..8d350e62f00 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -258,3 +258,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 8739f7bfa34..e12c2953805 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -251,3 +251,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 212ea72c727..391b531cfdb 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -263,3 +263,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 87934beb754..528c89893cc 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -256,3 +256,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index c4964688102..e8f1d4eec0f 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -255,3 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 0d8f89ac431..965da3cd29d 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -260,3 +260,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" +"Failed to store PROCEDURE" +"LEAVE with no matching label" +"ITERATE with no matching label" +"Redefining label" +"End-label without match" +"Referring to uninitialized variable" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4f05d1c475b..2cc2f674d4a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1097,7 +1097,7 @@ sp_proc_stmt: if (! lab) { - printf("QQ LEAVE with no matching label\n"); + send_error(YYTHD, ER_SP_LEAVE_MISMATCH); YYABORT; } else @@ -1115,7 +1115,7 @@ sp_proc_stmt: if (! lab) { - printf("QQ ITERATE with no matching label\n"); + send_error(YYTHD, ER_SP_ITERATE_MISMATCH); YYABORT; } else @@ -1217,7 +1217,7 @@ sp_labeled_control: if (lab) { - printf("QQ Redefining label\n"); + send_error(YYTHD, ER_SP_LABEL_REDEFINE); YYABORT; } else @@ -1231,14 +1231,9 @@ sp_labeled_control: LEX *lex= Lex; sp_label_t *lab= lex->spcont->find_label($5.str); - if (! lab) + if (! lab || strcasecmp($5.str, lab->name) != 0) { - printf("QQ end-label without match\n"); - YYABORT; - } - else if (strcasecmp($5.str, lab->name) != 0) - { - printf("QQ mismatching labels\n"); + send_error(YYTHD, ER_SP_LABEL_MISMATCH); YYABORT; } else @@ -4158,8 +4153,8 @@ simple_ident: { /* We're compiling a stored procedure and found a variable */ if (lex->sql_command != SQLCOM_CALL && ! spv->isset) { - printf("QQ Referring to an unitialized variable\n"); - YYABORT; /* QQ Referring to an unitialized variable */ + send_error(YYTHD, ER_SP_UNINIT_VAR); + YYABORT; } else $$ = (Item*) new Item_splocal(spv->offset); From bdac148469c44843e408423c8b1465b5fb521bcf Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Fri, 17 Jan 2003 14:48:58 +0400 Subject: [PATCH 18/83] Make the CLI client (client/mysql.cc) work with multi-line SPs. Make the mysqltest program (client/mysqltest.c) work with multi-line SPs. --- BitKeeper/etc/logging_ok | 1 + client/mysql.cc | 46 +++++++++++++++++++++++++++++----- client/mysqltest.c | 27 ++++++++++++++++---- mysql-test/install_test_db.sh | 14 +++++++++++ mysql-test/r/connect.result | 3 +++ mysql-test/r/mysql_proc.result | 22 ++++++++++++++++ mysql-test/t/mysql_proc.test | 21 ++++++++++++++++ 7 files changed, 123 insertions(+), 11 deletions(-) create mode 100644 mysql-test/r/mysql_proc.result create mode 100644 mysql-test/t/mysql_proc.test diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index e3da1e2292e..2e693cab134 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -17,6 +17,7 @@ bell@sanja.is.com.ua bk@admin.bk davida@isil.mysql.com gluh@gluh.(none) +gluh@gluh.mysql.r18.ru heikki@donna.mysql.fi heikki@hundin.mysql.fi heikki@rescue. diff --git a/client/mysql.cc b/client/mysql.cc index 58aee617107..2f8f2b821b7 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -100,6 +100,7 @@ extern "C" { #include "completion_hash.h" #define PROMPT_CHAR '\\' +#define DEFAULT_DELIMITER ';' typedef struct st_status { @@ -151,6 +152,7 @@ static char pager[FN_REFLEN], outfile[FN_REFLEN]; static FILE *PAGER, *OUTFILE; static MEM_ROOT hash_mem_root; static uint prompt_counter; +static char delimiter= DEFAULT_DELIMITER; #ifdef HAVE_SMEM static char *shared_memory_base_name=0; @@ -177,7 +179,7 @@ static int com_quit(String *str,char*), com_use(String *str,char*), com_source(String *str, char*), com_rehash(String *str, char*), com_tee(String *str, char*), com_notee(String *str, char*), com_shell(String *str, char *), - com_prompt(String *str, char*); + com_prompt(String *str, char*), com_delimiter(String *str, char*); #ifndef __WIN__ static int com_nopager(String *str, char*), com_pager(String *str, char*), @@ -245,7 +247,8 @@ static COMMANDS commands[] = { "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, - + { "delimiter", 'd', com_delimiter, 1, + "Set query delimiter. " }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, @@ -911,7 +914,7 @@ static COMMANDS *find_command (char *name,char cmd_char) { while (my_isspace(system_charset_info,*name)) name++; - if (strchr(name,';') || strstr(name,"\\g")) + if (strchr(name, delimiter) || strstr(name,"\\g")) return ((COMMANDS *) 0); if ((end=strcont(name," \t"))) { @@ -989,7 +992,7 @@ static bool add_line(String &buffer,char *line,char *in_string, return 1; // Quit if (com->takes_params) { - for (pos++ ; *pos && *pos != ';' ; pos++) ; // Remove parameters + for (pos++ ; *pos && *pos != delimiter; pos++) ; // Remove parameters if (!*pos) pos--; } @@ -1005,7 +1008,7 @@ static bool add_line(String &buffer,char *line,char *in_string, continue; } } - else if (!*ml_comment && inchar == ';' && !*in_string) + else if (!*ml_comment && inchar == delimiter && !*in_string) { // ';' is end of command if (out != line) buffer.append(line,(uint) (out-line)); // Add this line @@ -1514,7 +1517,7 @@ com_help (String *buffer __attribute__((unused)), for (i = 0; commands[i].name; i++) { if (commands[i].func) - tee_fprintf(stdout, "%s\t(\\%c)\t%s\n", commands[i].name, + tee_fprintf(stdout, "%-10s(\\%c)\t%s\n", commands[i].name, commands[i].cmd_char, commands[i].doc); } if (connected) @@ -2324,6 +2327,37 @@ static int com_source(String *buffer, char *line) return error; } + /* ARGSUSED */ +static int +com_delimiter(String *buffer __attribute__((unused)), char *line) +{ + char *tmp; + char buff[256]; + + if (strlen(line)> 255) + { + put_info("'DELIMITER' command was too long.", INFO_ERROR); + return 0; + } + bzero(buff, sizeof(buff)); + strmov(buff, line); + tmp= get_arg(buff, 0); + + if (!tmp || !*tmp) + { + put_info("DELIMITER must be followed by a 'delimiter' char", INFO_ERROR); + return 0; + } + + if (strlen(tmp)> 1) + { + put_info("Argument must be one char", INFO_ERROR); + return 0; + } + + delimiter= *tmp; + return 0; +} /* ARGSUSED */ static int diff --git a/client/mysqltest.c b/client/mysqltest.c index ed95efc282e..8a79c262a8c 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -89,6 +89,7 @@ #define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */ +#define DEFAULT_DELIMITER ';' enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD, OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC}; @@ -123,6 +124,8 @@ static int block_stack[BLOCK_STACK_DEPTH]; static int block_ok_stack[BLOCK_STACK_DEPTH]; static uint global_expected_errno[MAX_EXPECTED_ERRORS], global_expected_errors; +static char delimiter= DEFAULT_DELIMITER; + DYNAMIC_ARRAY q_lines; typedef struct @@ -197,7 +200,7 @@ Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER, Q_WAIT_FOR_SLAVE_TO_STOP, Q_REQUIRE_VERSION, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, -Q_ENABLE_INFO, Q_DISABLE_INFO, +Q_ENABLE_INFO, Q_DISABLE_INFO, Q_DELIMITER, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND @@ -260,6 +263,7 @@ const char *command_names[]= "disable_warnings", "enable_info", "diable_info", + "delimiter", 0 }; @@ -1537,6 +1541,16 @@ int do_while(struct st_query* q) return 0; } +int do_delimiter(char *p) +{ + while (*p && my_isspace(system_charset_info,*p)) + p++; + if (!*p) + die("Missing delimiter character\n"); + delimiter=*p; + + return 0; +} int safe_copy_unescape(char* dest, char* src, int size) { @@ -1616,7 +1630,7 @@ int read_line(char* buf, int size) switch(state) { case R_NORMAL: /* Only accept '{' in the beginning of a line */ - if (c == ';') + if (c == delimiter) { *p = 0; return 0; @@ -1656,7 +1670,7 @@ int read_line(char* buf, int size) *buf = 0; return 0; } - else if (c == ';' || c == '{') + else if (c == delimiter || c == '{') { *p = 0; return 0; @@ -1676,7 +1690,7 @@ int read_line(char* buf, int size) state = R_ESC_SLASH_Q1; break; case R_ESC_Q_Q1: - if (c == ';') + if (c == delimiter) { *p = 0; return 0; @@ -1697,7 +1711,7 @@ int read_line(char* buf, int size) state = R_ESC_SLASH_Q2; break; case R_ESC_Q_Q2: - if (c == ';') + if (c == delimiter) { *p = 0; return 0; @@ -2543,6 +2557,9 @@ int main(int argc, char** argv) do_sync_with_master2(""); break; } + case Q_DELIMITER: + do_delimiter(q->first_argument); + break; case Q_COMMENT: /* Ignore row */ case Q_COMMENT_WITH_COMMAND: case Q_PING: diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index 990c763efc8..d6e40b98ccc 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -66,6 +66,7 @@ c_h="" i_h="" c_u="" i_u="" c_f="" i_f="" c_t="" c_c="" +c_p="" # Check for old tables if test ! -f $mdata/db.frm @@ -207,6 +208,16 @@ then c_c="$c_c comment='Column privileges';" fi +if test ! -f $mdata/proc.frm +then + c_p="$c_p CREATE TABLE proc (" + c_p="$c_p name char(64) binary DEFAULT '' NOT NULL," + c_p="$c_p body blob DEFAULT '' NOT NULL," + c_p="$c_p PRIMARY KEY (name)" + c_p="$c_p )" + c_p="$c_p comment='Stored Procedures';" +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" @@ -227,6 +238,9 @@ $i_f $c_t $c_c + +$c_p + END_OF_DATA then exit 0 diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index 3e9091462d8..e799af58fc2 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -4,6 +4,7 @@ columns_priv db func host +proc tables_priv user show tables; @@ -16,6 +17,7 @@ columns_priv db func host +proc tables_priv user show tables; @@ -28,6 +30,7 @@ columns_priv db func host +proc tables_priv user show tables; diff --git a/mysql-test/r/mysql_proc.result b/mysql-test/r/mysql_proc.result new file mode 100644 index 00000000000..7820b476104 --- /dev/null +++ b/mysql-test/r/mysql_proc.result @@ -0,0 +1,22 @@ +drop table if exists t1; +create table t1(a1 char(10)); +create procedure a() +begin +insert into t1 values("aa"); +insert into t1 values("ab"); +end; +create procedure b() +begin +insert into t1 values("ba"); +insert into t1 values("bb"); +insert into t1 values("cc"); +end; +call a(); +call b(); +select * from t1; +a1 +aa +ab +ba +bb +cc diff --git a/mysql-test/t/mysql_proc.test b/mysql-test/t/mysql_proc.test new file mode 100644 index 00000000000..aaf7c067059 --- /dev/null +++ b/mysql-test/t/mysql_proc.test @@ -0,0 +1,21 @@ +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1(a1 char(10)); +delimiter |; +create procedure a() +begin +insert into t1 values("aa"); +insert into t1 values("ab"); +end| +create procedure b() +begin +insert into t1 values("ba"); +insert into t1 values("bb"); +insert into t1 values("cc"); +end| +delimiter ;| +call a(); +call b(); +select * from t1; From 4b0adb203b35a3313cd4614053c7935aa70b1ddc Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 17 Jan 2003 14:38:05 +0100 Subject: [PATCH 19/83] Added the Stored Procedure tests. Removed newly added, but now redundant, test file. --- mysql-test/r/mysql_proc.result | 22 --- mysql-test/r/sp.result | 261 +++++++++++++++++++++++++++++ mysql-test/t/mysql_proc.test | 21 --- mysql-test/t/sp.test | 290 +++++++++++++++++++++++++++++++++ 4 files changed, 551 insertions(+), 43 deletions(-) delete mode 100644 mysql-test/r/mysql_proc.result create mode 100644 mysql-test/r/sp.result delete mode 100644 mysql-test/t/mysql_proc.test create mode 100644 mysql-test/t/sp.test diff --git a/mysql-test/r/mysql_proc.result b/mysql-test/r/mysql_proc.result deleted file mode 100644 index 7820b476104..00000000000 --- a/mysql-test/r/mysql_proc.result +++ /dev/null @@ -1,22 +0,0 @@ -drop table if exists t1; -create table t1(a1 char(10)); -create procedure a() -begin -insert into t1 values("aa"); -insert into t1 values("ab"); -end; -create procedure b() -begin -insert into t1 values("ba"); -insert into t1 values("bb"); -insert into t1 values("cc"); -end; -call a(); -call b(); -select * from t1; -a1 -aa -ab -ba -bb -cc diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result new file mode 100644 index 00000000000..0e2dfc52c52 --- /dev/null +++ b/mysql-test/r/sp.result @@ -0,0 +1,261 @@ +use test; +drop table if exists t1; +create table t1 ( +id char(16) not null, +data int not null +); +create procedure foo42() +insert into test.t1 values ("foo", 42); +create procedure bar(x char(16), y int) +insert into test.t1 values (x, y); +create procedure two(x1 char(16), x2 char(16), y int) +begin +insert into test.t1 values (x1, y); +insert into test.t1 values (x2, y); +end; +create procedure locset(x char(16), y int) +begin +declare z1, z2 int; +set z1 = y; +set z2 = z1+2; +insert into test.t1 values (x, z2); +end; +create procedure mixset(x char(16), y int) +begin +declare z int; +set @z = y, z = 666, max_join_size = 100; +insert into test.t1 values (x, z); +end; +create procedure zip(x char(16), y int) +begin +declare z int; +call zap(y, z); +call bar(x, z); +end; +create procedure zap(x int, out y int) +begin +declare z int; +set z = x+1, y = z; +end; +create procedure iotest(x1 char(16), x2 char(16), y int) +begin +call inc2(x2, y); +insert into test.t1 values (x1, y); +end; +create procedure inc2(x char(16), y int) +begin +call inc(y); +insert into test.t1 values (x, y); +end; +create procedure inc(inout io int) +set io = io + 1; +create procedure cbv1() +begin +declare y int; +set y = 3; +call cbv2(y+1, y); +insert into test.t1 values ("cbv1", y); +end; +create procedure cbv2(y1 int, inout y2 int) +begin +set y2 = 4711; +insert into test.t1 values ("cbv2", y1); +end; +create procedure a0(x int) +while x do +set x = x-1; +insert into test.t1 values ("a0", x); +end while; +create procedure a(x int) +while x > 0 do +set x = x-1; +insert into test.t1 values ("a", x); +end while; +create procedure b(x int) +sprepeat +insert into test.t1 values ("b", x); +set x = x-1; +until x = 0 end sprepeat; +create procedure c(x int) +hmm: while x > 0 do +insert into test.t1 values ("c", x); +set x = x-1; +iterate hmm; +insert into test.t1 values ("x", x); +end while hmm; +create procedure d(x int) +hmm: while x > 0 do +insert into test.t1 values ("d", x); +set x = x-1; +leave hmm; +insert into test.t1 values ("x", x); +end while hmm; +create procedure e(x int) +foo: loop +if x = 0 then +leave foo; +end if; +insert into test.t1 values ("e", x); +set x = x-1; +end loop foo; +create procedure f(x int) +if x < 0 then +insert into test.t1 values ("f", 0); +elseif x = 0 then +insert into test.t1 values ("f", 1); +else +insert into test.t1 values ("f", 2); +end if; +create procedure g(x int) +case +when x < 0 then +insert into test.t1 values ("g", 0); +when x = 0 then +insert into test.t1 values ("g", 1); +else +insert into test.t1 values ("g", 2); +end case; +create procedure h(x int) +case x +when 0 then +insert into test.t1 values ("h0", x); +when 1 then +insert into test.t1 values ("h1", x); +else +insert into test.t1 values ("h?", x); +end case; +call foo42(); +select * from t1; +id data +foo 42 +delete from t1; +call bar("bar", 666); +select * from t1; +id data +bar 666 +delete from t1; +call two("one", "two", 3); +select * from t1; +id data +one 3 +two 3 +delete from t1; +call locset("locset", 19); +select * from t1; +id data +locset 21 +delete from t1; +call mixset("mixset", 19); +show variables like 'max_join_size'; +Variable_name Value +max_join_size 100 +select id,data,@z from t1; +id data @z +mixset 666 19 +delete from t1; +call zip("zip", 99); +select * from t1; +id data +zip 100 +delete from t1; +call iotest("io1", "io2", 1); +select * from t1; +id data +io2 2 +io1 1 +delete from t1; +call cbv1(); +select * from t1; +id data +cbv2 4 +cbv1 4711 +delete from t1; +call a0(3); +select * from t1; +id data +a0 2 +a0 1 +a0 0 +delete from t1; +call a(3); +select * from t1; +id data +a 2 +a 1 +a 0 +delete from t1; +call b(3); +select * from t1; +id data +b 3 +b 2 +b 1 +delete from t1; +call c(3); +select * from t1; +id data +c 3 +c 2 +c 1 +delete from t1; +call d(3); +select * from t1; +id data +d 3 +delete from t1; +call e(3); +select * from t1; +id data +e 3 +e 2 +e 1 +delete from t1; +call f(-2); +call f(0); +call f(4); +select * from t1; +id data +f 0 +f 1 +f 2 +delete from t1; +call g(-42); +call g(0); +call g(1); +select * from t1; +id data +g 0 +g 1 +g 2 +delete from t1; +call h(0); +call h(1); +call h(17); +select * from t1; +id data +h0 0 +h1 1 +h? 17 +delete from t1; +drop procedure foo42; +drop procedure bar; +drop procedure two; +drop procedure locset; +drop procedure mixset; +drop procedure zip; +drop procedure zap; +drop procedure iotest; +drop procedure inc2; +drop procedure inc; +drop procedure cbv1; +drop procedure cbv2; +drop procedure a0; +drop procedure a; +drop procedure b; +drop procedure c; +drop procedure d; +drop procedure e; +drop procedure f; +drop procedure g; +drop procedure h; +drop table t1; diff --git a/mysql-test/t/mysql_proc.test b/mysql-test/t/mysql_proc.test deleted file mode 100644 index aaf7c067059..00000000000 --- a/mysql-test/t/mysql_proc.test +++ /dev/null @@ -1,21 +0,0 @@ ---disable_warnings -drop table if exists t1; ---enable_warnings - -create table t1(a1 char(10)); -delimiter |; -create procedure a() -begin -insert into t1 values("aa"); -insert into t1 values("ab"); -end| -create procedure b() -begin -insert into t1 values("ba"); -insert into t1 values("bb"); -insert into t1 values("cc"); -end| -delimiter ;| -call a(); -call b(); -select * from t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test new file mode 100644 index 00000000000..6b90d700b58 --- /dev/null +++ b/mysql-test/t/sp.test @@ -0,0 +1,290 @@ +# +# Basic stored PROCEDURE tests +# +# + +use test; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 ( + id char(16) not null, + data int not null +); + +# Single statement, no params. +create procedure foo42() + insert into test.t1 values ("foo", 42); + +# Single statement, two IN params. +create procedure bar(x char(16), y int) + insert into test.t1 values (x, y); + +# Now for multiple statements... + +delimiter |; + +# Two statements. +create procedure two(x1 char(16), x2 char(16), y int) +begin + insert into test.t1 values (x1, y); + insert into test.t1 values (x2, y); +end| + +# Simple test of local variables and SET. +create procedure locset(x char(16), y int) +begin + declare z1, z2 int; + set z1 = y; + set z2 = z1+2; + insert into test.t1 values (x, z2); +end| + +# The peculiar (non-standard) mixture of variables types in SET. +create procedure mixset(x char(16), y int) +begin + declare z int; + + set @z = y, z = 666, max_join_size = 100; + insert into test.t1 values (x, z); +end| + +# Multiple CALL statements, one with OUT parameter. +create procedure zip(x char(16), y int) +begin + declare z int; + call zap(y, z); + call bar(x, z); +end| + +# SET local variables and OUT parameter. +create procedure zap(x int, out y int) +begin + declare z int; + set z = x+1, y = z; +end| + + +# INOUT test +create procedure iotest(x1 char(16), x2 char(16), y int) +begin + call inc2(x2, y); + insert into test.t1 values (x1, y); +end| + +create procedure inc2(x char(16), y int) +begin + call inc(y); + insert into test.t1 values (x, y); +end| + +create procedure inc(inout io int) + set io = io + 1| + + +# Call-by-value test +# The expected result is: +# ("cbv2", 4) +# ("cbv1", 4711) +create procedure cbv1() +begin + declare y int; + + set y = 3; + call cbv2(y+1, y); + insert into test.t1 values ("cbv1", y); +end| + +create procedure cbv2(y1 int, inout y2 int) +begin + set y2 = 4711; + insert into test.t1 values ("cbv2", y1); +end| + + +# Minimal tests of the flow control construts + +# Just test on 'x'... +create procedure a0(x int) +while x do + set x = x-1; + insert into test.t1 values ("a0", x); +end while| + +# The same, but with a more traditional test. +create procedure a(x int) +while x > 0 do + set x = x-1; + insert into test.t1 values ("a", x); +end while| + +# REPEAT +create procedure b(x int) +sprepeat + insert into test.t1 values ("b", x); + set x = x-1; +until x = 0 end sprepeat| + +# Labelled WHILE with ITERATE (pointless really) +create procedure c(x int) +hmm: while x > 0 do + insert into test.t1 values ("c", x); + set x = x-1; + iterate hmm; + insert into test.t1 values ("x", x); +end while hmm| + +# Labelled WHILE with LEAVE +create procedure d(x int) +hmm: while x > 0 do + insert into test.t1 values ("d", x); + set x = x-1; + leave hmm; + insert into test.t1 values ("x", x); +end while hmm| + +# LOOP, with simple IF statement +create procedure e(x int) +foo: loop + if x = 0 then + leave foo; + end if; + insert into test.t1 values ("e", x); + set x = x-1; +end loop foo| + +# A full IF statement +create procedure f(x int) +if x < 0 then + insert into test.t1 values ("f", 0); +elseif x = 0 then + insert into test.t1 values ("f", 1); +else + insert into test.t1 values ("f", 2); +end if| + +# This form of CASE is really just syntactic sugar for IF-ELSEIF-... +create procedure g(x int) +case +when x < 0 then + insert into test.t1 values ("g", 0); +when x = 0 then + insert into test.t1 values ("g", 1); +else + insert into test.t1 values ("g", 2); +end case| + +# The "simple CASE" +create procedure h(x int) +case x +when 0 then + insert into test.t1 values ("h0", x); +when 1 then + insert into test.t1 values ("h1", x); +else + insert into test.t1 values ("h?", x); +end case| + +delimiter ;| + +# Now, the CALL tests... +call foo42(); +select * from t1; +delete from t1; + +call bar("bar", 666); +select * from t1; +delete from t1; + +call two("one", "two", 3); +select * from t1; +delete from t1; + +call locset("locset", 19); +select * from t1; +delete from t1; + +call mixset("mixset", 19); +show variables like 'max_join_size'; +select id,data,@z from t1; +delete from t1; + +call zip("zip", 99); +select * from t1; +delete from t1; + +call iotest("io1", "io2", 1); +select * from t1; +delete from t1; + +call cbv1(); +select * from t1; +delete from t1; + +call a0(3); +select * from t1; +delete from t1; + +call a(3); +select * from t1; +delete from t1; + +call b(3); +select * from t1; +delete from t1; + +call c(3); +select * from t1; +delete from t1; + +call d(3); +select * from t1; +delete from t1; + +call e(3); +select * from t1; +delete from t1; + +call f(-2); +call f(0); +call f(4); +select * from t1; +delete from t1; + +call g(-42); +call g(0); +call g(1); +select * from t1; +delete from t1; + +call h(0); +call h(1); +call h(17); +select * from t1; +delete from t1; + +drop procedure foo42; +drop procedure bar; +drop procedure two; +drop procedure locset; +drop procedure mixset; +drop procedure zip; +drop procedure zap; +drop procedure iotest; +drop procedure inc2; +drop procedure inc; +drop procedure cbv1; +drop procedure cbv2; +drop procedure a0; +drop procedure a; +drop procedure b; +drop procedure c; +drop procedure d; +drop procedure e; +drop procedure f; +drop procedure g; +drop procedure h; + +drop table t1; From e6b8fa57072d29131071057fb827161346cd9df0 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Sat, 18 Jan 2003 18:21:13 +0200 Subject: [PATCH 20/83] SELECT ... INTO local_vars ...; For Stored Procedures --- mysql-test/r/sp.result | 17 ++++++++++++++ mysql-test/t/sp.test | 13 +++++++++++ sql/sql_class.cc | 51 +++++++++++++++++++++++++++++++++++------- sql/sql_class.h | 13 +++++++++-- sql/sql_yacc.yy | 23 +++++++++++++++++-- 5 files changed, 105 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 0e2dfc52c52..59259c1225e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -124,6 +124,15 @@ insert into test.t1 values ("h1", x); else insert into test.t1 values ("h?", x); end case; +create procedure sinisa() +begin +declare x char(16); +declare y int; +set x="aaaaa"; +set y=22; +select id,data into x,y from test.t1 limit 2,1; +insert into test.t1 values (x, y); +end; call foo42(); select * from t1; id data @@ -236,6 +245,13 @@ id data h0 0 h1 1 h? 17 +call sinisa(); +select * from t1; +id data +h0 0 +h1 1 +h? 17 +h? 17 delete from t1; drop procedure foo42; drop procedure bar; @@ -258,4 +274,5 @@ drop procedure e; drop procedure f; drop procedure g; drop procedure h; +drop procedure sinisa; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 6b90d700b58..d9b04afa333 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -187,6 +187,16 @@ else insert into test.t1 values ("h?", x); end case| +create procedure sinisa() +begin + declare x char(16); + declare y int; + set x="aaaaa"; + set y=22; + select id,data into x,y from test.t1 limit 2,1; + insert into test.t1 values (x, y); +end| + delimiter ;| # Now, the CALL tests... @@ -263,6 +273,8 @@ call h(0); call h(1); call h(17); select * from t1; +call sinisa(); +select * from t1; delete from t1; drop procedure foo42; @@ -286,5 +298,6 @@ drop procedure e; drop procedure f; drop procedure g; drop procedure h; +drop procedure sinisa; drop table t1; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a5fb7922243..8e66e1ca068 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -36,6 +36,7 @@ #endif #include #include +#include /***************************************************************************** @@ -960,37 +961,71 @@ bool select_exists_subselect::send_data(List &items) int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) { List_iterator_fast li(list); - List_iterator_fast gl(var_list); + List_iterator_fast gl(var_list); Item *item; + my_var *mv; LEX_STRING *ls; if (var_list.elements != list.elements) { my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); return 1; } + unit=u; while ((item=li++)) { - ls= gl++; - Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); - xx->fix_fields(current_thd,(TABLE_LIST*) current_thd->lex.select_lex.table_list.first,&item); - xx->fix_length_and_dec(); - vars.push_back(xx); + mv=gl++; + ls= &mv->s; + if (mv->local) + { + (void)local_vars.push_back(new Item_splocal(mv->offset)); + } + else + { + Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); + xx->fix_fields(thd,(TABLE_LIST*) thd->lex.select_lex.table_list.first,&item); + xx->fix_length_and_dec(); + vars.push_back(xx); + } } return 0; } bool select_dumpvar::send_data(List &items) { List_iterator_fast li(vars); + List_iterator_fast var_li(local_vars); + List_iterator_fast my_li(var_list); + List_iterator_fast it(items); Item_func_set_user_var *xx; + Item_splocal *yy; + Item *item; + my_var *zz; DBUG_ENTER("send_data"); + if (unit->offset_limit_cnt) + { // using limit offset,count + unit->offset_limit_cnt--; + DBUG_RETURN(0); + } if (row_count++) { my_error(ER_TOO_MANY_ROWS, MYF(0)); DBUG_RETURN(1); } - while ((xx=li++)) - xx->update(); + while ((zz=my_li++) && (item=it++)) + { + if (zz->local) + { + if ((yy=var_li++)) + { + thd->spcont->set_item(yy->get_offset(), item); + } + } + else + { + if ((xx=li++)) + xx->update(); + } + } DBUG_RETURN(0); } diff --git a/sql/sql_class.h b/sql/sql_class.h index a078c4bd286..f367b089fd3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -987,13 +987,22 @@ public: bool send_eof(); }; +class my_var : public Sql_alloc { +public: + LEX_STRING s; + bool local; + uint offset; + my_var (LEX_STRING& j, bool i, uint o) : s(j), local(i), offset(o) {} + ~my_var() {} +}; class select_dumpvar :public select_result { ha_rows row_count; public: - List var_list; + List var_list; List vars; - select_dumpvar(void) { var_list.empty(); vars.empty(); row_count=0;} + List local_vars; + select_dumpvar(void) { var_list.empty(); local_vars.empty(); vars.empty(); row_count=0;} ~select_dumpvar() {} int prepare(List &list, SELECT_LEX_UNIT *u); bool send_fields(List &list, uint flag) {return 0;} diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2cc2f674d4a..33ec3788b22 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3313,10 +3313,29 @@ select_var_list: | select_var_ident {} ; -select_var_ident: '@' ident_or_text +select_var_ident: + '@' ident_or_text { LEX *lex=Lex; - if (lex->result && ((select_dumpvar *)lex->result)->var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)))) + if (lex->result) + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0)); + else + YYABORT; + } + | ident_or_text + { + LEX *lex=Lex; + if (!lex->spcont) + YYABORT; + sp_pvar_t *t; + if (!(t=lex->spcont->find_pvar(&$1))) + { + send_error(lex->thd, ER_SYNTAX_ERROR); + YYABORT; + } + if (lex->result) + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset)); + else YYABORT; } ; From de135f50b81d847fe62fdebbcc02c5d159fbf6a7 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Mon, 20 Jan 2003 15:38:35 +0200 Subject: [PATCH 21/83] Changing some proc names to a more suitable one. --- mysql-test/r/sp.result | 6 +++--- mysql-test/t/sp.test | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 59259c1225e..da6d76ccd68 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -124,7 +124,7 @@ insert into test.t1 values ("h1", x); else insert into test.t1 values ("h?", x); end case; -create procedure sinisa() +create procedure into_test() begin declare x char(16); declare y int; @@ -245,7 +245,7 @@ id data h0 0 h1 1 h? 17 -call sinisa(); +call into_test(); select * from t1; id data h0 0 @@ -274,5 +274,5 @@ drop procedure e; drop procedure f; drop procedure g; drop procedure h; -drop procedure sinisa; +drop procedure into_test; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index d9b04afa333..319e59f11da 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -187,7 +187,7 @@ else insert into test.t1 values ("h?", x); end case| -create procedure sinisa() +create procedure into_test() begin declare x char(16); declare y int; @@ -273,7 +273,7 @@ call h(0); call h(1); call h(17); select * from t1; -call sinisa(); +call into_test(); select * from t1; delete from t1; @@ -298,6 +298,6 @@ drop procedure e; drop procedure f; drop procedure g; drop procedure h; -drop procedure sinisa; +drop procedure into_test; drop table t1; From 1fd4866322ce98e5b4eaf7454005f7ef150ce120 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Thu, 23 Jan 2003 17:00:31 +0400 Subject: [PATCH 22/83] solve the lex conflict between the existing repeat() function and repeat SP-construction --- mysql-test/r/sp.result | 12 ++++++------ mysql-test/t/sp.test | 6 +++--- sql/lex.h | 3 +-- sql/sql_yacc.yy | 9 +++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 0e2dfc52c52..0463ad0caf2 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -72,10 +72,10 @@ set x = x-1; insert into test.t1 values ("a", x); end while; create procedure b(x int) -sprepeat -insert into test.t1 values ("b", x); +repeat +insert into test.t1 values (repeat("b",3), x); set x = x-1; -until x = 0 end sprepeat; +until x = 0 end repeat; create procedure c(x int) hmm: while x > 0 do insert into test.t1 values ("c", x); @@ -187,9 +187,9 @@ delete from t1; call b(3); select * from t1; id data -b 3 -b 2 -b 1 +bbb 3 +bbb 2 +bbb 1 delete from t1; call c(3); select * from t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 6b90d700b58..e146d629f1b 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -122,10 +122,10 @@ end while| # REPEAT create procedure b(x int) -sprepeat - insert into test.t1 values ("b", x); +repeat + insert into test.t1 values (repeat("b",3), x); set x = x-1; -until x = 0 end sprepeat| +until x = 0 end repeat| # Labelled WHILE with ITERATE (pointless really) create procedure c(x int) diff --git a/sql/lex.h b/sql/lex.h index ccbd78dfe15..d86336d9662 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -318,7 +318,7 @@ static SYMBOL symbols[] = { { "REPAIR", SYM(REPAIR),0,0}, { "REPLACE", SYM(REPLACE),0,0}, { "REPLICATION", SYM(REPLICATION),0,0}, - { "SPREPEAT", SYM(SPREPEAT_SYM),0,0}, /* QQ Temp. until conflict solved */ + { "REPEAT", SYM(REPEAT_SYM),0,0}, { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, { "REQUIRE", SYM(REQUIRE_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0}, @@ -567,7 +567,6 @@ static SYMBOL sql_functions[] = { { "RADIANS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)}, { "RAND", SYM(RAND),0,0}, { "RELEASE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)}, - { "REPEAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_repeat)}, { "REVERSE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)}, { "ROUND", SYM(ROUND),0,0}, { "RPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2cc2f674d4a..3248048d304 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -535,8 +535,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ITERATE_SYM %token LEAVE_SYM %token LOOP_SYM -/* QQ This is temporary, until the REPEAT conflict is solved. */ -%token SPREPEAT_SYM +%token REPEAT_SYM %token UNTIL_SYM %token WHILE_SYM %token ASENSITIVE_SYM @@ -1284,8 +1283,8 @@ sp_unlabeled_control: lex->sphead->add_instr(i); } - | SPREPEAT_SYM sp_proc_stmts UNTIL_SYM expr END SPREPEAT_SYM - { /* ^^ QQ temp. until conflict solved ^^ */ + | REPEAT_SYM sp_proc_stmts UNTIL_SYM expr END REPEAT_SYM + { LEX *lex= Lex; uint ip= lex->sphead->instructions(); sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ @@ -2517,6 +2516,8 @@ simple_expr: { $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5);} | FUNC_ARG3 '(' expr ',' expr ',' expr ')' { $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7);} + | REPEAT_SYM '(' expr ',' expr ')' + { $$= new Item_func_repeat($3,$5); } | ATAN '(' expr ')' { $$= new Item_func_atan($3); } | ATAN '(' expr ',' expr ')' From a1d21d892ec580171c04fc65e891d1e4cd853fee Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 23 Jan 2003 14:00:32 +0100 Subject: [PATCH 23/83] Added check for selects without into in SPs, and updated error messages and tests accordingly. --- include/mysqld_error.h | 10 +++++----- mysql-test/r/sp.result | 13 +++++++++++++ mysql-test/t/sp.test | 18 ++++++++++++++++++ sql/share/czech/errmsg.txt | 6 +++--- sql/share/danish/errmsg.txt | 6 +++--- sql/share/dutch/errmsg.txt | 6 +++--- sql/share/english/errmsg.txt | 4 ++-- sql/share/estonian/errmsg.txt | 6 +++--- sql/share/french/errmsg.txt | 6 +++--- sql/share/german/errmsg.txt | 6 +++--- sql/share/greek/errmsg.txt | 6 +++--- sql/share/hungarian/errmsg.txt | 6 +++--- sql/share/italian/errmsg.txt | 6 +++--- sql/share/japanese/errmsg.txt | 6 +++--- sql/share/korean/errmsg.txt | 6 +++--- sql/share/norwegian-ny/errmsg.txt | 6 +++--- sql/share/norwegian/errmsg.txt | 6 +++--- sql/share/polish/errmsg.txt | 6 +++--- sql/share/portuguese/errmsg.txt | 6 +++--- sql/share/romanian/errmsg.txt | 6 +++--- sql/share/russian/errmsg.txt | 6 +++--- sql/share/serbian/errmsg.txt | 6 +++--- sql/share/slovak/errmsg.txt | 6 +++--- sql/share/spanish/errmsg.txt | 6 +++--- sql/share/swedish/errmsg.txt | 6 +++--- sql/share/ukrainian/errmsg.txt | 6 +++--- sql/sql_yacc.yy | 21 +++++++++++++++------ 27 files changed, 119 insertions(+), 79 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index e540b8371d8..f52fc75be86 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -271,10 +271,10 @@ #define ER_SP_DOES_NOT_EXIST 1252 #define ER_SP_DROP_FAILED 1253 #define ER_SP_STORE_FAILED 1254 -#define ER_SP_LEAVE_MISMATCH 1255 -#define ER_SP_ITERATE_MISMATCH 1256 -#define ER_SP_LABEL_REDEFINE 1257 -#define ER_SP_LABEL_MISMATCH 1258 -#define ER_SP_UNINIT_VAR 1259 +#define ER_SP_LILABEL_MISMATCH 1255 +#define ER_SP_LABEL_REDEFINE 1256 +#define ER_SP_LABEL_MISMATCH 1257 +#define ER_SP_UNINIT_VAR 1258 +#define ER_SP_BADSELECT 1259 #define ER_ERROR_MESSAGES 260 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 0463ad0caf2..f66649ba28e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -76,6 +76,19 @@ repeat insert into test.t1 values (repeat("b",3), x); set x = x-1; until x = 0 end repeat; +create procedure b2(x int) +repeat(select 1 into outfile 'b2'); +insert into test.t1 values (repeat("b2",3), x); +set x = x-1; +until x = 0 end repeat; +drop procedure b2; +create procedure b3(x int) +repeat +select * from test.t1; # No INTO! +insert into test.t1 values (repeat("b3",3), x); +set x = x-1; +until x = 0 end repeat; +SELECT in a stored procedure must have INTO create procedure c(x int) hmm: while x > 0 do insert into test.t1 values ("c", x); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index e146d629f1b..73bdcbcde15 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -127,6 +127,24 @@ repeat set x = x-1; until x = 0 end repeat| +# Check that repeat isn't parsed the wrong way +create procedure b2(x int) +repeat(select 1 into outfile 'b2'); + insert into test.t1 values (repeat("b2",3), x); + set x = x-1; +until x = 0 end repeat| +# We don't actually want to call it. +drop procedure b2| + +# Btw, this should generate an error +--error 1259 +create procedure b3(x int) +repeat + select * from test.t1; # No INTO! + insert into test.t1 values (repeat("b3",3), x); + set x = x-1; +until x = 0 end repeat| + # Labelled WHILE with ITERATE (pointless really) create procedure c(x int) hmm: while x > 0 do diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 79dae19dbc8..dd2df4c5243 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -264,9 +264,9 @@ v/* "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index a77c2b59622..3c66c5a64f2 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -258,9 +258,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 5f78ba6c21d..cdae9092602 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -266,9 +266,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 9fe52f075dc..811fb015fb7 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -256,8 +256,8 @@ "PROCEDURE does not exist" "Failed to DROP PROCEDURE" "Failed to CREATE PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 8202d782408..af32e4cc630 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -260,9 +260,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 799cb76d8c0..147948d567f 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -255,9 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index d6c9a2fb8ed..c3b4713241a 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -265,9 +265,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index c78d410df83..43ba3c3b173 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -255,9 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index b42c4a87c4f..9355daa634e 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -257,9 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 937f2d41379..aee2c229f80 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -255,9 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 136e4c77fb6..2b7515c12d1 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -257,9 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 08c496984a8..b8e0e7a4f25 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -255,9 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 7c7387da2fe..15894decc4a 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -257,9 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index fc42860af0d..01ce52ec060 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -257,9 +257,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index f907222ea28..a2440d5928e 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -259,9 +259,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index a26d6dae971..86b44f4d97d 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -255,9 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index e2ac7eade01..f6cc343a70d 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -259,9 +259,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 8d350e62f00..33dc4e5d3b8 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -258,9 +258,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index e12c2953805..eb699fc812c 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -251,9 +251,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 391b531cfdb..b1253642081 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -263,9 +263,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 528c89893cc..6be74571317 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -256,9 +256,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index e8f1d4eec0f..512314cf856 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -255,9 +255,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 965da3cd29d..337157829a9 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -260,9 +260,9 @@ "PROCEDURE already exists" "PROCEDURE does not exist" "Failed to DROP PROCEDURE" -"Failed to store PROCEDURE" -"LEAVE with no matching label" -"ITERATE with no matching label" +"Failed to CREATE PROCEDURE" +"%s with no matching label" "Redefining label" "End-label without match" "Referring to uninitialized variable" +"SELECT in a stored procedure must have INTO" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3248048d304..b8440943ac1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1041,11 +1041,20 @@ sp_proc_stmt: statement { LEX *lex= Lex; - sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); - i->set_lex(lex); - lex->sphead->add_instr(i); - lex->sphead->restore_lex(YYTHD); + if (lex->sql_command == SQLCOM_SELECT && !lex->result) + { + send_error(YYTHD, ER_SP_BADSELECT); + YYABORT; + } + else + { + sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); + + i->set_lex(lex); + lex->sphead->add_instr(i); + lex->sphead->restore_lex(YYTHD); + } } | IF sp_if END IF {} | CASE_SYM WHEN_SYM @@ -1096,7 +1105,7 @@ sp_proc_stmt: if (! lab) { - send_error(YYTHD, ER_SP_LEAVE_MISMATCH); + send_error(YYTHD, ER_SP_LILABEL_MISMATCH, "LEAVE"); YYABORT; } else @@ -1114,7 +1123,7 @@ sp_proc_stmt: if (! lab) { - send_error(YYTHD, ER_SP_ITERATE_MISMATCH); + send_error(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE"); YYABORT; } else From 44390c8cb6b895b53fc12c6b3bac705b9cc5ec97 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 28 Jan 2003 18:55:52 +0200 Subject: [PATCH 24/83] A feature of doing automatick result buffering when INSERT is done from the select containing a table to be inserted to. --- mysql-test/r/insert.result | 13 +++++++++++++ mysql-test/r/subselect.result | 3 ++- mysql-test/t/insert.test | 31 +++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 1 - sql/sql_parse.cc | 3 +-- 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index ebd34dd7668..3be04584749 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -64,3 +64,16 @@ use test_$1; create table t1 (c int); insert into test_$1.t1 set test_$1.t1.c = '1'; drop database test_$1; +use test; +drop table if exists t1,t2,t3; +create table t1(id1 int not null auto_increment primary key, t char(12)); +create table t2(id2 int not null, t char(12)); +create table t3(id3 int not null, t char(12), index(id3)); +select count(*) from t2; +count(*) +500 +insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3; +select count(*) from t2; +count(*) +25500 +drop table if exists t1,t2,t3; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 04bf0575db3..ca3323adb6c 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -576,7 +576,6 @@ x 3 3 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; -You can't specify target table 't1' for update in FROM clause INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); select * from t1; x @@ -584,6 +583,8 @@ x 2 3 3 +11 +11 0 drop table t1, t2, t3; CREATE TABLE t1 (x int not null, y int, primary key (x)); diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index bfa8aac7a1f..34302cdbc60 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -65,3 +65,34 @@ use test_$1; create table t1 (c int); insert into test_$1.t1 set test_$1.t1.c = '1'; drop database test_$1; +use test; +--disable_warnings +drop table if exists t1,t2,t3; +--enable_warnings +create table t1(id1 int not null auto_increment primary key, t char(12)); +create table t2(id2 int not null, t char(12)); +create table t3(id3 int not null, t char(12), index(id3)); +disable_query_log; +let $1 = 100; +while ($1) + { + let $2 = 5; + eval insert into t1(t) values ('$1'); + while ($2) + { + eval insert into t2(id2,t) values ($1,'$2'); + let $3 = 10; + while ($3) + { + eval insert into t3(id3,t) values ($1,'$2'); + dec $3; + } + dec $2; + } + dec $1; + } +enable_query_log; +select count(*) from t2; +insert into t2 select t1.* from t1, t2 t, t3 where t1.id1 = t.id2 and t.id2 = t3.id3; +select count(*) from t2; +drop table if exists t1,t2,t3; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1dcbd9a282d..9b7e5f0f290 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -332,7 +332,6 @@ INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); select * from t1; INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2; select * from t1; --- error 1093 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); -- sleep 1 diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b82846706a8..d1515025723 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2198,8 +2198,7 @@ mysql_execute_command(THD *thd) if (find_real_table_in_list(tables->next, tables->db, tables->real_name)) { - net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name); - return -1; + lex->select_lex.options |= OPTION_BUFFER_RESULT; } /* Skip first table, which is the table we are inserting in */ From 58d0b0ea1a3abd7116b1e160a860220f427b6679 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 2 Feb 2003 17:41:21 +0100 Subject: [PATCH 25/83] Added another select into test. --- mysql-test/r/sp.result | 31 ++++++++++++++++++++----------- mysql-test/t/sp.test | 26 +++++++++++++++++++------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ef6bca0f976..35b35e91777 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -137,14 +137,17 @@ insert into test.t1 values ("h1", x); else insert into test.t1 values ("h?", x); end case; -create procedure into_test() +create procedure into_test(x char(16), y int) begin -declare x char(16); -declare y int; -set x="aaaaa"; -set y=22; -select id,data into x,y from test.t1 limit 2,1; insert into test.t1 values (x, y); +select id,data into x,y from test.t1 limit 1; +insert into test.t1 values (concat(x, "2"), y+2); +end; +create procedure into_test2(x char(16), y int) +begin +insert into test.t1 values (x, y); +select id,data into x,@z from test.t1 limit 1; +insert into test.t1 values (concat(x, "2"), y+2); end; call foo42(); select * from t1; @@ -258,13 +261,18 @@ id data h0 0 h1 1 h? 17 -call into_test(); +delete from t1; +call into_test("into", 100); select * from t1; id data -h0 0 -h1 1 -h? 17 -h? 17 +into 100 +into2 102 +delete from t1; +call into_test2("into", 100); +select id,data,@z from t1; +id data @z +into 100 100 +into2 102 100 delete from t1; drop procedure foo42; drop procedure bar; @@ -288,4 +296,5 @@ drop procedure f; drop procedure g; drop procedure h; drop procedure into_test; +drop procedure into_test2; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 79eb088aa2d..48919ff1d6e 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -205,14 +205,19 @@ else insert into test.t1 values ("h?", x); end case| -create procedure into_test() +create procedure into_test(x char(16), y int) begin - declare x char(16); - declare y int; - set x="aaaaa"; - set y=22; - select id,data into x,y from test.t1 limit 2,1; insert into test.t1 values (x, y); + select id,data into x,y from test.t1 limit 1; + insert into test.t1 values (concat(x, "2"), y+2); +end| + +# Test INTO with a mix of local and global variables +create procedure into_test2(x char(16), y int) +begin + insert into test.t1 values (x, y); + select id,data into x,@z from test.t1 limit 1; + insert into test.t1 values (concat(x, "2"), y+2); end| delimiter ;| @@ -291,10 +296,16 @@ call h(0); call h(1); call h(17); select * from t1; -call into_test(); +delete from t1; + +call into_test("into", 100); select * from t1; delete from t1; +call into_test2("into", 100); +select id,data,@z from t1; +delete from t1; + drop procedure foo42; drop procedure bar; drop procedure two; @@ -317,5 +328,6 @@ drop procedure f; drop procedure g; drop procedure h; drop procedure into_test; +drop procedure into_test2; drop table t1; From b6890a793041e741c428cd9c108d6e546e10fd78 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 2 Feb 2003 17:44:39 +0100 Subject: [PATCH 26/83] Fixed crash bug when certain procedures are called from the top level. --- sql/sp_head.cc | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 621b31f5e11..286a009b38e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -117,6 +117,7 @@ sp_head::execute(THD *thd) uint params = pctx->params(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; + my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx if (csize > 0) { @@ -125,6 +126,11 @@ sp_head::execute(THD *thd) Item *it = li++; // Skip first one, it's the procedure name nctx = new sp_rcontext(csize); + if (! octx) + { // Create a temporary old context + octx = new sp_rcontext(csize); + tmp_octx = TRUE; + } // QQ: No error checking whatsoever right now. Should do type checking? for (i = 0 ; (it= li++) && i < params ; i++) { @@ -172,16 +178,44 @@ sp_head::execute(THD *thd) // Don't copy back OUT values if we got an error if (ret == 0 && csize > 0) { - // Copy back all OUT or INOUT values to the previous frame - for (uint i = 0 ; i < params ; i++) + List_iterator_fast li(m_call_lex->value_list); + Item *it = li++; // Skip first one, it's the procedure name + + // Copy back all OUT or INOUT values to the previous frame, or + // set global user variables + for (uint i = 0 ; (it= li++) && i < params ; i++) { int oi = nctx->get_oindex(i); if (oi >= 0) - octx->set_item(nctx->get_oindex(i), nctx->get_item(i)); + { + if (! tmp_octx) + octx->set_item(nctx->get_oindex(i), nctx->get_item(i)); + else + { // A global user variable +#if 0 + // QQ This works if the parameter really is a user variable, but + // for the moment we can't assure that, so it will crash if it's + // something else. So for now, we just do nothing, to avoid a crash. + // Note: This also assumes we have a get_name() method in + // the Item_func_get_user_var class. + Item *item= nctx->get_item(i); + Item_func_set_user_var *suv; + Item_func_get_user_var *guv= static_cast(it); + + suv= new Item_func_set_user_var(guv->get_name(), item); + suv->fix_fields(thd, NULL, &item); + suv->fix_length_and_dec(); + suv->update(); +#endif + } + } } - thd->spcont= octx; + if (tmp_octx) + thd->spcont= NULL; + else + thd->spcont= octx; } return ret; From b43d7af60e72bf2252780b3dadd616ec64c3722d Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 2 Feb 2003 17:49:42 +0100 Subject: [PATCH 27/83] Added some basic implementation documentation for stored procedures. --- Docs/sp-imp-spec.txt | 469 ++++++++++++++++++++++++++++++++++++++++ Docs/sp-implemented.txt | 60 +++++ 2 files changed, 529 insertions(+) create mode 100644 Docs/sp-imp-spec.txt create mode 100644 Docs/sp-implemented.txt diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt new file mode 100644 index 00000000000..23559497cae --- /dev/null +++ b/Docs/sp-imp-spec.txt @@ -0,0 +1,469 @@ + + Implementation specification for Stored Procedures + ================================================== + +This is a first draft, only covering the basics for parsing, creating, and +calling a PROCEDURE. + + +- How parsing and execution of queries work + + In order to execute a query, the function sql_parse.cc:mysql_parse() is + called, which in turn calls the parser (yyparse()) with an updated Lex + structure as the result. mysql_parse() then calls mysql_execute_command() + which dispatches on the command code (in Lex) to the corresponding code for + executing that particular query. + + There are thre structures involved in the execution of a query which are of + interest to the stored procedure implementation: + + - Lex (mentioned above) is the "compiled" query, that is the output from + the parser and what is then interpreted to do the actual work. + It constains an enum value (sql_command) which is the query type, and + all the data collected by the parser needed for the execution (table + names, fields, values, etc). + - THD is the "run-time" state of a connection, containing all that is + needed for a particular client connection, and, among other things, the + Lex structure currently being executed. + - Item_*: During parsing, all data is translated into "items", objects of + the subclasses of "Item", such as Item_int, Item_real, Item_string, etc, + for basic datatypes, and also various more specialized Item types for + expressions to be evaluated (Item_func objects). + + +- How to fit Stored Procedure into this scheme + + - An overview of the classes and files for stored procedures + (More detailed APIs at the end of this file) + + - class sp_head (sp_head.{cc,h}) + This contains, among other things, an array of "instructions" and the + method for executing the procedure. + + - class sp_pcontext (sp_pcontext.{cc,h} + This is the parse context for the procedure. It's primarily used during + parsing to keep track of local parameters, variables and labels, but + it's also used at CALL time do find parameters mode (IN, OUT or INOUT) + and type when setting up the runtime context. + + - class sp_instr (sp_head.{cc,h}) + This is the base class for "instructions", that is, what is generated + by the parser. It turns out that we only need 4 different sub classes: + - sp_instr_stmt + Execute a statement. This is the "call-out" any normal SQL statement, + like a SELECT, INSERT etc. It contains the Lex structure for the + statement in question. + - sp_instr_set + Set the value of a local variable (or parameter) + - sp_instr_jump + An unconditional jump. + - sp_instr_jump_if_not + Jump if condition is not true. It turns out that the negative test is + most convenient when generating the code for the flow control + constructs. + + - class sp_rcontext (sp_rcontext.h) + This is the runtime context in the THD structure. + It contains an array of items, the parameters and local variables for + the currently executing stored procedure. + This means that variable value lookup is in runtime is constant time, + a simple index operation. + + - class Item_splocal (Item.{cc,h}) + This is a subclass of Item. Its sole purpose is to hide the fact that + the real Item is actually in the current frame (runtime context). + It contains the frame offset and defers all methods to the real Item + in the frame. This is what the parser generates for local variables. + + - Utility functions (sp.{cc,h}) + This contains functions for creating, dropping and finding a stored + procedure in the mysql.proc table (or internal cache, when it is + implemented). + + + - Parsing CREATE PROCEDURE ... + + When parsing a CREATE PROCEDURE the parser first initializes the + sphead and spcont (runtime context) fields in the Lex. + The sql_command code for the result of parsing a is + SQLCOM_CREATE_PROCEDURE. + + The parsing of the parameter list and body is relatively + straight-forward: + + - Parameters: + name, type and mode (IN/OUT/INOUT) is pushed to spcont + - Declared local variables: + Same as parameters (mode is then IN) + - Local Variable references: + If an identifier is found in in spcont, an Item_splocal is created + with the variable's frame index, otherwise an Item_field or Item_ref + is created (as before). + - Statements: + The Lex in THD is replaced by a new Lex structure and the statement, + is parsed as usual. A sp_instr_stmt is created, containing the new + Lex, and added to added to the instructions in sphead. + Afterwards, the procedure's Lex is restored in THD. + - SET var: + Setting a local variable generates a sp_instr_set instruction, + containing the variable's frame offset, the expression (an Item), + and the type. + - Flow control: + Flow control constructs like, IF, WHILE, etc, generate a conditional + and unconditional jumps in the "obvious" way, but a few notes may + be required: + - Forward jumps: When jumping forward, the exact destination is not + known at the time of the creation of the jump instruction. The + sphead therefore contains list of instruction-label pairs for + each forward reference. When the position later is known, the + instructions in the list are updated with the correct location. + - Loop constructs have optional labels. If a loop doesn't have a + label, an anonymous label is generated to simplify the parsing. + - There are two types of CASE. The "simple" case is implemented + with an anonymous variable bound to the value to be tested. + + + - An example + + Parsing the procedure: + + create procedure a(s char(16)) + begin + declare x int; + set x = 3; + while x > 0 do + set x = x-1; + insert into db.tab values (x, s); + end while + end + + would generate the following structures: + ______ + thd: | | _________ + | lex -+--->| | ___________________ + |______| | spcont -+------------------->| "s",in,char(16):0 | + | sphead -+------ |("x",in,int :1)| + |_________| | |___________________| + ____V__________________ + | m_name: "a" | + | m_defstr: "create ..."| + | m_instr: ... | + |_______________________| + + Note that the contents of the spcont is changing during the parsing, + at all times reflecting the state of the would-be runtime frame. + The m_instr is an array of instructions: + + Pos. Instruction + 0 sp_instr_set(1, '3') + 1 sp_instr_jump_if_not(5, 'x>0') + 2 sp_instr_set(1, 'x-1') + 3 sp_instr_stmt('insert into ...') + 4 sp_instr_jump(1) + 5 + + Here, '3', 'x>0', etc, represent the Items or Lex for the respective + expressions or statements. + + + - Storing, caching, dropping... + + As seen above, the entired definition string, including the "CREATE + PROCEDURE" is kept. The procedure definition string is stored in the + table mysql.proc with the name as the key. + + This means that we can reparse the procedure as many time as we want. + The first time, the resulting Lex is used to store the procedure in + the database (using the function sp.c:sp_create_procedure()). + + The simplest way would be to just leave it at that, and re-read the + procedure from the database each time it is called. (And in fact, that's + the way the earliest implementation will work.) + However, this is not very efficient, and we can do better. The full + implementation should work like this: + + 1) Upon creation time, parse and store the procedure. Note that we still + need to parse it to catch syntax errors, but we can't check if called + procedures exists for instance. + 2) Upon first CALL, read from the database, parse it, and cache the + resulting Lex in memory. This time we can do more error checking. + 3) Upon subsequent CALLs, use the cached Lex. + + Note that this implies that the Lex structure with its sphead must be + reentrant, that is, reusable and shareable between different threads + and calls. The runtime state for a procedure is kept in the sp_rcontext + in THD. + + The mechanisms of storing, finding, and dropping procedures are + encapsulated in the files sp.{cc,h}. + + + - CALL + + A CALL is parsed just like any statement. The resulting Lex has the + sql_command SQLCOM_CALL, the procedure's name and the parameters are + pushed to the Lex' value_list. + + sql_parse.cc:mysql_execute_command() then uses sp.cc:sp_find() to + get the sp_head for the procedure (which may have been read from the + database or feetched from the in-memory cache) and calls the sp_head's + method execute(). + Note: It's important that substatements called by the procedure do not + do send_ok(). Fortunately, there is a flag in THD->net to disable + this during CALLs. If a substatement fails, it will however send + an error back to the client, so the CALL mechanism must return + immediately and without sending an error. + + The sp_head::execute() method works as follows: + + 1) Keep a pointer to the old runtime context in THD (if any) + 2) Create a new runtime context. The information about the required size + is in sp_head's parse time context. + 3) Push each parameter (from the CALL's Lex->value_list) to the new + context. If it's an OUT or INOUT parameter, the parameter's offset + in the caller's frame is set in the new context as well. + 4) For each instruction, call its execute() method. + The result is a pointer to the next instruction to execute (or NULL) + if an error occured. + 5) On success, set the new values of the OUT and INOUT parameters in + the caller's frame. + + + - Evaluating Items + + There are three occasions where we need to evaluate an expression: + + - When SETing a variable + - When CALLing a procedure + - When testing an expression for a branch (in IF, WHILE, etc) + + The semantics in stored procedures is "call-by-value", so we have to + evaluate any "func" Items at the point of the CALL or SET, otherwise + we would get a kind of "lazy" evaluation with unexpected results with + respect to OUT parameters for instance. + For this the support function, sp_head.cc:eval_func_item() is needed. + + + - Parsing DROP PROCEDURE + + The procedure name is pushed to Lex->value_list. + The sql_command code for the result of parsing a is + SQLCOM_DROP_PROCEDURE. + + Dropping is done by simply getting the procedure with the sp_find() + function and calling sp_drop() (both in sp.{cc,h}). + + + - Class and function APIs + + - The parser context: sp_pcontext.h + + typedef enum + { + sp_param_in, + sp_param_out, + sp_param_inout + } sp_param_mode_t; + + typedef struct + { + Item_string *name; + enum enum_field_types type; + sp_param_mode_t mode; + uint offset; // Offset in current frame + my_bool isset; + } sp_pvar_t; + + class sp_pcontext + { + sp_pcontext(); + + // Return the maximum frame size + uint max_framesize(); + + // Return the current frame size + uint current_framesize(); + + // Return the number of parameters + uint params(); + + // Set the number of parameters to the current frame size + void set_params(); + + // Set type of the variable at offset 'i' in the frame + void set_type(uint i, enum enum_field_types type); + + // Mark the i:th variable to "set" (i.e. having a value) with + // 'val' true. + void set_isset(uint i, my_bool val); + + // Push the variable 'name' to the frame. + void push(LEX_STRING *name, + enum enum_field_types type, sp_param_mode_t mode); + + // Pop 'num' variables from the frame. + void pop(uint num = 1); + + // Find variable by name + sp_pvar_t *find_pvar(LEX_STRING *name); + + // Find variable by index + sp_pvar_t *find_pvar(uint i); + + // Push label 'name' of instruction index 'ip' to the label context + sp_label_t *push_label(char *name, uint ip); + + // Find label 'name' in the context + sp_label_t *find_label(char *name); + + // Return the last pushed label + sp_label_t *last_label(); + + // Return and remove the last pushed label. + sp_label_t *pop_label(); + } + + + - The run-time context (call frame): sp_rcontext.h + + class sp_rcontext + { + // 'size' is the max size of the context + sp_rcontext(uint size); + + // Push value (parameter) 'i' to the frame + void push_item(Item *i); + + // Set slot 'idx' to value 'i' + void set_item(uint idx, Item *i); + + // Return the item in slot 'idx' + Item *get_item(uint idx); + + // Set the "out" index 'oidx' for slot 'idx. If it's an IN slot, + // use 'oidx' -1. + void set_oindex(uint idx, int oidx); + + // Return the "out" index for slot 'idx' + int get_oindex(uint idx); + } + + + - The procedure: sp_head.h + + class sp_head + { + sp_head(LEX_STRING *name, LEX*); + + // Store this procedure in the database. This is a wrapper around + // the function sp_create_procedure(). + int create(THD *); + + // CALL this procedure. + int execute(THD *); + + // Add the instruction to this procedure. + void add_instr(sp_instr *); + + // Return the number of instructions. + uint instructions(); + + // Resets lex in 'thd' and keeps a copy of the old one. + void reset_lex(THD *); + + // Restores lex in 'thd' from our copy, but keeps some status from the + // one in 'thd', like ptr, tables, fields, etc. + void restore_lex(THD *); + + // Put the instruction on the backpatch list, associated with + // the label. + void push_backpatch(sp_instr *, struct sp_label *); + + // Update all instruction with this label in the backpatch list to + // the current position. + void backpatch(struct sp_label *); + } + + - Instructions + + - The base class: + class sp_instr + { + // 'ip' is the index of this instruction + sp_instr(uint ip); + + // Execute this instrution. + // '*nextp' will be set to the index of the next instruction + // to execute. (For most instruction this will be the + // instruction following this one.) + // Returns 0 on success, non-zero if some error occured. + virtual int execute(THD *, uint *nextp) + } + + - Statement instruction: + class sp_instr_stmt : public sp_instr + { + sp_instr_stmt(uint ip); + + int execute(THD *, uint *nextp); + + // Set the statement's Lex + void set_lex(LEX *); + + // Return the statement's Lex + LEX *get_lex(); + } + + - SET instruction: + class sp_instr_set : public sp_instr + { + // 'offset' is the variable's frame offset, 'val' the value, + // and 'type' the variable type. + sp_instr_set(uint ip, + uint offset, Item *val, enum enum_field_types type); + + int execute(THD *, uint *nextp); + } + + - Unconditional jump + class sp_instr_jump : public sp_instr + { + // No destination, must be set. + sp_instr_jump(uint ip); + + // 'dest' is the destination instruction index. + sp_instr_jump(uint ip, uint dest); + + virtual int execute(THD *, uint *nextp); + + // Set the destination instruction 'dest'. + void set_destination(uint dest); + } + + - Conditional jump + class sp_instr_jump_if_not : public sp_instr_jump + { + // Jump if 'i' evaluates to false. Destination not set yet. + sp_instr_jump_if_not(uint ip, Item *i); + + // Jump to 'dest' if 'i' evaluates to false. + sp_instr_jump_if_not(uint ip, Item *i, uint dest) + + int execute(THD *, uint *nextp); + } + + - Utility functions: sp.h + + // Finds a stored procedure given its name. Returns NULL if not found. + sp_head *sp_find(THD *, Item_string *name); + + // Store the procedure 'name' in the database. 'def' is the complete + // definition string ("create procedure ..."). + int sp_create_procedure(THD *, + char *name, uint namelen, + char *def, uint deflen); + + // Drop the procedure 'name' from the database. + int sp_drop(THD *, char *name, uint namelen); + +-- diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt new file mode 100644 index 00000000000..9074ad426ea --- /dev/null +++ b/Docs/sp-implemented.txt @@ -0,0 +1,60 @@ +Stored Procedures implemented 2003-02-02: + +Summary of Not Yet Implemented: + + - FUNCTIONs + - Routine characteristics + - External languages + - Access control + - Prepared SP caching; SPs are fetched and reparsed at each call + - SQL-99 COMMIT (related to BEGIN/END) + - DECLARE CURSOR ... + - FOR-loops (as it requires cursors) + +Summary of what's implemented: + + - SQL PROCEDURES (CREATE/DROP) + - CALL + - DECLARE of local variables + - BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE + - SELECT INTO local variables + +List of what's implemented: + + - CREATE PROCEDURE name ( args ) body + No routine characteristics yet. + + - ALTER PROCEDURE name ... + Is parsed, but a no-op (as there are no characteristics implemented yet). + CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). + + - DROP PROCEDURE name + CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). + + - CALL name (args) + OUT and INOUT parameters are only supported for local variables, and + therefore only useful when calling such procedures from within another + procedure. + Note: For the time being, when a procedure with OUT/INOUT parameter is + called, the out values are silently discarded. In the future, this + will either generate an error message, or it might even work to + call all procedures from the top-level. + + - Procedure body: + - BEGIN/END + Is parsed, but not the real thing with (optional) transaction + control, it only serves as block syntax for multiple statements (and + local variable binding). + Note: Multiple statements requires a client that can send bodies + containing ";". This is handled in the CLI clients mysql and + mysqltest with the "delimiter" command. Changing the end-of-query + delimiter ";" to for instance "|" allows + - SET of local variables + Implemented as part of the pre-existing SET syntax. This allows an + extended syntax of "SET a=x, b=y, ..." where different variable types + (SP local and global) can be mixed. + - The flow control constructs: CASE, IF, LOOP, WHILE, ITERATE and LEAVE + are fully implemented. + - SELECT ... INTO local variables (as well as global session variables) + is implemented. (Note: This is not SQL-99 feature, but common in other + databases.) From f2d6ec93218d38e7ab0dd2c1797ca66dbbc4a051 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 4 Feb 2003 17:40:18 +0100 Subject: [PATCH 28/83] Some new stuff in the Docs/sp-* files, and renamed a few functions in preparation for future work. --- Docs/sp-imp-spec.txt | 42 ++++++++++++++++++++++++++++++++++++----- Docs/sp-implemented.txt | 22 ++++++++++++++++++++- sql/sp.cc | 4 ++-- sql/sp.h | 15 +++++++++++++-- sql/sql_parse.cc | 8 ++++---- 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index 23559497cae..198623a0f5b 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -166,11 +166,28 @@ calling a PROCEDURE. expressions or statements. + - Parsing CREATE FUNCTION ... + + Creating a functions is essensially the same thing as for a PROCEDURE, + with the addition that a FUNCTION has a return type and a RETURN + statement, but no OUT or INOUT parameters. + + [QQ - More details here; sp_head needs a result slot and a type flag + indicating if it's a function or procedure] + + - Storing, caching, dropping... As seen above, the entired definition string, including the "CREATE - PROCEDURE" is kept. The procedure definition string is stored in the - table mysql.proc with the name as the key. + PROCEDURE" (or "FUNCTION") is kept. The procedure definition string is + stored in the table mysql.proc with the name and type as the key, the + type being one of the enum ("procedure","function"). + + A PROCEDURE is just stored int the mysql.proc table. A FUNCTION has an + additional requirement. They will be called in expressions with the same + syntax as UDFs, so UDFs and stored FUNCTIONs share the namespace. Thus, + we must make sure that we do not have UDFs and FUNCTIONs with the same + name (even if they are storded in different places). This means that we can reparse the procedure as many time as we want. The first time, the resulting Lex is used to store the procedure in @@ -198,7 +215,7 @@ calling a PROCEDURE. encapsulated in the files sp.{cc,h}. - - CALL + - CALLing a procedure A CALL is parsed just like any statement. The resulting Lex has the sql_command SQLCOM_CALL, the procedure's name and the parameters are @@ -244,11 +261,26 @@ calling a PROCEDURE. For this the support function, sp_head.cc:eval_func_item() is needed. - - Parsing DROP PROCEDURE + - Calling a FUNCTION + + Functions don't have an explicit call keyword like procedures. Instead, + they appear in expressions with the conventional syntax "fun(arg, ...)". + The problem is that we already have User Defined Functions (UDFs) which + are called the same way. A UDF is detected by the lexical analyzer (not + the parser!), in the find_keyword() function, and returns a UDF_*_FUNC + or UDA_*_SUM token with the udf_func object as the yylval. + + So, stored functions must be handled in a simpilar way, and as a + consequence, UDFs and functions must not have the same name. + + [QQ - Details of how function calls works here] + + + - Parsing DROP PROCEDURE/FUNCTION The procedure name is pushed to Lex->value_list. The sql_command code for the result of parsing a is - SQLCOM_DROP_PROCEDURE. + SQLCOM_DROP_PROCEDURE/SQLCOM_DROP_FUNCTION. Dropping is done by simply getting the procedure with the sp_find() function and calling sp_drop() (both in sp.{cc,h}). diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index 9074ad426ea..97d4df2b62c 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -1,5 +1,6 @@ Stored Procedures implemented 2003-02-02: + Summary of Not Yet Implemented: - FUNCTIONs @@ -11,6 +12,7 @@ Summary of Not Yet Implemented: - DECLARE CURSOR ... - FOR-loops (as it requires cursors) + Summary of what's implemented: - SQL PROCEDURES (CREATE/DROP) @@ -19,6 +21,7 @@ Summary of what's implemented: - BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE - SELECT INTO local variables + List of what's implemented: - CREATE PROCEDURE name ( args ) body @@ -52,9 +55,26 @@ List of what's implemented: - SET of local variables Implemented as part of the pre-existing SET syntax. This allows an extended syntax of "SET a=x, b=y, ..." where different variable types - (SP local and global) can be mixed. + (SP local and global) can be mixed. This also allows combinations + of local variables and some options that only make sense for + global/system variables; in that case the options are accepted but + ignored. - The flow control constructs: CASE, IF, LOOP, WHILE, ITERATE and LEAVE are fully implemented. - SELECT ... INTO local variables (as well as global session variables) is implemented. (Note: This is not SQL-99 feature, but common in other databases.) + + +Open questions: + + - What is the expected result when creating a procedure with a name that + already exists? An error or overwrite? + - Do PROCEDUREs and FUNCTIONs share namespace or not? I think not, but the + we need to flag the type in the mysql.proc table and the name alone is + not a unique key any more, or, we have separate tables. + (Unfortunately, mysql.func is already taken. Use "sfunc" and maybe even + rename "proc" into "sproc" while we still can, for consistency?) + - SQL-99 variables and parameters are typed. For the present we don't do + any type checking, since this is the way MySQL works. I still don't know + if we should keep it this way, or implement type checking. diff --git a/sql/sp.cc b/sql/sp.cc index caeb01200ff..a4fd239b513 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -24,7 +24,7 @@ // the in-memory cache for SPs. (And store newly prepared SPs there of // course.) sp_head * -sp_find(THD *thd, Item_string *iname) +sp_find_procedure(THD *thd, Item_string *iname) { extern int yyparse(void *thd); LEX *tmplex; @@ -92,7 +92,7 @@ sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) } int -sp_drop(THD *thd, char *name, uint namelen) +sp_drop_procedure(THD *thd, char *name, uint namelen) { TABLE *table; TABLE_LIST tables; diff --git a/sql/sp.h b/sql/sp.h index cb3343a4e92..99ea97cba8f 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -22,12 +22,23 @@ // Finds a stored procedure given its name. Returns NULL if not found. // sp_head * -sp_find(THD *thd, Item_string *name); +sp_find_procedure(THD *thd, Item_string *name); int sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen); int -sp_drop(THD *thd, char *name, uint namelen); +sp_drop_procedure(THD *thd, char *name, uint namelen); + +#if 0 +sp_head * +sp_find_function(THD *thd, Item_string *name); + +int +sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen); + +int +sp_drop_function(THD *thd, char *name, uint namelen); +#endif #endif /* _SP_H_ */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d1515025723..d1d6f63694e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2833,7 +2833,7 @@ mysql_execute_command(THD *thd) sp_head *sp; s= (Item_string*)lex->value_list.head(); - sp= sp_find(thd, s); + sp= sp_find_procedure(thd, s); if (! sp) { send_error(thd, ER_SP_DOES_NOT_EXIST); @@ -2862,7 +2862,7 @@ mysql_execute_command(THD *thd) sp_head *sp; s= (Item_string*)lex->value_list.head(); - sp= sp_find(thd, s); + sp= sp_find_procedure(thd, s); if (! sp) { send_error(thd, ER_SP_DOES_NOT_EXIST); @@ -2882,7 +2882,7 @@ mysql_execute_command(THD *thd) sp_head *sp; s = (Item_string*)lex->value_list.head(); - sp = sp_find(thd, s); + sp = sp_find_procedure(thd, s); if (! sp) { send_error(thd, ER_SP_DOES_NOT_EXIST); @@ -2892,7 +2892,7 @@ mysql_execute_command(THD *thd) { String *name = s->const_string(); - res= sp_drop(thd, name->c_ptr(), name->length()); + res= sp_drop_procedure(thd, name->c_ptr(), name->length()); if (res != 0) { send_error(thd, ER_SP_DROP_FAILED); From d53fc3195870fe81dd8ef3f4d2c58e11f5ee8474 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 12 Feb 2003 16:17:03 +0100 Subject: [PATCH 29/83] Fixed some DBUGing, and optimized SET slightly. --- sql/sp.cc | 16 +++++++++++----- sql/sp_head.cc | 29 +++++++++++++++++++++-------- sql/sql_parse.cc | 12 ++++++------ sql/sql_yacc.yy | 14 +++++++++++--- 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index a4fd239b513..42b7248aa80 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -26,6 +26,7 @@ sp_head * sp_find_procedure(THD *thd, Item_string *iname) { + DBUG_ENTER("sp_find_procedure"); extern int yyparse(void *thd); LEX *tmplex; TABLE *table; @@ -35,11 +36,12 @@ sp_find_procedure(THD *thd, Item_string *iname) sp_head *sp = NULL; name = iname->const_string(); + DBUG_PRINT("enter", ("name: %*s", name->length(), name->c_ptr())); memset(&tables, 0, sizeof(tables)); tables.db= (char*)"mysql"; tables.real_name= tables.alias= (char*)"proc"; if (! (table= open_ltable(thd, &tables, TL_READ))) - return NULL; + DBUG_RETURN(NULL); if (table->file->index_read_idx(table->record[0], 0, (byte*)name->c_ptr(), name->length(), @@ -59,12 +61,14 @@ sp_find_procedure(THD *thd, Item_string *iname) done: if (table) close_thread_tables(thd); - return sp; + DBUG_RETURN(sp); } int sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) { + DBUG_ENTER("sp_create_procedure"); + DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def)); int ret= 0; TABLE *table; TABLE_LIST tables; @@ -88,12 +92,14 @@ sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) done: close_thread_tables(thd); - return ret; + DBUG_RETURN(ret); } int sp_drop_procedure(THD *thd, char *name, uint namelen) { + DBUG_ENTER("sp_drop_procedure"); + DBUG_PRINT("enter", ("name: %*s", namelen, name)); TABLE *table; TABLE_LIST tables; @@ -111,9 +117,9 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) table->file->print_error(error, MYF(0)); } close_thread_tables(thd); - return 0; + DBUG_RETURN(0); err: close_thread_tables(thd); - return -1; + DBUG_RETURN(-1); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 286a009b38e..ff487429ec7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -99,17 +99,21 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) int sp_head::create(THD *thd) { + DBUG_ENTER("sp_head::create"); String *name= m_name->const_string(); String *def= m_defstr->const_string(); - return sp_create_procedure(thd, - name->c_ptr(), name->length(), - def->c_ptr(), def->length()); + DBUG_PRINT("info", ("name: %s def: %s", name->c_ptr(), def->c_ptr())); + DBUG_RETURN(sp_create_procedure(thd, + name->c_ptr(), name->length(), + def->c_ptr(), def->length())); } int sp_head::execute(THD *thd) { + DBUG_ENTER("sp_head::execute"); + DBUG_PRINT("executing", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); int ret= 0; sp_instr *p; sp_pcontext *pctx = m_call_lex->spcont; @@ -171,6 +175,7 @@ sp_head::execute(THD *thd) i = get_instr(ip); // Returns NULL when we're done. if (i == NULL) break; + DBUG_PRINT("execute", ("Instruction %u", ip)); ret= i->execute(thd, &ip); } } @@ -218,7 +223,7 @@ sp_head::execute(THD *thd) thd->spcont= octx; } - return ret; + DBUG_RETURN(ret); } @@ -351,6 +356,8 @@ sp_head::backpatch(sp_label_t *lab) int sp_instr_stmt::execute(THD *thd, uint *nextp) { + DBUG_ENTER("sp_instr_stmt::execute"); + DBUG_PRINT("info", ("command: %d", m_lex.sql_command)); LEX olex; // The other lex int res; @@ -364,7 +371,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) memcpy(&thd->lex, &olex, sizeof(LEX)); // Restore the other lex *nextp = m_ip+1; - return res; + DBUG_RETURN(res); } // @@ -373,9 +380,11 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) int sp_instr_set::execute(THD *thd, uint *nextp) { + DBUG_ENTER("sp_instr_set::execute"); + DBUG_PRINT("info", ("offset: %u", m_offset)); thd->spcont->set_item(m_offset, eval_func_item(thd, m_value, m_type)); *nextp = m_ip+1; - return 0; + DBUG_RETURN(0); } // @@ -384,13 +393,15 @@ sp_instr_set::execute(THD *thd, uint *nextp) int sp_instr_jump_if::execute(THD *thd, uint *nextp) { + DBUG_ENTER("sp_instr_jump_if::execute"); + DBUG_PRINT("info", ("destination: %u", m_dest)); Item *it= eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (it->val_int()) *nextp = m_dest; else *nextp = m_ip+1; - return 0; + DBUG_RETURN(0); } // @@ -399,11 +410,13 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp) int sp_instr_jump_if_not::execute(THD *thd, uint *nextp) { + DBUG_ENTER("sp_instr_jump_if_not::execute"); + DBUG_PRINT("info", ("destination: %u", m_dest)); Item *it= eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (! it->val_int()) *nextp = m_dest; else *nextp = m_ip+1; - return 0; + DBUG_RETURN(0); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d1d6f63694e..8b5d315aac9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1513,7 +1513,7 @@ mysql_execute_command(THD *thd) given and the table list says the query should not be replicated */ if (table_rules_on && tables && !tables_ok(thd,tables)) - return 0; + DBUG_RETURN(0); #ifndef TO_BE_DELETED /* This is a workaround to deal with the shortcoming in 3.23.44-3.23.46 @@ -1549,7 +1549,7 @@ mysql_execute_command(THD *thd) { if (res < 0 || thd->net.report_error) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); - return res; + DBUG_RETURN(res); } } } @@ -1558,7 +1558,7 @@ mysql_execute_command(THD *thd) lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) - return 0; + DBUG_RETURN(0); statistic_increment(com_stat[lex->sql_command],&LOCK_status); switch (lex->sql_command) { @@ -1838,7 +1838,7 @@ mysql_execute_command(THD *thd) find_real_table_in_list(tables->next, tables->db, tables->real_name)) { net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name); - return -1; + DBUG_RETURN(-1); } if (tables->next) { @@ -2912,11 +2912,11 @@ mysql_execute_command(THD *thd) // or res != 0 and no send_error() has yet been done. if (res < 0) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); - return res; + DBUG_RETURN(res); error: // We end up here if send_error() has already been done. - return -1; + DBUG_RETURN(-1); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index aec286fb655..b15612070a3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1049,10 +1049,18 @@ sp_proc_stmt: } else { - sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); + /* Don't add an instruction for empty SET statements. + ** (This happens if the SET only contained local variables, + ** which get their set instructions generated separately.) + */ + if (lex->sql_command != SQLCOM_SET_OPTION || + !lex->var_list.is_empty()) + { + sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); - i->set_lex(lex); - lex->sphead->add_instr(i); + i->set_lex(lex); + lex->sphead->add_instr(i); + } lex->sphead->restore_lex(YYTHD); } } From 59dec76951be9be86740c2c663217f98688843a6 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 18 Feb 2003 13:24:26 +0100 Subject: [PATCH 30/83] Added new files to libmysqld too. --- libmysqld/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index daf65cb2f80..451ab3378d7 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -55,7 +55,8 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ - spatial.cc gstream.cc sql_help.cc + spatial.cc gstream.cc sql_help.cc \ + sp_head.cc sp_pcontext.cc sp.cc EXTRA_DIST = lib_vio.c From 02211a600b83d8be7e7f91e807d148a147093be3 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 18 Feb 2003 19:58:03 +0100 Subject: [PATCH 31/83] Post-merge fixes (adapting new SP code to 4.1 changes). --- sql/sp.cc | 4 ++-- sql/sql_class.cc | 9 +++++++++ sql/sql_parse.cc | 4 ++++ sql/sql_yacc.yy | 6 +++--- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 42b7248aa80..2d4cf97bce1 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -48,12 +48,12 @@ sp_find_procedure(THD *thd, Item_string *iname) HA_READ_KEY_EXACT)) goto done; - if ((defstr= get_field(&thd->mem_root, table, 1)) == NULL) + if ((defstr= get_field(&thd->mem_root, table->field[1])) == NULL) goto done; // QQ Set up our own mem_root here??? tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); - if (yyparse(thd) || thd->fatal_error || tmplex->sphead == NULL) + if (yyparse(thd) || thd->is_fatal_error || tmplex->sphead == NULL) goto done; // Error else sp = tmplex->sphead; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 5ac904393f5..7ea9bfc1ba6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1043,6 +1043,15 @@ bool select_dumpvar::send_data(List &items) bool select_dumpvar::send_eof() { + /* This mimics select_send::send_eof(), which unlocks this way. + * It appears to be necessary, since tables aren't unlock after + * selects otherwise. + */ + if (thd->lock) + { + mysql_unlock_tables(thd, thd->lock); + thd->lock=0; + } if (row_count) { ::send_ok(thd,row_count); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5d82877d1b3..ce592b8ae97 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2982,13 +2982,17 @@ mysql_execute_command(THD *thd) } else { +#ifndef EMBEDDED_LIBRARY // When executing substatements, they're assumed to send_error when // it happens, but not to send_ok. my_bool nsok= thd->net.no_send_ok; thd->net.no_send_ok= TRUE; +#endif res= sp->execute(thd); +#ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; +#endif if (res == 0) send_ok(thd); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 269bd9143b8..ea3b550146b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1224,9 +1224,9 @@ sp_case: ; sp_whens: - /* Empty */ - | WHEN_SYM sp_case - | ELSE sp_proc_stmts + /* Empty */ {} + | WHEN_SYM sp_case {} + | ELSE sp_proc_stmts {} ; sp_labeled_control: From 52cd3e3142da39afb30855d24833209cae924c90 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 19 Feb 2003 12:42:32 +0100 Subject: [PATCH 32/83] Fixed SELECT INTO OUTFILE/DUMPFILE and stored procedures, and extended and reorganized the sp.test file. --- mysql-test/r/sp.result | 354 +++++++++++++++++++++++++---------------- mysql-test/t/sp.test | 330 +++++++++++++++++++++++++------------- sql/sql_class.cc | 18 +++ 3 files changed, 451 insertions(+), 251 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 35b35e91777..ddc8c805f78 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6,13 +6,31 @@ data int not null ); create procedure foo42() insert into test.t1 values ("foo", 42); +call foo42(); +select * from t1; +id data +foo 42 +delete from t1; +drop procedure foo42; create procedure bar(x char(16), y int) insert into test.t1 values (x, y); +call bar("bar", 666); +select * from t1; +id data +bar 666 +delete from t1; create procedure two(x1 char(16), x2 char(16), y int) begin insert into test.t1 values (x1, y); insert into test.t1 values (x2, y); end; +call two("one", "two", 3); +select * from t1; +id data +one 3 +two 3 +delete from t1; +drop procedure two; create procedure locset(x char(16), y int) begin declare z1, z2 int; @@ -20,12 +38,27 @@ set z1 = y; set z2 = z1+2; insert into test.t1 values (x, z2); end; +call locset("locset", 19); +select * from t1; +id data +locset 21 +delete from t1; +drop procedure locset; create procedure mixset(x char(16), y int) begin declare z int; set @z = y, z = 666, max_join_size = 100; insert into test.t1 values (x, z); end; +call mixset("mixset", 19); +show variables like 'max_join_size'; +Variable_name Value +max_join_size 100 +select id,data,@z from t1; +id data @z +mixset 666 19 +delete from t1; +drop procedure mixset; create procedure zip(x char(16), y int) begin declare z int; @@ -37,6 +70,14 @@ begin declare z int; set z = x+1, y = z; end; +call zip("zip", 99); +select * from t1; +id data +zip 100 +delete from t1; +drop procedure zip; +drop procedure zap; +drop procedure bar; create procedure iotest(x1 char(16), x2 char(16), y int) begin call inc2(x2, y); @@ -49,6 +90,15 @@ insert into test.t1 values (x, y); end; create procedure inc(inout io int) set io = io + 1; +call iotest("io1", "io2", 1); +select * from t1; +id data +io2 2 +io1 1 +delete from t1; +drop procedure iotest; +drop procedure inc2; +drop procedure inc; create procedure cbv1() begin declare y int; @@ -61,21 +111,53 @@ begin set y2 = 4711; insert into test.t1 values ("cbv2", y1); end; +call cbv1(); +select * from t1; +id data +cbv2 4 +cbv1 4711 +delete from t1; +drop procedure cbv1; +drop procedure cbv2; create procedure a0(x int) while x do set x = x-1; insert into test.t1 values ("a0", x); end while; +call a0(3); +select * from t1; +id data +a0 2 +a0 1 +a0 0 +delete from t1; +drop procedure a0; create procedure a(x int) while x > 0 do set x = x-1; insert into test.t1 values ("a", x); end while; +call a(3); +select * from t1; +id data +a 2 +a 1 +a 0 +delete from t1; +drop procedure a; create procedure b(x int) repeat insert into test.t1 values (repeat("b",3), x); set x = x-1; until x = 0 end repeat; +call b(3); +select * from t1; +id data +bbb 3 +bbb 2 +bbb 1 +delete from t1; +drop procedure b; create procedure b2(x int) repeat(select 1 into outfile 'b2'); insert into test.t1 values (repeat("b2",3), x); @@ -96,6 +178,14 @@ set x = x-1; iterate hmm; insert into test.t1 values ("x", x); end while hmm; +call c(3); +select * from t1; +id data +c 3 +c 2 +c 1 +delete from t1; +drop procedure c; create procedure d(x int) hmm: while x > 0 do insert into test.t1 values ("d", x); @@ -103,6 +193,12 @@ set x = x-1; leave hmm; insert into test.t1 values ("x", x); end while hmm; +call d(3); +select * from t1; +id data +d 3 +delete from t1; +drop procedure d; create procedure e(x int) foo: loop if x = 0 then @@ -111,6 +207,14 @@ end if; insert into test.t1 values ("e", x); set x = x-1; end loop foo; +call e(3); +select * from t1; +id data +e 3 +e 2 +e 1 +delete from t1; +drop procedure e; create procedure f(x int) if x < 0 then insert into test.t1 values ("f", 0); @@ -119,122 +223,6 @@ insert into test.t1 values ("f", 1); else insert into test.t1 values ("f", 2); end if; -create procedure g(x int) -case -when x < 0 then -insert into test.t1 values ("g", 0); -when x = 0 then -insert into test.t1 values ("g", 1); -else -insert into test.t1 values ("g", 2); -end case; -create procedure h(x int) -case x -when 0 then -insert into test.t1 values ("h0", x); -when 1 then -insert into test.t1 values ("h1", x); -else -insert into test.t1 values ("h?", x); -end case; -create procedure into_test(x char(16), y int) -begin -insert into test.t1 values (x, y); -select id,data into x,y from test.t1 limit 1; -insert into test.t1 values (concat(x, "2"), y+2); -end; -create procedure into_test2(x char(16), y int) -begin -insert into test.t1 values (x, y); -select id,data into x,@z from test.t1 limit 1; -insert into test.t1 values (concat(x, "2"), y+2); -end; -call foo42(); -select * from t1; -id data -foo 42 -delete from t1; -call bar("bar", 666); -select * from t1; -id data -bar 666 -delete from t1; -call two("one", "two", 3); -select * from t1; -id data -one 3 -two 3 -delete from t1; -call locset("locset", 19); -select * from t1; -id data -locset 21 -delete from t1; -call mixset("mixset", 19); -show variables like 'max_join_size'; -Variable_name Value -max_join_size 100 -select id,data,@z from t1; -id data @z -mixset 666 19 -delete from t1; -call zip("zip", 99); -select * from t1; -id data -zip 100 -delete from t1; -call iotest("io1", "io2", 1); -select * from t1; -id data -io2 2 -io1 1 -delete from t1; -call cbv1(); -select * from t1; -id data -cbv2 4 -cbv1 4711 -delete from t1; -call a0(3); -select * from t1; -id data -a0 2 -a0 1 -a0 0 -delete from t1; -call a(3); -select * from t1; -id data -a 2 -a 1 -a 0 -delete from t1; -call b(3); -select * from t1; -id data -bbb 3 -bbb 2 -bbb 1 -delete from t1; -call c(3); -select * from t1; -id data -c 3 -c 2 -c 1 -delete from t1; -call d(3); -select * from t1; -id data -d 3 -delete from t1; -call e(3); -select * from t1; -id data -e 3 -e 2 -e 1 -delete from t1; call f(-2); call f(0); call f(4); @@ -244,6 +232,16 @@ f 0 f 1 f 2 delete from t1; +drop procedure f; +create procedure g(x int) +case +when x < 0 then +insert into test.t1 values ("g", 0); +when x = 0 then +insert into test.t1 values ("g", 1); +else +insert into test.t1 values ("g", 2); +end case; call g(-42); call g(0); call g(1); @@ -253,6 +251,16 @@ g 0 g 1 g 2 delete from t1; +drop procedure g; +create procedure h(x int) +case x +when 0 then +insert into test.t1 values ("h0", x); +when 1 then +insert into test.t1 values ("h1", x); +else +insert into test.t1 values ("h?", x); +end case; call h(0); call h(1); call h(17); @@ -262,39 +270,109 @@ h0 0 h1 1 h? 17 delete from t1; +drop procedure h; +drop table if exists fac; +create table fac (n int unsigned not null primary key, f bigint unsigned); +create procedure ifac(n int unsigned) +begin +declare i int unsigned; +set i = 1; +if n > 20 then +set n = 20; +end if; +while i <= n do +begin +declare f bigint unsigned; +set f = 0; # Temp. fix, this should not be needed in the future. +call fac(i, f); +insert into test.fac values (i, f); +set i = i + 1; +end; +end while; +end; +create procedure fac(n int unsigned, out f bigint unsigned) +begin +set f = 1; +while n > 1 do +set f = f * n; +set n = n - 1; +end while; +end; +call ifac(20); +select * from fac; +n f +1 1 +2 2 +3 6 +4 24 +5 120 +6 720 +7 5040 +8 40320 +9 362880 +10 3628800 +11 39916800 +12 479001600 +13 6227020800 +14 87178291200 +15 1307674368000 +16 20922789888000 +17 355687428096000 +18 6402373705728000 +19 121645100408832000 +20 2432902008176640000 +drop table fac; +drop procedure ifac; +drop procedure fac; +create procedure into_test(x char(16), y int) +begin +insert into test.t1 values (x, y); +select id,data into x,y from test.t1 limit 1; +insert into test.t1 values (concat(x, "2"), y+2); +end; call into_test("into", 100); select * from t1; id data into 100 into2 102 delete from t1; +drop procedure into_test; +create procedure into_test2(x char(16), y int) +begin +insert into test.t1 values (x, y); +select id,data into x,@z from test.t1 limit 1; +insert into test.t1 values (concat(x, "2"), y+2); +end; call into_test2("into", 100); select id,data,@z from t1; id data @z into 100 100 into2 102 100 delete from t1; -drop procedure foo42; -drop procedure bar; -drop procedure two; -drop procedure locset; -drop procedure mixset; -drop procedure zip; -drop procedure zap; -drop procedure iotest; -drop procedure inc2; -drop procedure inc; -drop procedure cbv1; -drop procedure cbv2; -drop procedure a0; -drop procedure a; -drop procedure b; -drop procedure c; -drop procedure d; -drop procedure e; -drop procedure f; -drop procedure g; -drop procedure h; -drop procedure into_test; drop procedure into_test2; +create procedure into_outfile(x char(16), y int) +begin +insert into test.t1 values (x, y); +select * into outfile "/tmp/spout" from test.t1; +insert into test.t1 values (concat(x, "2"), y+2); +end; +call into_outfile("ofile", 1); +delete from t1; +drop procedure into_outfile; +create procedure into_dumpfile(x char(16), y int) +begin +insert into test.t1 values (x, y); +select * into dumpfile "/tmp/spdump" from test.t1 limit 1; +insert into test.t1 values (concat(x, "2"), y+2); +end; +call into_dumpfile("dfile", 1); +delete from t1; +drop procedure into_dumpfile; +create procedure create_select(x char(16), y int) +begin +insert into test.t1 values (x, y); +create table test.t2 select * from test.t1; +insert into test.t2 values (concat(x, "2"), y+2); +end; +drop procedure create_select; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 48919ff1d6e..55aa287b8b0 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -14,16 +14,28 @@ create table t1 ( data int not null ); + # Single statement, no params. create procedure foo42() insert into test.t1 values ("foo", 42); +call foo42(); +select * from t1; +delete from t1; +drop procedure foo42; + + # Single statement, two IN params. create procedure bar(x char(16), y int) insert into test.t1 values (x, y); -# Now for multiple statements... +call bar("bar", 666); +select * from t1; +delete from t1; +# Don't drop procedure yet... + +# Now for multiple statements... delimiter |; # Two statements. @@ -33,6 +45,12 @@ begin insert into test.t1 values (x2, y); end| +call two("one", "two", 3)| +select * from t1| +delete from t1| +drop procedure two| + + # Simple test of local variables and SET. create procedure locset(x char(16), y int) begin @@ -42,6 +60,12 @@ begin insert into test.t1 values (x, z2); end| +call locset("locset", 19)| +select * from t1| +delete from t1| +drop procedure locset| + + # The peculiar (non-standard) mixture of variables types in SET. create procedure mixset(x char(16), y int) begin @@ -51,6 +75,13 @@ begin insert into test.t1 values (x, z); end| +call mixset("mixset", 19)| +show variables like 'max_join_size'| +select id,data,@z from t1| +delete from t1| +drop procedure mixset| + + # Multiple CALL statements, one with OUT parameter. create procedure zip(x char(16), y int) begin @@ -66,6 +97,13 @@ begin set z = x+1, y = z; end| +call zip("zip", 99)| +select * from t1| +delete from t1| +drop procedure zip| +drop procedure zap| +drop procedure bar| + # INOUT test create procedure iotest(x1 char(16), x2 char(16), y int) @@ -83,6 +121,13 @@ end| create procedure inc(inout io int) set io = io + 1| +call iotest("io1", "io2", 1)| +select * from t1| +delete from t1| +drop procedure iotest| +drop procedure inc2| +drop procedure inc| + # Call-by-value test # The expected result is: @@ -103,8 +148,14 @@ begin insert into test.t1 values ("cbv2", y1); end| +call cbv1()| +select * from t1| +delete from t1| +drop procedure cbv1| +drop procedure cbv2| -# Minimal tests of the flow control construts + +# Basic tests of the flow control constructs # Just test on 'x'... create procedure a0(x int) @@ -113,6 +164,12 @@ while x do insert into test.t1 values ("a0", x); end while| +call a0(3)| +select * from t1| +delete from t1| +drop procedure a0| + + # The same, but with a more traditional test. create procedure a(x int) while x > 0 do @@ -120,6 +177,12 @@ while x > 0 do insert into test.t1 values ("a", x); end while| +call a(3)| +select * from t1| +delete from t1| +drop procedure a| + + # REPEAT create procedure b(x int) repeat @@ -127,16 +190,24 @@ repeat set x = x-1; until x = 0 end repeat| +call b(3)| +select * from t1| +delete from t1| +drop procedure b| + + # Check that repeat isn't parsed the wrong way create procedure b2(x int) repeat(select 1 into outfile 'b2'); insert into test.t1 values (repeat("b2",3), x); set x = x-1; until x = 0 end repeat| + # We don't actually want to call it. drop procedure b2| -# Btw, this should generate an error + +# Btw, this should generate an error (for now; this might change in the future) --error 1259 create procedure b3(x int) repeat @@ -145,6 +216,7 @@ repeat set x = x-1; until x = 0 end repeat| + # Labelled WHILE with ITERATE (pointless really) create procedure c(x int) hmm: while x > 0 do @@ -154,6 +226,12 @@ hmm: while x > 0 do insert into test.t1 values ("x", x); end while hmm| +call c(3)| +select * from t1| +delete from t1| +drop procedure c| + + # Labelled WHILE with LEAVE create procedure d(x int) hmm: while x > 0 do @@ -163,6 +241,12 @@ hmm: while x > 0 do insert into test.t1 values ("x", x); end while hmm| +call d(3)| +select * from t1| +delete from t1| +drop procedure d| + + # LOOP, with simple IF statement create procedure e(x int) foo: loop @@ -173,6 +257,12 @@ foo: loop set x = x-1; end loop foo| +call e(3)| +select * from t1| +delete from t1| +drop procedure e| + + # A full IF statement create procedure f(x int) if x < 0 then @@ -183,6 +273,14 @@ else insert into test.t1 values ("f", 2); end if| +call f(-2)| +call f(0)| +call f(4)| +select * from t1| +delete from t1| +drop procedure f| + + # This form of CASE is really just syntactic sugar for IF-ELSEIF-... create procedure g(x int) case @@ -194,6 +292,14 @@ else insert into test.t1 values ("g", 2); end case| +call g(-42)| +call g(0)| +call g(1)| +select * from t1| +delete from t1| +drop procedure g| + + # The "simple CASE" create procedure h(x int) case x @@ -205,6 +311,56 @@ else insert into test.t1 values ("h?", x); end case| +call h(0)| +call h(1)| +call h(17)| +select * from t1| +delete from t1| +drop procedure h| + + +# A "real" procedure example + +--disable_warnings +drop table if exists fac| +--enable_warnings +create table fac (n int unsigned not null primary key, f bigint unsigned)| + +create procedure ifac(n int unsigned) +begin + declare i int unsigned; + set i = 1; + if n > 20 then + set n = 20; + end if; + while i <= n do + begin + declare f bigint unsigned; + set f = 0; # Temp. fix, this should not be needed in the future. + call fac(i, f); + insert into test.fac values (i, f); + set i = i + 1; + end; + end while; +end| + +create procedure fac(n int unsigned, out f bigint unsigned) +begin + set f = 1; + while n > 1 do + set f = f * n; + set n = n - 1; + end while; +end| + +call ifac(20)| +select * from fac| +drop table fac| +drop procedure ifac| +drop procedure fac| + + +# SELECT INTO local variables create procedure into_test(x char(16), y int) begin insert into test.t1 values (x, y); @@ -212,7 +368,13 @@ begin insert into test.t1 values (concat(x, "2"), y+2); end| -# Test INTO with a mix of local and global variables +call into_test("into", 100)| +select * from t1| +delete from t1| +drop procedure into_test| + + +# SELECT INTO with a mix of local and global variables create procedure into_test2(x char(16), y int) begin insert into test.t1 values (x, y); @@ -220,114 +382,56 @@ begin insert into test.t1 values (concat(x, "2"), y+2); end| +call into_test2("into", 100)| +select id,data,@z from t1| +delete from t1| +drop procedure into_test2| + + +# These two (and the two procedures above) caused an assert() to fail in +# sql_base.cc:lock_tables() at some point. + +create procedure into_outfile(x char(16), y int) +begin + insert into test.t1 values (x, y); + select * into outfile "/tmp/spout" from test.t1; + insert into test.t1 values (concat(x, "2"), y+2); +end| + +system rm -f /tmp/spout| +call into_outfile("ofile", 1)| +system rm -f /tmp/spout| +delete from t1| +drop procedure into_outfile| + +create procedure into_dumpfile(x char(16), y int) +begin + insert into test.t1 values (x, y); + select * into dumpfile "/tmp/spdump" from test.t1 limit 1; + insert into test.t1 values (concat(x, "2"), y+2); +end| + +system rm -f /tmp/spdump| +call into_dumpfile("dfile", 1)| +system rm -f /tmp/spdump| +delete from t1| +drop procedure into_dumpfile| + + +create procedure create_select(x char(16), y int) +begin + insert into test.t1 values (x, y); + create table test.t2 select * from test.t1; + insert into test.t2 values (concat(x, "2"), y+2); +end| + +# This doesn't work right now. It suffers from the same problem as the ones +# above, but the fix caused create.test to hang. :-( +#call create_select("cs", 90)| +#select * from t1, t2| +#delete from t1| +#drop table t2| +drop procedure create_select| + delimiter ;| - -# Now, the CALL tests... -call foo42(); -select * from t1; -delete from t1; - -call bar("bar", 666); -select * from t1; -delete from t1; - -call two("one", "two", 3); -select * from t1; -delete from t1; - -call locset("locset", 19); -select * from t1; -delete from t1; - -call mixset("mixset", 19); -show variables like 'max_join_size'; -select id,data,@z from t1; -delete from t1; - -call zip("zip", 99); -select * from t1; -delete from t1; - -call iotest("io1", "io2", 1); -select * from t1; -delete from t1; - -call cbv1(); -select * from t1; -delete from t1; - -call a0(3); -select * from t1; -delete from t1; - -call a(3); -select * from t1; -delete from t1; - -call b(3); -select * from t1; -delete from t1; - -call c(3); -select * from t1; -delete from t1; - -call d(3); -select * from t1; -delete from t1; - -call e(3); -select * from t1; -delete from t1; - -call f(-2); -call f(0); -call f(4); -select * from t1; -delete from t1; - -call g(-42); -call g(0); -call g(1); -select * from t1; -delete from t1; - -call h(0); -call h(1); -call h(17); -select * from t1; -delete from t1; - -call into_test("into", 100); -select * from t1; -delete from t1; - -call into_test2("into", 100); -select id,data,@z from t1; -delete from t1; - -drop procedure foo42; -drop procedure bar; -drop procedure two; -drop procedure locset; -drop procedure mixset; -drop procedure zip; -drop procedure zap; -drop procedure iotest; -drop procedure inc2; -drop procedure inc; -drop procedure cbv1; -drop procedure cbv2; -drop procedure a0; -drop procedure a; -drop procedure b; -drop procedure c; -drop procedure d; -drop procedure e; -drop procedure f; -drop procedure g; -drop procedure h; -drop procedure into_test; -drop procedure into_test2; - drop table t1; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7ea9bfc1ba6..ac82996600f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -801,6 +801,15 @@ void select_export::send_error(uint errcode, const char *err) bool select_export::send_eof() { + /* This mimics select_send::send_eof(), which unlocks this way. + * It appears to be necessary, since tables aren't unlock after + * selects otherwise. + */ + if (thd->lock) + { + mysql_unlock_tables(thd, thd->lock); + thd->lock=0; + } int error=test(end_io_cache(&cache)); if (my_close(file,MYF(MY_WME))) error=1; @@ -911,6 +920,15 @@ void select_dump::send_error(uint errcode,const char *err) bool select_dump::send_eof() { + /* This mimics select_send::send_eof(), which unlocks this way. + * It appears to be necessary, since tables aren't unlock after + * selects otherwise. + */ + if (thd->lock) + { + mysql_unlock_tables(thd, thd->lock); + thd->lock=0; + } int error=test(end_io_cache(&cache)); if (my_close(file,MYF(MY_WME))) error=1; From d8c75ec8aa867ec002c543e7931d54fd7144fd46 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 21 Feb 2003 17:37:05 +0100 Subject: [PATCH 33/83] Most of the groundwork for sprint task 729 (implement FUNCTIONs). Expanded the mysql.proc table, reworked the find/create/drop functions completely, added new functions for FUNCTIONs (lotta functions here :), got rid of some unnecessary use of Item_strings while at it. Extended the parser correspondingly, and fiddled around a bit to make SP FUNCTIONs coexist with UDFs. Can now CREATE and DROP FUNCTIONs. Invoking yet to come... --- Docs/sp-implemented.txt | 14 +- include/mysqld_error.h | 4 +- mysql-test/install_test_db.sh | 3 +- mysql-test/r/sp.result | 16 ++ mysql-test/t/sp.test | 27 ++++ scripts/mysql_install_db.sh | 3 +- sql/lex.h | 5 +- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sp.cc | 248 ++++++++++++++++++++++-------- sql/sp.h | 19 ++- sql/sp_head.cc | 38 +++-- sql/sp_head.h | 20 ++- sql/sql_lex.h | 4 +- sql/sql_parse.cc | 112 ++++++++------ sql/sql_yacc.yy | 124 ++++++++++----- 37 files changed, 478 insertions(+), 182 deletions(-) diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index 97d4df2b62c..b3b12b7edb8 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -11,6 +11,8 @@ Summary of Not Yet Implemented: - SQL-99 COMMIT (related to BEGIN/END) - DECLARE CURSOR ... - FOR-loops (as it requires cursors) + - CASCADE/RESTRICT for ALTER and DROP + - ALTER/DROP METHOD (as it implies User Defined Types) Summary of what's implemented: @@ -66,15 +68,23 @@ List of what's implemented: databases.) -Open questions: +Closed questions: - What is the expected result when creating a procedure with a name that already exists? An error or overwrite? + Answer: Error + - Do PROCEDUREs and FUNCTIONs share namespace or not? I think not, but the we need to flag the type in the mysql.proc table and the name alone is not a unique key any more, or, we have separate tables. (Unfortunately, mysql.func is already taken. Use "sfunc" and maybe even rename "proc" into "sproc" while we still can, for consistency?) + Answer: Same tables, with an additional key-field for the type. + + +Open questions: + - SQL-99 variables and parameters are typed. For the present we don't do any type checking, since this is the way MySQL works. I still don't know - if we should keep it this way, or implement type checking. + if we should keep it this way, or implement type checking. Possibly we + should have optional, uset-settable, type checking. diff --git a/include/mysqld_error.h b/include/mysqld_error.h index f52fc75be86..48e7f42c707 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -276,5 +276,5 @@ #define ER_SP_LABEL_MISMATCH 1257 #define ER_SP_UNINIT_VAR 1258 #define ER_SP_BADSELECT 1259 -#define ER_ERROR_MESSAGES 260 - +#define ER_SP_BADRETURN 1260 +#define ER_ERROR_MESSAGES 261 diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index aff00f6ce00..ed3b0fd683e 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -251,8 +251,9 @@ if test ! -f $mdata/proc.frm then c_p="$c_p CREATE TABLE proc (" c_p="$c_p name char(64) binary DEFAULT '' NOT NULL," + c_p="$c_p type enum('function','procedure') NOT NULL," c_p="$c_p body blob DEFAULT '' NOT NULL," - c_p="$c_p PRIMARY KEY (name)" + c_p="$c_p PRIMARY KEY (name,type)" c_p="$c_p )" c_p="$c_p comment='Stored Procedures';" fi diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ddc8c805f78..ba2709ebb7e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -375,4 +375,20 @@ create table test.t2 select * from test.t1; insert into test.t2 values (concat(x, "2"), y+2); end; drop procedure create_select; +create function foo returns real soname "foo.so"; +Can't open shared library 'foo.so' (errno: 22 foo.so: cannot open shared object file: No such file or director) +create function e() returns double +return 2.7182818284590452354; +drop function e; +create function fac(n int unsigned) returns bigint unsigned +begin +declare f bigint unsigned; +set f = 1; +while n > 1 do +set f = f * n; +set n = n - 1; +end while; +return f; +end; +drop function fac; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 55aa287b8b0..2be927c78ff 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -433,5 +433,32 @@ end| #drop table t2| drop procedure create_select| +# Check that we get the right error, i.e. UDF declaration parses correctly, +# but foo.so doesn't exist. +--error 1126 +create function foo returns real soname "foo.so"| + +# A minimal, constant FUNCTION. +create function e() returns double + return 2.7182818284590452354| + +drop function e| + + +# A function with flow control and a RETURN statement +create function fac(n int unsigned) returns bigint unsigned +begin + declare f bigint unsigned; + + set f = 1; + while n > 1 do + set f = f * n; + set n = n - 1; + end while; + return f; +end| + +drop function fac| + delimiter ;| drop table t1; diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 8ff5653d299..b7dc3fce194 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -312,8 +312,9 @@ then c_p="$c_p CREATE TABLE proc (" c_p="$c_p name char(64) binary DEFAULT '' NOT NULL," + c_p="$c_p type enum('function','procedure') NOT NULL," c_p="$c_p body blob DEFAULT '' NOT NULL," - c_p="$c_p PRIMARY KEY (name)" + c_p="$c_p PRIMARY KEY (name,type)" c_p="$c_p )" c_p="$c_p comment='Stored Procedures';" fi diff --git a/sql/lex.h b/sql/lex.h index 0cec9ef8a5d..33fbb90d21f 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -175,7 +175,7 @@ static SYMBOL symbols[] = { { "FOR", SYM(FOR_SYM),0,0}, { "FULL", SYM(FULL),0,0}, { "FULLTEXT", SYM(FULLTEXT_SYM),0,0}, - { "FUNCTION", SYM(UDF_SYM),0,0}, + { "FUNCTION", SYM(FUNCTION_SYM),0,0}, { "GEOMETRY", SYM(GEOMETRY_SYM),0,0}, { "GLOBAL", SYM(GLOBAL_SYM),0,0}, { "GRANT", SYM(GRANT),0,0}, @@ -332,7 +332,8 @@ static SYMBOL symbols[] = { { "USER_RESOURCES", SYM(RESOURCES),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTRICT", SYM(RESTRICT),0,0}, - { "RETURNS", SYM(UDF_RETURNS_SYM),0,0}, + { "RETURN", SYM(RETURN_SYM),0,0}, + { "RETURNS", SYM(RETURNS_SYM),0,0}, { "REVOKE", SYM(REVOKE),0,0}, { "RIGHT", SYM(RIGHT),0,0}, { "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */ diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index dd2df4c5243..67a7fc8259d 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -270,3 +270,4 @@ v/* "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 3c66c5a64f2..193d8204c7d 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -264,3 +264,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index cdae9092602..e328bc64cfd 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -272,3 +272,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 6aa45c2ced2..b2e56d8b701 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -261,3 +261,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index af32e4cc630..46b7240dd6d 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -266,3 +266,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 147948d567f..5dba7cd4739 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -261,3 +261,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index c3b4713241a..0a90b30d07c 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -271,3 +271,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 43ba3c3b173..0d64095b2e3 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -261,3 +261,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 9355daa634e..4927b9b86e0 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -263,3 +263,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index aee2c229f80..7a38bb4c9f0 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -261,3 +261,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 2b7515c12d1..21c891fb982 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -263,3 +263,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index b8e0e7a4f25..61aa944c92d 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -261,3 +261,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 15894decc4a..527db96e708 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -263,3 +263,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 01ce52ec060..9af96c322c6 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -263,3 +263,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index a2440d5928e..cec72e6a1a2 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -265,3 +265,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 86b44f4d97d..93f1bc4af81 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -261,3 +261,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index f6cc343a70d..c6cd6efc9a0 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -265,3 +265,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 33dc4e5d3b8..ecad689594d 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -264,3 +264,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index eb699fc812c..456df149576 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -257,3 +257,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index b1253642081..a2a9f94e970 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -269,3 +269,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 6be74571317..9faddd8b7f1 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -262,3 +262,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 512314cf856..33359dbf7aa 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -261,3 +261,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 337157829a9..dfdb3e1c378 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -266,3 +266,4 @@ "End-label without match" "Referring to uninitialized variable" "SELECT in a stored procedure must have INTO" +"RETURN is only allowed in a stored FUNCTION" diff --git a/sql/sp.cc b/sql/sp.cc index 2d4cf97bce1..eb3a9871ab5 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -19,48 +19,158 @@ #include "sp.h" #include "sp_head.h" -// Finds the SP 'name'. Currently this always reads from the database -// and prepares (parse) it, but in the future it will first look in -// the in-memory cache for SPs. (And store newly prepared SPs there of -// course.) -sp_head * -sp_find_procedure(THD *thd, Item_string *iname) +/* + * + * DB storage of Stored PROCEDUREs and FUNCTIONs + * + */ + +static int +db_find_routine_aux(THD *thd, int type, char *name, uint namelen, + enum thr_lock_type ltype, TABLE **tablep) { - DBUG_ENTER("sp_find_procedure"); - extern int yyparse(void *thd); - LEX *tmplex; + DBUG_ENTER("db_find_routine_aux"); + DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); TABLE *table; TABLE_LIST tables; - const char *defstr; - String *name; - sp_head *sp = NULL; + byte key[65]; // We know name is 64 and the enum is 1 byte + uint keylen; + int ret; + + // Put the key together + keylen= namelen; + if (keylen > sizeof(key)-1) + keylen= sizeof(key)-1; + memcpy(key, name, keylen); + memset(key+keylen, (int)' ', sizeof(key)-1 - keylen); // Pad with space + key[sizeof(key)-1]= type; + keylen= sizeof(key); - name = iname->const_string(); - DBUG_PRINT("enter", ("name: %*s", name->length(), name->c_ptr())); memset(&tables, 0, sizeof(tables)); tables.db= (char*)"mysql"; tables.real_name= tables.alias= (char*)"proc"; - if (! (table= open_ltable(thd, &tables, TL_READ))) - DBUG_RETURN(NULL); + if (! (table= open_ltable(thd, &tables, ltype))) + DBUG_RETURN(SP_OPEN_TABLE_FAILED); if (table->file->index_read_idx(table->record[0], 0, - (byte*)name->c_ptr(), name->length(), + key, keylen, HA_READ_KEY_EXACT)) - goto done; + { + close_thread_tables(thd); + DBUG_RETURN(SP_KEY_NOT_FOUND); + } + *tablep= table; - if ((defstr= get_field(&thd->mem_root, table->field[1])) == NULL) - goto done; + DBUG_RETURN(SP_OK); +} + +static int +db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) +{ + DBUG_ENTER("db_find_routine"); + DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); + extern int yyparse(void *thd); + LEX *tmplex; + TABLE *table; + const char *defstr; + int ret; // QQ Set up our own mem_root here??? + ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table); + if (ret != SP_OK) + goto done; + if ((defstr= get_field(&thd->mem_root, table->field[2])) == NULL) + { + ret= SP_GET_FIELD_FAILED; + goto done; + } + tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); if (yyparse(thd) || thd->is_fatal_error || tmplex->sphead == NULL) - goto done; // Error + ret= SP_PARSE_ERROR; else - sp = tmplex->sphead; + *sphp= tmplex->sphead; done: - if (table) + if (ret == SP_OK && table) close_thread_tables(thd); + DBUG_RETURN(ret); +} + +static int +db_create_routine(THD *thd, int type, + char *name, uint namelen, char *def, uint deflen) +{ + DBUG_ENTER("db_create_routine"); + DBUG_PRINT("enter", ("type: %d name: %*s def: %*s", type, namelen, name, deflen, def)); + int ret; + TABLE *table; + TABLE_LIST tables; + + memset(&tables, 0, sizeof(tables)); + tables.db= (char*)"mysql"; + tables.real_name= tables.alias= (char*)"proc"; + + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + ret= SP_OPEN_TABLE_FAILED; + else + { + restore_record(table, 2); // Get default values for fields + + table->field[0]->store(name, namelen, default_charset_info); + table->field[1]->store((longlong)type); + table->field[2]->store(def, deflen, default_charset_info); + + if (table->file->write_row(table->record[0])) + ret= SP_WRITE_ROW_FAILED; + else + ret= SP_OK; + } + + if (ret == SP_OK && table) + close_thread_tables(thd); + DBUG_RETURN(ret); +} + +static int +db_drop_routine(THD *thd, int type, char *name, uint namelen) +{ + DBUG_ENTER("db_drop_routine"); + DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); + TABLE *table; + int ret; + + ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table); + if (ret == SP_OK) + { + if (table->file->delete_row(table->record[0])) + ret= SP_DELETE_ROW_FAILED; + } + + if (ret == SP_OK && table) + close_thread_tables(thd); + DBUG_RETURN(ret); +} + + +/* + * + * PROCEDURE + * + */ + +sp_head * +sp_find_procedure(THD *thd, LEX_STRING *name) +{ + DBUG_ENTER("sp_find_procedure"); + sp_head *sp; + + DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + + if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, + name->str, name->length, &sp) != SP_OK) + sp= NULL; + DBUG_RETURN(sp); } @@ -69,29 +179,10 @@ sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) { DBUG_ENTER("sp_create_procedure"); DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def)); - int ret= 0; - TABLE *table; - TABLE_LIST tables; + int ret; - memset(&tables, 0, sizeof(tables)); - tables.db= (char*)"mysql"; - tables.real_name= tables.alias= (char*)"proc"; - /* Allow creation of procedures even if we can't open proc table */ - if (! (table= open_ltable(thd, &tables, TL_WRITE))) - { - ret= -1; - goto done; - } + ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, def, deflen); - restore_record(table, 2); // Get default values for fields - - table->field[0]->store(name, namelen, default_charset_info); - table->field[1]->store(def, deflen, default_charset_info); - - ret= table->file->write_row(table->record[0]); - - done: - close_thread_tables(thd); DBUG_RETURN(ret); } @@ -100,26 +191,55 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) { DBUG_ENTER("sp_drop_procedure"); DBUG_PRINT("enter", ("name: %*s", namelen, name)); - TABLE *table; - TABLE_LIST tables; + int ret; - tables.db= (char *)"mysql"; - tables.real_name= tables.alias= (char *)"proc"; - if (! (table= open_ltable(thd, &tables, TL_WRITE))) - goto err; - if (! table->file->index_read_idx(table->record[0], 0, - (byte *)name, namelen, - HA_READ_KEY_EXACT)) - { - int error; + ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen); - if ((error= table->file->delete_row(table->record[0]))) - table->file->print_error(error, MYF(0)); - } - close_thread_tables(thd); - DBUG_RETURN(0); - - err: - close_thread_tables(thd); - DBUG_RETURN(-1); + DBUG_RETURN(ret); +} + + +/* + * + * FUNCTION + * + */ + +sp_head * +sp_find_function(THD *thd, LEX_STRING *name) +{ + DBUG_ENTER("sp_find_function_i"); + sp_head *sp; + + DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + + if (db_find_routine(thd, TYPE_ENUM_FUNCTION, + name->str, name->length, &sp) != SP_OK) + sp= NULL; + + DBUG_RETURN(sp); +} + +int +sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen) +{ + DBUG_ENTER("sp_create_function"); + DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def)); + int ret; + + ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, def, deflen); + + DBUG_RETURN(ret); +} + +int +sp_drop_function(THD *thd, char *name, uint namelen) +{ + DBUG_ENTER("sp_drop_function"); + DBUG_PRINT("enter", ("name: %*s", namelen, name)); + int ret; + + ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen); + + DBUG_RETURN(ret); } diff --git a/sql/sp.h b/sql/sp.h index 99ea97cba8f..084afb8c8e0 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -18,11 +18,17 @@ #ifndef _SP_H_ #define _SP_H_ -// -// Finds a stored procedure given its name. Returns NULL if not found. -// +// Return codes from sp_create_* and sp_drop_*: +#define SP_OK 0 +#define SP_KEY_NOT_FOUND -1 +#define SP_OPEN_TABLE_FAILED -2 +#define SP_WRITE_ROW_FAILED -3 +#define SP_DELETE_ROW_FAILED -4 +#define SP_GET_FIELD_FAILED -5 +#define SP_PARSE_ERROR -6 + sp_head * -sp_find_procedure(THD *thd, Item_string *name); +sp_find_procedure(THD *thd, LEX_STRING *name); int sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen); @@ -30,15 +36,14 @@ sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen); int sp_drop_procedure(THD *thd, char *name, uint namelen); -#if 0 + sp_head * -sp_find_function(THD *thd, Item_string *name); +sp_find_function(THD *thd, LEX_STRING *name); int sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen); int sp_drop_function(THD *thd, char *name, uint namelen); -#endif #endif /* _SP_H_ */ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ff487429ec7..8682fa2cd9d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -102,11 +102,20 @@ sp_head::create(THD *thd) DBUG_ENTER("sp_head::create"); String *name= m_name->const_string(); String *def= m_defstr->const_string(); + int ret; - DBUG_PRINT("info", ("name: %s def: %s", name->c_ptr(), def->c_ptr())); - DBUG_RETURN(sp_create_procedure(thd, - name->c_ptr(), name->length(), - def->c_ptr(), def->length())); + DBUG_PRINT("info", ("type: %d name: %s def: %s", + m_type, name->c_ptr(), def->c_ptr())); + if (m_type == TYPE_ENUM_FUNCTION) + ret= sp_create_function(thd, + name->c_ptr(), name->length(), + def->c_ptr(), def->length()); + else + ret= sp_create_procedure(thd, + name->c_ptr(), name->length(), + def->c_ptr(), def->length()); + + DBUG_RETURN(ret); } int @@ -127,7 +136,7 @@ sp_head::execute(THD *thd) { uint i; List_iterator_fast li(m_call_lex->value_list); - Item *it = li++; // Skip first one, it's the procedure name + Item *it; nctx = new sp_rcontext(csize); if (! octx) @@ -184,7 +193,7 @@ sp_head::execute(THD *thd) if (ret == 0 && csize > 0) { List_iterator_fast li(m_call_lex->value_list); - Item *it = li++; // Skip first one, it's the procedure name + Item *it; // Copy back all OUT or INOUT values to the previous frame, or // set global user variables @@ -273,23 +282,18 @@ sp_head::restore_lex(THD *thd) // Collect some data from the sub statement lex. if (thd->lex.sql_command == SQLCOM_CALL) { - // We know they are Item_strings (since we put them there ourselves) // It would be slightly faster to keep the list sorted, but we need // an "insert before" method to do that. - Item_string *proc= static_cast(thd->lex.value_list.head()); - String *snew= proc->val_str(NULL); - List_iterator_fast li(m_calls); - Item_string *it; + char *proc= thd->lex.udf.name.str; + + List_iterator_fast li(m_calls); + char **it; while ((it= li++)) - { - String *sold= it->val_str(NULL); - - if (stringcmp(snew, sold) == 0) + if (strcasecmp(proc, *it) == 0) break; - } if (! it) - m_calls.push_back(proc); + m_calls.push_back(&proc); } // Merge used tables diff --git a/sql/sp_head.h b/sql/sp_head.h index 820193e8184..b0f57757f98 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -24,6 +24,11 @@ #include +// Values for the type enum. This reflects the order of the enum declaration +// in the CREATE TABLE command. +#define TYPE_ENUM_FUNCTION 1 +#define TYPE_ENUM_PROCEDURE 2 + struct sp_label; class sp_instr; @@ -35,8 +40,10 @@ class sp_head : public Sql_alloc public: + int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE + enum enum_field_types m_returns; // For FUNCTIONs only my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise - List m_calls; // Called procedures. + List m_calls; // Called procedures. List m_tables; // Used tables. static void *operator new(size_t size) @@ -87,6 +94,15 @@ public: void backpatch(struct sp_label *); + char *name(uint *lenp = 0) const + { + String *n= m_name->const_string(); + + if (lenp) + *lenp= n->length(); + return n->c_ptr(); + } + private: Item_string *m_name; @@ -99,7 +115,7 @@ private: struct sp_label *lab; sp_instr *instr; } bp_t; - List m_backpatch; // Instructions needing backpaching + List m_backpatch; // Instructions needing backpatching inline sp_instr * get_instr(uint i) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5e3a0a5762b..9a4b4b8bd08 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -75,8 +75,8 @@ enum enum_sql_command { SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, SQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_TABLE_TYPES, SQLCOM_SHOW_PRIVILEGES, SQLCOM_HELP, - SQLCOM_CREATE_PROCEDURE, SQLCOM_CALL, SQLCOM_DROP_PROCEDURE, - SQLCOM_ALTER_PROCEDURE, + SQLCOM_CREATE_PROCEDURE, SQLCOM_CALL, + SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION, /* This should be the last !!! */ SQLCOM_END diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ce592b8ae97..a4ff6a91b33 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2763,26 +2763,24 @@ mysql_execute_command(THD *thd) res=mysqld_show_create_db(thd,lex->name,&lex->create_info); break; } - case SQLCOM_CREATE_FUNCTION: - if (check_access(thd,INSERT_ACL,"mysql",0,1)) - break; + case SQLCOM_CREATE_FUNCTION: // UDF function + { + if (check_access(thd,INSERT_ACL,"mysql",0,1)) + break; #ifdef HAVE_DLOPEN - if (!(res = mysql_create_function(thd,&lex->udf))) - send_ok(thd); + sp_head *sph= sp_find_function(thd, &lex->udf.name); + if (sph) + { + net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str); + goto error; + } + if (!(res = mysql_create_function(thd,&lex->udf))) + send_ok(thd); #else - res= -1; + res= -1; #endif - break; - case SQLCOM_DROP_FUNCTION: - if (check_access(thd,DELETE_ACL,"mysql",0,1)) break; -#ifdef HAVE_DLOPEN - if (!(res = mysql_drop_function(thd,&lex->udf.name))) - send_ok(thd); -#else - res= -1; -#endif - break; + } case SQLCOM_REVOKE: case SQLCOM_GRANT: { @@ -2951,7 +2949,7 @@ mysql_execute_command(THD *thd) res= -1; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; - case SQLCOM_CREATE_PROCEDURE: + case SQLCOM_CREATE_PROCEDURE: // FUNCTION too (but not UDF!) if (!lex->sphead) { send_error(thd, ER_SP_NO_RECURSIVE_CREATE); @@ -2959,22 +2957,35 @@ mysql_execute_command(THD *thd) } else { - res= lex->sphead->create(thd); - if (res != 0) + uint namelen; + char *name= lex->sphead->name(&namelen); + udf_func *udf = find_udf(name, namelen); + + if (udf) { - send_error(thd, ER_SP_ALREADY_EXISTS); + net_printf(thd, ER_UDF_EXISTS, name); + goto error; + } + res= lex->sphead->create(thd); + switch (res) + { + case SP_OK: + send_ok(thd); + break; + case SP_WRITE_ROW_FAILED: + send_error(thd, ER_SP_ALREADY_EXISTS); + goto error; + default: + send_error(thd, ER_SP_STORE_FAILED); goto error; } - send_ok(thd); } break; case SQLCOM_CALL: { - Item_string *s; sp_head *sp; - s= (Item_string*)lex->value_list.head(); - sp= sp_find_procedure(thd, s); + sp= sp_find_procedure(thd, &lex->udf.name); if (! sp) { send_error(thd, ER_SP_DOES_NOT_EXIST); @@ -3002,12 +3013,14 @@ mysql_execute_command(THD *thd) } break; case SQLCOM_ALTER_PROCEDURE: + case SQLCOM_ALTER_FUNCTION: { - Item_string *s; sp_head *sp; - s= (Item_string*)lex->value_list.head(); - sp= sp_find_procedure(thd, s); + if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) + sp= sp_find_procedure(thd, &lex->udf.name); + else + sp= sp_find_function(thd, &lex->udf.name); if (! sp) { send_error(thd, ER_SP_DOES_NOT_EXIST); @@ -3022,28 +3035,41 @@ mysql_execute_command(THD *thd) } break; case SQLCOM_DROP_PROCEDURE: + case SQLCOM_DROP_FUNCTION: { - Item_string *s; - sp_head *sp; - - s = (Item_string*)lex->value_list.head(); - sp = sp_find_procedure(thd, s); - if (! sp) - { - send_error(thd, ER_SP_DOES_NOT_EXIST); - goto error; - } + if (lex->sql_command == SQLCOM_DROP_PROCEDURE) + res= sp_drop_procedure(thd, lex->udf.name.str, lex->udf.name.length); else { - String *name = s->const_string(); - - res= sp_drop_procedure(thd, name->c_ptr(), name->length()); - if (res != 0) + res= sp_drop_function(thd, lex->udf.name.str, lex->udf.name.length); +#ifdef HAVE_DLOPEN + if (res == SP_KEY_NOT_FOUND) { - send_error(thd, ER_SP_DROP_FAILED); - goto error; + udf_func *udf = find_udf(lex->udf.name.str, lex->udf.name.length); + if (udf) + { + if (check_access(thd, DELETE_ACL, "mysql", 0, 1)) + goto error; + if (!(res = mysql_drop_function(thd,&lex->udf.name))) + { + send_ok(thd); + break; + } + } } +#endif + } + switch (res) + { + case SP_OK: send_ok(thd); + break; + case SP_KEY_NOT_FOUND: + send_error(thd, ER_SP_DOES_NOT_EXIST); + goto error; + default: + send_error(thd, ER_SP_DROP_FAILED); + goto error; } } break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ea3b550146b..bfb9d06c16c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -366,9 +366,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token FUNC_ARG1 %token FUNC_ARG2 %token FUNC_ARG3 -%token UDF_RETURNS_SYM +%token RETURN_SYM +%token RETURNS_SYM %token UDF_SONAME_SYM -%token UDF_SYM +%token FUNCTION_SYM %token UNCOMMITTED_SYM %token UNDERSCORE_CHARSET %token UNICODE_SYM @@ -902,27 +903,23 @@ create: lex->name=$4.str; lex->create_info.options=$3; } - | CREATE udf_func_type UDF_SYM IDENT + | CREATE udf_func_type FUNCTION_SYM IDENT { LEX *lex=Lex; - lex->sql_command = SQLCOM_CREATE_FUNCTION; lex->udf.name = $4; lex->udf.type= $2; } - UDF_RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING - { - LEX *lex=Lex; - lex->udf.returns=(Item_result) $7; - lex->udf.dl=$9.str; - } + create_function_tail + {} | CREATE PROCEDURE ident { LEX *lex= Lex; - lex->spcont = new sp_pcontext(); - lex->sphead = new sp_head(&$3, lex); + lex->spcont= new sp_pcontext(); + lex->sphead= new sp_head(&$3, lex); + lex->sphead->m_type= TYPE_ENUM_PROCEDURE; } - '(' sp_dparam_list ')' + '(' sp_pdparam_list ')' { Lex->spcont->set_params(); } @@ -932,15 +929,43 @@ create: } ; +create_function_tail: + RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_CREATE_FUNCTION; + lex->udf.returns=(Item_result) $2; + lex->udf.dl=$4.str; + } + | '(' + { + LEX *lex= Lex; + + lex->sql_command = SQLCOM_CREATE_PROCEDURE; + lex->spcont= new sp_pcontext(); + lex->sphead= new sp_head(&lex->udf.name, lex); + lex->sphead->m_type= TYPE_ENUM_FUNCTION; + } + sp_fdparam_list ')' + { + Lex->spcont->set_params(); + } + RETURNS_SYM type + { + Lex->sphead->m_returns= (enum enum_field_types)$7; + } + sp_proc_stmt + {} + ; + call: CALL_SYM ident { LEX *lex = Lex; lex->sql_command= SQLCOM_CALL; + lex->udf.name= $2; lex->value_list.empty(); - lex->value_list.push_back( - (Item*)new Item_string($2.str, $2.length, default_charset_info)); } '(' sp_cparam_list ')' {} ; @@ -962,18 +987,36 @@ sp_cparams: } ; -/* SP parameter declaration list */ -sp_dparam_list: +/* Stored FUNCTION parameter declaration list */ +sp_fdparam_list: /* Empty */ - | sp_dparams + | sp_fdparams ; -sp_dparams: - sp_dparams ',' sp_dparam - | sp_dparam +sp_fdparams: + sp_fdparams ',' sp_fdparam + | sp_fdparam ; -sp_dparam: +sp_fdparam: + ident type sp_opt_locator + { + Lex->spcont->push(&$1, (enum enum_field_types)$2, sp_param_in); + } + ; + +/* Stored PROCEDURE parameter declaration list */ +sp_pdparam_list: + /* Empty */ + | sp_pdparams + ; + +sp_pdparams: + sp_pdparams ',' sp_pdparam + | sp_pdparam + ; + +sp_pdparam: sp_opt_inout ident type sp_opt_locator { Lex->spcont->push(&$2, @@ -1068,6 +1111,20 @@ sp_proc_stmt: lex->sphead->restore_lex(YYTHD); } } + | RETURN_SYM expr + { + LEX *lex= Lex; + + if (lex->sphead->m_type == TYPE_ENUM_PROCEDURE) + { + send_error(YYTHD, ER_SP_BADRETURN); + YYABORT; + } + else + { + /* QQ nothing yet */ + } + } | IF sp_if END IF {} | CASE_SYM WHEN_SYM { @@ -1886,7 +1943,7 @@ alter: lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; } - | ALTER PROCEDURE opt_specific ident + | ALTER PROCEDURE ident /* QQ Characteristics missing for now */ opt_restrict { @@ -1895,18 +1952,10 @@ alter: /* This is essensially an no-op right now, since we haven't put the characteristics in yet. */ lex->sql_command= SQLCOM_ALTER_PROCEDURE; - lex->value_list.empty(); - lex->value_list.push_back( - (Item*)new Item_string($4.str, $4.length, default_charset_info)); + lex->udf.name= $3; } ; -opt_specific: - /* Empty */ - | - SPECIFIC_SYM - ; - alter_list: | alter_list_item | alter_list ',' alter_list_item; @@ -3540,23 +3589,20 @@ drop: lex->drop_if_exists=$3; lex->name=$4.str; } - | DROP UDF_SYM IDENT + | DROP FUNCTION_SYM IDENT opt_restrict { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_FUNCTION; - lex->udf.name = $3; + lex->udf.name= $3; } | DROP PROCEDURE ident opt_restrict { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_PROCEDURE; - lex->value_list.empty(); - lex->value_list.push_back( - (Item*)new Item_string($3.str, $3.length, default_charset_info)); + lex->udf.name= $3; } ; - table_list: table_name | table_list ',' table_name; @@ -4583,7 +4629,7 @@ keyword: | TIMESTAMP {} | TIME_SYM {} | TYPE_SYM {} - | UDF_SYM {} + | FUNCTION_SYM {} | UNCOMMITTED_SYM {} | UNICODE_SYM {} | USE_FRM {} From ca2e77ca7a4cd4cbdb08425044ca71f3d38def64 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 26 Feb 2003 19:22:29 +0100 Subject: [PATCH 34/83] Made stored FUNCTION invokation work almost always. Still buggy and unstable, and various known problems, but good enough for a checkpoint commit. --- mysql-test/r/sp.result | 22 +++++- mysql-test/t/sp.test | 27 ++++++- sql/item_func.cc | 75 +++++++++++++++++++ sql/item_func.h | 66 ++++++++++++++++ sql/sp.cc | 21 +++++- sql/sp.h | 4 + sql/sp_head.cc | 166 +++++++++++++++++++++++++++-------------- sql/sp_head.h | 43 ++++++++++- sql/sp_rcontext.h | 15 +++- sql/sql_lex.cc | 13 ++++ sql/sql_parse.cc | 4 +- sql/sql_yacc.yy | 23 +++++- 12 files changed, 408 insertions(+), 71 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ba2709ebb7e..7beaa9fe673 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -375,11 +375,21 @@ create table test.t2 select * from test.t1; insert into test.t2 values (concat(x, "2"), y+2); end; drop procedure create_select; -create function foo returns real soname "foo.so"; -Can't open shared library 'foo.so' (errno: 22 foo.so: cannot open shared object file: No such file or director) create function e() returns double return 2.7182818284590452354; -drop function e; +select e(); +e() +2.718281828459 +create function inc(i int) returns int +return i+1; +select inc(1), inc(99), inc(-71); +inc(1) inc(99) inc(-71) +2 100 -70 +create function mul(x int, y int) returns int +return x*y; +select mul(1,1), mul(3,5), mul(4711, 666); +mul(1,1) mul(3,5) mul(4711, 666) +1 15 3137526 create function fac(n int unsigned) returns bigint unsigned begin declare f bigint unsigned; @@ -390,5 +400,11 @@ set n = n - 1; end while; return f; end; +select fac(1), fac(2), fac(10); +fac(1) fac(2) fac(10) +1 2 3628800 +drop function e; +drop function inc; +drop function mul; drop function fac; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 2be927c78ff..b509ff8e557 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -435,17 +435,31 @@ drop procedure create_select| # Check that we get the right error, i.e. UDF declaration parses correctly, # but foo.so doesn't exist. ---error 1126 -create function foo returns real soname "foo.so"| +# QQ This generates an error message containing a misleading errno which +# might vary between systems (it usually doesn't have anything to do with +# the actual failing dlopen()). +#--error 1126 +#create function foo returns real soname "foo.so"| # A minimal, constant FUNCTION. create function e() returns double return 2.7182818284590452354| -drop function e| +select e()| +# A minimal function with one argument +create function inc(i int) returns int + return i+1| -# A function with flow control and a RETURN statement +select inc(1), inc(99), inc(-71)| + +# A minimal function with two arguments +create function mul(x int, y int) returns int + return x*y| + +select mul(1,1), mul(3,5), mul(4711, 666)| + +# A function with flow control create function fac(n int unsigned) returns bigint unsigned begin declare f bigint unsigned; @@ -458,6 +472,11 @@ begin return f; end| +select fac(1), fac(2), fac(10)| + +drop function e| +drop function inc| +drop function mul| drop function fac| delimiter ;| diff --git a/sql/item_func.cc b/sql/item_func.cc index 45d666fb47b..945a6e25e4f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -28,6 +28,9 @@ #include #include #include +#include "sp_head.h" +#include "sp_rcontext.h" +#include "sp.h" /* return TRUE if item is a constant */ @@ -2770,3 +2773,75 @@ double Item_func_glength::val() geom.length(&res)); return res; } + + +int +Item_func_sp::execute(Item **itp) +{ + DBUG_ENTER("Item_func_sp::execute"); + THD *thd= current_thd; + + if (!m_sp && !(m_sp= sp_find_function(thd, &m_name))) + DBUG_RETURN(-1); + + DBUG_RETURN(m_sp->execute_function(thd, args, arg_count, itp)); +} + +Item_result +Item_func_sp::result_type() const +{ + DBUG_ENTER("Item_func_sp::result_type"); + DBUG_PRINT("info", ("m_sp = %p", m_sp)); + + if (m_sp) + { + DBUG_RETURN(m_sp->result()); + } + else + { + sp_head *sp= sp_find_function(current_thd, (LEX_STRING *)(&m_name)); + if (sp) + DBUG_RETURN(m_sp->result()); + DBUG_RETURN(STRING_RESULT); + } +} + +void +Item_func_sp::make_field(Send_field *field) +{ + DBUG_ENTER("Item_func_sp::make_field"); + Item *it; + + if (!execute(&it)) + { + it->set_name(name, 0); + init_make_field(field, field_type()); + it->make_field(field); + } + DBUG_VOID_RETURN; +} + +void +Item_func_sp::fix_length_and_dec() +{ + DBUG_ENTER("Item_func_sp::fix_length_and_dec"); + + if (m_sp || (m_sp= sp_find_function(current_thd, &m_name))) + { + switch (m_sp->result()) { + case STRING_RESULT: + maybe_null= 1; + max_length= 0; + break; + case REAL_RESULT: + decimals= NOT_FIXED_DEC; + max_length= float_length(decimals); + break; + case INT_RESULT: + decimals= 0; + max_length= 21; + break; + } + } + DBUG_VOID_RETURN; +} diff --git a/sql/item_func.h b/sql/item_func.h index 68804b83d26..07201093473 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1147,3 +1147,69 @@ enum Item_cast ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT, ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR }; + + +/* + * + * Stored FUNCTIONs + * + */ + +class sp_head; + +class Item_func_sp :public Item_func +{ +private: + LEX_STRING m_name; + sp_head *m_sp; + + int execute(Item **itp); + +public: + + Item_func_sp(LEX_STRING name) + :Item_func(), m_name(name), m_sp(NULL) + {} + + Item_func_sp(LEX_STRING name, List &list) + :Item_func(list), m_name(name), m_sp(NULL) + {} + + virtual ~Item_func_sp() + {} + + const char *func_name() const + { + return m_name.str; + } + + Item_result result_type() const; + + longlong val_int() + { + return (longlong)Item_func_sp::val(); + } + + double val() + { + Item *it; + + if (execute(&it)) + return 0.0; + return it->val(); + } + + String *val_str(String *str) + { + Item *it; + + if (execute(&it)) + return NULL; + return it->val_str(str); + } + + void make_field(Send_field *field); + + void fix_length_and_dec(); + +}; diff --git a/sql/sp.cc b/sql/sp.cc index eb3a9871ab5..f7b8cf235ca 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -84,6 +84,8 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) ret= SP_GET_FIELD_FAILED; goto done; } + close_thread_tables(thd); + table= NULL; tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); if (yyparse(thd) || thd->is_fatal_error || tmplex->sphead == NULL) @@ -92,7 +94,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) *sphp= tmplex->sphead; done: - if (ret == SP_OK && table) + if (ret != SP_OK && table) close_thread_tables(thd); DBUG_RETURN(ret); } @@ -208,7 +210,7 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) sp_head * sp_find_function(THD *thd, LEX_STRING *name) { - DBUG_ENTER("sp_find_function_i"); + DBUG_ENTER("sp_find_function"); sp_head *sp; DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); @@ -243,3 +245,18 @@ sp_drop_function(THD *thd, char *name, uint namelen) DBUG_RETURN(ret); } + +// QQ Temporary until the function call detection in sql_lex has been reworked. +bool +sp_function_exists(THD *thd, LEX_STRING *name) +{ + TABLE *table; + + if (db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, + name->str, name->length, TL_READ, &table) == SP_OK) + { + close_thread_tables(thd); + return TRUE; + } + return FALSE; +} diff --git a/sql/sp.h b/sql/sp.h index 084afb8c8e0..b9ade8fb3c1 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -46,4 +46,8 @@ sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen); int sp_drop_function(THD *thd, char *name, uint namelen); +// QQ Temporary until the function call detection in sql_lex has been reworked. +bool +sp_function_exists(THD *thd, LEX_STRING *name); + #endif /* _SP_H_ */ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8682fa2cd9d..64ecdc5b380 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -24,6 +24,26 @@ #include "sp_pcontext.h" #include "sp_rcontext.h" +Item_result +sp_map_result_type(enum enum_field_types type) +{ + switch (type) + { + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_INT24: + return INT_RESULT; + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + return REAL_RESULT; + default: + return STRING_RESULT; + } +} + /* Evaluate a (presumed) func item. Always returns an item, the parameter ** if nothing else. */ @@ -36,48 +56,28 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) return it; // Shouldn't happen? /* QQ How do we do this? Is there some better way? */ - switch (type) + if (type == MYSQL_TYPE_NULL) + it= new Item_null(); + else { - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - it= new Item_int(it->val_int()); - break; - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - it= new Item_real(it->val()); - break; - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_NEWDATE: - { - char buffer[MAX_FIELD_WIDTH]; - String tmp(buffer, sizeof(buffer), default_charset_info); - String *s= it->val_str(&tmp); - - it= new Item_string(s->c_ptr_quick(), s->length(), default_charset_info); + switch (sp_map_result_type(type)) { + case INT_RESULT: + it= new Item_int(it->val_int()); break; + case REAL_RESULT: + it= new Item_real(it->val()); + break; + default: + { + char buffer[MAX_FIELD_WIDTH]; + String tmp(buffer, sizeof(buffer), default_charset_info); + String *s= it->val_str(&tmp); + + it= new Item_string(s->c_ptr_quick(), s->length(), + default_charset_info); + break; + } } - case MYSQL_TYPE_NULL: - it= new Item_null(); // A NULL is a NULL is a NULL... - break; - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_GEOMETRY: - /* QQ Don't know what to do with the rest. */ - break; } return it; @@ -118,12 +118,69 @@ sp_head::create(THD *thd) DBUG_RETURN(ret); } + int sp_head::execute(THD *thd) { DBUG_ENTER("sp_head::execute"); - DBUG_PRINT("executing", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); int ret= 0; + uint ip= 0; + + do + { + sp_instr *i; + + i = get_instr(ip); // Returns NULL when we're done. + if (i == NULL) + break; + DBUG_PRINT("execute", ("Instruction %u", ip)); + ret= i->execute(thd, &ip); + } while (ret == 0); + DBUG_RETURN(ret); +} + + +int +sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) +{ + DBUG_ENTER("sp_head::execute"); + DBUG_PRINT("executing", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); + sp_pcontext *pctx = m_call_lex->spcont; + uint csize = pctx->max_framesize(); + uint params = pctx->params(); + sp_rcontext *octx = thd->spcont; + sp_rcontext *nctx = NULL; + uint i; + int ret; + + // QQ Should have some error checking here? (no. of args, types, etc...) + nctx= new sp_rcontext(csize); + for (i= 0 ; i < params && i < argcount ; i++) + { + sp_pvar_t *pvar = pctx->find_pvar(i); + + nctx->push_item(eval_func_item(thd, *argp++, pvar->type)); + } + // The rest of the frame are local variables which are all IN. + // QQ See comment in execute_procedure below. + for (; i < csize ; i++) + nctx->push_item(NULL); + thd->spcont= nctx; + + ret= execute(thd); + if (ret == 0) + *resp= nctx->get_result(); + + thd->spcont= octx; + DBUG_RETURN(ret); +} + +int +sp_head::execute_procedure(THD *thd, List *args) +{ + DBUG_ENTER("sp_head::execute"); + DBUG_PRINT("executing", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); + int ret; sp_instr *p; sp_pcontext *pctx = m_call_lex->spcont; uint csize = pctx->max_framesize(); @@ -135,7 +192,7 @@ sp_head::execute(THD *thd) if (csize > 0) { uint i; - List_iterator_fast li(m_call_lex->value_list); + List_iterator_fast li(*args); Item *it; nctx = new sp_rcontext(csize); @@ -174,20 +231,7 @@ sp_head::execute(THD *thd) thd->spcont= nctx; } - { // Execute instructions... - uint ip= 0; - - while (ret == 0) - { - sp_instr *i; - - i = get_instr(ip); // Returns NULL when we're done. - if (i == NULL) - break; - DBUG_PRINT("execute", ("Instruction %u", ip)); - ret= i->execute(thd, &ip); - } - } + ret= execute(thd); // Don't copy back OUT values if we got an error if (ret == 0 && csize > 0) @@ -424,3 +468,15 @@ sp_instr_jump_if_not::execute(THD *thd, uint *nextp) *nextp = m_ip+1; DBUG_RETURN(0); } + +// +// sp_instr_return +// +int +sp_instr_return::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_return::execute"); + thd->spcont->set_result(eval_func_item(thd, m_value, m_type)); + *nextp= UINT_MAX; + DBUG_RETURN(0); +} diff --git a/sql/sp_head.h b/sql/sp_head.h index b0f57757f98..fa2a76753e7 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -29,6 +29,9 @@ #define TYPE_ENUM_FUNCTION 1 #define TYPE_ENUM_PROCEDURE 2 +Item_result +sp_map_result_type(enum enum_field_types type); + struct sp_label; class sp_instr; @@ -62,7 +65,10 @@ public: create(THD *thd); int - execute(THD *thd); + execute_function(THD *thd, Item **args, uint argcount, Item **resp); + + int + execute_procedure(THD *thd, List *args); inline void add_instr(sp_instr *i) @@ -103,6 +109,11 @@ public: return n->c_ptr(); } + inline Item_result result() + { + return sp_map_result_type(m_returns); + } + private: Item_string *m_name; @@ -122,10 +133,14 @@ private: { sp_instr *in= NULL; - get_dynamic(&m_instr, (gptr)&in, i); + if (i < m_instr.elements) + get_dynamic(&m_instr, (gptr)&in, i); return in; } + int + execute(THD *thd); + }; // class sp_head : public Sql_alloc @@ -319,4 +334,28 @@ private: }; // class sp_instr_jump_if_not : public sp_instr_jump + +class sp_instr_return : public sp_instr +{ + sp_instr_return(const sp_instr_return &); /* Prevent use of these */ + void operator=(sp_instr_return &); + +public: + + sp_instr_return(uint ip, Item *val, enum enum_field_types type) + : sp_instr(ip), m_value(val), m_type(type) + {} + + virtual ~sp_instr_return() + {} + + virtual int execute(THD *thd, uint *nextp); + +protected: + + Item *m_value; + enum enum_field_types m_type; + +}; // class sp_instr_return : public sp_instr + #endif /* _SP_HEAD_H_ */ diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 5ffbb0266e6..78485fdd090 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -26,7 +26,7 @@ class sp_rcontext : public Sql_alloc public: sp_rcontext(uint size) - : m_count(0), m_size(size) + : m_count(0), m_size(size), m_result(NULL) { m_frame = (Item **)sql_alloc(size * sizeof(Item*)); m_outs = (int *)sql_alloc(size * sizeof(int)); @@ -70,12 +70,25 @@ class sp_rcontext : public Sql_alloc return m_outs[idx]; } + inline void + set_result(Item *it) + { + m_result= it; + } + + inline Item * + get_result() + { + return m_result; + } + private: uint m_count; uint m_size; Item **m_frame; int *m_outs; + Item *m_result; // For FUNCTIONs }; // class sp_rcontext : public Sql_alloc diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5bd5e69cdb8..a900d87949e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -21,6 +21,8 @@ #include "item_create.h" #include #include +#include "sp.h" +#include "sp_head.h" LEX_STRING tmp_table_alias= {(char*) "tmp-table",8}; @@ -197,6 +199,17 @@ static int find_keyword(LEX *lex, uint len, bool function) lex->yylval->symbol.length=len; return symbol->tok; } + + LEX_STRING ls; + ls.str = (char *)tok; ls.length= len; + if (function && sp_function_exists(current_thd, &ls)) // QQ temp fix + { + lex->safe_to_cache_query= 0; + lex->yylval->lex_str.str= lex->thd->strmake((char*)lex->tok_start, len); + lex->yylval->lex_str.length= len; + return SP_FUNC; + } + #ifdef HAVE_DLOPEN udf_func *udf; if (function && using_udf_functions && (udf=find_udf((char*) tok, len))) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a4ff6a91b33..67a3865057f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2959,6 +2959,7 @@ mysql_execute_command(THD *thd) { uint namelen; char *name= lex->sphead->name(&namelen); +#ifdef HAVE_DLOPEN udf_func *udf = find_udf(name, namelen); if (udf) @@ -2966,6 +2967,7 @@ mysql_execute_command(THD *thd) net_printf(thd, ER_UDF_EXISTS, name); goto error; } +#endif res= lex->sphead->create(thd); switch (res) { @@ -3000,7 +3002,7 @@ mysql_execute_command(THD *thd) thd->net.no_send_ok= TRUE; #endif - res= sp->execute(thd); + res= sp->execute_procedure(thd, &lex->value_list); #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bfb9d06c16c..fc91ee9a6e4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -506,6 +506,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ROUND %token SECOND_SYM %token SHARE_SYM +%token SP_FUNC %token SUBSTRING %token SUBSTRING_INDEX %token TRIM @@ -575,7 +576,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text - UNDERSCORE_CHARSET + UNDERSCORE_CHARSET SP_FUNC ident_or_spfunc %type opt_table_alias @@ -903,7 +904,7 @@ create: lex->name=$4.str; lex->create_info.options=$3; } - | CREATE udf_func_type FUNCTION_SYM IDENT + | CREATE udf_func_type FUNCTION_SYM ident_or_spfunc { LEX *lex=Lex; lex->udf.name = $4; @@ -929,6 +930,11 @@ create: } ; +ident_or_spfunc: + IDENT { $$= $1; } + | SP_FUNC { $$= $1; } + ; + create_function_tail: RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING { @@ -1122,7 +1128,11 @@ sp_proc_stmt: } else { - /* QQ nothing yet */ + sp_instr_return *i= + new sp_instr_return(lex->sphead->instructions(), + $2, lex->sphead->m_returns); + + lex->sphead->add_instr(i); } } | IF sp_if END IF {} @@ -2863,6 +2873,13 @@ simple_expr: { $$= new Item_func_round($3,$5,1); } | TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); } + | SP_FUNC '(' udf_expr_list ')' + { + if ($3) + $$= new Item_func_sp($1, *$3); + else + $$= new Item_func_sp($1); + } | UDA_CHAR_SUM '(' udf_expr_list ')' { if ($3 != NULL) From 16cff7e75d2c9895772554894c4e4ff5722664ae Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 27 Feb 2003 19:08:52 +0100 Subject: [PATCH 35/83] A small step forward. Fixed a few bugs and made string type functions work, but still strange interferences between multiple function invocations... --- mysql-test/r/sp.result | 19 +++++++++++------ mysql-test/t/sp.test | 12 +++++++++-- sql/item_func.cc | 48 +++++++++++++++++++++--------------------- sql/item_func.h | 6 +++--- sql/sp_head.cc | 6 +++--- 5 files changed, 53 insertions(+), 38 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 7beaa9fe673..ab445e44a5a 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -377,9 +377,10 @@ end; drop procedure create_select; create function e() returns double return 2.7182818284590452354; -select e(); -e() -2.718281828459 +set @e = e(); +select e(), @e; +e() @e +2.718281828459 2.718281828459 create function inc(i int) returns int return i+1; select inc(1), inc(99), inc(-71); @@ -390,6 +391,11 @@ return x*y; select mul(1,1), mul(3,5), mul(4711, 666); mul(1,1) mul(3,5) mul(4711, 666) 1 15 3137526 +create function append(s1 char(8), s2 char(8)) returns char(16) +return concat(s1, s2); +select append("foo", "bar"); +append("foo", "bar") +foobar create function fac(n int unsigned) returns bigint unsigned begin declare f bigint unsigned; @@ -400,11 +406,12 @@ set n = n - 1; end while; return f; end; -select fac(1), fac(2), fac(10); -fac(1) fac(2) fac(10) -1 2 3628800 +select fac(1), fac(2), fac(5), fac(10); +fac(1) fac(2) fac(5) fac(10) +1 2 120 3628800 drop function e; drop function inc; drop function mul; +drop function append; drop function fac; drop table t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index b509ff8e557..17b21f612d6 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -445,7 +445,8 @@ drop procedure create_select| create function e() returns double return 2.7182818284590452354| -select e()| +set @e = e()| +select e(), @e| # A minimal function with one argument create function inc(i int) returns int @@ -459,6 +460,12 @@ create function mul(x int, y int) returns int select mul(1,1), mul(3,5), mul(4711, 666)| +# A minimal string function +create function append(s1 char(8), s2 char(8)) returns char(16) + return concat(s1, s2)| + +select append("foo", "bar")| + # A function with flow control create function fac(n int unsigned) returns bigint unsigned begin @@ -472,11 +479,12 @@ begin return f; end| -select fac(1), fac(2), fac(10)| +select fac(1), fac(2), fac(5), fac(10)| drop function e| drop function inc| drop function mul| +drop function append| drop function fac| delimiter ;| diff --git a/sql/item_func.cc b/sql/item_func.cc index 945a6e25e4f..7c3faae8e6e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2781,44 +2781,42 @@ Item_func_sp::execute(Item **itp) DBUG_ENTER("Item_func_sp::execute"); THD *thd= current_thd; - if (!m_sp && !(m_sp= sp_find_function(thd, &m_name))) + if (! m_sp) + m_sp= sp_find_function(thd, &m_name); + if (! m_sp) DBUG_RETURN(-1); DBUG_RETURN(m_sp->execute_function(thd, args, arg_count, itp)); } +enum enum_field_types +Item_func_sp::field_type() const +{ + DBUG_ENTER("Item_func_sp::field_type"); + + if (! m_sp) + m_sp= sp_find_function(current_thd, const_cast(&m_name)); + if (m_sp) + { + DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); + DBUG_RETURN(m_sp->m_returns); + } + DBUG_RETURN(MYSQL_TYPE_STRING); +} + Item_result Item_func_sp::result_type() const { DBUG_ENTER("Item_func_sp::result_type"); DBUG_PRINT("info", ("m_sp = %p", m_sp)); + if (! m_sp) + m_sp= sp_find_function(current_thd, const_cast(&m_name)); if (m_sp) { DBUG_RETURN(m_sp->result()); } - else - { - sp_head *sp= sp_find_function(current_thd, (LEX_STRING *)(&m_name)); - if (sp) - DBUG_RETURN(m_sp->result()); - DBUG_RETURN(STRING_RESULT); - } -} - -void -Item_func_sp::make_field(Send_field *field) -{ - DBUG_ENTER("Item_func_sp::make_field"); - Item *it; - - if (!execute(&it)) - { - it->set_name(name, 0); - init_make_field(field, field_type()); - it->make_field(field); - } - DBUG_VOID_RETURN; + DBUG_RETURN(STRING_RESULT); } void @@ -2826,7 +2824,9 @@ Item_func_sp::fix_length_and_dec() { DBUG_ENTER("Item_func_sp::fix_length_and_dec"); - if (m_sp || (m_sp= sp_find_function(current_thd, &m_name))) + if (! m_sp) + m_sp= sp_find_function(current_thd, &m_name); + if (m_sp) { switch (m_sp->result()) { case STRING_RESULT: diff --git a/sql/item_func.h b/sql/item_func.h index 07201093473..00794b048a2 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1161,7 +1161,7 @@ class Item_func_sp :public Item_func { private: LEX_STRING m_name; - sp_head *m_sp; + mutable sp_head *m_sp; int execute(Item **itp); @@ -1183,6 +1183,8 @@ public: return m_name.str; } + enum enum_field_types field_type() const; + Item_result result_type() const; longlong val_int() @@ -1208,8 +1210,6 @@ public: return it->val_str(str); } - void make_field(Send_field *field); - void fix_length_and_dec(); }; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 64ecdc5b380..b461f2035ad 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -70,11 +70,11 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) default: { char buffer[MAX_FIELD_WIDTH]; - String tmp(buffer, sizeof(buffer), default_charset_info); + String tmp(buffer, sizeof(buffer), it->charset()); String *s= it->val_str(&tmp); - it= new Item_string(s->c_ptr_quick(), s->length(), - default_charset_info); + it= new Item_string(sql_strmake(s->c_ptr_quick(), s->length()), + s->length(), it->charset()); break; } } From b6ab762dc15a3ac4aa2528f9c9b2ba3725afe710 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 28 Feb 2003 15:07:14 +0100 Subject: [PATCH 36/83] Closing tables during SP execution the proper way. --- mysql-test/r/show_check.result | 1 + mysql-test/r/status.result | 2 +- sql/sp.cc | 20 +++++++++++--------- sql/sp_head.cc | 5 +++++ sql/sql_class.cc | 27 --------------------------- 5 files changed, 18 insertions(+), 37 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index de652b05154..c5e7ca154df 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -127,6 +127,7 @@ insert into t1 values (1); show open tables; Database Table In_use Name_locked test t1 0 0 +mysql proc 0 0 drop table t1; create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" TYPE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed; show create table t1; diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index 3ef6cec32b3..f93147d00c5 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -14,6 +14,6 @@ update t1 set n = 3; unlock tables; show status like 'Table_lock%'; Variable_name Value -Table_locks_immediate 3 +Table_locks_immediate 4 Table_locks_waited 1 drop table t1; diff --git a/sql/sp.cc b/sql/sp.cc index f7b8cf235ca..52d59eb1a3e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -50,13 +50,16 @@ db_find_routine_aux(THD *thd, int type, char *name, uint namelen, tables.db= (char*)"mysql"; tables.real_name= tables.alias= (char*)"proc"; if (! (table= open_ltable(thd, &tables, ltype))) + { + *tablep= NULL; DBUG_RETURN(SP_OPEN_TABLE_FAILED); + } if (table->file->index_read_idx(table->record[0], 0, key, keylen, HA_READ_KEY_EXACT)) { - close_thread_tables(thd); + *tablep= NULL; DBUG_RETURN(SP_KEY_NOT_FOUND); } *tablep= table; @@ -94,7 +97,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) *sphp= tmplex->sphead; done: - if (ret != SP_OK && table) + if (table) close_thread_tables(thd); DBUG_RETURN(ret); } @@ -129,8 +132,7 @@ db_create_routine(THD *thd, int type, ret= SP_OK; } - if (ret == SP_OK && table) - close_thread_tables(thd); + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -149,8 +151,7 @@ db_drop_routine(THD *thd, int type, char *name, uint namelen) ret= SP_DELETE_ROW_FAILED; } - if (ret == SP_OK && table) - close_thread_tables(thd); + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -251,12 +252,13 @@ bool sp_function_exists(THD *thd, LEX_STRING *name) { TABLE *table; + bool ret= FALSE; if (db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, name->str, name->length, TL_READ, &table) == SP_OK) { - close_thread_tables(thd); - return TRUE; + ret= TRUE; } - return FALSE; + close_thread_tables(thd); + return ret; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index b461f2035ad..9de3ee471f2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -415,6 +415,11 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) thd->lex.thd = thd; res= mysql_execute_command(thd); + if (thd->lock || thd->open_tables || thd->derived_tables) + { + thd->proc_info="closing tables"; + close_thread_tables(thd); /* Free tables */ + } memcpy(&thd->lex, &olex, sizeof(LEX)); // Restore the other lex diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ac82996600f..5ac904393f5 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -801,15 +801,6 @@ void select_export::send_error(uint errcode, const char *err) bool select_export::send_eof() { - /* This mimics select_send::send_eof(), which unlocks this way. - * It appears to be necessary, since tables aren't unlock after - * selects otherwise. - */ - if (thd->lock) - { - mysql_unlock_tables(thd, thd->lock); - thd->lock=0; - } int error=test(end_io_cache(&cache)); if (my_close(file,MYF(MY_WME))) error=1; @@ -920,15 +911,6 @@ void select_dump::send_error(uint errcode,const char *err) bool select_dump::send_eof() { - /* This mimics select_send::send_eof(), which unlocks this way. - * It appears to be necessary, since tables aren't unlock after - * selects otherwise. - */ - if (thd->lock) - { - mysql_unlock_tables(thd, thd->lock); - thd->lock=0; - } int error=test(end_io_cache(&cache)); if (my_close(file,MYF(MY_WME))) error=1; @@ -1061,15 +1043,6 @@ bool select_dumpvar::send_data(List &items) bool select_dumpvar::send_eof() { - /* This mimics select_send::send_eof(), which unlocks this way. - * It appears to be necessary, since tables aren't unlock after - * selects otherwise. - */ - if (thd->lock) - { - mysql_unlock_tables(thd, thd->lock); - thd->lock=0; - } if (row_count) { ::send_ok(thd,row_count); From 8049daf202178f937b83124661faaad6003e366d Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 2 Mar 2003 19:17:41 +0100 Subject: [PATCH 37/83] Made FUNCTIONs work in insert and select queries, as well as nested function invocations. Had to add a cahing mechanism which is in parts an ugly kludge, but it will be reworked once the real SP caching is implemented. --- mysql-test/r/sp.result | 30 ++++++++ mysql-test/t/sp.test | 27 +++++++ sql/sp.cc | 171 +++++++++++++++++++++++++++++++++++------ sql/sp.h | 12 +++ sql/sp_head.cc | 34 ++++---- sql/sp_head.h | 7 +- sql/sql_class.h | 1 + sql/sql_lex.cc | 1 + sql/sql_lex.h | 1 + sql/sql_parse.cc | 12 +++ sql/sql_yacc.yy | 4 +- 11 files changed, 259 insertions(+), 41 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ab445e44a5a..13983fbd69e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1,9 +1,15 @@ use test; drop table if exists t1; +drop table if exists t2; create table t1 ( id char(16) not null, data int not null ); +create table t2 ( +s char(16) not null, +i int not null, +d double not null +); create procedure foo42() insert into test.t1 values ("foo", 42); call foo42(); @@ -409,9 +415,33 @@ end; select fac(1), fac(2), fac(5), fac(10); fac(1) fac(2) fac(5) fac(10) 1 2 120 3628800 +create function fun(d double, i int, u int unsigned) returns double +return mul(inc(i), fac(u)) / e(); +select fun(2.3, 3, 5); +fun(2.3, 3, 5) +176.58213176229 +insert into t2 values (append("xxx", "yyy"), mul(4,3), e()); +insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6)); +select * from t2 where s = append("a", "b"); +s i d +ab 24 1324.36598821719 +select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2); +s i d +xxxyyy 12 2.71828182845905 +ab 24 1324.36598821719 +select * from t2 where d = e(); +s i d +xxxyyy 12 2.71828182845905 +select * from t2; +s i d +xxxyyy 12 2.71828182845905 +ab 24 1324.36598821719 +delete from t2; drop function e; drop function inc; drop function mul; drop function append; drop function fac; +drop function fun; drop table t1; +drop table t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 17b21f612d6..a5efee28446 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -7,12 +7,18 @@ use test; --disable_warnings drop table if exists t1; +drop table if exists t2; --enable_warnings create table t1 ( id char(16) not null, data int not null ); +create table t2 ( + s char(16) not null, + i int not null, + d double not null +); # Single statement, no params. @@ -481,11 +487,32 @@ end| select fac(1), fac(2), fac(5), fac(10)| +# Nested calls +create function fun(d double, i int, u int unsigned) returns double + return mul(inc(i), fac(u)) / e()| + +select fun(2.3, 3, 5)| + + +# Various function calls in differen statements + +insert into t2 values (append("xxx", "yyy"), mul(4,3), e())| +insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6))| + +# These don't work yet. +select * from t2 where s = append("a", "b")| +select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2)| +select * from t2 where d = e()| +select * from t2| +delete from t2| + drop function e| drop function inc| drop function mul| drop function append| drop function fac| +drop function fun| delimiter ;| drop table t1; +drop table t2; diff --git a/sql/sp.cc b/sql/sp.cc index 52d59eb1a3e..2bb714ab33a 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -19,20 +19,23 @@ #include "sp.h" #include "sp_head.h" + static sp_head * + sp_find_cached_function(THD *thd, char *name, uint namelen); + /* * * DB storage of Stored PROCEDUREs and FUNCTIONs * */ +// *openeed=true means we opened ourselves static int db_find_routine_aux(THD *thd, int type, char *name, uint namelen, - enum thr_lock_type ltype, TABLE **tablep) + enum thr_lock_type ltype, TABLE **tablep, bool *opened) { DBUG_ENTER("db_find_routine_aux"); DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); TABLE *table; - TABLE_LIST tables; byte key[65]; // We know name is 64 and the enum is 1 byte uint keylen; int ret; @@ -46,13 +49,25 @@ db_find_routine_aux(THD *thd, int type, char *name, uint namelen, key[sizeof(key)-1]= type; keylen= sizeof(key); - memset(&tables, 0, sizeof(tables)); - tables.db= (char*)"mysql"; - tables.real_name= tables.alias= (char*)"proc"; - if (! (table= open_ltable(thd, &tables, ltype))) + for (table= thd->open_tables ; table ; table= table->next) + if (strcmp(table->table_cache_key, "mysql") == 0 && + strcmp(table->real_name, "proc") == 0) + break; + if (table) + *opened= FALSE; + else { - *tablep= NULL; - DBUG_RETURN(SP_OPEN_TABLE_FAILED); + TABLE_LIST tables; + + memset(&tables, 0, sizeof(tables)); + tables.db= (char*)"mysql"; + tables.real_name= tables.alias= (char*)"proc"; + if (! (table= open_ltable(thd, &tables, ltype))) + { + *tablep= NULL; + DBUG_RETURN(SP_OPEN_TABLE_FAILED); + } + *opened= TRUE; } if (table->file->index_read_idx(table->record[0], 0, @@ -77,9 +92,10 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) TABLE *table; const char *defstr; int ret; + bool opened; // QQ Set up our own mem_root here??? - ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table); + ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened); if (ret != SP_OK) goto done; if ((defstr= get_field(&thd->mem_root, table->field[2])) == NULL) @@ -87,8 +103,11 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) ret= SP_GET_FIELD_FAILED; goto done; } - close_thread_tables(thd); - table= NULL; + if (opened) + { + close_thread_tables(thd); + table= NULL; + } tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); if (yyparse(thd) || thd->is_fatal_error || tmplex->sphead == NULL) @@ -97,7 +116,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) *sphp= tmplex->sphead; done: - if (table) + if (table && opened) close_thread_tables(thd); DBUG_RETURN(ret); } @@ -122,9 +141,9 @@ db_create_routine(THD *thd, int type, { restore_record(table, 2); // Get default values for fields - table->field[0]->store(name, namelen, default_charset_info); + table->field[0]->store(name, namelen, system_charset_info); table->field[1]->store((longlong)type); - table->field[2]->store(def, deflen, default_charset_info); + table->field[2]->store(def, deflen, system_charset_info); if (table->file->write_row(table->record[0])) ret= SP_WRITE_ROW_FAILED; @@ -143,15 +162,17 @@ db_drop_routine(THD *thd, int type, char *name, uint namelen) DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); TABLE *table; int ret; + bool opened; - ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table); + ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table, &opened); if (ret == SP_OK) { if (table->file->delete_row(table->record[0])) ret= SP_DELETE_ROW_FAILED; } - close_thread_tables(thd); + if (opened) + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -216,10 +237,13 @@ sp_find_function(THD *thd, LEX_STRING *name) DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); - if (db_find_routine(thd, TYPE_ENUM_FUNCTION, - name->str, name->length, &sp) != SP_OK) - sp= NULL; - + sp= sp_find_cached_function(thd, name->str, name->length); + if (! sp) + { + if (db_find_routine(thd, TYPE_ENUM_FUNCTION, + name->str, name->length, &sp) != SP_OK) + sp= NULL; + } DBUG_RETURN(sp); } @@ -253,12 +277,115 @@ sp_function_exists(THD *thd, LEX_STRING *name) { TABLE *table; bool ret= FALSE; + bool opened; if (db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, - name->str, name->length, TL_READ, &table) == SP_OK) + name->str, name->length, TL_READ, + &table, &opened) == SP_OK) { ret= TRUE; } - close_thread_tables(thd); + if (opened) + close_thread_tables(thd); return ret; } + + +/* + * + * The temporary FUNCTION cache. (QQ This will be rehacked later, but + * it's needed now to make functions work at all.) + * + */ + +void +sp_add_fun_to_lex(LEX *lex, LEX_STRING fun) +{ + List_iterator_fast li(lex->spfuns); + char *fn; + + while ((fn= li++)) + { + if (strncasecmp(fn, fun.str, fun.length) == 0) + break; + } + if (! fn) + { + char *s= sql_strmake(fun.str, fun.length); + lex->spfuns.push_back(s); + } +} + +void +sp_merge_funs(LEX *dst, LEX *src) +{ + List_iterator_fast li(src->spfuns); + char *fn; + + while ((fn= li++)) + { + LEX_STRING lx; + + lx.str= fn; lx.length= strlen(fn); + sp_add_fun_to_lex(dst, lx); + } +} + +/* QQ Not terribly efficient right now, but it'll do for starters. + We should actually open the mysql.proc table just once. */ +int +sp_cache_functions(THD *thd, LEX *lex) +{ + List_iterator li(lex->spfuns); + char *fn; + enum_sql_command cmd= lex->sql_command; + int ret= 0; + + while ((fn= li++)) + { + List_iterator_fast lisp(thd->spfuns); + sp_head *sp; + + while ((sp= lisp++)) + { + if (strcasecmp(fn, sp->name()) == 0) + break; + } + if (sp) + continue; + if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, strlen(fn), &sp) == SP_OK) + { + ret= sp_cache_functions(thd, &thd->lex); + if (ret) + break; + thd->spfuns.push_back(sp); + } + else + { + send_error(thd, ER_SP_DOES_NOT_EXIST); + ret= 1; + } + } + lex->sql_command= cmd; + return ret; +} + +void +sp_clear_function_cache(THD *thd) +{ + thd->spfuns.empty(); +} + +static sp_head * +sp_find_cached_function(THD *thd, char *name, uint namelen) +{ + List_iterator_fast li(thd->spfuns); + sp_head *sp; + + while ((sp= li++)) + { + if (strncasecmp(name, sp->name(), namelen) == 0) + break; + } + return sp; +} diff --git a/sql/sp.h b/sql/sp.h index b9ade8fb3c1..21fcb4c5360 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -50,4 +50,16 @@ sp_drop_function(THD *thd, char *name, uint namelen); bool sp_function_exists(THD *thd, LEX_STRING *name); + +// QQ More temporary stuff until the real cache is implemented. This is +// needed since we have to read the functions before we do anything else. +void +sp_add_fun_to_lex(LEX *lex, LEX_STRING fun); +void +sp_merge_funs(LEX *dst, LEX *src); +int +sp_cache_functions(THD *thd, LEX *lex); +void +sp_clear_function_cache(THD *thd); + #endif /* _SP_H_ */ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 9de3ee471f2..55d21c37609 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -88,10 +88,10 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) { const char *dstr = (const char*)lex->buf; - m_call_lex= lex; - m_name= new Item_string(name->str, name->length, default_charset_info); + m_name= new Item_string(name->str, name->length, system_charset_info); m_defstr= new Item_string(dstr, lex->end_of_query - lex->buf, - default_charset_info); + system_charset_info); + m_pcont= lex->spcont; my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_backpatch.empty(); } @@ -143,11 +143,10 @@ sp_head::execute(THD *thd) int sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) { - DBUG_ENTER("sp_head::execute"); - DBUG_PRINT("executing", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); - sp_pcontext *pctx = m_call_lex->spcont; - uint csize = pctx->max_framesize(); - uint params = pctx->params(); + DBUG_ENTER("sp_head::execute_function"); + DBUG_PRINT("info", ("function %s", ((String *)m_name->const_string())->c_ptr())); + uint csize = m_pcont->max_framesize(); + uint params = m_pcont->params(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; uint i; @@ -157,7 +156,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) nctx= new sp_rcontext(csize); for (i= 0 ; i < params && i < argcount ; i++) { - sp_pvar_t *pvar = pctx->find_pvar(i); + sp_pvar_t *pvar = m_pcont->find_pvar(i); nctx->push_item(eval_func_item(thd, *argp++, pvar->type)); } @@ -178,13 +177,12 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) int sp_head::execute_procedure(THD *thd, List *args) { - DBUG_ENTER("sp_head::execute"); - DBUG_PRINT("executing", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); + DBUG_ENTER("sp_head::execute_procedure"); + DBUG_PRINT("info", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); int ret; sp_instr *p; - sp_pcontext *pctx = m_call_lex->spcont; - uint csize = pctx->max_framesize(); - uint params = pctx->params(); + uint csize = m_pcont->max_framesize(); + uint params = m_pcont->params(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx @@ -204,7 +202,7 @@ sp_head::execute_procedure(THD *thd, List *args) // QQ: No error checking whatsoever right now. Should do type checking? for (i = 0 ; (it= li++) && i < params ; i++) { - sp_pvar_t *pvar = pctx->find_pvar(i); + sp_pvar_t *pvar = m_pcont->find_pvar(i); if (! pvar) nctx->set_oindex(i, -1); // Shouldn't happen @@ -236,7 +234,7 @@ sp_head::execute_procedure(THD *thd, List *args) // Don't copy back OUT values if we got an error if (ret == 0 && csize > 0) { - List_iterator_fast li(m_call_lex->value_list); + List_iterator_fast li(*args); Item *it; // Copy back all OUT or INOUT values to the previous frame, or @@ -324,6 +322,9 @@ sp_head::restore_lex(THD *thd) m_lex.next_state= thd->lex.next_state; // Collect some data from the sub statement lex. + sp_merge_funs(&m_lex, &thd->lex); +#if 0 + // We're not using this at the moment. if (thd->lex.sql_command == SQLCOM_CALL) { // It would be slightly faster to keep the list sorted, but we need @@ -362,6 +363,7 @@ sp_head::restore_lex(THD *thd) m_tables.push_back(&tables->real_name); } } +#endif memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex } diff --git a/sql/sp_head.h b/sql/sp_head.h index fa2a76753e7..ee64a1bd0cf 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -46,8 +46,11 @@ public: int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE enum enum_field_types m_returns; // For FUNCTIONs only my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise +#if 0 + // We're not using this at the moment. List m_calls; // Called procedures. List m_tables; // Used tables. +#endif static void *operator new(size_t size) { @@ -59,7 +62,7 @@ public: /* Empty */ } - sp_head(LEX_STRING *name, LEX* lex); + sp_head(LEX_STRING *name, LEX *lex); int create(THD *thd); @@ -118,7 +121,7 @@ private: Item_string *m_name; Item_string *m_defstr; - LEX *m_call_lex; // The CALL's own lex + sp_pcontext *m_pcont; // Parse context LEX m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" typedef struct diff --git a/sql/sql_class.h b/sql/sql_class.h index f316272ff0e..7740a54d007 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -553,6 +553,7 @@ public: bool prepare_command; bool tmp_table_used; sp_rcontext *spcont; // SP runtime context + List spfuns; // SP FUNCTIONs /* If we do a purge of binary logs, log index info of the threads diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a900d87949e..9f32b45c1ad 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -176,6 +176,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->sql_command=SQLCOM_END; lex->sphead= NULL; lex->spcont= NULL; + lex->spfuns.empty(); return lex; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 9a4b4b8bd08..337b69026bf 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -485,6 +485,7 @@ typedef struct st_lex char *help_arg; sp_head *sphead; sp_pcontext *spcont; + List spfuns; /* Called functions */ inline void uncacheable() { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 67a3865057f..94278371fd0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1583,6 +1583,18 @@ mysql_execute_command(THD *thd) SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); + /* + Clear the SP function cache before each statement (QQ this is a temporary + solution; caching will be rehacked later), and the new ones. + */ + sp_clear_function_cache(thd); + if (lex->sql_command != SQLCOM_CREATE_PROCEDURE && + lex->sql_command != SQLCOM_CREATE_FUNCTION) + { + if (sp_cache_functions(thd, lex)) + DBUG_RETURN(-1); + } + /* Reset warning count for each query that uses tables A better approach would be to reset this for any commands diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fc91ee9a6e4..7c2b97904fb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -37,6 +37,7 @@ #include "item_create.h" #include "sp_head.h" #include "sp_pcontext.h" +#include "sp.h" #include #include @@ -965,7 +966,7 @@ create_function_tail: ; call: - CALL_SYM ident + CALL_SYM ident_or_spfunc { LEX *lex = Lex; @@ -2875,6 +2876,7 @@ simple_expr: { $$= new Item_int((char*) "TRUE",1,1); } | SP_FUNC '(' udf_expr_list ')' { + sp_add_fun_to_lex(Lex, $1); if ($3) $$= new Item_func_sp($1, *$3); else From c4b76c2694611912a8bde6c0fc1afbc2732234a4 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Mon, 3 Mar 2003 15:03:19 +0100 Subject: [PATCH 38/83] New FUNCTION documentation, and a minor test case modification. --- Docs/sp-imp-spec.txt | 64 +++++++++++++++++++++++++-- Docs/sp-implemented.txt | 25 ++++++++--- mysql-test/r/sp.result | 96 ++++++++++++++++++----------------------- mysql-test/t/sp.test | 71 +++++++++++++----------------- 4 files changed, 151 insertions(+), 105 deletions(-) diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index 198623a0f5b..c3818f141dc 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -172,8 +172,9 @@ calling a PROCEDURE. with the addition that a FUNCTION has a return type and a RETURN statement, but no OUT or INOUT parameters. - [QQ - More details here; sp_head needs a result slot and a type flag - indicating if it's a function or procedure] + The main difference during parsing is that we store the result type + in the sp_head. However, there are big differences when it comes to + invoking a FUNCTION. (See below.) - Storing, caching, dropping... @@ -273,7 +274,64 @@ calling a PROCEDURE. So, stored functions must be handled in a simpilar way, and as a consequence, UDFs and functions must not have the same name. - [QQ - Details of how function calls works here] + - Detecting and parsing a FUNCTION invokation + + The existance of UDFs are checked during the lexical analysis (in + sql_lex.cc:find_keyword()). This has the drawback that they must + exist before they are refered to, which was ok before SPs existed, + but then it becomes a problem. The first implementation of SP FUNCTIONs + will work the same way, but this should be fixed a.s.a.p. (This will + required some reworking of the way UDFs are handled, which is why it's + not done from the start.) + For the time being, a FUNCTION is detected the same way, and returns + the token SP_FUNC. During the parsing we only check for the *existance* + of the function, we don't parse it, since wa can't call the parser + recursively. + + When encountering a SP_FUNC with parameters in the expression parser, + an instance of the new Item_func_sp class is created. Unlike UDFs, we + don't have different classes for different return types, since we at + this point don't know the type. + + - Collecting FUNCTIONs to invoke + + A FUNCTION differs from a PROCEDURE in one important aspect: Whereas a + PROCEDURE is CALLed as statement by itself, a FUNCTION is invoked + "on-the-fly" during the execution of *another* statement. + This makes things a lot more complicated compared to CALL: + - We can't read and parse the FUNCTION from the mysql.proc table at the + point of invokation; the server requires that all tables used are + opened and locked at the beginning of the query execution. + One "obvious" solution would be to simply push "mysql.proc" to the list + of tables used by the query, but this implies a "join" with this table + if the query is a select, so it doesn't work (and we can't exclude this + table easily; since a priviledged used might in fact want to search + the proc table). + Another solution would of course be to allow the opening and closing + of the mysql.proc table during a query execution, but this it not + possible at the present. + + So, the solution is to collect the names of the refered FUNCTIONs during + parsing in the lex. + Then, before doing anything else in mysql_execute_command(), read all + functions from the database an keep them in the THD, where the function + sp_find_function() can find them during the execution. + Note: Even when a global in-memory cache is implemented, we must still + make sure that the functions are indeed read and cached at this point. + The code that read and cache functions from the database must also be + invoked recursively for each read FUNCTION to make sure we have *all* the + functions we need. + + In the absence of the real in-memory cache for SPs, a temporary solution + has been implemented with a per-THD cache for just FUNCTIONs. This is + handled by the functions + + void sp_add_fun_to_lex(LEX *lex, LEX_STRING fun); + void sp_merge_funs(LEX *dst, LEX *src); + int sp_cache_functions(THD *thd, LEX *lex); + void sp_clear_function_cache(THD *thd); + + in sp.cc. - Parsing DROP PROCEDURE/FUNCTION diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index b3b12b7edb8..5173606e95c 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -3,7 +3,6 @@ Stored Procedures implemented 2003-02-02: Summary of Not Yet Implemented: - - FUNCTIONs - Routine characteristics - External languages - Access control @@ -26,14 +25,14 @@ Summary of what's implemented: List of what's implemented: - - CREATE PROCEDURE name ( args ) body + - CREATE PROCEDURE|FUNCTION name ( args ) body No routine characteristics yet. - - ALTER PROCEDURE name ... + - ALTER PROCEDURE|FUNCTION name ... Is parsed, but a no-op (as there are no characteristics implemented yet). CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). - - DROP PROCEDURE name + - DROP PROCEDURE|FUNCTION name CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). - CALL name (args) @@ -45,7 +44,7 @@ List of what's implemented: will either generate an error message, or it might even work to call all procedures from the top-level. - - Procedure body: + - Function/Procedure body: - BEGIN/END Is parsed, but not the real thing with (optional) transaction control, it only serves as block syntax for multiple statements (and @@ -82,9 +81,23 @@ Closed questions: Answer: Same tables, with an additional key-field for the type. -Open questions: +Open questions/issues: - SQL-99 variables and parameters are typed. For the present we don't do any type checking, since this is the way MySQL works. I still don't know if we should keep it this way, or implement type checking. Possibly we should have optional, uset-settable, type checking. + + - FUNCTIONs do not work correctly in all circumstances yet. + For instance a function like: + create function s() returns int + begin + declare s int; + select sum(test.t.y) into s from test.t; + return s; + end + do not work. Invoking this in queries like "SELECT * FROM t2 WHERE x = s()" + will make things very complicated. And, in fact, even "SET @s=s()" and + "SELECT s()" fail, although the exact reasons in these cases are a bit + obscure; part of the problem might be the way the lex structure is + bit-copied (a not completely sound thing to do). diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 13983fbd69e..a828ae9cd19 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -277,59 +277,6 @@ h1 1 h? 17 delete from t1; drop procedure h; -drop table if exists fac; -create table fac (n int unsigned not null primary key, f bigint unsigned); -create procedure ifac(n int unsigned) -begin -declare i int unsigned; -set i = 1; -if n > 20 then -set n = 20; -end if; -while i <= n do -begin -declare f bigint unsigned; -set f = 0; # Temp. fix, this should not be needed in the future. -call fac(i, f); -insert into test.fac values (i, f); -set i = i + 1; -end; -end while; -end; -create procedure fac(n int unsigned, out f bigint unsigned) -begin -set f = 1; -while n > 1 do -set f = f * n; -set n = n - 1; -end while; -end; -call ifac(20); -select * from fac; -n f -1 1 -2 2 -3 6 -4 24 -5 120 -6 720 -7 5040 -8 40320 -9 362880 -10 3628800 -11 39916800 -12 479001600 -13 6227020800 -14 87178291200 -15 1307674368000 -16 20922789888000 -17 355687428096000 -18 6402373705728000 -19 121645100408832000 -20 2432902008176640000 -drop table fac; -drop procedure ifac; -drop procedure fac; create procedure into_test(x char(16), y int) begin insert into test.t1 values (x, y); @@ -441,7 +388,48 @@ drop function e; drop function inc; drop function mul; drop function append; -drop function fac; drop function fun; +drop table if exists fac; +create table fac (n int unsigned not null primary key, f bigint unsigned); +create procedure ifac(n int unsigned) +begin +declare i int unsigned; +set i = 1; +if n > 20 then +set n = 20; # bigint overflow otherwise +end if; +while i <= n do +begin +insert into test.fac values (i, fac(i)); +set i = i + 1; +end; +end while; +end; +call ifac(20); +select * from fac; +n f +1 1 +2 2 +3 6 +4 24 +5 120 +6 720 +7 5040 +8 40320 +9 362880 +10 3628800 +11 39916800 +12 479001600 +13 6227020800 +14 87178291200 +15 1307674368000 +16 20922789888000 +17 355687428096000 +18 6402373705728000 +19 121645100408832000 +20 2432902008176640000 +drop table fac; +drop procedure ifac; +drop function fac; drop table t1; drop table t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index a5efee28446..3b690f8b542 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -325,47 +325,6 @@ delete from t1| drop procedure h| -# A "real" procedure example - ---disable_warnings -drop table if exists fac| ---enable_warnings -create table fac (n int unsigned not null primary key, f bigint unsigned)| - -create procedure ifac(n int unsigned) -begin - declare i int unsigned; - set i = 1; - if n > 20 then - set n = 20; - end if; - while i <= n do - begin - declare f bigint unsigned; - set f = 0; # Temp. fix, this should not be needed in the future. - call fac(i, f); - insert into test.fac values (i, f); - set i = i + 1; - end; - end while; -end| - -create procedure fac(n int unsigned, out f bigint unsigned) -begin - set f = 1; - while n > 1 do - set f = f * n; - set n = n - 1; - end while; -end| - -call ifac(20)| -select * from fac| -drop table fac| -drop procedure ifac| -drop procedure fac| - - # SELECT INTO local variables create procedure into_test(x char(16), y int) begin @@ -510,9 +469,37 @@ drop function e| drop function inc| drop function mul| drop function append| -drop function fac| drop function fun| + +# A "real" procedure and function example + +--disable_warnings +drop table if exists fac| +--enable_warnings +create table fac (n int unsigned not null primary key, f bigint unsigned)| + +create procedure ifac(n int unsigned) +begin + declare i int unsigned; + set i = 1; + if n > 20 then + set n = 20; # bigint overflow otherwise + end if; + while i <= n do + begin + insert into test.fac values (i, fac(i)); + set i = i + 1; + end; + end while; +end| + +call ifac(20)| +select * from fac| +drop table fac| +drop procedure ifac| +drop function fac| + delimiter ;| drop table t1; drop table t2; From 12f771d9e7817ae5f0243ef4452732910c544cdf Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 5 Mar 2003 19:45:17 +0100 Subject: [PATCH 39/83] Improved error handling regarding SPs (with info like names etc in the output). Disabled queries in FUNCTIONs. --- include/mysqld_error.h | 3 +- mysql-test/r/sp-error.result | 70 +++++++++++++++++++ mysql-test/t/sp-error.test | 110 ++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 18 ----- sql/share/czech/errmsg.txt | 21 +++--- sql/share/danish/errmsg.txt | 21 +++--- sql/share/dutch/errmsg.txt | 21 +++--- sql/share/english/errmsg.txt | 21 +++--- sql/share/estonian/errmsg.txt | 21 +++--- sql/share/french/errmsg.txt | 21 +++--- sql/share/german/errmsg.txt | 21 +++--- sql/share/greek/errmsg.txt | 21 +++--- sql/share/hungarian/errmsg.txt | 21 +++--- sql/share/italian/errmsg.txt | 21 +++--- sql/share/japanese/errmsg.txt | 21 +++--- sql/share/korean/errmsg.txt | 21 +++--- sql/share/norwegian-ny/errmsg.txt | 21 +++--- sql/share/norwegian/errmsg.txt | 21 +++--- sql/share/polish/errmsg.txt | 21 +++--- sql/share/portuguese/errmsg.txt | 21 +++--- sql/share/romanian/errmsg.txt | 21 +++--- sql/share/russian/errmsg.txt | 21 +++--- sql/share/serbian/errmsg.txt | 21 +++--- sql/share/slovak/errmsg.txt | 21 +++--- sql/share/spanish/errmsg.txt | 21 +++--- sql/share/swedish/errmsg.txt | 21 +++--- sql/share/ukrainian/errmsg.txt | 21 +++--- sql/sp_head.cc | 13 ++++ sql/sp_head.h | 6 +- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 45 ++++++++---- sql/sql_yacc.yy | 66 ++++++++++++++---- 32 files changed, 533 insertions(+), 283 deletions(-) create mode 100644 mysql-test/r/sp-error.result create mode 100644 mysql-test/t/sp-error.test diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 48e7f42c707..7d2ca2de0f1 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -277,4 +277,5 @@ #define ER_SP_UNINIT_VAR 1258 #define ER_SP_BADSELECT 1259 #define ER_SP_BADRETURN 1260 -#define ER_ERROR_MESSAGES 261 +#define ER_SP_BADQUERY 1261 +#define ER_ERROR_MESSAGES 262 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result new file mode 100644 index 00000000000..ee99e871c3e --- /dev/null +++ b/mysql-test/r/sp-error.result @@ -0,0 +1,70 @@ +delete from mysql.proc; +create procedure proc1() +set @x = 42; +create function func1() returns int +return 42; +create procedure foo() +create procedure bar() set @x=3; +Can't create a PROCEDURE from within another stored routine +create procedure foo() +create function bar() returns double return 2.3; +Can't create a FUNCTION from within another stored routine +create procedure proc1() +set @x = 42; +PROCEDURE proc1 already exists +create function func1() returns int +return 42; +FUNCTION func1 already exists +alter procedure foo; +PROCEDURE foo does not exist +alter function foo; +FUNCTION foo does not exist +drop procedure foo; +PROCEDURE foo does not exist +drop function foo; +FUNCTION foo does not exist +call foo(); +PROCEDURE foo does not exist +create procedure foo() +foo: loop +leave bar; +end loop; +LEAVE with no matching label: bar +create procedure foo() +foo: loop +iterate bar; +end loop; +ITERATE with no matching label: bar +create procedure foo() +foo: loop +foo: loop +set @x=2; +end loop foo; +end loop foo; +Redefining label foo +create procedure foo() +foo: loop +set @x=2; +end loop bar; +End-label bar without match +create procedure foo(out x int) +begin +declare y int; +set x = y; +end; +Referring to uninitialized variable y +create procedure foo(x int) +select * from test.t1; +SELECT in a stored procedure must have INTO +create procedure foo() +return 42; +RETURN is only allowed in a FUNCTION +create function foo() returns int +begin +declare x int; +select max(c) into x from test.t; +return x; +end; +Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION +drop procedure proc1; +drop function func1; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test new file mode 100644 index 00000000000..e3577803a47 --- /dev/null +++ b/mysql-test/t/sp-error.test @@ -0,0 +1,110 @@ +# +# Stored PROCEDURE error tests +# + +# Make sure we don't have any procedures left. +delete from mysql.proc; + +delimiter |; + +# Check that we get the right error, i.e. UDF declaration parses correctly, +# but foo.so doesn't exist. +# QQ This generates an error message containing a misleading errno which +# might vary between systems (it usually doesn't have anything to do with +# the actual failing dlopen()). +#--error 1126 +#create function foo returns real soname "foo.so"| + +create procedure proc1() + set @x = 42| + +create function func1() returns int + return 42| + +# Can't create recursively +--error 1250 +create procedure foo() + create procedure bar() set @x=3| +--error 1250 +create procedure foo() + create function bar() returns double return 2.3| + +# Already exists +--error 1251 +create procedure proc1() + set @x = 42| +--error 1251 +create function func1() returns int + return 42| + +# Does not exist +--error 1252 +alter procedure foo| +--error 1252 +alter function foo| +--error 1252 +drop procedure foo| +--error 1252 +drop function foo| +--error 1252 +call foo()| + +# LEAVE/ITERATE with no match +--error 1255 +create procedure foo() +foo: loop + leave bar; +end loop| +--error 1255 +create procedure foo() +foo: loop + iterate bar; +end loop| + +# Redefining label +--error 1256 +create procedure foo() +foo: loop + foo: loop + set @x=2; + end loop foo; +end loop foo| + +# End label mismatch +--error 1257 +create procedure foo() +foo: loop + set @x=2; +end loop bar| + +# Referring to undef variable +--error 1258 +create procedure foo(out x int) +begin + declare y int; + set x = y; +end| + +# We require INTO in SELECTs (for now; this might change in the future) +--error 1259 +create procedure foo(x int) + select * from test.t1| + +# RETURN in FUNCTION only +--error 1260 +create procedure foo() + return 42| + +# Doesn't allow queries in FUNCTIONs (for now :-( ) +--error 1261 +create function foo() returns int +begin + declare x int; + select max(c) into x from test.t; + return x; +end| + +drop procedure proc1| +drop function func1| + +delimiter ;| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 3b690f8b542..d56d5859940 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -213,16 +213,6 @@ until x = 0 end repeat| drop procedure b2| -# Btw, this should generate an error (for now; this might change in the future) ---error 1259 -create procedure b3(x int) -repeat - select * from test.t1; # No INTO! - insert into test.t1 values (repeat("b3",3), x); - set x = x-1; -until x = 0 end repeat| - - # Labelled WHILE with ITERATE (pointless really) create procedure c(x int) hmm: while x > 0 do @@ -398,14 +388,6 @@ end| #drop table t2| drop procedure create_select| -# Check that we get the right error, i.e. UDF declaration parses correctly, -# but foo.so doesn't exist. -# QQ This generates an error message containing a misleading errno which -# might vary between systems (it usually doesn't have anything to do with -# the actual failing dlopen()). -#--error 1126 -#create function foo returns real soname "foo.so"| - # A minimal, constant FUNCTION. create function e() returns double return 2.7182818284590452354| diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 67a7fc8259d..cf423e3d995 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -260,14 +260,15 @@ v/* "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 193d8204c7d..4aa1fb6756c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -254,14 +254,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index e328bc64cfd..de19d3b2e3d 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -262,14 +262,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index b2e56d8b701..97a533c04d8 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -251,14 +251,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 46b7240dd6d..648fdc1a8f3 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -256,14 +256,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 5dba7cd4739..a504701c52b 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -251,14 +251,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 0a90b30d07c..76c6ac7b5cb 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -261,14 +261,15 @@ "Select %u wurde während der Optimierung reduziert.", "Tabelle '%-.64s', die in einem der SELECT-Befehle verwendet wurde kann nicht in %-.32s verwendet werden." "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 0d64095b2e3..dbdd3da364f 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -251,14 +251,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 4927b9b86e0..19acbdb413e 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -253,14 +253,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 7a38bb4c9f0..1aaabf17187 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -251,14 +251,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 21c891fb982..83dce80cc96 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -253,14 +253,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 61aa944c92d..e8322b66873 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -251,14 +251,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 527db96e708..a2c1cb04415 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -253,14 +253,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 9af96c322c6..72212208faf 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -253,14 +253,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index cec72e6a1a2..7a012f20de3 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -255,14 +255,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 93f1bc4af81..f749d98c29b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -251,14 +251,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index c6cd6efc9a0..0df04309f40 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -255,14 +255,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index ecad689594d..362b65f8623 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -254,14 +254,15 @@ "Select %u ÂÙÌ ÕÐÒÁÚÄÎÅÎ × ÐÒÏÃÅÓÓÅ ÏÐÔÉÍÉÚÁÃÉÉ", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 456df149576..1350e56062d 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -247,14 +247,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index a2a9f94e970..53331bdb904 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -259,14 +259,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 9faddd8b7f1..e48922ac566 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -252,14 +252,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 33359dbf7aa..0b83c93efea 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -251,14 +251,15 @@ "Select %u was reduced during optimisation", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index dfdb3e1c378..006789fb781 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -256,14 +256,15 @@ "Select %u was ÓËÁÓÏ×ÁÎÏ ÐÒÉ ÏÐÔÉÍiÚÁÃii", "Table '%-.64s' from one of SELECT's can not be used in %-.32s" "Client does not support authentication protocol requested by server. Consider upgrading MySQL client" -"Can't create a PROCEDURE from within a PROCEDURE" -"PROCEDURE already exists" -"PROCEDURE does not exist" -"Failed to DROP PROCEDURE" -"Failed to CREATE PROCEDURE" -"%s with no matching label" -"Redefining label" -"End-label without match" -"Referring to uninitialized variable" +"Can't create a %s from within another stored routine" +"%s %s already exists" +"%s %s does not exist" +"Failed to DROP %s %s" +"Failed to CREATE %s %s" +"%s with no matching label: %s" +"Redefining label %s" +"End-label %s without match" +"Referring to uninitialized variable %s" "SELECT in a stored procedure must have INTO" -"RETURN is only allowed in a stored FUNCTION" +"RETURN is only allowed in a FUNCTION" +"Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 55d21c37609..58ea7a7a873 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -442,6 +442,19 @@ sp_instr_set::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } +// +// sp_instr_jump +// +int +sp_instr_jump::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_jump::execute"); + DBUG_PRINT("info", ("destination: %u", m_dest)); + + *nextp= m_dest; + DBUG_RETURN(0); +} + // // sp_instr_jump_if // diff --git a/sql/sp_head.h b/sql/sp_head.h index ee64a1bd0cf..52cbdc56093 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -265,11 +265,7 @@ public: virtual ~sp_instr_jump() {} - virtual int execute(THD *thd, uint *nextp) - { - *nextp= m_dest; - return 0; - } + virtual int execute(THD *thd, uint *nextp); virtual void set_destination(uint dest) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 337b69026bf..66c58090bfd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -75,7 +75,7 @@ enum enum_sql_command { SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, SQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_TABLE_TYPES, SQLCOM_SHOW_PRIVILEGES, SQLCOM_HELP, - SQLCOM_CREATE_PROCEDURE, SQLCOM_CALL, + SQLCOM_CREATE_PROCEDURE, SQLCOM_CREATE_SPFUNCTION, SQLCOM_CALL, SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION, /* This should be the last !!! */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 94278371fd0..539913383a7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -52,6 +52,15 @@ #define TRANS_MEM_ROOT_BLOCK_SIZE 4096 #define TRANS_MEM_ROOT_PREALLOC 4096 +/* Used in error handling only */ +#define SP_TYPE_STRING(LP) \ + ((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE") +#define SP_COM_STRING(LP) \ + ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \ + (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \ + (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \ + "FUNCTION" : "PROCEDURE") + extern int yyparse(void *thd); extern "C" pthread_mutex_t THR_LOCK_keycache; #ifdef SOLARIS @@ -1589,7 +1598,7 @@ mysql_execute_command(THD *thd) */ sp_clear_function_cache(thd); if (lex->sql_command != SQLCOM_CREATE_PROCEDURE && - lex->sql_command != SQLCOM_CREATE_FUNCTION) + lex->sql_command != SQLCOM_CREATE_SPFUNCTION) { if (sp_cache_functions(thd, lex)) DBUG_RETURN(-1); @@ -2961,23 +2970,27 @@ mysql_execute_command(THD *thd) res= -1; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; - case SQLCOM_CREATE_PROCEDURE: // FUNCTION too (but not UDF!) + case SQLCOM_CREATE_PROCEDURE: + case SQLCOM_CREATE_SPFUNCTION: if (!lex->sphead) { - send_error(thd, ER_SP_NO_RECURSIVE_CREATE); - goto error; + res= -1; // Shouldn't happen + break; } else { uint namelen; char *name= lex->sphead->name(&namelen); #ifdef HAVE_DLOPEN - udf_func *udf = find_udf(name, namelen); - - if (udf) + if (lex->sphead->m_type == TYPE_ENUM_FUNCTION) { - net_printf(thd, ER_UDF_EXISTS, name); - goto error; + udf_func *udf = find_udf(name, namelen); + + if (udf) + { + net_printf(thd, ER_UDF_EXISTS, name); + goto error; + } } #endif res= lex->sphead->create(thd); @@ -2987,10 +3000,10 @@ mysql_execute_command(THD *thd) send_ok(thd); break; case SP_WRITE_ROW_FAILED: - send_error(thd, ER_SP_ALREADY_EXISTS); + net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name); goto error; default: - send_error(thd, ER_SP_STORE_FAILED); + net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name); goto error; } } @@ -3002,7 +3015,7 @@ mysql_execute_command(THD *thd) sp= sp_find_procedure(thd, &lex->udf.name); if (! sp) { - send_error(thd, ER_SP_DOES_NOT_EXIST); + net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", lex->udf.name); goto error; } else @@ -3037,7 +3050,7 @@ mysql_execute_command(THD *thd) sp= sp_find_function(thd, &lex->udf.name); if (! sp) { - send_error(thd, ER_SP_DOES_NOT_EXIST); + net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex),lex->udf.name); goto error; } else @@ -3079,10 +3092,12 @@ mysql_execute_command(THD *thd) send_ok(thd); break; case SP_KEY_NOT_FOUND: - send_error(thd, ER_SP_DOES_NOT_EXIST); + net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), + lex->udf.name.str); goto error; default: - send_error(thd, ER_SP_DROP_FAILED); + net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex), + lex->udf.name.str); goto error; } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7c2b97904fb..576962058c0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -917,6 +917,11 @@ create: { LEX *lex= Lex; + if (lex->sphead) + { + net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "PROCEDURE"); + YYABORT; + } lex->spcont= new sp_pcontext(); lex->sphead= new sp_head(&$3, lex); lex->sphead->m_type= TYPE_ENUM_PROCEDURE; @@ -948,7 +953,11 @@ create_function_tail: { LEX *lex= Lex; - lex->sql_command = SQLCOM_CREATE_PROCEDURE; + if (lex->sphead) + { + net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "FUNCTION"); + YYABORT; + } lex->spcont= new sp_pcontext(); lex->sphead= new sp_head(&lex->udf.name, lex); lex->sphead->m_type= TYPE_ENUM_FUNCTION; @@ -962,7 +971,9 @@ create_function_tail: Lex->sphead->m_returns= (enum enum_field_types)$7; } sp_proc_stmt - {} + { + Lex->sql_command = SQLCOM_CREATE_SPFUNCTION; + } ; call: @@ -1110,10 +1121,25 @@ sp_proc_stmt: if (lex->sql_command != SQLCOM_SET_OPTION || !lex->var_list.is_empty()) { - sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); + /* Currently we can't handle queries inside a FUNCTION, + ** because of the way table locking works. + ** This is unfortunate, and limits the usefulness of functions + ** a great deal, but it's nothing we can do about this at the + ** moment. + */ + if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && + lex->sql_command != SQLCOM_SET_OPTION) + { + send_error(YYTHD, ER_SP_BADQUERY); + YYABORT; + } + else + { + sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); - i->set_lex(lex); - lex->sphead->add_instr(i); + i->set_lex(lex); + lex->sphead->add_instr(i); + } } lex->sphead->restore_lex(YYTHD); } @@ -1185,7 +1211,7 @@ sp_proc_stmt: if (! lab) { - send_error(YYTHD, ER_SP_LILABEL_MISMATCH, "LEAVE"); + net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "LEAVE", $2.str); YYABORT; } else @@ -1203,7 +1229,7 @@ sp_proc_stmt: if (! lab) { - send_error(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE"); + net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE", $2.str); YYABORT; } else @@ -1305,7 +1331,7 @@ sp_labeled_control: if (lab) { - send_error(YYTHD, ER_SP_LABEL_REDEFINE); + net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $1.str); YYABORT; } else @@ -1321,7 +1347,7 @@ sp_labeled_control: if (! lab || strcasecmp($5.str, lab->name) != 0) { - send_error(YYTHD, ER_SP_LABEL_MISMATCH); + net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); YYABORT; } else @@ -1965,6 +1991,17 @@ alter: lex->sql_command= SQLCOM_ALTER_PROCEDURE; lex->udf.name= $3; } + | ALTER FUNCTION_SYM ident + /* QQ Characteristics missing for now */ + opt_restrict + { + LEX *lex=Lex; + + /* This is essensially an no-op right now, since we haven't + put the characteristics in yet. */ + lex->sql_command= SQLCOM_ALTER_FUNCTION; + lex->udf.name= $3; + } ; alter_list: @@ -3526,10 +3563,13 @@ select_var_ident: send_error(lex->thd, ER_SYNTAX_ERROR); YYABORT; } - if (lex->result) - ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset)); - else + if (! lex->result) YYABORT; + else + { + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset)); + t->isset= TRUE; + } } ; @@ -4384,7 +4424,7 @@ simple_ident: { /* We're compiling a stored procedure and found a variable */ if (lex->sql_command != SQLCOM_CALL && ! spv->isset) { - send_error(YYTHD, ER_SP_UNINIT_VAR); + net_printf(YYTHD, ER_SP_UNINIT_VAR, $1.str); YYABORT; } else From dba598cddd9c14fd15cf2f0a23f668617e4bf09b Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 6 Mar 2003 19:16:46 +0100 Subject: [PATCH 40/83] Fixed reentrantness bugs in select (lex->result) and select_dumpvar, and added cool prime number test example. --- mysql-test/r/sp.result | 76 ++++++++++++++++++++++++++++++---- mysql-test/t/sp.test | 92 +++++++++++++++++++++++++++++++++++++++++- sql/sql_class.cc | 3 ++ sql/sql_select.cc | 3 +- 4 files changed, 165 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index a828ae9cd19..b188a6ed57d 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -170,13 +170,6 @@ insert into test.t1 values (repeat("b2",3), x); set x = x-1; until x = 0 end repeat; drop procedure b2; -create procedure b3(x int) -repeat -select * from test.t1; # No INTO! -insert into test.t1 values (repeat("b3",3), x); -set x = x-1; -until x = 0 end repeat; -SELECT in a stored procedure must have INTO create procedure c(x int) hmm: while x > 0 do insert into test.t1 values ("c", x); @@ -431,5 +424,74 @@ n f drop table fac; drop procedure ifac; drop function fac; +drop table if exists primes; +create table primes ( +i int unsigned not null primary key, +p bigint unsigned not null +); +insert into primes values +( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13), +( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31), +(10, 37), (11, 41), (12, 43), (13, 47), (14, 53), +(15, 59), (16, 61), (17, 67), (18, 71), (19, 73), +(20, 79), (21, 83), (22, 89), (23, 97), (24, 101), +(25, 103), (26, 107), (27, 109), (28, 113), (29, 127), +(30, 131), (31, 137), (32, 139), (33, 149), (34, 151), +(35, 157), (36, 163), (37, 167), (38, 173), (39, 179), +(40, 181), (41, 191), (42, 193), (43, 197), (44, 199); +create procedure opp(n bigint unsigned, out pp bool) +begin +declare r double; +declare b, s bigint unsigned; +set b = 0, s = 0; +set r = sqrt(n); +again: +loop +if s = 45 then +set b = b+200, s = 0; +else +begin +declare p bigint unsigned; +select t.p into p from test.primes t where t.i = s; +if b+p > r then +set pp = 1; +leave again; +end if; +if mod(n, b+p) = 0 then +set pp = 0; +leave again; +end if; +set s = s+1; +end; +end if; +end loop again; +end; +create procedure ip(m int unsigned) +begin +declare p bigint unsigned; +declare i int unsigned; +set i=45, p=201; +while i < m do +begin +declare pp bool; +set pp = 0; +call opp(p, pp); +if pp then +insert into test.primes values (i, p); +set i = i+1; +end if; +set p = p+2; +end; +end while; +end; +call ip(200); +select * from primes where i=45 or i=100 or i=199; +i p +45 211 +100 557 +199 1229 +drop table primes; +drop procedure opp; +drop procedure ip; drop table t1; drop table t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index d56d5859940..0d6a84fa63b 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -454,7 +454,11 @@ drop function append| drop function fun| -# A "real" procedure and function example +# +# Some "real" examples +# + +# fac --disable_warnings drop table if exists fac| @@ -482,6 +486,92 @@ drop table fac| drop procedure ifac| drop function fac| + +# primes + +--disable_warnings +drop table if exists primes| +--enable_warnings + +create table primes ( + i int unsigned not null primary key, + p bigint unsigned not null +)| + +insert into primes values + ( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13), + ( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31), + (10, 37), (11, 41), (12, 43), (13, 47), (14, 53), + (15, 59), (16, 61), (17, 67), (18, 71), (19, 73), + (20, 79), (21, 83), (22, 89), (23, 97), (24, 101), + (25, 103), (26, 107), (27, 109), (28, 113), (29, 127), + (30, 131), (31, 137), (32, 139), (33, 149), (34, 151), + (35, 157), (36, 163), (37, 167), (38, 173), (39, 179), + (40, 181), (41, 191), (42, 193), (43, 197), (44, 199)| + +create procedure opp(n bigint unsigned, out pp bool) +begin + declare r double; + declare b, s bigint unsigned; + + set b = 0, s = 0; + set r = sqrt(n); + + again: + loop + if s = 45 then + set b = b+200, s = 0; + else + begin + declare p bigint unsigned; + + select t.p into p from test.primes t where t.i = s; + if b+p > r then + set pp = 1; + leave again; + end if; + if mod(n, b+p) = 0 then + set pp = 0; + leave again; + end if; + set s = s+1; + end; + end if; + end loop again; +end| + +create procedure ip(m int unsigned) +begin + declare p bigint unsigned; + declare i int unsigned; + + set i=45, p=201; + + while i < m do + begin + declare pp bool; + + set pp = 0; + call opp(p, pp); + if pp then + insert into test.primes values (i, p); + set i = i+1; + end if; + set p = p+2; + end; + end while; +end| + +# This isn't the fastest way in the world to compute prime numbers, so +# don't be too ambition. ;-) +call ip(200)| +# We don't want to select the entire table here, just pick a few +# examples. +select * from primes where i=45 or i=100 or i=199| +drop table primes| +drop procedure opp| +drop procedure ip| + delimiter ;| drop table t1; drop table t2; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 5ac904393f5..ee14ce16593 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -972,6 +972,8 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) Item *item; my_var *mv; LEX_STRING *ls; + + row_count= 0; if (var_list.elements != list.elements) { my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); @@ -996,6 +998,7 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) } return 0; } + bool select_dumpvar::send_data(List &items) { List_iterator_fast li(vars); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4543c6bc5d0..c99da1928ca 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -191,7 +191,8 @@ int handle_select(THD *thd, LEX *lex, select_result *result) send_error(thd, 0, NullS); res= 1; } - delete result; + if (result != lex->result) + delete result; return res; } From df8ac83e56a17ac9d9d2f07b34e09ec6652bd35e Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 7 Mar 2003 10:58:42 +0100 Subject: [PATCH 41/83] Updated documentation with the latest FUNCTION stuff. --- Docs/sp-imp-spec.txt | 59 +++++++++++++++++++++++++++++++++++------ Docs/sp-implemented.txt | 32 ++++++++++------------ 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index c3818f141dc..1303ae19c5c 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -2,9 +2,6 @@ Implementation specification for Stored Procedures ================================================== -This is a first draft, only covering the basics for parsing, creating, and -calling a PROCEDURE. - - How parsing and execution of queries work @@ -436,21 +433,37 @@ calling a PROCEDURE. // Return the "out" index for slot 'idx' int get_oindex(uint idx); + + // Set the FUNCTION result + void set_result(Item *i); + + // Get the FUNCTION result + Item *get_result(); } - The procedure: sp_head.h + #define TYPE_ENUM_FUNCTION 1 + #define TYPE_ENUM_PROCEDURE 2 + class sp_head { + int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE + sp_head(LEX_STRING *name, LEX*); // Store this procedure in the database. This is a wrapper around // the function sp_create_procedure(). int create(THD *); - // CALL this procedure. - int execute(THD *); + // Invoke a FUNCTION + int + execute_function(THD *thd, Item **args, uint argcount, Item **resp); + + // CALL a PROCEDURE + int + execute_procedure(THD *thd, List *args); // Add the instruction to this procedure. void add_instr(sp_instr *); @@ -524,7 +537,7 @@ calling a PROCEDURE. // 'dest' is the destination instruction index. sp_instr_jump(uint ip, uint dest); - virtual int execute(THD *, uint *nextp); + int execute(THD *, uint *nextp); // Set the destination instruction 'dest'. void set_destination(uint dest); @@ -542,10 +555,28 @@ calling a PROCEDURE. int execute(THD *, uint *nextp); } + - Return a function value + class sp_instr_return : public sp_instr + { + // Return the value 'val' + sp_instr_return(uint ip, Item *val, enum enum_field_types type); + + int execute(THD *thd, uint *nextp); + } + + - Utility functions: sp.h + #define SP_OK 0 + #define SP_KEY_NOT_FOUND -1 + #define SP_OPEN_TABLE_FAILED -2 + #define SP_WRITE_ROW_FAILED -3 + #define SP_DELETE_ROW_FAILED -4 + #define SP_GET_FIELD_FAILED -5 + #define SP_PARSE_ERROR -6 + // Finds a stored procedure given its name. Returns NULL if not found. - sp_head *sp_find(THD *, Item_string *name); + sp_head *sp_find_procedure(THD *, LEX_STRING *name); // Store the procedure 'name' in the database. 'def' is the complete // definition string ("create procedure ..."). @@ -554,6 +585,18 @@ calling a PROCEDURE. char *def, uint deflen); // Drop the procedure 'name' from the database. - int sp_drop(THD *, char *name, uint namelen); + int sp_drop_procedure(THD *, char *name, uint namelen); + + // Finds a stored function given its name. Returns NULL if not found. + sp_head *sp_find_function(THD *, LEX_STRING *name); + + // Store the function 'name' in the database. 'def' is the complete + // definition string ("create function ..."). + int sp_create_function(THD *, + char *name, uint namelen, + char *def, uint deflen); + + // Drop the function 'name' from the database. + int sp_drop_function(THD *, char *name, uint namelen); -- diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index 5173606e95c..1878c99b7ed 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -1,26 +1,29 @@ -Stored Procedures implemented 2003-02-02: +Stored Procedures implemented 2003-03-07: Summary of Not Yet Implemented: - - Routine characteristics + - SQL queries (like SELECT, INSERT, UPDATE etc) in FUNCTION bodies - External languages - Access control + - Routine characteristics (mostly used for external languages) - Prepared SP caching; SPs are fetched and reparsed at each call - SQL-99 COMMIT (related to BEGIN/END) - DECLARE CURSOR ... - FOR-loops (as it requires cursors) - CASCADE/RESTRICT for ALTER and DROP - ALTER/DROP METHOD (as it implies User Defined Types) + - CONDITIONs, HANDLERs, SIGNAL and RESIGNAL (will probably not be implemented) Summary of what's implemented: - - SQL PROCEDURES (CREATE/DROP) + - SQL PROCEDUREs/FUNCTIONs (CREATE/DROP) - CALL - DECLARE of local variables - BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE - SELECT INTO local variables + - "Non-query" FUNCTIONs only List of what's implemented: @@ -52,7 +55,8 @@ List of what's implemented: Note: Multiple statements requires a client that can send bodies containing ";". This is handled in the CLI clients mysql and mysqltest with the "delimiter" command. Changing the end-of-query - delimiter ";" to for instance "|" allows + delimiter ";" to for instance "|" allows ";" to be used in the + routine body. - SET of local variables Implemented as part of the pre-existing SET syntax. This allows an extended syntax of "SET a=x, b=y, ..." where different variable types @@ -65,6 +69,12 @@ List of what's implemented: - SELECT ... INTO local variables (as well as global session variables) is implemented. (Note: This is not SQL-99 feature, but common in other databases.) + - A FUNCTION can have flow control contructs, but must not contain + an SQL query, like SELECT, INSERT, UPDATE, etc. The reason is that it's + hard to allow this is that a FUNCTION is executed as part of another + query (unlike a PROCEDURE, which is called as a statement). The table + locking scheme used makes it difficult to allow "subqueries" during + FUNCTION invokation. Closed questions: @@ -87,17 +97,3 @@ Open questions/issues: any type checking, since this is the way MySQL works. I still don't know if we should keep it this way, or implement type checking. Possibly we should have optional, uset-settable, type checking. - - - FUNCTIONs do not work correctly in all circumstances yet. - For instance a function like: - create function s() returns int - begin - declare s int; - select sum(test.t.y) into s from test.t; - return s; - end - do not work. Invoking this in queries like "SELECT * FROM t2 WHERE x = s()" - will make things very complicated. And, in fact, even "SET @s=s()" and - "SELECT s()" fail, although the exact reasons in these cases are a bit - obscure; part of the problem might be the way the lex structure is - bit-copied (a not completely sound thing to do). From 6822eb5ec0f590f35c8c4ce1020f1a68c1f8904a Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 19 Mar 2003 11:36:32 +0100 Subject: [PATCH 42/83] Post-merge fixes. --- client/mysqltest.c | 2 +- mysql-test/r/sp.result | 6 ------ mysql-test/t/sp-error.test | 34 +++++++++++++++++----------------- mysql-test/t/sp.test | 5 +++-- sql/item.cc | 1 + sql/share/german/errmsg.txt | 3 +-- sql/sp_pcontext.cc | 8 ++++++-- 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 9914887380b..3dbcaf891ba 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1536,7 +1536,7 @@ int do_while(struct st_query* q) int do_delimiter(char *p) { - while (*p && my_isspace(system_charset_info,*p)) + while (*p && my_isspace(charset_info,*p)) p++; if (!*p) die("Missing delimiter character\n"); diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index b188a6ed57d..a7d28407385 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -484,12 +484,6 @@ set p = p+2; end; end while; end; -call ip(200); -select * from primes where i=45 or i=100 or i=199; -i p -45 211 -100 557 -199 1229 drop table primes; drop procedure opp; drop procedure ip; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index e3577803a47..343b30ea8da 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -22,47 +22,47 @@ create function func1() returns int return 42| # Can't create recursively ---error 1250 +--error 1254 create procedure foo() create procedure bar() set @x=3| ---error 1250 +--error 1254 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1251 +--error 1255 create procedure proc1() set @x = 42| ---error 1251 +--error 1255 create function func1() returns int return 42| # Does not exist ---error 1252 +--error 1256 alter procedure foo| ---error 1252 +--error 1256 alter function foo| ---error 1252 +--error 1256 drop procedure foo| ---error 1252 +--error 1256 drop function foo| ---error 1252 +--error 1256 call foo()| # LEAVE/ITERATE with no match ---error 1255 +--error 1259 create procedure foo() foo: loop leave bar; end loop| ---error 1255 +--error 1259 create procedure foo() foo: loop iterate bar; end loop| # Redefining label ---error 1256 +--error 1260 create procedure foo() foo: loop foo: loop @@ -71,14 +71,14 @@ foo: loop end loop foo| # End label mismatch ---error 1257 +--error 1261 create procedure foo() foo: loop set @x=2; end loop bar| # Referring to undef variable ---error 1258 +--error 1262 create procedure foo(out x int) begin declare y int; @@ -86,17 +86,17 @@ begin end| # We require INTO in SELECTs (for now; this might change in the future) ---error 1259 +--error 1263 create procedure foo(x int) select * from test.t1| # RETURN in FUNCTION only ---error 1260 +--error 1264 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1261 +--error 1265 create function foo() returns int begin declare x int; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 0d6a84fa63b..bcde9e5102c 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -564,10 +564,11 @@ end| # This isn't the fastest way in the world to compute prime numbers, so # don't be too ambition. ;-) -call ip(200)| +#QQ Something broke after the last merge. :-( /2003-03-19 +#QQ call ip(200)| # We don't want to select the entire table here, just pick a few # examples. -select * from primes where i=45 or i=100 or i=199| +#QQ select * from primes where i=45 or i=100 or i=199| drop table primes| drop procedure opp| drop procedure ip| diff --git a/sql/item.cc b/sql/item.cc index 546734de662..17047bde916 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -171,6 +171,7 @@ bool Item::get_time(TIME *ltime) CHARSET_INFO * Item::default_charset() const { return current_thd->db_charset; +} Item * diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index eb7638c6ba4..b1b6e695fb1 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -259,13 +259,12 @@ "Referenz '%-.64s' wird nicht unterstützt (%s)", "Für jede abgeleitete Tabelle muss ein eigener Alias angegeben werden.", "Select %u wurde während der Optimierung reduziert.", -"Tabelle '%-.64s', die in einem der SELECT-Befehle verwendet wurde kann nicht in %-.32s verwendet werden." +"Tabelle '%-.64s', die in einem der SELECT-Befehle verwendet wurde kann nicht in %-.32s verwendet werden", "Client does not support authentication protocol requested by server. Consider upgrading MySQL client", "All parts of a SPATIAL KEY must be NOT NULL" "COLLATION '%s' is not valid for CHARACTER SET '%s'" "The slave was already running" "The slave was already stopped" -"Client does not support authentication protocol requested by server. Consider upgrading MySQL client" "Can't create a %s from within another stored routine" "%s %s already exists" "%s %s does not exist" diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 407151c3e38..9cf7a45b46b 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -61,13 +61,17 @@ sp_pcontext::grow() sp_pvar_t * sp_pcontext::find_pvar(LEX_STRING *name) { - String n(name->str, name->length, default_charset_info); uint i = m_i; while (i-- > 0) { - if (stringcmp(&n, m_pvar[i].name->const_string()) == 0) + if (my_strncasecmp(system_charset_info, + name->str, + m_pvar[i].name->const_string()->ptr(), + name->length) == 0) + { return m_pvar + i; + } } return NULL; } From 0d95f36a12bd9a5b9c71cbc6ed2f3f877e9522c0 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 20 Mar 2003 11:57:05 +0100 Subject: [PATCH 43/83] Post post merge fix. Made the broken ip test work again. --- mysql-test/r/sp.result | 6 ++++++ mysql-test/t/sp.test | 5 ++--- sql/sp_head.cc | 14 +++++++++++--- sql/sp_pcontext.cc | 6 +++++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index a7d28407385..b188a6ed57d 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -484,6 +484,12 @@ set p = p+2; end; end while; end; +call ip(200); +select * from primes where i=45 or i=100 or i=199; +i p +45 211 +100 557 +199 1229 drop table primes; drop procedure opp; drop procedure ip; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index bcde9e5102c..0d6a84fa63b 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -564,11 +564,10 @@ end| # This isn't the fastest way in the world to compute prime numbers, so # don't be too ambition. ;-) -#QQ Something broke after the last merge. :-( /2003-03-19 -#QQ call ip(200)| +call ip(200)| # We don't want to select the entire table here, just pick a few # examples. -#QQ select * from primes where i=45 or i=100 or i=199| +select * from primes where i=45 or i=100 or i=199| drop table primes| drop procedure opp| drop procedure ip| diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 58ea7a7a873..0a232ea5b4a 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -50,10 +50,15 @@ sp_map_result_type(enum enum_field_types type) static Item * eval_func_item(THD *thd, Item *it, enum enum_field_types type) { + DBUG_ENTER("eval_func_item"); it= it->this_item(); + DBUG_PRINT("info", ("type: %d", type)); if (it->fix_fields(thd, 0, NULL)) - return it; // Shouldn't happen? + { + DBUG_PRINT("info", ("fix_fields() failed")); + DBUG_RETURN(it); // Shouldn't happen? + } /* QQ How do we do this? Is there some better way? */ if (type == MYSQL_TYPE_NULL) @@ -62,9 +67,11 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) { switch (sp_map_result_type(type)) { case INT_RESULT: + DBUG_PRINT("info", ("INT_RESULT: %d", it->val_int())); it= new Item_int(it->val_int()); break; case REAL_RESULT: + DBUG_PRINT("info", ("REAL_RESULT: %g", it->val())); it= new Item_real(it->val()); break; default: @@ -73,6 +80,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) String tmp(buffer, sizeof(buffer), it->charset()); String *s= it->val_str(&tmp); + DBUG_PRINT("info", ("default result: %*s", s->length(), s->c_ptr_quick())) it= new Item_string(sql_strmake(s->c_ptr_quick(), s->length()), s->length(), it->charset()); break; @@ -80,7 +88,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) } } - return it; + DBUG_RETURN(it); } sp_head::sp_head(LEX_STRING *name, LEX *lex) @@ -209,7 +217,7 @@ sp_head::execute_procedure(THD *thd, List *args) else { if (pvar->mode == sp_param_out) - nctx->push_item(it->this_item()); // OUT + nctx->push_item(NULL); // OUT else nctx->push_item(eval_func_item(thd, it, pvar->type)); // IN or INOUT // Note: If it's OUT or INOUT, it must be a variable. diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 9cf7a45b46b..9d22c6be62b 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -65,10 +65,14 @@ sp_pcontext::find_pvar(LEX_STRING *name) while (i-- > 0) { + uint len= m_pvar[i].name->const_string()->length(); + + if (name->length > len) + len= name->length; if (my_strncasecmp(system_charset_info, name->str, m_pvar[i].name->const_string()->ptr(), - name->length) == 0) + len) == 0) { return m_pvar + i; } From dd49c33f20c43532675c4b40b283484ee7b107df Mon Sep 17 00:00:00 2001 From: "hf@genie.(none)" <> Date: Fri, 21 Mar 2003 09:37:01 +0400 Subject: [PATCH 44/83] SCRUM two versions of KILL implementation --- include/mysql_com.h | 2 ++ sql/lex.h | 1 + sql/mysql_priv.h | 2 +- sql/sql_class.h | 1 + sql/sql_parse.cc | 22 +++++++++++++++++----- sql/sql_yacc.yy | 12 +++++++++--- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 7eac3b113d2..dec184133dc 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -118,6 +118,8 @@ enum enum_server_command #define NET_WRITE_TIMEOUT 60 /* Timeout on write */ #define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */ +#define ONLY_KILL_QUERY 1 + struct st_vio; /* Only C */ typedef struct st_vio Vio; diff --git a/sql/lex.h b/sql/lex.h index 33fbb90d21f..df6cfaffece 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -102,6 +102,7 @@ static SYMBOL symbols[] = { { "COMMITTED", SYM(COMMITTED_SYM),0,0}, { "COMPRESSED", SYM(COMPRESSED_SYM),0,0}, { "CONCURRENT", SYM(CONCURRENT),0,0}, + { "CONNECTION", SYM(CONNECTION_SYM),0,0}, { "CONSTRAINT", SYM(CONSTRAINT),0,0}, { "CREATE", SYM(CREATE),0,0}, { "CROSS", SYM(CROSS),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b3457db07c5..3d4ddfc63d1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -45,7 +45,7 @@ char *sql_strdup(const char *str); char *sql_strmake(const char *str,uint len); gptr sql_memdup(const void * ptr,unsigned size); void sql_element_free(void *ptr); -void kill_one_thread(THD *thd, ulong id); +void kill_one_thread(THD *thd, ulong id, bool only_kill_query); bool net_request_file(NET* net, const char* fname); char* query_table_status(THD *thd,const char *db,const char *table_name); diff --git a/sql/sql_class.h b/sql/sql_class.h index 7740a54d007..cc935bd69bb 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -550,6 +550,7 @@ public: bool system_thread,in_lock_tables,global_read_lock; bool query_error, bootstrap, cleanup_done; bool volatile killed; + bool volatile only_kill_query; bool prepare_command; bool tmp_table_used; sp_rcontext *spcont; // SP runtime context diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 539913383a7..a3a96aac224 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -848,7 +848,7 @@ pthread_handler_decl(handle_one_connection,arg) init_sql_alloc(&thd->mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); init_sql_alloc(&thd->transaction.mem_root, TRANS_MEM_ROOT_BLOCK_SIZE, TRANS_MEM_ROOT_PREALLOC); - while (!net->error && net->vio != 0 && !thd->killed) + while (!net->error && net->vio != 0 && !(thd->killed && !thd->only_kill_query)) { if (do_command(thd)) break; @@ -1054,6 +1054,12 @@ bool do_command(THD *thd) } else { + if (thd->only_kill_query) + { + thd->killed= FALSE; + thd->only_kill_query= FALSE; + } + packet=(char*) net->read_pos; command = (enum enum_server_command) (uchar) packet[0]; if (command >= COM_END) @@ -1473,7 +1479,7 @@ restore_user: { statistic_increment(com_stat[SQLCOM_KILL],&LOCK_status); ulong id=(ulong) uint4korr(packet); - kill_one_thread(thd,id); + kill_one_thread(thd,id,false); break; } case COM_DEBUG: @@ -2890,7 +2896,7 @@ mysql_execute_command(THD *thd) reload_acl_and_cache(thd, lex->type, tables) ; break; case SQLCOM_KILL: - kill_one_thread(thd,lex->thread_id); + kill_one_thread(thd,lex->thread_id, lex->type & ONLY_KILL_QUERY); break; case SQLCOM_SHOW_GRANTS: res=0; @@ -4179,7 +4185,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) This is written such that we have a short lock on LOCK_thread_count */ -void kill_one_thread(THD *thd, ulong id) +void kill_one_thread(THD *thd, ulong id, bool only_kill_query) { THD *tmp; uint error=ER_NO_SUCH_THREAD; @@ -4199,7 +4205,13 @@ void kill_one_thread(THD *thd, ulong id) if ((thd->master_access & SUPER_ACL) || !strcmp(thd->user,tmp->user)) { - tmp->awake(1 /*prepare to die*/); + if (only_kill_query) + { + tmp->killed= 1; + tmp->only_kill_query= 1; + } + else + tmp->awake(1 /*prepare to die*/); error=0; } else diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 576962058c0..1b99977d527 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -201,6 +201,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token COLUMNS %token COLUMN_SYM %token CONCURRENT +%token CONNECTION_SYM %token CONSTRAINT %token CONVERT_SYM %token DATABASES @@ -4231,18 +4232,23 @@ purge: /* kill threads */ kill: - KILL_SYM expr + KILL_SYM kill_option expr { LEX *lex=Lex; - if ($2->fix_fields(lex->thd, 0, &$2) || $2->check_cols(1)) + if ($3->fix_fields(lex->thd, 0, &$3) || $3->check_cols(1)) { send_error(lex->thd, ER_SET_CONSTANTS_ONLY); YYABORT; } lex->sql_command=SQLCOM_KILL; - lex->thread_id= (ulong) $2->val_int(); + lex->thread_id= (ulong) $3->val_int(); }; +kill_option: + /* empty */ { Lex->type= 0; } + | CONNECTION_SYM { Lex->type= 0; } + | QUERY_SYM { Lex->type= ONLY_KILL_QUERY; }; + /* change database */ use: USE_SYM ident From 2578564725535f850e92f8d5e2b9b94c804da6df Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 26 Mar 2003 12:29:58 +0100 Subject: [PATCH 45/83] Added IF EXISTS to DROP PROCEDURE|FUNCTION. Changed another unecessary use of Item_string into LEX_STRING (in sp_pcontext). --- Docs/sp-implemented.txt | 2 +- mysql-test/r/sp-error.result | 3 +++ mysql-test/t/sp-error.test | 1 + sql/sp_pcontext.cc | 11 +++++------ sql/sp_pcontext.h | 2 +- sql/sql_parse.cc | 9 +++++++++ sql/sql_yacc.yy | 10 ++++++---- 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index 1878c99b7ed..41e7c4b2923 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -35,7 +35,7 @@ List of what's implemented: Is parsed, but a no-op (as there are no characteristics implemented yet). CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). - - DROP PROCEDURE|FUNCTION name + - DROP PROCEDURE|FUNCTION [IF EXISTS] name CASCADE/RESTRICT is not implemented (and CASCADE probably will not be). - CALL name (args) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index ee99e871c3e..ad1510c27f6 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -25,6 +25,9 @@ drop function foo; FUNCTION foo does not exist call foo(); PROCEDURE foo does not exist +drop procedure if exists foo; +Warnings: +Warning 1256 PROCEDURE foo does not exist create procedure foo() foo: loop leave bar; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 343b30ea8da..dd9becc631d 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -48,6 +48,7 @@ drop procedure foo| drop function foo| --error 1256 call foo()| +drop procedure if exists foo| # LEAVE/ITERATE with no match --error 1259 diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 9d22c6be62b..94eb8df4b95 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -65,13 +65,12 @@ sp_pcontext::find_pvar(LEX_STRING *name) while (i-- > 0) { - uint len= m_pvar[i].name->const_string()->length(); + uint len= (m_pvar[i].name.length > name->length ? + m_pvar[i].name.length : name->length); - if (name->length > len) - len= name->length; if (my_strncasecmp(system_charset_info, name->str, - m_pvar[i].name->const_string()->ptr(), + m_pvar[i].name.str, len) == 0) { return m_pvar + i; @@ -90,8 +89,8 @@ sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, { if (m_i == m_framesize) m_framesize += 1; - m_pvar[m_i].name= new Item_string(name->str, name->length, - default_charset_info); + m_pvar[m_i].name.str= name->str; + m_pvar[m_i].name.length= name->length, m_pvar[m_i].type= type; m_pvar[m_i].mode= mode; m_pvar[m_i].offset= m_i; diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 6ab38e77017..c5b0f1d410b 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -31,7 +31,7 @@ typedef enum typedef struct { - Item_string *name; + LEX_STRING name; enum enum_field_types type; sp_param_mode_t mode; uint offset; // Offset in current frame diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0fa05e13f9c..dbd8dc5ce8d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3101,6 +3101,15 @@ mysql_execute_command(THD *thd) send_ok(thd); break; case SP_KEY_NOT_FOUND: + if (lex->drop_if_exists) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), + SP_COM_STRING(lex), lex->udf.name.str); + res= 0; + send_ok(thd); + break; + } net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), lex->udf.name.str); goto error; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 43cfe94bdea..133f2e18ac6 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3699,17 +3699,19 @@ drop: lex->drop_if_exists=$3; lex->name=$4.str; } - | DROP FUNCTION_SYM IDENT_sys opt_restrict + | DROP FUNCTION_SYM if_exists IDENT_sys opt_restrict { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_FUNCTION; - lex->udf.name= $3; + lex->drop_if_exists= $3; + lex->udf.name= $4; } - | DROP PROCEDURE ident opt_restrict + | DROP PROCEDURE if_exists IDENT_sys opt_restrict { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_PROCEDURE; - lex->udf.name= $3; + lex->drop_if_exists= $3; + lex->udf.name= $4; } ; From 483efba2397d337d66636af637f1ae38988bed7e Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 26 Mar 2003 15:02:48 +0100 Subject: [PATCH 46/83] Fixed save/restore of current database when calling a procedure. --- Docs/sp-imp-spec.txt | 20 ++++++++++++++++++++ mysql-test/r/sp.result | 10 ++++++++++ mysql-test/t/sp.test | 12 ++++++++++++ sql/sp_head.cc | 15 +++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index 1303ae19c5c..385625464f1 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -243,6 +243,23 @@ 5) On success, set the new values of the OUT and INOUT parameters in the caller's frame. + - USE database + + Before executing the instruction we also keeps the current default + database (if any). If this was changed during execution (i.e. a "USE" + statement has been executed), we restore the current database to the + original. + + This is the most useful way to handle USE in procedures. If we didn't, + the caller would find himself in a different database after calling + a function, which can be confusing. + Restoring the database also gives full freedom to the procedure writer: + - It's possible to write "general" procedures that are independent of + the actual database name. + - It's possible to write procedures that work on a particular database + by calling USE, without having to use fully qualified table names + everywhere (which doesn't help if you want to call other, "general", + procedures anyway). - Evaluating Items @@ -340,6 +357,9 @@ Dropping is done by simply getting the procedure with the sp_find() function and calling sp_drop() (both in sp.{cc,h}). + DROP PROCEDURE/FUNCTION also supports the non-standard "IF EXISTS", + analogous to other DROP statements in MySQL. + - Class and function APIs diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index b188a6ed57d..3fe175b10c3 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -18,6 +18,16 @@ id data foo 42 delete from t1; drop procedure foo42; +create procedure u() +use sptmp; +create database sptmp; +use test; +call u(); +select database(); +database() +test +drop database sptmp; +drop procedure u; create procedure bar(x char(16), y int) insert into test.t1 values (x, y); call bar("bar", 666); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 0d6a84fa63b..3908561b6b0 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -31,6 +31,18 @@ delete from t1; drop procedure foo42; +# USE test: Make sure we remain in the same DB. +create procedure u() + use sptmp; + +create database sptmp; +use test; +call u(); +select database(); +drop database sptmp; +drop procedure u; + + # Single statement, two IN params. create procedure bar(x char(16), y int) insert into test.t1 values (x, y); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0a232ea5b4a..09c680a0b80 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -131,9 +131,14 @@ int sp_head::execute(THD *thd) { DBUG_ENTER("sp_head::execute"); + char *olddbname; + char *olddbptr= thd->db; int ret= 0; uint ip= 0; + if (olddbptr) + olddbname= my_strdup(olddbptr, MYF(MY_WME)); + do { sp_instr *i; @@ -144,6 +149,16 @@ sp_head::execute(THD *thd) DBUG_PRINT("execute", ("Instruction %u", ip)); ret= i->execute(thd, &ip); } while (ret == 0); + + /* If the DB has changed, the pointer has changed too, but the + original thd->db will then have been freed */ + if (olddbptr && olddbptr != thd->db && olddbname) + { + /* QQ Maybe we should issue some special error message or warning here, + if this fails?? */ + ret= mysql_change_db(thd, olddbname); + my_free(olddbname, MYF(0)); + } DBUG_RETURN(ret); } From ac44a5f66e0a0846e1a6146266bd54b11672e55a Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 27 Mar 2003 17:35:27 +0100 Subject: [PATCH 47/83] Replaced a couple of strcasecmps. --- sql/sp.cc | 2 +- sql/sp_head.cc | 4 ++-- sql/sp_pcontext.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 2bb714ab33a..abfb0f26e23 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -348,7 +348,7 @@ sp_cache_functions(THD *thd, LEX *lex) while ((sp= lisp++)) { - if (strcasecmp(fn, sp->name()) == 0) + if (my_strcasecmp(system_charset_info, fn, sp->name()) == 0) break; } if (sp) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 09c680a0b80..f15553c7e33 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -358,7 +358,7 @@ sp_head::restore_lex(THD *thd) char **it; while ((it= li++)) - if (strcasecmp(proc, *it) == 0) + if (my_strcasecmp(system_charset_info, proc, *it) == 0) break; if (! it) m_calls.push_back(&proc); @@ -380,7 +380,7 @@ sp_head::restore_lex(THD *thd) char **tb; while ((tb= li++)) - if (strcasecmp(tables->real_name, *tb) == 0) + if (my_strcasecmp(system_charset_info, tables->real_name, *tb) == 0) break; if (! tb) m_tables.push_back(&tables->real_name); diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 94eb8df4b95..d59db9b449b 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -120,7 +120,7 @@ sp_pcontext::find_label(char *name) sp_label_t *lab; while ((lab= li++)) - if (strcasecmp(name, lab->name) == 0) + if (my_strcasecmp(system_charset_info, name, lab->name) == 0) return lab; return NULL; From 9b6d015a850ce503ddb2bb0a81b680f74f59ddc9 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 27 Mar 2003 17:47:25 +0100 Subject: [PATCH 48/83] ...and got rid of the strncasecmps too. --- sql/sp.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index abfb0f26e23..5eb12c9fae5 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -306,7 +306,7 @@ sp_add_fun_to_lex(LEX *lex, LEX_STRING fun) while ((fn= li++)) { - if (strncasecmp(fn, fun.str, fun.length) == 0) + if (my_strncasecmp(system_charset_info, fn, fun.str, fun.length) == 0) break; } if (! fn) @@ -384,7 +384,7 @@ sp_find_cached_function(THD *thd, char *name, uint namelen) while ((sp= li++)) { - if (strncasecmp(name, sp->name(), namelen) == 0) + if (my_strncasecmp(system_charset_info, name, sp->name(), namelen) == 0) break; } return sp; From 017ba13005ab7e1fa9eba8ddff2539ddb9cf7442 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 28 Mar 2003 17:02:31 +0100 Subject: [PATCH 49/83] Check for thd->killed in execution loop. (Makes more graceful behaviour in certain interrupt cases.) --- sql/sp_head.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f15553c7e33..61cf3228760 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -136,6 +136,7 @@ sp_head::execute(THD *thd) int ret= 0; uint ip= 0; + LINT_INIT(olddbname); if (olddbptr) olddbname= my_strdup(olddbptr, MYF(MY_WME)); @@ -148,15 +149,19 @@ sp_head::execute(THD *thd) break; DBUG_PRINT("execute", ("Instruction %u", ip)); ret= i->execute(thd, &ip); - } while (ret == 0); + } while (ret == 0 && !thd->killed); + DBUG_PRINT("info", ("ret=%d killed=%d", ret, thd->killed)); + if (thd->killed) + ret= -1; /* If the DB has changed, the pointer has changed too, but the original thd->db will then have been freed */ if (olddbptr && olddbptr != thd->db && olddbname) { /* QQ Maybe we should issue some special error message or warning here, if this fails?? */ - ret= mysql_change_db(thd, olddbname); + if (! thd->killed) + ret= mysql_change_db(thd, olddbname); my_free(olddbname, MYF(0)); } DBUG_RETURN(ret); From aa479700fdad64e9748e2881cad5a03c7cdaa345 Mon Sep 17 00:00:00 2001 From: "pmartin@build.mysql2.com" <> Date: Fri, 28 Mar 2003 18:27:36 +0100 Subject: [PATCH 50/83] Renamed .del-makefile.w32 to .del-makefile3.w32 --- BitKeeper/etc/logging_ok | 1 + 1 file changed, 1 insertion(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index b00af7095d7..d4328f49e42 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -75,6 +75,7 @@ pem@mysql.com peter@linux.local peter@mysql.com pgulutzan@linux.local +pmartin@build.mysql2.com ram@gw.udmsearch.izhnet.ru ram@mysql.r18.ru ram@ram.(none) From 64552a658dd666f77ef57372526ca25a616dd829 Mon Sep 17 00:00:00 2001 From: "pem@per-erik-martins-dator.local" <> Date: Sun, 30 Mar 2003 13:25:43 +0200 Subject: [PATCH 51/83] Implemented DEFAULT for DECLARE variables. --- BitKeeper/etc/logging_ok | 1 + mysql-test/r/sp.result | 15 +++++---------- mysql-test/t/sp.test | 16 ++++++---------- sql/sql_yacc.yy | 24 ++++++++++++++++++++---- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index d4328f49e42..3fafa15cece 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -72,6 +72,7 @@ papa@gbichot.local paul@central.snake.net paul@teton.kitebird.com pem@mysql.com +pem@per-erik-martins-dator.local peter@linux.local peter@mysql.com pgulutzan@linux.local diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 3fe175b10c3..4833b152f07 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -117,8 +117,7 @@ drop procedure inc2; drop procedure inc; create procedure cbv1() begin -declare y int; -set y = 3; +declare y int default 3; call cbv2(y+1, y); insert into test.t1 values ("cbv1", y); end; @@ -354,8 +353,7 @@ append("foo", "bar") foobar create function fac(n int unsigned) returns bigint unsigned begin -declare f bigint unsigned; -set f = 1; +declare f bigint unsigned default 1; while n > 1 do set f = f * n; set n = n - 1; @@ -396,8 +394,7 @@ drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) begin -declare i int unsigned; -set i = 1; +declare i int unsigned default 1; if n > 20 then set n = 20; # bigint overflow otherwise end if; @@ -452,8 +449,7 @@ insert into primes values create procedure opp(n bigint unsigned, out pp bool) begin declare r double; -declare b, s bigint unsigned; -set b = 0, s = 0; +declare b, s bigint unsigned default 0; set r = sqrt(n); again: loop @@ -483,8 +479,7 @@ declare i int unsigned; set i=45, p=201; while i < m do begin -declare pp bool; -set pp = 0; +declare pp bool default 0; call opp(p, pp); if pp then insert into test.primes values (i, p); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 3908561b6b0..95b3e4732a9 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -153,9 +153,8 @@ drop procedure inc| # ("cbv1", 4711) create procedure cbv1() begin - declare y int; + declare y int default 3; - set y = 3; call cbv2(y+1, y); insert into test.t1 values ("cbv1", y); end| @@ -428,9 +427,8 @@ select append("foo", "bar")| # A function with flow control create function fac(n int unsigned) returns bigint unsigned begin - declare f bigint unsigned; + declare f bigint unsigned default 1; - set f = 1; while n > 1 do set f = f * n; set n = n - 1; @@ -479,8 +477,8 @@ create table fac (n int unsigned not null primary key, f bigint unsigned)| create procedure ifac(n int unsigned) begin - declare i int unsigned; - set i = 1; + declare i int unsigned default 1; + if n > 20 then set n = 20; # bigint overflow otherwise end if; @@ -524,9 +522,8 @@ insert into primes values create procedure opp(n bigint unsigned, out pp bool) begin declare r double; - declare b, s bigint unsigned; + declare b, s bigint unsigned default 0; - set b = 0, s = 0; set r = sqrt(n); again: @@ -561,9 +558,8 @@ begin while i < m do begin - declare pp bool; + declare pp bool default 0; - set pp = 0; call opp(p, pp); if pp then insert into test.primes values (i, p); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8aecb62f51c..3ff214272a1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -622,7 +622,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr using_list expr_or_default set_expr_or_default interval_expr param_marker singlerow_subselect singlerow_subselect_init - exists_subselect exists_subselect_init + exists_subselect exists_subselect_init sp_opt_default %type expr_list udf_expr_list when_list ident_list ident_list_arg @@ -1082,15 +1082,26 @@ sp_decls: ; sp_decl: - DECLARE_SYM sp_decl_idents type + DECLARE_SYM sp_decl_idents type sp_opt_default { LEX *lex= Lex; uint max= lex->spcont->current_framesize(); + enum enum_field_types type= (enum enum_field_types)$3; + Item *it= $4; for (uint i = max-$2 ; i < max ; i++) { - lex->spcont->set_type(i, (enum enum_field_types)$3); - lex->spcont->set_isset(i, FALSE); + lex->spcont->set_type(i, type); + if (! it) + lex->spcont->set_isset(i, FALSE); + else + { + sp_instr_set *in= new sp_instr_set(lex->sphead->instructions(), + i, it, type); + + lex->sphead->add_instr(in); + lex->spcont->set_isset(i, TRUE); + } } $$= $2; } @@ -1109,6 +1120,11 @@ sp_decl_idents: } ; +sp_opt_default: + /* Empty */ { $$ = NULL; } + | DEFAULT expr { $$ = $2; } + ; + sp_proc_stmt: { Lex->sphead->reset_lex(YYTHD); From f8f0b703808f19b788b57c8c35c9aa0147b48b7f Mon Sep 17 00:00:00 2001 From: "hf@genie.(none)" <> Date: Mon, 31 Mar 2003 13:39:46 +0500 Subject: [PATCH 52/83] SCRUM two KILL commands implementation (version 2) --- include/mysqld_error.h | 3 ++- myisam/mi_check.c | 2 +- myisam/myisamchk.c | 4 ++-- myisam/myisamdef.h | 2 +- myisam/sort.c | 5 +++-- sql/filesort.cc | 8 ++++---- sql/ha_berkeley.cc | 2 +- sql/ha_myisam.cc | 4 ++-- sql/lock.cc | 2 +- sql/log_event.cc | 2 +- sql/mysqld.cc | 6 +++--- sql/records.cc | 2 +- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/slave.cc | 2 +- sql/sql_base.cc | 2 +- sql/sql_cache.cc | 2 +- sql/sql_class.cc | 15 ++++++++------- sql/sql_class.h | 8 +++++--- sql/sql_delete.cc | 2 +- sql/sql_insert.cc | 16 ++++++++-------- sql/sql_load.cc | 4 ++-- sql/sql_parse.cc | 21 ++++++--------------- sql/sql_prepare.cc | 2 +- sql/sql_repl.cc | 2 +- sql/sql_repl.h | 2 +- sql/sql_select.cc | 18 +++++++++--------- sql/sql_show.cc | 2 +- sql/sql_table.cc | 2 +- sql/sql_update.cc | 2 +- 51 files changed, 93 insertions(+), 74 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 70e9a70ea9d..056de3f29c7 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -282,4 +282,5 @@ #define ER_SP_BADSELECT 1263 #define ER_SP_BADRETURN 1264 #define ER_SP_BADQUERY 1265 -#define ER_ERROR_MESSAGES 266 +#define ER_QUERY_INTERRUPTED 1266 +#define ER_ERROR_MESSAGES 267 diff --git a/myisam/mi_check.c b/myisam/mi_check.c index d0e9d17a43b..7ae61bb7275 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -2585,7 +2585,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) char llbuff[22],llbuff2[22]; DBUG_ENTER("sort_get_next_record"); - if (*killed_ptr(param)) + if (killed_ptr(param->thd)) DBUG_RETURN(1); switch (share->data_file_type) { diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 104b344a9e2..d816cd3f2a2 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -1644,9 +1644,9 @@ err: DBUG_RETURN(1); } /* sort_record_index */ -volatile bool *killed_ptr(MI_CHECK *param) +bool killed_ptr(void *thd) { - return (bool *)(& param->thd); /* always NULL */ + return (bool)thd; /* always NULL */ } /* print warnings and errors */ diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 25f2969a973..b2d6807ad73 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -693,7 +693,7 @@ int mi_open_keyfile(MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share); /* Functions needed by mi_check */ -volatile bool *killed_ptr(MI_CHECK *param); +bool killed_ptr(void *thd); void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...)); diff --git a/myisam/sort.c b/myisam/sort.c index 006b96cfaab..1913af650c0 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -844,7 +844,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, uchar *strpos; BUFFPEK *buffpek,**refpek; QUEUE queue; - volatile bool *killed= killed_ptr(info->sort_info->param); + void *thd= info->sort_info->param->thd; + DBUG_ENTER("merge_buffers"); count=error=0; @@ -875,7 +876,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, { for (;;) { - if (*killed) + if (killed_ptr(thd)) { error=1; goto err; } diff --git a/sql/filesort.cc b/sql/filesort.cc index cc7b15f1f4a..7e4e9687860 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -277,7 +277,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, byte *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH]; my_off_t record; TABLE *sort_form; - volatile bool *killed= ¤t_thd->killed; + volatile THD::killed_state *killed= ¤t_thd->killed; handler *file; DBUG_ENTER("find_all_keys"); DBUG_PRINT("info",("using: %s",(select?select->quick?"ranges":"where":"every row"))); @@ -690,15 +690,15 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, BUFFPEK *buffpek,**refpek; QUEUE queue; qsort2_cmp cmp; - volatile bool *killed= ¤t_thd->killed; - bool not_killable; + volatile THD::killed_state *killed= ¤t_thd->killed; + THD::killed_state not_killable; DBUG_ENTER("merge_buffers"); statistic_increment(filesort_merge_passes, &LOCK_status); if (param->not_killable) { killed= ¬_killable; - not_killable=0; + not_killable=THD::NOT_KILLED; } error=0; diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index dbed955c0a9..9057e21d4c2 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -2103,7 +2103,7 @@ static void print_msg(THD *thd, const char *table_name, const char *op_name, protocol->store(msg_type); protocol->store(msgbuf); if (protocol->write()) - thd->killed=1; + thd->killed=THD::KILL_CONNECTION; } #endif diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 26268f5deaf..7b3e3f6b942 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -89,9 +89,9 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, extern "C" { -volatile bool *killed_ptr(MI_CHECK *param) +bool killed_ptr(void *thd) { - return &(((THD *)(param->thd))->killed); + return ((THD *)thd)->killed; } void mi_check_print_error(MI_CHECK *param, const char *fmt,...) diff --git a/sql/lock.cc b/sql/lock.cc index 8f342b28d67..d2ad47cbbfa 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -154,7 +154,7 @@ retry: thd->proc_info=0; if (thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_error(thd->killed, MYF(0)); if (sql_lock) { mysql_unlock_tables(thd,sql_lock); diff --git a/sql/log_event.cc b/sql/log_event.cc index 3a1dbb6485e..7cb7310cfdd 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -770,7 +770,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), data_buf(0), query(query_arg), db(thd_arg->db), q_len((uint32) query_length), - error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno), + error_code((int)thd_arg->killed ? (int)thd_arg->killed : thd_arg->net.last_errno), thread_id(thd_arg->thread_id) { time_t end_time; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7f9c39e7e8f..16187fd044b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -632,7 +632,7 @@ static void close_connections(void) { DBUG_PRINT("quit",("Informing thread %ld that it's time to die", tmp->thread_id)); - tmp->killed=1; + tmp->killed= THD::KILL_CONNECTION; if (tmp->mysys_var) { tmp->mysys_var->abort=1; @@ -1393,7 +1393,7 @@ extern "C" sig_handler abort_thread(int sig __attribute__((unused))) THD *thd=current_thd; DBUG_ENTER("abort_thread"); if (thd) - thd->killed=1; + thd->killed= THD::KILL_CONNECTION; DBUG_VOID_RETURN; } #endif @@ -2802,7 +2802,7 @@ static void create_new_thread(THD *thd) ("Can't create thread to handle request (error %d)", error)); thread_count--; - thd->killed=1; // Safety + thd->killed= THD::KILL_CONNECTION; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); net_printf(thd,ER_CANT_CREATE_THREAD,error); (void) pthread_mutex_lock(&LOCK_thread_count); diff --git a/sql/records.cc b/sql/records.cc index 22c4d54550c..38904fa405f 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -154,7 +154,7 @@ static int rr_sequential(READ_RECORD *info) { if (info->thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_error(info->thd->killed,MYF(0)); return 1; } if (tmp != HA_ERR_RECORD_DELETED) diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 4d93ecf7db3..50fe3a70436 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -276,3 +276,4 @@ v/* "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index c5cf27a94d7..beed74938a2 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -270,3 +270,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 6105d619ec0..e7d895426a8 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -278,3 +278,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index bcd96916516..7e6adec8374 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -267,3 +267,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 6f90684dcfe..ff545578756 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -272,3 +272,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 56065154b38..cb3de886601 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -267,3 +267,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index b1b6e695fb1..1c959902678 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -277,3 +277,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index bad888430ef..65df4417f3f 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -267,3 +267,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 1ee7d95bebe..f14f27728e9 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -269,3 +269,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index dcacb064356..d9eff4aa546 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -267,3 +267,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index bb928217a6d..158092ef605 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -269,3 +269,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 0f6f4f95fa9..5b9e18c2113 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -267,3 +267,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 4ece1312243..b14d8f5bbca 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -269,3 +269,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 9b2165909aa..40cfe267908 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -269,3 +269,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 2d988a62860..9e4e82640e5 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -271,3 +271,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 24cc385b1ed..04b643de0ba 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -267,3 +267,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 4ab6c04d67b..fc9510022b9 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -271,3 +271,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index befadcf02df..3c6d81667b2 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -270,3 +270,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 402f4b94f70..d0fdcfd1fff 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -263,3 +263,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 5e0cf29c734..1fc8bc65b37 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -275,3 +275,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index e26ca91bd8d..cea2db1f19d 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -268,3 +268,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index e7142c65066..00327211a5b 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -267,3 +267,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 242c1bef664..d3e19d5761c 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -272,3 +272,4 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"Query execution was interrupted" diff --git a/sql/slave.cc b/sql/slave.cc index b06895b1779..787201841f7 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -543,7 +543,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock, if (thd->killed) { pthread_mutex_unlock(cond_lock); - DBUG_RETURN(ER_SERVER_SHUTDOWN); + DBUG_RETURN(thd->killed); } } } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 79f0e7eb269..8ef85f77008 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2390,7 +2390,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, /* Kill delayed insert threads */ if (in_use->system_thread && ! in_use->killed) { - in_use->killed=1; + in_use->killed= THD::KILL_CONNECTION; pthread_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 90fd61ebeb7..cbd6e008586 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2929,7 +2929,7 @@ void Query_cache::wreck(uint line, const char *message) DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line)); DBUG_PRINT("warning", ("==================================")); if (thd) - thd->killed = 1; + thd->killed= THD::KILL_CONNECTION; cache_dump(); /* check_integrity(0); */ /* Can't call it here because of locks */ bins_dump(); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cf790012c37..7058b9d7b3c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -85,8 +85,9 @@ THD::THD():user_time(0), is_fatal_error(0), { host=user=priv_user=db=query=ip=0; host_or_ip= "connecting host"; - locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password= + locked=count_cuted_fields=some_tables_deleted=no_errors=password= query_start_used=prepare_command=0; + killed= NOT_KILLED; db_length=query_length=col_access=0; query_error= tmp_table_used= 0; next_insert_id=last_insert_id=0; @@ -176,7 +177,7 @@ THD::THD():user_time(0), is_fatal_error(0), if (open_cached_file(&transaction.trans_log, mysql_tmpdir, LOG_PREFIX, binlog_cache_size, MYF(MY_WME))) - killed=1; + killed= KILL_CONNECTION; transaction.trans_log.end_of_file= max_binlog_cache_size; } #endif @@ -318,14 +319,14 @@ THD::~THD() } -void THD::awake(bool prepare_to_die) +void THD::awake(THD::killed_state state_to_set) { THD_CHECK_SENTRY(this); safe_mutex_assert_owner(&LOCK_delete); - if (prepare_to_die) - killed = 1; - thr_alarm_kill(real_id); + killed= state_to_set; + if (state_to_set != THD::KILL_QUERY) + thr_alarm_kill(real_id); #ifdef SIGNAL_WITH_VIO_CLOSE close_active_vio(); #endif @@ -442,7 +443,7 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) { my_error(EE_OUTOFMEMORY, MYF(ME_BELL), ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); - killed= 1; + killed= KILL_CONNECTION; return 0; } diff --git a/sql/sql_class.h b/sql/sql_class.h index f1817876fc3..1e293fd0323 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -548,8 +548,10 @@ public: bool query_start_used,last_insert_id_used,insert_id_used,rand_used; bool system_thread,in_lock_tables,global_read_lock; bool query_error, bootstrap, cleanup_done; - bool volatile killed; - bool volatile only_kill_query; + + enum killed_state { NOT_KILLED=0, KILL_CONNECTION=ER_SERVER_SHUTDOWN, KILL_QUERY=ER_QUERY_INTERRUPTED }; + killed_state volatile killed; + bool prepare_command; bool tmp_table_used; sp_rcontext *spcont; // SP runtime context @@ -592,7 +594,7 @@ public: } void close_active_vio(); #endif - void awake(bool prepare_to_die); + void awake(THD::killed_state state_to_set); inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg) { diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 05f84616a4c..921854469a5 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -212,7 +212,7 @@ cleanup: delete select; free_underlaid_joins(thd, &thd->lex.select_lex); if (error >= 0 || thd->net.report_error) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0); + send_error(thd,thd->killed); else { send_ok(thd,deleted); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9ca51ebc053..aee545b5bbb 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -935,7 +935,7 @@ void kill_delayed_threads(void) { /* Ensure that the thread doesn't kill itself while we are looking at it */ pthread_mutex_lock(&tmp->mutex); - tmp->thd.killed=1; + tmp->thd.killed= THD::KILL_CONNECTION; if (tmp->thd.mysys_var) { pthread_mutex_lock(&tmp->thd.mysys_var->mutex); @@ -974,7 +974,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) thd->thread_id=thread_id++; thd->end_time(); threads.append(thd); - thd->killed=abort_loop; + thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_lock(&di->mutex); @@ -1027,7 +1027,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) for (;;) { - if (thd->killed) + if (thd->killed == THD::KILL_CONNECTION) { uint lock_count; /* @@ -1075,7 +1075,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) break; if (error == ETIME || error == ETIMEDOUT) { - thd->killed=1; + thd->killed= THD::KILL_CONNECTION; break; } } @@ -1094,7 +1094,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) /* request for new delayed insert */ if (!(thd->lock=mysql_lock_tables(thd,&di->table,1))) { - di->dead=thd->killed=1; // Fatal error + di->dead=thd->killed= THD::KILL_CONNECTION; // Fatal error } pthread_cond_broadcast(&di->cond_client); } @@ -1102,7 +1102,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) { if (di->handle_inserts()) { - di->dead=thd->killed=1; // Some fatal error + di->dead=thd->killed=THD::KILL_CONNECTION; // Some fatal error } } di->status=0; @@ -1129,7 +1129,7 @@ end: close_thread_tables(thd); // Free the table di->table=0; - di->dead=thd->killed=1; // If error + di->dead=thd->killed= THD::KILL_CONNECTION; // If error pthread_cond_broadcast(&di->cond_client); // Safety pthread_mutex_unlock(&di->mutex); @@ -1198,7 +1198,7 @@ bool delayed_insert::handle_inserts(void) max_rows=delayed_insert_limit; if (thd.killed || table->version != refresh_version) { - thd.killed=1; + thd.killed= THD::KILL_CONNECTION; max_rows= ~0; // Do as much as possible } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4f5b19e6f49..69585ddbc77 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -379,7 +379,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List &fields, { if (thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_error(thd->killed,MYF(0)); DBUG_RETURN(1); } it.rewind(); @@ -453,7 +453,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, { if (thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_error(thd->killed,MYF(0)); DBUG_RETURN(1); } while ((sql_field=(Item_field*) it++)) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 278b7b92574..d99a3d4bbea 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -848,7 +848,7 @@ pthread_handler_decl(handle_one_connection,arg) init_sql_alloc(&thd->mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); init_sql_alloc(&thd->transaction.mem_root, TRANS_MEM_ROOT_BLOCK_SIZE, TRANS_MEM_ROOT_PREALLOC); - while (!net->error && net->vio != 0 && !(thd->killed && !thd->only_kill_query)) + while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION)) { if (do_command(thd)) break; @@ -1054,11 +1054,8 @@ bool do_command(THD *thd) } else { - if (thd->only_kill_query) - { - thd->killed= FALSE; - thd->only_kill_query= FALSE; - } + if (thd->killed == THD::KILL_QUERY) + thd->killed= THD::NOT_KILLED; packet=(char*) net->read_pos; command = (enum enum_server_command) (uchar) packet[0]; @@ -1666,7 +1663,7 @@ mysql_execute_command(THD *thd) cursor))) { if (res < 0 || thd->net.report_error) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + send_error(thd,thd->killed); DBUG_RETURN(res); } } @@ -3126,7 +3123,7 @@ mysql_execute_command(THD *thd) // We end up here if res == 0 and send_ok() has been done, // or res != 0 and no send_error() has yet been done. if (res < 0) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + send_error(thd,thd->killed); DBUG_RETURN(res); error: @@ -4221,13 +4218,7 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) if ((thd->master_access & SUPER_ACL) || !strcmp(thd->user,tmp->user)) { - if (only_kill_query) - { - tmp->killed= 1; - tmp->only_kill_query= 1; - } - else - tmp->awake(1 /*prepare to die*/); + tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION); error=0; } else diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index fc8959c6493..cc762f28fd8 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -675,7 +675,7 @@ static bool send_prepare_results(PREP_STMT *stmt) DBUG_RETURN(0); abort: - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + send_error(thd,thd->killed); DBUG_RETURN(1); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index fd6c9060079..12d110ac35b 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -826,7 +826,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id) it will be slow because it will iterate through the list again. We just to do kill the thread ourselves. */ - tmp->awake(1/*prepare to die*/); + tmp->awake(THD::KILL_QUERY); pthread_mutex_unlock(&tmp->LOCK_delete); } } diff --git a/sql/sql_repl.h b/sql/sql_repl.h index e3d600b9798..cf5d2387ca5 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -20,7 +20,7 @@ extern I_List binlog_do_db, binlog_ignore_db; extern int max_binlog_dump_events; extern my_bool opt_sporadic_binlog_dump_fail; -#define KICK_SLAVE(thd) { pthread_mutex_lock(&(thd)->LOCK_delete); (thd)->awake(0 /* do not prepare to die*/); pthread_mutex_unlock(&(thd)->LOCK_delete); } +#define KICK_SLAVE(thd) { pthread_mutex_lock(&(thd)->LOCK_delete); (thd)->awake(THD::NOT_KILLED); pthread_mutex_unlock(&(thd)->LOCK_delete); } File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0192d9f7ab2..ad2a66da573 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4943,7 +4943,7 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) } if (join->thd->killed) // If aborted by user { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */ + my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ return -2; /* purecov: inspected */ } if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0) @@ -4982,7 +4982,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) { if (join->thd->killed) // Aborted by user { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */ + my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ return -2; /* purecov: inspected */ } join->examined_rows++; @@ -5062,7 +5062,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skipp_last) { if (join->thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */ + my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ return -2; // Aborted by user /* purecov: inspected */ } SQL_SELECT *select=join_tab->select; @@ -5710,7 +5710,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->thd->killed) // Aborted by user { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */ + my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ DBUG_RETURN(-2); /* purecov: inspected */ } if (!end_of_records) @@ -5778,7 +5778,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(0); if (join->thd->killed) // Aborted by user { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */ + my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ DBUG_RETURN(-2); /* purecov: inspected */ } @@ -5848,7 +5848,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(0); if (join->thd->killed) // Aborted by user { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */ + my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ DBUG_RETURN(-2); /* purecov: inspected */ } @@ -5895,7 +5895,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->thd->killed) { // Aborted by user - my_error(ER_SERVER_SHUTDOWN,MYF(0)); /* purecov: inspected */ + my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ DBUG_RETURN(-2); /* purecov: inspected */ } if (!join->first_record || end_of_records || @@ -6617,7 +6617,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, { if (thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_error(thd->killed,MYF(0)); error=0; goto err; } @@ -6729,7 +6729,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, { if (thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_error(thd->killed,MYF(0)); error=0; goto err; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 00df2c44fd6..80749afb533 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1335,7 +1335,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) thd_info->command=(int) tmp->command; if ((mysys_var= tmp->mysys_var)) pthread_mutex_lock(&mysys_var->mutex); - thd_info->proc_info= (char*) (tmp->killed ? "Killed" : 0); + thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0); #ifndef EMBEDDED_LIBRARY thd_info->state_info= (char*) (tmp->locked ? "Locked" : tmp->net.reading_or_writing ? diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0033451a439..bba82dd5bbc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2379,7 +2379,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, { if (thd->killed) { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_error(thd->killed,MYF(0)); error= 1; break; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 95128b2db3d..95db54944cd 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -355,7 +355,7 @@ int mysql_update(THD *thd, delete select; free_underlaid_joins(thd, &thd->lex.select_lex); if (error >= 0) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */ + send_error(thd,thd->killed); /* purecov: inspected */ else { char buff[80]; From 654410a3d3d1d5d2bfe4be60ab8f1fbcfa211d19 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Wed, 2 Apr 2003 00:15:20 +0200 Subject: [PATCH 53/83] Deprecated the update log (Sprint task #792). Now --log-update just turns on --log-bin and prints a warning. SQL_LOG_UPDATE is handled in two ways (see mysqld.cc for comments). --- include/mysqld_error.h | 4 +- sql/log.cc | 13 ++----- sql/mysqld.cc | 65 ++++++++++++++++++++++++++----- sql/set_var.cc | 28 ++++++++++++- sql/share/czech/errmsg.txt | 2 + sql/share/danish/errmsg.txt | 2 + sql/share/dutch/errmsg.txt | 2 + sql/share/english/errmsg.txt | 2 + sql/share/estonian/errmsg.txt | 2 + sql/share/french/errmsg.txt | 2 + sql/share/german/errmsg.txt | 2 + sql/share/greek/errmsg.txt | 2 + sql/share/hungarian/errmsg.txt | 2 + sql/share/italian/errmsg.txt | 2 + sql/share/japanese/errmsg.txt | 2 + sql/share/korean/errmsg.txt | 2 + sql/share/norwegian-ny/errmsg.txt | 2 + sql/share/norwegian/errmsg.txt | 2 + sql/share/polish/errmsg.txt | 2 + sql/share/portuguese/errmsg.txt | 2 + sql/share/romanian/errmsg.txt | 2 + sql/share/russian/errmsg.txt | 2 + sql/share/serbian/errmsg.txt | 2 + sql/share/slovak/errmsg.txt | 2 + sql/share/spanish/errmsg.txt | 2 + sql/share/swedish/errmsg.txt | 2 + sql/share/ukrainian/errmsg.txt | 2 + sql/sql_acl.cc | 1 - sql/sql_db.cc | 3 -- sql/sql_delete.cc | 3 -- sql/sql_insert.cc | 36 ++++------------- sql/sql_load.cc | 3 -- sql/sql_parse.cc | 13 ++----- sql/sql_rename.cc | 1 - sql/sql_table.cc | 31 +++++---------- sql/sql_update.cc | 2 - 36 files changed, 157 insertions(+), 92 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 70e9a70ea9d..3a7a42e7c0c 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -282,4 +282,6 @@ #define ER_SP_BADSELECT 1263 #define ER_SP_BADRETURN 1264 #define ER_SP_BADQUERY 1265 -#define ER_ERROR_MESSAGES 266 +#define ER_UPDATE_LOG_DEPRECATED_IGNORED 1266 +#define ER_UPDATE_LOG_DEPRECATED_TRANSLATED 1267 +#define ER_ERROR_MESSAGES 268 diff --git a/sql/log.cc b/sql/log.cc index cd4c2a38ac8..74afcef3ac5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -30,7 +30,7 @@ #include #include // For test_if_number -MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; +MYSQL_LOG mysql_log, mysql_slow_log, mysql_bin_log; extern I_List binlog_do_db, binlog_ignore_db; static bool test_if_number(const char *str, @@ -1020,7 +1020,7 @@ err: /* Write to normal (not rotable) log - This is the format for the 'normal', 'slow' and 'update' logs. + This is the format for the 'normal' log. */ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, @@ -1392,8 +1392,7 @@ err: /* - Write update log in a format suitable for incremental backup - This is also used by the slow query log. + Write to the slow query log. */ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, @@ -1409,12 +1408,6 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, int tmp_errno=0; char buff[80],*end; end=buff; - if (!(thd->options & OPTION_UPDATE_LOG) && - (thd->master_access & SUPER_ACL)) - { - VOID(pthread_mutex_unlock(&LOCK_log)); - return 0; - } if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start_arg) { current_time=time(NULL); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ac3703c5a1d..da476097a33 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -22,6 +22,7 @@ #include "sql_repl.h" #include "repl_failsafe.h" #include "stacktrace.h" +#include "mysys_err.h" #ifdef HAVE_BERKELEY_DB #include "ha_berkeley.h" #endif @@ -345,7 +346,7 @@ uint mysql_port; uint test_flags = 0, select_errors=0, dropping_tables=0,ha_open_options=0; uint volatile thread_count=0, thread_running=0, kill_cached_threads=0, wake_thread=0; -ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL | +ulong thd_startup_options=(OPTION_AUTO_IS_NULL | OPTION_BIN_LOG | OPTION_QUOTE_SHOW_CREATE ); uint protocol_version=PROTOCOL_VERSION; struct system_variables global_system_variables; @@ -911,7 +912,6 @@ void clean_up(bool print_message) mysql_log.cleanup(); mysql_slow_log.cleanup(); - mysql_update_log.cleanup(); mysql_bin_log.cleanup(); #ifdef HAVE_REPLICATION @@ -2177,9 +2177,55 @@ static int init_server_components() LOG_NORMAL); if (opt_update_log) { - open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - NullS, LOG_NEW); - using_update_log=1; + /* + Update log is removed since 5.0. But we still accept the option. + The idea is if the user already uses the binlog and the update log, + we completely ignore any option/variable related to the update log, like + if the update log did not exist. But if the user uses only the update log, + then we translate everything into binlog for him (with warnings). + Implementation of the above : + - If mysqld is started with --log-update and --log-bin, + ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE + is used, and turn off --sql-bin-update-same. + This will completely ignore SQL_LOG_UPDATE + - If mysqld is started with --log-update only, + change it to --log-bin (with the filename passed to log-update, + plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is + used, and turn on --sql-bin-update-same. + This will translate SQL_LOG_UPDATE to SQL_LOG_BIN. + + Note that we tell the user that --sql-bin-update-same is deprecated and + does nothing, and we don't take into account if he used this option or + not; but internally we give this variable a value to have the behaviour we + want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not). + As sql-bin-update-same, log-update and log-bin cannot be changed by the user + after starting the server (they are not variables), the user will not + later interfere with the settings we do here. + */ + if (opt_bin_log) + { + opt_sql_bin_update= 0; + sql_print_error("The update log is no longer supported by MySQL in \ +version 5.0 and above. It is replaced by the binary log."); + } + else + { + opt_sql_bin_update= 1; + opt_bin_log= 1; + if (opt_update_logname) + { + // as opt_bin_log==0, no need to free opt_bin_logname + if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME)))) + exit(EXIT_OUT_OF_MEMORY); + sql_print_error("The update log is no longer supported by MySQL in \ +version 5.0 and above. It is replaced by the binary log. Now starting MySQL \ +with --log-bin='%s' instead.",opt_bin_logname); + } + else + sql_print_error("The update log is no longer supported by MySQL in \ +version 5.0 and above. It is replaced by the binary log. Now starting MySQL \ +with --log-bin instead."); + } } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", @@ -3659,7 +3705,8 @@ struct my_option my_long_options[] = (gptr*) &myisam_log_filename, (gptr*) &myisam_log_filename, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-update", OPT_UPDATE_LOG, - "Log updates to file.# where # is a unique number if not given.", + "The update log is deprecated since version 5.0, is replaced by the binary \ +log and this option justs turns on --log-bin instead.", (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-slow-queries", OPT_SLOW_QUERY_LOG, @@ -3910,9 +3957,9 @@ struct my_option my_long_options[] = (gptr*) &mysql_unix_port, (gptr*) &mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME, - "If set, setting SQL_LOG_BIN to a value will automatically set SQL_LOG_UPDATE to the same value and vice versa.", - (gptr*) &opt_sql_bin_update, (gptr*) &opt_sql_bin_update, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, + "The update log is deprecated since version 5.0, is replaced by the binary \ +log and this option does nothing anymore.", + 0, 0, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"sql-mode", OPT_SQL_MODE, "Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.", (gptr*) &sql_mode_str, (gptr*) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0, diff --git a/sql/set_var.cc b/sql/set_var.cc index c4a4819689c..5e5d9e8ac7f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -78,6 +78,7 @@ static void sys_set_default_charset(THD *thd, enum_var_type type); static bool set_option_bit(THD *thd, set_var *var); static bool set_option_autocommit(THD *thd, set_var *var); static bool set_log_update(THD *thd, set_var *var); +static bool set_log_bin(THD *thd, set_var *var); static void fix_low_priority_updates(THD *thd, enum_var_type type); static void fix_tx_isolation(THD *thd, enum_var_type type); static void fix_net_read_timeout(THD *thd, enum_var_type type); @@ -265,7 +266,7 @@ static sys_var_thd_bit sys_log_update("sql_log_update", set_log_update, OPTION_UPDATE_LOG); static sys_var_thd_bit sys_log_binlog("sql_log_bin", - set_log_update, + set_log_bin, OPTION_BIN_LOG); static sys_var_thd_bit sys_sql_warnings("sql_warnings", set_option_bit, @@ -1363,6 +1364,30 @@ static bool set_option_autocommit(THD *thd, set_var *var) static bool set_log_update(THD *thd, set_var *var) +{ + /* + The update log is not supported anymore since 5.0. + See sql/mysqld.cc/, comments in function init_server_components() for an + explaination of the different warnings we send below + */ + + if (opt_sql_bin_update) + { + ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG | + OPTION_UPDATE_LOG); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_UPDATE_LOG_DEPRECATED_TRANSLATED, + ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED)); + } + else + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_UPDATE_LOG_DEPRECATED_IGNORED, + ER(ER_UPDATE_LOG_DEPRECATED_IGNORED)); + set_option_bit(thd, var); + return 0; +} + +static bool set_log_bin(THD *thd, set_var *var) { if (opt_sql_bin_update) ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG | @@ -1371,6 +1396,7 @@ static bool set_log_update(THD *thd, set_var *var) return 0; } + static byte *get_warning_count(THD *thd) { thd->sys_var_tmp.long_value= diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 4d93ecf7db3..95abb868f95 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -276,3 +276,5 @@ v/* "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index c5cf27a94d7..71740270274 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -270,3 +270,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 6105d619ec0..53cf3736f68 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -278,3 +278,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index bcd96916516..079d445039b 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -267,3 +267,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 6f90684dcfe..a6a0941625c 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -272,3 +272,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 56065154b38..57f164caac9 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -267,3 +267,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index b1b6e695fb1..9367f1942e0 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -277,3 +277,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index bad888430ef..d2394428d1c 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -267,3 +267,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 1ee7d95bebe..e08c886dec6 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -269,3 +269,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index dcacb064356..d2122d86405 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -267,3 +267,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index bb928217a6d..00d03a7c192 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -269,3 +269,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 0f6f4f95fa9..58df04f1f62 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -267,3 +267,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 4ece1312243..c5246746ae2 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -269,3 +269,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 9b2165909aa..138f0df1f2c 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -269,3 +269,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index ed02910549a..781402b4911 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -271,3 +271,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 24cc385b1ed..53ef6f8946c 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -267,3 +267,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 4ab6c04d67b..1f8628dfb04 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -271,3 +271,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index e136e2d4e35..63e7f69df74 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -269,3 +269,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 402f4b94f70..0388b71405d 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -263,3 +263,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 5e0cf29c734..2b40b206089 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -275,3 +275,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index e26ca91bd8d..34cd0768f1c 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -268,3 +268,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index d2c099d38d0..51ae086d553 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -267,3 +267,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 242c1bef664..91066f8836c 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -272,3 +272,5 @@ "SELECT in a stored procedure must have INTO" "RETURN is only allowed in a FUNCTION" "Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION" +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." +"The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5f8f71e1bd4..3165cb7bcf8 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1161,7 +1161,6 @@ bool change_password(THD *thd, const char *host, const char *user, acl_user->user ? acl_user->user : "", acl_user->host.hostname ? acl_user->host.hostname : "", new_password)); - mysql_update_log.write(thd, buff, query_length); Query_log_event qinfo(thd, buff, query_length, 0); mysql_bin_log.write(&qinfo); DBUG_RETURN(0); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index ffa5416eaf5..27d50a25fd9 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -231,7 +231,6 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, query= thd->query; query_length= thd->query_length; } - mysql_update_log.write(thd, query, query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, query, query_length, 0); @@ -283,7 +282,6 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) create_info->table_charset : default_charset_info; } - mysql_update_log.write(thd,thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); @@ -369,7 +367,6 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) query=thd->query; query_length=thd->query_length; } - mysql_update_log.write(thd, query, query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, query, query_length, 0); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 05f84616a4c..e13e51e0171 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -179,7 +179,6 @@ cleanup: log_delayed= (transactional_table || table->tmp_table); if (deleted && (error <= 0 || !transactional_table)) { - mysql_update_log.write(thd,thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, @@ -486,7 +485,6 @@ bool multi_delete::send_eof() */ if (deleted && (error <= 0 || normal_tables)) { - mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, @@ -601,7 +599,6 @@ end: { if (!error) { - mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index dcb39f8526f..97e7e1a5d7f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -23,7 +23,7 @@ static int check_null_fields(THD *thd,TABLE *entry); static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list); static int write_delayed(THD *thd,TABLE *table, enum_duplicates dup, - char *query, uint query_length, int log_on); + char *query, uint query_length, bool log_on); static void end_delayed_insert(THD *thd); extern "C" pthread_handler_decl(handle_delayed_insert,arg); static void unlink_blobs(register TABLE *table); @@ -38,9 +38,6 @@ static void unlink_blobs(register TABLE *table); #define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0)) #endif -#define DELAYED_LOG_UPDATE 1 -#define DELAYED_LOG_BIN 2 - /* Check if insert fields are correct Updates table->time_stamp to point to timestamp field or 0, depending on @@ -114,8 +111,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, By default, both logs are enabled (this won't cause problems if the server runs without --log-update or --log-bin). */ - int log_on= DELAYED_LOG_UPDATE | DELAYED_LOG_BIN ; - + bool log_on= (!(thd->master_access & SUPER_ACL)) || (thd->options & OPTION_BIN_LOG); bool transactional_table, log_delayed, bulk_insert; uint value_count; ulong counter = 1; @@ -130,14 +126,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->lex.select_lex.table_list.first; DBUG_ENTER("mysql_insert"); - if (thd->master_access & SUPER_ACL) - { - if (!(thd->options & OPTION_UPDATE_LOG)) - log_on&= ~(int) DELAYED_LOG_UPDATE; - if (!(thd->options & OPTION_BIN_LOG)) - log_on&= ~(int) DELAYED_LOG_BIN; - } - /* in safe mode or with skip-new change delayed insert to be regular if we are told to replace duplicates, the insert cannot be concurrent @@ -338,7 +326,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, log_delayed= (transactional_table || table->tmp_table); if ((info.copied || info.deleted) && (error <= 0 || !transactional_table)) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, @@ -562,13 +549,12 @@ public: char *record,*query; enum_duplicates dup; time_t start_time; - bool query_start_used,last_insert_id_used,insert_id_used; - int log_query; + bool query_start_used,last_insert_id_used,insert_id_used, log_query; ulonglong last_insert_id; ulong time_stamp; uint query_length; - delayed_row(enum_duplicates dup_arg, int log_query_arg) + delayed_row(enum_duplicates dup_arg, bool log_query_arg) :record(0),query(0),dup(dup_arg),log_query(log_query_arg) {} ~delayed_row() { @@ -871,7 +857,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd) /* Put a question in queue */ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, - char *query, uint query_length, int log_on) + char *query, uint query_length, bool log_on) { delayed_row *row=0; delayed_insert *di=thd->di; @@ -1258,15 +1244,10 @@ bool delayed_insert::handle_inserts(void) using_ignore=0; table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); } - if (row->query) + if (row->query && row->log_query && using_bin_log) { - if (row->log_query & DELAYED_LOG_UPDATE) - mysql_update_log.write(&thd,row->query, row->query_length); - if (row->log_query & DELAYED_LOG_BIN && using_bin_log) - { - Query_log_event qinfo(&thd, row->query, row->query_length,0); - mysql_bin_log.write(&qinfo); - } + Query_log_event qinfo(&thd, row->query, row->query_length,0); + mysql_bin_log.write(&qinfo); } if (table->blob_fields) free_delayed_insert_blobs(table); @@ -1449,7 +1430,6 @@ bool select_insert::send_eof() if (last_insert_id) thd->insert_id(last_insert_id); // For update log ::send_ok(thd,info.copied,last_insert_id,buff); - mysql_update_log.write(thd,thd->query,thd->query_length); return 0; } } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4f5b19e6f49..e4cdcd1015b 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -315,9 +315,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, sprintf(name,ER(ER_LOAD_INFO),info.records,info.deleted, info.records-info.copied,thd->cuted_fields); send_ok(thd,info.copied+info.deleted,0L,name); - // on the slave thd->query is never initialized - if (!thd->slave_thread) - mysql_update_log.write(thd,thd->query,thd->query_length); if (!log_delayed) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f22e00a31bc..cc9c2decf5b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2861,14 +2861,11 @@ mysql_execute_command(THD *thd) goto error; if (!(res = mysql_table_grant(thd,tables,lex->users_list, lex->columns, lex->grant, - lex->sql_command == SQLCOM_REVOKE))) + lex->sql_command == SQLCOM_REVOKE)) && + mysql_bin_log.is_open()) { - mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); - mysql_bin_log.write(&qinfo); - } + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); } } else @@ -2883,7 +2880,6 @@ mysql_execute_command(THD *thd) lex->sql_command == SQLCOM_REVOKE); if (!res) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); @@ -4114,7 +4110,6 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) if (options & REFRESH_LOG) { mysql_log.new_file(1); - mysql_update_log.new_file(1); mysql_bin_log.new_file(1); #ifdef HAVE_REPLICATION if (expire_logs_days) diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 19b4d299e59..5ef8d5d1c1d 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -79,7 +79,6 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) /* Lets hope this doesn't fail as the result will be messy */ if (!error) { - mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f4bcd6bd684..8cf049df5e5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -255,15 +255,11 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (some_tables_deleted || tmp_table_deleted) { query_cache_invalidate3(thd, tables, 0); - if (!dont_log_query) + if (!dont_log_query && mysql_bin_log.is_open()) { - mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, - tmp_table_deleted && !some_tables_deleted); - mysql_bin_log.write(&qinfo); - } + Query_log_event qinfo(thd, thd->query, thd->query_length, + tmp_table_deleted && !some_tables_deleted); + mysql_bin_log.write(&qinfo); } } @@ -908,17 +904,13 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } thd->tmp_table_used= 1; } - if (!tmp_table && !no_log) - { + if (!tmp_table && !no_log && mysql_bin_log.is_open()) // Must be written before unlock - mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, - test(create_info->options & - HA_LEX_CREATE_TMP_TABLE)); - mysql_bin_log.write(&qinfo); - } + { + Query_log_event qinfo(thd, thd->query, thd->query_length, + test(create_info->options & + HA_LEX_CREATE_TMP_TABLE)); + mysql_bin_log.write(&qinfo); } error=0; end: @@ -1742,7 +1734,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } if (!error) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); @@ -2123,7 +2114,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, my_free((gptr) new_table,MYF(0)); goto err; } - mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); @@ -2252,7 +2242,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } thd->proc_info="end"; - mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ec1183819dc..b96ddded8d1 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -323,7 +323,6 @@ int mysql_update(THD *thd, log_delayed= (transactional_table || table->tmp_table); if (updated && (error <= 0 || !transactional_table)) { - mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, @@ -932,7 +931,6 @@ bool multi_update::send_eof() if (updated && (local_error <= 0 || !trans_safe)) { - mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, From 9df615b7b19fb5c242ef10b58f2ff3b821a8d6a7 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Wed, 2 Apr 2003 10:59:21 +0200 Subject: [PATCH 54/83] Tiny optimisation for a (boolean || boolean) test, as SQL_LOG_BIN is set to 1 by default --- sql/sql_insert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 97e7e1a5d7f..2a747bbc089 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -111,7 +111,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, By default, both logs are enabled (this won't cause problems if the server runs without --log-update or --log-bin). */ - bool log_on= (!(thd->master_access & SUPER_ACL)) || (thd->options & OPTION_BIN_LOG); + bool log_on= (thd->options & OPTION_BIN_LOG) || (!(thd->master_access & SUPER_ACL)); bool transactional_table, log_delayed, bulk_insert; uint value_count; ulong counter = 1; From c673fcb813cace451070bd08e3670329a1c31c62 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 2 Apr 2003 20:42:28 +0200 Subject: [PATCH 55/83] Getting rid of lots of memory leaks (but not quite all of them yet, some will go away when temporary code is replaced). --- mysql-test/r/sp.result | 1 + mysql-test/t/sp.test | 3 +++ sql/sp.cc | 11 ++++++-- sql/sp_head.cc | 28 +++++++++++++++------ sql/sp_head.h | 22 +++++++--------- sql/sp_pcontext.cc | 57 ++++++++++++++++++------------------------ sql/sp_pcontext.h | 41 +++++++++++++++++------------- sql/sql_class.cc | 7 ++++++ sql/sql_parse.cc | 4 +++ 9 files changed, 102 insertions(+), 72 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 4833b152f07..1ff6d1552f4 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -20,6 +20,7 @@ delete from t1; drop procedure foo42; create procedure u() use sptmp; +drop database if exists sptmp; create database sptmp; use test; call u(); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 95b3e4732a9..a12e06f24b1 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -35,6 +35,9 @@ drop procedure foo42; create procedure u() use sptmp; +--disable_warnings +drop database if exists sptmp; +--enable_warnings create database sptmp; use test; call u(); diff --git a/sql/sp.cc b/sql/sp.cc index 5eb12c9fae5..c8dc328ced1 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -19,8 +19,8 @@ #include "sp.h" #include "sp_head.h" - static sp_head * - sp_find_cached_function(THD *thd, char *name, uint namelen); +static sp_head * +sp_find_cached_function(THD *thd, char *name, uint namelen); /* * @@ -373,6 +373,13 @@ sp_cache_functions(THD *thd, LEX *lex) void sp_clear_function_cache(THD *thd) { + //QQ This doesn't work for some completely mysterious reason, but since this + //QQ is tempoarary code anyway, we just ignore it for now. + //QQ List_iterator_fast li(thd->spfuns); + //QQ sp_head *sp; + + //QQ while ((sp= li++)) + //QQ sp->destroy(); thd->spfuns.empty(); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 61cf3228760..036207796c3 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -92,7 +92,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) } sp_head::sp_head(LEX_STRING *name, LEX *lex) - : m_simple_case(FALSE) + : Sql_alloc(), m_simple_case(FALSE) { const char *dstr = (const char*)lex->buf; @@ -126,19 +126,34 @@ sp_head::create(THD *thd) DBUG_RETURN(ret); } +void +sp_head::destroy() +{ + delete_dynamic(&m_instr); + m_pcont->destroy(); +} int sp_head::execute(THD *thd) { DBUG_ENTER("sp_head::execute"); - char *olddbname; + char olddbname[128]; char *olddbptr= thd->db; int ret= 0; uint ip= 0; - LINT_INIT(olddbname); if (olddbptr) - olddbname= my_strdup(olddbptr, MYF(MY_WME)); + { + uint i= 0; + char *p= olddbptr; + + /* Fast inline strncpy without padding... */ + while (*p && i < sizeof(olddbname)) + olddbname[i++]= *p++; + if (i == sizeof(olddbname)) + i-= 1; // QQ Error or warning for truncate? + olddbname[i]= '\0'; + } do { @@ -156,13 +171,12 @@ sp_head::execute(THD *thd) ret= -1; /* If the DB has changed, the pointer has changed too, but the original thd->db will then have been freed */ - if (olddbptr && olddbptr != thd->db && olddbname) + if (olddbptr && olddbptr != thd->db) { /* QQ Maybe we should issue some special error message or warning here, if this fails?? */ if (! thd->killed) ret= mysql_change_db(thd, olddbname); - my_free(olddbname, MYF(0)); } DBUG_RETURN(ret); } @@ -399,7 +413,7 @@ sp_head::restore_lex(THD *thd) void sp_head::push_backpatch(sp_instr *i, sp_label_t *lab) { - bp_t *bp= (bp_t *)my_malloc(sizeof(bp_t), MYF(MY_WME)); + bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t)); if (bp) { diff --git a/sql/sp_head.h b/sql/sp_head.h index 52cbdc56093..840276681a5 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -52,21 +52,15 @@ public: List m_tables; // Used tables. #endif - static void *operator new(size_t size) - { - return (void*) sql_alloc((uint) size); - } - - static void operator delete(void *ptr, size_t size) - { - /* Empty */ - } - sp_head(LEX_STRING *name, LEX *lex); int create(THD *thd); + // Free memory + void + destroy(); + int execute_function(THD *thd, Item **args, uint argcount, Item **resp); @@ -134,11 +128,13 @@ private: inline sp_instr * get_instr(uint i) { - sp_instr *in= NULL; + sp_instr *ip; if (i < m_instr.elements) - get_dynamic(&m_instr, (gptr)&in, i); - return in; + get_dynamic(&m_instr, (gptr)&ip, i); + else + ip= NULL; + return ip; } int diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index d59db9b449b..4d3cf80cd34 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -27,30 +27,20 @@ #include "sp_head.h" sp_pcontext::sp_pcontext() - : m_params(0), m_framesize(0), m_i(0), m_genlab(0) + : Sql_alloc(), m_params(0), m_framesize(0), m_genlab(0) { - m_pvar_size = 16; - m_pvar = (sp_pvar_t *)my_malloc(m_pvar_size * sizeof(sp_pvar_t), MYF(MY_WME)); - if (m_pvar) - memset(m_pvar, 0, m_pvar_size * sizeof(sp_pvar_t)); + VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8)); m_label.empty(); } void -sp_pcontext::grow() +sp_pcontext::destroy() { - uint sz = m_pvar_size + 8; - sp_pvar_t *a = (sp_pvar_t *)my_realloc((char *)m_pvar, - sz * sizeof(sp_pvar_t), - MYF(MY_WME | MY_ALLOW_ZERO_PTR)); - - if (a) - { - m_pvar_size = sz; - m_pvar = a; - } + delete_dynamic(&m_pvar); + m_label.empty(); } + /* This does a linear search (from newer to older variables, in case ** we have shadowed names). ** It's possible to have a more efficient allocation and search method, @@ -61,19 +51,20 @@ sp_pcontext::grow() sp_pvar_t * sp_pcontext::find_pvar(LEX_STRING *name) { - uint i = m_i; + uint i = m_pvar.elements; while (i-- > 0) { - uint len= (m_pvar[i].name.length > name->length ? - m_pvar[i].name.length : name->length); + sp_pvar_t *p= find_pvar(i); + uint len= (p->name.length > name->length ? + p->name.length : name->length); if (my_strncasecmp(system_charset_info, name->str, - m_pvar[i].name.str, + p->name.str, len) == 0) { - return m_pvar + i; + return p; } } return NULL; @@ -83,26 +74,26 @@ void sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode) { - if (m_i >= m_pvar_size) - grow(); - if (m_i < m_pvar_size) + sp_pvar_t *p= (sp_pvar_t *)sql_alloc(sizeof(sp_pvar_t)); + + if (p) { - if (m_i == m_framesize) + if (m_pvar.elements == m_framesize) m_framesize += 1; - m_pvar[m_i].name.str= name->str; - m_pvar[m_i].name.length= name->length, - m_pvar[m_i].type= type; - m_pvar[m_i].mode= mode; - m_pvar[m_i].offset= m_i; - m_pvar[m_i].isset= (mode == sp_param_out ? FALSE : TRUE); - m_i += 1; + p->name.str= name->str; + p->name.length= name->length; + p->type= type; + p->mode= mode; + p->offset= m_pvar.elements; + p->isset= (mode == sp_param_out ? FALSE : TRUE); + insert_dynamic(&m_pvar, (gptr)&p); } } sp_label_t * sp_pcontext::push_label(char *name, uint ip) { - sp_label_t *lab = (sp_label_t *)my_malloc(sizeof(sp_label_t), MYF(MY_WME)); + sp_label_t *lab = (sp_label_t *)sql_alloc(sizeof(sp_label_t)); if (lab) { diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index c5b0f1d410b..6900e18aa93 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -53,6 +53,10 @@ class sp_pcontext : public Sql_alloc sp_pcontext(); + // Free memory + void + destroy(); + inline uint max_framesize() { @@ -62,7 +66,7 @@ class sp_pcontext : public Sql_alloc inline uint current_framesize() { - return m_i; + return m_pvar.elements; } inline uint @@ -75,21 +79,25 @@ class sp_pcontext : public Sql_alloc inline void set_params() { - m_params= m_i; + m_params= m_pvar.elements; } inline void set_type(uint i, enum enum_field_types type) { - if (i < m_i) - m_pvar[i].type= type; + sp_pvar_t *p= find_pvar(i); + + if (p) + p->type= type; } inline void set_isset(uint i, my_bool val) { - if (i < m_i) - m_pvar[i].isset= val; + sp_pvar_t *p= find_pvar(i); + + if (p) + p->isset= val; } void @@ -99,8 +107,8 @@ class sp_pcontext : public Sql_alloc inline void pop(uint num = 1) { - if (num < m_i) - m_i -= num; + while (num--) + pop_dynamic(&m_pvar); } // Find by name @@ -111,9 +119,13 @@ class sp_pcontext : public Sql_alloc sp_pvar_t * find_pvar(uint i) { - if (i >= m_i) - return NULL; - return m_pvar+i; + sp_pvar_t *p; + + if (i < m_pvar.elements) + get_dynamic(&m_pvar, (gptr)&p, i); + else + p= NULL; + return p; } sp_label_t * @@ -138,13 +150,8 @@ private: uint m_params; // The number of parameters uint m_framesize; // The maximum framesize - uint m_i; // The current index (during parsing) - sp_pvar_t *m_pvar; - uint m_pvar_size; // Current size of m_pvar. - - void - grow(); + DYNAMIC_ARRAY m_pvar; List m_label; // The label list uint m_genlab; // Gen. label counter diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d5197b65071..7247d5bc3d0 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -191,6 +191,9 @@ THD::THD():user_time(0), is_fatal_error(0), pthread_mutex_unlock(&LOCK_thread_count); randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id); } + + /* QQ init the temporary function cache */ + spfuns.empty(); } @@ -282,6 +285,10 @@ void THD::cleanup(void) pthread_mutex_unlock(&LOCK_user_locks); ull= 0; } + + // extern void sp_clear_function_cache(THD *); + // sp_clear_function_cache(this); + cleanup_done=1; DBUG_VOID_RETURN; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f22e00a31bc..5259389778c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2810,6 +2810,7 @@ mysql_execute_command(THD *thd) sp_head *sph= sp_find_function(thd, &lex->udf.name); if (sph) { + sph->destroy(); // QQ Free memory. Remove this when caching!!! net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str); goto error; } @@ -3050,6 +3051,8 @@ mysql_execute_command(THD *thd) thd->net.no_send_ok= nsok; #endif + sp->destroy(); // QQ Free memory. Remove this when caching!!! + if (res == 0) send_ok(thd); else @@ -3075,6 +3078,7 @@ mysql_execute_command(THD *thd) { /* QQ This is an no-op right now, since we haven't put the characteristics in yet. */ + sp->destroy(); // QQ Free memory. Remove this when caching!!! send_ok(thd); } } From e483c8ff5ac531650c18920ceaf11635269120ba Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 2 Apr 2003 21:18:52 +0200 Subject: [PATCH 56/83] Updated result file. --- mysql-test/r/variables.result | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 822fab5ae47..e4101f3d754 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -297,6 +297,8 @@ set sql_buffer_result=1; set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; +Warnings: +Note 1266 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. set sql_low_priority_updates=1; set sql_max_join_size=200; select @@sql_max_join_size,@@max_join_size; From 1fc3582b7d473e3b99ce9bc13a2fadd456a027a6 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 3 Apr 2003 16:00:09 +0200 Subject: [PATCH 57/83] Got rid of the last unecessary Item_strings. --- sql/sp_head.cc | 23 +++++++++++------------ sql/sp_head.h | 10 ++++------ 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 036207796c3..ed6e07aa0a8 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -96,9 +96,10 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) { const char *dstr = (const char*)lex->buf; - m_name= new Item_string(name->str, name->length, system_charset_info); - m_defstr= new Item_string(dstr, lex->end_of_query - lex->buf, - system_charset_info); + m_name.length= name->length; + m_name.str= name->str; + m_defstr.length= lex->end_of_query - lex->buf; + m_defstr.str= sql_strmake(dstr, m_defstr.length); m_pcont= lex->spcont; my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_backpatch.empty(); @@ -108,20 +109,18 @@ int sp_head::create(THD *thd) { DBUG_ENTER("sp_head::create"); - String *name= m_name->const_string(); - String *def= m_defstr->const_string(); int ret; DBUG_PRINT("info", ("type: %d name: %s def: %s", - m_type, name->c_ptr(), def->c_ptr())); + m_type, m_name.str, m_defstr.str)); if (m_type == TYPE_ENUM_FUNCTION) ret= sp_create_function(thd, - name->c_ptr(), name->length(), - def->c_ptr(), def->length()); + m_name.str, m_name.length, + m_defstr.str, m_defstr.length); else ret= sp_create_procedure(thd, - name->c_ptr(), name->length(), - def->c_ptr(), def->length()); + m_name.str, m_name.length, + m_defstr.str, m_defstr.length); DBUG_RETURN(ret); } @@ -186,7 +185,7 @@ int sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) { DBUG_ENTER("sp_head::execute_function"); - DBUG_PRINT("info", ("function %s", ((String *)m_name->const_string())->c_ptr())); + DBUG_PRINT("info", ("function %s", m_name.str)); uint csize = m_pcont->max_framesize(); uint params = m_pcont->params(); sp_rcontext *octx = thd->spcont; @@ -220,7 +219,7 @@ int sp_head::execute_procedure(THD *thd, List *args) { DBUG_ENTER("sp_head::execute_procedure"); - DBUG_PRINT("info", ("procedure %s", ((String *)m_name->const_string())->c_ptr())); + DBUG_PRINT("info", ("procedure %s", m_name.str)); int ret; sp_instr *p; uint csize = m_pcont->max_framesize(); diff --git a/sql/sp_head.h b/sql/sp_head.h index 840276681a5..afc7822cca3 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -99,11 +99,9 @@ public: char *name(uint *lenp = 0) const { - String *n= m_name->const_string(); - if (lenp) - *lenp= n->length(); - return n->c_ptr(); + *lenp= m_name.length; + return m_name.str; } inline Item_result result() @@ -113,8 +111,8 @@ public: private: - Item_string *m_name; - Item_string *m_defstr; + LEX_STRING m_name; + LEX_STRING m_defstr; sp_pcontext *m_pcont; // Parse context LEX m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" From 5c4122d3e08474c873b081d2442b842605447f84 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 3 Apr 2003 20:00:52 +0200 Subject: [PATCH 58/83] Fixed the last memory leaks in the SP code. --- sql/sp.cc | 10 ++++------ sql/sp_head.cc | 6 ++++++ sql/sql_parse.cc | 16 +++++++++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index c8dc328ced1..2d7e38b47bd 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -373,13 +373,11 @@ sp_cache_functions(THD *thd, LEX *lex) void sp_clear_function_cache(THD *thd) { - //QQ This doesn't work for some completely mysterious reason, but since this - //QQ is tempoarary code anyway, we just ignore it for now. - //QQ List_iterator_fast li(thd->spfuns); - //QQ sp_head *sp; + List_iterator_fast li(thd->spfuns); + sp_head *sp; - //QQ while ((sp= li++)) - //QQ sp->destroy(); + while ((sp= li++)) + sp->destroy(); thd->spfuns.empty(); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ed6e07aa0a8..758345f764a 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -94,8 +94,10 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) sp_head::sp_head(LEX_STRING *name, LEX *lex) : Sql_alloc(), m_simple_case(FALSE) { + DBUG_ENTER("sp_head::sp_head"); const char *dstr = (const char*)lex->buf; + DBUG_PRINT("info", ("name: %s", name->str)); m_name.length= name->length; m_name.str= name->str; m_defstr.length= lex->end_of_query - lex->buf; @@ -103,6 +105,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) m_pcont= lex->spcont; my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_backpatch.empty(); + DBUG_VOID_RETURN; } int @@ -128,8 +131,11 @@ sp_head::create(THD *thd) void sp_head::destroy() { + DBUG_ENTER("sp_head::destroy"); + DBUG_PRINT("info", ("name: %s", m_name.str)); delete_dynamic(&m_instr); m_pcont->destroy(); + DBUG_VOID_RETURN; } int diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4d9cb072932..5d98d95a130 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1523,6 +1523,14 @@ restore_user: thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory + + /* + Clear the SP function cache after each statement (QQ this is a temporary + solution; caching will be rehacked later). + Note: Must do this before we free_root. + */ + sp_clear_function_cache(thd); + free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); DBUG_RETURN(error); } @@ -1587,11 +1595,6 @@ mysql_execute_command(THD *thd) SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); - /* - Clear the SP function cache before each statement (QQ this is a temporary - solution; caching will be rehacked later), and the new ones. - */ - sp_clear_function_cache(thd); if (lex->sql_command != SQLCOM_CREATE_PROCEDURE && lex->sql_command != SQLCOM_CREATE_SPFUNCTION) { @@ -3009,6 +3012,9 @@ mysql_execute_command(THD *thd) } #endif res= lex->sphead->create(thd); + + lex->sphead->destroy(); // QQ Free memory. Remove this when caching!!! + switch (res) { case SP_OK: From 462430ba558f047c8792ff577b45077aa332856a Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 4 Apr 2003 15:47:43 +0200 Subject: [PATCH 59/83] Post merge fixes. --- mysql-test/r/sp-error.result | 2 +- mysql-test/r/sp.result | 12 ++++++++++-- mysql-test/r/variables.result | 2 +- mysql-test/t/sp-error.test | 34 +++++++++++++++++----------------- mysql-test/t/sp.test | 22 +++++++++++++--------- sql/sp.cc | 13 +++++++++++-- sql/sp_pcontext.cc | 9 +++------ 7 files changed, 56 insertions(+), 38 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index ad1510c27f6..3a15b748316 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -27,7 +27,7 @@ call foo(); PROCEDURE foo does not exist drop procedure if exists foo; Warnings: -Warning 1256 PROCEDURE foo does not exist +Warning 1257 PROCEDURE foo does not exist create procedure foo() foo: loop leave bar; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1ff6d1552f4..2c738c47deb 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -327,9 +327,17 @@ drop procedure into_dumpfile; create procedure create_select(x char(16), y int) begin insert into test.t1 values (x, y); -create table test.t2 select * from test.t1; -insert into test.t2 values (concat(x, "2"), y+2); +create table test.t3 select * from test.t1; +insert into test.t3 values (concat(x, "2"), y+2); end; +drop table if exists t3; +call create_select("cs", 90); +select * from t1, t3; +id data id data +cs 90 cs 90 +cs 90 cs2 92 +drop table if exists t3; +delete from t1; drop procedure create_select; create function e() returns double return 2.7182818284590452354; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index fd9c00c9bca..ae4d90a05ab 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -298,7 +298,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1266 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1267 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. set sql_low_priority_updates=1; set sql_max_join_size=200; select @@sql_max_join_size,@@max_join_size; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index dd9becc631d..dd3bf916260 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -22,48 +22,48 @@ create function func1() returns int return 42| # Can't create recursively ---error 1254 +--error 1255 create procedure foo() create procedure bar() set @x=3| ---error 1254 +--error 1255 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1255 +--error 1256 create procedure proc1() set @x = 42| ---error 1255 +--error 1256 create function func1() returns int return 42| # Does not exist ---error 1256 +--error 1257 alter procedure foo| ---error 1256 +--error 1257 alter function foo| ---error 1256 +--error 1257 drop procedure foo| ---error 1256 +--error 1257 drop function foo| ---error 1256 +--error 1257 call foo()| drop procedure if exists foo| # LEAVE/ITERATE with no match ---error 1259 +--error 1260 create procedure foo() foo: loop leave bar; end loop| ---error 1259 +--error 1260 create procedure foo() foo: loop iterate bar; end loop| # Redefining label ---error 1260 +--error 1261 create procedure foo() foo: loop foo: loop @@ -72,14 +72,14 @@ foo: loop end loop foo| # End label mismatch ---error 1261 +--error 1262 create procedure foo() foo: loop set @x=2; end loop bar| # Referring to undef variable ---error 1262 +--error 1263 create procedure foo(out x int) begin declare y int; @@ -87,17 +87,17 @@ begin end| # We require INTO in SELECTs (for now; this might change in the future) ---error 1263 +--error 1264 create procedure foo(x int) select * from test.t1| # RETURN in FUNCTION only ---error 1264 +--error 1265 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1265 +--error 1266 create function foo() returns int begin declare x int; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index a12e06f24b1..294b61514fa 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -390,18 +390,22 @@ drop procedure into_dumpfile| create procedure create_select(x char(16), y int) begin insert into test.t1 values (x, y); - create table test.t2 select * from test.t1; - insert into test.t2 values (concat(x, "2"), y+2); + create table test.t3 select * from test.t1; + insert into test.t3 values (concat(x, "2"), y+2); end| -# This doesn't work right now. It suffers from the same problem as the ones -# above, but the fix caused create.test to hang. :-( -#call create_select("cs", 90)| -#select * from t1, t2| -#delete from t1| -#drop table t2| +--disable_warnings +drop table if exists t3| +--enable_warnings +call create_select("cs", 90)| +select * from t1, t3| +--disable_warnings +drop table if exists t3| +--enable_warnings +delete from t1| drop procedure create_select| + # A minimal, constant FUNCTION. create function e() returns double return 2.7182818284590452354| @@ -574,7 +578,7 @@ begin end| # This isn't the fastest way in the world to compute prime numbers, so -# don't be too ambition. ;-) +# don't be too ambitious. ;-) call ip(200)| # We don't want to select the entire table here, just pick a few # examples. diff --git a/sql/sp.cc b/sql/sp.cc index 2d7e38b47bd..9e0d848b19d 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -306,7 +306,11 @@ sp_add_fun_to_lex(LEX *lex, LEX_STRING fun) while ((fn= li++)) { - if (my_strncasecmp(system_charset_info, fn, fun.str, fun.length) == 0) + uint len= strlen(fn); + + if (my_strnncoll(system_charset_info, + (const uchar *)fn, len, + (const uchar *)fun.str, fun.length) == 0) break; } if (! fn) @@ -389,7 +393,12 @@ sp_find_cached_function(THD *thd, char *name, uint namelen) while ((sp= li++)) { - if (my_strncasecmp(system_charset_info, name, sp->name(), namelen) == 0) + uint len; + const uchar *n= (const uchar *)sp->name(&len); + + if (my_strnncoll(system_charset_info, + (const uchar *)name, namelen, + n, len) == 0) break; } return sp; diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 4d3cf80cd34..3973f05b74b 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -56,13 +56,10 @@ sp_pcontext::find_pvar(LEX_STRING *name) while (i-- > 0) { sp_pvar_t *p= find_pvar(i); - uint len= (p->name.length > name->length ? - p->name.length : name->length); - if (my_strncasecmp(system_charset_info, - name->str, - p->name.str, - len) == 0) + if (my_strnncoll(system_charset_info, + (const uchar *)name->str, name->length, + (const uchar *)p->name.str, p->name.length) == 0) { return p; } From 0428d08606269faf5eddd5740b5f9e80abfacbe4 Mon Sep 17 00:00:00 2001 From: "hf@deer.mysql.r18.ru" <> Date: Tue, 8 Apr 2003 19:18:33 +0500 Subject: [PATCH 60/83] SCRUM two KILL versions code trimming with headquarter's suggestions --- myisam/mi_check.c | 2 +- myisam/myisamchk.c | 4 ++-- myisam/myisamdef.h | 2 +- myisam/sort.c | 4 ++-- sql/ha_myisam.cc | 4 ++-- sql/lock.cc | 2 +- sql/log_event.cc | 2 +- sql/records.cc | 2 +- sql/slave.cc | 4 ++-- sql/sql_class.h | 8 ++++++++ sql/sql_delete.cc | 2 +- sql/sql_load.cc | 4 ++-- sql/sql_parse.cc | 4 ++-- sql/sql_prepare.cc | 2 +- sql/sql_select.cc | 20 ++++++++++---------- sql/sql_table.cc | 2 +- sql/sql_update.cc | 2 +- 17 files changed, 39 insertions(+), 31 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 23d477fb140..197739c0631 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -2585,7 +2585,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) char llbuff[22],llbuff2[22]; DBUG_ENTER("sort_get_next_record"); - if (killed_ptr(param->thd)) + if (*killed_ptr(param->thd)) DBUG_RETURN(1); switch (share->data_file_type) { diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index d816cd3f2a2..b0eade99a3d 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -1644,9 +1644,9 @@ err: DBUG_RETURN(1); } /* sort_record_index */ -bool killed_ptr(void *thd) +int *killed_ptr(void *thd) { - return (bool)thd; /* always NULL */ + return (int *)thd; /* always NULL */ } /* print warnings and errors */ diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index b2d6807ad73..6886554d94e 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -693,7 +693,7 @@ int mi_open_keyfile(MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share); /* Functions needed by mi_check */ -bool killed_ptr(void *thd); +int *killed_ptr(void *thd); void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_warning _VARARGS((MI_CHECK *param, const char *fmt,...)); void mi_check_print_info _VARARGS((MI_CHECK *param, const char *fmt,...)); diff --git a/myisam/sort.c b/myisam/sort.c index 1913af650c0..73c5b414edf 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -844,7 +844,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, uchar *strpos; BUFFPEK *buffpek,**refpek; QUEUE queue; - void *thd= info->sort_info->param->thd; + int *killed= killed_ptr(info->sort_info->param->thd); DBUG_ENTER("merge_buffers"); @@ -876,7 +876,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, { for (;;) { - if (killed_ptr(thd)) + if (*killed) { error=1; goto err; } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 69b6e248ac5..10574a15e3a 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -89,9 +89,9 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, extern "C" { -bool killed_ptr(void *thd) +int *killed_ptr(void *thd) { - return ((THD *)thd)->killed; + return (int*)&((THD *)thd)->killed; } void mi_check_print_error(MI_CHECK *param, const char *fmt,...) diff --git a/sql/lock.cc b/sql/lock.cc index 9e399a364b2..45ffefed14f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -154,7 +154,7 @@ retry: thd->proc_info=0; if (thd->killed) { - my_error(thd->killed, MYF(0)); + thd->send_kill_message(); if (sql_lock) { mysql_unlock_tables(thd,sql_lock); diff --git a/sql/log_event.cc b/sql/log_event.cc index 5132388224f..b533ddb126a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -779,7 +779,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), data_buf(0), query(query_arg), db(thd_arg->db), q_len((uint32) query_length), - error_code((int)thd_arg->killed ? (int)thd_arg->killed : thd_arg->net.last_errno), + error_code(thd_arg->killed != THD::NOT_KILLED ? thd->killed_errno() : thd_arg->net.last_errno), thread_id(thd_arg->thread_id) { time_t end_time; diff --git a/sql/records.cc b/sql/records.cc index 38904fa405f..2efd331b048 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -154,7 +154,7 @@ static int rr_sequential(READ_RECORD *info) { if (info->thd->killed) { - my_error(info->thd->killed,MYF(0)); + info->thd->send_kill_message(); return 1; } if (tmp != HA_ERR_RECORD_DELETED) diff --git a/sql/slave.cc b/sql/slave.cc index 78b415503f9..e6f7c5eac54 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -559,7 +559,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock, if (thd->killed) { pthread_mutex_unlock(cond_lock); - DBUG_RETURN(thd->killed); + DBUG_RETURN(thd->killed_errno()); } } } @@ -1861,7 +1861,7 @@ err: pthread_mutex_unlock(&data_lock); DBUG_PRINT("exit",("killed: %d abort: %d slave_running: %d \ improper_arguments: %d timed_out: %d", - (int) thd->killed, + thd->killed_errno(), (int) (init_abort_pos_wait != abort_pos_wait), (int) mi->slave_running, (int) (error == -2), diff --git a/sql/sql_class.h b/sql/sql_class.h index 96a3bb7051f..605d86e9684 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -527,6 +527,14 @@ public: enum killed_state { NOT_KILLED=0, KILL_CONNECTION=ER_SERVER_SHUTDOWN, KILL_QUERY=ER_QUERY_INTERRUPTED }; killed_state volatile killed; + inline int killed_errno() const + { + return killed; + } + inline void send_kill_message() const + { + my_error(killed_errno(), MYF(0)); + } bool prepare_command; bool tmp_table_used; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 921854469a5..392b81ba30b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -212,7 +212,7 @@ cleanup: delete select; free_underlaid_joins(thd, &thd->lex.select_lex); if (error >= 0 || thd->net.report_error) - send_error(thd,thd->killed); + send_error(thd,thd->killed_errno()); else { send_ok(thd,deleted); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 69585ddbc77..b7f007fa7ba 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -379,7 +379,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List &fields, { if (thd->killed) { - my_error(thd->killed,MYF(0)); + thd->send_kill_message(); DBUG_RETURN(1); } it.rewind(); @@ -453,7 +453,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, { if (thd->killed) { - my_error(thd->killed,MYF(0)); + thd->send_kill_message(); DBUG_RETURN(1); } while ((sql_field=(Item_field*) it++)) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5f99163b33c..6b604644450 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1658,7 +1658,7 @@ mysql_execute_command(THD *thd) cursor))) { if (res < 0 || thd->net.report_error) - send_error(thd,thd->killed); + send_error(thd,thd->killed_errno()); DBUG_RETURN(res); } } @@ -3141,7 +3141,7 @@ mysql_execute_command(THD *thd) // We end up here if res == 0 and send_ok() has been done, // or res != 0 and no send_error() has yet been done. if (res < 0) - send_error(thd,thd->killed); + send_error(thd,thd->killed_errno()); DBUG_RETURN(res); error: diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1d5e78b5e69..5ed8159793a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -674,7 +674,7 @@ static bool send_prepare_results(PREP_STMT *stmt) DBUG_RETURN(0); abort: - send_error(thd,thd->killed); + send_error(thd,thd->killed_errno()); DBUG_RETURN(1); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f6b5372812b..cbf30126272 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1725,7 +1725,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, sizeof(POSITION)*join->const_tables); join->best_read=1.0; } - DBUG_RETURN(join->thd->killed || get_best_combination(join)); + DBUG_RETURN(join->thd->killed_errno() || get_best_combination(join)); } @@ -4978,7 +4978,7 @@ sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) } if (join->thd->killed) // If aborted by user { - my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ + join->thd->send_kill_message(); return -2; /* purecov: inspected */ } if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0) @@ -5017,7 +5017,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) { if (join->thd->killed) // Aborted by user { - my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ + join->thd->send_kill_message(); return -2; /* purecov: inspected */ } join->examined_rows++; @@ -5097,7 +5097,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skipp_last) { if (join->thd->killed) { - my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ + join->thd->send_kill_message(); return -2; // Aborted by user /* purecov: inspected */ } SQL_SELECT *select=join_tab->select; @@ -5745,7 +5745,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->thd->killed) // Aborted by user { - my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ + join->thd->send_kill_message(); DBUG_RETURN(-2); /* purecov: inspected */ } if (!end_of_records) @@ -5813,7 +5813,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(0); if (join->thd->killed) // Aborted by user { - my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ + join->thd->send_kill_message(); DBUG_RETURN(-2); /* purecov: inspected */ } @@ -5883,7 +5883,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(0); if (join->thd->killed) // Aborted by user { - my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ + join->thd->send_kill_message(); DBUG_RETURN(-2); /* purecov: inspected */ } @@ -5930,7 +5930,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->thd->killed) { // Aborted by user - my_error(join->thd->killed,MYF(0)); /* purecov: inspected */ + join->thd->send_kill_message(); DBUG_RETURN(-2); /* purecov: inspected */ } if (!join->first_record || end_of_records || @@ -6652,7 +6652,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, { if (thd->killed) { - my_error(thd->killed,MYF(0)); + thd->send_kill_message(); error=0; goto err; } @@ -6764,7 +6764,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, { if (thd->killed) { - my_error(thd->killed,MYF(0)); + thd->send_kill_message(); error=0; goto err; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6473fe7f961..27db0ea0827 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2381,7 +2381,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, { if (thd->killed) { - my_error(thd->killed,MYF(0)); + thd->send_kill_message(); error= 1; break; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 23783883502..4ad14da242e 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -357,7 +357,7 @@ int mysql_update(THD *thd, delete select; free_underlaid_joins(thd, &thd->lex.select_lex); if (error >= 0) - send_error(thd,thd->killed); /* purecov: inspected */ + send_error(thd,thd->killed_errno()); /* purecov: inspected */ else { char buff[80]; From 0e006f5650a36afa9e188e7e66ceaabce64f6ca2 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 17 Apr 2003 00:18:29 +0200 Subject: [PATCH 61/83] Post-merge fixes. --- mysql-test/r/sp-error.result | 2 +- mysql-test/r/variables.result | 2 +- mysql-test/t/sp-error.test | 34 +++++++++++++++++----------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 3a15b748316..c754544a840 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -27,7 +27,7 @@ call foo(); PROCEDURE foo does not exist drop procedure if exists foo; Warnings: -Warning 1257 PROCEDURE foo does not exist +Warning 1261 PROCEDURE foo does not exist create procedure foo() foo: loop leave bar; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index db4de33ebe0..d5d34730c14 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -286,7 +286,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1267 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1271 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. set sql_low_priority_updates=1; set sql_max_join_size=200; select @@sql_max_join_size,@@max_join_size; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index dd3bf916260..63850f409dc 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -22,48 +22,48 @@ create function func1() returns int return 42| # Can't create recursively ---error 1255 +--error 1259 create procedure foo() create procedure bar() set @x=3| ---error 1255 +--error 1259 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1256 +--error 1260 create procedure proc1() set @x = 42| ---error 1256 +--error 1260 create function func1() returns int return 42| # Does not exist ---error 1257 +--error 1261 alter procedure foo| ---error 1257 +--error 1261 alter function foo| ---error 1257 +--error 1261 drop procedure foo| ---error 1257 +--error 1261 drop function foo| ---error 1257 +--error 1261 call foo()| drop procedure if exists foo| # LEAVE/ITERATE with no match ---error 1260 +--error 1264 create procedure foo() foo: loop leave bar; end loop| ---error 1260 +--error 1264 create procedure foo() foo: loop iterate bar; end loop| # Redefining label ---error 1261 +--error 1265 create procedure foo() foo: loop foo: loop @@ -72,14 +72,14 @@ foo: loop end loop foo| # End label mismatch ---error 1262 +--error 1266 create procedure foo() foo: loop set @x=2; end loop bar| # Referring to undef variable ---error 1263 +--error 1267 create procedure foo(out x int) begin declare y int; @@ -87,17 +87,17 @@ begin end| # We require INTO in SELECTs (for now; this might change in the future) ---error 1264 +--error 1268 create procedure foo(x int) select * from test.t1| # RETURN in FUNCTION only ---error 1265 +--error 1269 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1266 +--error 1270 create function foo() returns int begin declare x int; From 7b5df9edeca776b393142ab35e77d0df67fdd0e0 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 17 Apr 2003 13:20:02 +0200 Subject: [PATCH 62/83] Check the number of args to SPs. Fixes bug #280. --- include/mysqld_error.h | 3 ++- mysql-test/r/sp-error.result | 18 ++++++++++++++++-- mysql-test/t/sp-error.test | 22 ++++++++++++++++++++-- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sp_head.cc | 20 ++++++++++++++++++-- 27 files changed, 79 insertions(+), 7 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 5cd38a77614..623e665703e 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -290,4 +290,5 @@ #define ER_UPDATE_LOG_DEPRECATED_IGNORED 1271 #define ER_UPDATE_LOG_DEPRECATED_TRANSLATED 1272 #define ER_QUERY_INTERRUPTED 1273 -#define ER_ERROR_MESSAGES 274 +#define ER_SP_WRONG_NO_OF_ARGS 1274 +#define ER_ERROR_MESSAGES 275 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index c754544a840..5e1815d685f 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -15,6 +15,8 @@ PROCEDURE proc1 already exists create function func1() returns int return 42; FUNCTION func1 already exists +drop procedure proc1; +drop function func1; alter procedure foo; PROCEDURE foo does not exist alter function foo; @@ -69,5 +71,17 @@ select max(c) into x from test.t; return x; end; Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION -drop procedure proc1; -drop function func1; +create procedure p(x int) +insert into test.t1 values (x); +create function f(x int) returns int +return x+42; +call p(); +Wrong number of arguments for PROCEDURE p, expected 1, got 0 +call p(1, 2); +Wrong number of arguments for PROCEDURE p, expected 1, got 2 +select f(); +Wrong number of arguments for FUNCTION f, expected 1, got 0 +select f(1, 2); +Wrong number of arguments for FUNCTION f, expected 1, got 2 +drop procedure p; +drop function f; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 63850f409dc..cdeca75cd97 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -37,6 +37,9 @@ create procedure proc1() create function func1() returns int return 42| +drop procedure proc1| +drop function func1| + # Does not exist --error 1261 alter procedure foo| @@ -105,7 +108,22 @@ begin return x; end| -drop procedure proc1| -drop function func1| +# Wrong number of arguments +create procedure p(x int) + insert into test.t1 values (x)| +create function f(x int) returns int + return x+42| + +--error 1274 +call p()| +--error 1274 +call p(1, 2)| +--error 1274 +select f()| +--error 1274 +select f(1, 2)| + +drop procedure p| +drop function f| delimiter ;| diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 4954c8e9c35..76e69e23426 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -284,3 +284,4 @@ v/* "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 3a129ce39d0..363c9baa54c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -278,3 +278,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index d7411a727ec..9d008de76bb 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -286,3 +286,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 93b5aefedc9..19032f55d83 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -275,3 +275,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 9b6c015ae91..1bfdf8207ac 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -280,3 +280,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index d51bbff6fcc..4775f14f30b 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -275,3 +275,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 63e93b84dcd..72f66175c0b 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -284,3 +284,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 6f03bc26c0a..4c947568f8c 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -275,3 +275,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 20fab382d78..29f28886320 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -277,3 +277,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 8221fbd098e..3b64be1e140 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -275,3 +275,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 17746d51c46..8e81096cc73 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -277,3 +277,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 5a1d4456cac..45622f0d8c1 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -275,3 +275,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 8dc7d599756..2dccc62389e 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -277,3 +277,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 57118be3532..4af581f29bd 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -277,3 +277,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 29410a7fcbb..9bfbfd1a19f 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -279,3 +279,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 497928a7edf..7cfa3dfb258 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -275,3 +275,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index f681bedc89e..840c4a78332 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -279,3 +279,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 2c6c81974fa..a96437b3e92 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -277,3 +277,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index a4df5562a84..034a1aec7a9 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -271,3 +271,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 157b21615a3..46cd8fd3052 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -283,3 +283,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 3a863e8df1e..52e9ce77ec3 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -276,3 +276,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 8493bc628cd..76b9b631632 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -275,3 +275,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index c35a4b292bb..5867dc07c3c 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -280,3 +280,4 @@ "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored." "The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN." "Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 758345f764a..a10fc5792dc 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -199,7 +199,16 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) uint i; int ret; - // QQ Should have some error checking here? (no. of args, types, etc...) + if (argcount != params) + { + // Need to use my_printf_error here, or it will not terminate the + // invoking query properly. + my_printf_error(ER_SP_WRONG_NO_OF_ARGS, ER(ER_SP_WRONG_NO_OF_ARGS), MYF(0), + "FUNCTION", m_name.str, params, argcount); + DBUG_RETURN(-1); + } + + // QQ Should have some error checking here? (types, etc...) nctx= new sp_rcontext(csize); for (i= 0 ; i < params && i < argcount ; i++) { @@ -234,6 +243,13 @@ sp_head::execute_procedure(THD *thd, List *args) sp_rcontext *nctx = NULL; my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx + if (args->elements != params) + { + net_printf(thd, ER_SP_WRONG_NO_OF_ARGS, "PROCEDURE", m_name.str, + params, args->elements); + DBUG_RETURN(-1); + } + if (csize > 0) { uint i; @@ -246,7 +262,7 @@ sp_head::execute_procedure(THD *thd, List *args) octx = new sp_rcontext(csize); tmp_octx = TRUE; } - // QQ: No error checking whatsoever right now. Should do type checking? + // QQ: Should do type checking? for (i = 0 ; (it= li++) && i < params ; i++) { sp_pvar_t *pvar = m_pcont->find_pvar(i); From a4e065920b709029fa939be624b531def810eb2d Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 23 Apr 2003 09:22:54 +0200 Subject: [PATCH 63/83] Made multiple queries (SELECT without INTO) work in SPs. This included bug fixes in the 4.1 protocol (actually send and receive the server_status flags). --- libmysql/libmysql.c | 5 +++ mysql-test/r/sp-error.result | 9 +++- mysql-test/t/sp-error.test | 12 +++-- sql/protocol.cc | 2 +- sql/sp_head.cc | 2 +- sql/sp_head.h | 2 + sql/sql_parse.cc | 33 +++++++++++--- sql/sql_yacc.yy | 85 +++++++++++++++++++++++------------- 8 files changed, 107 insertions(+), 43 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index cc268101d38..f9df6445749 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1370,6 +1370,7 @@ static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, if (pkt_len > 1) /* MySQL 4.1 protocol */ { mysql->warning_count= uint2korr(cp+1); + mysql->server_status= uint2korr(cp+3); DBUG_PRINT("info",("warning_count: %ld", mysql->warning_count)); } DBUG_PRINT("exit",("Got %d rows",result->rows)); @@ -1395,7 +1396,10 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) if (pkt_len <= 8 && mysql->net.read_pos[0] == 254) { if (pkt_len > 1) /* MySQL 4.1 protocol */ + { mysql->warning_count= uint2korr(mysql->net.read_pos+1); + mysql->server_status= uint2korr(mysql->net.read_pos+3); + } return 1; /* End of data */ } prev_pos= 0; /* allowed to write at packet[-1] */ @@ -5370,6 +5374,7 @@ static MYSQL_DATA *read_binary_rows(MYSQL_STMT *stmt) if (pkt_len > 1) { mysql->warning_count= uint2korr(cp+1); + mysql->server_status= uint2korr(cp+3); DBUG_PRINT("info",("warning_count: %ld", mysql->warning_count)); } DBUG_PRINT("exit",("Got %d rows",result->rows)); diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 5e1815d685f..99bdfc25ba8 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -58,9 +58,14 @@ declare y int; set x = y; end; Referring to uninitialized variable y -create procedure foo(x int) -select * from test.t1; +create procedure foo() +begin +select name from mysql.proc; +select type from mysql.proc; +end; +call foo(); SELECT in a stored procedure must have INTO +drop procedure foo; create procedure foo() return 42; RETURN is only allowed in a FUNCTION diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index cdeca75cd97..93852b2219d 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -89,10 +89,16 @@ begin set x = y; end| -# We require INTO in SELECTs (for now; this might change in the future) +# We require INTO in SELECTs for some older clients (as mysql and mysqltest, +# for now). +create procedure foo() +begin + select name from mysql.proc; + select type from mysql.proc; +end| --error 1268 -create procedure foo(x int) - select * from test.t1| +call foo()| +drop procedure foo| # RETURN in FUNCTION only --error 1269 diff --git a/sql/protocol.cc b/sql/protocol.cc index 99b815a7840..eede2496e0c 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -360,7 +360,7 @@ send_eof(THD *thd, bool no_flush) uint tmp= min(thd->total_warn_count, 65535); buff[0]=254; int2store(buff+1, tmp); - int2store(buff+3, 0); // No flags yet + int2store(buff+3, thd->server_status); VOID(my_net_write(net,(char*) buff,5)); VOID(net_flush(net)); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a10fc5792dc..82019186a01 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -92,7 +92,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) } sp_head::sp_head(LEX_STRING *name, LEX *lex) - : Sql_alloc(), m_simple_case(FALSE) + : Sql_alloc(), m_simple_case(FALSE), m_multi_query(FALSE) { DBUG_ENTER("sp_head::sp_head"); const char *dstr = (const char*)lex->buf; diff --git a/sql/sp_head.h b/sql/sp_head.h index afc7822cca3..b79dfdab8e9 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -46,6 +46,8 @@ public: int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE enum enum_field_types m_returns; // For FUNCTIONs only my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise + my_bool m_multi_query; // TRUE if a procedure with SELECT(s) + uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value #if 0 // We're not using this at the moment. List m_calls; // Called procedures. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f3154277d94..b0a183f0711 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3043,8 +3043,8 @@ mysql_execute_command(THD *thd) net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name); goto error; } + break; } - break; case SQLCOM_CALL: { sp_head *sp; @@ -3057,17 +3057,40 @@ mysql_execute_command(THD *thd) } else { + uint smrx; + LINT_INIT(smrx); + #ifndef EMBEDDED_LIBRARY // When executing substatements, they're assumed to send_error when // it happens, but not to send_ok. my_bool nsok= thd->net.no_send_ok; - thd->net.no_send_ok= TRUE; #endif + if (sp->m_multi_query) + { + if (! (thd->client_capabilities & CLIENT_MULTI_QUERIES)) + { + send_error(thd, ER_SP_BADSELECT); +#ifndef EMBEDDED_LIBRARY + thd->net.no_send_ok= nsok; +#endif + sp->destroy(); // QQ Free memory. Remove this when caching!!! + goto error; + } + smrx= thd->server_status & SERVER_MORE_RESULTS_EXISTS; + thd->server_status |= SERVER_MORE_RESULTS_EXISTS; + } + res= sp->execute_procedure(thd, &lex->value_list); + #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif + if (sp->m_multi_query) + { + if (! smrx) + thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; + } sp->destroy(); // QQ Free memory. Remove this when caching!!! @@ -3076,8 +3099,8 @@ mysql_execute_command(THD *thd) else goto error; // Substatement should already have sent error } + break; } - break; case SQLCOM_ALTER_PROCEDURE: case SQLCOM_ALTER_FUNCTION: { @@ -3099,8 +3122,8 @@ mysql_execute_command(THD *thd) sp->destroy(); // QQ Free memory. Remove this when caching!!! send_ok(thd); } + break; } - break; case SQLCOM_DROP_PROCEDURE: case SQLCOM_DROP_FUNCTION: { @@ -3149,8 +3172,8 @@ mysql_execute_command(THD *thd) lex->udf.name.str); goto error; } + break; } - break; default: /* Impossible */ send_ok(thd); break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 04b4ae07bfc..dba829d2183 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -940,6 +940,14 @@ create: lex->spcont= new sp_pcontext(); lex->sphead= new sp_head(&$3, lex); lex->sphead->m_type= TYPE_ENUM_PROCEDURE; + /* + * We have to turn of CLIENT_MULTI_QUERIES while parsing a + * stored procedure, otherwise yylex will chop it into pieces + * at each ';'. + */ + lex->sphead->m_old_cmq= + YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); } '(' sp_pdparam_list ')' { @@ -947,7 +955,12 @@ create: } sp_proc_stmt { - Lex->sql_command= SQLCOM_CREATE_PROCEDURE; + LEX *lex= Lex; + + lex->sql_command= SQLCOM_CREATE_PROCEDURE; + /* Restore flag if it was cleared above */ + if (lex->sphead->m_old_cmq) + YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; } ; @@ -976,6 +989,14 @@ create_function_tail: lex->spcont= new sp_pcontext(); lex->sphead= new sp_head(&lex->udf.name, lex); lex->sphead->m_type= TYPE_ENUM_FUNCTION; + /* + * We have to turn of CLIENT_MULTI_QUERIES while parsing a + * stored procedure, otherwise yylex will chop it into pieces + * at each ';'. + */ + lex->sphead->m_old_cmq= + YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; } sp_fdparam_list ')' { @@ -987,7 +1008,12 @@ create_function_tail: } sp_proc_stmt { - Lex->sql_command = SQLCOM_CREATE_SPFUNCTION; + LEX *lex= Lex; + + lex->sql_command = SQLCOM_CREATE_SPFUNCTION; + /* Restore flag if it was cleared above */ + if (lex->sphead->m_old_cmq) + YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; } ; @@ -1140,40 +1166,37 @@ sp_proc_stmt: if (lex->sql_command == SQLCOM_SELECT && !lex->result) { - send_error(YYTHD, ER_SP_BADSELECT); - YYABORT; + /* We maybe have one or more SELECT without INTO */ + lex->sphead->m_multi_query= TRUE; } - else + /* Don't add an instruction for empty SET statements. + ** (This happens if the SET only contained local variables, + ** which get their set instructions generated separately.) + */ + if (lex->sql_command != SQLCOM_SET_OPTION || + !lex->var_list.is_empty()) { - /* Don't add an instruction for empty SET statements. - ** (This happens if the SET only contained local variables, - ** which get their set instructions generated separately.) + /* Currently we can't handle queries inside a FUNCTION, + ** because of the way table locking works. + ** This is unfortunate, and limits the usefulness of functions + ** a great deal, but it's nothing we can do about this at the + ** moment. */ - if (lex->sql_command != SQLCOM_SET_OPTION || - !lex->var_list.is_empty()) + if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && + lex->sql_command != SQLCOM_SET_OPTION) { - /* Currently we can't handle queries inside a FUNCTION, - ** because of the way table locking works. - ** This is unfortunate, and limits the usefulness of functions - ** a great deal, but it's nothing we can do about this at the - ** moment. - */ - if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && - lex->sql_command != SQLCOM_SET_OPTION) - { - send_error(YYTHD, ER_SP_BADQUERY); - YYABORT; - } - else - { - sp_instr_stmt *i= new sp_instr_stmt(lex->sphead->instructions()); + send_error(YYTHD, ER_SP_BADQUERY); + YYABORT; + } + else + { + sp_instr_stmt *i=new sp_instr_stmt(lex->sphead->instructions()); - i->set_lex(lex); - lex->sphead->add_instr(i); - } - } - lex->sphead->restore_lex(YYTHD); - } + i->set_lex(lex); + lex->sphead->add_instr(i); + } + } + lex->sphead->restore_lex(YYTHD); } | RETURN_SYM expr { From cba91cce8cb49745201786e41e803ca7b8e849f4 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 23 Apr 2003 16:21:56 +0200 Subject: [PATCH 64/83] Fixes bug #302: call u((select 1)) now works. More complex cases, like call u((select x from table limit 1)) does not. --- sql/sp_head.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 82019186a01..2d02f0262f4 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -54,7 +54,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) it= it->this_item(); DBUG_PRINT("info", ("type: %d", type)); - if (it->fix_fields(thd, 0, NULL)) + if (it->fix_fields(thd, 0, &it)) { DBUG_PRINT("info", ("fix_fields() failed")); DBUG_RETURN(it); // Shouldn't happen? From b9a4bf8cad2ab4283d3b603846d020044eac2ee0 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 23 Apr 2003 22:31:47 +0300 Subject: [PATCH 65/83] subselect in procedure argument list (Bug #302) --- .bzrignore | 3 +++ mysql-test/r/subselect.result | 17 +++++++++++++++++ mysql-test/t/subselect.test | 20 ++++++++++++++++++++ sql/sp_head.cc | 6 ++++++ sql/sql_parse.cc | 5 +++++ 5 files changed, 51 insertions(+) diff --git a/.bzrignore b/.bzrignore index b3db91e7c59..213ebc07624 100644 --- a/.bzrignore +++ b/.bzrignore @@ -605,3 +605,6 @@ vio/viotest-ssl myisam/ftbench/var/* myisam/ftbench/data myisam/ftbench/t +libmysqld/sp_pcontext.cc +libmysqld/sp.cc +libmysqld/sp_head.cc diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 3c34e615dab..b34503c34c2 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -887,6 +887,23 @@ do (SELECT a from t1); Table 'test.t1' doesn't exist set @a:=(SELECT a from t1); Table 'test.t1' doesn't exist +create table t1 (a int); +create table t2 (a int); +insert into t2 values (1), (2), (3); +create procedure foo1(x int) +insert into test.t1 values (x); +create function foo2(i int) returns int +return i+1; +call foo1((select max(a) from t2)); +select * from t1; +a +3 +select foo2((select max(a) from t2)); +foo2((select max(a) from t2)) +4 +drop table t1, t2; +drop procedure foo1; +drop function foo2; CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; HANDLER t1 READ a=((SELECT 1)); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9dd4fba0bd0..3e868fd0add 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -486,6 +486,9 @@ select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a'); select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2); drop table t1; +# +# DO & SET +# create table t1 (a int); insert into t1 values (1); do @a:=(SELECT a from t1); @@ -499,6 +502,23 @@ do (SELECT a from t1); -- error 1146 set @a:=(SELECT a from t1); +# +# CALL +# +create table t1 (a int); +create table t2 (a int); +insert into t2 values (1), (2), (3); +create procedure foo1(x int) + insert into test.t1 values (x); +create function foo2(i int) returns int + return i+1; +call foo1((select max(a) from t2)); +select * from t1; +select foo2((select max(a) from t2)); +drop table t1, t2; +drop procedure foo1; +drop function foo2; + CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; -- error 1149 diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2d02f0262f4..ce908afb19f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -216,6 +216,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) nctx->push_item(eval_func_item(thd, *argp++, pvar->type)); } + // Close tables opened for subselect in argument list + close_thread_tables(thd); + // The rest of the frame are local variables which are all IN. // QQ See comment in execute_procedure below. for (; i < csize ; i++) @@ -283,6 +286,9 @@ sp_head::execute_procedure(THD *thd, List *args) nctx->set_oindex(i, static_cast(it)->get_offset()); } } + // Close tables opened for subselect in argument list + close_thread_tables(thd); + // The rest of the frame are local variables which are all IN. // QQ We haven't found any hint of what the value is when unassigned, // so we set it to NULL for now. It's an error to refer to an diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b0a183f0711..4b077f4454b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3060,6 +3060,11 @@ mysql_execute_command(THD *thd) uint smrx; LINT_INIT(smrx); + if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || + (res= open_and_lock_tables(thd,tables)))) + break; + fix_tables_pointers(lex->all_selects_list); + #ifndef EMBEDDED_LIBRARY // When executing substatements, they're assumed to send_error when // it happens, but not to send_ok. From 3706f8b9a40d38efa754502f52cd2537763e953f Mon Sep 17 00:00:00 2001 From: "hf@deer.mysql.r18.ru" <> Date: Thu, 24 Apr 2003 08:22:11 +0500 Subject: [PATCH 66/83] SCRUM two versions of KILL small fix --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 61d86c85972..38f1c62ec60 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1725,7 +1725,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, sizeof(POSITION)*join->const_tables); join->best_read=1.0; } - DBUG_RETURN(join->thd->killed_errno() || get_best_combination(join)); + DBUG_RETURN(join->thd->killed || get_best_combination(join)); } From 6c85c6aa6afa24af80dbbe8f320fbbe9f5f4faa9 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 27 Apr 2003 17:35:54 +0200 Subject: [PATCH 67/83] Post-fix of bug #302 fix. Fixed bug #320. Some new tests and cosmetic changes. Another strcasecmp() replaced. --- mysql-test/r/sp.result | 27 +++++++++++++++++++++++++++ mysql-test/r/subselect.result | 17 ----------------- mysql-test/t/sp.test | 30 ++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 16 ---------------- sql/sp.cc | 4 ++-- sql/sp_head.cc | 4 ++-- sql/sp_head.h | 2 +- sql/sql_derived.cc | 8 +++++++- sql/sql_parse.cc | 6 +++++- sql/sql_yacc.yy | 3 ++- 10 files changed, 76 insertions(+), 41 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 2c738c47deb..29200a43975 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -135,6 +135,26 @@ cbv1 4711 delete from t1; drop procedure cbv1; drop procedure cbv2; +insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3); +create procedure sub1(id char(16), x int) +insert into test.t1 values (id, x); +create function sub3(i int) returns int +return i+1; +call sub1("sub1a", (select 7)); +call sub1("sub1b", (select max(i) from t2)); +call sub1("sub1c", (select i,d from t2 limit 1)); +call sub1("sub1d", (select 1 from (select 1) a)); +select * from t1; +id data +sub1a 7 +sub1b 3 +sub1c 1 +sub1d 1 +select sub3((select max(i) from t2)); +sub3((select max(i) from t2)) +4 +drop procedure sub1; +drop function sub3; create procedure a0(x int) while x do set x = x-1; @@ -143,6 +163,10 @@ end while; call a0(3); select * from t1; id data +sub1a 7 +sub1b 3 +sub1c 1 +sub1d 1 a0 2 a0 1 a0 0 @@ -391,6 +415,9 @@ s i d xxxyyy 12 2.71828182845905 select * from t2; s i d +a 1 1.1 +b 2 1.2 +c 3 1.3 xxxyyy 12 2.71828182845905 ab 24 1324.36598821719 delete from t2; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index b34503c34c2..3c34e615dab 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -887,23 +887,6 @@ do (SELECT a from t1); Table 'test.t1' doesn't exist set @a:=(SELECT a from t1); Table 'test.t1' doesn't exist -create table t1 (a int); -create table t2 (a int); -insert into t2 values (1), (2), (3); -create procedure foo1(x int) -insert into test.t1 values (x); -create function foo2(i int) returns int -return i+1; -call foo1((select max(a) from t2)); -select * from t1; -a -3 -select foo2((select max(a) from t2)); -foo2((select max(a) from t2)) -4 -drop table t1, t2; -drop procedure foo1; -drop function foo2; CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; HANDLER t1 READ a=((SELECT 1)); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 294b61514fa..c501501b82f 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -175,6 +175,36 @@ drop procedure cbv1| drop procedure cbv2| +# Subselect arguments + +insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3)| + +create procedure sub1(id char(16), x int) + insert into test.t1 values (id, x)| + +# QQ This doesn't work yet +#create procedure sub2(id char(16)) +#begin +# declare x int; +# set x = (select sum(t.x) from test.t2 t); +# insert into test.t1 values (id, x); +#end| + +create function sub3(i int) returns int + return i+1| + +call sub1("sub1a", (select 7))| +call sub1("sub1b", (select max(i) from t2))| +call sub1("sub1c", (select i,d from t2 limit 1))| +call sub1("sub1d", (select 1 from (select 1) a))| +#call sub2("sub2"); +select * from t1| +select sub3((select max(i) from t2))| +drop procedure sub1| +#drop procedure sub2| +drop function sub3| + + # Basic tests of the flow control constructs # Just test on 'x'... diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 3e868fd0add..ff40695de47 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -502,22 +502,6 @@ do (SELECT a from t1); -- error 1146 set @a:=(SELECT a from t1); -# -# CALL -# -create table t1 (a int); -create table t2 (a int); -insert into t2 values (1), (2), (3); -create procedure foo1(x int) - insert into test.t1 values (x); -create function foo2(i int) returns int - return i+1; -call foo1((select max(a) from t2)); -select * from t1; -select foo2((select max(a) from t2)); -drop table t1, t2; -drop procedure foo1; -drop function foo2; CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; diff --git a/sql/sp.cc b/sql/sp.cc index 9e0d848b19d..0d6a7b99e32 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -105,7 +105,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) } if (opened) { - close_thread_tables(thd); + close_thread_tables(thd, 0, 1); table= NULL; } @@ -286,7 +286,7 @@ sp_function_exists(THD *thd, LEX_STRING *name) ret= TRUE; } if (opened) - close_thread_tables(thd); + close_thread_tables(thd, 0, 1); return ret; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ce908afb19f..3bd958cfba9 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -80,7 +80,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) String tmp(buffer, sizeof(buffer), it->charset()); String *s= it->val_str(&tmp); - DBUG_PRINT("info", ("default result: %*s", s->length(), s->c_ptr_quick())) + DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick())); it= new Item_string(sql_strmake(s->c_ptr_quick(), s->length()), s->length(), it->charset()); break; @@ -393,7 +393,7 @@ sp_head::restore_lex(THD *thd) // Collect some data from the sub statement lex. sp_merge_funs(&m_lex, &thd->lex); #if 0 - // We're not using this at the moment. + // QQ We're not using this at the moment. if (thd->lex.sql_command == SQLCOM_CALL) { // It would be slightly faster to keep the list sorted, but we need diff --git a/sql/sp_head.h b/sql/sp_head.h index b79dfdab8e9..b0685ba7ca3 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -49,7 +49,7 @@ public: my_bool m_multi_query; // TRUE if a procedure with SELECT(s) uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value #if 0 - // We're not using this at the moment. + // QQ We're not using this at the moment. List m_calls; // Called procedures. List m_tables; // Used tables. #endif diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index ca761140955..9db7f172776 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -199,7 +199,13 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, else unit->exclude_level(); org_table_list->db= (char *)""; -#ifndef DBUG_OFF +#if 0 + /* QQ This was #ifndef DBUG_OFF, but that caused crashes with + * certain subselect args to SPs. Since ->derived is tested + * for non-null value in some places in the code, this seems + * to be the wrong way to do it. Simply letting derived be 0 + * appears to work fine. /pem + */ /* Try to catch errors if this is accessed */ org_table_list->derived=(SELECT_LEX_UNIT *) 1; #endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4b077f4454b..28ec89f40da 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3060,9 +3060,13 @@ mysql_execute_command(THD *thd) uint smrx; LINT_INIT(smrx); + // In case the arguments are subselects... if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || - (res= open_and_lock_tables(thd,tables)))) + (res= open_and_lock_tables(thd, tables)))) + { + sp->destroy(); // QQ Free memory. Remove this when caching!!! break; + } fix_tables_pointers(lex->all_selects_list); #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index dba829d2183..d5ca5a172b7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1399,7 +1399,8 @@ sp_labeled_control: LEX *lex= Lex; sp_label_t *lab= lex->spcont->find_label($5.str); - if (! lab || strcasecmp($5.str, lab->name) != 0) + if (!lab || + my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) { net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); YYABORT; From a8ba8521cd6ed02557154594c69220278a06f823 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 29 Apr 2003 12:31:03 +0200 Subject: [PATCH 68/83] Post-merge fix. --- client/mysql.cc | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 9c41f4afc30..2623660033b 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1568,7 +1568,7 @@ com_help(String *buffer __attribute__((unused)), for (i = 0; commands[i].name; i++) { if (commands[i].func) - tee_fprintf(stdout, "%-10s(\\%c)\t%s\n", commands[i].name, + tee_fprintf(stdout, "%s\t(\\%c)\t%s\n", commands[i].name, commands[i].cmd_char, commands[i].doc); } } @@ -2380,37 +2380,6 @@ static int com_source(String *buffer, char *line) return error; } - /* ARGSUSED */ -static int -com_delimiter(String *buffer __attribute__((unused)), char *line) -{ - char *tmp; - char buff[256]; - - if (strlen(line)> 255) - { - put_info("'DELIMITER' command was too long.", INFO_ERROR); - return 0; - } - bzero(buff, sizeof(buff)); - strmov(buff, line); - tmp= get_arg(buff, 0); - - if (!tmp || !*tmp) - { - put_info("DELIMITER must be followed by a 'delimiter' char", INFO_ERROR); - return 0; - } - - if (strlen(tmp)> 1) - { - put_info("Argument must be one char", INFO_ERROR); - return 0; - } - - delimiter= *tmp; - return 0; -} /* ARGSUSED */ static int From e73dafdca068fe9f2d2a86ad6caf10c559edbc01 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 29 Apr 2003 15:00:16 +0200 Subject: [PATCH 69/83] One final post-merge fix. --- sql/sql_prepare.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 37a1cfe924a..8bb633affdb 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -778,7 +778,7 @@ static bool init_param_items(PREP_STMT *stmt) stmt->lex= thd->lex; - if (mysql_bin_log.is_open() || mysql_update_log.is_open()) + if (mysql_bin_log.is_open()) { stmt->log_full_query= 1; stmt->setup_params= insert_params_withlog; From afd581edd39976432cd9c920ebedbca0f544a81e Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Mon, 5 May 2003 14:54:37 -0400 Subject: [PATCH 70/83] made lex a pointer in THD --- sql/filesort.cc | 2 +- sql/ha_innodb.cc | 8 +++--- sql/ha_myisam.cc | 4 +-- sql/item.cc | 24 ++++++++--------- sql/item_create.cc | 14 +++++----- sql/item_func.cc | 6 ++--- sql/item_subselect.cc | 16 ++++++------ sql/item_sum.cc | 2 +- sql/mysql_priv.h | 8 +++--- sql/mysqld.cc | 4 +-- sql/repl_failsafe.cc | 2 +- sql/set_var.cc | 2 +- sql/sp.cc | 2 +- sql/sp_head.cc | 60 +++++++++++++++++++++---------------------- sql/sql_acl.cc | 42 +++++++++++++++--------------- sql/sql_cache.cc | 10 ++++---- sql/sql_class.cc | 3 ++- sql/sql_class.h | 3 ++- sql/sql_delete.cc | 24 ++++++++--------- sql/sql_error.cc | 2 +- sql/sql_insert.cc | 8 +++--- sql/sql_lex.cc | 4 +-- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 28 ++++++++++---------- sql/sql_prepare.cc | 34 ++++++++++++------------ sql/sql_repl.cc | 16 ++++++------ sql/sql_select.cc | 16 ++++++------ sql/sql_table.cc | 6 ++--- sql/sql_union.cc | 28 ++++++++++---------- sql/sql_update.cc | 30 +++++++++++----------- sql/sql_yacc.yy | 26 +++++++++---------- 31 files changed, 219 insertions(+), 217 deletions(-) diff --git a/sql/filesort.cc b/sql/filesort.cc index ab645836b4b..155e4d17172 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1110,7 +1110,7 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength) The fact is the filter 'field->query_id != thd->query_id' doesn't work for alter table */ - if (thd->lex.sql_command != SQLCOM_SELECT) + if (thd->lex->sql_command != SQLCOM_SELECT) return 0; for (pfield= ptabfield; (field= *pfield) ; pfield++) { diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4f955d8f79e..63d0e87fb09 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1938,8 +1938,8 @@ ha_innobase::write_row( build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW); } - if (user_thd->lex.sql_command == SQLCOM_INSERT - && user_thd->lex.duplicates == DUP_IGNORE) { + if (user_thd->lex->sql_command == SQLCOM_INSERT + && user_thd->lex->duplicates == DUP_IGNORE) { prebuilt->trx->ignore_duplicates_in_insert = TRUE; } else { prebuilt->trx->ignore_duplicates_in_insert = FALSE; @@ -1967,8 +1967,8 @@ ha_innobase::write_row( skip_auto_inc_decr = FALSE; if (error == DB_DUPLICATE_KEY - && (user_thd->lex.sql_command == SQLCOM_REPLACE - || user_thd->lex.sql_command + && (user_thd->lex->sql_command == SQLCOM_REPLACE + || user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT)) { skip_auto_inc_decr= TRUE; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 90c5c4a0eb7..76aaeb8d407 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -388,7 +388,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) { HA_CHECK_OPT tmp_check_opt; - char* backup_dir = thd->lex.backup_dir; + char* backup_dir = thd->lex->backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char* table_name = table->real_name; int error; @@ -428,7 +428,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) { - char* backup_dir = thd->lex.backup_dir; + char* backup_dir = thd->lex->backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char* table_name = table->real_name; int error; diff --git a/sql/item.cc b/sql/item.cc index 484c55a4dec..60adca463b5 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -779,7 +779,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item **refer= (Item **)not_found_item; uint counter; // Prevent using outer fields in subselects, that is not supported now - SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select; + SELECT_LEX *cursel=(SELECT_LEX *) thd->lex->current_select; if (outer_resolving || cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) for (SELECT_LEX *sl=(outer_resolving?cursel:cursel->outer_select()); @@ -839,7 +839,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Mark all selects from resolved to 1 before select where was found table as depended (of select where was found table) */ - thd->lex.current_select->mark_as_dependent(last); + thd->lex->current_select->mark_as_dependent(last); if (depended_from->having_fix_field) { Item_ref *rf; @@ -1242,8 +1242,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { TABLE_LIST *where= 0; SELECT_LEX *sl= (outer_resolving? - thd->lex.current_select->select_lex(): - thd->lex.current_select->outer_select()); + thd->lex->current_select->select_lex(): + thd->lex->current_select->outer_select()); /* Finding only in current select will be performed for selects that have not outer one and for derived tables (which not support using outer @@ -1251,10 +1251,10 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) */ if (outer_resolving || (ref= find_item_in_list(this, - *(thd->lex.current_select->get_item_list()), + *(thd->lex->current_select->get_item_list()), &counter, ((sl && - thd->lex.current_select->master_unit()-> + thd->lex->current_select->master_unit()-> first_select()->linkage != DERIVED_TABLE_TYPE) ? REPORT_EXCEPT_NOT_FOUND : @@ -1296,7 +1296,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { // Call to report error find_item_in_list(this, - *(thd->lex.current_select->get_item_list()), + *(thd->lex->current_select->get_item_list()), &counter, REPORT_ALL_ERRORS); ref= 0; @@ -1310,7 +1310,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) return 1; // store pointer on SELECT_LEX from wich item is dependent f->depended_from= last; - thd->lex.current_select->mark_as_dependent(last); + thd->lex->current_select->mark_as_dependent(last); return 0; } else @@ -1325,7 +1325,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) depended_from: pointer on SELECT_LEX from wich item is dependent */ ref= (depended_from= last)->ref_pointer_array + counter; - thd->lex.current_select->mark_as_dependent(last); + thd->lex->current_select->mark_as_dependent(last); } } else if (!ref) @@ -1338,7 +1338,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) "forward reference in item list"); return -1; } - ref= thd->lex.current_select->ref_pointer_array + counter; + ref= thd->lex->current_select->ref_pointer_array + counter; } } @@ -1353,8 +1353,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) if (((*ref)->with_sum_func && name && (depended_from || - !(thd->lex.current_select->linkage != GLOBAL_OPTIONS_TYPE && - thd->lex.current_select->select_lex()->having_fix_field))) || + !(thd->lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && + thd->lex->current_select->select_lex()->having_fix_field))) || !(*ref)->fixed) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, diff --git a/sql/item_create.cc b/sql/item_create.cc index 23e4ce1d2b4..b7333813d54 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -83,7 +83,7 @@ Item *create_func_ceiling(Item* a) Item *create_func_connection_id(void) { THD *thd=current_thd; - thd->lex.safe_to_cache_query=0; + thd->lex->safe_to_cache_query=0; return new Item_int(NullS,(longlong) thd->thread_id,10); } @@ -159,7 +159,7 @@ Item *create_func_floor(Item* a) Item *create_func_found_rows(void) { THD *thd=current_thd; - thd->lex.safe_to_cache_query=0; + thd->lex->safe_to_cache_query=0; return new Item_int(NullS,(longlong) thd->found_rows(),21); } @@ -170,7 +170,7 @@ Item *create_func_from_days(Item* a) Item *create_func_get_lock(Item* a, Item *b) { - current_thd->lex.uncacheable(); + current_thd->lex->uncacheable(); return new Item_func_get_lock(a, b); } @@ -340,7 +340,7 @@ Item *create_func_radians(Item *a) Item *create_func_release_lock(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex->uncacheable(); return new Item_func_release_lock(a); } @@ -448,7 +448,7 @@ Item *create_func_year(Item* a) Item *create_load_file(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex->uncacheable(); return new Item_load_file(a); } @@ -471,13 +471,13 @@ Item *create_func_cast(Item *a, Item_cast cast_type) Item *create_func_is_free_lock(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex->uncacheable(); return new Item_func_is_free_lock(a); } Item *create_func_is_used_lock(Item* a) { - current_thd->lex.uncacheable(); + current_thd->lex->uncacheable(); return new Item_func_is_used_lock(a); } diff --git a/sql/item_func.cc b/sql/item_func.cc index 0933977370c..e30c130c449 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2253,7 +2253,7 @@ void Item_func_get_user_var::fix_length_and_dec() if ((var_entry= get_variable(&thd->user_vars, name, 0))) { - if (opt_bin_log && is_update_query(thd->lex.sql_command) && + if (opt_bin_log && is_update_query(thd->lex->sql_command) && var_entry->used_query_id != thd->query_id) { uint size; @@ -2632,7 +2632,7 @@ Item *get_system_var(enum_var_type var_type, LEX_STRING name) } if (!(item=var->item(thd, var_type))) return 0; // Impossible - thd->lex.uncacheable(); + thd->lex->uncacheable(); buff[0]='@'; buff[1]='@'; pos=buff+2; @@ -2658,7 +2658,7 @@ Item *get_system_var(enum_var_type var_type, const char *var_name, uint length, DBUG_ASSERT(var != 0); if (!(item=var->item(thd, var_type))) return 0; // Impossible - thd->lex.uncacheable(); + thd->lex->uncacheable(); item->set_name(item_name, 0, system_charset_info); // Will use original name return item; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 6c0b799b4de..c0343185cf2 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -170,7 +170,7 @@ void Item_singlerow_subselect::select_transformer(THD *thd, { have_to_be_excluded= 1; - if (thd->lex.describe) + if (thd->lex->describe) { char warn_buff[MYSQL_ERRMSG_SIZE]; sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number); @@ -560,7 +560,7 @@ void Item_in_subselect::single_value_transformer(THD *thd, item= (*func)(left_expr, item); substitution= item; have_to_be_excluded= 1; - if (thd->lex.describe) + if (thd->lex->describe) { char warn_buff[MYSQL_ERRMSG_SIZE]; sprintf(warn_buff, ER(ER_SELECT_REDUCED), sl->select_number); @@ -703,8 +703,8 @@ int subselect_single_select_engine::prepare() if (prepared) return 0; prepared= 1; - SELECT_LEX_NODE *save_select= thd->lex.current_select; - thd->lex.current_select= select_lex; + SELECT_LEX_NODE *save_select= thd->lex->current_select; + thd->lex->current_select= select_lex; if (join->prepare(&select_lex->ref_pointer_array, (TABLE_LIST*) select_lex->table_list.first, select_lex->with_wild, @@ -717,7 +717,7 @@ int subselect_single_select_engine::prepare() (ORDER*) 0, select_lex, select_lex->master_unit(), 0)) return 1; - thd->lex.current_select= save_select; + thd->lex->current_select= save_select; return 0; } @@ -830,10 +830,10 @@ int subselect_single_select_engine::exec() } if (!executed) { - SELECT_LEX_NODE *save_select= join->thd->lex.current_select; - join->thd->lex.current_select= select_lex; + SELECT_LEX_NODE *save_select= join->thd->lex->current_select; + join->thd->lex->current_select= select_lex; join->exec(); - join->thd->lex.current_select= save_select; + join->thd->lex->current_select= save_select; executed= 1; join->thd->where= save_where; DBUG_RETURN(join->error||thd->is_fatal_error); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 653f71e3d79..3a91b86f04f 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -57,7 +57,7 @@ Item_sum::Item_sum(THD *thd, Item_sum &item): void Item_sum::mark_as_sum_func() { - current_thd->lex.current_select->with_sum_func++; + current_thd->lex->current_select->with_sum_func++; with_sum_func= 1; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2adfd31d151..64b84858282 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -895,22 +895,22 @@ bool flush_error_log(void); inline bool add_item_to_list(THD *thd, Item *item) { - return thd->lex.current_select->add_item_to_list(thd, item); + return thd->lex->current_select->add_item_to_list(thd, item); } inline bool add_value_to_list(THD *thd, Item *value) { - return thd->lex.value_list.push_back(value); + return thd->lex->value_list.push_back(value); } inline bool add_order_to_list(THD *thd, Item *item, bool asc) { - return thd->lex.current_select->add_order_to_list(thd, item, asc); + return thd->lex->current_select->add_order_to_list(thd, item, asc); } inline bool add_group_to_list(THD *thd, Item *item, bool asc) { - return thd->lex.current_select->add_group_to_list(thd, item, asc); + return thd->lex->current_select->add_group_to_list(thd, item, asc); } inline void mark_as_null_row(TABLE *table) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 58676ea2fec..32ab02807b9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1269,12 +1269,12 @@ static void server_init(void) void yyerror(const char *s) { THD *thd=current_thd; - char *yytext=(char*) thd->lex.tok_start; + char *yytext=(char*) thd->lex->tok_start; /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) s=ER(ER_SYNTAX_ERROR); net_printf(thd,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "", - thd->lex.yylineno); + thd->lex->yylineno); } diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 58769827bed..a71beb8f230 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -422,7 +422,7 @@ int show_new_master(THD* thd) DBUG_ENTER("show_new_master"); List field_list; char errmsg[SLAVE_ERRMSG_SIZE]; - LEX_MASTER_INFO* lex_mi = &thd->lex.mi; + LEX_MASTER_INFO* lex_mi = &thd->lex->mi; errmsg[0]=0; // Safety if (translate_master(thd, lex_mi, errmsg)) diff --git a/sql/set_var.cc b/sql/set_var.cc index 20bb7bb5b30..f60ee19cc2a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1158,7 +1158,7 @@ void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type) bool sys_var_thd_bit::update(THD *thd, set_var *var) { int res= (*update_func)(thd, var); - thd->lex.select_lex.options=thd->options; + thd->lex->select_lex.options=thd->options; return res; } diff --git a/sql/sp.cc b/sql/sp.cc index 0d6a7b99e32..dff6b63a98c 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -359,7 +359,7 @@ sp_cache_functions(THD *thd, LEX *lex) continue; if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, strlen(fn), &sp) == SP_OK) { - ret= sp_cache_functions(thd, &thd->lex); + ret= sp_cache_functions(thd, thd->lex); if (ret) break; thd->spfuns.push_back(sp); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 3bd958cfba9..473d27238eb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -351,35 +351,35 @@ sp_head::execute_procedure(THD *thd, List *args) void sp_head::reset_lex(THD *thd) { - memcpy(&m_lex, &thd->lex, sizeof(LEX)); // Save old one + memcpy(&m_lex, thd->lex, sizeof(LEX)); // Save old one /* Reset most stuff. The length arguments doesn't matter here. */ lex_start(thd, m_lex.buf, m_lex.end_of_query - m_lex.ptr); /* We must reset ptr and end_of_query again */ - thd->lex.ptr= m_lex.ptr; - thd->lex.end_of_query= m_lex.end_of_query; + thd->lex->ptr= m_lex.ptr; + thd->lex->end_of_query= m_lex.end_of_query; /* And keep the SP stuff too */ - thd->lex.sphead = m_lex.sphead; - thd->lex.spcont = m_lex.spcont; + thd->lex->sphead = m_lex.sphead; + thd->lex->spcont = m_lex.spcont; /* Clear all lists. (QQ Why isn't this reset by lex_start()?). We may be overdoing this, but we know for sure that value_list must be cleared at least. */ - thd->lex.col_list.empty(); - thd->lex.ref_list.empty(); - thd->lex.drop_list.empty(); - thd->lex.alter_list.empty(); - thd->lex.interval_list.empty(); - thd->lex.users_list.empty(); - thd->lex.columns.empty(); - thd->lex.key_list.empty(); - thd->lex.create_list.empty(); - thd->lex.insert_list= NULL; - thd->lex.field_list.empty(); - thd->lex.value_list.empty(); - thd->lex.many_values.empty(); - thd->lex.var_list.empty(); - thd->lex.param_list.empty(); - thd->lex.proc_list.empty(); - thd->lex.auxilliary_table_list.empty(); + thd->lex->col_list.empty(); + thd->lex->ref_list.empty(); + thd->lex->drop_list.empty(); + thd->lex->alter_list.empty(); + thd->lex->interval_list.empty(); + thd->lex->users_list.empty(); + thd->lex->columns.empty(); + thd->lex->key_list.empty(); + thd->lex->create_list.empty(); + thd->lex->insert_list= NULL; + thd->lex->field_list.empty(); + thd->lex->value_list.empty(); + thd->lex->many_values.empty(); + thd->lex->var_list.empty(); + thd->lex->param_list.empty(); + thd->lex->proc_list.empty(); + thd->lex->auxilliary_table_list.empty(); } // Restore lex during parsing, after we have parsed a sub statement. @@ -387,11 +387,11 @@ void sp_head::restore_lex(THD *thd) { // Update some state in the old one first - m_lex.ptr= thd->lex.ptr; - m_lex.next_state= thd->lex.next_state; + m_lex.ptr= thd->lex->ptr; + m_lex.next_state= thd->lex->next_state; // Collect some data from the sub statement lex. - sp_merge_funs(&m_lex, &thd->lex); + sp_merge_funs(&m_lex, thd->lex); #if 0 // QQ We're not using this at the moment. if (thd->lex.sql_command == SQLCOM_CALL) @@ -434,7 +434,7 @@ sp_head::restore_lex(THD *thd) } #endif - memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Restore lex + memcpy(thd->lex, &m_lex, sizeof(LEX)); // Restore lex } void @@ -480,10 +480,10 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) LEX olex; // The other lex int res; - memcpy(&olex, &thd->lex, sizeof(LEX)); // Save the other lex + memcpy(&olex, thd->lex, sizeof(LEX)); // Save the other lex - memcpy(&thd->lex, &m_lex, sizeof(LEX)); // Use my own lex - thd->lex.thd = thd; + memcpy(thd->lex, &m_lex, sizeof(LEX)); // Use my own lex + thd->lex->thd = thd; res= mysql_execute_command(thd); if (thd->lock || thd->open_tables || thd->derived_tables) @@ -492,7 +492,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) close_thread_tables(thd); /* Free tables */ } - memcpy(&thd->lex, &olex, sizeof(LEX)); // Restore the other lex + memcpy(thd->lex, &olex, sizeof(LEX)); // Restore the other lex *nextp = m_ip+1; DBUG_RETURN(res); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index db4d60ebf77..52d72176486 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1401,7 +1401,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (table->fields >= 31) /* From 4.0.0 we have more fields */ { /* We write down SSL related ACL stuff */ - switch (thd->lex.ssl_type) { + switch (thd->lex->ssl_type) { case SSL_TYPE_ANY: table->field[24]->store("ANY",3, &my_charset_latin1); table->field[25]->store("", 0, &my_charset_latin1); @@ -1419,15 +1419,15 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, table->field[25]->store("", 0, &my_charset_latin1); table->field[26]->store("", 0, &my_charset_latin1); table->field[27]->store("", 0, &my_charset_latin1); - if (thd->lex.ssl_cipher) - table->field[25]->store(thd->lex.ssl_cipher, - strlen(thd->lex.ssl_cipher), &my_charset_latin1); - if (thd->lex.x509_issuer) - table->field[26]->store(thd->lex.x509_issuer, - strlen(thd->lex.x509_issuer), &my_charset_latin1); - if (thd->lex.x509_subject) - table->field[27]->store(thd->lex.x509_subject, - strlen(thd->lex.x509_subject), &my_charset_latin1); + if (thd->lex->ssl_cipher) + table->field[25]->store(thd->lex->ssl_cipher, + strlen(thd->lex->ssl_cipher), &my_charset_latin1); + if (thd->lex->x509_issuer) + table->field[26]->store(thd->lex->x509_issuer, + strlen(thd->lex->x509_issuer), &my_charset_latin1); + if (thd->lex->x509_subject) + table->field[27]->store(thd->lex->x509_subject, + strlen(thd->lex->x509_subject), &my_charset_latin1); break; case SSL_TYPE_NOT_SPECIFIED: break; @@ -1439,7 +1439,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, break; } - USER_RESOURCES mqh = thd->lex.mqh; + USER_RESOURCES mqh = thd->lex->mqh; if (mqh.bits & 1) table->field[28]->store((longlong) mqh.questions); if (mqh.bits & 2) @@ -1482,19 +1482,19 @@ end: password=0; // No password given on command if (old_row_exists) acl_update_user(combo.user.str,combo.host.str,password, - thd->lex.ssl_type, - thd->lex.ssl_cipher, - thd->lex.x509_issuer, - thd->lex.x509_subject, - &thd->lex.mqh, + thd->lex->ssl_type, + thd->lex->ssl_cipher, + thd->lex->x509_issuer, + thd->lex->x509_subject, + &thd->lex->mqh, rights); else acl_insert_user(combo.user.str,combo.host.str,password, - thd->lex.ssl_type, - thd->lex.ssl_cipher, - thd->lex.x509_issuer, - thd->lex.x509_subject, - &thd->lex.mqh, + thd->lex->ssl_type, + thd->lex->ssl_cipher, + thd->lex->x509_issuer, + thd->lex->x509_subject, + &thd->lex->mqh, rights); } table->file->index_end(); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8dc4802c3ee..fcc1aad98da 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -761,7 +761,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) uint8 tables_type= 0; if ((local_tables = is_cacheable(thd, thd->query_length, - thd->query, &thd->lex, tables_used, + thd->query, thd->lex, tables_used, &tables_type))) { NET *net= &thd->net; @@ -895,7 +895,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) /* Check that we haven't forgot to reset the query cache variables */ DBUG_ASSERT(thd->net.query_cache_query == 0); - if (!thd->lex.safe_to_cache_query) + if (!thd->lex->safe_to_cache_query) { DBUG_PRINT("qcache", ("SELECT is non-cacheable")); goto err; @@ -996,7 +996,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) table_list.db, table_list.alias)); refused++; // This is actually a hit STRUCT_UNLOCK(&structure_guard_mutex); - thd->lex.safe_to_cache_query=0; // Don't try to cache this + thd->lex->safe_to_cache_query=0; // Don't try to cache this BLOCK_UNLOCK_RD(query_block); DBUG_RETURN(-1); // Privilege error } @@ -1005,7 +1005,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) DBUG_PRINT("qcache", ("Need to check column privileges for %s.%s", table_list.db, table_list.alias)); BLOCK_UNLOCK_RD(query_block); - thd->lex.safe_to_cache_query= 0; // Don't try to cache this + thd->lex->safe_to_cache_query= 0; // Don't try to cache this goto err_unlock; // Parse query } if (check_tables && !handler::caching_allowed(thd, table->db(), @@ -1015,7 +1015,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s", table_list.db, table_list.alias)); BLOCK_UNLOCK_RD(query_block); - thd->lex.safe_to_cache_query= 0; // Don't try to cache this + thd->lex->safe_to_cache_query= 0; // Don't try to cache this goto err_unlock; // Parse query } else diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0ead869216f..5c7091529d8 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -90,6 +90,7 @@ THD::THD():user_time(0), is_fatal_error(0), insert_id_used(0), rand_used(0), in_lock_tables(0), global_read_lock(0), bootstrap(0), spcont(NULL) { + lex= &main_lex; host=user=priv_user=db=query=ip=0; host_or_ip= "connecting host"; locked=count_cuted_fields=some_tables_deleted=no_errors=password= @@ -1040,7 +1041,7 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) else { Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); - xx->fix_fields(thd,(TABLE_LIST*) thd->lex.select_lex.table_list.first,&item); + xx->fix_fields(thd,(TABLE_LIST*) thd->lex->select_lex.table_list.first,&item); xx->fix_length_and_dec(); vars.push_back(xx); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 1a3cd66c7e4..3bb0f348024 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -404,7 +404,8 @@ public: struct st_mysql *mysql; #endif NET net; // client connection descriptor - LEX lex; // parse tree descriptor + LEX main_lex; + LEX *lex; // parse tree descriptor MEM_ROOT mem_root; // 1 command-life memory pool MEM_ROOT con_root; // connection-life memory MEM_ROOT warn_root; // For warnings and errors diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 08f1727c515..8de40e416c2 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -38,18 +38,18 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, bool transactional_table, log_delayed, safe_update, const_cond; ha_rows deleted; TABLE_LIST *delete_table_list= (TABLE_LIST*) - thd->lex.select_lex.table_list.first; + thd->lex->select_lex.table_list.first; DBUG_ENTER("mysql_delete"); if ((open_and_lock_tables(thd, table_list))) DBUG_RETURN(-1); - fix_tables_pointers(thd->lex.all_selects_list); + fix_tables_pointers(thd->lex->all_selects_list); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; table->map=1; if (setup_conds(thd, delete_table_list, &conds) || - setup_ftfuncs(&thd->lex.select_lex)) + setup_ftfuncs(&thd->lex->select_lex)) DBUG_RETURN(-1); if (find_real_table_in_list(table_list->next, table_list->db, table_list->real_name)) @@ -92,7 +92,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, if ((select && select->check_quick(safe_update, limit)) || !limit) { delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); send_ok(thd,0L); DBUG_RETURN(0); // Nothing to delete } @@ -100,11 +100,11 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, /* If running in safe sql mode, don't allow updates without keys */ if (!table->quick_keys) { - thd->lex.select_lex.options|=QUERY_NO_INDEX_USED; + thd->lex->select_lex.options|=QUERY_NO_INDEX_USED; if (safe_update && !using_limit) { delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); DBUG_RETURN(1); } @@ -126,9 +126,9 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); - if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array, + if (setup_ref_array(thd, &thd->lex->select_lex.ref_pointer_array, all_fields.elements)|| - setup_order(thd, thd->lex.select_lex.ref_pointer_array, &tables, + setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || (table->sort.found_records = filesort(thd, table, sortorder, length, @@ -137,14 +137,14 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, == HA_POS_ERROR) { delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(-1); // This will force out message } } init_read_record(&info,thd,table,select,1,1); deleted=0L; - init_ftfuncs(thd, &thd->lex.select_lex, 1); + init_ftfuncs(thd, &thd->lex->select_lex, 1); thd->proc_info="updating"; while (!(error=info.read_record(&info)) && !thd->killed && !thd->net.report_error) @@ -212,7 +212,7 @@ cleanup: thd->lock=0; } delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); if (error >= 0 || thd->net.report_error) send_error(thd,thd->killed_errno()); else @@ -302,7 +302,7 @@ multi_delete::initialize_tables(JOIN *join) table->file->ref_length, MEM_STRIP_BUF_SIZE); } - init_ftfuncs(thd, thd->lex.current_select->select_lex(), 1); + init_ftfuncs(thd, thd->lex->current_select->select_lex(), 1); DBUG_RETURN(thd->is_fatal_error != 0); } diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 3b9c329d5e5..09da75afc65 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -183,7 +183,7 @@ my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) DBUG_RETURN(1); MYSQL_ERROR *err; - SELECT_LEX *sel= &thd->lex.select_lex; + SELECT_LEX *sel= &thd->lex->select_lex; ha_rows offset= sel->offset_limit, limit= sel->select_limit; Protocol *protocol=thd->protocol; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ab91c3fb29b..3db936190ff 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -123,7 +123,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, char *query=thd->query; thr_lock_type lock_type = table_list->lock_type; TABLE_LIST *insert_table_list= (TABLE_LIST*) - thd->lex.select_lex.table_list.first; + thd->lex->select_lex.table_list.first; DBUG_ENTER("mysql_insert"); /* @@ -166,7 +166,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, res= open_and_lock_tables(thd, table_list); if (res) DBUG_RETURN(-1); - fix_tables_pointers(thd->lex.all_selects_list); + fix_tables_pointers(thd->lex->all_selects_list); table= table_list->table; thd->proc_info="init"; @@ -378,13 +378,13 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->cuted_fields); ::send_ok(thd,info.copied+info.deleted,(ulonglong)id,buff); } - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(0); abort: if (lock_type == TL_WRITE_DELAYED) end_delayed_insert(thd); - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(-1); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e1298957a0f..2b3a6addcbd 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -108,7 +108,7 @@ void lex_free(void) LEX *lex_start(THD *thd, uchar *buf,uint length) { - LEX *lex= &thd->lex; + LEX *lex= thd->lex; lex->thd= thd; lex->next_state=MY_LEX_START; lex->buf= buf; @@ -436,7 +436,7 @@ int yylex(void *arg, void *yythd) int tokval; uint length; enum my_lex_states state,prev_state; - LEX *lex= &(((THD *)yythd)->lex); + LEX *lex= (((THD *)yythd)->lex); YYSTYPE *yylval=(YYSTYPE*) arg; CHARSET_INFO *cs= ((THD *) yythd)->charset(); uchar *state_map= cs->state_map; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index df5b84f88e3..ecf04c1575c 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -529,4 +529,4 @@ extern pthread_key(LEX*,THR_LEX); extern LEX_STRING tmp_table_alias; -#define current_lex (¤t_thd->lex) +#define current_lex (current_thd->lex) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 540d7f132ac..d1b9fecee35 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1087,7 +1087,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thread_running++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); - thd->lex.select_lex.options=0; // We store status here + thd->lex->select_lex.options=0; // We store status here switch (command) { case COM_INIT_DB: statistic_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status); @@ -1263,16 +1263,16 @@ restore_user: DBUG_PRINT("query",("%-.4096s",thd->query)); mysql_parse(thd,thd->query, thd->query_length); - while (!thd->killed && !thd->is_fatal_error && thd->lex.found_colon) + while (!thd->killed && !thd->is_fatal_error && thd->lex->found_colon) { - char *packet= thd->lex.found_colon; + char *packet= thd->lex->found_colon; /* Multiple queries exits, execute them individually */ if (thd->lock || thd->open_tables || thd->derived_tables) close_thread_tables(thd); - ulong length= thd->query_length-(ulong)(thd->lex.found_colon-thd->query); + ulong length= thd->query_length-(ulong)(thd->lex->found_colon-thd->query); /* Remove garbage at start of query */ while (my_isspace(thd->charset(), *packet) && length > 0) @@ -1510,7 +1510,7 @@ restore_user: if ((ulong) (thd->start_time - thd->time_after_lock) > thd->variables.long_query_time || - ((thd->lex.select_lex.options & + ((thd->lex->select_lex.options & (QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED)) && (specialflag & SPECIAL_LONG_LOG_FORMAT))) { @@ -1592,7 +1592,7 @@ int mysql_execute_command(THD *thd) { int res= 0; - LEX *lex= &thd->lex; + LEX *lex= thd->lex; TABLE_LIST *tables= (TABLE_LIST*) lex->select_lex.table_list.first; SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX_UNIT *unit= &lex->unit; @@ -1719,7 +1719,7 @@ mysql_execute_command(THD *thd) else thd->send_explain_fields(result); fix_tables_pointers(lex->all_selects_list); - res= mysql_explain_union(thd, &thd->lex.unit, result); + res= mysql_explain_union(thd, &thd->lex->unit, result); MYSQL_LOCK *save_lock= thd->lock; thd->lock= (MYSQL_LOCK *)0; result->send_eof(); @@ -2404,7 +2404,7 @@ mysql_execute_command(THD *thd) } case SQLCOM_DELETE_MULTI: { - TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first; + TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex->auxilliary_table_list.first; TABLE_LIST *auxi; uint table_count=0; multi_delete *result; @@ -3436,7 +3436,7 @@ void mysql_init_query(THD *thd) { DBUG_ENTER("mysql_init_query"); - LEX *lex=&thd->lex; + LEX *lex=thd->lex; lex->unit.init_query(); lex->unit.init_select(); lex->unit.thd= thd; @@ -3621,7 +3621,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, uint uint_geom_type) { register create_field *new_field; - LEX *lex= &thd->lex; + LEX *lex= thd->lex; uint allowed_type_modifier=0; char warn_buff[MYSQL_ERRMSG_SIZE]; DBUG_ENTER("add_field_to_list"); @@ -3945,7 +3945,7 @@ add_proc_to_list(THD* thd, Item *item) *item_ptr= item; order->item=item_ptr; order->free_me=0; - thd->lex.proc_list.link_in_list((byte*) order,(byte**) &order->next); + thd->lex->proc_list.link_in_list((byte*) order,(byte**) &order->next); return 0; } @@ -4368,11 +4368,11 @@ static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name) bool check_simple_select() { THD *thd= current_thd; - if (thd->lex.current_select != &thd->lex.select_lex) + if (thd->lex->current_select != &thd->lex->select_lex) { char command[80]; - strmake(command, thd->lex.yylval->symbol.str, - min(thd->lex.yylval->symbol.length, sizeof(command)-1)); + strmake(command, thd->lex->yylval->symbol.str, + min(thd->lex->yylval->symbol.length, sizeof(command)-1)); net_printf(thd, ER_CANT_USE_OPTION_HERE, command); return 1; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 8bb633affdb..43376012d4c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -399,7 +399,7 @@ static void setup_param_functions(Item_param *param, uchar param_type) static bool insert_params_withlog(PREP_STMT *stmt, uchar *pos, uchar *read_pos) { THD *thd= stmt->thd; - List ¶ms= thd->lex.param_list; + List ¶ms= thd->lex->param_list; List_iterator param_iterator(params); Item_param *param; DBUG_ENTER("insert_params_withlog"); @@ -445,7 +445,7 @@ static bool insert_params_withlog(PREP_STMT *stmt, uchar *pos, uchar *read_pos) static bool insert_params(PREP_STMT *stmt, uchar *pos, uchar *read_pos) { THD *thd= stmt->thd; - List ¶ms= thd->lex.param_list; + List ¶ms= thd->lex->param_list; List_iterator param_iterator(params); Item_param *param; DBUG_ENTER("insert_params"); @@ -471,7 +471,7 @@ static bool insert_params(PREP_STMT *stmt, uchar *pos, uchar *read_pos) static bool setup_params_data(PREP_STMT *stmt) { THD *thd= stmt->thd; - List ¶ms= thd->lex.param_list; + List ¶ms= thd->lex->param_list; List_iterator param_iterator(params); Item_param *param; DBUG_ENTER("setup_params_data"); @@ -517,8 +517,8 @@ static bool mysql_test_insert_fields(PREP_STMT *stmt, List_item *values; DBUG_ENTER("mysql_test_insert_fields"); - my_bool update=(thd->lex.value_list.elements ? UPDATE_ACL : 0); - ulong privilege= (thd->lex.duplicates == DUP_REPLACE ? + my_bool update=(thd->lex->value_list.elements ? UPDATE_ACL : 0); + ulong privilege= (thd->lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL | update); if (check_access(thd,privilege,table_list->db, @@ -616,8 +616,8 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, SELECT_LEX *select_lex) { THD *thd= stmt->thd; - LEX *lex= &thd->lex; - select_result *result= thd->lex.result; + LEX *lex= thd->lex; + select_result *result= thd->lex->result; DBUG_ENTER("mysql_test_select_fields"); ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; @@ -643,7 +643,7 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, } else { - fix_tables_pointers(thd->lex.all_selects_list); + fix_tables_pointers(thd->lex->all_selects_list); if (!result && !(result= new select_send())) { delete select_lex->having; @@ -676,8 +676,8 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, static bool send_prepare_results(PREP_STMT *stmt) { THD *thd= stmt->thd; - LEX *lex= &thd->lex; - enum enum_sql_command sql_command= thd->lex.sql_command; + LEX *lex= thd->lex; + enum enum_sql_command sql_command= thd->lex->sql_command; DBUG_ENTER("send_prepare_results"); DBUG_PRINT("enter",("command: %d, param_count: %ld", sql_command, lex->param_count)); @@ -758,7 +758,7 @@ static bool parse_prepare_query(PREP_STMT *stmt, LEX *lex=lex_start(thd, (uchar*) packet, length); lex->safe_to_cache_query= 0; thd->prepare_command= TRUE; - thd->lex.param_count= 0; + thd->lex->param_count= 0; if (!yyparse((void *)thd) && !thd->is_fatal_error) error= send_prepare_results(stmt); lex_end(lex); @@ -772,11 +772,11 @@ static bool parse_prepare_query(PREP_STMT *stmt, static bool init_param_items(PREP_STMT *stmt) { THD *thd= stmt->thd; - List ¶ms= thd->lex.param_list; + List ¶ms= thd->lex->param_list; Item_param **to; uint32 length= thd->query_length; - stmt->lex= thd->lex; + stmt->lex= *thd->lex; if (mysql_bin_log.is_open()) { @@ -817,7 +817,7 @@ static bool init_param_items(PREP_STMT *stmt) static void init_stmt_execute(PREP_STMT *stmt) { THD *thd= stmt->thd; - TABLE_LIST *tables= (TABLE_LIST*) thd->lex.select_lex.table_list.first; + TABLE_LIST *tables= (TABLE_LIST*) thd->lex->select_lex.table_list.first; /* TODO: When the new table structure is ready, then have a status bit @@ -914,8 +914,8 @@ void mysql_stmt_execute(THD *thd, char *packet) DBUG_VOID_RETURN; } - LEX thd_lex= thd->lex; - thd->lex= stmt->lex; + LEX *old_thd_lex= thd->lex; + thd->lex= &stmt->lex; init_stmt_execute(stmt); if (stmt->param_count && setup_params_data(stmt)) @@ -937,7 +937,7 @@ void mysql_stmt_execute(THD *thd, char *packet) if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); - thd->lex= thd_lex; + thd->lex= old_thd_lex; DBUG_VOID_RETURN; } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 9ada41ff837..f256c3b54eb 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -650,8 +650,8 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) was running (as we don't wan't to touch the other thread), so set the bit to 0 for the other thread */ - if (thd->lex.slave_thd_opt) - thread_mask &= thd->lex.slave_thd_opt; + if (thd->lex->slave_thd_opt) + thread_mask &= thd->lex->slave_thd_opt; if (thread_mask) //some threads are stopped, start them { if (init_master_info(mi,master_info_file,relay_log_info_file, 0)) @@ -707,8 +707,8 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) was stopped (as we don't wan't to touch the other thread), so set the bit to 0 for the other thread */ - if (thd->lex.slave_thd_opt) - thread_mask &= thd->lex.slave_thd_opt; + if (thd->lex->slave_thd_opt) + thread_mask &= thd->lex->slave_thd_opt; if (thread_mask) { @@ -856,7 +856,7 @@ int change_master(THD* thd, MASTER_INFO* mi) } thd->proc_info = "changing master"; - LEX_MASTER_INFO* lex_mi = &thd->lex.mi; + LEX_MASTER_INFO* lex_mi = &thd->lex->mi; // TODO: see if needs re-write if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) { @@ -1003,7 +1003,7 @@ int show_binlog_events(THD* thd) if (mysql_bin_log.is_open()) { - LEX_MASTER_INFO *lex_mi = &thd->lex.mi; + LEX_MASTER_INFO *lex_mi = &thd->lex->mi; ha_rows event_count, limit_start, limit_end; my_off_t pos = lex_mi->pos; char search_file_name[FN_REFLEN], *name; @@ -1012,8 +1012,8 @@ int show_binlog_events(THD* thd) LOG_INFO linfo; Log_event* ev; - limit_start = thd->lex.current_select->offset_limit; - limit_end = thd->lex.current_select->select_limit + limit_start; + limit_start = thd->lex->current_select->offset_limit; + limit_end = thd->lex->current_select->select_limit + limit_start; name= search_file_name; if (log_file_name) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 559ed59b0a4..c79235505d0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -816,7 +816,7 @@ JOIN::optimize() } } - if (select_lex != &thd->lex.select_lex && + if (select_lex != &thd->lex->select_lex && select_lex->linkage != DERIVED_TABLE_TYPE) { if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) @@ -3076,7 +3076,7 @@ static void make_join_readinfo(JOIN *join, uint options) { uint i; - SELECT_LEX *select_lex = &(join->thd->lex.select_lex); + SELECT_LEX *select_lex = &(join->thd->lex->select_lex); DBUG_ENTER("make_join_readinfo"); for (i=join->const_tables ; i < join->tables ; i++) @@ -4788,7 +4788,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, thd->proc_info="converting HEAP to MyISAM"; if (create_myisam_tmp_table(&new_table,param, - thd->lex.select_lex.options | thd->options)) + thd->lex->select_lex.options | thd->options)) goto err2; if (open_tmp_table(&new_table)) goto err1; @@ -7917,7 +7917,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, List field_list; List item_list; THD *thd=join->thd; - SELECT_LEX *select_lex = &(join->thd->lex.select_lex); + SELECT_LEX *select_lex = &(join->thd->lex->select_lex); select_result *result=join->result; Item *item_null= new Item_null(); CHARSET_INFO *cs= &my_charset_latin1; @@ -8101,8 +8101,8 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) sl= sl->next_select()) { res= mysql_explain_select(thd, sl, - (((&thd->lex.select_lex)==sl)? - ((thd->lex.all_selects_list != sl)?"PRIMARY": + (((&thd->lex->select_lex)==sl)? + ((thd->lex->all_selects_list != sl)?"PRIMARY": "SIMPLE"): ((sl == first)? ((sl->linkage == DERIVED_TABLE_TYPE) ? @@ -8130,7 +8130,7 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, DBUG_ENTER("mysql_explain_select"); DBUG_PRINT("info", ("Select 0x%lx, type %s", (ulong)select_lex, type)) select_lex->type= type; - thd->lex.current_select= select_lex; + thd->lex->current_select= select_lex; SELECT_LEX_UNIT *unit= select_lex->master_unit(); int res= mysql_select(thd, &select_lex->ref_pointer_array, (TABLE_LIST*) select_lex->table_list.first, @@ -8141,7 +8141,7 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, (ORDER*) select_lex->order_list.first, (ORDER*) select_lex->group_list.first, select_lex->having, - (ORDER*) thd->lex.proc_list.first, + (ORDER*) thd->lex->proc_list.first, select_lex->options | thd->options | SELECT_DESCRIBE, result, unit, select_lex, 0); DBUG_RETURN(res); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6d546001781..66dec8feee4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1132,7 +1132,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, } else { - char* backup_dir = thd->lex.backup_dir; + char* backup_dir = thd->lex->backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char* table_name = table->real_name; char* db = thd->db ? thd->db : table->db; @@ -2345,9 +2345,9 @@ copy_data_between_tables(TABLE *from,TABLE *to, tables.db = from->table_cache_key; error=1; - if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array, + if (setup_ref_array(thd, &thd->lex->select_lex.ref_pointer_array, order_num)|| - setup_order(thd, thd->lex.select_lex.ref_pointer_array, + setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || (from->sort.found_records = filesort(thd, from, sortorder, length, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index fe4ca49da14..728000c4365 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -115,7 +115,7 @@ bool select_union::flush() int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, bool tables_and_fields_initied) { - SELECT_LEX_NODE *lex_select_save= thd->lex.current_select; + SELECT_LEX_NODE *lex_select_save= thd->lex->current_select; SELECT_LEX *select_cursor; DBUG_ENTER("st_select_lex_unit::prepare"); @@ -129,7 +129,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, t_and_f= tables_and_fields_initied; bzero((char *)&tmp_table_param,sizeof(TMP_TABLE_PARAM)); - thd->lex.current_select= select_cursor= first_select_in_union(); + thd->lex->current_select= select_cursor= first_select_in_union(); /* Global option */ if (((void*)(global_parameters)) == ((void*)this)) { @@ -194,14 +194,14 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, or derived table ... */ - if (thd->lex.describe) + if (thd->lex->describe) { for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { JOIN *join= new JOIN(thd, sl->item_list, sl->options | thd->options | SELECT_NO_UNLOCK, union_result); - thd->lex.current_select= sl; + thd->lex->current_select= sl; offset_limit_cnt= sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit; if (select_limit_cnt < sl->select_limit) @@ -227,7 +227,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, } item_list.empty(); - thd->lex.current_select= lex_select_save; + thd->lex->current_select= lex_select_save; { List_iterator it(select_cursor->item_list); Field **field; @@ -242,7 +242,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result, DBUG_RETURN(res || thd->is_fatal_error ? 1 : 0); err: - thd->lex.current_select= lex_select_save; + thd->lex->current_select= lex_select_save; DBUG_RETURN(-1); } @@ -250,7 +250,7 @@ err: int st_select_lex_unit::exec() { int do_print_slow= 0; - SELECT_LEX_NODE *lex_select_save= thd->lex.current_select; + SELECT_LEX_NODE *lex_select_save= thd->lex->current_select; SELECT_LEX *select_cursor=first_select_in_union(); DBUG_ENTER("st_select_lex_unit::exec"); @@ -275,7 +275,7 @@ int st_select_lex_unit::exec() JOIN *join= new JOIN(thd, sl->item_list, sl->options | thd->options | SELECT_NO_UNLOCK, union_result); - thd->lex.current_select= sl; + thd->lex->current_select= sl; offset_limit_cnt= sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit; if (select_limit_cnt < sl->select_limit) @@ -297,7 +297,7 @@ int st_select_lex_unit::exec() t_and_f=0; if (res | thd->is_fatal_error) { - thd->lex.current_select= lex_select_save; + thd->lex->current_select= lex_select_save; DBUG_RETURN(res); } res= sl->join->optimize(); @@ -308,13 +308,13 @@ int st_select_lex_unit::exec() res= sl->join->error; if (!res && union_result->flush()) { - thd->lex.current_select= lex_select_save; + thd->lex->current_select= lex_select_save; DBUG_RETURN(1); } } if (res) { - thd->lex.current_select= lex_select_save; + thd->lex->current_select= lex_select_save; DBUG_RETURN(res); } do_print_slow|= select_cursor->options; @@ -325,7 +325,7 @@ int st_select_lex_unit::exec() /* Send result to 'result' */ // to correct ORDER BY reference resolving - thd->lex.current_select= select_cursor; + thd->lex->current_select= select_cursor; res= -1; { List empty_list; @@ -333,7 +333,7 @@ int st_select_lex_unit::exec() if (!thd->is_fatal_error) // Check if EOM { - SELECT_LEX *fake_select = new SELECT_LEX(&thd->lex); + SELECT_LEX *fake_select = new SELECT_LEX(thd->lex); offset_limit_cnt= (select_cursor->braces ? global_parameters->offset_limit : 0); select_limit_cnt= (select_cursor->braces ? @@ -367,7 +367,7 @@ int st_select_lex_unit::exec() QUERY_NO_GOOD_INDEX_USED)); } } - thd->lex.current_select= lex_select_save; + thd->lex->current_select= lex_select_save; DBUG_RETURN(res); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 1dba10dc299..0d9480b822c 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -67,14 +67,14 @@ int mysql_update(THD *thd, SQL_SELECT *select; READ_RECORD info; TABLE_LIST *update_table_list= (TABLE_LIST*) - thd->lex.select_lex.table_list.first; + thd->lex->select_lex.table_list.first; DBUG_ENTER("mysql_update"); LINT_INIT(used_index); LINT_INIT(timestamp_query_id); if ((open_and_lock_tables(thd, table_list))) DBUG_RETURN(-1); - fix_tables_pointers(thd->lex.all_selects_list); + fix_tables_pointers(thd->lex->all_selects_list); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); @@ -87,7 +87,7 @@ int mysql_update(THD *thd, table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); if (setup_tables(update_table_list) || setup_conds(thd,update_table_list,&conds) - || setup_ftfuncs(&thd->lex.select_lex)) + || setup_ftfuncs(&thd->lex->select_lex)) DBUG_RETURN(-1); /* purecov: inspected */ if (find_real_table_in_list(table_list->next, table_list->db, table_list->real_name)) @@ -126,7 +126,7 @@ int mysql_update(THD *thd, table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); if (setup_fields(thd, 0, update_table_list, values, 0, 0, 0)) { - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(-1); /* purecov: inspected */ } @@ -137,7 +137,7 @@ int mysql_update(THD *thd, (select && select->check_quick(safe_update, limit)) || !limit) { delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); if (error) { DBUG_RETURN(-1); // Error in where @@ -148,16 +148,16 @@ int mysql_update(THD *thd, /* If running in safe sql mode, don't allow updates without keys */ if (!table->quick_keys) { - thd->lex.select_lex.options|=QUERY_NO_INDEX_USED; + thd->lex->select_lex.options|=QUERY_NO_INDEX_USED; if (safe_update && !using_limit) { delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); DBUG_RETURN(1); } } - init_ftfuncs(thd, &thd->lex.select_lex, 1); + init_ftfuncs(thd, &thd->lex->select_lex, 1); /* Check if we are modifying a key that we are used to search with */ if (select && select->quick) used_key_is_modified= (!select->quick->unique_key_range() && @@ -180,7 +180,7 @@ int mysql_update(THD *thd, DISK_BUFFER_SIZE, MYF(MY_WME))) { delete select; /* purecov: inspected */ - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(-1); } if (old_used_keys & ((key_map) 1 << used_index)) @@ -203,9 +203,9 @@ int mysql_update(THD *thd, table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); - if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array, + if (setup_ref_array(thd, &thd->lex->select_lex.ref_pointer_array, order_num)|| - setup_order(thd, thd->lex.select_lex.ref_pointer_array, + setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || (table->sort.found_records = filesort(thd, table, sortorder, length, @@ -214,7 +214,7 @@ int mysql_update(THD *thd, == HA_POS_ERROR) { delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(-1); } } @@ -269,7 +269,7 @@ int mysql_update(THD *thd, if (error >= 0) { delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(-1); } } @@ -354,7 +354,7 @@ int mysql_update(THD *thd, } delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); if (error >= 0) send_error(thd,thd->killed_errno()); /* purecov: inspected */ else @@ -399,7 +399,7 @@ int mysql_multi_update(THD *thd, table_list->grant.want_privilege=(SELECT_ACL & ~table_list->grant.privilege); if ((res=open_and_lock_tables(thd,table_list))) DBUG_RETURN(res); - fix_tables_pointers(thd->lex.all_selects_list); + fix_tables_pointers(thd->lex->all_selects_list); thd->select_limit=HA_POS_ERROR; if (setup_fields(thd, 0, table_list, *fields, 1, 0, 0)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d1ed240e317..512cce301db 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -28,7 +28,7 @@ #define MYSQL_YACC #define YYINITDEPTH 100 #define YYMAXDEPTH 3200 /* Because of 64K stack */ -#define Lex (&(YYTHD->lex)) +#define Lex ((YYTHD->lex)) #define Select Lex->current_select #include "mysql_priv.h" #include "slave.h" @@ -729,14 +729,14 @@ query: { THD *thd= YYTHD; if (!thd->bootstrap && - (!(thd->lex.select_lex.options & OPTION_FOUND_COMMENT))) + (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) { send_error(thd,ER_EMPTY_QUERY); YYABORT; } else { - thd->lex.sql_command = SQLCOM_EMPTY_QUERY; + thd->lex->sql_command = SQLCOM_EMPTY_QUERY; } } | verb_clause END_OF_INPUT {}; @@ -2082,7 +2082,7 @@ alter: ALTER opt_ignore TABLE_SYM table_ident { THD *thd= YYTHD; - LEX *lex=&thd->lex; + LEX *lex= thd->lex; lex->sql_command = SQLCOM_ALTER_TABLE; lex->name=0; if (!lex->select_lex.add_table_to_list(thd, $4, NULL, @@ -2532,7 +2532,7 @@ select_item_list: THD *thd= YYTHD; if (add_item_to_list(thd, new Item_field(NULL, NULL, "*"))) YYABORT; - (thd->lex.current_select->select_lex()->with_wild)++; + (thd->lex->current_select->select_lex()->with_wild)++; }; @@ -4260,8 +4260,8 @@ show_param: | opt_var_type VARIABLES wild { THD *thd= YYTHD; - thd->lex.sql_command= SQLCOM_SHOW_VARIABLES; - thd->lex.option_type= (enum_var_type) $1; + thd->lex->sql_command= SQLCOM_SHOW_VARIABLES; + thd->lex->option_type= (enum_var_type) $1; } | charset wild { Lex->sql_command= SQLCOM_SHOW_CHARSETS; } @@ -4664,7 +4664,7 @@ simple_ident: | ident '.' ident { THD *thd= YYTHD; - LEX *lex= &thd->lex; + LEX *lex= thd->lex; SELECT_LEX_NODE *sel= lex->current_select; if (sel->no_table_names_allowed) { @@ -4677,7 +4677,7 @@ simple_ident: | '.' ident '.' ident { THD *thd= YYTHD; - LEX *lex= &thd->lex; + LEX *lex= thd->lex; SELECT_LEX_NODE *sel= lex->current_select; if (sel->no_table_names_allowed) { @@ -4690,7 +4690,7 @@ simple_ident: | ident '.' ident '.' ident { THD *thd= YYTHD; - LEX *lex= &thd->lex; + LEX *lex= thd->lex; SELECT_LEX_NODE *sel= lex->current_select; if (sel->no_table_names_allowed) { @@ -5079,7 +5079,7 @@ option_value: YYABORT; user->host.str=0; user->user.str=thd->priv_user; - thd->lex.var_list.push_back(new set_var_password(user, $3)); + thd->lex->var_list.push_back(new set_var_password(user, $3)); } | PASSWORD FOR_SYM user equal text_or_password { @@ -5597,7 +5597,7 @@ optional_order_or_limit: | { THD *thd= YYTHD; - LEX *lex= &thd->lex; + LEX *lex= thd->lex; DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE); SELECT_LEX *sel= lex->current_select->select_lex(); SELECT_LEX_UNIT *unit= sel->master_unit(); @@ -5609,7 +5609,7 @@ optional_order_or_limit: order_or_limit { THD *thd= YYTHD; - thd->lex.current_select->no_table_names_allowed= 0; + thd->lex->current_select->no_table_names_allowed= 0; thd->where= ""; } ; From 33cabdc3b1b912f4ac6a5add91c6f98033eabb2c Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Tue, 6 May 2003 21:09:20 +0500 Subject: [PATCH 71/83] Expand the mysql.proc table --- mysql-test/install_test_db.sh | 5 +++ scripts/mysql_install_db.sh | 5 +++ sql/sp.cc | 64 ++++++++++++++++++++++++++++++++--- sql/sp.h | 6 ++-- sql/sp_head.cc | 20 +++++++++-- sql/sp_head.h | 22 +++++++++++- sql/sql_yacc.yy | 4 +-- 7 files changed, 113 insertions(+), 13 deletions(-) diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index ed3b0fd683e..8477a0cd66d 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -253,6 +253,11 @@ then c_p="$c_p name char(64) binary DEFAULT '' NOT NULL," c_p="$c_p type enum('function','procedure') NOT NULL," c_p="$c_p body blob DEFAULT '' NOT NULL," + c_p="$c_p creator char(77) binary DEFAULT '' NOT NULL," + c_p="$c_p created timestamp," + c_p="$c_p modified timestamp," + c_p="$c_p suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL," + c_p="$c_p comment char(64) binary DEFAULT '' NOT NULL," c_p="$c_p PRIMARY KEY (name,type)" c_p="$c_p )" c_p="$c_p comment='Stored Procedures';" diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 0ce45c8d114..9e7032244cc 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -361,6 +361,11 @@ then c_p="$c_p name char(64) binary DEFAULT '' NOT NULL," c_p="$c_p type enum('function','procedure') NOT NULL," c_p="$c_p body blob DEFAULT '' NOT NULL," + c_p="$c_p creator char(77) binary DEFAULT '' NOT NULL," + c_p="$c_p created timestamp," + c_p="$c_p modified timestamp," + c_p="$c_p suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL," + c_p="$c_p comment char(64) binary DEFAULT '' NOT NULL," c_p="$c_p PRIMARY KEY (name,type)" c_p="$c_p )" c_p="$c_p comment='Stored Procedures';" diff --git a/sql/sp.cc b/sql/sp.cc index 0d6a7b99e32..7bca9977f0c 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -93,6 +93,14 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) const char *defstr; int ret; bool opened; + const char *creator; + longlong created; + longlong modified; + bool suid= 1; + char *ptr; + uint length; + char buff[65]; + String str(buff,sizeof(buff),&my_charset_bin); // QQ Set up our own mem_root here??? ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened); @@ -103,6 +111,35 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) ret= SP_GET_FIELD_FAILED; goto done; } + + //Get additional information + if ((creator= get_field(&thd->mem_root, table->field[3])) == NULL) + { + ret= SP_GET_FIELD_FAILED; + goto done; + } + + created= table->field[4]->val_int(); + modified= table->field[5]->val_int(); + + if ((ptr= get_field(&thd->mem_root, table->field[6])) == NULL) + { + ret= SP_GET_FIELD_FAILED; + goto done; + } + if (ptr[0] == 'N') + suid= 0; + + table->field[7]->val_str(&str,&str); + length=str.length(); + ptr= 0; + if (length) + { + ptr= (char*) alloc_root(&thd->mem_root,length+1); + memcpy(ptr,str.ptr(),(uint) length); + ptr[length]=0; + } + if (opened) { close_thread_tables(thd, 0, 1); @@ -113,7 +150,12 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) if (yyparse(thd) || thd->is_fatal_error || tmplex->sphead == NULL) ret= SP_PARSE_ERROR; else + { *sphp= tmplex->sphead; + (*sphp)->sp_set_info((char *) creator, (uint) strlen(creator), + created, modified, suid, + ptr, length); + } done: if (table && opened) @@ -123,13 +165,15 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) static int db_create_routine(THD *thd, int type, - char *name, uint namelen, char *def, uint deflen) + char *name, uint namelen, char *def, uint deflen, + char *comment, uint commentlen, bool suid) { DBUG_ENTER("db_create_routine"); DBUG_PRINT("enter", ("type: %d name: %*s def: %*s", type, namelen, name, deflen, def)); int ret; TABLE *table; TABLE_LIST tables; + char creator[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; memset(&tables, 0, sizeof(tables)); tables.db= (char*)"mysql"; @@ -140,10 +184,16 @@ db_create_routine(THD *thd, int type, else { restore_record(table, 2); // Get default values for fields + strxmov(creator, thd->user, "@", thd->host_or_ip, NullS); table->field[0]->store(name, namelen, system_charset_info); table->field[1]->store((longlong)type); table->field[2]->store(def, deflen, system_charset_info); + table->field[3]->store(creator, (uint) strlen(creator), system_charset_info); + if (suid) + table->field[6]->store((longlong) suid); + if (comment) + table->field[7]->store(comment, commentlen, system_charset_info); if (table->file->write_row(table->record[0])) ret= SP_WRITE_ROW_FAILED; @@ -199,13 +249,15 @@ sp_find_procedure(THD *thd, LEX_STRING *name) } int -sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) +sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen, + char *comment, uint commentlen, bool suid) { DBUG_ENTER("sp_create_procedure"); DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def)); int ret; - ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, def, deflen); + ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, def, deflen, + comment, commentlen, suid); DBUG_RETURN(ret); } @@ -248,13 +300,15 @@ sp_find_function(THD *thd, LEX_STRING *name) } int -sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen) +sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen, + char *comment, uint commentlen, bool suid) { DBUG_ENTER("sp_create_function"); DBUG_PRINT("enter", ("name: %*s def: %*s", namelen, name, deflen, def)); int ret; - ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, def, deflen); + ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, def, deflen, + comment, commentlen, suid); DBUG_RETURN(ret); } diff --git a/sql/sp.h b/sql/sp.h index 21fcb4c5360..3a021288907 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -31,7 +31,8 @@ sp_head * sp_find_procedure(THD *thd, LEX_STRING *name); int -sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen); +sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen, + char *comment, uint commentlen, bool suid); int sp_drop_procedure(THD *thd, char *name, uint namelen); @@ -41,7 +42,8 @@ sp_head * sp_find_function(THD *thd, LEX_STRING *name); int -sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen); +sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen, + char *comment, uint commentlen, bool suid); int sp_drop_function(THD *thd, char *name, uint namelen); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 3bd958cfba9..11fedb1a294 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -91,7 +91,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) DBUG_RETURN(it); } -sp_head::sp_head(LEX_STRING *name, LEX *lex) +sp_head::sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) : Sql_alloc(), m_simple_case(FALSE), m_multi_query(FALSE) { DBUG_ENTER("sp_head::sp_head"); @@ -102,6 +102,16 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex) m_name.str= name->str; m_defstr.length= lex->end_of_query - lex->buf; m_defstr.str= sql_strmake(dstr, m_defstr.length); + + m_comment.length= 0; + m_comment.str= 0; + if (comment) + { + m_comment.length= comment->length; + m_comment.str= comment->str; + } + + m_suid= suid; m_pcont= lex->spcont; my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_backpatch.empty(); @@ -119,11 +129,15 @@ sp_head::create(THD *thd) if (m_type == TYPE_ENUM_FUNCTION) ret= sp_create_function(thd, m_name.str, m_name.length, - m_defstr.str, m_defstr.length); + m_defstr.str, m_defstr.length, + m_comment.str, m_comment.length, + m_suid); else ret= sp_create_procedure(thd, m_name.str, m_name.length, - m_defstr.str, m_defstr.length); + m_defstr.str, m_defstr.length, + m_comment.str, m_comment.length, + m_suid); DBUG_RETURN(ret); } diff --git a/sql/sp_head.h b/sql/sp_head.h index b0685ba7ca3..d5bf7138785 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -54,7 +54,7 @@ public: List m_tables; // Used tables. #endif - sp_head(LEX_STRING *name, LEX *lex); + sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid); int create(THD *thd); @@ -111,10 +111,30 @@ public: return sp_map_result_type(m_returns); } + void sp_set_info(char *creator, uint creatorlen, + longlong created, longlong modified, + bool suid, char *comment, uint commentlen) + { + m_creator= creator; + m_creatorlen= creatorlen; + m_created= created; + m_modified= modified; + m_comment.length= commentlen; + m_comment.str= comment; + m_suid= suid; + } + private: LEX_STRING m_name; LEX_STRING m_defstr; + LEX_STRING m_comment; + char *m_creator; + uint m_creatorlen; + longlong m_created; + longlong m_modified; + bool m_suid; + sp_pcontext *m_pcont; // Parse context LEX m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d1ed240e317..6c3557145be 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -938,7 +938,7 @@ create: YYABORT; } lex->spcont= new sp_pcontext(); - lex->sphead= new sp_head(&$3, lex); + lex->sphead= new sp_head(&$3, lex, 0, 0); lex->sphead->m_type= TYPE_ENUM_PROCEDURE; /* * We have to turn of CLIENT_MULTI_QUERIES while parsing a @@ -987,7 +987,7 @@ create_function_tail: YYABORT; } lex->spcont= new sp_pcontext(); - lex->sphead= new sp_head(&lex->udf.name, lex); + lex->sphead= new sp_head(&lex->udf.name, lex, 0, 0); lex->sphead->m_type= TYPE_ENUM_FUNCTION; /* * We have to turn of CLIENT_MULTI_QUERIES while parsing a From 05c78eec38cd1b8e4ddf088ebd208eb5b34a5e2c Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 12 May 2003 15:36:31 +0200 Subject: [PATCH 72/83] Task #627 : user variables' names are now case-insensitive : @test=@"tEsT"=@`teST` etc. Tests updated. Note that the patch to sql_class.cc does not use HASH_CASE_INSENSITIVE as did the one which I sent for review. This is because meanwhile HASH_CASE_INSENSITIVE has disappeared (since cset 1.1504.1.6). --- mysql-test/r/variables.result | 30 ++++++++++++++++++++++++++---- mysql-test/t/variables.test | 16 ++++++++++++++-- sql/sql_class.cc | 6 +++--- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 8dff27bdd6f..2bcb749955e 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1,8 +1,30 @@ drop table if exists t1,t2; -set @`test`=1,@TEST=3,@select=2,@t5=1.23456; -select @test,@`select`,@TEST,@not_used; -@test @`select` @TEST @not_used -1 2 3 NULL +set @`test`=1; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +@test @`test` @TEST @`TEST` @"teSt" +1 1 1 1 1 +set @TEST=2; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +@test @`test` @TEST @`TEST` @"teSt" +2 2 2 2 2 +set @"tEST"=3; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +@test @`test` @TEST @`TEST` @"teSt" +3 3 3 3 3 +set @`TeST`=4; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +@test @`test` @TEST @`TEST` @"teSt" +4 4 4 4 4 +select @`teST`:=5; +@`teST`:=5 +5 +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +@test @`test` @TEST @`TEST` @"teSt" +5 5 5 5 5 +set @select=2,@t5=1.23456; +select @`select`,@not_used; +@`select` @not_used +2 NULL set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL; select @test_int,@test_double,@test_string,@test_string2,@select; @test_int @test_double @test_string @test_string2 @select diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index d1c8df64be2..dbe12554130 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -5,8 +5,20 @@ drop table if exists t1,t2; --enable_warnings -set @`test`=1,@TEST=3,@select=2,@t5=1.23456; -select @test,@`select`,@TEST,@not_used; +# case insensitivity tests (new in 5.0) +set @`test`=1; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +set @TEST=2; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +set @"tEST"=3; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +set @`TeST`=4; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; +select @`teST`:=5; +select @test, @`test`, @TEST, @`TEST`, @"teSt"; + +set @select=2,@t5=1.23456; +select @`select`,@not_used; set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL; select @test_int,@test_double,@test_string,@test_string2,@select; set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello"; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0ead869216f..7f73ed6238d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -151,9 +151,9 @@ THD::THD():user_time(0), is_fatal_error(0), bzero((char*) &warn_root,sizeof(warn_root)); init_alloc_root(&warn_root, 1024, 0); user_connect=(USER_CONN *)0; - hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0, + hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, - (hash_free_key) free_user_var,0); + (hash_free_key) free_user_var, 0); /* For user vars replication*/ if (opt_bin_log) @@ -257,7 +257,7 @@ void THD::change_user(void) cleanup(); cleanup_done= 0; init(); - hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0, + hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (hash_free_key) free_user_var, 0); } From 4523a7b179d3ef869ec232dc54cda653b3ab1abf Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Fri, 23 May 2003 15:32:31 +0200 Subject: [PATCH 73/83] Adopt SP stuff to the new lex pointer. --- mysql-test/r/sp.result | 17 ++++++++++ mysql-test/t/sp.test | 18 +++++++++++ sql/mysql_priv.h | 2 +- sql/sp.cc | 31 ++++++++++++------ sql/sp_head.cc | 71 ++++++++++++++++++------------------------ sql/sp_head.h | 8 ++--- sql/sql_lex.h | 4 +-- sql/sql_parse.cc | 35 ++++++++++++++------- sql/sql_prepare.cc | 3 ++ 9 files changed, 121 insertions(+), 68 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 29200a43975..c08d252cfe3 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -95,6 +95,23 @@ delete from t1; drop procedure zip; drop procedure zap; drop procedure bar; +create procedure c1(x int) +call c2("c", x); +create procedure c2(s char(16), x int) +call c3(x, s); +create procedure c3(x int, s char(16)) +call c4("level", x, s); +create procedure c4(l char(8), x int, s char(16)) +insert into t1 values (concat(l,s), x); +call c1(42); +select * from t1; +id data +levelc 42 +delete from t1; +drop procedure c1; +drop procedure c2; +drop procedure c3; +drop procedure c4; create procedure iotest(x1 char(16), x2 char(16), y int) begin call inc2(x2, y); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index c501501b82f..61519c52929 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -126,6 +126,24 @@ drop procedure zap| drop procedure bar| +# "Deep" calls... +create procedure c1(x int) + call c2("c", x)| +create procedure c2(s char(16), x int) + call c3(x, s)| +create procedure c3(x int, s char(16)) + call c4("level", x, s)| +create procedure c4(l char(8), x int, s char(16)) + insert into t1 values (concat(l,s), x)| + +call c1(42)| +select * from t1| +delete from t1| +drop procedure c1| +drop procedure c2| +drop procedure c3| +drop procedure c4| + # INOUT test create procedure iotest(x1 char(16), x2 char(16), y int) begin diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 64b84858282..57a7fd0f553 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -353,7 +353,7 @@ bool is_update_query(enum enum_sql_command command); void free_items(Item *item); bool alloc_query(THD *thd, char *packet, ulong packet_length); void mysql_init_select(LEX *lex); -void mysql_init_query(THD *thd); +void mysql_init_query(THD *thd, bool lexonly=0); bool mysql_new_select(LEX *lex, bool move_down); void create_select_for_variable(const char *var_name); void mysql_init_multi_delete(LEX *lex); diff --git a/sql/sp.cc b/sql/sp.cc index b1b73f30811..5c87488bcda 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -88,7 +88,6 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) DBUG_ENTER("db_find_routine"); DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); extern int yyparse(void *thd); - LEX *tmplex; TABLE *table; const char *defstr; int ret; @@ -146,15 +145,29 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) table= NULL; } - tmplex= lex_start(thd, (uchar*)defstr, strlen(defstr)); - if (yyparse(thd) || thd->is_fatal_error || tmplex->sphead == NULL) - ret= SP_PARSE_ERROR; - else { - *sphp= tmplex->sphead; - (*sphp)->sp_set_info((char *) creator, (uint) strlen(creator), - created, modified, suid, - ptr, length); + LEX *oldlex= thd->lex; + enum enum_sql_command oldcmd= thd->lex->sql_command; + + lex_start(thd, (uchar*)defstr, strlen(defstr)); + if (yyparse(thd) || thd->is_fatal_error || thd->lex->sphead == NULL) + { + if (thd->lex->sphead) + { + if (oldlex != thd->lex) + thd->lex->sphead->restore_lex(thd); + thd->lex->sphead->destroy(); + } + ret= SP_PARSE_ERROR; + } + else + { + *sphp= thd->lex->sphead; + (*sphp)->sp_set_info((char *) creator, (uint) strlen(creator), + created, modified, suid, + ptr, length); + } + thd->lex->sql_command= oldcmd; } done: diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 15a85173f8f..96624430307 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -365,54 +365,44 @@ sp_head::execute_procedure(THD *thd, List *args) void sp_head::reset_lex(THD *thd) { - memcpy(&m_lex, thd->lex, sizeof(LEX)); // Save old one + DBUG_ENTER("sp_head::reset_lex"); + LEX *sublex; + + m_lex= thd->lex; + thd->lex= sublex= new st_lex; + sublex->yylineno= m_lex->yylineno; /* Reset most stuff. The length arguments doesn't matter here. */ - lex_start(thd, m_lex.buf, m_lex.end_of_query - m_lex.ptr); + lex_start(thd, m_lex->buf, m_lex->end_of_query - m_lex->ptr); /* We must reset ptr and end_of_query again */ - thd->lex->ptr= m_lex.ptr; - thd->lex->end_of_query= m_lex.end_of_query; + sublex->ptr= m_lex->ptr; + sublex->end_of_query= m_lex->end_of_query; /* And keep the SP stuff too */ - thd->lex->sphead = m_lex.sphead; - thd->lex->spcont = m_lex.spcont; - /* Clear all lists. (QQ Why isn't this reset by lex_start()?). - We may be overdoing this, but we know for sure that value_list must - be cleared at least. */ - thd->lex->col_list.empty(); - thd->lex->ref_list.empty(); - thd->lex->drop_list.empty(); - thd->lex->alter_list.empty(); - thd->lex->interval_list.empty(); - thd->lex->users_list.empty(); - thd->lex->columns.empty(); - thd->lex->key_list.empty(); - thd->lex->create_list.empty(); - thd->lex->insert_list= NULL; - thd->lex->field_list.empty(); - thd->lex->value_list.empty(); - thd->lex->many_values.empty(); - thd->lex->var_list.empty(); - thd->lex->param_list.empty(); - thd->lex->proc_list.empty(); - thd->lex->auxilliary_table_list.empty(); + sublex->sphead= m_lex->sphead; + sublex->spcont= m_lex->spcont; + mysql_init_query(thd, true); // Only init lex + DBUG_VOID_RETURN; } // Restore lex during parsing, after we have parsed a sub statement. void sp_head::restore_lex(THD *thd) { + DBUG_ENTER("sp_head::restore_lex"); + LEX *sublex= thd->lex; + // Update some state in the old one first - m_lex.ptr= thd->lex->ptr; - m_lex.next_state= thd->lex->next_state; + m_lex->ptr= sublex->ptr; + m_lex->next_state= sublex->next_state; // Collect some data from the sub statement lex. - sp_merge_funs(&m_lex, thd->lex); + sp_merge_funs(m_lex, sublex); #if 0 // QQ We're not using this at the moment. - if (thd->lex.sql_command == SQLCOM_CALL) + if (sublex.sql_command == SQLCOM_CALL) { // It would be slightly faster to keep the list sorted, but we need // an "insert before" method to do that. - char *proc= thd->lex.udf.name.str; + char *proc= sublex.udf.name.str; List_iterator_fast li(m_calls); char **it; @@ -428,7 +418,7 @@ sp_head::restore_lex(THD *thd) // QQ ...or just open tables in thd->open_tables? // This is not entirerly clear at the moment, but for now, we collect // tables here. - for (SELECT_LEX *sl= thd->lex.all_selects_list ; + for (SELECT_LEX *sl= sublex.all_selects_list ; sl ; sl= sl->next_select()) { @@ -448,7 +438,8 @@ sp_head::restore_lex(THD *thd) } #endif - memcpy(thd->lex, &m_lex, sizeof(LEX)); // Restore lex + thd->lex= m_lex; + DBUG_VOID_RETURN; } void @@ -490,14 +481,14 @@ int sp_instr_stmt::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_stmt::execute"); - DBUG_PRINT("info", ("command: %d", m_lex.sql_command)); - LEX olex; // The other lex + DBUG_PRINT("info", ("command: %d", m_lex->sql_command)); + LEX *olex; // The other lex int res; - memcpy(&olex, thd->lex, sizeof(LEX)); // Save the other lex - - memcpy(thd->lex, &m_lex, sizeof(LEX)); // Use my own lex - thd->lex->thd = thd; + olex= thd->lex; // Save the other lex + thd->lex= m_lex; // Use my own lex + thd->lex->thd = thd; // QQ Not reentrant! + thd->lex->unit.thd= thd; // QQ Not reentrant res= mysql_execute_command(thd); if (thd->lock || thd->open_tables || thd->derived_tables) @@ -506,7 +497,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) close_thread_tables(thd); /* Free tables */ } - memcpy(thd->lex, &olex, sizeof(LEX)); // Restore the other lex + thd->lex= olex; // Restore the other lex *nextp = m_ip+1; DBUG_RETURN(res); diff --git a/sql/sp_head.h b/sql/sp_head.h index d5bf7138785..f25e141cd18 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -136,7 +136,7 @@ private: bool m_suid; sp_pcontext *m_pcont; // Parse context - LEX m_lex; // Temp. store for the other lex + LEX *m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" typedef struct { @@ -222,18 +222,18 @@ public: inline void set_lex(LEX *lex) { - memcpy(&m_lex, lex, sizeof(LEX)); + m_lex= lex; } inline LEX * get_lex() { - return &m_lex; + return m_lex; } private: - LEX m_lex; // My own lex + LEX *m_lex; // My own lex }; // class sp_instr_stmt : public sp_instr diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ecf04c1575c..09cbe107ffa 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -320,7 +320,7 @@ public: int exec(); int cleanup(); - friend void mysql_init_query(THD *thd); + friend void mysql_init_query(THD *thd, bool lexonly); friend int subselect_union_engine::exec(); private: bool create_total_list_n_last_return(THD *thd, st_lex *lex, @@ -408,7 +408,7 @@ public: order_list.next= (byte**) &order_list.first; } - friend void mysql_init_query(THD *thd); + friend void mysql_init_query(THD *thd, bool lexonly); st_select_lex(struct st_lex *lex); st_select_lex() {} void make_empty_select(st_select_lex *last_select) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d1b9fecee35..e434524957e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3433,7 +3433,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize) ****************************************************************************/ void -mysql_init_query(THD *thd) +mysql_init_query(THD *thd, bool lexonly) { DBUG_ENTER("mysql_init_query"); LEX *lex=thd->lex; @@ -3457,17 +3457,20 @@ mysql_init_query(THD *thd) lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; - thd->select_number= lex->select_lex.select_number= 1; - thd->free_list= 0; - thd->total_warn_count=0; // Warnings for this query - thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; - thd->sent_row_count= thd->examined_row_count= 0; - thd->is_fatal_error= thd->rand_used= 0; - thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; - thd->tmp_table_used= 0; - if (opt_bin_log) - reset_dynamic(&thd->user_var_events); - thd->clear_error(); + if (! lexonly) + { + thd->select_number= lex->select_lex.select_number= 1; + thd->free_list= 0; + thd->total_warn_count=0; // Warnings for this query + thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; + thd->sent_row_count= thd->examined_row_count= 0; + thd->is_fatal_error= thd->rand_used= 0; + thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; + thd->tmp_table_used= 0; + if (opt_bin_log) + reset_dynamic(&thd->user_var_events); + thd->clear_error(); + } DBUG_VOID_RETURN; } @@ -3582,7 +3585,11 @@ mysql_parse(THD *thd, char *inBuf, uint length) else { if (thd->net.report_error) + { send_error(thd, 0, NullS); + if (thd->lex->sphead) + thd->lex->sphead->destroy(); + } else { mysql_execute_command(thd); @@ -3598,8 +3605,12 @@ mysql_parse(THD *thd, char *inBuf, uint length) thd->is_fatal_error)); #ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ query_cache_abort(&thd->net); + if (thd->lex->sphead) + thd->lex->sphead->destroy(); #endif } + if (thd->lex->sphead && lex != thd->lex) + thd->lex->sphead->restore_lex(thd); thd->proc_info="freeing items"; free_items(thd->free_list); /* Free strings used by items */ lex_end(lex); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 43376012d4c..bd0a3a09422 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -71,6 +71,7 @@ Long data handling: #include "sql_acl.h" #include "sql_select.h" // for JOIN #include // for isspace() +#include "sp_head.h" #define IS_PARAM_NULL(pos, param_no) pos[param_no/8] & (1 << param_no & 7) @@ -761,6 +762,8 @@ static bool parse_prepare_query(PREP_STMT *stmt, thd->lex->param_count= 0; if (!yyparse((void *)thd) && !thd->is_fatal_error) error= send_prepare_results(stmt); + if (thd->lex->sphead && lex != thd->lex) + thd->lex->sphead->restore_lex(thd); lex_end(lex); DBUG_RETURN(error); } From ea46c24279cda90a45c1ae87cb7334b048ae8870 Mon Sep 17 00:00:00 2001 From: "greg@mysql.com[greg]" <> Date: Thu, 29 May 2003 14:28:02 -0400 Subject: [PATCH 74/83] rlyon-5.0.0-alpha.patch --- client/mysql.cc | 3 + configure.in | 17 +++-- include/config-netware.h | 20 +++++- include/my_global.h | 7 ++ include/my_pthread.h | 5 ++ mysys/my_pthread.c | 23 +++++++ netware/BUILD/compile-AUTOTOOLS | 6 ++ netware/BUILD/compile-linux-tools | 5 +- netware/BUILD/compile-netware-END | 8 ++- netware/BUILD/compile-netware-START | 5 +- netware/BUILD/compile-netware-all | 7 ++ netware/BUILD/compile-netware-debug | 6 ++ netware/BUILD/compile-netware-src | 36 ++++++++++ netware/BUILD/compile-netware-standard | 9 ++- netware/BUILD/cron-build | 46 +++++++++++++ netware/BUILD/crontab | 4 ++ netware/BUILD/knetware.imp | 2 + netware/BUILD/mwasmnlm | 3 + netware/BUILD/mwccnlm | 3 + netware/BUILD/mwenv | 8 +-- netware/BUILD/mwldnlm | 3 + netware/BUILD/nwbootstrap | 25 ++++++- netware/Makefile.am | 41 ++++++------ netware/mysql_test_run.c | 15 +++++ scripts/make_binary_distribution.sh | 93 ++++++++++++++++++-------- sql/mysqld.cc | 9 ++- sql/slave.cc | 4 -- 27 files changed, 336 insertions(+), 77 deletions(-) create mode 100644 netware/BUILD/compile-netware-src create mode 100644 netware/BUILD/cron-build create mode 100644 netware/BUILD/crontab create mode 100644 netware/BUILD/knetware.imp diff --git a/client/mysql.cc b/client/mysql.cc index 2623660033b..6ce7a3453da 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2780,6 +2780,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...) { va_list args; + NETWARE_YIELD va_start(args, fmt); (void) vfprintf(file, fmt, args); #ifdef OS2 @@ -2793,6 +2794,7 @@ void tee_fprintf(FILE *file, const char *fmt, ...) void tee_fputs(const char *s, FILE *file) { + NETWARE_YIELD fputs(s, file); #ifdef OS2 fflush( file); @@ -2804,6 +2806,7 @@ void tee_fputs(const char *s, FILE *file) void tee_puts(const char *s, FILE *file) { + NETWARE_YIELD fputs(s, file); fputs("\n", file); #ifdef OS2 diff --git a/configure.in b/configure.in index 4603e1fc9c4..5527c78124a 100644 --- a/configure.in +++ b/configure.in @@ -36,7 +36,7 @@ for i in $AVAILABLE_LANGUAGES do AVAILABLE_LANGUAGES_ERRORS="$AVAILABLE_LANGUAGES_ERRORS $i/errmsg.sys" case $host_os in - netware* | modesto*) + netware*) echo "$i/errmsg.sys: $i/errmsg.txt \$(top_builddir)/extra/comp_err.linux \$^ $i/errmsg.sys" \ >> $AVAILABLE_LANGUAGES_ERRORS_RULES @@ -458,7 +458,7 @@ else *cygwin*) FIND_PROC="$PS -e | grep mysqld | grep \" \$\$PID \" > /dev/null" ;; - *netware* | *modesto*) + *netware*) FIND_PROC= ;; *) @@ -1533,7 +1533,7 @@ AC_SUBST(LIBDL) # System characteristics case $SYSTEM_TYPE in - *netware* | *modesto*) ;; + *netware*) ;; *) AC_SYS_RESTARTABLE_SYSCALLS ;; @@ -1563,10 +1563,12 @@ else fi if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then - DEBUG_CFLAGS="$DEBUG_CFLAGS -DDEBUG -sym internal,codeview4" - DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -DDEBUG -sym internal,codeview4" - OPTIMIZE_CFLAGS="$OPTIMIZE_CFLAGS -DNDEBUG" - OPTIMIZE_CXXFLAGS="$OPTIMIZE_CXXFLAGS -DNDEBUG" + DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4" + DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4" + DEBUG_OPTIMIZE_CC="-DDEBUG" + DEBUG_OPTIMIZE_CXX="-DDEBUG" + OPTIMIZE_CFLAGS="-O3 -DNDEBUG" + OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG" fi AC_ARG_WITH(debug, @@ -2661,6 +2663,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl include/Makefile sql-bench/Makefile tools/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile mysql-test/Makefile dnl + netware/Makefile dnl include/mysql_version.h dnl , , [ test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h diff --git a/include/config-netware.h b/include/config-netware.h index dab365a7127..6a7f6291e26 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -14,7 +14,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Defines for netware compatible with MySQL */ +/* Header for NetWare compatible with MySQL */ + +#ifndef _config_netware_h +#define _config_netware_h /* required headers */ #include @@ -32,6 +35,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* required adjustments */ #undef HAVE_READDIR_R #undef HAVE_RWLOCK_INIT @@ -80,6 +87,15 @@ /* do not use the extended time in LibC sys\stat.h */ #define _POSIX_SOURCE -/* Some macros for portability */ +/* kernal call on NetWare that will only yield if our time slice is up */ +void kYieldIfTimeSliceUp(void); +/* some macros for portability */ #define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=(SEC); (ABSTIME).tv_nsec=0; } + +#ifdef __cplusplus +} +#endif + +#endif /* _config_netware_h */ + diff --git a/include/my_global.h b/include/my_global.h index 510de43c9ee..8440830a342 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -69,6 +69,13 @@ #endif #endif /* _WIN32... */ +/* extra protection against CPU Hogs on NetWare */ +#ifdef __NETWARE__ + #define NETWARE_YIELD { kYieldIfTimeSliceUp(); } +#else + #define NETWARE_YIELD { } +#endif + /* The macros below are borrowed from include/linux/compiler.h in the Linux kernel. Use them to indicate the likelyhood of the truthfulness diff --git a/include/my_pthread.h b/include/my_pthread.h index 58f89517679..bff82ef7320 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -248,6 +248,11 @@ extern int my_sigwait(const sigset_t *set,int *sig); #error Requires at least rev 2 of EMX pthreads library. #endif +#ifdef __NETWARE__ +void my_pthread_exit(void *status); +#define pthread_exit(A) my_pthread_exit(A) +#endif + extern int my_pthread_getprio(pthread_t thread_id); #define pthread_key(T,V) pthread_key_t V diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 1eb15d92bc9..f88a884a1bc 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -90,6 +90,29 @@ void *my_pthread_getspecific_imp(pthread_key_t key) } #endif +#ifdef __NETWARE__ +/* +don't kill the LibC Reaper thread or the main thread +*/ +#include +void my_pthread_exit(void *status) +{ +#undef pthread_exit + NXThreadId_t tid = NXThreadGetId(); + NXContext_t ctx; + char name[PATH_MAX] = ""; + + NXThreadGetContext(tid, &ctx); + NXContextGetName(ctx, name, PATH_MAX); + + // "MYSQLD.NLM's LibC Reaper" or "MYSQLD.NLM's main thread" + // with a debug build of LibC the reaper can have different names + if (!strindex(name, "\'s")) + { + pthread_exit(status); + } +} +#endif /* Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7 (and DEC OSF/1 3.2 too) */ diff --git a/netware/BUILD/compile-AUTOTOOLS b/netware/BUILD/compile-AUTOTOOLS index 0688ea5aaca..57213b1b3d0 100755 --- a/netware/BUILD/compile-AUTOTOOLS +++ b/netware/BUILD/compile-AUTOTOOLS @@ -1,5 +1,11 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + for package in . ./innobase do (cd $package diff --git a/netware/BUILD/compile-linux-tools b/netware/BUILD/compile-linux-tools index 598be96ab66..3590a900338 100755 --- a/netware/BUILD/compile-linux-tools +++ b/netware/BUILD/compile-linux-tools @@ -1,8 +1,11 @@ #! /bin/sh -#debug +# debug #set -x +# stop on errors +set -e + if test ! -r ./sql/mysqld.cc then echo "you must start from the top source directory" diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END index beb15fbeda3..19d24ff8c6f 100755 --- a/netware/BUILD/compile-netware-END +++ b/netware/BUILD/compile-netware-END @@ -1,5 +1,11 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + path=`dirname $0` # clean @@ -23,7 +29,7 @@ rm -rf Makefile.in.bk make clean bin-dist # mark the build -for file in *.tar.gz +for file in *.tar.gz *.zip do if (expr "$file" : "mysql-[1-9].*" > /dev/null) then diff --git a/netware/BUILD/compile-netware-START b/netware/BUILD/compile-netware-START index 2941d8868e4..7eef192a907 100755 --- a/netware/BUILD/compile-netware-START +++ b/netware/BUILD/compile-netware-START @@ -1,8 +1,11 @@ #! /bin/sh -#debug +# debug #set -x +# stop on errors +set -e + if test ! -r ./sql/mysqld.cc then echo "you must start from the top source directory" diff --git a/netware/BUILD/compile-netware-all b/netware/BUILD/compile-netware-all index f8dea0f7583..6baff699e94 100755 --- a/netware/BUILD/compile-netware-all +++ b/netware/BUILD/compile-netware-all @@ -1,7 +1,14 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + path=`dirname $0` +$path/compile-netware-src $path/compile-netware-standard $path/compile-netware-debug #$path/compile-netware-max diff --git a/netware/BUILD/compile-netware-debug b/netware/BUILD/compile-netware-debug index 2cd292c82fd..e44d64e3074 100755 --- a/netware/BUILD/compile-netware-debug +++ b/netware/BUILD/compile-netware-debug @@ -1,5 +1,11 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + path=`dirname $0` . $path/compile-netware-START diff --git a/netware/BUILD/compile-netware-src b/netware/BUILD/compile-netware-src new file mode 100644 index 00000000000..df7f6fcdd1a --- /dev/null +++ b/netware/BUILD/compile-netware-src @@ -0,0 +1,36 @@ +#! /bin/sh + +# debug +#set -x + +# stop on errors +set -e + +if test ! -r ./sql/mysqld.cc +then + echo "you must start from the top source directory" + exit 1 +fi + +path=`dirname $0` + +# clean +if test -e "Makefile"; then + make -k clean; + make -k distclean; +fi + +# remove other files +rm -f NEW-RPMS/* +rm -f */.deps/*.P +rm -rf Makefile.in.bk + +# zip source +files=`pwd | sed -e "s/.*\\\(mysql-.*\)/\1/"` +file=`pwd | sed -e "s/.*\\mysql-\(.*\)/mysql-src-\1-pc-netware-i686/"` +cd .. +if test -e "$file.zip"; then rm -f $file.zip; fi +zip -r $file.zip $files -x \*.zip -x \*.tar.gz +if test -e "./$files/$file.zip"; then mv -f ./$files/$file.zip ./$files/$file.zip.old; fi +mv -f $file.zip ./$files/$file.zip + diff --git a/netware/BUILD/compile-netware-standard b/netware/BUILD/compile-netware-standard index c09337b5fe0..45f5021862c 100755 --- a/netware/BUILD/compile-netware-standard +++ b/netware/BUILD/compile-netware-standard @@ -1,12 +1,19 @@ #! /bin/sh +# debug +#set -x + +# stop on errors +set -e + + path=`dirname $0` . $path/compile-netware-START suffix="standard" extra_configs=" \ - --with-innodb + --with-innodb \ " . $path/compile-netware-END diff --git a/netware/BUILD/cron-build b/netware/BUILD/cron-build new file mode 100644 index 00000000000..26ccde28e2a --- /dev/null +++ b/netware/BUILD/cron-build @@ -0,0 +1,46 @@ +#! /bin/sh + +# debug +#set -x + +# stop on errors +set -e + +# repository direcotry +repo_dir=`pwd` + +# show usage +show_usage() +{ + cat << EOF + +usage: cron-patch + +EOF + exit 0; +} + +echo "starting build..." + +# check for bk and repo_dir +bk help > /dev/null +repo_dir=`bk root $repo_dir` +cd $repo_dir + +# pull latest code +echo 'y' | bk pull + +# determine version +version=`grep -e "AM_INIT_AUTOMAKE(mysql, .*)" < configure.in | sed -e "s/AM_INIT_AUTOMAKE(mysql, \(.*\))/\1/"` +echo "version: $version" + +# latest revision +rev=`bk changes -e -n -d':REV:' | head -1` +echo "latest revision: $rev" + +# run bootstrap +./netware/BUILD/nwbootstrap --revision=$rev --suffix=$rev --build=all + +echo "done" + + diff --git a/netware/BUILD/crontab b/netware/BUILD/crontab new file mode 100644 index 00000000000..0097f8acaaf --- /dev/null +++ b/netware/BUILD/crontab @@ -0,0 +1,4 @@ +00 23 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysqldoc; echo 'y' | bk pull) +00 00 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysql-4.0; ./netware/BUILD/cron-build) +00 04 * * * (export PATH='/usr/local/bin:/usr/bin:/bin'; export DISPLAY=':0'; cd ~/bk/mysql-4.1; ./netware/BUILD/cron-build) + diff --git a/netware/BUILD/knetware.imp b/netware/BUILD/knetware.imp new file mode 100644 index 00000000000..d9a9372b34f --- /dev/null +++ b/netware/BUILD/knetware.imp @@ -0,0 +1,2 @@ +kYieldIfTimeSliceUp + diff --git a/netware/BUILD/mwasmnlm b/netware/BUILD/mwasmnlm index c3501112aa5..381f84ec0c8 100755 --- a/netware/BUILD/mwasmnlm +++ b/netware/BUILD/mwasmnlm @@ -1,5 +1,8 @@ #! /bin/sh +# stop on errors +set -e + args=" $*" wine --debugmsg -all -- mwasmnlm $args diff --git a/netware/BUILD/mwccnlm b/netware/BUILD/mwccnlm index 9e989485bd9..cb2d62fe8cf 100755 --- a/netware/BUILD/mwccnlm +++ b/netware/BUILD/mwccnlm @@ -1,5 +1,8 @@ #! /bin/sh +# stop on errors +set -e + # mwccnlm is having a hard time understanding "-I./../include" # convert it to "-I../include" args=" "`echo $* | sed -e 's/-I.\/../-I../g'` diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index 27f7056d251..4445bc5b2e5 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -7,8 +7,8 @@ export MYDEV="WINE_BUILD_DIR" export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/zlib-1.1.4" -export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/zlib-1.1.4" -export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;libz.a" +export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/mysql-VERSION/netware/BUILD;$MYDEV/zlib-1.1.4" +export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;knetware.imp;libz.a" export WINEPATH="$MYDEV/mw/bin" @@ -19,9 +19,9 @@ export AR='mwldnlm' export AR_FLAGS='-type library -o' export AS='mwasmnlm' export CC='mwccnlm -gccincludes' -export CFLAGS='-dialect c -proc 686 -relax_pointers' +export CFLAGS='-align 8 -proc 686 -relax_pointers -dialect c' export CXX='mwccnlm -gccincludes' -export CXXFLAGS='-dialect c++ -proc 686 -bool on -wchar_t on -relax_pointers -D_WCHAR_T' +export CXXFLAGS='-align 8 -proc 686 -relax_pointers -dialect c++ -bool on -wchar_t on -D_WCHAR_T' export LD='mwldnlm' export LDFLAGS='-entry _LibCPrelude -exit _LibCPostlude -flags pseudopreemption' export RANLIB=: diff --git a/netware/BUILD/mwldnlm b/netware/BUILD/mwldnlm index 7ad2872ccbb..28566fc5cb1 100755 --- a/netware/BUILD/mwldnlm +++ b/netware/BUILD/mwldnlm @@ -1,5 +1,8 @@ #! /bin/sh +# stop on errors +set -e + args=" $*" wine --debugmsg -all -- mwldnlm $args diff --git a/netware/BUILD/nwbootstrap b/netware/BUILD/nwbootstrap index 002e19c8e49..43b61d5254d 100755 --- a/netware/BUILD/nwbootstrap +++ b/netware/BUILD/nwbootstrap @@ -3,11 +3,11 @@ # debug #set -x -path=`dirname $0` - # stop on errors set -e +path=`dirname $0` + # repository direcotry repo_dir=`pwd` @@ -24,6 +24,7 @@ temp_dir="" revision="" rev="" build="" +suffix="" mwenv="" # show usage @@ -81,6 +82,7 @@ for arg do --wine-build-dir=*) wine_build_dir=`echo "$arg" | sed -e "s;--wine-build-dir=;;"` ;; --revision=*) revision=`echo "$arg" | sed -e "s;--revision=;;"` ;; --build=*) build=`echo "$arg" | sed -e "s;--build=;;"` ;; + --suffix=*) suffix=`echo "$arg" | sed -e "s;--suffix=;;"` ;; --doc-dir=*) doc_dir=`echo "$arg" | sed -e "s;--doc-dir=;;"` ;; *) show_usage ;; esac @@ -111,6 +113,12 @@ echo "version: $version" # build target directory target_dir="$build_dir/mysql-$version" +# add suffix +if test $suffix +then + target_dir="$target_dir-$suffix" +fi + # delete any old target if test -d $target_dir.old; then rm -rf $target_dir.old; fi @@ -139,10 +147,12 @@ then fi # make files writeable +echo "making files writable..." cd $target_dir chmod -R u+rw,g+rw . # edit the mvenv file +echo "updating the mwenv environment file..." mwenv="./netware/BUILD/mwenv" mv -f $mwenv $mwenv.org sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \ @@ -150,6 +160,17 @@ sed -e "s;WINE_BUILD_DIR;$wine_build_dir;g" \ -e "s;VERSION;$version;g" $mwenv.org > $mwenv chmod +rwx $mwenv +#edit the def file versions +echo "updating *.def file versions..." +nlm_version=`echo "$version" | sed -e "s;\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*;\1, \2, \3;"` + +for file in ./netware/*.def +do +mv -f $file $file.org +sed -e "s;VERSION.*;VERSION $nlm_version;g" $file.org > $file +rm $file.org +done + # build linux tools echo "compiling linux tools..." ./netware/BUILD/compile-linux-tools diff --git a/netware/Makefile.am b/netware/Makefile.am index 6495f538ffb..e4b9a14ecf0 100644 --- a/netware/Makefile.am +++ b/netware/Makefile.am @@ -14,35 +14,34 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -INCLUDES = -I$(srcdir)/../include -I../include -I.. -bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql -mysqld_safe_SOURCES= mysqld_safe.c my_manage.c +INCLUDES= -I$(srcdir)/../include -I../include -I.. +bin_PROGRAMS= mysqld_safe mysql_install_db mysql_test_run libmysql +mysqld_safe_SOURCES= mysqld_safe.c my_manage.c mysql_install_db_SOURCES= mysql_install_db.c my_manage.c mysql_test_run_SOURCES= mysql_test_run.c my_manage.c -libmysql_SOURCES= libmysqlmain.c -libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a +libmysql_SOURCES= libmysqlmain.c +libmysql_LDADD= ../libmysql/.libs/libmysqlclient.a -netware_build_files = client/mysql.def client/mysqladmin.def \ - client/mysqlbinlog.def client/mysqlcheck.def \ - client/mysqldump.def client/mysqlimport.def \ - client/mysqlshow.def client/mysqltest.def \ - extra/mysql_install.def extra/my_print_defaults.def \ - extra/perror.def extra/replace.def \ - extra/resolveip.def extra/comp_err.def \ - isam/isamchk.def \ - isam/isamlog.def isam/pack_isam.def \ - libmysqld/libmysqld.def myisam/myisamchk.def \ - myisam/myisamlog.def myisam/myisampack.def \ - sql/mysqld.def +netware_build_files = client/mysql.def client/mysqladmin.def \ + client/mysqlbinlog.def client/mysqlcheck.def \ + client/mysqldump.def client/mysqlimport.def \ + client/mysqlshow.def client/mysqltest.def \ + extra/mysql_install.def extra/my_print_defaults.def \ + extra/perror.def extra/replace.def \ + extra/resolveip.def extra/comp_err.def \ + isam/isamchk.def \ + isam/isamlog.def isam/pack_isam.def \ + libmysqld/libmysqld.def myisam/myisamchk.def \ + myisam/myisamlog.def myisam/myisampack.def \ + sql/mysqld.def link_sources: set -x; \ for f in $(netware_build_files); do \ - rm -f $(srcdir)/../$$f; \ - org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \ - @LN_CP_F@ $(srcdir)/$$org $(srcdir)/../$$f; \ + rm -f $(srcdir)/../$$f; \ + org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \ + @LN_CP_F@ $(srcdir)/$$org $(srcdir)/../$$f; \ done; - # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index ff629546793..8bf0b7e0016 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -266,6 +266,7 @@ void start_master() int err, i; char master_out[PATH_MAX]; char master_err[PATH_MAX]; + char temp[PATH_MAX]; // remove old berkeley db log files that can confuse the server removef("%s/log.*", master_dir); @@ -289,6 +290,20 @@ void start_master() if (master_init_script[0] != NULL) { // run_init_script(master_init_script); + + // TODO: use the scripts + if (strindex(master_init_script, "repair_part2-master.sh") != NULL) + { + FILE *fp; + + // create an empty index file + snprintf(temp, PATH_MAX, "%s/test/t1.MYI", master_dir); + fp = fopen(temp, "wb+"); + + fputs("1", fp); + + fclose(fp); + } } // redirection files diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 1731a7555e0..7e96c90905c 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -73,9 +73,25 @@ if [ $BASE_SYSTEM != "netware" ] ; then chmod o-rwx $BASE/data $BASE/data/* fi -for i in ChangeLog COPYING COPYING.LIB README Docs/INSTALL-BINARY \ - MySQLEULA.txt Docs/manual.html Docs/manual.txt Docs/manual_toc.html \ - LICENSE.doc README.NW Docs/mysqlbug.txt +# Non platform-specific doc files: +DOC_FILES=" \ + ChangeLog COPYING COPYING.LIB README \ + Docs/manual.html Docs/manual.txt Docs/manual_toc.html \ + Docs/mysqlbug.txt \ +"; + +# Platform-specific doc files: +if [ $BASE_SYSTEM = "netware" ] ; then + DOC_FILES="$DOC_FILES \ + "; +# For all other platforms: +else + DOC_FILES="$DOC_FILES \ + Docs/INSTALL-BINARY MySQLEULA.txt \ + "; +fi + +for i in $DOC_FILES do if [ -f $i ] then @@ -83,7 +99,7 @@ do fi done -# Non platform-specific bin dir files: +# Non platform-specific bin files: BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \ extra/resolveip$BS extra/my_print_defaults$BS \ extra/resolve_stack_dump$BS extra/mysql_waitpid$BS \ @@ -93,18 +109,18 @@ BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \ client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \ client/mysqldump$BS client/mysqlimport$BS \ client/mysqltest$BS client/mysqlcheck$BS \ - client/mysqlbinlog$BS + client/mysqlbinlog$BS \ "; -# Platform-specific bin dir files: +# Platform-specific bin files: if [ $BASE_SYSTEM = "netware" ] ; then BIN_FILES="$BIN_FILES \ netware/mysqld_safe$BS netware/mysql_install_db$BS \ netware/init_db.sql netware/test_db.sql netware/mysql_explain_log$BS \ - netware/mysqlhotcopy$BS netware/libmysql$BS netware/init_secure_db.sql + netware/mysqlhotcopy$BS netware/libmysql$BS netware/init_secure_db.sql \ "; +# For all other platforms: else - # For all other platforms: BIN_FILES="$BIN_FILES \ client/mysqlmanagerc \ client/mysqlmanager-pwgen tools/mysqlmanager \ @@ -224,7 +240,9 @@ rm -f $BASE/bin/Makefile* $BASE/bin/*.in $BASE/bin/*.sh $BASE/bin/mysql_install_ # Make safe_mysqld a symlink to mysqld_safe for backwards portability # To be removed in MySQL 4.1 -(cd $BASE/bin ; ln -s mysqld_safe safe_mysqld ) +if [ $BASE_SYSTEM != "netware" ] ; then + (cd $BASE/bin ; ln -s mysqld_safe safe_mysqld ) +fi # Clean up if we did this from a bk tree if [ -d $BASE/sql-bench/SCCS ] ; then @@ -283,29 +301,48 @@ which_1 () exit 1 } -# -# Create the result tar file -# - -tar=`which_1 gnutar gtar` -if test "$?" = "1" -o "$tar" = "" -then - tar=tar -fi - -echo "Using $tar to create archive" cd $TMP + +if [ $BASE_SYSTEM = "netware" ] ; then + + # + # Create a zip file for NetWare users + # + + if test -e "$SOURCE/$NEW_NAME.zip"; then rm $SOURCE/$NEW_NAME.zip; fi + zip -r $SOURCE/$NEW_NAME.zip $NEW_NAME + echo "$NEW_NAME.zip created" + +else + + # + # Create the result tar file + # + + tar=`which_1 gnutar gtar` + if test "$?" = "1" -o "$tar" = "" + then + tar=tar + fi + + echo "Using $tar to create archive" + + OPT=cvf + if [ x$SILENT = x1 ] ; then + OPT=cf + fi + + $tar $OPT $SOURCE/$NEW_NAME.tar $NEW_NAME + cd $SOURCE + + echo "Compressing archive" + gzip -9 $NEW_NAME.tar + + echo "$NEW_NAME.tar.gz created" -OPT=cvf -if [ x$SILENT = x1 ] ; then - OPT=cf fi -$tar $OPT $SOURCE/$NEW_NAME.tar $NEW_NAME -cd $SOURCE -echo "Compressing archive" -gzip -9 $NEW_NAME.tar echo "Removing temporary directory" rm -r -f $BASE -echo "$NEW_NAME.tar.gz created" + diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 32ab02807b9..f356a5135ee 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -825,11 +825,12 @@ static void __cdecl kill_server(int sig_ptr) unireg_abort(1); /* purecov: inspected */ else unireg_end(); + #ifdef __NETWARE__ pthread_join(select_thread, NULL); // wait for main thread -#else - pthread_exit(0); /* purecov: deadcode */ #endif /* __NETWARE__ */ + + pthread_exit(0); /* purecov: deadcode */ #endif /* EMBEDDED_LIBRARY */ RETURN_FROM_KILL_SERVER; @@ -887,13 +888,11 @@ void unireg_end(void) { clean_up(1); my_thread_end(); -#ifndef __NETWARE__ -#ifdef SIGNALS_DONT_BREAK_READ +#if defined(SIGNALS_DONT_BREAK_READ) && !defined(__NETWARE__) exit(0); #else pthread_exit(0); // Exit is in main thread #endif -#endif /* __NETWARE__ */ } diff --git a/sql/slave.cc b/sql/slave.cc index 1c5ad681153..9e8fb90c066 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2429,9 +2429,7 @@ err: goto slave_begin; #endif my_thread_end(); -#ifndef __NETWARE__ pthread_exit(0); -#endif /* __NETWARE__ */ DBUG_RETURN(0); // Can't return anything here } @@ -2573,9 +2571,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ goto slave_begin; #endif my_thread_end(); -#ifndef __NETWARE__ pthread_exit(0); -#endif /* __NETWARE__ */ DBUG_RETURN(0); // Can't return anything here } From 99121518b4b795d115ced90b35de629bc2954ac8 Mon Sep 17 00:00:00 2001 From: "greg@mysql.com" <> Date: Thu, 29 May 2003 14:44:00 -0400 Subject: [PATCH 75/83] Reviewed Novell-supplied patch for 5.0 tree --- configure.in | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.in b/configure.in index 5527c78124a..24c15686e67 100644 --- a/configure.in +++ b/configure.in @@ -2663,7 +2663,6 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl include/Makefile sql-bench/Makefile tools/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile mysql-test/Makefile dnl - netware/Makefile dnl include/mysql_version.h dnl , , [ test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h From 7c6522a74ed868e6b67577ebdaa0b1675ac7890b Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Mon, 2 Jun 2003 14:25:01 +0500 Subject: [PATCH 76/83] 'Expand the mysql.proc table to include (almost) all fields' task(851) Fix after review --- mysql-test/install_test_db.sh | 2 +- scripts/mysql_install_db.sh | 2 +- sql/sp.cc | 14 +++++--------- sql/sp_head.cc | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index 8477a0cd66d..1cb49b72fdd 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -254,8 +254,8 @@ then c_p="$c_p type enum('function','procedure') NOT NULL," c_p="$c_p body blob DEFAULT '' NOT NULL," c_p="$c_p creator char(77) binary DEFAULT '' NOT NULL," - c_p="$c_p created timestamp," c_p="$c_p modified timestamp," + c_p="$c_p created timestamp," c_p="$c_p suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL," c_p="$c_p comment char(64) binary DEFAULT '' NOT NULL," c_p="$c_p PRIMARY KEY (name,type)" diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 9e7032244cc..246fd33d1c6 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -362,8 +362,8 @@ then c_p="$c_p type enum('function','procedure') NOT NULL," c_p="$c_p body blob DEFAULT '' NOT NULL," c_p="$c_p creator char(77) binary DEFAULT '' NOT NULL," - c_p="$c_p created timestamp," c_p="$c_p modified timestamp," + c_p="$c_p created timestamp," c_p="$c_p suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL," c_p="$c_p comment char(64) binary DEFAULT '' NOT NULL," c_p="$c_p PRIMARY KEY (name,type)" diff --git a/sql/sp.cc b/sql/sp.cc index 5c87488bcda..f44335a6c75 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -118,8 +118,8 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) goto done; } - created= table->field[4]->val_int(); - modified= table->field[5]->val_int(); + modified= table->field[4]->val_int(); + created= table->field[5]->val_int(); if ((ptr= get_field(&thd->mem_root, table->field[6])) == NULL) { @@ -130,14 +130,9 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) suid= 0; table->field[7]->val_str(&str,&str); - length=str.length(); ptr= 0; - if (length) - { - ptr= (char*) alloc_root(&thd->mem_root,length+1); - memcpy(ptr,str.ptr(),(uint) length); - ptr[length]=0; - } + if ((length= str.length())) + ptr= strmake_root(&thd->mem_root, str.ptr(),length); if (opened) { @@ -203,6 +198,7 @@ db_create_routine(THD *thd, int type, table->field[1]->store((longlong)type); table->field[2]->store(def, deflen, system_charset_info); table->field[3]->store(creator, (uint) strlen(creator), system_charset_info); + ((Field_timestamp*) table->field[5])->set_time(); if (suid) table->field[6]->store((longlong) suid); if (comment) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 96624430307..f4bfb74dd3c 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -101,7 +101,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) m_name.length= name->length; m_name.str= name->str; m_defstr.length= lex->end_of_query - lex->buf; - m_defstr.str= sql_strmake(dstr, m_defstr.length); + m_defstr.str= lex->thd->strmake(dstr, m_defstr.length); m_comment.length= 0; m_comment.str= 0; From 541c94fcf1f95e22aef9cff615ebe3c2594f0a0a Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 12 Jun 2003 15:31:20 +0200 Subject: [PATCH 77/83] Fixed bug #643, which caused intermittent crashes in net_printf() with repeated syntax errors in stored procedures. --- mysql-test/r/sp-error.result | 6 ++++++ mysql-test/t/sp-error.test | 10 ++++++++++ sql/sp_head.cc | 1 + 3 files changed, 17 insertions(+) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 99bdfc25ba8..0c1db1703ac 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1,4 +1,10 @@ delete from mysql.proc; +create procedure syntaxerror(t int); +You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +create procedure syntaxerror(t int); +You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +create procedure syntaxerror(t int); +You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 create procedure proc1() set @x = 42; create function func1() returns int diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 93852b2219d..8fa0b3c55cf 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -7,6 +7,16 @@ delete from mysql.proc; delimiter |; +# This should give three syntax errors (sometimes crashed; bug #643) +# (Unfortunately, this is not a 100% test, on some platforms this +# passed despite the bug.) +--error 1064 +create procedure syntaxerror(t int)| +--error 1064 +create procedure syntaxerror(t int)| +--error 1064 +create procedure syntaxerror(t int)| + # Check that we get the right error, i.e. UDF declaration parses correctly, # but foo.so doesn't exist. # QQ This generates an error message containing a misleading errno which diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f4bfb74dd3c..04a7ef8aa09 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -376,6 +376,7 @@ sp_head::reset_lex(THD *thd) /* We must reset ptr and end_of_query again */ sublex->ptr= m_lex->ptr; sublex->end_of_query= m_lex->end_of_query; + sublex->tok_start= m_lex->tok_start; /* And keep the SP stuff too */ sublex->sphead= m_lex->sphead; sublex->spcont= m_lex->spcont; From 9f14ae75161d9ec6d7efb9bbade21a1a36cd2099 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Sun, 29 Jun 2003 18:15:17 +0200 Subject: [PATCH 78/83] sp_head now has its own mem_root (WL#961). Also fixed some difficult memory leaks that became apparent in this task. --- sql/sp.cc | 5 ++- sql/sp_head.cc | 91 ++++++++++++++++++++++++++++++++++++++-------- sql/sp_head.h | 41 ++++++++++++++++++--- sql/sql_lex.h | 1 + sql/sql_parse.cc | 34 +++++++++++------ sql/sql_prepare.cc | 12 +++++- sql/sql_yacc.yy | 7 +++- 7 files changed, 155 insertions(+), 36 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index f44335a6c75..8fd0273fcce 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -151,7 +151,8 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) { if (oldlex != thd->lex) thd->lex->sphead->restore_lex(thd); - thd->lex->sphead->destroy(); + delete thd->lex->sphead; + thd->lex= NULL; } ret= SP_PARSE_ERROR; } @@ -444,7 +445,7 @@ sp_clear_function_cache(THD *thd) sp_head *sp; while ((sp= li++)) - sp->destroy(); + delete sp; thd->spfuns.empty(); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 04a7ef8aa09..51fc7b1ef94 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -81,7 +81,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) String *s= it->val_str(&tmp); DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick())); - it= new Item_string(sql_strmake(s->c_ptr_quick(), s->length()), + it= new Item_string(thd->strmake(s->c_ptr_quick(), s->length()), s->length(), it->charset()); break; } @@ -91,6 +91,34 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) DBUG_RETURN(it); } +void * +sp_head::operator new(size_t size) +{ + DBUG_ENTER("sp_head::operator new"); + MEM_ROOT own_root; + sp_head *sp; + + bzero((char *)&own_root, sizeof(own_root)); + init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + sp= (sp_head *)alloc_root(&own_root, size); + sp->m_mem_root= own_root; + + DBUG_RETURN(sp); +} + +void +sp_head::operator delete(void *ptr, size_t size) +{ + DBUG_ENTER("sp_head::operator delete"); + MEM_ROOT own_root; + sp_head *sp= (sp_head *)ptr; + + memcpy(&own_root, (const void *)&sp->m_mem_root, sizeof(MEM_ROOT)); + free_root(&own_root, MYF(0)); + + DBUG_VOID_RETURN; +} + sp_head::sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) : Sql_alloc(), m_simple_case(FALSE), m_multi_query(FALSE) { @@ -102,6 +130,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) m_name.str= name->str; m_defstr.length= lex->end_of_query - lex->buf; m_defstr.str= lex->thd->strmake(dstr, m_defstr.length); + m_free_list= NULL; m_comment.length= 0; m_comment.str= 0; @@ -115,6 +144,7 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) m_pcont= lex->spcont; my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_backpatch.empty(); + m_lex.empty(); DBUG_VOID_RETURN; } @@ -142,13 +172,31 @@ sp_head::create(THD *thd) DBUG_RETURN(ret); } +sp_head::~sp_head() +{ + destroy(); + if (m_thd) + restore_thd_mem_root(m_thd); +} + void sp_head::destroy() { DBUG_ENTER("sp_head::destroy"); DBUG_PRINT("info", ("name: %s", m_name.str)); + sp_instr *i; + LEX *lex; + + for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) + delete i; delete_dynamic(&m_instr); m_pcont->destroy(); + free_items(m_free_list); + while ((lex= (LEX *)m_lex.pop())) + { + if (lex != &m_thd->main_lex) // We got interrupted and have lex'es left + delete lex; + } DBUG_VOID_RETURN; } @@ -367,20 +415,22 @@ sp_head::reset_lex(THD *thd) { DBUG_ENTER("sp_head::reset_lex"); LEX *sublex; + LEX *oldlex= thd->lex; - m_lex= thd->lex; + (void)m_lex.push_front(oldlex); thd->lex= sublex= new st_lex; - sublex->yylineno= m_lex->yylineno; + sublex->yylineno= oldlex->yylineno; /* Reset most stuff. The length arguments doesn't matter here. */ - lex_start(thd, m_lex->buf, m_lex->end_of_query - m_lex->ptr); + lex_start(thd, oldlex->buf, oldlex->end_of_query - oldlex->ptr); /* We must reset ptr and end_of_query again */ - sublex->ptr= m_lex->ptr; - sublex->end_of_query= m_lex->end_of_query; - sublex->tok_start= m_lex->tok_start; + sublex->ptr= oldlex->ptr; + sublex->end_of_query= oldlex->end_of_query; + sublex->tok_start= oldlex->tok_start; /* And keep the SP stuff too */ - sublex->sphead= m_lex->sphead; - sublex->spcont= m_lex->spcont; + sublex->sphead= oldlex->sphead; + sublex->spcont= oldlex->spcont; mysql_init_query(thd, true); // Only init lex + sublex->sp_lex_in_use= FALSE; DBUG_VOID_RETURN; } @@ -390,14 +440,18 @@ sp_head::restore_lex(THD *thd) { DBUG_ENTER("sp_head::restore_lex"); LEX *sublex= thd->lex; + LEX *oldlex= (LEX *)m_lex.pop(); + + if (! oldlex) + return; // Nothing to restore // Update some state in the old one first - m_lex->ptr= sublex->ptr; - m_lex->next_state= sublex->next_state; + oldlex->ptr= sublex->ptr; + oldlex->next_state= sublex->next_state; // Collect some data from the sub statement lex. - sp_merge_funs(m_lex, sublex); -#if 0 + sp_merge_funs(oldlex, sublex); +#ifdef NOT_USED_NOW // QQ We're not using this at the moment. if (sublex.sql_command == SQLCOM_CALL) { @@ -438,8 +492,9 @@ sp_head::restore_lex(THD *thd) } } #endif - - thd->lex= m_lex; + if (! sublex->sp_lex_in_use) + delete sublex; + thd->lex= oldlex; DBUG_VOID_RETURN; } @@ -478,6 +533,12 @@ sp_head::backpatch(sp_label_t *lab) // // sp_instr_stmt // +sp_instr_stmt::~sp_instr_stmt() +{ + if (m_lex) + delete m_lex; +} + int sp_instr_stmt::execute(THD *thd, uint *nextp) { diff --git a/sql/sp_head.h b/sql/sp_head.h index f25e141cd18..dc27da5c5b2 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -54,11 +54,19 @@ public: List m_tables; // Used tables. #endif + static void * + operator new(size_t size); + + static void + operator delete(void *ptr, size_t size); + sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid); int create(THD *thd); + virtual ~sp_head(); + // Free memory void destroy(); @@ -87,6 +95,7 @@ public: // Restores lex in 'thd' from our copy, but keeps some status from the // one in 'thd', like ptr, tables, fields, etc. + // If 'delete_lex' is true, we delete the current lex. void restore_lex(THD *thd); @@ -122,10 +131,33 @@ public: m_comment.length= commentlen; m_comment.str= comment; m_suid= suid; - } + } + + inline void reset_thd_mem_root(THD *thd) + { + m_thd_root= thd->mem_root; + thd->mem_root= m_mem_root; + m_free_list= thd->free_list; // Keep the old list + thd->free_list= NULL; // Start a new one + m_thd= thd; + } + + inline void restore_thd_mem_root(THD *thd) + { + Item *flist= m_free_list; // The old list + m_free_list= thd->free_list; // Get the new one + thd->free_list= flist; // Restore the old one + m_mem_root= thd->mem_root; + thd->mem_root= m_thd_root; + m_thd= NULL; + } private: + MEM_ROOT m_mem_root; // My own mem_root + MEM_ROOT m_thd_root; // Temp. store for thd's mem_root + Item *m_free_list; // Where the items go + THD *m_thd; // Set if we have reset mem_root LEX_STRING m_name; LEX_STRING m_defstr; LEX_STRING m_comment; @@ -136,7 +168,7 @@ private: bool m_suid; sp_pcontext *m_pcont; // Parse context - LEX *m_lex; // Temp. store for the other lex + List m_lex; // Temp. store for the other lex DYNAMIC_ARRAY m_instr; // The "instructions" typedef struct { @@ -211,11 +243,10 @@ class sp_instr_stmt : public sp_instr public: sp_instr_stmt(uint ip) - : sp_instr(ip) + : sp_instr(ip), m_lex(NULL) {} - virtual ~sp_instr_stmt() - {} + virtual ~sp_instr_stmt(); virtual int execute(THD *thd, uint *nextp); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 09cbe107ffa..ffb1b2b0df7 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -495,6 +495,7 @@ typedef struct st_lex char *help_arg; SQL_LIST *gorder_list; sp_head *sphead; + bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ sp_pcontext *spcont; List spfuns; /* Called functions */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e434524957e..b29e1734302 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2829,7 +2829,7 @@ mysql_execute_command(THD *thd) sp_head *sph= sp_find_function(thd, &lex->udf.name); if (sph) { - sph->destroy(); // QQ Free memory. Remove this when caching!!! + delete sph; // QQ Free memory. Remove this when caching!!! net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str); goto error; } @@ -3029,18 +3029,22 @@ mysql_execute_command(THD *thd) #endif res= lex->sphead->create(thd); - lex->sphead->destroy(); // QQ Free memory. Remove this when caching!!! - switch (res) { case SP_OK: send_ok(thd); + delete lex->sphead; // QQ Free memory. Remove this when caching!!! + lex->sphead= NULL; break; case SP_WRITE_ROW_FAILED: net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name); + delete lex->sphead; // QQ Free memory. Remove this when caching!!! + lex->sphead= NULL; goto error; default: net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name); + delete lex->sphead; // QQ Free memory. Remove this when caching!!! + lex->sphead= NULL; goto error; } break; @@ -3064,7 +3068,7 @@ mysql_execute_command(THD *thd) if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || (res= open_and_lock_tables(thd, tables)))) { - sp->destroy(); // QQ Free memory. Remove this when caching!!! + delete sp; // Free memory. Remove this when caching!!! break; } fix_tables_pointers(lex->all_selects_list); @@ -3083,7 +3087,7 @@ mysql_execute_command(THD *thd) #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif - sp->destroy(); // QQ Free memory. Remove this when caching!!! + delete sp; // QQ Free memory. Remove this when caching!!! goto error; } smrx= thd->server_status & SERVER_MORE_RESULTS_EXISTS; @@ -3101,7 +3105,7 @@ mysql_execute_command(THD *thd) thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; } - sp->destroy(); // QQ Free memory. Remove this when caching!!! + delete sp; // QQ Free memory. Remove this when caching!!! if (res == 0) send_ok(thd); @@ -3128,7 +3132,7 @@ mysql_execute_command(THD *thd) { /* QQ This is an no-op right now, since we haven't put the characteristics in yet. */ - sp->destroy(); // QQ Free memory. Remove this when caching!!! + delete sp; // QQ Free memory. Remove this when caching!!! send_ok(thd); } break; @@ -3588,7 +3592,12 @@ mysql_parse(THD *thd, char *inBuf, uint length) { send_error(thd, 0, NullS); if (thd->lex->sphead) - thd->lex->sphead->destroy(); + { + if (lex != thd->lex) + thd->lex->sphead->restore_lex(thd); + delete thd->lex->sphead; + thd->lex->sphead= NULL; + } } else { @@ -3606,11 +3615,14 @@ mysql_parse(THD *thd, char *inBuf, uint length) #ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ query_cache_abort(&thd->net); if (thd->lex->sphead) - thd->lex->sphead->destroy(); + { + if (lex != thd->lex) + thd->lex->sphead->restore_lex(thd); + delete thd->lex->sphead; + thd->lex->sphead= NULL; + } #endif } - if (thd->lex->sphead && lex != thd->lex) - thd->lex->sphead->restore_lex(thd); thd->proc_info="freeing items"; free_items(thd->free_list); /* Free strings used by items */ lex_end(lex); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index bd0a3a09422..155e7b4b461 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -762,8 +762,16 @@ static bool parse_prepare_query(PREP_STMT *stmt, thd->lex->param_count= 0; if (!yyparse((void *)thd) && !thd->is_fatal_error) error= send_prepare_results(stmt); - if (thd->lex->sphead && lex != thd->lex) - thd->lex->sphead->restore_lex(thd); + else + { + if (thd->lex->sphead) + { + if (lex != thd->lex) + thd->lex->sphead->restore_lex(thd); + delete thd->lex->sphead; + thd->lex->sphead= NULL; + } + } lex_end(lex); DBUG_RETURN(error); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 742a834e447..98270b93cb7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -948,6 +948,7 @@ create: lex->sphead->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); + lex->sphead->reset_thd_mem_root(YYTHD); } '(' sp_pdparam_list ')' { @@ -961,6 +962,7 @@ create: /* Restore flag if it was cleared above */ if (lex->sphead->m_old_cmq) YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; + lex->sphead->restore_thd_mem_root(YYTHD); } ; @@ -997,6 +999,7 @@ create_function_tail: lex->sphead->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; + lex->sphead->reset_thd_mem_root(YYTHD); } sp_fdparam_list ')' { @@ -1014,6 +1017,7 @@ create_function_tail: /* Restore flag if it was cleared above */ if (lex->sphead->m_old_cmq) YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; + lex->sphead->restore_thd_mem_root(YYTHD); } ; @@ -1174,7 +1178,7 @@ sp_proc_stmt: ** which get their set instructions generated separately.) */ if (lex->sql_command != SQLCOM_SET_OPTION || - !lex->var_list.is_empty()) + ! lex->var_list.is_empty()) { /* Currently we can't handle queries inside a FUNCTION, ** because of the way table locking works. @@ -1194,6 +1198,7 @@ sp_proc_stmt: i->set_lex(lex); lex->sphead->add_instr(i); + lex->sp_lex_in_use= TRUE; } } lex->sphead->restore_lex(YYTHD); From 4006e95808d71325d66c39039abb2980b9384e04 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 1 Jul 2003 17:19:48 +0200 Subject: [PATCH 79/83] Bugfixes for the sp_head memroot stuff. --- sql/sp.cc | 13 ++++++++----- sql/sp_head.cc | 23 +++++++++++++++-------- sql/sp_head.h | 6 +++++- sql/sql_yacc.yy | 30 ++++++++++++++++++------------ 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 8fd0273fcce..79beb78e3e5 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -147,12 +147,15 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) lex_start(thd, (uchar*)defstr, strlen(defstr)); if (yyparse(thd) || thd->is_fatal_error || thd->lex->sphead == NULL) { - if (thd->lex->sphead) + LEX *newlex= thd->lex; + sp_head *sp= newlex->sphead; + + if (sp) { - if (oldlex != thd->lex) - thd->lex->sphead->restore_lex(thd); - delete thd->lex->sphead; - thd->lex= NULL; + if (oldlex != newlex) + sp->restore_lex(thd); + delete sp; + newlex->sphead= NULL; } ret= SP_PARSE_ERROR; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 51fc7b1ef94..b9360a35593 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -119,18 +119,27 @@ sp_head::operator delete(void *ptr, size_t size) DBUG_VOID_RETURN; } -sp_head::sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) - : Sql_alloc(), m_simple_case(FALSE), m_multi_query(FALSE) +sp_head::sp_head() + : Sql_alloc(), m_simple_case(FALSE), m_multi_query(FALSE), m_free_list(NULL) { DBUG_ENTER("sp_head::sp_head"); + + m_backpatch.empty(); + m_lex.empty(); + DBUG_VOID_RETURN; +} + +void +sp_head::init(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) +{ + DBUG_ENTER("sp_head::init"); const char *dstr = (const char*)lex->buf; - DBUG_PRINT("info", ("name: %s", name->str)); + DBUG_PRINT("info", ("name: %*s", name->length, name->str)); m_name.length= name->length; - m_name.str= name->str; + m_name.str= lex->thd->strmake(name->str, name->length); m_defstr.length= lex->end_of_query - lex->buf; m_defstr.str= lex->thd->strmake(dstr, m_defstr.length); - m_free_list= NULL; m_comment.length= 0; m_comment.str= 0; @@ -141,10 +150,8 @@ sp_head::sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) } m_suid= suid; - m_pcont= lex->spcont; + lex->spcont= m_pcont= new sp_pcontext(); my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); - m_backpatch.empty(); - m_lex.empty(); DBUG_VOID_RETURN; } diff --git a/sql/sp_head.h b/sql/sp_head.h index dc27da5c5b2..df551897fbb 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -60,7 +60,11 @@ public: static void operator delete(void *ptr, size_t size); - sp_head(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid); + sp_head(); + + // Initialize after we have reset mem_root + void + init(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid); int create(THD *thd); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 98270b93cb7..b4065a7d095 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -931,24 +931,27 @@ create: | CREATE PROCEDURE ident { LEX *lex= Lex; + sp_head *sp; if (lex->sphead) { net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "PROCEDURE"); YYABORT; } - lex->spcont= new sp_pcontext(); - lex->sphead= new sp_head(&$3, lex, 0, 0); - lex->sphead->m_type= TYPE_ENUM_PROCEDURE; + /* Order is important here: new - reset - init */ + sp= new sp_head(); + sp->reset_thd_mem_root(YYTHD); + sp->init(&$3, lex, 0, 0); + + sp->m_type= TYPE_ENUM_PROCEDURE; + lex->sphead= sp; /* * We have to turn of CLIENT_MULTI_QUERIES while parsing a * stored procedure, otherwise yylex will chop it into pieces * at each ';'. */ - lex->sphead->m_old_cmq= - YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); - lex->sphead->reset_thd_mem_root(YYTHD); } '(' sp_pdparam_list ')' { @@ -982,24 +985,27 @@ create_function_tail: | '(' { LEX *lex= Lex; + sp_head *sp; if (lex->sphead) { net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "FUNCTION"); YYABORT; } - lex->spcont= new sp_pcontext(); - lex->sphead= new sp_head(&lex->udf.name, lex, 0, 0); - lex->sphead->m_type= TYPE_ENUM_FUNCTION; + /* Order is important here: new - reset - init */ + sp= new sp_head(); + sp->reset_thd_mem_root(YYTHD); + sp->init(&lex->udf.name, lex, 0, 0); + + sp->m_type= TYPE_ENUM_FUNCTION; + lex->sphead= sp; /* * We have to turn of CLIENT_MULTI_QUERIES while parsing a * stored procedure, otherwise yylex will chop it into pieces * at each ';'. */ - lex->sphead->m_old_cmq= - YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; - lex->sphead->reset_thd_mem_root(YYTHD); } sp_fdparam_list ')' { From 1d3c703d58af5b98ba1055054319d5c5b521b335 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 1 Jul 2003 18:14:24 +0200 Subject: [PATCH 80/83] SP cache (WL#730). (Mostly by vva, additions by pem.) --- sql/sp.cc | 97 +++++++++++++++++++++++++++--------------------- sql/sp.h | 6 +-- sql/sql_class.cc | 19 +++++++--- sql/sql_class.h | 2 +- sql/sql_parse.cc | 19 ---------- 5 files changed, 70 insertions(+), 73 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 79beb78e3e5..ecbe0ff3955 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -22,6 +22,9 @@ static sp_head * sp_find_cached_function(THD *thd, char *name, uint namelen); +static sp_head * +sp_find_cached_procedure(THD *thd, char *name, uint namelen); + /* * * DB storage of Stored PROCEDUREs and FUNCTIONs @@ -254,9 +257,17 @@ sp_find_procedure(THD *thd, LEX_STRING *name) DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); - if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, - name->str, name->length, &sp) != SP_OK) - sp= NULL; + sp= sp_find_cached_procedure(thd, name->str, name->length); + if (! sp) + { + if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, + name->str, name->length, &sp) == SP_OK) + { + HASH *phash= thd->sp_hash+TYPE_ENUM_PROCEDURE-1; + + hash_insert(phash, (const byte*)sp); + } + } DBUG_RETURN(sp); } @@ -280,8 +291,17 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) { DBUG_ENTER("sp_drop_procedure"); DBUG_PRINT("enter", ("name: %*s", namelen, name)); + sp_head *sp; int ret; + sp= sp_find_cached_procedure(thd, name, namelen); + if (sp) + { + HASH *phash= thd->sp_hash+TYPE_ENUM_PROCEDURE-1; + + hash_delete(phash, (byte*)sp); + delete sp; + } ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen); DBUG_RETURN(ret); @@ -331,8 +351,17 @@ sp_drop_function(THD *thd, char *name, uint namelen) { DBUG_ENTER("sp_drop_function"); DBUG_PRINT("enter", ("name: %*s", namelen, name)); + sp_head *sp; int ret; + sp= sp_find_cached_function(thd, name, namelen); + if (sp) + { + HASH *fhash= thd->sp_hash+TYPE_ENUM_FUNCTION-1; + + hash_delete(fhash, (byte*)sp); + delete sp; + } ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen); DBUG_RETURN(ret); @@ -344,9 +373,10 @@ sp_function_exists(THD *thd, LEX_STRING *name) { TABLE *table; bool ret= FALSE; - bool opened; + bool opened= FALSE; - if (db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, + if (sp_find_cached_function(thd, name->str, name->length) || + db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, name->str, name->length, TL_READ, &table, &opened) == SP_OK) { @@ -358,13 +388,6 @@ sp_function_exists(THD *thd, LEX_STRING *name) } -/* - * - * The temporary FUNCTION cache. (QQ This will be rehacked later, but - * it's needed now to make functions work at all.) - * - */ - void sp_add_fun_to_lex(LEX *lex, LEX_STRING fun) { @@ -411,25 +434,22 @@ sp_cache_functions(THD *thd, LEX *lex) char *fn; enum_sql_command cmd= lex->sql_command; int ret= 0; + HASH *fhash= thd->sp_hash+TYPE_ENUM_FUNCTION-1; while ((fn= li++)) { - List_iterator_fast lisp(thd->spfuns); sp_head *sp; + int len= strlen(fn); - while ((sp= lisp++)) - { - if (my_strcasecmp(system_charset_info, fn, sp->name()) == 0) - break; - } - if (sp) + if (hash_search(fhash,(const byte*)fn,len)) continue; - if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, strlen(fn), &sp) == SP_OK) + + if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, len, &sp) == SP_OK) { ret= sp_cache_functions(thd, thd->lex); if (ret) break; - thd->spfuns.push_back(sp); + hash_insert(fhash,(const byte*)sp); } else { @@ -441,32 +461,23 @@ sp_cache_functions(THD *thd, LEX *lex) return ret; } -void -sp_clear_function_cache(THD *thd) +byte * +hash_get_key_for_sp_head(const byte *ptr, uint *plen, + my_bool first) { - List_iterator_fast li(thd->spfuns); - sp_head *sp; - - while ((sp= li++)) - delete sp; - thd->spfuns.empty(); + return ((sp_head*)ptr)->name(plen); } static sp_head * sp_find_cached_function(THD *thd, char *name, uint namelen) { - List_iterator_fast li(thd->spfuns); - sp_head *sp; - - while ((sp= li++)) - { - uint len; - const uchar *n= (const uchar *)sp->name(&len); - - if (my_strnncoll(system_charset_info, - (const uchar *)name, namelen, - n, len) == 0) - break; - } - return sp; + return (sp_head*)hash_search(thd->sp_hash+TYPE_ENUM_FUNCTION-1, + (const byte*)name,namelen); +} + +static sp_head * +sp_find_cached_procedure(THD *thd, char *name, uint namelen) +{ + return (sp_head*)hash_search(thd->sp_hash+TYPE_ENUM_PROCEDURE-1, + (const byte*)name,namelen); } diff --git a/sql/sp.h b/sql/sp.h index 3a021288907..bbf8832d55d 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -53,15 +53,13 @@ bool sp_function_exists(THD *thd, LEX_STRING *name); -// QQ More temporary stuff until the real cache is implemented. This is -// needed since we have to read the functions before we do anything else. +// This is needed since we have to read the functions before we +// do anything else. void sp_add_fun_to_lex(LEX *lex, LEX_STRING fun); void sp_merge_funs(LEX *dst, LEX *src); int sp_cache_functions(THD *thd, LEX *lex); -void -sp_clear_function_cache(THD *thd); #endif /* _SP_H_ */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c64bb7ff8fa..5ab096b91e4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -38,6 +38,8 @@ #include +byte *hash_get_key_for_sp_head(const byte*,uint*,my_bool); + /* The following is used to initialise Table_ident with a internal table name @@ -155,6 +157,11 @@ THD::THD():user_time(0), is_fatal_error(0), hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (hash_free_key) free_user_var, 0); + + hash_init(sp_hash,system_charset_info,0,0,0, + hash_get_key_for_sp_head,0,0); + hash_init(sp_hash+1,system_charset_info,0,0,0, + hash_get_key_for_sp_head,0,0); /* For user vars replication*/ if (opt_bin_log) @@ -200,9 +207,6 @@ THD::THD():user_time(0), is_fatal_error(0), pthread_mutex_unlock(&LOCK_thread_count); randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id); } - - /* QQ init the temporary function cache */ - spfuns.empty(); } @@ -261,6 +265,10 @@ void THD::change_user(void) hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (hash_free_key) free_user_var, 0); + hash_init(sp_hash,system_charset_info,0,0,0, + hash_get_key_for_sp_head,0,0); + hash_init(sp_hash+1,system_charset_info,0,0,0, + hash_get_key_for_sp_head,0,0); } @@ -284,6 +292,8 @@ void THD::cleanup(void) close_temporary_tables(this); delete_dynamic(&user_var_events); hash_free(&user_vars); + hash_free(sp_hash); + hash_free(sp_hash+1); if (global_read_lock) unlock_global_read_lock(this); if (ull) @@ -294,9 +304,6 @@ void THD::cleanup(void) ull= 0; } - // extern void sp_clear_function_cache(THD *); - // sp_clear_function_cache(this); - cleanup_done=1; DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 3bb0f348024..cebcdf68391 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -551,7 +551,7 @@ public: bool prepare_command; bool tmp_table_used; sp_rcontext *spcont; // SP runtime context - List spfuns; // SP FUNCTIONs + HASH sp_hash[2]; // hash for SP PROCEDURES and FUNCTIONS /* If we do a purge of binary logs, log index info of the threads diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b29e1734302..6a02383e984 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1527,13 +1527,6 @@ restore_user: VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory - /* - Clear the SP function cache after each statement (QQ this is a temporary - solution; caching will be rehacked later). - Note: Must do this before we free_root. - */ - sp_clear_function_cache(thd); - free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); DBUG_RETURN(error); } @@ -2829,7 +2822,6 @@ mysql_execute_command(THD *thd) sp_head *sph= sp_find_function(thd, &lex->udf.name); if (sph) { - delete sph; // QQ Free memory. Remove this when caching!!! net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str); goto error; } @@ -3033,18 +3025,12 @@ mysql_execute_command(THD *thd) { case SP_OK: send_ok(thd); - delete lex->sphead; // QQ Free memory. Remove this when caching!!! - lex->sphead= NULL; break; case SP_WRITE_ROW_FAILED: net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name); - delete lex->sphead; // QQ Free memory. Remove this when caching!!! - lex->sphead= NULL; goto error; default: net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name); - delete lex->sphead; // QQ Free memory. Remove this when caching!!! - lex->sphead= NULL; goto error; } break; @@ -3068,7 +3054,6 @@ mysql_execute_command(THD *thd) if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || (res= open_and_lock_tables(thd, tables)))) { - delete sp; // Free memory. Remove this when caching!!! break; } fix_tables_pointers(lex->all_selects_list); @@ -3087,7 +3072,6 @@ mysql_execute_command(THD *thd) #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif - delete sp; // QQ Free memory. Remove this when caching!!! goto error; } smrx= thd->server_status & SERVER_MORE_RESULTS_EXISTS; @@ -3105,8 +3089,6 @@ mysql_execute_command(THD *thd) thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; } - delete sp; // QQ Free memory. Remove this when caching!!! - if (res == 0) send_ok(thd); else @@ -3132,7 +3114,6 @@ mysql_execute_command(THD *thd) { /* QQ This is an no-op right now, since we haven't put the characteristics in yet. */ - delete sp; // QQ Free memory. Remove this when caching!!! send_ok(thd); } break; From 6d225437ed4eb35b93e991ef77d0600c2496f7a7 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 3 Jul 2003 15:58:37 +0200 Subject: [PATCH 81/83] Code cleanup (and moved sp cache to separate file). --- libmysqld/Makefile.am | 2 +- sql/Makefile.am | 4 +-- sql/sp.cc | 69 +++++++++++-------------------------------- sql/sp_head.cc | 2 +- sql/sp_head.h | 2 +- sql/sql_class.cc | 24 +++++++-------- sql/sql_class.h | 4 ++- 7 files changed, 37 insertions(+), 70 deletions(-) diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 13e389b4dca..fecec6254af 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -56,7 +56,7 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ spatial.cc gstream.cc sql_help.cc \ - sp_head.cc sp_pcontext.cc sp.cc + sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc EXTRA_DIST = lib_vio.c diff --git a/sql/Makefile.am b/sql/Makefile.am index 74372e9ae2f..77a7e6b2e49 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -58,7 +58,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ log_event.h mini_client.h sql_repl.h slave.h \ stacktrace.h sql_sort.h sql_cache.h set_var.h \ spatial.h gstream.h sp_head.h sp_pcontext.h \ - sp_rcontext.h sp.h + sp_rcontext.h sp.h sp_cache.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ @@ -87,7 +87,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ mini_client.cc mini_client_errors.c pack.c\ stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc\ gstream.cc spatial.cc sql_help.cc protocol_cursor.cc \ - sp_head.cc sp_pcontext.cc sp.cc + sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/sp.cc b/sql/sp.cc index ecbe0ff3955..a368748e9fa 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -18,12 +18,7 @@ #include "mysql_priv.h" #include "sp.h" #include "sp_head.h" - -static sp_head * -sp_find_cached_function(THD *thd, char *name, uint namelen); - -static sp_head * -sp_find_cached_procedure(THD *thd, char *name, uint namelen); +#include "sp_cache.h" /* * @@ -102,7 +97,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) char *ptr; uint length; char buff[65]; - String str(buff,sizeof(buff),&my_charset_bin); + String str(buff, sizeof(buff), &my_charset_bin); // QQ Set up our own mem_root here??? ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened); @@ -132,10 +127,10 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) if (ptr[0] == 'N') suid= 0; - table->field[7]->val_str(&str,&str); + table->field[7]->val_str(&str, &str); ptr= 0; if ((length= str.length())) - ptr= strmake_root(&thd->mem_root, str.ptr(),length); + ptr= strmake_root(&thd->mem_root, str.ptr(), length); if (opened) { @@ -166,7 +161,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) { *sphp= thd->lex->sphead; (*sphp)->sp_set_info((char *) creator, (uint) strlen(creator), - created, modified, suid, + created, modified, suid, ptr, length); } thd->lex->sql_command= oldcmd; @@ -204,10 +199,10 @@ db_create_routine(THD *thd, int type, table->field[0]->store(name, namelen, system_charset_info); table->field[1]->store((longlong)type); table->field[2]->store(def, deflen, system_charset_info); - table->field[3]->store(creator, (uint) strlen(creator), system_charset_info); - ((Field_timestamp*) table->field[5])->set_time(); + table->field[3]->store(creator, (uint)strlen(creator), system_charset_info); + ((Field_timestamp *)table->field[5])->set_time(); if (suid) - table->field[6]->store((longlong) suid); + table->field[6]->store((longlong)suid); if (comment) table->field[7]->store(comment, commentlen, system_charset_info); @@ -257,15 +252,13 @@ sp_find_procedure(THD *thd, LEX_STRING *name) DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); - sp= sp_find_cached_procedure(thd, name->str, name->length); + sp= thd->sp_proc_cache->lookup(name->str, name->length); if (! sp) { if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, name->str, name->length, &sp) == SP_OK) { - HASH *phash= thd->sp_hash+TYPE_ENUM_PROCEDURE-1; - - hash_insert(phash, (const byte*)sp); + thd->sp_proc_cache->insert(sp); } } @@ -294,12 +287,10 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) sp_head *sp; int ret; - sp= sp_find_cached_procedure(thd, name, namelen); + sp= thd->sp_proc_cache->lookup(name, namelen); if (sp) { - HASH *phash= thd->sp_hash+TYPE_ENUM_PROCEDURE-1; - - hash_delete(phash, (byte*)sp); + thd->sp_proc_cache->remove(sp); delete sp; } ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen); @@ -322,7 +313,7 @@ sp_find_function(THD *thd, LEX_STRING *name) DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); - sp= sp_find_cached_function(thd, name->str, name->length); + sp= thd->sp_func_cache->lookup(name->str, name->length); if (! sp) { if (db_find_routine(thd, TYPE_ENUM_FUNCTION, @@ -354,12 +345,10 @@ sp_drop_function(THD *thd, char *name, uint namelen) sp_head *sp; int ret; - sp= sp_find_cached_function(thd, name, namelen); + sp= thd->sp_func_cache->lookup(name, namelen); if (sp) { - HASH *fhash= thd->sp_hash+TYPE_ENUM_FUNCTION-1; - - hash_delete(fhash, (byte*)sp); + thd->sp_func_cache->remove(sp); delete sp; } ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen); @@ -375,7 +364,7 @@ sp_function_exists(THD *thd, LEX_STRING *name) bool ret= FALSE; bool opened= FALSE; - if (sp_find_cached_function(thd, name->str, name->length) || + if (thd->sp_func_cache->lookup(name->str, name->length) || db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, name->str, name->length, TL_READ, &table, &opened) == SP_OK) @@ -434,14 +423,13 @@ sp_cache_functions(THD *thd, LEX *lex) char *fn; enum_sql_command cmd= lex->sql_command; int ret= 0; - HASH *fhash= thd->sp_hash+TYPE_ENUM_FUNCTION-1; while ((fn= li++)) { sp_head *sp; int len= strlen(fn); - if (hash_search(fhash,(const byte*)fn,len)) + if (thd->sp_func_cache->lookup(fn, len)) continue; if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, len, &sp) == SP_OK) @@ -449,7 +437,7 @@ sp_cache_functions(THD *thd, LEX *lex) ret= sp_cache_functions(thd, thd->lex); if (ret) break; - hash_insert(fhash,(const byte*)sp); + thd->sp_func_cache->insert(sp); } else { @@ -460,24 +448,3 @@ sp_cache_functions(THD *thd, LEX *lex) lex->sql_command= cmd; return ret; } - -byte * -hash_get_key_for_sp_head(const byte *ptr, uint *plen, - my_bool first) -{ - return ((sp_head*)ptr)->name(plen); -} - -static sp_head * -sp_find_cached_function(THD *thd, char *name, uint namelen) -{ - return (sp_head*)hash_search(thd->sp_hash+TYPE_ENUM_FUNCTION-1, - (const byte*)name,namelen); -} - -static sp_head * -sp_find_cached_procedure(THD *thd, char *name, uint namelen) -{ - return (sp_head*)hash_search(thd->sp_hash+TYPE_ENUM_PROCEDURE-1, - (const byte*)name,namelen); -} diff --git a/sql/sp_head.cc b/sql/sp_head.cc index b9360a35593..1c2baa1c0dd 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -387,7 +387,7 @@ sp_head::execute_procedure(THD *thd, List *args) octx->set_item(nctx->get_oindex(i), nctx->get_item(i)); else { // A global user variable -#if 0 +#if NOT_USED_NOW // QQ This works if the parameter really is a user variable, but // for the moment we can't assure that, so it will crash if it's // something else. So for now, we just do nothing, to avoid a crash. diff --git a/sql/sp_head.h b/sql/sp_head.h index df551897fbb..2c37d87c7c1 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -48,7 +48,7 @@ public: my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise my_bool m_multi_query; // TRUE if a procedure with SELECT(s) uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value -#if 0 +#if NOT_USED_NOW // QQ We're not using this at the moment. List m_calls; // Called procedures. List m_tables; // Used tables. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 5ab096b91e4..e66c70fcf21 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -37,8 +37,7 @@ #include #include - -byte *hash_get_key_for_sp_head(const byte*,uint*,my_bool); +#include /* The following is used to initialise Table_ident with a internal @@ -157,11 +156,9 @@ THD::THD():user_time(0), is_fatal_error(0), hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (hash_free_key) free_user_var, 0); - - hash_init(sp_hash,system_charset_info,0,0,0, - hash_get_key_for_sp_head,0,0); - hash_init(sp_hash+1,system_charset_info,0,0,0, - hash_get_key_for_sp_head,0,0); + + sp_proc_cache= new sp_cache(); + sp_func_cache= new sp_cache(); /* For user vars replication*/ if (opt_bin_log) @@ -265,10 +262,8 @@ void THD::change_user(void) hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (hash_free_key) free_user_var, 0); - hash_init(sp_hash,system_charset_info,0,0,0, - hash_get_key_for_sp_head,0,0); - hash_init(sp_hash+1,system_charset_info,0,0,0, - hash_get_key_for_sp_head,0,0); + sp_proc_cache->init(); + sp_func_cache->init(); } @@ -292,8 +287,8 @@ void THD::cleanup(void) close_temporary_tables(this); delete_dynamic(&user_var_events); hash_free(&user_vars); - hash_free(sp_hash); - hash_free(sp_hash+1); + sp_proc_cache->cleanup(); + sp_func_cache->cleanup(); if (global_read_lock) unlock_global_read_lock(this); if (ull) @@ -335,6 +330,9 @@ THD::~THD() } #endif + delete sp_proc_cache; + delete sp_func_cache; + DBUG_PRINT("info", ("freeing host")); if (host != localhost) // If not pointer to constant safeFree(host); diff --git a/sql/sql_class.h b/sql/sql_class.h index cebcdf68391..e1aa22831cb 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -27,6 +27,7 @@ class Query_log_event; class Load_log_event; class Slave_log_event; class sp_rcontext; +class sp_cache; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY }; @@ -551,7 +552,8 @@ public: bool prepare_command; bool tmp_table_used; sp_rcontext *spcont; // SP runtime context - HASH sp_hash[2]; // hash for SP PROCEDURES and FUNCTIONS + sp_cache *sp_proc_cache; + sp_cache *sp_func_cache; /* If we do a purge of binary logs, log index info of the threads From 38c459e6b84df43de3a7809b76089a8f6de219e1 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 3 Jul 2003 16:01:31 +0200 Subject: [PATCH 82/83] Add the new sp cache files too (should have been in previous changeset). --- sql/sp_cache.cc | 53 ++++++++++++++++++++++++++++++++++++++++ sql/sp_cache.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 sql/sp_cache.cc create mode 100644 sql/sp_cache.h diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc new file mode 100644 index 00000000000..1b8816ee0f4 --- /dev/null +++ b/sql/sp_cache.cc @@ -0,0 +1,53 @@ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include "mysql_priv.h" +#include "sp_cache.h" +#include "sp_head.h" + +static byte * +hash_get_key_for_sp_head(const byte *ptr, uint *plen, + my_bool first) +{ + return ((sp_head*)ptr)->name(plen); +} + +sp_cache::sp_cache() +{ + init(); +} + +sp_cache::~sp_cache() +{ + hash_free(&m_hashtable); +} + +void +sp_cache::init() +{ + hash_init(&m_hashtable, system_charset_info, 0, 0, 0, + hash_get_key_for_sp_head, 0, 0); +} + +void +sp_cache::cleanup() +{ + hash_free(&m_hashtable); +} diff --git a/sql/sp_cache.h b/sql/sp_cache.h new file mode 100644 index 00000000000..68a97839ed8 --- /dev/null +++ b/sql/sp_cache.h @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +/* Copyright (C) 2002 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _SP_CACHE_H_ +#define _SP_CACHE_H_ + +#ifdef __GNUC__ +#pragma interface /* gcc class implementation */ +#endif + +class sp_head; + +class sp_cache +{ +public: + + sp_cache(); + + ~sp_cache(); + + void + init(); + + void + cleanup(); + + inline void + insert(sp_head *sp) + { + hash_insert(&m_hashtable, (const byte *)sp); + } + + inline sp_head * + lookup(char *name, uint namelen) + { + return (sp_head *)hash_search(&m_hashtable, (const byte *)name, namelen); + } + + inline void + remove(sp_head *sp) + { + hash_delete(&m_hashtable, (byte *)sp); + } + +private: + + HASH m_hashtable; + +}; // class sp_cache + +#endif /* _SP_CACHE_H_ */ From c908b555ff3dae8511a7529f2cd8717d1f848c03 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Mon, 7 Jul 2003 14:55:10 +0200 Subject: [PATCH 83/83] Fixed the old kludge for pre-loading functions and made it more efficient using a hash table instead (and made it work with lex pointers). Some additional code cleanup too. --- sql/sp.cc | 90 +++++++++++++++++++++++++------------------------- sql/sp_head.h | 2 +- sql/sql_lex.cc | 7 +++- sql/sql_lex.h | 14 ++++++-- 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index a368748e9fa..a767622057a 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -26,7 +26,7 @@ * */ -// *openeed=true means we opened ourselves +// *opened=true means we opened ourselves static int db_find_routine_aux(THD *thd, int type, char *name, uint namelen, enum thr_lock_type ltype, TABLE **tablep, bool *opened) @@ -99,7 +99,6 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) char buff[65]; String str(buff, sizeof(buff), &my_charset_bin); - // QQ Set up our own mem_root here??? ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened); if (ret != SP_OK) goto done; @@ -109,7 +108,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) goto done; } - //Get additional information + // Get additional information if ((creator= get_field(&thd->mem_root, table->field[3])) == NULL) { ret= SP_GET_FIELD_FAILED; @@ -377,74 +376,75 @@ sp_function_exists(THD *thd, LEX_STRING *name) } +byte * +sp_lex_spfuns_key(const byte *ptr, uint *plen, my_bool first) +{ + LEX_STRING *lsp= (LEX_STRING *)ptr; + *plen= lsp->length; + return (byte *)lsp->str; +} + void sp_add_fun_to_lex(LEX *lex, LEX_STRING fun) { - List_iterator_fast li(lex->spfuns); - char *fn; - - while ((fn= li++)) + if (! hash_search(&lex->spfuns, (byte *)fun.str, fun.length)) { - uint len= strlen(fn); + LEX_STRING *ls= (LEX_STRING *)sql_alloc(sizeof(LEX_STRING)); + ls->str= sql_strmake(fun.str, fun.length); + ls->length= fun.length; - if (my_strnncoll(system_charset_info, - (const uchar *)fn, len, - (const uchar *)fun.str, fun.length) == 0) - break; - } - if (! fn) - { - char *s= sql_strmake(fun.str, fun.length); - lex->spfuns.push_back(s); + hash_insert(&lex->spfuns, (byte *)ls); } } void sp_merge_funs(LEX *dst, LEX *src) { - List_iterator_fast li(src->spfuns); - char *fn; - - while ((fn= li++)) + for (uint i=0 ; i < src->spfuns.records ; i++) { - LEX_STRING lx; + LEX_STRING *ls= (LEX_STRING *)hash_element(&src->spfuns, i); - lx.str= fn; lx.length= strlen(fn); - sp_add_fun_to_lex(dst, lx); + if (! hash_search(&dst->spfuns, (byte *)ls->str, ls->length)) + hash_insert(&dst->spfuns, (byte *)ls); } } -/* QQ Not terribly efficient right now, but it'll do for starters. - We should actually open the mysql.proc table just once. */ int sp_cache_functions(THD *thd, LEX *lex) { - List_iterator li(lex->spfuns); - char *fn; - enum_sql_command cmd= lex->sql_command; + HASH *h= &lex->spfuns; int ret= 0; - while ((fn= li++)) + for (uint i=0 ; i < h->records ; i++) { - sp_head *sp; - int len= strlen(fn); + LEX_STRING *ls= (LEX_STRING *)hash_element(h, i); - if (thd->sp_func_cache->lookup(fn, len)) - continue; - - if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, len, &sp) == SP_OK) + if (! thd->sp_func_cache->lookup(ls->str, ls->length)) { - ret= sp_cache_functions(thd, thd->lex); - if (ret) + sp_head *sp; + LEX *oldlex= thd->lex; + LEX *newlex= new st_lex; + + thd->lex= newlex; + if (db_find_routine(thd, TYPE_ENUM_FUNCTION, ls->str, ls->length, &sp) + == SP_OK) + { + ret= sp_cache_functions(thd, newlex); + delete newlex; + thd->lex= oldlex; + if (ret) + break; + thd->sp_func_cache->insert(sp); + } + else + { + delete newlex; + thd->lex= oldlex; + net_printf(thd, ER_SP_DOES_NOT_EXIST, "FUNCTION", ls->str); + ret= 1; break; - thd->sp_func_cache->insert(sp); - } - else - { - send_error(thd, ER_SP_DOES_NOT_EXIST); - ret= 1; + } } } - lex->sql_command= cmd; return ret; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 2c37d87c7c1..bdb9e2e4eb1 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -99,7 +99,6 @@ public: // Restores lex in 'thd' from our copy, but keeps some status from the // one in 'thd', like ptr, tables, fields, etc. - // If 'delete_lex' is true, we delete the current lex. void restore_lex(THD *thd); @@ -162,6 +161,7 @@ private: MEM_ROOT m_thd_root; // Temp. store for thd's mem_root Item *m_free_list; // Where the items go THD *m_thd; // Set if we have reset mem_root + LEX_STRING m_name; LEX_STRING m_defstr; LEX_STRING m_comment; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2b3a6addcbd..cf94b63217c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -126,7 +126,12 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->sql_command=SQLCOM_END; lex->sphead= NULL; lex->spcont= NULL; - lex->spfuns.empty(); + + extern byte *sp_lex_spfuns_key(const byte *ptr, uint *plen, my_bool first); + hash_free(&lex->spfuns); + hash_init(&lex->spfuns, system_charset_info, 0, 0, 0, + sp_lex_spfuns_key, 0, 0); + return lex; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ffb1b2b0df7..9cb9ac0946e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -497,9 +497,19 @@ typedef struct st_lex sp_head *sphead; bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ sp_pcontext *spcont; - List spfuns; /* Called functions */ + HASH spfuns; /* Called functions */ + + st_lex() + { + bzero((char *)&spfuns, sizeof(spfuns)); + } + + ~st_lex() + { + if (spfuns.array.buffer) + hash_free(&spfuns); + } - st_lex() {} inline void uncacheable() { safe_to_cache_query= 0;