From 8f177a9d1ef00c0cd37b4d659798ea97ce850be8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Oct 2002 09:34:58 +0200 Subject: 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/triggers/post-commit: Updated for 5.0 Removed truncate for commits to internal lists (for complete code reviews) configure.in: Updated for 5.0 BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- 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 -- cgit v1.2.1 From 940f4fd88fa9fd8de114ba7a5343165a39fff435 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 6 Oct 2002 16:21:52 +0200 Subject: Added missing semicolons in sql_yacc.yy, and did a style clean-up. Note: Textual changes only, no functional changes. sql/sql_yacc.yy: Added missing semicolons to quiet yacc warnings. Also did a general style clean-up, placing clause terminating semicolons in a consistent way (on separate lines). BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- 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(); - }; + } + ; -- cgit v1.2.1 From b76c803ab9a655b98c4cc561709c7e61b33f98e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 20 Oct 2002 21:26:25 +0200 Subject: BK automatic LOD removal. BitKeeper/etc/skipkeys: auto add BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/gone | 2360 +++++++++++++++++++++++----------------------- BitKeeper/etc/logging_ok | 5 +- BitKeeper/etc/skipkeys | 7 + 3 files changed, 1191 insertions(+), 1181 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,26 +563,116 @@ 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 -mwagner@evoq.home.mwagner.org|mysql-test/chew_on_this/select.res|20001014084759|41327|1295456b93948768 -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 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.22/README|20001009213643|04628|2bddc2706d0834d0 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/README|20001009213643|10190|f9fd36f3c3711305 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000004.result|20001017133900|06471|1f8d1265be521c17 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000005.result|20001017133900|07980|d5410bb765199cc5 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000006.result|20001017133900|09337|d38004d1acfc11a5 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000007.result|20001017133900|10672|df455e49f9727c4f -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000008.result|20001017133900|11918|67a459ff62c84d6a -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000009.result|20001017133900|13159|e042b35ab131fb3 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000010.result|20001017133900|14408|eee5b9631a1e0066 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000011.result|20001017133900|15675|6907fe356973ed25 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000012.result|20001017133900|16957|be18991fc28954c2 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000013.result|20001017133900|18248|513389e06c96af73 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000014.result|20001017133900|19568|fc8de0ec89d9e35 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000015.result|20001017133900|20900|cadbc52051d47bac -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000016.result|20001017133900|22246|6177851869bd5b07 -mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000017.result|20001017133900|25454|84ebf147850ff31c +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 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.22/README|20001009213643|04628|2bddc2706d0834d0 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/README|20001009213643|10190|f9fd36f3c3711305 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000004.result|20001017133900|06471|1f8d1265be521c17 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000005.result|20001017133900|07980|d5410bb765199cc5 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000006.result|20001017133900|09337|d38004d1acfc11a5 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000007.result|20001017133900|10672|df455e49f9727c4f +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000008.result|20001017133900|11918|67a459ff62c84d6a +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000009.result|20001017133900|13159|e042b35ab131fb3 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000010.result|20001017133900|14408|eee5b9631a1e0066 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000011.result|20001017133900|15675|6907fe356973ed25 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000012.result|20001017133900|16957|be18991fc28954c2 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000013.result|20001017133900|18248|513389e06c96af73 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000014.result|20001017133900|19568|fc8de0ec89d9e35 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000015.result|20001017133900|20900|cadbc52051d47bac +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000016.result|20001017133900|22246|6177851869bd5b07 +mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000017.result|20001017133900|25454|84ebf147850ff31c mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000018.result|20001017133900|26863|562ac9094cf53aba mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000019.result|20001017133900|28330|2870fe1c4998d929 mwagner@evoq.home.mwagner.org|mysql-test/r/3.23/sel000020.result|20001017133900|29810|faa670294ef5fa91 @@ -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/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/sel000019.test|20001211130731|47552|8fd63c8dc6be8dbc +serg@serg.mysql.com|mysql-test/t/sel000020.test|20001211130731|52532|c5758ad18a6dff1e +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 -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 +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_bt_minkey.html|20010305004144|40498|e2d52ba2d0174432 +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/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_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.b.result|20001212120058|34425|5de41ce15ae1cedb -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/sel000028.test|20001211130731|28317|db9bfc0a808fb629 -serg@serg.mysql.com|mysql-test/t/sel000030.test|20001211130732|03110|a29683eac3e7b706 -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_win32/db_checkpoint.dsp|20010305004134|26943|8071af22db95b1db -tim@threads.polyesthetic.msg|bdb/build_win32/db_upgrade.dsp|20010305004135|03711|90fd250190af4984 -tim@threads.polyesthetic.msg|bdb/dist/install-sh|20010305004136|21695|1858c24340b72628 -tim@threads.polyesthetic.msg|bdb/dist/template/gen_client_ret|20010305004137|22087|786a5e65119b3991 -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_lsn.html|20010305004143|34135|5edb9bce1118feae -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_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_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_h_nelem.html|20010305004144|10635|bd8371e033b15c8f -tim@threads.polyesthetic.msg|bdb/docs/api_c/db_set_re_len.html|20010305004144|15420|f30d68257bd60e1e -tim@threads.polyesthetic.msg|bdb/docs/api_c/dbc_put.html|20010305004144|27355|a2c4a52329376657 -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_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/log_compare.html|20010305004145|47782|4f12fdf04d30ab94 -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_yield.html|20010305004144|25375|ca5e359bcbeca7fd -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_cxx/db_err.html|20010305004145|10496|77022bd5af575696 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/dbc_close.html|20010305004146|30462|2adba79b482ee157 -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_verbose.html|20010305004146|04365|e804a65368b5cdc1 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/lock_put.html|20010305004146|09587|9eb85a1c9e88621 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/log_file.html|20010305004146|14965|9a724b41d84e0c31 -tim@threads.polyesthetic.msg|bdb/docs/api_cxx/memp_fopen.html|20010305004146|24842|abfef0a4db99c8e1 +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/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/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/refs/libtp_usenix.ps|20010305004150|08667|73329b041f7e8c41 +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 -- cgit v1.2.1 From 34fa4492484d868f5bbcdc13eac9bc48c21461d6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Nov 2002 19:21:52 +0100 Subject: 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; } ; -- cgit v1.2.1 From e88847048d17346e55a30cbdd44e918fd2c1701e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 30 Nov 2002 13:02:54 +0100 Subject: 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: -- cgit v1.2.1 From 3a49b1ab2d8e3a4273d24ca787efb8fbd4ceba3c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 30 Nov 2002 15:58:06 +0100 Subject: 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(); - } - ; + }; -- cgit v1.2.1 From 27de9ece815b04651db03ed3d413374f42c9d894 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Dec 2002 19:59:22 +0100 Subject: 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: Added SP files. sql/item.cc: Added this*_item() methods for Item_splocal. (SP local variable) sql/item.h: Added this*_item() methods for SPs in Item, and the new Item_splocal class (SP local variable). sql/lex.h: Added new symbols for SPs. (Note: SPSET is temporary and will go away later.) sql/sql_class.cc: Initialize SP runtime context in THD. sql/sql_class.h: Add SP runtime context to THD. sql/sql_lex.cc: Init. buf pointer to beginning of command (needed by SPs). Also initialize SP head and parse time context. sql/sql_lex.h: New SQLCOM_ tags for SPs, and added pointer to beginning of command pointer and SP head and parse-time context to LEX. sql/sql_parse.cc: Added SQLCOM_CREATE_PROCEDURE, _CALL, _ALTER_PROCEDURE and _DROP_PROCEDURE cases. (Still rudimentary and lacking proper error handling...) sql/sql_yacc.yy: Lots and lots of additions for SPs... (Still even more missing, and no error messages...) --- 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 { -- cgit v1.2.1 From 37ce17e2cd6e796ca19674fb42f91bd153aaedf2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2002 14:24:29 +0100 Subject: 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: Added more keywords for embedded SQL. sql/sp_head.cc: Fixed bugs in the parameter evaluation. Modified execute() for better jump support. Added jump instruction and backpatch support. sql/sp_head.h: Fixed bugs in the parameter evaluation. Modified execute() for better jump support. Added jump instruction and backpatch support. sql/sp_pcontext.cc: Added label support. sql/sp_pcontext.h: Added label support. sql/sql_yacc.yy: Outlined flow control constructs (parses, but nothing generated yet). --- 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 {} -- cgit v1.2.1 From b1b62274856c81a5f1f7a49384fc93810fd2a2bd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Dec 2002 13:14:23 +0100 Subject: 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: Added new sp.h/sp.cc file. sql/item.h: New deferred result_type() method in Item_splocal. sql/lex.h: Temporary fix until REPEAT conflict is solved. Use SPREPEAT for now. sql/sp_head.cc: Moved create/find/drop functions to sp.cc. Fixed the backpatch stuff. (Also removed some dead code and updated comments.) sql/sp_head.h: Moved create/find/drop declarations to sp.h. Fixed the backpatch stuff. sql/sp_pcontext.h: New method: last_label(). sql/sql_parse.cc: Include sp.h. sql/sql_yacc.yy: Fixed backpatching of forward jumps. Implemented LOOP, WHILE, and REPEAT. (Note: SPREPEAT for now.) --- 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) -{ - 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 -// course.) -sp_head * -sp_find(THD *thd, Item_string *iname) +sp_head::backpatch() { - 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; -} + sp_instr *ip; + uint dest= instructions(); + List_iterator_fast li(m_backpatch); -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))) + while ((ip= li++)) { - ret= -1; - goto done; - } - - restore_record(table, 2); // Get default values for fields + sp_instr_jump *i= static_cast(ip); - 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)); + i->set_destination(dest); } - 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: -- cgit v1.2.1 From 390b3e745c05a39704c01365958710189e216f79 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Dec 2002 18:25:36 +0100 Subject: 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: Added creation of the mysql.proc table. Note: The table format will change later, right now it's rather minimalistic, just so things can be tested (and the database can easily be recreated when I break it :-/ ). sql/item.h: Removed unused method. sql/sp_head.cc: Added collection of called procedures in a list. Fixed eval bug; now conditions with local variables work in WHILE et al. --- 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; -- cgit v1.2.1 From f6611aa0ab45aa5586101b34c444b8fab305fac9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Dec 2002 15:40:44 +0100 Subject: Fixed the broken backpatching implementation. Implemented IF-THEN-ELSE. sql/sp_head.cc: Reimplemented the broken backpatching, so it works for nested constructions and IF-THEN-ELSE too. sql/sp_head.h: Reimplemented the broken backpatching, so it works for nested constructions and IF-THEN-ELSE too. sql/sp_pcontext.cc: Return the value from push-methods, for convenience. sql/sp_pcontext.h: Return the value from push-methods, for convenience. sql/sql_yacc.yy: Implemented IF-THEN-ELSE. Corrected for the new backpatch method. --- 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 { -- cgit v1.2.1 From b12330b3d9597b6da2ee8ef51765093e9de38e42 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Dec 2002 10:01:52 +0100 Subject: Added parsing of CASE (both generic and "simple"). sql/sp_head.cc: Init. the simple_case flag. sql/sp_head.h: New flag for (simple)case parsing. sql/sp_pcontext.cc: Removed push_gen_label method (not needed any more). sql/sp_pcontext.h: Removed push_gen_label method (not needed any more). Fixed bug in pop(). sql/sql_yacc.yy: Added CASE parsing. --- 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 ':' { -- cgit v1.2.1 From a3fe4223e89ea4e5857005181367faccf2c7bed6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Dec 2002 18:43:25 +0100 Subject: Fixed some of the data collection during parsing. sql/sp_head.cc: Renamed m_mylex into m_call_lex. Fixed some data collection. sql/sp_head.h: Renamed m_mylex into m_call_lex. Put called procedures and used tables in class member vars (for now at least). --- 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 -- cgit v1.2.1 From 59aba38458f32295a257674fbcffd3155cdf0c94 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Jan 2003 18:30:58 +0100 Subject: Post-merge fix. mysql-test/r/rpl_temporary.result: Corrected version number in result file. --- 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) -- cgit v1.2.1 From bc543f69971fb0737cde034ae3477aa0ce937858 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Jan 2003 17:14:26 +0100 Subject: 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: Removed dummy SPSET symbol. sql/sql_yacc.yy: Removed dummy SPSET construct. Setting of SP local variables is now part of the existing SET syntax. --- 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; } -- cgit v1.2.1 From 79993565a9d0c534a1aade553df5412173c37bf4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Jan 2003 15:39:36 +0100 Subject: Fixed some basic error handling for SP functions in mysql_execute_command(). include/mysqld_error.h: Added error codes for SPs sql/mysql_priv.h: Changed return value of mysql_execute_command() from void to int; need to be able to detect if executions of substatements in SPs failed. sql/share/czech/errmsg.txt: Added error messages for SPs. sql/share/danish/errmsg.txt: Added error messages for SPs. sql/share/dutch/errmsg.txt: Added error messages for SPs. sql/share/english/errmsg.txt: Added error messages for SPs. sql/share/estonian/errmsg.txt: Added error messages for SPs. sql/share/french/errmsg.txt: Added error messages for SPs. sql/share/german/errmsg.txt: Added error messages for SPs. sql/share/greek/errmsg.txt: Added error messages for SPs. sql/share/hungarian/errmsg.txt: Added error messages for SPs. sql/share/italian/errmsg.txt: Added error messages for SPs. sql/share/japanese/errmsg.txt: Added error messages for SPs. sql/share/korean/errmsg.txt: Added error messages for SPs. sql/share/norwegian-ny/errmsg.txt: Added error messages for SPs. sql/share/norwegian/errmsg.txt: Added error messages for SPs. sql/share/polish/errmsg.txt: Added error messages for SPs. sql/share/portuguese/errmsg.txt: Added error messages for SPs. sql/share/romanian/errmsg.txt: Added error messages for SPs. sql/share/russian/errmsg.txt: Added error messages for SPs. sql/share/serbian/errmsg.txt: Added error messages for SPs. sql/share/slovak/errmsg.txt: Added error messages for SPs. sql/share/spanish/errmsg.txt: Added error messages for SPs. sql/share/swedish/errmsg.txt: Added error messages for SPs. sql/share/ukrainian/errmsg.txt: Added error messages for SPs. sql/sp_head.cc: Moved net.no_send_ok fiddling to sql_parse.cc. Check if mysql_execute_command() failed. sql/sql_parse.cc: Changed return value of mysql_execute_command() from void to int; need to be able to detect if executions of substatements in SPs failed. Fixed all returns accordingly. Added error checks for SQLCOM_CREATE_PROCEDURE, CALL, ALTER_PROCEDURE, and DROP_PROCEDURE. --- 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; } -- cgit v1.2.1 From dcac913c15b25c2d12db9fa4546e0f3d3f58dc72 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Jan 2003 18:06:07 +0100 Subject: Fixed some error handling in the SP parts of the parser. include/mysqld_error.h: Added SP error messages for the parser. sql/share/czech/errmsg.txt: Added SP error messages for the parser. sql/share/danish/errmsg.txt: Added SP error messages for the parser. sql/share/dutch/errmsg.txt: Added SP error messages for the parser. sql/share/english/errmsg.txt: Added SP error messages for the parser. sql/share/estonian/errmsg.txt: Added SP error messages for the parser. sql/share/french/errmsg.txt: Added SP error messages for the parser. sql/share/german/errmsg.txt: Added SP error messages for the parser. sql/share/greek/errmsg.txt: Added SP error messages for the parser. sql/share/hungarian/errmsg.txt: Added SP error messages for the parser. sql/share/italian/errmsg.txt: Added SP error messages for the parser. sql/share/japanese/errmsg.txt: Added SP error messages for the parser. sql/share/korean/errmsg.txt: Added SP error messages for the parser. sql/share/norwegian-ny/errmsg.txt: Added SP error messages for the parser. sql/share/norwegian/errmsg.txt: Added SP error messages for the parser. sql/share/polish/errmsg.txt: Added SP error messages for the parser. sql/share/portuguese/errmsg.txt: Added SP error messages for the parser. sql/share/romanian/errmsg.txt: Added SP error messages for the parser. sql/share/russian/errmsg.txt: Added SP error messages for the parser. sql/share/serbian/errmsg.txt: Added SP error messages for the parser. sql/share/slovak/errmsg.txt: Added SP error messages for the parser. sql/share/spanish/errmsg.txt: Added SP error messages for the parser. sql/share/swedish/errmsg.txt: Added SP error messages for the parser. sql/share/ukrainian/errmsg.txt: Added SP error messages for the parser. sql/sql_yacc.yy: Replaced dummy printfs with real error messages in the SP 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); -- cgit v1.2.1 From e7ffc21546b68c22c6dbc80e2dc198039177c655 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Jan 2003 14:48:58 +0400 Subject: Make the CLI client (client/mysql.cc) work with multi-line SPs. Make the mysqltest program (client/mysqltest.c) work with multi-line SPs. client/mysql.cc: Added 'delimiter' command client/mysqltest.c: Added 'delimiter' command mysql-test/install_test_db.sh: Fix for install 'proc' table mysql-test/r/connect.result: Fix for 'proc' table BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- 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; -- cgit v1.2.1 From 838303a731bb8172b3fd861acc90dc92007977f8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Jan 2003 14:38:05 +0100 Subject: Added the Stored Procedure tests. Removed newly added, but now redundant, test file. BitKeeper/deleted/.del-mysql_proc.result~63faae2f407c3fc2: Delete: mysql-test/r/mysql_proc.result BitKeeper/deleted/.del-mysql_proc.test~8863f59cfc347469: Delete: mysql-test/t/mysql_proc.test --- 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; -- cgit v1.2.1 From 69047e719a6845800d0f05c04dca55d2de95feed Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 18 Jan 2003 18:21:13 +0200 Subject: 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; } ; -- cgit v1.2.1 From 6d5f7d1c4bbade6a83a49d0b932a3850fcb4f951 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Jan 2003 15:38:35 +0200 Subject: 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; -- cgit v1.2.1 From 172dc5b37143eee4e6047f8f401973265f4b1af5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 Jan 2003 17:00:31 +0400 Subject: 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 ')' -- cgit v1.2.1 From cbc757066586fe1ec283259d42ba785732f4dec4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 Jan 2003 14:00:32 +0100 Subject: Added check for selects without into in SPs, and updated error messages and tests accordingly. include/mysqld_error.h: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/czech/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/danish/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/dutch/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/english/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/estonian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/french/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/german/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/greek/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/hungarian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/italian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/japanese/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/korean/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/norwegian-ny/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/norwegian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/polish/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/portuguese/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/romanian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/russian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/serbian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/slovak/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/spanish/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/swedish/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). sql/share/ukrainian/errmsg.txt: Added bad select in SP error (and fixed leave/iterate label mismatch error). mysql-test/r/sp.result: New test for repeat(...) and select with and without into in SPs. mysql-test/t/sp.test: New test for repeat(...) and select with and without into in SPs. sql/sql_yacc.yy: Check if an SP substatement is a SELECT and if so, has an INTO. If not, it's an error. --- 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 -- cgit v1.2.1 From 7b137f15bd28727a62a6215cf21a92878948760e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jan 2003 18:55:52 +0200 Subject: 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 */ -- cgit v1.2.1 From f8b7968e049fe115d97181d77c10ba4ca6893744 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Feb 2003 17:41:21 +0100 Subject: Added another select into test. mysql-test/r/sp.result: Added another test for select into (mixed variable types), and made into_test independent of previous tests. mysql-test/t/sp.test: Added another test for select into (mixed variable types), and made into_test independent of previous tests. --- 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 +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 -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,@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 + 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 - 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,@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; -- cgit v1.2.1 From a3111ad09b074dcf7c95b0a055e0bbbf6005b2ba Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Feb 2003 17:44:39 +0100 Subject: Fixed crash bug when certain procedures are called from the top level. sql/sp_head.cc: Fixed crash bug when certain procedures are called from the top level. Attempted to support global user vars as OUT/INOUT parameters too, but unfortunately we can't quite manage that yet. --- 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; -- cgit v1.2.1 From 77f30e19a6da4d17a5e282e5967cf4c61b35ddec Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Feb 2003 17:49:42 +0100 Subject: 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.) -- cgit v1.2.1 From 565d98958efd48d7c0a39891c5c0d463626dd1fc Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 4 Feb 2003 17:40:18 +0100 Subject: Some new stuff in the Docs/sp-* files, and renamed a few functions in preparation for future work. Docs/sp-imp-spec.txt: Started on the FUNCTION parts... Docs/sp-implemented.txt: Added som info on SET behaviour, and added Open questions. sql/sp.cc: Renamed functions. sql/sp.h: Renamed functions. sql/sql_parse.cc: Renamed functions. --- 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); -- cgit v1.2.1 From 6cfaf04e4d81e0a30cf096b67064841dc938c07e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Feb 2003 16:17:03 +0100 Subject: Fixed some DBUGing, and optimized SET slightly. sql/sp.cc: Added DBUG statements. sql/sp_head.cc: Added DBUG statements. sql/sql_parse.cc: Changed returns into DBUG_RETURNs in mysql_execute_command(). sql/sql_yacc.yy: Small optimization: Don't generate sp_instr_stmt instructions for empty SET_OPTIONs. (Which happened if there were only local variables in the SET statement.) --- sql/sp.cc | 16 +++++++++++----- sql/sp_head.cc | 29 +++++++++++++++++++++-------- sql/sql_parse.cc | 12 ++++++------ sql/sql_yacc.yy | 16 ++++++++++++---- 4 files changed, 50 insertions(+), 23 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()); - - i->set_lex(lex); - lex->sphead->add_instr(i); + /* 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); + } lex->sphead->restore_lex(YYTHD); } } -- cgit v1.2.1 From d6303970e91fbb072909bdf6d5affc19b2ed4786 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Feb 2003 13:24:26 +0100 Subject: 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 -- cgit v1.2.1 From 344c639b8b5929c7764e18071d433f8ecf019818 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Feb 2003 19:58:03 +0100 Subject: Post-merge fixes (adapting new SP code to 4.1 changes). sql/sql_class.cc: Unlock tables after a SELECT INTO variables, or an assert() in lock_tables() fails. Note: This might be a problem with other SELECT variants too. sql/sql_yacc.yy: Make all bison versions work (hopefully). --- 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: -- cgit v1.2.1 From 3c88ebdc9dec478a44de8f6d55a22c105f1d20f0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Feb 2003 12:42:32 +0100 Subject: Fixed SELECT INTO OUTFILE/DUMPFILE and stored procedures, and extended and reorganized the sp.test file. mysql-test/r/sp.result: New results from the reorganized sp.test file. mysql-test/t/sp.test: Reorganized the tests, and added a few new ones. ("fac" and more "select into") sql/sql_class.cc: Unlock tables and set thd->lock=0 in select_export::send_eof() and select_dump::send_eof(). This fixes a problem with an assert() in lock_tables(), and made SELECT ... INTO OUTFILE and ... INTO DUMPFILE work in stored procedures. --- mysql-test/r/sp.result | 354 ++++++++++++++++++++++++++++++------------------- mysql-test/t/sp.test | 312 ++++++++++++++++++++++++++++--------------- sql/sql_class.cc | 18 +++ 3 files changed, 442 insertions(+), 242 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| -delimiter ;| +call into_test2("into", 100)| +select id,data,@z from t1| +delete from t1| +drop procedure into_test2| -# 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; +# These two (and the two procedures above) caused an assert() to fail in +# sql_base.cc:lock_tables() at some point. -call e(3); -select * from t1; -delete from t1; +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 f(-2); -call f(0); -call f(4); -select * from t1; -delete from t1; +system rm -f /tmp/spout| +call into_outfile("ofile", 1)| +system rm -f /tmp/spout| +delete from t1| +drop procedure into_outfile| -call g(-42); -call g(0); -call g(1); -select * from t1; -delete from t1; +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 h(0); -call h(1); -call h(17); -select * from t1; -delete from t1; +system rm -f /tmp/spdump| +call into_dumpfile("dfile", 1)| +system rm -f /tmp/spdump| +delete from t1| +drop procedure into_dumpfile| -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; +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 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; +# 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 ;| 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; -- cgit v1.2.1 From 0521fb5444df9a97e0682307242700bd94c6595e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Feb 2003 17:37:05 +0100 Subject: 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: Updated with info about CASCADE/RESTICT and METHOD, and some answers to questions. include/mysqld_error.h: New error message for misuse of RETURN. mysql-test/install_test_db.sh: Added enum field to mysql.proc to distinguish between FUNCTION and PROCEDURE. mysql-test/r/sp.result: New test for creating and dropping FUNCTIONS. mysql-test/t/sp.test: New test for creating and dropping FUNCTIONS. scripts/mysql_install_db.sh: Added enum field to mysql.proc to distinguish between FUNCTION and PROCEDURE. sql/lex.h: De-UDFed some symbol names, as they are now used for SPs as well. Added RETURN_SYM. sql/share/czech/errmsg.txt: New error message for misuse of RETURN. sql/share/danish/errmsg.txt: New error message for misuse of RETURN. sql/share/dutch/errmsg.txt: New error message for misuse of RETURN. sql/share/english/errmsg.txt: New error message for misuse of RETURN. sql/share/estonian/errmsg.txt: New error message for misuse of RETURN. sql/share/french/errmsg.txt: New error message for misuse of RETURN. sql/share/german/errmsg.txt: New error message for misuse of RETURN. sql/share/greek/errmsg.txt: New error message for misuse of RETURN. sql/share/hungarian/errmsg.txt: New error message for misuse of RETURN. sql/share/italian/errmsg.txt: New error message for misuse of RETURN. sql/share/japanese/errmsg.txt: New error message for misuse of RETURN. sql/share/korean/errmsg.txt: New error message for misuse of RETURN. sql/share/norwegian-ny/errmsg.txt: New error message for misuse of RETURN. sql/share/norwegian/errmsg.txt: New error message for misuse of RETURN. sql/share/polish/errmsg.txt: New error message for misuse of RETURN. sql/share/portuguese/errmsg.txt: New error message for misuse of RETURN. sql/share/romanian/errmsg.txt: New error message for misuse of RETURN. sql/share/russian/errmsg.txt: New error message for misuse of RETURN. sql/share/serbian/errmsg.txt: New error message for misuse of RETURN. sql/share/slovak/errmsg.txt: New error message for misuse of RETURN. sql/share/spanish/errmsg.txt: New error message for misuse of RETURN. sql/share/swedish/errmsg.txt: New error message for misuse of RETURN. sql/share/ukrainian/errmsg.txt: New error message for misuse of RETURN. sql/sp.cc: Major rehack to accomodate FUNCTIONs, and to make it easier to add future in-memory cache of prepared SPs. sql/sp.h: Major rehack to accomodate FUNCTIONs, and to make it easier to add future in-memory cache of prepared SPs. sql/sp_head.cc: Now creates FUNCTIONs too. (And got rid of some unnecessary Item_string use.) sql/sp_head.h: Now creates FUNCTIONs too. (And got rid of some unnecessary Item_string use.) sql/sql_lex.h: New stored FUNCTION commands. sql/sql_parse.cc: Added FUNCTION support ("drop" merged with the old UDF code), and made some additional changes for better error handling (following the sp.cc rehacking). sql/sql_yacc.yy: Some former UDF specific symbols renamed. Added CREATE FUNCTION parsing. DROP FUNCTION had to be partly merged with the old UDF code, because of the similar syntax. RETURN statement added, but still a no-op. --- 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 | 234 ++++++++++++++++++++++++++++---------- sql/sp.h | 19 ++-- sql/sp_head.cc | 38 ++++--- sql/sp_head.h | 20 +++- sql/sql_lex.h | 4 +- sql/sql_parse.cc | 108 +++++++++++------- sql/sql_yacc.yy | 124 +++++++++++++------- 37 files changed, 469 insertions(+), 173 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,79 +19,170 @@ #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(sp); + DBUG_RETURN(ret); } -int -sp_create_procedure(THD *thd, char *name, uint namelen, char *def, uint deflen) +static int +db_create_routine(THD *thd, int type, + 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; + 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"; - /* Allow creation of procedures even if we can't open proc table */ + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + ret= SP_OPEN_TABLE_FAILED; + else { - 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((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; } - restore_record(table, 2); // Get default values for fields + if (ret == SP_OK && table) + close_thread_tables(thd); + DBUG_RETURN(ret); +} - table->field[0]->store(name, namelen, default_charset_info); - table->field[1]->store(def, deflen, default_charset_info); +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= table->file->write_row(table->record[0]); + 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); +} + +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; + + ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, def, deflen); - 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); + + DBUG_RETURN(ret); +} - 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); +/* + * + * 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", ("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_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_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; - while ((it= li++)) - { - String *sold= it->val_str(NULL); + List_iterator_fast li(m_calls); + char **it; - if (stringcmp(snew, sold) == 0) + while ((it= li++)) + 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 { + uint namelen; + char *name= lex->sphead->name(&namelen); + udf_func *udf = find_udf(name, namelen); + + if (udf) + { + net_printf(thd, ER_UDF_EXISTS, name); + goto error; + } res= lex->sphead->create(thd); - if (res != 0) + 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 {} -- cgit v1.2.1 From 76b037dc4288fada1b64efbef422cb8b4bd0d5b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Feb 2003 19:22:29 +0100 Subject: 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: New tests for invoking simple FUNCTIONs. mysql-test/t/sp.test: New tests for invoking simple FUNCTIONs. sql/item_func.cc: New Item_func_sp for stored FUNCTIONs. sql/item_func.h: New Item_func_sp for stored FUNCTIONs. sql/sp.cc: Close mysql.proc table earlier so recursive find_function calls work. Added temporary sp_function_exists() function for checking without parsing. sql/sp.h: Added temporary sp_function_exists() function for checking without parsing. sql/sp_head.cc: New code for executing a FUNCTION. (And reworked some of the old code in the process.) sql/sp_head.h: New code for executing a FUNCTION. sql/sp_rcontext.h: Added result slot for FUNCTIONs. sql/sql_lex.cc: Added check for stored FUNCTION, analogous to UDFs. sql/sql_parse.cc: sp_head::execute was renamed into execute_procedure. sql/sql_yacc.yy: Added parsing of stored FUNCTION invocation and code generation for RETURN statement. --- 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| + +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| -# A function with flow control and a RETURN statement +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) -- cgit v1.2.1 From aecc6a21bd1e802d31318cf3e82d03d57b090c5f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Feb 2003 19:08:52 +0100 Subject: 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: New FUNCTION tests. mysql-test/t/sp.test: New FUNCTION tests. sql/item_func.cc: Fixed field_type bug; now string functions work too. Removed unecessary function which was added in a state of confusion. sql/item_func.h: Fixed field_type bug; now string functions work too. Removed unecessary function which was added in a state of confusion. sql/sp_head.cc: Fixed string type bug, and set the right charset. --- mysql-test/r/sp.result | 19 +++++++++++++------ mysql-test/t/sp.test | 12 ++++++++++-- sql/item_func.cc | 46 +++++++++++++++++++++++----------------------- sql/item_func.h | 6 +++--- sql/sp_head.cc | 6 +++--- 5 files changed, 52 insertions(+), 37 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)); } -Item_result -Item_func_sp::result_type() const +enum enum_field_types +Item_func_sp::field_type() const { - DBUG_ENTER("Item_func_sp::result_type"); - DBUG_PRINT("info", ("m_sp = %p", m_sp)); + 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_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); + DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); + DBUG_RETURN(m_sp->m_returns); } + DBUG_RETURN(MYSQL_TYPE_STRING); } -void -Item_func_sp::make_field(Send_field *field) +Item_result +Item_func_sp::result_type() const { - DBUG_ENTER("Item_func_sp::make_field"); - Item *it; + DBUG_ENTER("Item_func_sp::result_type"); + DBUG_PRINT("info", ("m_sp = %p", m_sp)); - if (!execute(&it)) + if (! m_sp) + m_sp= sp_find_function(current_thd, const_cast(&m_name)); + if (m_sp) { - it->set_name(name, 0); - init_make_field(field, field_type()); - it->make_field(field); + DBUG_RETURN(m_sp->result()); } - 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; } } -- cgit v1.2.1 From 1ff79b61a056e5b50fc0402680f6f74ca1eb2a57 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Feb 2003 15:07:14 +0100 Subject: Closing tables during SP execution the proper way. mysql-test/r/show_check.result: proc table now shows up in different places. mysql-test/r/status.result: proc table now shows up in different places. sql/sp.cc: Fixed closing of tables. sql/sp_head.cc: Close tables after each sub statement. sql/sql_class.cc: Removed closing of tables in various send_eof() methods again. --- 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); -- cgit v1.2.1 From 8a9422bd2af6ea39676171b9ec16897c64104dc8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Mar 2003 19:17:41 +0100 Subject: 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: New function tests. mysql-test/t/sp.test: New function tests. sql/sp.cc: Big rehack of mysql.proc table usage strategy and adding a function cache mechanism, since we need to read used functions from the db before doing anything else when executing a query. (This cache is temporary and will probably be replaced by the real thing later.) sql/sp.h: New (temporary) FUNCTION caching functions. sql/sp_head.cc: Fixed some bugs in the function and procedure execution. Disabled some data collections that's not used at the moment. sql/sp_head.h: Fixed some bugs in the function and procedure execution. Disabled some data collections that's not used at the moment. sql/sql_class.h: Added SP function cache list to thd. sql/sql_lex.cc: Added SP function name list to lex. sql/sql_lex.h: Added SP function name list to lex. sql/sql_parse.cc: Read used FUNCTIONs from db and cache them in thd before doing anything else in a query execution. (This is necessary since we can't open mysql.proc during query execution.) sql/sql_yacc.yy: Collect used function names in lex. --- 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 -- cgit v1.2.1 From f519382d2bf276a9beb5d123fde93ec4cdfdefea Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 3 Mar 2003 15:03:19 +0100 Subject: New FUNCTION documentation, and a minor test case modification. Docs/sp-imp-spec.txt: Updated docs about stored FUNCTIONs. Docs/sp-implemented.txt: Updated docs about stored FUNCTIONs. mysql-test/r/sp.result: Changed the ifac test example into a combination of a procedure and a function. mysql-test/t/sp.test: Changed the ifac test example into a combination of a procedure and a function. --- 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; -- cgit v1.2.1 From f74b36a24266e290cf23c7d06333c3a558e33af9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Mar 2003 19:45:17 +0100 Subject: Improved error handling regarding SPs (with info like names etc in the output). Disabled queries in FUNCTIONs. include/mysqld_error.h: New error message for queries in FUNCTIONs. mysql-test/t/sp.test: Moved error tests to sp-error.test. sql/share/czech/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/danish/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/dutch/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/english/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/estonian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/french/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/german/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/greek/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/hungarian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/italian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/japanese/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/korean/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/norwegian-ny/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/norwegian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/polish/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/portuguese/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/romanian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/russian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/serbian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/slovak/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/spanish/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/swedish/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/share/ukrainian/errmsg.txt: New error message for queries in FUNCTIONs. Improved most of the SP error messages with added info. sql/sp_head.cc: Added debug output to sp_instr_jump::execute(). (Moved from sp_head.h) sql/sp_head.h: Moved sp_instr_jump::execute() to sp_head.cc. sql/sql_lex.h: Added SQLCOM_CREATE_SPFUNCTION (for improved error handling). sql/sql_parse.cc: Improved error handling regarding SPs (adding info like names etc in output). sql/sql_yacc.yy: Improved error handling regarding SPs (adding info like names etc in output). Disabled queries in FUNCTIONS (since it can't work anyway). --- 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 | 68 ++++++++++++++++++----- 32 files changed, 534 insertions(+), 284 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()); - - i->set_lex(lex); - lex->sphead->add_instr(i); + /* 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); + } } 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 -- cgit v1.2.1 From 6b3c898655bf9159f4b90aa7a0f055ce9667fd2c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Mar 2003 19:16:46 +0100 Subject: Fixed reentrantness bugs in select (lex->result) and select_dumpvar, and added cool prime number test example. mysql-test/r/sp.result: New prime number example. (Good for future benchmarkings too.) mysql-test/t/sp.test: New prime number example. (Good for future benchmarkings too.) sql/sql_class.cc: Reset row_count in select_dumpvar when preparing, to make it reentrant as a lex member. sql/sql_select.cc: Don't delete result if it's a lex member (since lex needs to be reentrant). --- 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; } -- cgit v1.2.1 From 867efa281af9ac6ff5d7930d2575fbca346cd443 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Mar 2003 10:58:42 +0100 Subject: 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). -- cgit v1.2.1 From addf8ea04ec295a679845cd1911d5e3504c91fab Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Mar 2003 11:36:32 +0100 Subject: Post-merge fixes. mysql-test/r/sp.result: Post-merge fixes. (And disabled the ip test, since some change in 4.1 broke it.) mysql-test/t/sp.test: Post-merge fixes. (And disabled the ip test, since some change in 4.1 broke it.) --- 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; } -- cgit v1.2.1 From fa870804d37c27a69551c9767b9a17224fe495b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Mar 2003 11:57:05 +0100 Subject: Post post merge fix. Made the broken ip test work again. sql/sp_head.cc: Added some more DBUG output. sql/sp_pcontext.cc: Post post merge fix. --- 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; } -- cgit v1.2.1 From 744942beab531d724032133bba44bd6d0cc8d42f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Mar 2003 09:37:01 +0400 Subject: SCRUM two versions of KILL implementation include/mysql_com.h: ONLY_KILL_QUERY flag definition sql/lex.h: CONNECTION keyword added sql/mysql_priv.h: kill_one_thread function extended sql/sql_class.h: only_kill_query flag added to the THD structure sql/sql_parse.cc: handling of KILL QUERY feature added sql/sql_yacc.yy: KILL syntax extended with CONNECTION an QUERY options --- 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 -- cgit v1.2.1 From 3946b8235c6f4dfbb5a1aeefed5b620bf89df34e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Mar 2003 12:29:58 +0100 Subject: Added IF EXISTS to DROP PROCEDURE|FUNCTION. Changed another unecessary use of Item_string into LEX_STRING (in sp_pcontext). Docs/sp-implemented.txt: Added IF EXISTS to DROP PROCEDURE|FUNCTION mysql-test/r/sp-error.result: Added IF EXISTS to DROP PROCEDURE|FUNCTION mysql-test/t/sp-error.test: Added IF EXISTS to DROP PROCEDURE|FUNCTION sql/sp_pcontext.cc: Changed another unecessary use of Item_string into LEX_STRING. sql/sp_pcontext.h: Changed another unecessary use of Item_string into LEX_STRING. sql/sql_parse.cc: Added IF EXISTS to DROP PROCEDURE|FUNCTION sql/sql_yacc.yy: Added IF EXISTS to DROP PROCEDURE|FUNCTION --- 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; } ; -- cgit v1.2.1 From 2c9ef84cc35198c1ae888a335c2e228ecfb6b81d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Mar 2003 15:02:48 +0100 Subject: 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); } -- cgit v1.2.1 From e9cc965afdc60200efa058bdd71ff78093c63ef4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Mar 2003 17:35:27 +0100 Subject: 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; -- cgit v1.2.1 From 56106b024b9359c6371e2a6dc9405819c4346e6f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Mar 2003 17:47:25 +0100 Subject: ...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; -- cgit v1.2.1 From e22976638d691a440c95b1e75e73cc40c363d3b4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Mar 2003 17:02:31 +0100 Subject: 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); -- cgit v1.2.1 From 771237ce307081616ff2d7beea65d4fdbd336ef2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Mar 2003 18:27:36 +0100 Subject: Renamed .del-makefile.w32 to .del-makefile3.w32 BitKeeper/deleted/.del-makefile3.w32: Rename: BitKeeper/deleted/.del-makefile.w32 -> BitKeeper/deleted/.del-makefile3.w32 BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- 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) -- cgit v1.2.1 From cc0f1f15cddb29386ff691adc1712369ee8cee0c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Mar 2003 13:25:43 +0200 Subject: Implemented DEFAULT for DECLARE variables. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- 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); -- cgit v1.2.1 From 3814f2a8edf71a964cdbd8c965790d7216eff9fa Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 31 Mar 2003 13:39:46 +0500 Subject: SCRUM two KILL commands implementation (version 2) include/mysqld_error.h: Error message about query interruption added myisam/mi_check.c: killed_ptr now retutns only value - not pointer myisam/myisamchk.c: killed_ptr returns value now myisam/myisamdef.h: killed_ptr returns value now myisam/sort.c: killed_ptr returns value now sql/filesort.cc: THD::killed now has enum type sql/ha_berkeley.cc: THD::killed has enum type sql/ha_myisam.cc: killed_ptr returns value now sql/lock.cc: two different errors possible here now sql/log_event.cc: two ways of killing possible here now sql/mysqld.cc: THD::killed has enum type now sql/records.cc: two errors are possible here now sql/share/czech/errmsg.txt: new error message sql/share/danish/errmsg.txt: new error message sql/share/dutch/errmsg.txt: new error message sql/share/english/errmsg.txt: new error message sql/share/estonian/errmsg.txt: new error message sql/share/french/errmsg.txt: new error message sql/share/german/errmsg.txt: new error message sql/share/greek/errmsg.txt: new error message sql/share/hungarian/errmsg.txt: new error message sql/share/italian/errmsg.txt: new error message sql/share/japanese/errmsg.txt: new error message sql/share/korean/errmsg.txt: new error message sql/share/norwegian-ny/errmsg.txt: new error message sql/share/norwegian/errmsg.txt: new error message sql/share/polish/errmsg.txt: new error message sql/share/portuguese/errmsg.txt: new error message sql/share/romanian/errmsg.txt: new error message sql/share/russian/errmsg.txt: new error message sql/share/serbian/errmsg.txt: new error message sql/share/slovak/errmsg.txt: new error message sql/share/spanish/errmsg.txt: new error message sql/share/swedish/errmsg.txt: new error message sql/share/ukrainian/errmsg.txt: new error message sql/slave.cc: two errors are possible here now sql/sql_base.cc: THD::killed has enum type now sql/sql_cache.cc: THD::killed has enum type now sql/sql_class.cc: THD::awake implementation changed to handle KILL_QUERY sql/sql_class.h: class THD changed to handle KILL_QUERY sql/sql_delete.cc: two errors are possible here now sql/sql_insert.cc: THD::killed has enum type now sql/sql_load.cc: two errors are possible here now sql/sql_parse.cc: kill_one_thread function changed to handle KILL_QUERY sql/sql_prepare.cc: two errors are possible here now sql/sql_repl.cc: the parameter to awake is of THD::killed_state type now sql/sql_repl.h: awake parameter changed sql/sql_select.cc: two errors are possible here now sql/sql_show.cc: notification adopted to changes in class THD sql/sql_table.cc: two errors are possible here now sql/sql_update.cc: two errors are possible here now --- 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]; -- cgit v1.2.1 From 590d769e2cbf9c3f7a0c39ae37a2da6976bde94b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Apr 2003 00:15:20 +0200 Subject: 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: deprecated update log sql/log.cc: deprecated update log sql/mysqld.cc: deprecated update log sql/set_var.cc: deprecated update log sql/share/czech/errmsg.txt: deprecated update log sql/share/danish/errmsg.txt: deprecated update log sql/share/dutch/errmsg.txt: deprecated update log sql/share/english/errmsg.txt: deprecated update log sql/share/estonian/errmsg.txt: deprecated update log sql/share/french/errmsg.txt: deprecated update log sql/share/german/errmsg.txt: deprecated update log sql/share/greek/errmsg.txt: deprecated update log sql/share/hungarian/errmsg.txt: deprecated update log sql/share/italian/errmsg.txt: deprecated update log sql/share/japanese/errmsg.txt: deprecated update log sql/share/korean/errmsg.txt: deprecated update log sql/share/norwegian-ny/errmsg.txt: deprecated update log sql/share/norwegian/errmsg.txt: deprecated update log sql/share/polish/errmsg.txt: deprecated update log sql/share/portuguese/errmsg.txt: deprecated update log sql/share/romanian/errmsg.txt: deprecated update log sql/share/russian/errmsg.txt: deprecated update log sql/share/serbian/errmsg.txt: deprecated update log sql/share/slovak/errmsg.txt: deprecated update log sql/share/spanish/errmsg.txt: deprecated update log sql/share/swedish/errmsg.txt: deprecated update log sql/share/ukrainian/errmsg.txt: deprecated update log sql/sql_acl.cc: deprecated update log sql/sql_db.cc: deprecated update log sql/sql_delete.cc: deprecated update log sql/sql_insert.cc: deprecated update log sql/sql_load.cc: deprecated update log sql/sql_parse.cc: deprecated update log sql/sql_rename.cc: deprecated update log sql/sql_table.cc: deprecated update log sql/sql_update.cc: deprecated update log --- 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, -- cgit v1.2.1 From 9a68ee758184d84d45ff51f43a966f17b8c9734b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Apr 2003 10:59:21 +0200 Subject: Tiny optimisation for a (boolean || boolean) test, as SQL_LOG_BIN is set to 1 by default sql/sql_insert.cc: Tiny optimisation --- 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; -- cgit v1.2.1 From 2eebaf7bd364ec449c220160e6ff3d59461d13a3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Apr 2003 20:42:28 +0200 Subject: 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: Drop db before creating. mysql-test/t/sp.test: Drop db before creating. --- 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); } } -- cgit v1.2.1 From 3a321d49e8f50a0773c4637fbe2ad74f0f94bdd7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Apr 2003 21:18:52 +0200 Subject: 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; -- cgit v1.2.1 From 0d71f5e1d32e5cc963ae246fb1b5ff487915ec23 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Apr 2003 16:00:09 +0200 Subject: 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" -- cgit v1.2.1 From fc448ccb7fba68f874edd8f33ec401873a1b4e1d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Apr 2003 20:00:52 +0200 Subject: Fixed the last memory leaks in the SP code. sql/sp.cc: Fixed clear_function_cache bug that made memory freeing work for functions too. sql/sp_head.cc: Added more DBUG output to help finding memory leak. sql/sql_parse.cc: Moved sp_clear_function_cache call so it *works*. Added missing memory freeing call. --- 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: -- cgit v1.2.1 From cfd69393e4195e55412778a9d60c7eb99c87de4c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 Apr 2003 15:47:43 +0200 Subject: Post merge fixes. mysql-test/r/sp.result: Enabled the cs test as it works now. mysql-test/t/sp.test: Enabled the cs test as it works now. --- 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; } -- cgit v1.2.1 From 131d90001f2eca14d3497207b57fcd484c3f8927 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Apr 2003 19:18:33 +0500 Subject: SCRUM two KILL versions code trimming with headquarter's suggestions myisam/mi_check.c: killed_ptr function changed backward myisam/myisamchk.c: killed_ptr function changed backward myisam/myisamdef.h: killed_ptr function changed backward myisam/sort.c: killed_ptr function changed backward sql/ha_myisam.cc: killed_ptr function changed backward sql/lock.cc: error sending trimmed sql/log_event.cc: error sending trimmed sql/records.cc: error sending trimmed sql/slave.cc: error sending trimmed sql/sql_class.h: inline functions to send right message about killing added sql/sql_delete.cc: error sending trimmed sql/sql_load.cc: error sending trimmed sql/sql_parse.cc: error sending trimmed sql/sql_prepare.cc: error sending trimmed sql/sql_select.cc: error sending trimmed sql/sql_table.cc: error sending trimmed sql/sql_update.cc: error sending trimmed --- 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]; -- cgit v1.2.1 From d7edf9785b4d6b103e9067be06ec1413320ed50f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Apr 2003 00:18:29 +0200 Subject: 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; -- cgit v1.2.1 From 4ed94fcd8ec8afc11e4208a5a3e83bd90b5fc644 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Apr 2003 13:20:02 +0200 Subject: Check the number of args to SPs. Fixes bug #280. include/mysqld_error.h: Check the number of args to SPs. mysql-test/r/sp-error.result: Check the number of args to SPs. mysql-test/t/sp-error.test: Check the number of args to SPs. sql/share/czech/errmsg.txt: Check the number of args to SPs. sql/share/danish/errmsg.txt: Check the number of args to SPs. sql/share/dutch/errmsg.txt: Check the number of args to SPs. sql/share/english/errmsg.txt: Check the number of args to SPs. sql/share/estonian/errmsg.txt: Check the number of args to SPs. sql/share/french/errmsg.txt: Check the number of args to SPs. sql/share/german/errmsg.txt: Check the number of args to SPs. sql/share/greek/errmsg.txt: Check the number of args to SPs. sql/share/hungarian/errmsg.txt: Check the number of args to SPs. sql/share/italian/errmsg.txt: Check the number of args to SPs. sql/share/japanese/errmsg.txt: Check the number of args to SPs. sql/share/korean/errmsg.txt: Check the number of args to SPs. sql/share/norwegian-ny/errmsg.txt: Check the number of args to SPs. sql/share/norwegian/errmsg.txt: Check the number of args to SPs. sql/share/polish/errmsg.txt: Check the number of args to SPs. sql/share/portuguese/errmsg.txt: Check the number of args to SPs. sql/share/romanian/errmsg.txt: Check the number of args to SPs. sql/share/russian/errmsg.txt: Check the number of args to SPs. sql/share/serbian/errmsg.txt: Check the number of args to SPs. sql/share/slovak/errmsg.txt: Check the number of args to SPs. sql/share/spanish/errmsg.txt: Check the number of args to SPs. sql/share/swedish/errmsg.txt: Check the number of args to SPs. sql/share/ukrainian/errmsg.txt: Check the number of args to SPs. sql/sp_head.cc: Check the number of args to SPs. --- 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); -- cgit v1.2.1 From f525047d1eb2d1bad50cf453210939ceb15d7282 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Apr 2003 09:22:54 +0200 Subject: 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: Pick up the server_status (with the 4.1 protocol) as well. mysql-test/r/sp-error.result: Test for "bad selects" in non-CLIENT_MULTI_QUERIES clients (as mysqltest for the momen; this test will have to go away eventually). mysql-test/t/sp-error.test: Test for "bad selects" in non-CLIENT_MULTI_QUERIES clients (as mysqltest for the momen; this test will have to go away eventually). sql/protocol.cc: Actually send the server_status flags in send_eof() (4.1 protocol), not just zero. sql/sp_head.cc: Made multiple queries (SELECT without INTO) work in SPs. sql/sp_head.h: Made multiple queries (SELECT without INTO) work in SPs. sql/sql_parse.cc: Made multiple queries (SELECT without INTO) work in SPs. sql/sql_yacc.yy: Made multiple queries (SELECT without INTO) work in SPs. --- 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 | 87 ++++++++++++++++++++++++++++---------------- 8 files changed, 108 insertions(+), 44 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()); - - i->set_lex(lex); - lex->sphead->add_instr(i); - } - } - lex->sphead->restore_lex(YYTHD); - } + 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); } | RETURN_SYM expr { -- cgit v1.2.1 From 440521609999a2e36d90a27cb18dac637708a74c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Apr 2003 16:21:56 +0200 Subject: 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? -- cgit v1.2.1 From 37c9401782fd0b365cccb712c8a187b6dc3e4aaf Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Apr 2003 22:31:47 +0300 Subject: subselect in procedure argument list (Bug #302) BitKeeper/etc/ignore: Added libmysqld/sp_pcontext.cc libmysqld/sp.cc libmysqld/sp_head.cc to the ignore list mysql-test/r/subselect.result: test of subselect in procedure argument list mysql-test/t/subselect.test: test of subselect in procedure argument list sql/sp_head.cc: subselect in procedure argument list sql/sql_parse.cc: subselect in procedure argument list --- .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. -- cgit v1.2.1 From d19e16d4ded1273daecb1b43f9af1b8f7be272d1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Apr 2003 08:22:11 +0500 Subject: SCRUM two versions of KILL small fix sql/sql_select.cc: it's more logical to use killed here --- 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)); } -- cgit v1.2.1 From 64cad16faab92467061ea41f6c763dd8e044f344 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 27 Apr 2003 17:35:54 +0200 Subject: Post-fix of bug #302 fix. Fixed bug #320. Some new tests and cosmetic changes. Another strcasecmp() replaced. mysql-test/r/sp.result: Moved SP tests from subselect and added some more. mysql-test/r/subselect.result: Moved SP tests to sp.test. mysql-test/t/sp.test: Moved SP tests from subselect and added some more. mysql-test/t/subselect.test: Moved SP tests to sp.test. sql/sp.cc: Don't close derived tables. sql/sp_head.cc: Minor layout and comment fix. sql/sp_head.h: Minor comment fix. sql/sql_derived.cc: Don't set org_table_list->derived to 1 when debugging, as this breaks certain subselect args to SPs. sql/sql_parse.cc: Post-fix of bugfix (free memory on error), and added comment. sql/sql_yacc.yy: 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; -- cgit v1.2.1 From 16a751cca8d67a2eec9bc11941fd822e885758fd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Apr 2003 12:31:03 +0200 Subject: 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 -- cgit v1.2.1 From aa1720f3cbfaa985124d982fc0a421084f52fbf0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Apr 2003 15:00:16 +0200 Subject: 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; -- cgit v1.2.1 From b9121cdea38b75aabc5a29a769ee409c962f42e0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 5 May 2003 14:54:37 -0400 Subject: 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= ""; } ; -- cgit v1.2.1 From fb5df27adf58998f5e2a4a66d1634003cd106af2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 6 May 2003 21:09:20 +0500 Subject: 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 -- cgit v1.2.1 From ab7b332835e285bfbd3bc6637c8b388e29cae754 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 May 2003 15:36:31 +0200 Subject: 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: updated test mysql-test/t/variables.test: updated test sql/sql_class.cc: Task #627 : user variables' names are now case-insensitive : @test=@"tEsT"=@`teST` etc. --- 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); } -- cgit v1.2.1 From 8ea9613e7ef35880c5b91cab446142be213bf0ba Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 May 2003 15:32:31 +0200 Subject: Adopt SP stuff to the new lex pointer. mysql-test/r/sp.result: New test (of more call levels). mysql-test/t/sp.test: New test (of more call levels). sql/mysql_priv.h: SPs wants to init lex only. sql/sp.cc: Restore lex pointer (and fixed memory leak). sql/sp_head.cc: lex is now a pointer, so reset things the right way. sql/sp_head.h: lex is now a pointer. sql/sql_lex.h: SPs wants to init lex only. sql/sql_parse.cc: SPs wants to init lex only. sql/sql_prepare.cc: Restore 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); } -- cgit v1.2.1 From c560a02dcd1681ccb137580930b26de9414e55f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 May 2003 14:28:02 -0400 Subject: rlyon-5.0.0-alpha.patch client/mysql.cc: Import patch rlyon-5.0.0-alpha.patch configure.in: Import patch rlyon-5.0.0-alpha.patch include/config-netware.h: Import patch rlyon-5.0.0-alpha.patch include/my_global.h: Import patch rlyon-5.0.0-alpha.patch include/my_pthread.h: Import patch rlyon-5.0.0-alpha.patch mysys/my_pthread.c: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-AUTOTOOLS: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-linux-tools: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-netware-END: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-netware-START: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-netware-all: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-netware-debug: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-netware-standard: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/mwasmnlm: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/mwccnlm: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/mwenv: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/mwldnlm: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/nwbootstrap: Import patch rlyon-5.0.0-alpha.patch netware/Makefile.am: Import patch rlyon-5.0.0-alpha.patch netware/mysql_test_run.c: Import patch rlyon-5.0.0-alpha.patch scripts/make_binary_distribution.sh: Import patch rlyon-5.0.0-alpha.patch sql/mysqld.cc: Import patch rlyon-5.0.0-alpha.patch sql/slave.cc: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/compile-netware-src: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/cron-build: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/crontab: Import patch rlyon-5.0.0-alpha.patch netware/BUILD/knetware.imp: Import patch 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 } -- cgit v1.2.1 From de223659661693c985a2f72bea2f76bf77371a1e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 May 2003 14:44:00 -0400 Subject: Reviewed Novell-supplied patch for 5.0 tree configure.in: Can't put this in yet because of 'make dist' --- 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 -- cgit v1.2.1 From 40f41ee1fc708821a8893f6647c2ae6ec2608489 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Jun 2003 14:25:01 +0500 Subject: '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; -- cgit v1.2.1 From e42120c664fa7c5ad5fefd1226c5676014d5e517 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Jun 2003 15:31:20 +0200 Subject: Fixed bug #643, which caused intermittent crashes in net_printf() with repeated syntax errors in stored procedures. mysql-test/r/sp-error.result: New test case for bugfix (#643) mysql-test/t/sp-error.test: New test case for bugfix (#643) sql/sp_head.cc: Forgot to copy a slot from the original lex. (bug #643) --- 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; -- cgit v1.2.1 From 663ac86f6cd55b4a22a91c312ccc17fa4fdf158c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Jun 2003 18:15:17 +0200 Subject: 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: sp_head now has its own mem_root. sql/sp_head.cc: sp_head now has its own mem_root. Also fixed some difficult memory leaks. sql/sp_head.h: sp_head now has its own mem_root. sql/sql_lex.h: Fixed some memory leaks in sp_head. Need to keep track on used lex:es. sql/sql_parse.cc: sp_head now has its own mem_root. Fixed SP memory leaks. sql/sql_prepare.cc: Fixed SP memory leaks. sql/sql_yacc.yy: sp_head now has its own mem_root. --- 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); -- cgit v1.2.1 From 31a58c4068e28405a8b23722b39033eb175b5dcf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Jul 2003 17:19:48 +0200 Subject: Bugfixes for the sp_head memroot stuff. sql/sp.cc: Bugfixes for the sp_head memroot stuff. (Do things in the correct order at error clean-up.) sql/sp_head.cc: Bugfixes for the sp_head memroot stuff. Make sure everything goes to the right memroot. Need separate post-reset-memroot init in sp_head. sql/sp_head.h: Need separate post-reset-memroot init method. sql/sql_yacc.yy: Bugfixes for the sp_head memroot stuff. Make sure everything goes to the right memroot. Must do things in the correct order for this. --- 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 ')' { -- cgit v1.2.1 From 8070c06ae009e6dea64992419899d8a769458ddb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Jul 2003 18:14:24 +0200 Subject: SP cache (WL#730). (Mostly by vva, additions by pem.) sql/sp.cc: In-memory cache added. sp_clear_function_cache() no longer needed. sql/sp.h: In-memory cache added. sp_clear_function_cache() no longer needed. sql/sql_class.cc: In-memory cache added. sql/sql_class.h: In-memory cache added. sql/sql_parse.cc: In-memory cache added. sp_clear_function_cache() no longer needed. Don't delete sp_heads after each use. --- sql/sp.cc | 95 +++++++++++++++++++++++++++++++------------------------- sql/sp.h | 6 ++-- sql/sql_class.cc | 19 ++++++++---- sql/sql_class.h | 2 +- sql/sql_parse.cc | 19 ------------ 5 files changed, 69 insertions(+), 72 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); + return (sp_head*)hash_search(thd->sp_hash+TYPE_ENUM_FUNCTION-1, + (const byte*)name,namelen); +} - if (my_strnncoll(system_charset_info, - (const uchar *)name, namelen, - n, len) == 0) - break; - } - return sp; +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; -- cgit v1.2.1 From f1c754efe9b78fb8497042ebdb1b2245df392381 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Jul 2003 15:58:37 +0200 Subject: 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 -- cgit v1.2.1 From d17a3ae1f41b00f15a06ccd6773fd602c4116932 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Jul 2003 16:01:31 +0200 Subject: 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_ */ -- cgit v1.2.1 From a6b9cbd65c79289e86855472a8477e130609ada9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Jul 2003 14:55:10 +0200 Subject: 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: 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 cleanup of comments too. sql/sp_head.h: Some additional code cleanup. sql/sql_lex.cc: Use hash table for function pre-loading (isntead of list). sql/sql_lex.h: Use hash table for function pre-loading (isntead of list). --- 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); - - if (thd->sp_func_cache->lookup(fn, len)) - continue; + LEX_STRING *ls= (LEX_STRING *)hash_element(h, i); - 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; -- cgit v1.2.1 From 2b16d5457b88f5c0b6099fd38b528a2387978ecd Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Jul 2003 17:07:12 +0200 Subject: Merging 4.1 into 5.0 (second pass; post-merge fixes). One test in subselect.test still wrong. Had to reconstruct all errmsg.txt files completely, since auto-merge made a mess of the lot. :-( mysql-test/r/sp-error.result: Merging 4.1 into 5.0 (second pass; post-merge fixes). mysql-test/r/subselect.result: Merging 4.1 into 5.0 (second pass; post-merge fixes). One test still wrong (different from 4.1), left for Sanja. :) mysql-test/r/variables.result: Merging 4.1 into 5.0 (second pass; post-merge fixes). mysql-test/t/sp-error.test: Merging 4.1 into 5.0 (second pass; post-merge fixes). mysql-test/t/subselect.test: Merging 4.1 into 5.0 (second pass; post-merge fixes). One test still wrong (different from 4.1), left for Sanja :) scripts/mysql_create_system_tables.sh: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/item.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/item_cmpfunc.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/item_subselect.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/item_sum.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/mysql_priv.h: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/mysqld.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/danish/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/dutch/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/english/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/estonian/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/french/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/german/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/greek/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/hungarian/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/italian/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/japanese/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/korean/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/norwegian-ny/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/norwegian/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/polish/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/portuguese/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/russian/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/serbian/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/slovak/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/spanish/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/swedish/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/share/ukrainian/errmsg.txt: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/sp.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/sql_base.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/sql_cache.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/sql_insert.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/sql_parse.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/sql_select.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). sql/sql_update.cc: Merging 4.1 into 5.0 (second pass; post-merge fixes). --- mysql-test/r/sp-error.result | 50 +++++++++++++-------------- mysql-test/r/subselect.result | 3 +- mysql-test/r/variables.result | 2 +- mysql-test/t/sp-error.test | 42 +++++++++++------------ mysql-test/t/subselect.test | 3 +- scripts/mysql_create_system_tables.sh | 20 +++++++++++ sql/item.cc | 6 ++-- sql/item_cmpfunc.cc | 2 +- sql/item_subselect.cc | 12 +++---- sql/item_sum.cc | 6 ++-- sql/mysql_priv.h | 1 + sql/mysqld.cc | 14 ++++++-- sql/share/danish/errmsg.txt | 33 ++++++++++++++++++ sql/share/dutch/errmsg.txt | 33 ++++++++++++++++++ sql/share/english/errmsg.txt | 38 +++++++++++++++++++++ sql/share/estonian/errmsg.txt | 33 ++++++++++++++++++ sql/share/french/errmsg.txt | 33 ++++++++++++++++++ sql/share/german/errmsg.txt | 33 ++++++++++++++++++ sql/share/greek/errmsg.txt | 33 ++++++++++++++++++ sql/share/hungarian/errmsg.txt | 33 ++++++++++++++++++ sql/share/italian/errmsg.txt | 33 ++++++++++++++++++ sql/share/japanese/errmsg.txt | 33 ++++++++++++++++++ sql/share/korean/errmsg.txt | 33 ++++++++++++++++++ sql/share/norwegian-ny/errmsg.txt | 33 ++++++++++++++++++ sql/share/norwegian/errmsg.txt | 33 ++++++++++++++++++ sql/share/polish/errmsg.txt | 33 ++++++++++++++++++ sql/share/portuguese/errmsg.txt | 63 +++++++++++++++++++++++++++++++++++ sql/share/russian/errmsg.txt | 33 ++++++++++++++++++ sql/share/serbian/errmsg.txt | 33 ++++++++++++++++++ sql/share/slovak/errmsg.txt | 33 ++++++++++++++++++ sql/share/spanish/errmsg.txt | 33 ++++++++++++++++++ sql/share/swedish/errmsg.txt | 33 ++++++++++++++++++ sql/share/ukrainian/errmsg.txt | 33 ++++++++++++++++++ sql/sp.cc | 2 +- sql/sql_base.cc | 6 ++-- sql/sql_cache.cc | 2 +- sql/sql_insert.cc | 2 -- sql/sql_parse.cc | 9 ++--- sql/sql_select.cc | 6 ++-- sql/sql_update.cc | 2 +- 40 files changed, 836 insertions(+), 82 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 0c1db1703ac..11935e4b137 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1,98 +1,98 @@ 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 +ERROR 42000: 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 +ERROR 42000: 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 +ERROR 42000: 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 return 42; create procedure foo() create procedure bar() set @x=3; -Can't create a PROCEDURE from within another stored routine +ERROR HY000: 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 +ERROR HY000: Can't create a FUNCTION from within another stored routine create procedure proc1() set @x = 42; -PROCEDURE proc1 already exists +ERROR HY000: PROCEDURE proc1 already exists create function func1() returns int return 42; -FUNCTION func1 already exists +ERROR HY000: FUNCTION func1 already exists drop procedure proc1; drop function func1; alter procedure foo; -PROCEDURE foo does not exist +ERROR HY000: PROCEDURE foo does not exist alter function foo; -FUNCTION foo does not exist +ERROR HY000: FUNCTION foo does not exist drop procedure foo; -PROCEDURE foo does not exist +ERROR HY000: PROCEDURE foo does not exist drop function foo; -FUNCTION foo does not exist +ERROR HY000: FUNCTION foo does not exist call foo(); -PROCEDURE foo does not exist +ERROR HY000: PROCEDURE foo does not exist drop procedure if exists foo; Warnings: -Warning 1261 PROCEDURE foo does not exist +Warning 1272 PROCEDURE foo does not exist create procedure foo() foo: loop leave bar; end loop; -LEAVE with no matching label: bar +ERROR HY000: LEAVE with no matching label: bar create procedure foo() foo: loop iterate bar; end loop; -ITERATE with no matching label: bar +ERROR HY000: 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 +ERROR HY000: Redefining label foo create procedure foo() foo: loop set @x=2; end loop bar; -End-label bar without match +ERROR HY000: End-label bar without match create procedure foo(out x int) begin declare y int; set x = y; end; -Referring to uninitialized variable y +ERROR HY000: Referring to uninitialized variable y 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 +ERROR HY000: SELECT in a stored procedure must have INTO drop procedure foo; create procedure foo() return 42; -RETURN is only allowed in a FUNCTION +ERROR HY000: 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 +ERROR HY000: Queries, like SELECT, INSERT, UPDATE (and others), are not allowed in a FUNCTION 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 +ERROR HY000: 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 +ERROR HY000: Wrong number of arguments for PROCEDURE p, expected 1, got 2 select f(); -Wrong number of arguments for FUNCTION f, expected 1, got 0 +ERROR HY000: 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 +ERROR HY000: Wrong number of arguments for FUNCTION f, expected 1, got 2 drop procedure p; drop function f; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index bba86ff8891..7292230cf5e 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -608,7 +608,6 @@ x 3 3 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; -ERROR HY000: You can't specify target table 't1' for update in FROM clause INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); ERROR 42S22: Unknown column 'x' in 'field list' INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); @@ -618,6 +617,8 @@ x 2 3 3 +11 +11 2 drop table t1, t2, t3; CREATE TABLE t1 (x int not null, y int, primary key (x)); diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 6588e8dd4a0..4c9fe07a428 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -309,7 +309,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1271 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1282 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 8fa0b3c55cf..448a571fa11 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -32,18 +32,18 @@ create function func1() returns int return 42| # Can't create recursively ---error 1259 +--error 1270 create procedure foo() create procedure bar() set @x=3| ---error 1259 +--error 1270 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1260 +--error 1271 create procedure proc1() set @x = 42| ---error 1260 +--error 1271 create function func1() returns int return 42| @@ -51,32 +51,32 @@ drop procedure proc1| drop function func1| # Does not exist ---error 1261 +--error 1272 alter procedure foo| ---error 1261 +--error 1272 alter function foo| ---error 1261 +--error 1272 drop procedure foo| ---error 1261 +--error 1272 drop function foo| ---error 1261 +--error 1272 call foo()| drop procedure if exists foo| # LEAVE/ITERATE with no match ---error 1264 +--error 1275 create procedure foo() foo: loop leave bar; end loop| ---error 1264 +--error 1275 create procedure foo() foo: loop iterate bar; end loop| # Redefining label ---error 1265 +--error 1276 create procedure foo() foo: loop foo: loop @@ -85,14 +85,14 @@ foo: loop end loop foo| # End label mismatch ---error 1266 +--error 1277 create procedure foo() foo: loop set @x=2; end loop bar| # Referring to undef variable ---error 1267 +--error 1278 create procedure foo(out x int) begin declare y int; @@ -106,17 +106,17 @@ begin select name from mysql.proc; select type from mysql.proc; end| ---error 1268 +--error 1279 call foo()| drop procedure foo| # RETURN in FUNCTION only ---error 1269 +--error 1280 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1270 +--error 1281 create function foo() returns int begin declare x int; @@ -130,13 +130,13 @@ create procedure p(x int) create function f(x int) returns int return x+42| ---error 1274 +--error 1285 call p()| ---error 1274 +--error 1285 call p(1, 2)| ---error 1274 +--error 1285 select f()| ---error 1274 +--error 1285 select f(1, 2)| drop procedure p| diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index afa07d91545..0be80c21c8d 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -351,6 +351,8 @@ 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; +# QQ This doesn't work right since the merge /pem 2003-07-09 +#-- error 1093 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; -- error 1054 INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); @@ -518,7 +520,6 @@ do (SELECT a from t1); -- error 1146 set @a:=(SELECT a from t1); - CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; -- error 1149 diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index 2739c45e750..cf2e703a7b9 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -39,6 +39,7 @@ c_hc="" c_hr="" c_hk="" i_ht="" +c_p="" # Check for old tables if test ! -f $mdata/db.frm @@ -285,6 +286,22 @@ then c_hr="$c_hr comment='keyword-topic relation';" 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 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 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)" + c_p="$c_p )" + c_p="$c_p comment='Stored Procedures';" +fi + cat << END_OF_DATA use mysql; $c_d @@ -306,5 +323,8 @@ $c_ht $c_hc $c_hr $c_hk + +$c_p + END_OF_DATA diff --git a/sql/item.cc b/sql/item.cc index fbb9f6912ac..14bf7a6ee64 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -56,9 +56,9 @@ Item::Item(): command => we should check thd->lex.current_select on zero (thd->lex can be uninitialised) */ - if (thd->lex.current_select && - thd->lex.current_select->parsing_place == SELECT_LEX_NODE::SELECT_LIST) - thd->lex.current_select->select_items++; + if (thd->lex->current_select && + thd->lex->current_select->parsing_place == SELECT_LEX_NODE::SELECT_LIST) + thd->lex->current_select->select_items++; } /* diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 326138d798d..2abfe1a7d8d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1617,7 +1617,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) maybe_null=1; } if (thd) - thd->lex.current_select->cond_count+=list.elements; + thd->lex->current_select->cond_count+=list.elements; fix_length_and_dec(); fixed= 1; return 0; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index f0791e50bc8..1ede8bb74ef 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -824,8 +824,8 @@ int subselect_single_select_engine::exec() { DBUG_ENTER("subselect_single_select_engine::exec"); char const *save_where= join->thd->where; - 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; if (!optimized) { optimized=1; @@ -833,7 +833,7 @@ int subselect_single_select_engine::exec() { join->thd->where= save_where; executed= 1; - join->thd->lex.current_select= save_select; + join->thd->lex->current_select= save_select; DBUG_RETURN(join->error?join->error:1); } } @@ -842,7 +842,7 @@ int subselect_single_select_engine::exec() if (join->reinit()) { join->thd->where= save_where; - join->thd->lex.current_select= save_select; + join->thd->lex->current_select= save_select; DBUG_RETURN(1); } item->reset(); @@ -853,11 +853,11 @@ int subselect_single_select_engine::exec() join->exec(); executed= 1; join->thd->where= save_where; - join->thd->lex.current_select= save_select; + join->thd->lex->current_select= save_select; DBUG_RETURN(join->error||thd->is_fatal_error); } join->thd->where= save_where; - join->thd->lex.current_select= save_select; + join->thd->lex->current_select= save_select; DBUG_RETURN(0); } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 538185da2e3..792ccc22939 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1114,7 +1114,7 @@ void Item_sum_count_distinct::make_unique() bool Item_sum_count_distinct::setup(THD *thd) { List list; - SELECT_LEX *select_lex= thd->lex.current_select->select_lex(); + SELECT_LEX *select_lex= thd->lex->current_select->select_lex(); if (select_lex->linkage == GLOBAL_OPTIONS_TYPE) return 1; @@ -1608,7 +1608,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, quick_group= 0; mark_as_sum_func(); item_thd= current_thd; - SELECT_LEX *select_lex= item_thd->lex.current_select->select_lex(); + SELECT_LEX *select_lex= item_thd->lex->current_select->select_lex(); order= 0; group_concat_max_len= item_thd->variables.group_concat_max_len; @@ -1790,7 +1790,7 @@ bool Item_func_group_concat::setup(THD *thd) { DBUG_ENTER("Item_func_group_concat::setup"); List list; - SELECT_LEX *select_lex= thd->lex.current_select->select_lex(); + SELECT_LEX *select_lex= thd->lex->current_select->select_lex(); if (select_lex->linkage == GLOBAL_OPTIONS_TYPE) DBUG_RETURN(1); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 31293527419..e3491be62a0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -49,6 +49,7 @@ char *sql_strmake_with_convert(const char *str, uint32 arg_length, CHARSET_INFO *from_cs, uint32 max_res_length, CHARSET_INFO *to_cs, uint32 *result_length); +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/mysqld.cc b/sql/mysqld.cc index e3d8dc2814c..9c644b002aa 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -255,6 +255,16 @@ my_bool opt_log_slave_updates= 0, opt_old_passwords=0, use_old_passwords=0; my_bool opt_console= 0, opt_bdb, opt_innodb, opt_isam; my_bool opt_readonly, use_temp_pool, relay_log_purge; volatile bool mqh_used = 0; + +uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; +uint delay_key_write_options, protocol_version; +uint volatile thread_count, thread_running, kill_cached_threads, wake_thread; + +ulong back_log, connect_timeout, concurrency; +ulong server_id, thd_startup_options; +ulong table_cache_size, thread_stack, thread_stack_min, what_to_log; +ulong query_buff_size, slow_launch_time, slave_open_temp_tables; +ulong open_files_limit, max_binlog_size; ulong slave_net_timeout; ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; ulong query_cache_size=0; @@ -1816,8 +1826,8 @@ extern "C" int my_message_sql(uint error, const char *str, thd->lex.current_select equel to zero if lex structure is not inited (not query command (COM_QUERY)) */ - if (thd->lex.current_select && - thd->lex.current_select->no_error && !thd->is_fatal_error) + if (thd->lex->current_select && + thd->lex->current_select->no_error && !thd->is_fatal_error) { DBUG_PRINT("error", ("above error converted to warning")); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str); diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 48b20004b1f..830ba419935 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -252,3 +252,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 64e35e506ae..8629f181961 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -260,3 +260,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 c7c1bce15a1..b02940f1f42 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -249,3 +249,41 @@ "Reference '%-.64s' not supported (%s)", "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" +"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" +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)" +"Z_BUF_ERROR: Not enough memory available for zlib" +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)" +"Z_DATA_ERROR: Input data was corrupted for zlib" +"%d line(s) was(were) cut by group_concat()" +"Record count is fewer than the column count at row %ld"; +"Record count is more than the column count at row %ld"; +"Data truncated, NULL supplied to NOT NULL column '%s' at row %ld"; +"Data truncated, out of range for column '%s' at row %ld"; +"Data truncated for column '%s' at row %ld" +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 3d762bc2369..7b69880bf26 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -254,3 +254,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 de95a0838d8..9cb86929c6d 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -249,3 +249,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 d2c65194b67..07b748f4961 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -258,3 +258,36 @@ "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 9e2abd85efb..8c9141d162b 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -249,3 +249,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 8a713858a63..bfc43c1a609 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -251,3 +251,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 56f4f618a89..7f96fce798e 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -249,3 +249,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 49fb8d46241..86f3828bbc4 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -251,3 +251,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 01592503452..d17ac877d70 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -249,3 +249,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 00580adf3ad..696c1c93b78 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -251,3 +251,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 d6b75b597d8..7014cfacedb 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -251,3 +251,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 1fb9bc0f7d9..ff317dbb790 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -253,3 +253,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 c17e0f15211..5eff7c64ada 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -219,3 +219,66 @@ "Não pode acrescentar uma restrição de chave estrangeira", "Não pode acrescentar uma linha filha: uma restrição de chave estrangeira falhou", "Não pode apagar uma linha pai: uma restrição de chave estrangeira falhou", +"Erro connectando para o master: %-.128s", +"Erro rodando consulta no master: %-.128s", +"Erro quando executando comando %s: %-.128s", +"Uso errado de %s e %s", +"Os comandos SELECT usados têm diferentes números de colunas", +"Não pode executar a consulta porque você tem um conflitante travamento de leitura", +"Combinação de tabelas transacionais e não transacionais está desativada", +"Opção '%s' usada duas vezes no comando", +"Usuário '%-.64s' há excedido o '%s' de recursos (atual valor: %ld)", +"Acesso negado. Você necessita o privilégio %-.128s para essa operação", +"Variável '%-.64s' é uma LOCAL variável e não pode ser usada com SET GLOBAL", +"Variável '%-.64s' é uma GLOBAL variável e deve ser configurada com SET GLOBAL", +"Variável '%-.64s' não tem um valor default (padrão)", +"Variável '%-.64s' não pode ser configurada para o valor de '%-.64s'", +"Tipo de argumento errado para a variável '%-.64s'", +"Variável '%-.64s' somente pode ser configurada, não lida", +"Uso/localização errada de '%s'", +"Esta versão de MySQL não suporta ainda '%s'", +"Obteve fatal error %d: '%-.128s' a partir do master quando lendo dados do binary log", +"Definição errada da chave estrangeira para '%-.64s': %s", +"Referência da chave e referência da tabela não coincidem", +"Error de cardinalidade (mais/menos que %d colunas)", +"Subconsulta retorna mais que 1 registro", +"Desconhecido manipulador de declaração preparado (%ld) determinado para %s", +"Banco de dado de ajuda corrupto ou não existente", +"Referência cíclica em subconsultas", +"Convertendo coluna '%s' de %s para %s", +"Referência '%-.64s' não suportada (%s)", +"Cada tabela derivada deve ter seu próprio alias", +"Select %u foi reduzido durante otimização", +"Tabela '%-.64s' de um dos SELECT's não pode ser usada em %-.32s", +"Cliente não suporta o protocolo de autenticação exigido pelo servidor; considere a atualização deo cliente MySQL", +"Todas as partes de uma SPATIAL KEY devem ser NOT NULL", +"COLLATION '%s' não é válida para CHARACTER SET '%s'", +"O slave já está rodando", +"O slave já está parado", +"Tamanho muito grande dos dados des comprimidos. O máximo tamanho é %d. (provavelmente, o comprimento dos dados descomprimidos está corrupto)", +"Z_BUF_ERROR: Não suficiente memória disponível para zlib", +"Z_MEM_ERROR: Não suficiente espaço no buffer emissor para zlib (provavelmente, o comprimento dos dados descomprimidos está corrupto)", +"Z_DATA_ERROR: Dados de entrada está corrupto para zlib", +"%d linha(s) foi(foram) cortada(s) por group_concat()", +"Usando engine de armazenamento %s para tabela '%s'", +"Combinação ilegal de collations (%s,%s) e (%s,%s) para operação '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 b2faa95603f..7ef0c975f80 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -251,3 +251,36 @@ "óÓÙÌËÁ '%-.64s' ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 8b7044ab718..6e4231b0b92 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -245,3 +245,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 529e254ae9b..b46f0745a19 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -257,3 +257,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 1961e3bb620..7d815a424ed 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -250,3 +250,36 @@ "Reference '%-.64s' not supported (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 9e4f60eeb74..d51f5bce5b6 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -249,3 +249,36 @@ "Referens '%-.64s' stöds inte (%s)", "Varje 'derived table' måste ha sitt eget alias", "Select %u reducerades vid optimiering", +"Tabell '%-.64s' från en SELECT kan inte användas i %-.32s", +"Klienten stöder inte autentiseringsprotokollet som begärts av servern; överväg uppgradering av klientprogrammet.", +"Alla delar av en SPATIAL KEY måste vara NOT NULL", +"COLLATION '%s' är inte tillåtet för CHARACTER SET '%s'", +"Slaven har redan startat", +"Slaven har redan stoppat", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d rad(er) kapades av group_concat()", +"Använder handler %s för tabell '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"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 f87df8b1649..dd16f93c7bd 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -254,3 +254,36 @@ "ðÏÓÉÌÁÎÎÑ '%-.64s' ÎÅ ÐiÄÔÒÉÍÕÅÔÓÑ (%s)", "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", +"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", +"Too big size of uncompressed data. The maximum size is %d. (probably, length of uncompressed data was corrupted)", +"Z_BUF_ERROR: Not enough memory available for zlib", +"Z_MEM_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", +"Z_DATA_ERROR: Input data was corrupted for zlib", +"%d line(s) was(were) cut by group_concat()", +"Using storage engine %s for table '%s'", +"Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", +"Can't drop one or more of the requested users" +"Can't revoke all privileges, grant for one or more of the requested users" +"Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", +"Illegal mix of collations for operation '%s'", +"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 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." +"Query execution was interrupted" +"Wrong number of arguments for %s %s, expected %u, got %u" diff --git a/sql/sp.cc b/sql/sp.cc index a767622057a..092a3b0989b 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -192,7 +192,7 @@ db_create_routine(THD *thd, int type, ret= SP_OPEN_TABLE_FAILED; else { - restore_record(table, 2); // Get default values for fields + restore_record(table, default_values); // Get default values for fields strxmov(creator, thd->user, "@", thd->host_or_ip, NullS); table->field[0]->store(name, namelen, system_charset_info); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 28c5ab54edc..b1811c4cca7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2151,7 +2151,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) DBUG_ENTER("setup_conds"); thd->set_query_id=1; - thd->lex.current_select->cond_count= 0; + thd->lex->current_select->cond_count= 0; if (*conds) { thd->where="where clause"; @@ -2169,7 +2169,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) if (table->on_expr->fix_fields(thd, tables, &table->on_expr) || table->on_expr->check_cols(1)) DBUG_RETURN(1); - thd->lex.current_select->cond_count++; + thd->lex->current_select->cond_count++; /* If it's a normal join, add the ON/USING expression to the WHERE */ if (!table->outer_join) @@ -2215,7 +2215,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) } } cond_and->used_tables_cache= t1->map | t2->map; - thd->lex.current_select->cond_count+=cond_and->list.elements; + thd->lex->current_select->cond_count+=cond_and->list.elements; if (!table->outer_join) // Not left join { if (!(*conds=and_conds(*conds, cond_and))) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index d483cceb562..c77d9c1f0b0 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; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 82df3c5ff9f..075c19900fe 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1423,7 +1423,6 @@ void select_insert::send_error(uint errcode,const char *err) { if (last_insert_id) thd->insert_id(last_insert_id); // For binary log - 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, @@ -1455,7 +1454,6 @@ bool select_insert::send_eof() if (last_insert_id) thd->insert_id(last_insert_id); // For binary log /* Write to binlog before commiting transaction */ - 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_parse.cc b/sql/sql_parse.cc index 890a7c46d6e..b9324d922ff 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1073,7 +1073,7 @@ bool do_command(THD *thd) indicator of uninitialized lex => normal flow of errors handling (see my_message_sql) */ - thd->lex.current_select= 0; + thd->lex->current_select= 0; packet=0; old_timeout=net->read_timeout; @@ -2275,7 +2275,6 @@ mysql_execute_command(THD *thd) /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { - 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); @@ -2301,7 +2300,6 @@ mysql_execute_command(THD *thd) /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { - 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); @@ -2340,7 +2338,6 @@ mysql_execute_command(THD *thd) /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { - 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); @@ -2941,13 +2938,13 @@ mysql_execute_command(THD *thd) res= -1; #endif break; + } case SQLCOM_DROP_USER: { if (check_access(thd, GRANT_ACL,"mysql",0,1)) break; if (!(res= mysql_drop_user(thd, lex->users_list))) { - 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); @@ -2963,7 +2960,6 @@ mysql_execute_command(THD *thd) break; if (!(res = mysql_revoke_all(thd, lex->users_list))) { - 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); @@ -3074,7 +3070,6 @@ mysql_execute_command(THD *thd) */ if (!lex->no_write_to_binlog && write_to_binlog) { - 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_select.cc b/sql/sql_select.cc index a9c7fc513f6..0ed6fdf7687 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -444,8 +444,8 @@ JOIN::optimize() optimized= 1; // Ignore errors of execution if option IGNORE present - if (thd->lex.duplicates == DUP_IGNORE) - thd->lex.current_select->no_error= 1; + if (thd->lex->duplicates == DUP_IGNORE) + thd->lex->current_select->no_error= 1; #ifdef HAVE_REF_TO_FIELDS // Not done yet /* Add HAVING to WHERE if possible */ if (having && !group_list && !sum_func_count) @@ -2256,7 +2256,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, if (!(key_fields=(KEY_FIELD*) thd->alloc(sizeof(key_fields[0])* - (thd->lex.current_select->cond_count+1)*2))) + (thd->lex->current_select->cond_count+1)*2))) return TRUE; /* purecov: inspected */ and_level=0; end=key_fields; if (cond) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ee091ee9fc9..da1cf4128cd 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -385,7 +385,7 @@ int mysql_update(THD *thd, err: delete select; - free_underlaid_joins(thd, &thd->lex.select_lex); + free_underlaid_joins(thd, &thd->lex->select_lex); if (table->key_read) { table->key_read=0; -- cgit v1.2.1 From c8d7ca2b1ee4029454afea79def701af829e1db7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 10 Jul 2003 12:45:34 +0200 Subject: A test in subselect.test turned out to be correct after all, a difference between 5.0 and 4.1 (where it fails). mysql-test/r/subselect.result: It turns out that it's correct that this test doesn't give an error in 5.0. mysql-test/t/subselect.test: It turns out that it's correct that this test doesn't give an error in 5.0. --- mysql-test/r/subselect.result | 8 ++++++++ mysql-test/t/subselect.test | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 7292230cf5e..3fe62d46e1c 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -608,6 +608,14 @@ x 3 3 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; +select * from t1; +x +1 +2 +3 +3 +11 +11 INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); ERROR 42S22: Unknown column 'x' in 'field list' INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 0be80c21c8d..0d9a485311f 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -351,9 +351,9 @@ 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; -# QQ This doesn't work right since the merge /pem 2003-07-09 -#-- error 1093 +# After this, only data based on old t1 records should have been added. INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; +select * from t1; -- error 1054 INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); -- cgit v1.2.1 From c64dda59434c026071c09515a68d3c70c15dd648 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Jul 2003 16:34:50 +0300 Subject: allow to look up queries with leading comments BitKeeper/etc/ignore: Added libmysqld/sp_cache.cc to the ignore list mysql-test/r/query_cache.result: test of query with leding comment mysql-test/t/query_cache.test: test of query with leding comment --- .bzrignore | 1 + mysql-test/r/query_cache.result | 24 ++++++++++++++++++++++++ mysql-test/t/query_cache.test | 14 ++++++++++++++ sql/sql_cache.cc | 13 +++++++++---- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/.bzrignore b/.bzrignore index 23acc9e7dbc..2643fdfa3b6 100644 --- a/.bzrignore +++ b/.bzrignore @@ -625,3 +625,4 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +libmysqld/sp_cache.cc diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 3b3e52d8240..8d97b36406e 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -699,3 +699,27 @@ Variable_name Value Qcache_queries_in_cache 2 SET OPTION SQL_SELECT_LIMIT=DEFAULT; drop table t1; +create table t1 (a int); +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 41 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 13 +/**/ select * from t1; +a +/**/ select * from t1; +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 42 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 14 +drop table t1; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 929146ba97a..2a2e17e839f 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -477,3 +477,17 @@ select * from t1; show status like "Qcache_queries_in_cache"; SET OPTION SQL_SELECT_LIMIT=DEFAULT; drop table t1; + +# +# comments before command +# +create table t1 (a int); +show status like "Qcache_queries_in_cache"; +show status like "Qcache_inserts"; +show status like "Qcache_hits"; +/**/ select * from t1; +/**/ select * from t1; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_inserts"; +show status like "Qcache_hits"; +drop table t1; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index c77d9c1f0b0..b97e9f02d3b 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -905,11 +905,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) /* Test if the query is a SELECT - (pre-space is removed in dispatch_command) + (pre-space is removed in dispatch_command). + + First '/' looks like comment before command it is not + frequently appeared in real lihe, consequently we can + check all such queries, too. */ - if (my_toupper(system_charset_info, sql[0]) != 'S' || - my_toupper(system_charset_info, sql[1]) != 'E' || - my_toupper(system_charset_info,sql[2]) !='L') + if ((my_toupper(system_charset_info, sql[0]) != 'S' || + my_toupper(system_charset_info, sql[1]) != 'E' || + my_toupper(system_charset_info,sql[2]) !='L') && + sql[0] != '/') { DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); goto err; -- cgit v1.2.1 From 970f1abbdb9a67936b66fc96a0c6fa1f0aa1535c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Jul 2003 01:35:24 -0400 Subject: mysql_test_run.c and associated files, with my initial changes and WAX's changes for Windows netware/Makefile.am: Replace tabs netware/my_manage.c: Various changes toward platform independence netware/my_manage.h: Various changes toward platform independence netware/mysql_test_run.c: Various changes toward platform independence BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + netware/Makefile.am | 56 ++-- netware/my_manage.c | 768 ++++++++++++++++++++++++++++++++--------------- netware/my_manage.h | 34 ++- netware/mysql_test_run.c | 633 +++++++++++++++++++++----------------- 5 files changed, 939 insertions(+), 553 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 2f79988a274..952eb34b853 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -22,6 +22,7 @@ carsten@tsort.bitbybit.dk davida@isil.mysql.com gluh@gluh.(none) gluh@gluh.mysql.r18.ru +greg@gcw.ath.cx greg@mysql.com guilhem@mysql.com gweir@work.mysql.com diff --git a/netware/Makefile.am b/netware/Makefile.am index e4b9a14ecf0..5cc0e21f989 100644 --- a/netware/Makefile.am +++ b/netware/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (c) 2002 Novell, Inc. All Rights Reserved. +# Copyright (c) 2002 Novell, Inc. All Rights Reserved. # # 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 @@ -11,37 +11,37 @@ # 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 +# 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 -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 +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 -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; \ - done; + 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; \ + done; # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/netware/my_manage.c b/netware/my_manage.c index 490438b0485..f5889766726 100644 --- a/netware/my_manage.c +++ b/netware/my_manage.c @@ -1,90 +1,104 @@ /* - Copyright (c) 2003 Novell, Inc. All Rights Reserved. + Copyright (c) 2003 MySQL AB + Copyright (c) 2003 Novell, Inc. - 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 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. + 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 + 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include +*/ + +/***************************************************************************** +** Utility functions for support programs +*****************************************************************************/ + +/* MySQL library headers */ +#include +#include +#include +#include + +/* These 'should' be POSIX or ANSI */ +#include /* ASSERT */ +#include /* vsprintf, va_* */ +#include /* pid_t */ +#ifndef __WIN__ +#include /* fork, rmdir, execve */ +#endif +#include /* freopen */ +#include /* FILE */ +#ifndef __WIN__ +#include /* opendir, readdir */ +#endif + +#if !defined(__NETWARE__) && !defined(__WIN__) +#include +#endif + +#if !defined(__NETWARE__) +#include +#endif + +/* For ASSERT -- Not totally sure about this one: */ +#if !defined(ASSERT) +#define ASSERT(A) assert(A) +#endif #include "my_manage.h" - -/****************************************************************************** - - macros - -******************************************************************************/ - -/****************************************************************************** - - global variables - -******************************************************************************/ - +#define __STDC__ 1 +#include "process.h" /****************************************************************************** - functions - -******************************************************************************/ - -/****************************************************************************** + init_args() - init_args() - - Init an argument list. + Init an argument list. ******************************************************************************/ void init_args(arg_list_t *al) { +#ifndef __WIN__ ASSERT(al != NULL); - + al->argc = 0; al->size = ARG_BUF; - al->argv = malloc(al->size * sizeof(char *)); + al->argv = (char **)my_malloc(al->size * sizeof(char *), MYF(MY_WME)); ASSERT(al->argv != NULL); - +#else + win_args[0]= '\0'; + skip_first_param= TRUE; +#endif return; } /****************************************************************************** - add_arg() - - Add an argument to a list. + add_arg() + + Add an argument to a list. ******************************************************************************/ -void add_arg(arg_list_t *al, char *format, ...) +void add_arg(arg_list_t *al, const char *format, ...) { +#ifndef __WIN__ va_list ap; char temp[PATH_MAX]; ASSERT(al != NULL); - // increase size - if (al->argc >= al->size) + /* increase size */ + if (al->argc >= (int)al->size) { al->size += ARG_BUF; - al->argv = realloc(al->argv, al->size * sizeof(char *)); + al->argv = (char **)my_realloc((char *)al->argv, al->size * sizeof(char *), MYF(MY_WME)); ASSERT(al->argv != NULL); } @@ -94,7 +108,7 @@ void add_arg(arg_list_t *al, char *format, ...) vsprintf(temp, format, ap); va_end(ap); - al->argv[al->argc] = malloc(strlen(temp)+1); + al->argv[al->argc] = my_malloc(strlen(temp)+1, MYF(MY_WME)); ASSERT(al->argv[al->argc] != NULL); strcpy(al->argv[al->argc], temp); @@ -104,19 +118,36 @@ void add_arg(arg_list_t *al, char *format, ...) { al->argv[al->argc] = NULL; } +#else + va_list ap; + char param[PATH_MAX]; + if (!skip_first_param) + { + va_start(ap, format); + vsprintf(¶m, format, ap); + va_end(ap); + strcat(win_args," "); + strcat(win_args,param); + } + else + { + skip_first_param= FALSE; + } +#endif return; } /****************************************************************************** - free_args() - - Free an argument list. + free_args() + + Free an argument list. ******************************************************************************/ void free_args(arg_list_t *al) { +#ifndef __WIN__ int i; ASSERT(al != NULL); @@ -124,74 +155,110 @@ void free_args(arg_list_t *al) for(i = 0; i < al->argc; i++) { ASSERT(al->argv[i] != NULL); - free(al->argv[i]); + my_free(al->argv[i], MYF(MY_WME)); al->argv[i] = NULL; } - free(al->argv); + my_free((char *)al->argv, MYF(MY_WME)); al->argc = 0; al->argv = NULL; - +#endif return; } /****************************************************************************** - sleep_until_file_deleted() - - Sleep until the given file is no longer found. + sleep_until_file_deleted() + + Sleep until the given file is no longer found. ******************************************************************************/ int sleep_until_file_deleted(char *pid_file) { - struct stat buf; - int i, err; - - for(i = 0; (i < TRY_MAX) && (err = !stat(pid_file, &buf)); i++) sleep(1); - - if (err != 0) err = errno; - - return err; + MY_STAT stat_info; + int i, err = 0; +#ifndef __WIN__ + for(i = 0; i < TRY_MAX; i++) + { + if (my_stat(pid_file, &stat_info, MYF(0)) == (MY_STAT *) NULL) + { + err = errno; + break; + } + my_sleep(1); + } +#else + switch (pid_mode) + { + case MASTER_PID: + err= (WaitForSingleObject(master_server, TRY_MAX*1000) == WAIT_TIMEOUT); + pid_mode= 0; + break; + case SLAVE_PID: + err= (WaitForSingleObject(slave_server, TRY_MAX*1000) == WAIT_TIMEOUT); + pid_mode= 0; + break; + }; +#endif + return err; } /****************************************************************************** - sleep_until_file_exists() - - Sleep until the given file exists. + sleep_until_file_exists() + + Sleep until the given file exists. ******************************************************************************/ int sleep_until_file_exists(char *pid_file) { - struct stat buf; - int i, err; - - for(i = 0; (i < TRY_MAX) && (err = stat(pid_file, &buf)); i++) sleep(1); - - if (err != 0) err = errno; - - return err; + MY_STAT stat_info; + int i, err = 0; + +#ifndef __WIN__ + for(i = 0; i < TRY_MAX; i++) + { + if (my_stat(pid_file, &stat_info, MYF(0)) == (MY_STAT *) NULL) + { + err = errno; + break; + } + my_sleep(1); + } +#else + switch (pid_mode) + { + case MASTER_PID: + WaitForSingleObject(master_server, TRY_MAX*1000); + pid_mode= 0; + break; + case SLAVE_PID: + WaitForSingleObject(slave_server, TRY_MAX*1000); + pid_mode= 0; + break; + }; +#endif + + return err; } /****************************************************************************** - wait_for_server_start() - - Wait for the server on the given port to start. + wait_for_server_start() + + Wait for the server on the given port to start. ******************************************************************************/ int wait_for_server_start(char *bin_dir, char *user, char *password, int port) { arg_list_t al; - int err, i; - char mysqladmin_file[PATH_MAX]; + int err = 0, i; char trash[PATH_MAX]; - // mysqladmin file - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); - snprintf(trash, PATH_MAX, "/tmp/trash.out"); - - // args + /* mysqladmin file */ + my_snprintf(trash, PATH_MAX, "/tmp/trash.out"); + + /* args */ init_args(&al); add_arg(&al, "%s", mysqladmin_file); add_arg(&al, "--no-defaults"); @@ -205,13 +272,13 @@ int wait_for_server_start(char *bin_dir, char *user, char *password, int port) add_arg(&al, "--host=localhost"); add_arg(&al, "ping"); - // NetWare does not support the connect timeout in the TCP/IP stack - // -- we will try the ping multiple times - for(i = 0; (i < TRY_MAX) - && (err = spawn(mysqladmin_file, &al, TRUE, NULL, - trash, NULL)); i++) sleep(1); - - // free args + /* NetWare does not support the connect timeout in the TCP/IP stack + -- we will try the ping multiple times */ + for(i = 0; (i < TRY_MAX) + && (err = spawn(mysqladmin_file, &al, TRUE, NULL, + trash, NULL, NOT_NEED_PID)); i++) sleep(1); + + /* free args */ free_args(&al); return err; @@ -219,20 +286,23 @@ int wait_for_server_start(char *bin_dir, char *user, char *password, int port) /****************************************************************************** - spawn() - - Spawn the given path with the given arguments. + spawn() + + Spawn the executable at the given path with the given arguments. ******************************************************************************/ + +#ifdef __NETWARE__ + int spawn(char *path, arg_list_t *al, int join, char *input, char *output, char *error) { - pid_t pid; + pid_t pid; int result = 0; wiring_t wiring = { FD_UNUSED, FD_UNUSED, FD_UNUSED }; unsigned long flags = PROC_CURRENT_SPACE | PROC_INHERIT_CWD; - // open wiring + /* open wiring */ if (input) wiring.infd = open(input, O_RDONLY); @@ -242,14 +312,14 @@ int spawn(char *path, arg_list_t *al, int join, char *input, if (error) wiring.errfd = open(error, O_WRONLY | O_CREAT | O_TRUNC); - // procve requires a NULL + /* procve requires a NULL */ add_arg(al, NULL); - // go + /* go */ pid = procve(path, flags, NULL, &wiring, NULL, NULL, 0, NULL, (const char **)al->argv); - if (pid == -1) + if (pid == -1) { result = -1; } @@ -257,8 +327,8 @@ int spawn(char *path, arg_list_t *al, int join, char *input, { waitpid(pid, &result, 0); } - - // close wiring + + /* close wiring */ if (wiring.infd != -1) close(wiring.infd); @@ -268,207 +338,411 @@ int spawn(char *path, arg_list_t *al, int join, char *input, if (wiring.errfd != -1) close(wiring.errfd); - return result; + return result; +} + +#else /* NOT __NETWARE__ */ + +#ifdef __WIN__ + +int my_vsnprintf_(char *to, size_t n, const char* value, ...) +{ + char *start=to, *end=to+n-1; + uint length, num_state, pre_zero; + reg2 char *par;// = value; + va_list args; + va_start(args,value); + + par = va_arg(args, char *); + while (par != NULL) + { + uint plen,left_len = (uint)(end-to)+1; + if (!par) par = (char*)"(null)"; + plen = (uint) strlen(par); + if (left_len <= plen) + plen = left_len - 1; + to=strnmov(to+strlen(to),par,plen); + par = va_arg(args, char *); + } + va_end(args); + DBUG_ASSERT(to <= end); + *to='\0'; + return (uint) (to - start); +} + +int spawn(char *path, arg_list_t *al, int join, char *input, + char *output, char *error) +{ + char *cl; + char *arg; + intptr_t result; + int j; + int err; + STARTUPINFO startup_info; + PROCESS_INFORMATION process_information; + ULONG dosretval; + int retval; + DWORD exit_code; + SECURITY_ATTRIBUTES process_attributes, thread_attributes; + char command_line[1024]= ""; + + + memset(&startup_info,0,sizeof(STARTUPINFO)); + startup_info.cb = sizeof(STARTUPINFO); + + if (input) + freopen(input, "rb", stdin); + + if (output) + freopen(output, "wb", stdout); + + if (error) + freopen(error, "wb", stderr); + + result= CreateProcess( + path, + &win_args, + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &startup_info, + &process_information + ); + + if (process_information.hProcess) + { + if (join) + { + if (WaitForSingleObject(process_information.hProcess, mysqld_timeout) == WAIT_TIMEOUT) + { + exit_code= -1; + } + else + { + GetExitCodeProcess(process_information.hProcess, &exit_code); + } + CloseHandle(process_information.hProcess); + } + else + { + exit_code= 0; + } + if (run_server) + { + switch (pid_mode) + { + case MASTER_PID: + master_server= process_information.hProcess; + break; + case SLAVE_PID: + slave_server= process_information.hProcess; + break; + }; + pid_mode= 0; + run_server= FALSE; + }; + } + else + { + exit_code= -1; + } + if (input) + freopen("CONIN$","rb",stdin); + if (output) + freopen("CONOUT$","wb",stdout); + if (error) + freopen("CONOUT$","wb",stderr); + + return exit_code; } +#else /* NOT __NETWARE__, NOT __WIN__ */ + +/* This assumes full POSIX.1 compliance */ +int spawn(char *path, arg_list_t *al, int join, char *input, + char *output, char *error) +{ + int result = 0; + pid_t pid; + + if ((pid = fork())) + { + /* Remains in parent process */ + if (join && (pid != -1)) + waitpid(pid, &result, 0); + } + else + { + /* Child process */ + + /* Reassign streams */ + if (input) + freopen(input, "r", stdin); + + if (output) + freopen(output, "w", stdout); + + if (error) + freopen(error, "w", stderr); + + /* Spawn the process */ + execve(path, al->argv, environ); + } + + return result; +} + +#endif /* __WIN__ */ + +#endif /* __NETWARE__ */ + /****************************************************************************** - stop_server() - - Stop the server with the given port and pid file. + stop_server() + + Stop the server with the given port and pid file. ******************************************************************************/ int stop_server(char *bin_dir, char *user, char *password, int port, char *pid_file) { - arg_list_t al; - int err, i, argc = 0; - char mysqladmin_file[PATH_MAX]; + arg_list_t al; + int err; char trash[PATH_MAX]; - // mysqladmin file - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); - snprintf(trash, PATH_MAX, "/tmp/trash.out"); - - // args + my_snprintf(trash, PATH_MAX, "/tmp/trash.out"); + + /* args */ init_args(&al); - add_arg(&al, "%s", mysqladmin_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--port=%u", port); - add_arg(&al, "--user=%s", user); - add_arg(&al, "--password=%s", password); - add_arg(&al, "-O"); - add_arg(&al, "shutdown_timeout=20"); - add_arg(&al, "shutdown"); - - // spawn - if ((err = spawn(mysqladmin_file, &al, TRUE, NULL, - trash, NULL)) == 0) - { - sleep_until_file_deleted(pid_file); - } - else - { + add_arg(&al, "%s", mysqladmin_file); + add_arg(&al, "--no-defaults"); + add_arg(&al, "--port=%u", port); + add_arg(&al, "--user=%s", user); + add_arg(&al, "--password=%s", password); + add_arg(&al, "-O"); + add_arg(&al, "shutdown_timeout=20"); + add_arg(&al, "shutdown"); + + /* spawn */ + if ((err = spawn(mysqladmin_file, &al, TRUE, NULL, + trash, NULL)) == 0) + { + sleep_until_file_deleted(pid_file); + } + else + { pid_t pid = get_server_pid(pid_file); - - // shutdown failed - kill server - kill_server(pid); - - sleep(TRY_MAX); - // remove pid file if possible - err = remove(pid_file); + /* shutdown failed - kill server */ + kill_server(pid); + + sleep(TRY_MAX); + + /* remove pid file if possible */ + err = my_delete(pid_file, MYF(MY_WME)); } - // free args + /* free args */ free_args(&al); - return err; + return err; } /****************************************************************************** - get_server_pid() - - Get the VM id with the given pid file. + get_server_pid() + + Get the VM id with the given pid file. ******************************************************************************/ pid_t get_server_pid(char *pid_file) { - char buf[PATH_MAX]; - int fd, err; - char *p; - pid_t id; - - // discover id - fd = open(pid_file, O_RDONLY); - - err = read(fd, buf, PATH_MAX); - - close(fd); - - if (err > 0) - { - // terminate string - if ((p = strchr(buf, '\n')) != NULL) - { - *p = NULL; - - // check for a '\r' - if ((p = strchr(buf, '\r')) != NULL) - { - *p = NULL; - } - } - else - { - buf[err] = NULL; - } - - id = strtol(buf, NULL, 0); - } + char buf[PATH_MAX]; + int err; + File fd; + char *p; + pid_t id = 0; + + /* discover id */ + fd = my_open(pid_file, O_RDONLY, MYF(MY_WME)); + + err = my_read(fd, buf, PATH_MAX, MYF(MY_WME)); + + my_close(fd, MYF(MY_WME)); + + if (err > 0) + { + /* terminate string */ + if ((p = strchr(buf, '\n')) != NULL) + { + *p = '\0'; + + /* check for a '\r' */ + if ((p = strchr(buf, '\r')) != NULL) + { + *p = '\0'; + } + } + else + { + buf[err] = '\0'; + } + id = strtol(buf, NULL, 0); + } + return id; } - /****************************************************************************** - kill_server() - - Force a kill of the server with the given pid. + kill_server() + + Force a kill of the server with the given pid. ******************************************************************************/ void kill_server(pid_t pid) { if (pid > 0) { - // destroy vm + +#if !defined(__NETWARE__) + /* Send SIGTERM to pid */ + kill(pid, SIGTERM); +#else /* __NETWARE__ */ + /* destroy vm */ NXVmDestroy(pid); + +#endif + } } /****************************************************************************** - del_tree() - - Delete the directory and subdirectories. + del_tree() + + Delete the directory and subdirectories. ******************************************************************************/ void del_tree(char *dir) { - DIR *parent = opendir(dir); - DIR *entry; - char temp[PATH_MAX]; - - if (parent == NULL) - { - return; - } - - while((entry = readdir(parent)) != NULL) - { - // create long name - snprintf(temp, PATH_MAX, "%s/%s", dir, entry->d_name); - - if (entry->d_name[0] == '.') - { - // Skip - } - else if (S_ISDIR(entry->d_type)) - { - // delete subdirectory - del_tree(temp); - } - else - { - // remove file - remove(temp); - } - } - - // remove directory - rmdir(dir); + MY_DIR *current; + uint i; + char temp[PATH_MAX]; + + current = my_dir(dir, MYF(MY_WME | MY_WANT_STAT)); + + /* current is NULL if dir does not exist */ + if (current == NULL) + return; + + for (i = 0; i < current->number_off_files; i++) + { + /* create long name */ + my_snprintf(temp, PATH_MAX, "%s/%s", dir, current->dir_entry[i].name); + + if (current->dir_entry[i].name[0] == '.') + { + /* Skip */ + } + else if (MY_S_ISDIR(current->dir_entry[i].mystat.st_mode)) + { + /* delete subdirectory */ + del_tree(temp); + } + else + { + /* remove file */ + my_delete(temp, MYF(MY_WME)); + } + } + + my_dirend(current); + + /* remove directory */ + rmdir(dir); } /****************************************************************************** - removef() - + removef() + ******************************************************************************/ -int removef(char *format, ...) +int removef(const char *format, ...) { - va_list ap; + va_list ap; char path[PATH_MAX]; - - va_start(ap, format); - vsnprintf(path, PATH_MAX, format, ap); - - va_end(ap); + va_start(ap, format); + + my_vsnprintf(path, PATH_MAX, format, ap); - return remove(path); + va_end(ap); +#ifdef __WIN__ + { + MY_DIR *current; + uint i; + struct _finddata_t find; + char temp[PATH_MAX]; +#ifdef _WIN64 + __int64 handle; +#else + long handle; +#endif + char *p; + + p= strrchr(path,'\\'); + if (p == NULL) + { + p= strrchr(path,'/'); + if (p == NULL) + p= &path; + else + p++; + } + else + p++; + + if ((handle=_findfirst(path,&find)) == -1L) + return 0; + do + { + strcpy(p,find.name); + my_delete(path, MYF(MY_WME)); + } while (!_findnext(handle,&find)); + _findclose(handle); + } +#else + return my_delete(path, MYF(MY_WME)); +#endif } /****************************************************************************** - get_basedir() - + get_basedir() + ******************************************************************************/ void get_basedir(char *argv0, char *basedir) { - char temp[PATH_MAX]; - char *p; - - ASSERT(argv0 != NULL); + char temp[PATH_MAX]; + char *p; + + ASSERT(argv0 != NULL); ASSERT(basedir != NULL); - strcpy(temp, strlwr(argv0)); - while((p = strchr(temp, '\\')) != NULL) *p = '/'; - - if ((p = strindex(temp, "/bin/")) != NULL) - { - *p = NULL; - strcpy(basedir, temp); - } + strcpy(temp, argv0); +#ifndef __WIN__ + casedn_str(temp); +#endif + while((p = strchr(temp, '\\')) != NULL) *p = '/'; + + if ((p = strstr(temp, "/bin/")) != NullS) + { + *p = '\0'; + strcpy(basedir, temp); + } } diff --git a/netware/my_manage.h b/netware/my_manage.h index b19662c4ee9..4215ae59a25 100644 --- a/netware/my_manage.h +++ b/netware/my_manage.h @@ -26,17 +26,41 @@ ******************************************************************************/ #include +#ifndef __WIN__ #include +#endif /****************************************************************************** macros ******************************************************************************/ +#ifdef __WIN__ +#define PATH_MAX _MAX_PATH +#define NAME_MAX _MAX_FNAME +#define kill(A,B) TerminateProcess((HANDLE)A,0) +#define NOT_NEED_PID 0 +#define MASTER_PID 1 +#define SLAVE_PID 2 +#define mysqld_timeout 60000 + +intptr_t master_server; +intptr_t slave_server; +int pid_mode; +bool run_server; +char win_args[1024]; +bool skip_first_param; +#endif + #define ARG_BUF 10 #define TRY_MAX 5 +#ifdef __NETWARE__ +#define strstr(A,B) strindex(A,B) +#endif + + /****************************************************************************** structures @@ -53,6 +77,8 @@ typedef struct } arg_list_t; + +typedef int pid_t; /****************************************************************************** global variables @@ -66,7 +92,7 @@ typedef struct ******************************************************************************/ void init_args(arg_list_t *); -void add_arg(arg_list_t *, char *, ...); +void add_arg(arg_list_t *, const char *, ...); void free_args(arg_list_t *); int sleep_until_file_exists(char *); @@ -80,8 +106,12 @@ pid_t get_server_pid(char *); void kill_server(pid_t pid); void del_tree(char *); -int removef(char *, ...); +int removef(const char *, ...); void get_basedir(char *, char *); +char mysqladmin_file[PATH_MAX]; + #endif /* _MY_MANAGE */ + + diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index 8bf0b7e0016..fb914c355e4 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -16,21 +16,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include + +/* MySQL library headers */ +#include +#include +#include +#include + +/* These 'should' be POSIX or ANSI */ #include -#include -#include -#include +#include + +#ifdef __NETWARE__ #include -#include -#include -#include -#include -#include +#endif #include "my_config.h" #include "my_manage.h" +#ifdef __WIN__ +#include +#endif + + /****************************************************************************** macros @@ -42,16 +50,16 @@ #define NW_TEST_SUFFIX ".nw-test" #define NW_RESULT_SUFFIX ".nw-result" -#define TEST_SUFFIX ".test" -#define RESULT_SUFFIX ".result" -#define REJECT_SUFFIX ".reject" -#define OUT_SUFFIX ".out" -#define ERR_SUFFIX ".err" +#define TEST_SUFFIX ".test" +#define RESULT_SUFFIX ".result" +#define REJECT_SUFFIX ".reject" +#define OUT_SUFFIX ".out" +#define ERR_SUFFIX ".err" -#define TEST_PASS "[ pass ]" -#define TEST_SKIP "[ skip ]" -#define TEST_FAIL "[ fail ]" -#define TEST_BAD "[ bad ]" +#define TEST_PASS "[ pass ]" +#define TEST_SKIP "[ skip ]" +#define TEST_FAIL "[ fail ]" +#define TEST_BAD "[ bad ]" /****************************************************************************** @@ -59,7 +67,7 @@ ******************************************************************************/ -char base_dir[PATH_MAX] = "sys:/mysql"; +char base_dir[PATH_MAX] = "/mysql"; char db[PATH_MAX] = "test"; char user[PATH_MAX] = "root"; char password[PATH_MAX] = ""; @@ -67,7 +75,7 @@ char password[PATH_MAX] = ""; int master_port = 9306; int slave_port = 9307; -// comma delimited list of tests to skip or empty string +/* comma delimited list of tests to skip or empty string */ char skip_test[PATH_MAX] = ""; char bin_dir[PATH_MAX]; @@ -80,7 +88,6 @@ char slave_dir[PATH_MAX]; char lang_dir[PATH_MAX]; char char_dir[PATH_MAX]; -char mysqladmin_file[PATH_MAX]; char mysqld_file[PATH_MAX]; char mysqltest_file[PATH_MAX]; char master_pid[PATH_MAX]; @@ -109,17 +116,30 @@ int single_test = TRUE; int restarts = 0; FILE *log_fd = NULL; +// WAX +#include + +const char* mysqld = "mysqld", *opt_exedir="client_debug"; + +static struct my_option my_long_options[] = +{ + {"mysqld", 'M', "Type of mysqld (without extention of file)- mysqld, mysql-nt, mysql-nt-max, mysqld-max.", + (gptr*) &mysqld, (gptr*) &mysqld, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"exefiledir", 'e', "Directory of .exe files (client_debug or client_release).", (gptr*) &opt_exedir, + (gptr*) &opt_exedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +}; + /****************************************************************************** functions - + ******************************************************************************/ /****************************************************************************** prototypes - + ******************************************************************************/ void report_stats(); @@ -135,17 +155,17 @@ void mysql_restart(); int read_option(char *, char *); void run_test(char *); void setup(char *); -void vlog(char *, va_list); -void log(char *, ...); -void log_info(char *, ...); -void log_error(char *, ...); -void log_errno(char *, ...); -void die(char *); +void vlog(const char *, va_list); +void mtr_log(const char *, ...); +void mtr_log_info(const char *, ...); +void mtr_log_error(const char *, ...); +void mtr_log_errno(const char *, ...); +void die(const char *); /****************************************************************************** report_stats() - + Report the gathered statistics. ******************************************************************************/ @@ -153,42 +173,42 @@ void report_stats() { if (total_fail == 0) { - log("\nAll %d test(s) were successful.\n", total_test); + mtr_log("\nAll %d test(s) were successful.\n", total_test); } else { double percent = ((double)total_pass / total_test) * 100; - - log("\nFailed %u/%u test(s), %.02f%% successful.\n", + + mtr_log("\nFailed %u/%u test(s), %.02f%% successful.\n", total_fail, total_test, percent); - log("\nThe .out and .err files in %s may give you some\n", result_dir); - log("hint of what when wrong.\n"); - log("\nIf you want to report this error, please first read the documentation\n"); - log("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n"); + mtr_log("\nThe .out and .err files in %s may give you some\n", result_dir); + mtr_log("hint of what when wrong.\n"); + mtr_log("\nIf you want to report this error, please first read the documentation\n"); + mtr_log("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n"); } - log("\n%.02f total minutes elapsed in the test cases\n\n", total_time / 60); + mtr_log("\n%.02f total minutes elapsed in the test cases\n\n", total_time / 60); } /****************************************************************************** install_db() - + Install the a database. ******************************************************************************/ void install_db(char *datadir) { arg_list_t al; - int err, i; + int err; char input[PATH_MAX]; char output[PATH_MAX]; char error[PATH_MAX]; // input file - snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir); - snprintf(output, PATH_MAX, "%s/install.out", datadir); - snprintf(error, PATH_MAX, "%s/install.err", datadir); + my_snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir); + my_snprintf(output, PATH_MAX, "%s/install.out", datadir); + my_snprintf(error, PATH_MAX, "%s/install.err", datadir); // args init_args(&al); @@ -201,6 +221,7 @@ void install_db(char *datadir) add_arg(&al, "--skip-bdb"); // spawn + if ((err = spawn(mysqld_file, &al, TRUE, input, output, error)) != 0) { die("Unable to create database."); @@ -221,34 +242,34 @@ void mysql_install_db() { char temp[PATH_MAX]; - // var directory - snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir); + /* var directory */ + my_snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir); - // clean up old direcotry + /* clean up old directory */ del_tree(temp); - // create var directory - mkdir(temp, S_IRWXU); - - // create subdirectories - snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); - - // install databases + /* create var directory */ + my_mkdir(temp, 0700, MYF(MY_WME)); + + /* create subdirectories */ + my_snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + my_snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + my_snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + my_snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + my_snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + my_snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + my_snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + my_snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir); + my_mkdir(temp, 0700, MYF(MY_WME)); + + /* install databases */ install_db(master_dir); install_db(slave_dir); } @@ -263,56 +284,35 @@ void mysql_install_db() void start_master() { arg_list_t al; - int err, i; + int err; 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 + /* remove old berkeley db log files that can confuse the server */ removef("%s/log.*", master_dir); - - // remove stale binary logs + + /* remove stale binary logs */ removef("%s/*-bin.*", master_dir); - // remove stale binary logs + /* remove stale binary logs */ removef("%s/*.index", master_dir); - // remove master.info file + /* remove master.info file */ removef("%s/master.info", master_dir); - // remove relay files + /* remove relay files */ removef("%s/var/log/*relay*", mysql_test_dir); - // remove relay-log.info file + /* remove relay-log.info file */ removef("%s/relay-log.info", master_dir); - // init script - 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 - snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out", + /* redirection files */ + my_snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out", mysql_test_dir, restarts); - snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err", + my_snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err", mysql_test_dir, restarts); - // args + /* args */ init_args(&al); add_arg(&al, "%s", mysqld_file); add_arg(&al, "--no-defaults"); @@ -328,11 +328,11 @@ void start_master() add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); add_arg(&al, "--language=%s", lang_dir); - // $MASTER_40_ARGS + /* $MASTER_40_ARGS */ add_arg(&al, "--rpl-recovery-rank=1"); add_arg(&al, "--init-rpl-role=master"); - // $SMALL_SERVER + /* $SMALL_SERVER */ add_arg(&al, "-O"); add_arg(&al, "key_buffer_size=1M"); add_arg(&al, "-O"); @@ -340,8 +340,8 @@ void start_master() add_arg(&al, "-O"); add_arg(&al, "max_heap_table_size=1M"); - // $EXTRA_MASTER_OPT - if (master_opt[0] != NULL) + /* $EXTRA_MASTER_OPT */ + if (master_opt[0] != '\0') { char *p; @@ -350,34 +350,39 @@ void start_master() while(p) { add_arg(&al, "%s", p); - + p = (char *)strtok(NULL, " \t"); } } - // remove the pid file if it exists - remove(master_pid); + /* remove the pid file if it exists */ +#ifndef __WIN__ + my_delete(master_pid, MYF(MY_WME)); +#else + pid_mode= MASTER_PID; + run_server= TRUE; +#endif - // spawn + /* spawn */ if ((err = spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err)) == 0) { sleep_until_file_exists(master_pid); - if ((err = wait_for_server_start(bin_dir, user, password, master_port)) == 0) + if ((err = wait_for_server_start(bin_dir, user, password, master_port)) == 0) { master_running = TRUE; } else { - log_error("The master server went down early."); + mtr_log_error("The master server went down early."); } } else { - log_error("Unable to start master server."); + mtr_log_error("Unable to start master server."); } - // free_args + /* free_args */ free_args(&al); } @@ -391,48 +396,48 @@ void start_master() void start_slave() { arg_list_t al; - int err, i; + int err; char slave_out[PATH_MAX]; char slave_err[PATH_MAX]; char temp[PATH_MAX]; - // skip? + /* skip? */ if (skip_slave) return; - // remove stale binary logs + /* remove stale binary logs */ removef("%s/*-bin.*", slave_dir); - // remove stale binary logs + /* remove stale binary logs */ removef("%s/*.index", slave_dir); - // remove master.info file + /* remove master.info file */ removef("%s/master.info", slave_dir); - // remove relay files + /* remove relay files */ removef("%s/var/log/*relay*", mysql_test_dir); - // remove relay-log.info file + /* remove relay-log.info file */ removef("%s/relay-log.info", slave_dir); - // init script - if (slave_init_script[0] != NULL) + /* init script */ + if (slave_init_script[0] != '\0') { - // run_init_script(slave_init_script); + /* run_init_script(slave_init_script); */ - // TODO: use the scripts - if (strindex(slave_init_script, "rpl000016-slave.sh") != NULL) + /* TODO: use the scripts */ + if (strstr(slave_init_script, "rpl000016-slave.sh") != NULL) { - // create empty master.info file - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); - close(open(temp, O_WRONLY | O_CREAT)); + /* create empty master.info file */ + my_snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); + my_close(my_open(temp, O_WRONLY | O_CREAT, MYF(0)), MYF(0)); } - else if (strindex(slave_init_script, "rpl000017-slave.sh") != NULL) + else if (strstr(slave_init_script, "rpl000017-slave.sh") != NullS) { FILE *fp; - // create a master.info file - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); - fp = fopen(temp, "wb+"); + /* create a master.info file */ + my_snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); + fp = my_fopen(temp, (int)(O_WRONLY | O_BINARY | O_CREAT), MYF(MY_WME)); fputs("master-bin.001\n", fp); fputs("4\n", fp); @@ -443,20 +448,20 @@ void start_slave() fputs("1\n", fp); fputs("0\n", fp); - fclose(fp); + my_fclose(fp, MYF(MY_WME)); } - else if (strindex(slave_init_script, "rpl_rotate_logs-slave.sh") != NULL) + else if (strstr(slave_init_script, "rpl_rotate_logs-slave.sh") != NullS) { - // create empty master.info file - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); - close(open(temp, O_WRONLY | O_CREAT)); + /* create empty master.info file */ + my_snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); + my_close(my_open(temp, O_WRONLY | O_CREAT, MYF(0)), MYF(0)); } } - // redirection files - snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out", + /* redirection files */ + my_snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out", mysql_test_dir, restarts); - snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err", + my_snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err", mysql_test_dir, restarts); // args @@ -482,15 +487,15 @@ void start_slave() add_arg(&al, "--slave-load-tmpdir=../../var/tmp"); add_arg(&al, "--report-user=%s", user); - add_arg(&al, "--report-host=127.0.0.1"); + add_arg(&al, "--report-host=127.0.0.1"); add_arg(&al, "--report-port=%u", slave_port); add_arg(&al, "--master-retry-count=10"); add_arg(&al, "-O"); add_arg(&al, "slave_net_timeout=10"); - // slave master info - if (slave_master_info[0] != NULL) + /* slave master info */ + if (slave_master_info[0] != '\0') { char *p; @@ -514,7 +519,7 @@ void start_slave() add_arg(&al, "--rpl-recovery-rank=2"); } - // small server + /* small server */ add_arg(&al, "-O"); add_arg(&al, "key_buffer_size=1M"); add_arg(&al, "-O"); @@ -522,8 +527,8 @@ void start_slave() add_arg(&al, "-O"); add_arg(&al, "max_heap_table_size=1M"); - // opt args - if (slave_opt[0] != NULL) + /* opt args */ + if (slave_opt[0] != '\0') { char *p; @@ -536,9 +541,14 @@ void start_slave() p = (char *)strtok(NULL, " \t"); } } - - // remove the pid file if it exists - remove(slave_pid); + + /* remove the pid file if it exists */ +#ifndef __WIN__ + my_delete(slave_pid, MYF(MY_WME)); +#else + pid_mode= SLAVE_PID; + run_server= TRUE; +#endif // spawn if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err)) == 0) @@ -551,12 +561,12 @@ void start_slave() } else { - log_error("The slave server went down early."); + mtr_log_error("The slave server went down early."); } } else { - log_error("Unable to start slave server."); + mtr_log_error("Unable to start slave server."); } // free args @@ -576,8 +586,10 @@ void mysql_start() start_slave(); +#ifdef __NETWARE__ // activate the test screen ActivateScreen(getscreenhandle()); +#endif } /****************************************************************************** @@ -591,17 +603,20 @@ void stop_slave() { int err; - // running? + /* running? */ if (!slave_running) return; +#ifdef __WIN__ + pid_mode= SLAVE_PID; +#endif - // stop + /* stop */ if ((err = stop_server(bin_dir, user, password, slave_port, slave_pid)) == 0) { slave_running = FALSE; } else { - log_error("Unable to stop slave server."); + mtr_log_error("Unable to stop slave server."); } } @@ -616,16 +631,18 @@ void stop_master() { int err; - // running? + /* running? */ if (!master_running) return; - +#ifdef __WIN__ + pid_mode= MASTER_PID; +#endif if ((err = stop_server(bin_dir, user, password, master_port, master_pid)) == 0) { master_running = FALSE; } else { - log_error("Unable to stop master server."); + mtr_log_error("Unable to stop master server."); } } @@ -642,8 +659,10 @@ void mysql_stop() stop_slave(); +#ifdef __NETWARE__ // activate the test screen ActivateScreen(getscreenhandle()); +#endif } /****************************************************************************** @@ -655,7 +674,7 @@ void mysql_stop() ******************************************************************************/ void mysql_restart() { - log_info("Restarting the MySQL server(s): %u", ++restarts); + mtr_log_info("Restarting the MySQL server(s): %u", ++restarts); mysql_stop(); @@ -671,45 +690,50 @@ void mysql_restart() ******************************************************************************/ int read_option(char *opt_file, char *opt) { - int fd, err; - int result; + File fd; + int err; char *p; char buf[PATH_MAX]; - // copy current option + /* copy current option */ strncpy(buf, opt, PATH_MAX); - // open options file - fd = open(opt_file, O_RDONLY); +#ifdef __WIN__ + if (PathFileExistsA(opt_file)) + { +#endif + + /* open options file */ + fd = my_open(opt_file, O_RDONLY, MYF(MY_WME)); - err = read(fd, opt, PATH_MAX); + err = my_read(fd, opt, PATH_MAX, MYF(MY_WME)); - close(fd); + my_close(fd, MYF(MY_WME)); if (err > 0) { - // terminate string + /* terminate string */ if ((p = strchr(opt, '\n')) != NULL) { - *p = NULL; + *p = '\0'; - // check for a '\r' + /* check for a '\r' */ if ((p = strchr(opt, '\r')) != NULL) { - *p = NULL; + *p = '\0'; } } else { - opt[err] = NULL; + opt[err] = '\0'; } - // check for $MYSQL_TEST_DIR - if ((p = strstr(opt, "$MYSQL_TEST_DIR")) != NULL) + /* check for $MYSQL_TEST_DIR */ + if ((p = strstr(opt, "$MYSQL_TEST_DIR")) != NullS) { char temp[PATH_MAX]; - *p = NULL; + *p = '\0'; strcpy(temp, p + strlen("$MYSQL_TEST_DIR")); @@ -720,11 +744,14 @@ int read_option(char *opt_file, char *opt) } else { - // clear option - *opt = NULL; + /* clear option */ + *opt = '\0'; } +#ifdef __WIN__ + } +#endif - // compare current option with previous + /* compare current option with previous */ return strcmp(opt, buf); } @@ -739,21 +766,20 @@ void run_test(char *test) { char temp[PATH_MAX]; char *rstr; - double elapsed = 0; int skip = FALSE; int restart = FALSE; int flag = FALSE; struct stat info; - - // single test? + + /* single test? */ if (!single_test) { // skip tests in the skip list - snprintf(temp, PATH_MAX, " %s ", test); - skip = (strindex(skip_test, temp) != NULL); + my_snprintf(temp, PATH_MAX, " %s ", test); + skip = strinstr(skip_test, temp); } - // skip test? + /* skip test? */ if (!skip) { char test_file[PATH_MAX]; @@ -766,7 +792,6 @@ void run_test(char *test) char err_file[PATH_MAX]; int err; arg_list_t al; - NXTime_t start, stop; // skip slave? flag = skip_slave; @@ -774,36 +799,36 @@ void run_test(char *test) if (flag != skip_slave) restart = TRUE; // create files - snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test); - snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test); - snprintf(slave_master_info_file, PATH_MAX, "%s/%s.slave-mi", test_dir, test); - snprintf(reject_file, PATH_MAX, "%s/%s%s", result_dir, test, REJECT_SUFFIX); - snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX); - snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX); + my_snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test); + my_snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test); + my_snprintf(slave_master_info_file, PATH_MAX, "%s/%s.slave-mi", test_dir, test); + my_snprintf(reject_file, PATH_MAX, "%s/%s%s", result_dir, test, REJECT_SUFFIX); + my_snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX); + my_snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX); // netware specific files - snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX); + my_snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX); if (stat(test_file, &info)) { - snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX); + my_snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX); } - snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX); + my_snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX); if (stat(result_file, &info)) { - snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, RESULT_SUFFIX); + my_snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, RESULT_SUFFIX); } // init scripts - snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test); + my_snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test); if (stat(master_init_script, &info)) - master_init_script[0] = NULL; + master_init_script[0] = '\0'; else restart = TRUE; - snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test); + my_snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test); if (stat(slave_init_script, &info)) - slave_init_script[0] = NULL; + slave_init_script[0] = '\0'; else restart = TRUE; @@ -825,7 +850,7 @@ void run_test(char *test) sleep(1); // show test - log("%-46s ", test); + mtr_log("%-46s ", test); // args init_args(&al); @@ -842,26 +867,16 @@ void run_test(char *test) add_arg(&al, "-R"); add_arg(&al, "%s", result_file); - // start timer - NXGetTime(NX_SINCE_BOOT, NX_USECONDS, &start); - // spawn err = spawn(mysqltest_file, &al, TRUE, test_file, out_file, err_file); - - // stop timer - NXGetTime(NX_SINCE_BOOT, NX_USECONDS, &stop); - - // calculate - elapsed = ((double)(stop - start)) / NX_USECONDS; - total_time += elapsed; - + // free args free_args(&al); if (err == 0) { // pass - rstr = TEST_PASS; + rstr = (char *)TEST_PASS; ++total_pass; // increment total @@ -870,13 +885,13 @@ void run_test(char *test) else if (err == 2) { // skip - rstr = TEST_SKIP; + rstr = (char *)TEST_SKIP; ++total_skip; } else if (err == 1) { // fail - rstr = TEST_FAIL; + rstr = (char *)TEST_FAIL; ++total_fail; // increment total @@ -884,21 +899,21 @@ void run_test(char *test) } else { - rstr = TEST_BAD; + rstr = (char *)TEST_BAD; } } else // early skips { // show test - log("%-46s ", test); + mtr_log("%-46s ", test); // skip - rstr = TEST_SKIP; + rstr = (char *)TEST_SKIP; ++total_skip; } // result - log("%10.06f %-14s\n", elapsed, rstr); + mtr_log(" %-14s\n", rstr); } /****************************************************************************** @@ -908,7 +923,7 @@ void run_test(char *test) Log the message. ******************************************************************************/ -void vlog(char *format, va_list ap) +void vlog(const char *format, va_list ap) { vfprintf(stdout, format, ap); fflush(stdout); @@ -922,12 +937,12 @@ void vlog(char *format, va_list ap) /****************************************************************************** - log() + mtr_log() Log the message. ******************************************************************************/ -void log(char *format, ...) +void mtr_log(const char *format, ...) { va_list ap; @@ -940,60 +955,60 @@ void log(char *format, ...) /****************************************************************************** - log_info() + mtr_log_info() Log the given information. ******************************************************************************/ -void log_info(char *format, ...) +void mtr_log_info(const char *format, ...) { va_list ap; va_start(ap, format); - log("-- INFO : "); + mtr_log("-- INFO : "); vlog(format, ap); - log("\n"); + mtr_log("\n"); va_end(ap); } /****************************************************************************** - log_error() + mtr_log_error() Log the given error. ******************************************************************************/ -void log_error(char *format, ...) +void mtr_log_error(const char *format, ...) { va_list ap; va_start(ap, format); - log("-- ERROR: "); + mtr_log("-- ERROR: "); vlog(format, ap); - log("\n"); + mtr_log("\n"); va_end(ap); } /****************************************************************************** - log_errno() + mtr_log_errno() Log the given error and errno. ******************************************************************************/ -void log_errno(char *format, ...) +void mtr_log_errno(const char *format, ...) { va_list ap; va_start(ap, format); - log("-- ERROR: (%003u) ", errno); + mtr_log("-- ERROR: (%003u) ", errno); vlog(format, ap); - log("\n"); + mtr_log("\n"); va_end(ap); } @@ -1005,11 +1020,13 @@ void log_errno(char *format, ...) Exit the application. ******************************************************************************/ -void die(char *msg) +void die(const char *msg) { - log_error(msg); + mtr_log_error(msg); +#ifdef __NETWARE__ pressanykey(); +#endif exit(-1); } @@ -1027,50 +1044,83 @@ void setup(char *file) char *p; // set the timezone for the timestamp test +#ifdef __WIN__ + _putenv( "TZ=GMT-3" ); +#else setenv("TZ", "GMT-3", TRUE); +#endif // find base dir - strcpy(temp, strlwr(file)); + strcpy(temp, file); +#ifndef __WIN__ + casedn_str(temp); +#endif while((p = strchr(temp, '\\')) != NULL) *p = '/'; - if ((p = strindex(temp, "/mysql-test/")) != NULL) + if ((p = strstr(temp, "/mysql-test/"))) { - *p = NULL; - strcpy(base_dir, temp); + *p = '\0'; + strcpy(base_dir, (const char *)temp); } // setup paths - snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir); - snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); - snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); - snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir); - snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir); +#ifdef __WIN__ + my_snprintf(bin_dir, PATH_MAX, "%s/%s", base_dir,opt_exedir); +#else + my_snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir); +#endif + my_snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); + my_snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); + my_snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); + my_snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); + my_snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); + my_snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); + my_snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir); + my_snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir); // setup files - snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir); - snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir); - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); - snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir); - snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir); +#ifdef __WIN__ + my_snprintf(mysqld_file, PATH_MAX, "%s/%s.exe", bin_dir, mysqld); + my_snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest.exe", bin_dir); + my_snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin.exe", bin_dir); + pid_mode= NOT_NEED_PID; +#else + my_snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir); + my_snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir); + my_snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); +#endif + my_snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir); + my_snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir); // create log file - snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir); + my_snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir); if ((log_fd = fopen(temp, "w+")) == NULL) { - log_errno("Unable to create log file."); + mtr_log_errno("Unable to create log file."); } // prepare skip test list while((p = strchr(skip_test, ',')) != NULL) *p = ' '; - strcpy(temp, strlwr(skip_test)); - snprintf(skip_test, PATH_MAX, " %s ", temp); + strcpy(temp, skip_test); +#ifndef __WIN__ + casedn_str(temp); +#endif + my_snprintf(skip_test, PATH_MAX, " %s ", temp); // enviornment - setenv("MYSQL_TEST_DIR", mysql_test_dir, 1); +#ifdef __WIN__ + my_snprintf(temp, PATH_MAX, "MYSQL_TEST_DIR=%s", mysql_test_dir); + _putenv(temp); +#else + setenv("MYSQL_TEST_DIR", mysql_test_dir, 1); +#endif +} + +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + return(0); } /****************************************************************************** @@ -1080,31 +1130,59 @@ void setup(char *file) ******************************************************************************/ int main(int argc, char **argv) { + int i; + uint ui; + + +#ifdef __WIN__ + int ho_error; + DWORD len= PATH_MAX; + char current_dir[PATH_MAX] = "."; + + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(1); + if (len= GetCurrentDirectory(&len,current_dir)) + { + current_dir[len]= '\\'; + current_dir[len+1]='\0'; + }; + MY_INIT(current_dir); +#endif // setup +#ifdef __WIN__ + setup(current_dir); +#else setup(argv[0]); - +#endif // header - log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE); + mtr_log("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE); - log("Initializing Tests...\n"); + mtr_log("Initializing Tests...\n"); // install test databases mysql_install_db(); - log("Starting Tests...\n"); + mtr_log("Starting Tests...\n"); - log("\n"); - log(HEADER); - log(DASH); + mtr_log("\n"); + mtr_log(HEADER); + mtr_log(DASH); +#ifdef __WIN__ + if (argc > 0) +#else if (argc > 1) +#endif { - int i; // single test single_test = TRUE; +#ifdef __WIN__ + for (i = 0; i < argc; i++) +#else for (i = 1; i < argc; i++) +#endif { // run given test run_test(argv[i]); @@ -1113,8 +1191,7 @@ int main(int argc, char **argv) else { // run all tests - DIR *dir = opendir(test_dir); - DIR *entry; + MY_DIR *dir = my_dir(test_dir, MYF(MY_WME | MY_WANT_STAT)); char test[NAME_MAX]; char *p; @@ -1126,14 +1203,16 @@ int main(int argc, char **argv) die("Unable to open tests directory."); } - while((entry = readdir(dir)) != NULL) + for (ui = 0; ui < dir->number_off_files; ui++) { - if (!S_ISDIR(entry->d_type)) + if (!MY_S_ISDIR(dir->dir_entry[ui].mystat.st_mode)) { - strcpy(test, strlwr(entry->d_name)); - + strcpy(test, dir->dir_entry[ui].name); +#ifndef __WIN__ + casedn_str(test); +#endif // find the test suffix - if ((p = strindex(test, TEST_SUFFIX)) != NULL) + if ((p = strstr(test, TEST_SUFFIX))) { // null terminate at the suffix *p = '\0'; @@ -1143,14 +1222,14 @@ int main(int argc, char **argv) } } } - - closedir(dir); + + my_dirend(dir); } - log(DASH); - log("\n"); + mtr_log(DASH); + mtr_log("\n"); - log("Ending Tests...\n"); + mtr_log("Ending Tests...\n"); // stop server mysql_stop(); @@ -1161,8 +1240,10 @@ int main(int argc, char **argv) // close log if (log_fd) fclose(log_fd); +#ifdef __NETWARE__ // keep results up pressanykey(); +#endif return 0; } -- cgit v1.2.1 From 55e776d14565ea6ee9841612069c24f6b8a3023c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 26 Aug 2003 17:41:40 +0200 Subject: Post-merge fixes. --- mysql-test/r/query_cache.result | 8 +++---- mysql-test/r/sel000100.result | 4 ++-- mysql-test/r/sp-error.result | 2 +- mysql-test/r/symlink.result | 2 -- mysql-test/r/variables.result | 2 +- mysql-test/t/sel000100.test | 4 ++-- mysql-test/t/sp-error.test | 42 ++++++++++++++++++------------------ sql/item.cc | 2 +- sql/item_subselect.cc | 12 +++++------ sql/mysqld.cc | 1 - sql/slave.cc | 2 +- sql/sp_head.cc | 4 ++-- sql/sql_parse.cc | 2 +- sql/sql_table.cc | 2 +- sql/sql_union.cc | 2 +- sql/sql_update.cc | 2 +- sql/sql_yacc.yy | 48 +++++++++++++++++++++++++++++++++-------- 17 files changed, 84 insertions(+), 57 deletions(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index b8b4f243ac4..664943157c1 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -1248,10 +1248,10 @@ Variable_name Value Qcache_queries_in_cache 0 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 41 +Qcache_inserts 1 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 13 +Qcache_hits 1 /**/ select * from t1; a /**/ select * from t1; @@ -1261,8 +1261,8 @@ Variable_name Value Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 42 +Qcache_inserts 2 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 14 +Qcache_hits 2 drop table t1; diff --git a/mysql-test/r/sel000100.result b/mysql-test/r/sel000100.result index 3ffa4004b84..39600b755c1 100644 --- a/mysql-test/r/sel000100.result +++ b/mysql-test/r/sel000100.result @@ -29,10 +29,10 @@ drop table t1,t2; CREATE TABLE t1 ( html varchar(5) default NULL, rin int(11) default '0', -out int(11) default '0' +rout int(11) default '0' ) TYPE=MyISAM; INSERT INTO t1 VALUES ('1',1,0); -SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; +SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; html prod 1 0.00 drop table t1; diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 11935e4b137..95fe8edf321 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -35,7 +35,7 @@ call foo(); ERROR HY000: PROCEDURE foo does not exist drop procedure if exists foo; Warnings: -Warning 1272 PROCEDURE foo does not exist +Warning 1275 PROCEDURE foo does not exist create procedure foo() foo: loop leave bar; diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 216fb4d6124..4469ca36941 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -46,8 +46,6 @@ alter table t8 rename t7; rename table t7 to t9; drop table t1; Got one of the listed errors -Warnings: -Note 1008 Can't drop database 'test_mysqltest'; database doesn't exist Got one of the listed errors Got one of the listed errors Got one of the listed errors diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 1e1aeb365c1..8bbe773ed01 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -311,7 +311,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1282 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1285 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/sel000100.test b/mysql-test/t/sel000100.test index c9923d178c6..8c673566847 100644 --- a/mysql-test/t/sel000100.test +++ b/mysql-test/t/sel000100.test @@ -38,11 +38,11 @@ drop table t1,t2; CREATE TABLE t1 ( html varchar(5) default NULL, rin int(11) default '0', - out int(11) default '0' + rout int(11) default '0' ) TYPE=MyISAM; INSERT INTO t1 VALUES ('1',1,0); -SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; +SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; drop table t1; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 448a571fa11..01e05246d3e 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -32,18 +32,18 @@ create function func1() returns int return 42| # Can't create recursively ---error 1270 +--error 1273 create procedure foo() create procedure bar() set @x=3| ---error 1270 +--error 1273 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1271 +--error 1274 create procedure proc1() set @x = 42| ---error 1271 +--error 1274 create function func1() returns int return 42| @@ -51,32 +51,32 @@ drop procedure proc1| drop function func1| # Does not exist ---error 1272 +--error 1275 alter procedure foo| ---error 1272 +--error 1275 alter function foo| ---error 1272 +--error 1275 drop procedure foo| ---error 1272 +--error 1275 drop function foo| ---error 1272 +--error 1275 call foo()| drop procedure if exists foo| # LEAVE/ITERATE with no match ---error 1275 +--error 1278 create procedure foo() foo: loop leave bar; end loop| ---error 1275 +--error 1278 create procedure foo() foo: loop iterate bar; end loop| # Redefining label ---error 1276 +--error 1279 create procedure foo() foo: loop foo: loop @@ -85,14 +85,14 @@ foo: loop end loop foo| # End label mismatch ---error 1277 +--error 1280 create procedure foo() foo: loop set @x=2; end loop bar| # Referring to undef variable ---error 1278 +--error 1281 create procedure foo(out x int) begin declare y int; @@ -106,17 +106,17 @@ begin select name from mysql.proc; select type from mysql.proc; end| ---error 1279 +--error 1282 call foo()| drop procedure foo| # RETURN in FUNCTION only ---error 1280 +--error 1283 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1281 +--error 1284 create function foo() returns int begin declare x int; @@ -130,13 +130,13 @@ create procedure p(x int) create function f(x int) returns int return x+42| ---error 1285 +--error 1288 call p()| ---error 1285 +--error 1288 call p(1, 2)| ---error 1285 +--error 1288 select f()| ---error 1285 +--error 1288 select f(1, 2)| drop procedure p| diff --git a/sql/item.cc b/sql/item.cc index 2fb80416848..0111e4bb0bc 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -54,7 +54,7 @@ Item::Item(): command => we should check thd->lex.current_select on zero (thd->lex can be uninitialised) */ - if (thd->lex.current_select) + if (thd->lex->current_select) { SELECT_LEX_NODE::enum_parsing_place place= thd->lex->current_select->parsing_place; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 9545ff27f45..ab887ab5c26 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -501,7 +501,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, SELECT_LEX_UNIT *unit= select_lex->master_unit(); substitution= optimizer= new Item_in_optimizer(left_expr, this); - SELECT_LEX *current= thd->lex.current_select, *up; + SELECT_LEX *current= thd->lex->current_select, *up; thd->lex->current_select= up= current->return_after_parsing(); //optimizer never use Item **ref => we can pass 0 as parameter @@ -603,7 +603,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, // fix_field of item will be done in time of substituting 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), select_lex->select_number); @@ -634,15 +634,15 @@ Item_in_subselect::row_value_transformer(JOIN *join, SELECT_LEX_UNIT *unit= select_lex->master_unit(); substitution= optimizer= new Item_in_optimizer(left_expr, this); - SELECT_LEX *current= thd->lex.current_select, *up; - thd->lex.current_select= up= current->return_after_parsing(); + SELECT_LEX *current= thd->lex->current_select, *up; + thd->lex->current_select= up= current->return_after_parsing(); //optimizer never use Item **ref => we can pass 0 as parameter if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0)) { - thd->lex.current_select= current; + thd->lex->current_select= current; DBUG_RETURN(ERROR); } - thd->lex.current_select= current; + thd->lex->current_select= current; unit->dependent= 1; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e8b475db6fc..a9929cfe1c0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2009,7 +2009,6 @@ static int init_common_variables(const char *conf_file_name, int argc, before MY_INIT(). So we do it here. */ mysql_log.init_pthread_objects(); - mysql_update_log.init_pthread_objects(); mysql_slow_log.init_pthread_objects(); mysql_bin_log.init_pthread_objects(); diff --git a/sql/slave.cc b/sql/slave.cc index cdf34817949..5592566fba5 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2385,7 +2385,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) thd->server_id = ev->server_id; // use the original server id for logging thd->set_time(); // time the query - thd->lex.current_select= 0; + thd->lex->current_select= 0; if (!ev->when) ev->when = time(NULL); ev->thd = thd; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 1c2baa1c0dd..63d78039803 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -77,12 +77,12 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) default: { char buffer[MAX_FIELD_WIDTH]; - String tmp(buffer, sizeof(buffer), it->charset()); + String tmp(buffer, sizeof(buffer), it->collation.collation); String *s= it->val_str(&tmp); DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick())); it= new Item_string(thd->strmake(s->c_ptr_quick(), s->length()), - s->length(), it->charset()); + s->length(), it->collation.collation); break; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7882135e401..7cb0a593e80 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3867,7 +3867,7 @@ void create_select_for_variable(const char *var_name) DBUG_ENTER("create_select_for_variable"); thd= current_thd; - lex= &thd->lex; + lex= thd->lex; mysql_init_select(lex); lex->sql_command= SQLCOM_SELECT; tmp.str= (char*) var_name; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8c577375ddb..d11bbb43609 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2494,7 +2494,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, tables.db = from->table_cache_key; error=1; - if (thd->lex.select_lex->setup_ref_array(thd, order_num) || + if (thd->lex->select_lex.setup_ref_array(thd, order_num) || setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 3448128e03d..3ac12975c60 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -257,7 +257,7 @@ int st_select_lex_unit::exec() for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { ha_rows rows= 0; - thd->lex.current_select= sl; + thd->lex->current_select= sl; if (optimized) res= sl->join->reinit(); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index fb19c53ec2b..6a047fe4544 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -95,7 +95,7 @@ int mysql_update(THD *thd, if (setup_tables(update_table_list) || setup_conds(thd,update_table_list,&conds) || - thd->lex.select_lex->setup_ref_array(thd, order_num) || + thd->lex->select_lex.setup_ref_array(thd, order_num) || setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, all_fields, all_fields, order) || setup_ftfuncs(&thd->lex->select_lex)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 75ff156cc63..a8ee9f28fda 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5251,10 +5251,27 @@ 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))); + 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 + { + LEX *lex=Lex; + + if ($1.var) + { /* System variable */ + lex->var_list.push_back(new set_var(lex->option_type, $1.var, + &$1.base_name, $3)); + } + else + { /* An SP local variable */ + sp_pvar_t *spv= lex->spcont->find_pvar(&$1.base_name); + sp_instr_set *i= new sp_instr_set(lex->sphead->instructions(), + spv->offset, $3, spv->type); + + lex->sphead->add_instr(i); + spv->isset= TRUE; + } } - | internal_or_splocal - {} | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default { LEX *lex=Lex; @@ -5311,12 +5328,25 @@ option_value: internal_variable_name: ident { - sys_var *tmp=find_sys_var($1.str, $1.length); - if (!tmp) - YYABORT; - $$.var= tmp; - $$.base_name.str=0; - $$.base_name.length=0; + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + /* We have to lookup here since local vars can shadow sysvars */ + 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; + $$.var= tmp; + $$.base_name.str=0; + $$.base_name.length=0; + } + else + { /* An SP local variable */ + $$.var= NULL; + $$.base_name= $1; + } } | ident '.' ident { -- cgit v1.2.1 From e68197450d5f42f1b07138248fff46455190ebce Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Aug 2003 17:04:33 +0200 Subject: Adopt to the introduction of a separate CLIENT_MULTI_RESULTS flag. --- sql/sp_head.cc | 2 +- sql/sp_head.h | 2 +- sql/sql_parse.cc | 6 +++--- sql/sql_yacc.yy | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 63d78039803..c6e89222175 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -120,7 +120,7 @@ sp_head::operator delete(void *ptr, size_t size) } sp_head::sp_head() - : Sql_alloc(), m_simple_case(FALSE), m_multi_query(FALSE), m_free_list(NULL) + : Sql_alloc(), m_simple_case(FALSE), m_multi_results(FALSE), m_free_list(NULL) { DBUG_ENTER("sp_head::sp_head"); diff --git a/sql/sp_head.h b/sql/sp_head.h index bdb9e2e4eb1..f0435de99d7 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -46,7 +46,7 @@ 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) + my_bool m_multi_results; // TRUE if a procedure with SELECT(s) uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value #if NOT_USED_NOW // QQ We're not using this at the moment. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7cb0a593e80..da0bf3738df 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3309,9 +3309,9 @@ mysql_execute_command(THD *thd) my_bool nsok= thd->net.no_send_ok; thd->net.no_send_ok= TRUE; #endif - if (sp->m_multi_query) + if (sp->m_multi_results) { - if (! (thd->client_capabilities & CLIENT_MULTI_QUERIES)) + if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS)) { send_error(thd, ER_SP_BADSELECT); #ifndef EMBEDDED_LIBRARY @@ -3328,7 +3328,7 @@ mysql_execute_command(THD *thd) #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif - if (sp->m_multi_query) + if (sp->m_multi_results) { if (! smrx) thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a8ee9f28fda..d1c6975bfa4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1203,7 +1203,7 @@ sp_proc_stmt: if (lex->sql_command == SQLCOM_SELECT && !lex->result) { /* We maybe have one or more SELECT without INTO */ - lex->sphead->m_multi_query= TRUE; + lex->sphead->m_multi_results= TRUE; } /* Don't add an instruction for empty SET statements. ** (This happens if the SET only contained local variables, -- cgit v1.2.1 From 07e372cd6b3a89d301fc44b5359fac01e285aa76 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 13 Sep 2003 17:47:59 +0300 Subject: new UDF arguments interface (WL#1017) (SCRUM) include/mysql_com.h: new UDF arguments interface sql/item.cc: added lenghth name foe item (to avoid strlen() call) sql/item.h: added lenghth name foe item (to avoid strlen() call) sql/item_func.cc: new UDF arguments sql/sql_parse.cc: fixed problem with UDF in 5.0 sql/sql_yacc.yy: new syntax of UDF arguments sql/udf_example.cc: new UDF example (stupid function to test parameters) tests/udf_test.res: new UDF example (stupid function to test parameters) tests/udf_test: new UDF example (stupid function to test parameters) --- include/mysql_com.h | 2 ++ sql/item.cc | 7 ++++--- sql/item.h | 1 + sql/item_func.cc | 17 ++++++++++++----- sql/sql_parse.cc | 2 ++ sql/sql_yacc.yy | 44 +++++++++++++++++++++++++++++++++++++++----- sql/udf_example.cc | 48 +++++++++++++++++++++++++++++++++++++++++++++++- tests/udf_test | 3 +++ tests/udf_test.res | 24 ++++++++++++++++++++++++ 9 files changed, 134 insertions(+), 14 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index cd850aa5e0a..7ad7197f695 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -278,6 +278,8 @@ typedef struct st_udf_args char **args; /* Pointer to argument */ unsigned long *lengths; /* Length of string arguments */ char *maybe_null; /* Set to 1 for all maybe_null args */ + char **attributes; /* Pointer to attribute name */ + unsigned long *attribute_lengths; /* Length of attribute arguments */ } UDF_ARGS; /* This holds information about the result */ diff --git a/sql/item.cc b/sql/item.cc index 0111e4bb0bc..5782904f243 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -39,7 +39,7 @@ void item_init(void) } Item::Item(): - fixed(0) + name_length(0), fixed(0) { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; @@ -121,6 +121,7 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) { /* Empty string, used by AS or internal function like last_insert_id() */ name= (char*) str; + name_length= 0; return; } while (length && !my_isgraph(cs,*str)) @@ -131,12 +132,12 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) if (!my_charset_same(cs, system_charset_info)) { uint32 res_length; - name= sql_strmake_with_convert(str, length, cs, + name= sql_strmake_with_convert(str, name_length= length, cs, MAX_ALIAS_NAME, system_charset_info, &res_length); } else - name=sql_strmake(str, min(length,MAX_ALIAS_NAME)); + name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME))); } diff --git a/sql/item.h b/sql/item.h index 35ad8818a25..a8e6a08c8e5 100644 --- a/sql/item.h +++ b/sql/item.h @@ -106,6 +106,7 @@ public: my_string name; /* Name from select */ Item *next; uint32 max_length; + uint name_length; /* Length of name */ uint8 marker,decimals; my_bool maybe_null; /* If item may be null */ my_bool null_value; /* if item is null */ diff --git a/sql/item_func.cc b/sql/item_func.cc index 8bac8fb6e07..c8307f30a0b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1498,11 +1498,16 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, const_item_cache&=item->const_item(); f_args.arg_type[i]=item->result_type(); } + //TODO: why all folowing memory is not allocated with 1 call of sql_alloc? if (!(buffers=new String[arg_count]) || !(f_args.args= (char**) sql_alloc(arg_count * sizeof(char *))) || - !(f_args.lengths=(ulong*) sql_alloc(arg_count * sizeof(long))) || - !(f_args.maybe_null=(char*) sql_alloc(arg_count * sizeof(char))) || - !(num_buffer= (char*) sql_alloc(ALIGN_SIZE(sizeof(double))*arg_count))) + !(f_args.lengths= (ulong*) sql_alloc(arg_count * sizeof(long))) || + !(f_args.maybe_null= (char*) sql_alloc(arg_count * sizeof(char))) || + !(num_buffer= (char*) sql_alloc(arg_count * + ALIGN_SIZE(sizeof(double)))) || + !(f_args.attributes= (char**) sql_alloc(arg_count * sizeof(char *))) || + !(f_args.attribute_lengths= (ulong*) sql_alloc(arg_count * + sizeof(long)))) { free_udf(u_d); DBUG_RETURN(1); @@ -1521,8 +1526,10 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, for (uint i=0; i < arg_count; i++) { f_args.args[i]=0; - f_args.lengths[i]=arguments[i]->max_length; - f_args.maybe_null[i]=(char) arguments[i]->maybe_null; + f_args.lengths[i]= arguments[i]->max_length; + f_args.maybe_null[i]= (char) arguments[i]->maybe_null; + f_args.attributes[i]= arguments[i]->name; + f_args.attribute_lengths[i]= arguments[i]->name_length; switch(arguments[i]->type()) { case Item::STRING_ITEM: // Constant string ! diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7cb0a593e80..7c2a4b9780a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2986,6 +2986,8 @@ mysql_execute_command(THD *thd) break; #ifdef HAVE_DLOPEN sp_head *sph= sp_find_function(thd, &lex->udf.name); + // close & unlock table opened by sp_find_function + close_thread_tables(thd); if (sph) { net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a8ee9f28fda..0a7511fa872 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -630,13 +630,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type literal text_literal insert_ident order_ident simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr - table_wild no_in_expr expr_expr simple_expr no_and_expr + table_wild no_in_expr expr_expr simple_expr no_and_expr udf_expr using_list expr_or_default set_expr_or_default interval_expr param_marker singlerow_subselect singlerow_subselect_init exists_subselect exists_subselect_init sp_opt_default %type - expr_list udf_expr_list when_list ident_list ident_list_arg + expr_list sp_expr_list udf_expr_list udf_expr_list2 when_list + ident_list ident_list_arg %type key_type opt_unique_or_fulltext @@ -702,7 +703,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); select_item_list select_item values_list no_braces opt_limit_clause delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item - when_list2 expr_list2 handler + when_list2 expr_list2 udf_expr_list3 handler opt_precision opt_ignore opt_column opt_restrict grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock @@ -3246,7 +3247,7 @@ simple_expr: { $$= new Item_func_round($3,$5,1); } | TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); } - | SP_FUNC '(' udf_expr_list ')' + | SP_FUNC '(' sp_expr_list ')' { sp_add_fun_to_lex(Lex, $1); if ($3) @@ -3336,10 +3337,43 @@ simple_expr: | EXTRACT_SYM '(' interval FROM expr ')' { $$=new Item_extract( $3, $5); }; -udf_expr_list: +sp_expr_list: /* empty */ { $$= NULL; } | expr_list { $$= $1;}; +udf_expr_list: + /* empty */ { $$= NULL; } + | udf_expr_list2 { $$= $1;} + ; + +udf_expr_list2: + { Select->expr_list.push_front(new List); } + udf_expr_list3 + { $$= Select->expr_list.pop(); } + ; + +udf_expr_list3: + udf_expr + { + Select->expr_list.head()->push_back($1); + } + | udf_expr_list3 ',' udf_expr + { + Select->expr_list.head()->push_back($3); + } + ; + +udf_expr: + remember_name expr remember_end select_alias + { + if ($4.str) + $2->set_name($4.str,$4.length,system_charset_info); + else + $2->set_name($1,(uint) ($3 - $1), YYTHD->charset()); + $$= $2; + } + ; + sum_expr: AVG_SYM '(' in_sum_expr ')' { $$=new Item_sum_avg($3); } diff --git a/sql/udf_example.cc b/sql/udf_example.cc index 7f4417bf8fe..54901003c7a 100644 --- a/sql/udf_example.cc +++ b/sql/udf_example.cc @@ -56,7 +56,9 @@ ** ** Function 'myfunc_int' returns summary length of all its arguments. ** -** Function 'sequence' returns an sequence starting from a certain number +** Function 'sequence' returns an sequence starting from a certain number. +** +** Function 'myfunc_argument_name' returns name of argument. ** ** On the end is a couple of functions that converts hostnames to ip and ** vice versa. @@ -82,6 +84,7 @@ ** CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; ** CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; ** CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so"; +** CREATE FUNCTION myfunc_argument_name RETURNS STRING SONAME "udf_example.so"; ** ** After this the functions will work exactly like native MySQL functions. ** Functions should be created only once. @@ -94,6 +97,7 @@ ** DROP FUNCTION lookup; ** DROP FUNCTION reverse_lookup; ** DROP FUNCTION avgcost; +** DROP FUNCTION myfunc_argument_name; ** ** The CREATE FUNCTION and DROP FUNCTION update the func@mysql table. All ** Active function will be reloaded on every restart of server @@ -975,4 +979,46 @@ avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error ) return data->totalprice/double(data->totalquantity); } +extern "C" { +my_bool myfunc_argument_name_init(UDF_INIT *initid, UDF_ARGS *args, + char *message); +void myfunc_argument_name_deinit(UDF_INIT *initid); +char *myfunc_argument_name(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *length, char *null_value, + char *error); +} + +my_bool myfunc_argument_name_init(UDF_INIT *initid, UDF_ARGS *args, + char *message) +{ + if (args->arg_count != 1) + { + strmov(message,"myfunc_argument_name_init accepts only one argument"); + return 1; + } + initid->max_length= args->attribute_lengths[0]; + initid->maybe_null= 1; + initid->const_item= 1; + return 0; +} + +void myfunc_argument_name_deinit(UDF_INIT *initid) {} + +char *myfunc_argument_name(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *length, char *null_value, + char *error) +{ + if (!args->attributes[0]) + { + null_value= 0; + return 0; + } + (*length)--; // space for ending \0 (for debugging purposes) + if (*length > args->attribute_lengths[0]) + *length= args->attribute_lengths[0]; + memcpy(result, args->attributes[0], *length); + result[*length]= 0; + return result; +} + #endif /* HAVE_DLOPEN */ diff --git a/tests/udf_test b/tests/udf_test index 4621a7b34a5..2bdacc34d13 100644 --- a/tests/udf_test +++ b/tests/udf_test @@ -9,6 +9,7 @@ CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so"; +CREATE FUNCTION myfunc_argument_name RETURNS STRING SONAME "udf_example.so"; select metaphon("hello"); select myfunc_double("hello","world"); @@ -20,6 +21,7 @@ create temporary table t1 (a int,b double); insert into t1 values (1,5),(1,4),(2,8),(3,9),(4,11); select avgcost(a,b) from t1; select avgcost(a,b) from t1 group by a; +select a, myfunc_argument_name(a) from t1; drop table t1; DROP FUNCTION metaphon; @@ -28,3 +30,4 @@ DROP FUNCTION myfunc_int; DROP FUNCTION lookup; DROP FUNCTION reverse_lookup; DROP FUNCTION avgcost; +DROP FUNCTION myfunc_argument_name; diff --git a/tests/udf_test.res b/tests/udf_test.res index 66634e13616..cd65d3794d8 100644 --- a/tests/udf_test.res +++ b/tests/udf_test.res @@ -34,6 +34,12 @@ CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so" Query OK, 0 rows affected +-------------- +CREATE FUNCTION myfunc_argument_name RETURNS STRING SONAME "udf_example.so" +-------------- + +Query OK, 0 rows affected + -------------- select metaphon("hello") -------------- @@ -106,6 +112,18 @@ avgcost(a,b) 11.0000 4 rows in set +-------------- +select a, myfunc_argument_name(a) from t1; +-------------- + +a myfunc_argument_name(a) +1 a +1 a +2 a +3 a +4 a +5 rows in set + -------------- drop table t1 -------------- @@ -148,4 +166,10 @@ DROP FUNCTION avgcost Query OK, 0 rows affected +-------------- +DROP FUNCTION myfunc_argument_name; +-------------- + +Query OK, 0 rows affected + Bye -- cgit v1.2.1 From 4deedf6263df02229a30a0aa2f6621074f140b19 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 Sep 2003 14:26:08 +0200 Subject: Implemented SP CONDITIONs and HANDLERs, with the extension of handling MySQL error codes as well. (No UNDO HANDLERs yet, and no SIGNAL or RESIGNAL.) WL#850 Docs/sp-imp-spec.txt: Spec of CONDITIONs and HANDLERs (and updated some old stuff too). Docs/sp-implemented.txt: Updated info about caching, CONDITIONs and HANDLERs. include/mysqld_error.h: New error for undeclared CONDITION. libmysqld/Makefile.am: New file: sp_rcontext.cc. mysql-test/r/sp-error.result: New tests for CONDITIONs and HANDLERs. mysql-test/r/sp.result: New tests for CONDITIONs and HANDLERs. mysql-test/t/sp-error.test: New tests for CONDITIONs and HANDLERs. mysql-test/t/sp.test: New tests for CONDITIONs and HANDLERs. sql/Makefile.am: New file: sp_rcontext.cc. sql/lex.h: New symbols for CONDITIONs, HANDLERs and CURSORs. sql/mysqld.cc: Catch error if we have a handler for it. sql/protocol.cc: Catch error if we have a handler for it. sql/share/czech/errmsg.txt: New error for undeclared CONDITION. sql/share/danish/errmsg.txt: New error for undeclared CONDITION. sql/share/dutch/errmsg.txt: New error for undeclared CONDITION. sql/share/english/errmsg.txt: New error for undeclared CONDITION. sql/share/estonian/errmsg.txt: New error for undeclared CONDITION. sql/share/french/errmsg.txt: New error for undeclared CONDITION. sql/share/german/errmsg.txt: New error for undeclared CONDITION. sql/share/greek/errmsg.txt: New error for undeclared CONDITION. sql/share/hungarian/errmsg.txt: New error for undeclared CONDITION. sql/share/italian/errmsg.txt: New error for undeclared CONDITION. sql/share/japanese/errmsg.txt: New error for undeclared CONDITION. sql/share/korean/errmsg.txt: New error for undeclared CONDITION. sql/share/norwegian-ny/errmsg.txt: New error for undeclared CONDITION. sql/share/norwegian/errmsg.txt: New error for undeclared CONDITION. sql/share/polish/errmsg.txt: New error for undeclared CONDITION. sql/share/portuguese/errmsg.txt: New error for undeclared CONDITION. sql/share/romanian/errmsg.txt: New error for undeclared CONDITION. sql/share/russian/errmsg.txt: New error for undeclared CONDITION. sql/share/serbian/errmsg.txt: New error for undeclared CONDITION. sql/share/slovak/errmsg.txt: New error for undeclared CONDITION. sql/share/spanish/errmsg.txt: New error for undeclared CONDITION. sql/share/swedish/errmsg.txt: New error for undeclared CONDITION. sql/share/ukrainian/errmsg.txt: New error for undeclared CONDITION. sql/sp_head.cc: New HANDLER code. sql/sp_head.h: New HANDLER code. sql/sp_pcontext.cc: New CONDITION and HANDLER code. sql/sp_pcontext.h: New CONDITION and HANDLER code. sql/sp_rcontext.h: New CONDITION and HANDLER code. sql/sql_yacc.yy: New CONDITION and HANDLER code. --- Docs/sp-imp-spec.txt | 431 ++++++++++++++++++++++++++++++-------- Docs/sp-implemented.txt | 20 +- include/mysqld_error.h | 3 +- libmysqld/Makefile.am | 2 +- mysql-test/r/sp-error.result | 25 +++ mysql-test/r/sp.result | 57 +++++ mysql-test/t/sp-error.test | 29 +++ mysql-test/t/sp.test | 70 +++++++ sql/Makefile.am | 3 +- sql/lex.h | 12 +- sql/mysqld.cc | 5 + sql/protocol.cc | 13 ++ 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 | 81 ++++++- sql/sp_head.h | 106 +++++++++- sql/sp_pcontext.cc | 50 ++++- sql/sp_pcontext.h | 62 +++++- sql/sp_rcontext.cc | 95 +++++++++ sql/sp_rcontext.h | 97 ++++++++- sql/sql_yacc.yy | 194 +++++++++++++++-- 42 files changed, 1231 insertions(+), 147 deletions(-) create mode 100644 sql/sp_rcontext.cc diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index 385625464f1..1b72026c427 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -1,6 +1,6 @@ - Implementation specification for Stored Procedures - ================================================== + Implementation specification for Stored Procedures + ================================================== - How parsing and execution of queries work @@ -45,7 +45,8 @@ - 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: + by the parser. It turns out that we only need a minimum of 5 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 @@ -58,6 +59,10 @@ 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. + - sp_instr_freturn + Return a value from a FUNCTION and exit. + For condition HANDLERs some special instructions are also needed, see + that section below. - class sp_rcontext (sp_rcontext.h) This is the runtime context in the THD structure. @@ -120,7 +125,7 @@ with an anonymous variable bound to the value to be tested. - - An example + - A simple example Parsing the procedure: @@ -258,8 +263,8 @@ 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). + everywhere (which doesn't help if you want to call other, "general", + procedures anyway). - Evaluating Items @@ -315,7 +320,7 @@ 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. + 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 @@ -341,9 +346,9 @@ 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); + 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. @@ -361,82 +366,231 @@ analogous to other DROP statements in MySQL. + - Condition and Handlers + + Condition names are lexical entities and are kept in the parser context + just like variables. But, condition are just "aliases" for SQLSTATE + strings, or mysqld error codes (which is a non-standard extension in + MySQL), and are only used during parsing. + + Handlers comes in three types, CONTINUE, EXIT and UNDO. The latter is + like an EXIT handler with an implicit rollback, and is currently not + implemented. + The EXIT handler jumps to the end of its BEGIN-END block when finished. + The CONTINUE handler returns to the statement following that which + invoked the handler. + + The handlers in effect at any point is part of each thread's runtime + state, so we need to push and pop handlers in the sp_rcontext during + execution. We use special instructions for this: + - sp_instr_hpush_jump + Push a handler. The instruction contains the necessary information, + like which conditions we handle and the location of the handler. + The jump takes us to the location after the handler code. + - sp_instr_hpop + Pop the handlers of the current frame (which we are just leaving). + + It might seems strange to jump past the handlers like that, but there's + no extra cost in doing this, and for technical reasons it's easiest for + the parser to generate the handler instructions when they occur in the + source. + + When an error occurs, one of the error routines is called and an error + message is normally sent back to the client immediately. + Catching a condition must be done in these error routines (there are + quite a few) to prevent them from doing this. We do this by calling + a method in the THD's sp_rcontext (if there is one). If a handler is + found, this is recorded in the context and the routine returns without + sending the error message. + The exectution loop (sp_head::execute()) checks for this after each + statement and invokes the handler that has been found. If several + errors or warnings occurs during one statement, only the first is + caught, the rest are ignored. + + Invoking and returning from a handler is trivial in the EXIT case. + We simply jump to it, and it will have an sp_instr_jump as its last + instruction. + + Calling and returning from a CONTINUE handler poses some special + problems. Since we need to return to the point after its invokation, + we push the return location on a stack in the sp_rcontext (this is + done by the exectution loop). The handler then ends with a special + instruction, sp_instr_hreturn, which returns to this location. + + CONTINUE handlers have one additional problem: They are parsed at + the lexical level where they occur, so variable offsets will assume + that it's actually called at that level. However, a handler might be + invoked from a sub-block where additional local variables have been + declared, which will then share the location of any local variables + in the handler itself. So, when calling a CONTINUE handler, we need + to save any local variables above the handler's frame offset, and + restore them upon return. (This is not a problem for EXIT handlers, + since they will leave the block anyway.) + This is taken care of by the execution loop and the sp_instr_hreturn + instruction. + + - Examples: + + - EXIT handler + begin + declare x int default 0; + + begin + declare exit handler for 'XXXXX' set x = 1; + + (statement1); + (statement2); + end; + (statement3); + end + + Pos. Instruction + 0 sp_instr_set(0, '0') + 1 sp_instr_hpush_jump(4, 1) # location and frame size + 2 sp_instr_set(0, '1') + 3 sp_instr_jump(6) + 4 sp_instr_stmt('statement1') + 5 sp_instr_stmt('statement2') + 6 sp_instr_hpop(1) + 7 sp_instr_stmt('statement3') + + - CONTINUE handler + create procedure hndlr1(val int) + begin + declare x int default 0; + declare foo condition for 1146; + declare continue handler for foo set x = 1; + + insert into t3 values ("hndlr1", val); # Non-existing table? + if x>0 then + insert into t1 values ("hndlr1", val); # This instead then + end if; + end| + + Pos. Instruction + 0 sp_instr_set(1, '0') + 1 sp_instr_hpush_jump(4, 2) + 2 sp_instr_set(1, '1') + 3 sp_instr_hreturn(2) # frame size + 4 sp_instr_stmt('insert ... t3 ...') + 5 sp_instr_jump_if_not(7, 'x>0') + 6 sp_instr_stmt('insert ... t1 ...') + 7 sp_instr_hpop(2) + + - Class and function APIs + This is an outline of the key types. Some types and other details + in the actual files have been omitted for readability. - The parser context: sp_pcontext.h typedef enum { sp_param_in, - sp_param_out, - sp_param_inout + 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; + LEX_STRING name; + enum enum_field_types type; + sp_param_mode_t mode; + uint offset; // Offset in current frame + my_bool isset; } sp_pvar_t; + typedef struct sp_cond_type + { + enum { number, state, warning, notfound, exception } type; + char sqlstate[6]; + uint mysqlerr; + } sp_cond_type_t; + class sp_pcontext { sp_pcontext(); - // Return the maximum frame size - uint max_framesize(); + // Return the maximum frame size + uint max_framesize(); - // Return the current frame size - uint current_framesize(); + // Return the current frame size + uint current_framesize(); - // Return the number of parameters - uint params(); + // Return the number of parameters + uint params(); - // Set the number of parameters to the current frame size - void set_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); + // 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); + // 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); + // Push the variable 'name' to the frame. + void push_var(LEX_STRING *name, + enum enum_field_types type, sp_param_mode_t mode); // Pop 'num' variables from the frame. - void pop(uint num = 1); + void pop_var(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 variable by name - sp_pvar_t *find_pvar(LEX_STRING *name); + // Find label 'name' in the context + sp_label_t *find_label(char *name); - // Find variable by index - sp_pvar_t *find_pvar(uint i); + // Return the last pushed label + sp_label_t *last_label(); - // Push label 'name' of instruction index 'ip' to the label context - sp_label_t *push_label(char *name, uint ip); + // Return and remove the last pushed label. + sp_label_t *pop_label(); - // Find label 'name' in the context - sp_label_t *find_label(char *name); + // Push a condition to the context + void push_cond(LEX_STRING *name, sp_cond_type_t *val); - // Return the last pushed label - sp_label_t *last_label(); + // Pop a 'num' condition from the context + void pop_cond(uint num); - // Return and remove the last pushed label. - sp_label_t *pop_label(); + // Find a condition in the context + sp_cond_type_t *find_cond(LEX_STRING *name); + + // Increase the handler count + void add_handler(); + + // Returns the handler count + uint handlers(); } - The run-time context (call frame): sp_rcontext.h + #define SP_HANDLER_NONE 0 + #define SP_HANDLER_EXIT 1 + #define SP_HANDLER_CONTINUE 2 + #define SP_HANDLER_UNDO 3 + + typedef struct + { + struct sp_cond_type *cond; + uint handler; // Location of handler + int type; + uint foffset; // Frame offset for the handlers declare level + } sp_handler_t; + class sp_rcontext { - // 'size' is the max size of the context - sp_rcontext(uint size); + // 'fsize' is the max size of the context, 'hmax' the number of handlers + sp_rcontext(uint fsize, uint hmax); // Push value (parameter) 'i' to the frame void push_item(Item *i); @@ -459,6 +613,38 @@ // Get the FUNCTION result Item *get_result(); + + // Push handler at location 'h' for condition 'cond'. 'f' is the + // current variable frame size. + void push_handler(sp_cond_type_t *cond, uint h, int type, uint f); + + // Pop 'count' handlers + void pop_handlers(uint count); + + // Find a handler for this error. This sets the state for a found + // handler in the context. If called repeatedly without clearing, + // only the first call's state is kept. + int find_handler(uint sql_errno); + + // Returns 1 if a handler has been found, with '*ip' and '*fp' set + // to the handler location and frame size respectively. + int found_handler(uint *ip, uint *fp); + + // Clear the found handler state. + void clear_handler(); + + // Push a return address for a CONTINUE handler + void push_hstack(uint ip); + + // Pop the CONTINUE handler return stack + uint pop_hstack(); + + // Save variables from frame index 'fp' and up. + void save_variables(uint fp); + + // Restore saved variables from to frame index 'fp' and up. + void restore_variables(uint fp); + } @@ -469,28 +655,33 @@ class sp_head { - int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE + int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE - sp_head(LEX_STRING *name, LEX*); + sp_head(); + + void init(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid); // Store this procedure in the database. This is a wrapper around // the function sp_create_procedure(). int create(THD *); - // Invoke a FUNCTION - int - execute_function(THD *thd, Item **args, uint argcount, Item **resp); + // Invoke a FUNCTION + int + execute_function(THD *thd, Item **args, uint argcount, Item **resp); - // CALL a PROCEDURE - int - execute_procedure(THD *thd, List *args); + // CALL a PROCEDURE + int + execute_procedure(THD *thd, List *args); // Add the instruction to this procedure. void add_instr(sp_instr *); - // Return the number of instructions. + // Returns the number of instructions. uint instructions(); + // Returns the last instruction + sp_instr *last_instruction(); + // Resets lex in 'thd' and keeps a copy of the old one. void reset_lex(THD *); @@ -505,6 +696,17 @@ // Update all instruction with this label in the backpatch list to // the current position. void backpatch(struct sp_label *); + + // Returns the SP name (with optional length in '*lenp'). + char *name(uint *lenp = 0); + + // Returns the result type for a function + Item_result result(); + + // Sets various attributes + void sp_set_info(char *creator, uint creatorlen, + longlong created, longlong modified, + bool suid, char *comment, uint commentlen); } - Instructions @@ -530,60 +732,89 @@ int execute(THD *, uint *nextp); - // Set the statement's Lex + // Set the statement's Lex void set_lex(LEX *); - // Return the statement's Lex - LEX *get_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); + { + // '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); - } + int execute(THD *, uint *nextp); + } - Unconditional jump class sp_instr_jump : public sp_instr - { - // No destination, must be set. - sp_instr_jump(uint ip); + { + // No destination, must be set. + sp_instr_jump(uint ip); - // 'dest' is the destination instruction index. - sp_instr_jump(uint ip, uint dest); + // 'dest' is the destination instruction index. + sp_instr_jump(uint ip, uint dest); - int execute(THD *, uint *nextp); + int execute(THD *, uint *nextp); - // Set the destination instruction 'dest'. - void set_destination(uint dest); + // 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 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) + // Jump to 'dest' if 'i' evaluates to false. + sp_instr_jump_if_not(uint ip, Item *i, uint dest) - int execute(THD *, uint *nextp); + 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); - } + class sp_instr_freturn : public sp_instr + { + // Return the value 'val' + sp_instr_freturn(uint ip, Item *val, enum enum_field_types type); + + int execute(THD *thd, uint *nextp); + } + + - Push a handler and jump + class sp_instr_hpush_jump : public sp_instr_jump + { + // Push handler of type 'htype', with current frame size 'fp' + sp_instr_hpush_jump(uint ip, int htype, uint fp); + + int execute(THD *thd, uint *nextp); + + // Add condition for this handler + void add_condition(struct sp_cond_type *cond); + } + - Pops handlers + class sp_instr_hpop : public sp_instr + { + // Pop 'count' handlers + sp_instr_hpop(uint ip, uint count); + + int execute(THD *thd, uint *nextp); + } + + - Return from a CONTINUE handler + class sp_instr_hreturn : public sp_instr + { + // Return from handler, and restore variables to 'fp'. + sp_instr_hreturn(uint ip, uint fp); + + int execute(THD *thd, uint *nextp); + } - Utility functions: sp.h @@ -602,7 +833,8 @@ // definition string ("create procedure ..."). int sp_create_procedure(THD *, char *name, uint namelen, - char *def, uint deflen); + char *def, uint deflen, + char *comment, uint commentlen, bool suid); // Drop the procedure 'name' from the database. int sp_drop_procedure(THD *, char *name, uint namelen); @@ -614,9 +846,28 @@ // definition string ("create function ..."). int sp_create_function(THD *, char *name, uint namelen, - char *def, uint deflen); + char *def, uint deflen, + char *comment, uint commentlen, bool suid); // Drop the function 'name' from the database. int sp_drop_function(THD *, char *name, uint namelen); + + - The cache: sp_cache.h + + class sp_cache + { + sp_cache(); + + void init(); + + void cleanup(); + + void insert(sp_head *sp); + + sp_head *lookup(char *name, uint namelen); + + void remove(sp_head *sp); + } + -- diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index 41e7c4b2923..5ce09ae3af4 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -1,4 +1,4 @@ -Stored Procedures implemented 2003-03-07: +Stored Procedures implemented 2003-09-16: Summary of Not Yet Implemented: @@ -7,13 +7,12 @@ Summary of Not Yet Implemented: - 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) + - SIGNAL and RESIGNAL, and UNDO handlers Summary of what's implemented: @@ -24,7 +23,8 @@ Summary of what's implemented: - BEGIN/END, SET, CASE, IF, LOOP, WHILE, REPEAT, ITERATE, LEAVE - SELECT INTO local variables - "Non-query" FUNCTIONs only - + - Prepared SP caching + - CONDITIONs and HANDLERs List of what's implemented: @@ -75,7 +75,17 @@ List of what's implemented: query (unlike a PROCEDURE, which is called as a statement). The table locking scheme used makes it difficult to allow "subqueries" during FUNCTION invokation. - + - SPs are cached, but with a separate cache for each thread (THD). + There are still quite a few non-reentrant constructs in the lexical + context which makes sharing prepared SPs impossible. And, even when + this is resolved, it's not necessarily the case that it will be faster + than a cache per thread. A global cache requires locks, which might + become a buttleneck. (It would save memory though.) + - CONDITIONs and HANDLERs are implemented, but not the SIGNAL and + RESIGNAL statements. (It's unclear if these can be implemented.) + The semantics of CONDITIONs is expanded to allow catching MySQL error + codes as well. UNDO handlers are not implemented (since we don't have + SQL-99 style transaction control yet). Closed questions: diff --git a/include/mysqld_error.h b/include/mysqld_error.h index aabd04bcae8..a448126084d 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -305,4 +305,5 @@ #define ER_UPDATE_LOG_DEPRECATED_TRANSLATED 1286 #define ER_QUERY_INTERRUPTED 1287 #define ER_SP_WRONG_NO_OF_ARGS 1288 -#define ER_ERROR_MESSAGES 289 +#define ER_SP_COND_MISMATCH 1289 +#define ER_ERROR_MESSAGES 290 diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 17ff22bce65..080da0c7725 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -57,7 +57,7 @@ sqlsources = 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_cache.cc + sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) libmysqld_a_SOURCES= diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 95fe8edf321..d839b8a3af8 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -96,3 +96,28 @@ select f(1, 2); ERROR HY000: Wrong number of arguments for FUNCTION f, expected 1, got 2 drop procedure p; drop function f; +create procedure p(val int, out res int) +begin +declare x int default 0; +declare continue handler for foo set x = 1; +insert into test.t1 values (val); +if (x) then +set res = 0; +else +set res = 1; +end if; +end; +ERROR HY000: Undefined CONDITION: foo +create procedure p(val int, out res int) +begin +declare x int default 0; +declare foo condition for 1146; +declare continue handler for bar set x = 1; +insert into test.t1 values (val); +if (x) then +set res = 0; +else +set res = 1; +end if; +end; +ERROR HY000: Undefined CONDITION: bar diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index c08d252cfe3..42f720c7791 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -443,6 +443,63 @@ drop function inc; drop function mul; drop function append; drop function fun; +create procedure hndlr1(val int) +begin +declare x int default 0; +declare foo condition for 1146; +declare continue handler for foo set x = 1; +insert into test.t666 values ("hndlr1", val); # Non-existing table +if (x) then +insert into test.t1 values ("hndlr1", val); # This instead then +end if; +end; +call hndlr1(42); +select * from t1; +id data +hndlr1 42 +delete from t1; +drop procedure hndlr1; +create procedure hndlr2(val int) +begin +declare x int default 0; +begin +declare exit handler for '42S02' set x = 1; +insert into test.t666 values ("hndlr2", val); # Non-existing table +end; +insert into test.t1 values ("hndlr2", x); +end; +call hndlr2(42); +select * from t1; +id data +hndlr2 1 +delete from t1; +drop procedure hndlr2; +create procedure hndlr3(val int) +begin +declare x int default 0; +declare continue handler for sqlexception # Any error +begin +declare z int; +set z = 2 * val; +set x = 1; +end; +if val < 10 then +begin +declare y int; +set y = val + 10; +insert into test.t666 values ("hndlr3", y); # Non-existing table +if x then +insert into test.t1 values ("hndlr3", y); +end if; +end; +end if; +end; +call hndlr3(3); +select * from t1; +id data +hndlr3 13 +delete from t1; +drop procedure hndlr3; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 01e05246d3e..5d46c39b601 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -142,4 +142,33 @@ select f(1, 2)| drop procedure p| drop function f| +--error 1289 +create procedure p(val int, out res int) +begin + declare x int default 0; + declare continue handler for foo set x = 1; + + insert into test.t1 values (val); + if (x) then + set res = 0; + else + set res = 1; + end if; +end| + +--error 1289 +create procedure p(val int, out res int) +begin + declare x int default 0; + declare foo condition for 1146; + declare continue handler for bar set x = 1; + + insert into test.t1 values (val); + if (x) then + set res = 0; + else + set res = 1; + end if; +end| + delimiter ;| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 61519c52929..3450b47b4e5 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -519,6 +519,76 @@ drop function append| drop function fun| +# +# CONDITIONs and HANDLERs +# + +create procedure hndlr1(val int) +begin + declare x int default 0; + declare foo condition for 1146; + declare continue handler for foo set x = 1; + + insert into test.t666 values ("hndlr1", val); # Non-existing table + if (x) then + insert into test.t1 values ("hndlr1", val); # This instead then + end if; +end| + +call hndlr1(42)| +select * from t1| +delete from t1| +drop procedure hndlr1| + +create procedure hndlr2(val int) +begin + declare x int default 0; + + begin + declare exit handler for '42S02' set x = 1; + + insert into test.t666 values ("hndlr2", val); # Non-existing table + end; + + insert into test.t1 values ("hndlr2", x); +end| + +call hndlr2(42)| +select * from t1| +delete from t1| +drop procedure hndlr2| + + +create procedure hndlr3(val int) +begin + declare x int default 0; + declare continue handler for sqlexception # Any error + begin + declare z int; + + set z = 2 * val; + set x = 1; + end; + + if val < 10 then + begin + declare y int; + + set y = val + 10; + insert into test.t666 values ("hndlr3", y); # Non-existing table + if x then + insert into test.t1 values ("hndlr3", y); + end if; + end; + end if; +end| + +call hndlr3(3)| +select * from t1| +delete from t1| +drop procedure hndlr3| + + # # Some "real" examples # diff --git a/sql/Makefile.am b/sql/Makefile.am index 088e0fa64ab..b809021b3b5 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -88,7 +88,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ client.c sql_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_cache.cc + sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \ + sp_cache.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/lex.h b/sql/lex.h index ca278a7e911..23347f6113c 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -104,8 +104,10 @@ static SYMBOL symbols[] = { { "COMMITTED", SYM(COMMITTED_SYM),0,0}, { "COMPRESSED", SYM(COMPRESSED_SYM),0,0}, { "CONCURRENT", SYM(CONCURRENT),0,0}, + { "CONDITION", SYM(CONDITION_SYM),0,0}, { "CONNECTION", SYM(CONNECTION_SYM),0,0}, { "CONSTRAINT", SYM(CONSTRAINT),0,0}, + { "CONTINUE", SYM(CONTINUE_SYM),0,0}, { "CREATE", SYM(CREATE),0,0}, { "CROSS", SYM(CROSS),0,0}, { "CUBE", SYM(CUBE_SYM),0,0}, @@ -156,10 +158,13 @@ static SYMBOL symbols[] = { { "ENUM", SYM(ENUM),0,0}, { "EVENTS", SYM(EVENTS_SYM),0,0}, { "EXECUTE", SYM(EXECUTE_SYM),0,0}, - { "EXPLAIN", SYM(DESCRIBE),0,0}, { "EXISTS", SYM(EXISTS),0,0}, + { "EXIT", SYM(EXIT_SYM),0,0}, + { "EXPLAIN", SYM(DESCRIBE),0,0}, { "EXTENDED", SYM(EXTENDED_SYM),0,0}, + { "FALSE", SYM(FALSE_SYM),0,0}, { "FAST", SYM(FAST_SYM),0,0}, + { "FETCH", SYM(FETCH_SYM),0,0}, { "FIELDS", SYM(COLUMNS),0,0}, { "FILE", SYM(FILE_SYM),0,0}, { "FIRST", SYM(FIRST_SYM),0,0}, @@ -168,9 +173,9 @@ static SYMBOL symbols[] = { { "FLOAT4", SYM(FLOAT_SYM),0,0}, { "FLOAT8", SYM(DOUBLE_SYM),0,0}, { "FLUSH", SYM(FLUSH_SYM),0,0}, - { "FALSE", SYM(FALSE_SYM),0,0}, { "FOREIGN", SYM(FOREIGN),0,0}, { "FORCE", SYM(FORCE_SYM),0,0}, + { "FOUND", SYM(FOUND_SYM),0,0}, { "RAID_TYPE", SYM(RAID_TYPE),0,0}, { "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0}, { "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0}, @@ -375,6 +380,8 @@ static SYMBOL symbols[] = { { "SONAME", SYM(UDF_SONAME_SYM),0,0}, { "SPATIAL", SYM(SPATIAL_SYM),0,0}, { "SPECIFIC", SYM(SPECIFIC_SYM),0,0}, + { "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM),0,0}, + { "SQLWARNING", SYM(SQLWARNING_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}, @@ -412,6 +419,7 @@ static SYMBOL symbols[] = { { "TYPE", SYM(TYPE_SYM),0,0}, { "TYPES", SYM(TYPES_SYM),0,0}, { "UNCOMMITTED", SYM(UNCOMMITTED_SYM),0,0}, + { "UNDO", SYM(UNDO_SYM),0,0}, { "UNICODE", SYM(UNICODE_SYM),0,0}, { "UNION", SYM(UNION_SYM),0,0}, { "UNIQUE", SYM(UNIQUE_SYM),0,0}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a9929cfe1c0..a6dbc41cbf7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -37,6 +37,7 @@ #include #include #include +#include "sp_rcontext.h" #define mysqld_charset &my_charset_latin1 @@ -1846,6 +1847,10 @@ extern "C" int my_message_sql(uint error, const char *str, DBUG_PRINT("error", ("Message: '%s'", str)); if ((thd= current_thd)) { + if (thd->spcont && thd->spcont->find_handler(error)) + { + DBUG_RETURN(0); + } /* thd->lex.current_select equel to zero if lex structure is not inited (not query command (COM_QUERY)) diff --git a/sql/protocol.cc b/sql/protocol.cc index 940f9035f7a..0a29a182890 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -24,6 +24,7 @@ #endif #include "mysql_priv.h" +#include "sp_rcontext.h" #include #ifndef EMBEDDED_LIBRARY @@ -60,6 +61,10 @@ void send_error(THD *thd, uint sql_errno, const char *err) err ? err : net->last_error[0] ? net->last_error : "NULL")); + if (thd->spcont && thd->spcont->find_handler(sql_errno)) + { + DBUG_VOID_RETURN; + } #ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ query_cache_abort(net); #endif @@ -139,6 +144,10 @@ void send_error(THD *thd, uint sql_errno, const char *err) void send_warning(THD *thd, uint sql_errno, const char *err) { DBUG_ENTER("send_warning"); + if (thd->spcont && thd->spcont->find_handler(sql_errno)) + { + DBUG_VOID_RETURN; + } push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno, err ? err : ER(sql_errno)); send_ok(thd); @@ -169,6 +178,10 @@ net_printf(THD *thd, uint errcode, ...) DBUG_ENTER("net_printf"); DBUG_PRINT("enter",("message: %u",errcode)); + if (thd->spcont && thd->spcont->find_handler(errcode)) + { + DBUG_VOID_RETURN; + } thd->query_error= 1; // needed to catch query errors during replication #ifndef EMBEDDED_LIBRARY query_cache_abort(net); // Safety diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index dbe4ed7c508..876eb634677 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -294,3 +294,4 @@ v/* "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" +"Undefined CONDITION: %s" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 9c95f966273..762353384f3 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -288,3 +288,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 7da1db7a5b1..fbfeee9b042 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -296,3 +296,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 52d4b315c7d..f72175e533e 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -290,3 +290,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 74fdb0336d1..6338aa66e7c 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -290,3 +290,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 83e05270e1f..f56e47df734 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -285,3 +285,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 207c5653631..8e003d1742e 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -294,3 +294,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 861f4dd1cbf..f07756f8f8c 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -285,3 +285,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 2f655ec47cb..d8f717e2a50 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -287,3 +287,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index e1b2696a1c3..1b6e7995a1c 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -285,3 +285,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index bec7512eefd..9c7263599a0 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -287,3 +287,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 42614efd8b5..91d8131bb3e 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -285,3 +285,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 3f103c1bc7e..93815312817 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -287,3 +287,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 35b06835084..c3eef6ad8e2 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -287,3 +287,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 6574a9abaf4..93cd9279018 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -289,3 +289,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index bbc487b77c2..b50b12a92ef 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -285,3 +285,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index e49a67b92d2..41255003a9f 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -289,3 +289,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 9319898c0a8..a371cd00248 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -287,3 +287,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 0aae9b64a6d..d442eafe220 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -280,3 +280,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 66a58812004..66792676a5b 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -293,3 +293,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index ef9fd53e0b3..901a5335695 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -286,3 +286,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 2bf66db0183..2e5cd806a66 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -285,3 +285,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 0f9f26b76b5..a86346faf9c 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -290,3 +290,4 @@ "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" +"Undefined CONDITION: %s" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c6e89222175..f34cb39ab7d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -213,6 +213,7 @@ sp_head::execute(THD *thd) DBUG_ENTER("sp_head::execute"); char olddbname[128]; char *olddbptr= thd->db; + sp_rcontext *ctx= thd->spcont; int ret= 0; uint ip= 0; @@ -229,15 +230,38 @@ sp_head::execute(THD *thd) olddbname[i]= '\0'; } + if (ctx) + ctx->clear_handler(); do { sp_instr *i; + uint hip; // Handler ip 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); + // Check if an exception has occurred and a handler has been found + if (ret && !thd->killed && ctx) + { + uint hf; + + switch (ctx->found_handler(&hip, &hf)) + { + case SP_HANDLER_NONE: + break; + case SP_HANDLER_CONTINUE: + ctx->save_variables(hf); + ctx->push_hstack(ip); + // Fall through + default: + ip= hip; + ret= 0; + ctx->clear_handler(); + continue; + } + } } while (ret == 0 && !thd->killed); DBUG_PRINT("info", ("ret=%d killed=%d", ret, thd->killed)); @@ -263,6 +287,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) DBUG_PRINT("info", ("function %s", m_name.str)); uint csize = m_pcont->max_framesize(); uint params = m_pcont->params(); + uint hmax = m_pcont->handlers(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; uint i; @@ -278,7 +303,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) } // QQ Should have some error checking here? (types, etc...) - nctx= new sp_rcontext(csize); + nctx= new sp_rcontext(csize, hmax); for (i= 0 ; i < params && i < argcount ; i++) { sp_pvar_t *pvar = m_pcont->find_pvar(i); @@ -311,6 +336,7 @@ sp_head::execute_procedure(THD *thd, List *args) sp_instr *p; uint csize = m_pcont->max_framesize(); uint params = m_pcont->params(); + uint hmax = m_pcont->handlers(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx @@ -322,16 +348,16 @@ sp_head::execute_procedure(THD *thd, List *args) DBUG_RETURN(-1); } - if (csize > 0) + if (csize > 0 || hmax > 0) { uint i; List_iterator_fast li(*args); Item *it; - nctx = new sp_rcontext(csize); + nctx = new sp_rcontext(csize, hmax); if (! octx) { // Create a temporary old context - octx = new sp_rcontext(csize); + octx = new sp_rcontext(csize, hmax); tmp_octx = TRUE; } // QQ: Should do type checking? @@ -633,13 +659,54 @@ sp_instr_jump_if_not::execute(THD *thd, uint *nextp) } // -// sp_instr_return +// sp_instr_freturn // int -sp_instr_return::execute(THD *thd, uint *nextp) +sp_instr_freturn::execute(THD *thd, uint *nextp) { - DBUG_ENTER("sp_instr_return::execute"); + DBUG_ENTER("sp_instr_freturn::execute"); thd->spcont->set_result(eval_func_item(thd, m_value, m_type)); *nextp= UINT_MAX; DBUG_RETURN(0); } + +// +// sp_instr_hpush_jump +// +int +sp_instr_hpush_jump::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_hpush_jump::execute"); + List_iterator_fast li(m_cond); + sp_cond_type_t *p; + + while ((p= li++)) + thd->spcont->push_handler(p, m_handler, m_type, m_frame); + + *nextp= m_dest; + DBUG_RETURN(0); +} + +// +// sp_instr_hpop +// +int +sp_instr_hpop::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_hpop::execute"); + thd->spcont->pop_handlers(m_count); + *nextp= m_ip+1; + DBUG_RETURN(0); +} + +// +// sp_instr_hreturn +// +int +sp_instr_hreturn::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_hreturn::execute"); + thd->spcont->restore_variables(m_frame); + *nextp= thd->spcont->pop_hstack(); + DBUG_RETURN(0); +} diff --git a/sql/sp_head.h b/sql/sp_head.h index f0435de99d7..e7dbd3f68a6 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -36,6 +36,8 @@ struct sp_label; class sp_instr; +struct sp_cond_type; + class sp_head : public Sql_alloc { sp_head(const sp_head &); /* Prevent use of these */ @@ -93,6 +95,15 @@ public: return m_instr.elements; } + inline sp_instr * + last_instruction() + { + sp_instr *i; + + get_dynamic(&m_instr, (gptr)&i, m_instr.elements-1); + return i; + } + // Resets lex in 'thd' and keeps a copy of the old one. void reset_lex(THD *thd); @@ -385,18 +396,18 @@ private: }; // class sp_instr_jump_if_not : public sp_instr_jump -class sp_instr_return : public sp_instr +class sp_instr_freturn : public sp_instr { - sp_instr_return(const sp_instr_return &); /* Prevent use of these */ - void operator=(sp_instr_return &); + sp_instr_freturn(const sp_instr_freturn &); /* Prevent use of these */ + void operator=(sp_instr_freturn &); public: - sp_instr_return(uint ip, Item *val, enum enum_field_types type) + sp_instr_freturn(uint ip, Item *val, enum enum_field_types type) : sp_instr(ip), m_value(val), m_type(type) {} - virtual ~sp_instr_return() + virtual ~sp_instr_freturn() {} virtual int execute(THD *thd, uint *nextp); @@ -406,6 +417,89 @@ protected: Item *m_value; enum enum_field_types m_type; -}; // class sp_instr_return : public sp_instr +}; // class sp_instr_freturn : public sp_instr + + +class sp_instr_hpush_jump : public sp_instr_jump +{ + sp_instr_hpush_jump(const sp_instr_hpush_jump &); /* Prevent use of these */ + void operator=(sp_instr_hpush_jump &); + +public: + + sp_instr_hpush_jump(uint ip, int htype, uint fp) + : sp_instr_jump(ip), m_type(htype), m_frame(fp) + { + m_handler= ip+1; + m_cond.empty(); + } + + virtual ~sp_instr_hpush_jump() + { + m_cond.empty(); + } + + virtual int execute(THD *thd, uint *nextp); + + inline void add_condition(struct sp_cond_type *cond) + { + m_cond.push_front(cond); + } + +private: + + int m_type; // Handler type + uint m_frame; + uint m_handler; // Location of handler + List m_cond; + +}; // class sp_instr_hpush_jump : public sp_instr_jump + + +class sp_instr_hpop : public sp_instr +{ + sp_instr_hpop(const sp_instr_hpop &); /* Prevent use of these */ + void operator=(sp_instr_hpop &); + +public: + + sp_instr_hpop(uint ip, uint count) + : sp_instr(ip), m_count(count) + {} + + virtual ~sp_instr_hpop() + {} + + virtual int execute(THD *thd, uint *nextp); + +private: + + uint m_count; + +}; // class sp_instr_hpop : public sp_instr + + +class sp_instr_hreturn : public sp_instr +{ + sp_instr_hreturn(const sp_instr_hreturn &); /* Prevent use of these */ + void operator=(sp_instr_hreturn &); + +public: + + sp_instr_hreturn(uint ip, uint fp) + : sp_instr(ip), m_frame(fp) + {} + + virtual ~sp_instr_hreturn() + {} + + virtual int execute(THD *thd, uint *nextp); + +private: + + uint m_frame; + +}; // class sp_instr_hreturn : public sp_instr + #endif /* _SP_HEAD_H_ */ diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 3973f05b74b..a192d78b9a3 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -27,9 +27,10 @@ #include "sp_head.h" sp_pcontext::sp_pcontext() - : Sql_alloc(), m_params(0), m_framesize(0), m_genlab(0) + : Sql_alloc(), m_params(0), m_framesize(0), m_handlers(0), m_genlab(0) { VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8)); + VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8)); m_label.empty(); } @@ -37,6 +38,7 @@ void sp_pcontext::destroy() { delete_dynamic(&m_pvar); + delete_dynamic(&m_cond); m_label.empty(); } @@ -55,8 +57,9 @@ sp_pcontext::find_pvar(LEX_STRING *name) while (i-- > 0) { - sp_pvar_t *p= find_pvar(i); + sp_pvar_t *p; + get_dynamic(&m_pvar, (gptr)&p, i); if (my_strnncoll(system_charset_info, (const uchar *)name->str, name->length, (const uchar *)p->name.str, p->name.length) == 0) @@ -68,8 +71,8 @@ sp_pcontext::find_pvar(LEX_STRING *name) } void -sp_pcontext::push(LEX_STRING *name, enum enum_field_types type, - sp_param_mode_t mode) +sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type, + sp_param_mode_t mode) { sp_pvar_t *p= (sp_pvar_t *)sql_alloc(sizeof(sp_pvar_t)); @@ -113,3 +116,42 @@ sp_pcontext::find_label(char *name) return NULL; } + +void +sp_pcontext::push_cond(LEX_STRING *name, sp_cond_type_t *val) +{ + sp_cond_t *p= (sp_cond_t *)sql_alloc(sizeof(sp_cond_t)); + + if (p) + { + if (m_cond.elements == m_framesize) + m_framesize += 1; + p->name.str= name->str; + p->name.length= name->length; + p->val= val; + insert_dynamic(&m_cond, (gptr)&p); + } +} + +/* + * See comment for find_pvar() above + */ +sp_cond_type_t * +sp_pcontext::find_cond(LEX_STRING *name) +{ + uint i = m_cond.elements; + + while (i-- > 0) + { + sp_cond_t *p; + + get_dynamic(&m_cond, (gptr)&p, i); + if (my_strnncoll(system_charset_info, + (const uchar *)name->str, name->length, + (const uchar *)p->name.str, p->name.length) == 0) + { + return p->val; + } + } + return NULL; +} diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 6900e18aa93..6fb56faccf6 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -44,6 +44,19 @@ typedef struct sp_label uint ip; // Instruction index } sp_label_t; +typedef struct sp_cond_type +{ + enum { number, state, warning, notfound, exception } type; + char sqlstate[6]; + uint mysqlerr; +} sp_cond_type_t; + +typedef struct sp_cond +{ + LEX_STRING name; + sp_cond_type_t *val; +} sp_cond_t; + class sp_pcontext : public Sql_alloc { sp_pcontext(const sp_pcontext &); /* Prevent use of these */ @@ -57,6 +70,10 @@ class sp_pcontext : public Sql_alloc void destroy(); + // + // Parameters and variables + // + inline uint max_framesize() { @@ -101,11 +118,11 @@ class sp_pcontext : public Sql_alloc } void - push(LEX_STRING *name, enum enum_field_types type, sp_param_mode_t mode); + push_pvar(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) + pop_pvar(uint num = 1) { while (num--) pop_dynamic(&m_pvar); @@ -128,6 +145,10 @@ class sp_pcontext : public Sql_alloc return p; } + // + // Labels + // + sp_label_t * push_label(char *name, uint ip); @@ -146,12 +167,47 @@ class sp_pcontext : public Sql_alloc return m_label.pop(); } + // + // Conditions + // + + void + push_cond(LEX_STRING *name, sp_cond_type_t *val); + + inline void + pop_cond(uint num) + { + while (num--) + pop_dynamic(&m_cond); + } + + sp_cond_type_t * + find_cond(LEX_STRING *name); + + // + // Handlers + // + + inline void + add_handler() + { + m_handlers+= 1; + } + + inline uint + handlers() + { + return m_handlers; + } + private: uint m_params; // The number of parameters uint m_framesize; // The maximum framesize + uint m_handlers; // The total number of handlers - DYNAMIC_ARRAY m_pvar; + DYNAMIC_ARRAY m_pvar; // Parameters/variables + DYNAMIC_ARRAY m_cond; // Conditions List m_label; // The label list uint m_genlab; // Gen. label counter diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc new file mode 100644 index 00000000000..79d02d843ea --- /dev/null +++ b/sql/sp_rcontext.cc @@ -0,0 +1,95 @@ +/* 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_rcontext.h" +#include "sp_pcontext.h" + +sp_rcontext::sp_rcontext(uint fsize, uint hmax) + : m_count(0), m_fsize(fsize), m_result(NULL), m_hcount(0), m_hsp(0) +{ + m_frame= (Item **)sql_alloc(fsize * sizeof(Item*)); + m_outs= (int *)sql_alloc(fsize * sizeof(int)); + m_handler= (sp_handler_t *)sql_alloc(hmax * sizeof(sp_handler_t)); + m_hstack= (uint *)sql_alloc(hmax * sizeof(uint)); + m_saved.empty(); +} + +int +sp_rcontext::find_handler(uint sql_errno) +{ + if (m_hfound >= 0) + return 1; // Already got one + + const char *sqlstate= mysql_errno_to_sqlstate(sql_errno); + int i= m_hcount, found= 0; + + while (!found && i--) + { + sp_cond_type_t *cond= m_handler[i].cond; + + switch (cond->type) + { + case sp_cond_type_t::number: + if (sql_errno == cond->mysqlerr) + found= 1; + break; + case sp_cond_type_t::state: + if (strcmp(sqlstate, cond->sqlstate) == 0) + found= 1; + break; + case sp_cond_type_t::warning: + if (sqlstate[0] == '0' && sqlstate[0] == '1') + found= 1; + break; + case sp_cond_type_t::notfound: + if (sqlstate[0] == '0' && sqlstate[0] == '2') + found= 1; + break; + case sp_cond_type_t::exception: + if (sqlstate[0] != '0' || sqlstate[0] > '2') + found= 1; + break; + } + } + if (found) + m_hfound= i; + return found; +} + +void +sp_rcontext::save_variables(uint fp) +{ + while (fp < m_count) + m_saved.push_front(m_frame[fp++]); +} + +void +sp_rcontext::restore_variables(uint fp) +{ + uint i= m_count; + + while (i-- > fp) + m_frame[i]= m_saved.pop(); +} diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 78485fdd090..fe954ed0d94 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -18,6 +18,25 @@ #ifndef _SP_RCONTEXT_H_ #define _SP_RCONTEXT_H_ +#ifdef __GNUC__ +#pragma interface /* gcc class implementation */ +#endif + +struct sp_cond_type; + +#define SP_HANDLER_NONE 0 +#define SP_HANDLER_EXIT 1 +#define SP_HANDLER_CONTINUE 2 +#define SP_HANDLER_UNDO 3 + +typedef struct +{ + struct sp_cond_type *cond; + uint handler; // Location of handler + int type; + uint foffset; // Frame offset for the handlers declare level +} sp_handler_t; + class sp_rcontext : public Sql_alloc { sp_rcontext(const sp_rcontext &); /* Prevent use of these */ @@ -25,23 +44,19 @@ class sp_rcontext : public Sql_alloc public: - sp_rcontext(uint 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)); - } + sp_rcontext(uint fsize, uint hmax); ~sp_rcontext() { // Not needed? //sql_element_free(m_frame); + //m_saved.empty(); } inline void push_item(Item *i) { - if (m_count < m_size) + if (m_count < m_fsize) m_frame[m_count++] = i; } @@ -82,13 +97,79 @@ class sp_rcontext : public Sql_alloc return m_result; } + inline void + push_handler(struct sp_cond_type *cond, uint h, int type, uint f) + { + m_handler[m_hcount].cond= cond; + m_handler[m_hcount].handler= h; + m_handler[m_hcount].type= type; + m_handler[m_hcount].foffset= f; + m_hcount+= 1; + } + + inline void + pop_handlers(uint count) + { + m_hcount-= count; + } + + // Returns 1 if a handler was found, 0 otherwise. + int + find_handler(uint sql_errno); + + // Returns handler type and sets *ip to location if one was found + inline int + found_handler(uint *ip, uint *fp) + { + if (m_hfound < 0) + return SP_HANDLER_NONE; + *ip= m_handler[m_hfound].handler; + *fp= m_handler[m_hfound].foffset; + return m_handler[m_hfound].type; + } + + // Clears the handler find state + inline void + clear_handler() + { + m_hfound= -1; + } + + inline void + push_hstack(uint h) + { + m_hstack[m_hsp++]= h; + } + + inline uint + pop_hstack() + { + return m_hstack[--m_hsp]; + } + + // Save variables starting at fp and up + void + save_variables(uint fp); + + // Restore variables down to fp + void + restore_variables(uint fp); + private: uint m_count; - uint m_size; + uint m_fsize; Item **m_frame; int *m_outs; Item *m_result; // For FUNCTIONs + sp_handler_t *m_handler; + uint m_hcount; + uint *m_hstack; + uint m_hsp; + + int m_hfound; // Set by find_handler; -1 if not found + + List m_saved; // Saved variables }; // class sp_rcontext : public Sql_alloc diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d1c6975bfa4..17bd75bb71c 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_rcontext.h" #include "sp.h" #include #include @@ -84,6 +85,8 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) interval_type interval; st_select_lex *select_lex; chooser_compare_func_creator boolfunc2creator; + struct sp_cond_type *spcondtype; + struct { int vars, conds, hndlrs; } spblock; } %{ @@ -204,8 +207,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token COLUMNS %token COLUMN_SYM %token CONCURRENT +%token CONDITION_SYM %token CONNECTION_SYM %token CONSTRAINT +%token CONTINUE_SYM %token CONVERT_SYM %token DATABASES %token DATA_SYM @@ -226,14 +231,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token DIRECTORY_SYM %token ESCAPE_SYM %token EXISTS +%token EXIT_SYM %token EXTENDED_SYM %token FALSE_SYM +%token FETCH_SYM %token FILE_SYM %token FIRST_SYM %token FIXED_SYM %token FLOAT_NUM %token FORCE_SYM %token FOREIGN +%token FOUND_SYM %token FROM %token FULL %token FULLTEXT_SYM @@ -356,6 +364,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SHUTDOWN %token SPATIAL_SYM %token SPECIFIC_SYM +%token SQLEXCEPTION_SYM +%token SQLWARNING_SYM %token SSL_SYM %token STARTING %token STATUS_SYM @@ -382,6 +392,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token FUNCTION_SYM %token UNCOMMITTED_SYM %token UNDERSCORE_CHARSET +%token UNDO_SYM %token UNICODE_SYM %token UNION_SYM %token UNIQUE_SYM @@ -725,7 +736,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); END_OF_INPUT %type call sp_proc_stmts sp_proc_stmt -%type sp_decls sp_decl sp_decl_idents sp_opt_inout +%type sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list +%type sp_cond sp_hcond +%type sp_decls sp_decl %type '-' '+' '*' '/' '%' '(' ')' @@ -1096,7 +1109,7 @@ sp_fdparams: sp_fdparam: ident type sp_opt_locator { - Lex->spcont->push(&$1, (enum enum_field_types)$2, sp_param_in); + Lex->spcont->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); } ; @@ -1114,9 +1127,9 @@ sp_pdparams: sp_pdparam: sp_opt_inout ident type sp_opt_locator { - Lex->spcont->push(&$2, - (enum enum_field_types)$3, - (sp_param_mode_t)$1); + Lex->spcont->push_pvar(&$2, + (enum enum_field_types)$3, + (sp_param_mode_t)$1); } ; @@ -1140,11 +1153,13 @@ sp_proc_stmts: sp_decls: /* Empty */ { - $$= 0; + $$.vars= $$.conds= $$.hndlrs= 0; } | sp_decls sp_decl ';' { - $$= $1 + $2; + $$.vars= $1.vars + $2.vars; + $$.conds= $1.conds + $2.conds; + $$.hndlrs= $1.hndlrs + $2.hndlrs; } ; @@ -1170,19 +1185,141 @@ sp_decl: lex->spcont->set_isset(i, TRUE); } } - $$= $2; + $$.vars= $2; + $$.conds= $$.hndlrs= 0; + } + | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond + { + YYTHD->lex->spcont->push_cond(&$2, $5); + $$.vars= $$.hndlrs= 0; + $$.conds= 1; + } + | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_instr_hpush_jump *i= + new sp_instr_hpush_jump(sp->instructions(), $2, + ctx->current_framesize()); + + sp->add_instr(i); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + ctx->add_handler(); + } + sp_hcond_list sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_label_t *hlab= lex->spcont->pop_label(); /* After this hdlr */ + + if ($2 == SP_HANDLER_CONTINUE) + sp->add_instr(new sp_instr_hreturn(sp->instructions(), + lex->spcont->current_framesize())); + else + { /* EXIT or UNDO handler, just jump to the end of the block */ + sp_instr_jump *i= new sp_instr_jump(sp->instructions()); + + sp->add_instr(i); + sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */ + } + lex->sphead->backpatch(hlab); + $$.vars= $$.conds= 0; + $$.hndlrs= $6; + } +/* QQ Not yet + | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt + { + $$.vars= $$.conds= $$.hndlrs= 0; + }*/ + ; + +sp_handler_type: + EXIT_SYM { $$= SP_HANDLER_EXIT; } + | CONTINUE_SYM { $$= SP_HANDLER_CONTINUE; } +/* | UNDO_SYM { QQ No yet } */ + ; + +sp_hcond_list: + sp_hcond + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($1); + $$= 1; + } + | sp_hcond_list ',' sp_hcond + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($3); + $$= $1 + 1; + } + ; + +sp_cond: + ULONG_NUM + { /* mysql errno */ + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::number; + $$->mysqlerr= $1; + } + | TEXT_STRING_literal + { /* SQLSTATE */ + uint len= ($1.length < sizeof($$->sqlstate)-1 ? + $1.length : sizeof($$->sqlstate)-1); + + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::state; + memcpy($$->sqlstate, $1.str, len); + $$->sqlstate[len]= '\0'; + } + ; + +sp_hcond: + sp_cond + { + $$= $1; + } + | ident /* CONDITION name */ + { + $$= Lex->spcont->find_cond(&$1); + if ($$ == NULL) + { + net_printf(YYTHD, ER_SP_COND_MISMATCH, $1.str); + YYABORT; + } + } + | SQLWARNING_SYM /* SQLSTATEs 01??? */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::warning; + } + | NOT FOUND_SYM /* SQLSTATEs 02??? */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::notfound; + } + | SQLEXCEPTION_SYM /* All other SQLSTATEs */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::exception; } ; sp_decl_idents: ident { - Lex->spcont->push(&$1, (enum_field_types)0, sp_param_in); + Lex->spcont->push_pvar(&$1, (enum_field_types)0, sp_param_in); $$= 1; } | sp_decl_idents ',' ident { - Lex->spcont->push(&$3, (enum_field_types)0, sp_param_in); + Lex->spcont->push_pvar(&$3, (enum_field_types)0, sp_param_in); $$= $1 + 1; } ; @@ -1246,9 +1383,9 @@ sp_proc_stmt: } else { - sp_instr_return *i= - new sp_instr_return(lex->sphead->instructions(), - $2, lex->sphead->m_returns); + sp_instr_freturn *i= + new sp_instr_freturn(lex->sphead->instructions(), + $2, lex->sphead->m_returns); lex->sphead->add_instr(i); } @@ -1273,13 +1410,13 @@ sp_proc_stmt: dummy.str= (char *)""; dummy.length= 0; - lex->spcont->push(&dummy, MYSQL_TYPE_STRING, sp_param_in); + lex->spcont->push_pvar(&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(); + Lex->spcont->pop_pvar(); } | sp_labeled_control {} @@ -1331,6 +1468,12 @@ sp_proc_stmt: lex->sphead->add_instr(i); } } + | OPEN_SYM ident + {} + | FETCH_SYM ident INTO select_var_list_init + {} + | CLOSE_SYM ident + {} ; sp_if: @@ -1452,13 +1595,26 @@ sp_labeled_control: sp_unlabeled_control: 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); + + Lex->spcont->push_label((char *)"", 0); /* For end of block */ + } + sp_decls + sp_proc_stmts + END + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_instr_hpop *i; + + sp->backpatch(ctx->pop_label()); + ctx->pop_pvar($3.vars); + ctx->pop_cond($3.conds); + i= new sp_instr_hpop(sp->instructions(), $3.hndlrs); + sp->add_instr(i); } | LOOP_SYM sp_proc_stmts END LOOP_SYM -- cgit v1.2.1 From c21755eb5f4187c95986185b46e22d7d0026d594 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 17 Sep 2003 12:30:05 +0200 Subject: Fix bug in sp.cc:db_find_routine() which made tables remain open in some cases. sql/sp.cc: Fix bug which made tables remain open in some cases. --- sql/sp.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 092a3b0989b..729a5f0d641 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -134,7 +134,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) if (opened) { close_thread_tables(thd, 0, 1); - table= NULL; + opened= FALSE; } { @@ -167,7 +167,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) } done: - if (table && opened) + if (opened) close_thread_tables(thd); DBUG_RETURN(ret); } -- cgit v1.2.1 From 03042c7db4be039b0088de24bd5b7b50f76c91b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Sep 2003 15:26:20 +0200 Subject: Post-merge fixes. --- client/mysqltest.c | 3 ++- libmysqld/lib_sql.cc | 4 ++-- mysql-test/r/distinct.result | 4 ++-- mysql-test/r/query_cache.result | 8 +++---- mysql-test/r/sp-error.result | 2 +- mysql-test/r/variables.result | 2 +- mysql-test/t/distinct.test | 4 ++-- mysql-test/t/sp-error.test | 46 ++++++++++++++++++++--------------------- sql/item.cc | 2 +- sql/lex.h | 1 - sql/sp.cc | 4 ++-- sql/sp_cache.h | 2 +- sql/sql_cache.cc | 2 +- sql/sql_insert.cc | 2 +- sql/sql_prepare.cc | 2 +- sql/sql_repl.cc | 14 ++++++------- 16 files changed, 51 insertions(+), 51 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index aed4c142ab8..0c3cded4218 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -206,8 +206,9 @@ 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_DELIMITER, +Q_ENABLE_INFO, Q_DISABLE_INFO, Q_EXEC, +Q_DELIMITER, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 179bbaeec91..8e05e99261f 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -698,7 +698,7 @@ bool Protocol::convert_str(const char *from, uint length) bool setup_params_data(st_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; ulong param_no= 0; @@ -728,7 +728,7 @@ bool setup_params_data(st_prep_stmt *stmt) bool setup_params_data_withlog(st_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; MYSQL_BIND *client_param= thd->client_params; diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 5e713f59100..38df7674ed8 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -457,10 +457,10 @@ drop table t1,t2; CREATE TABLE t1 ( html varchar(5) default NULL, rin int(11) default '0', -out int(11) default '0' +rout int(11) default '0' ) TYPE=MyISAM; INSERT INTO t1 VALUES ('1',1,0); -SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; +SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; html prod 1 0.00 drop table t1; diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 3207443369b..611c8464626 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -715,10 +715,10 @@ Variable_name Value Qcache_queries_in_cache 0 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 1 +Qcache_inserts 44 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 1 +Qcache_hits 12 /**/ select * from t1; a /**/ select * from t1; @@ -728,8 +728,8 @@ Variable_name Value Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 2 +Qcache_inserts 45 show status like "Qcache_hits"; Variable_name Value -Qcache_hits 2 +Qcache_hits 13 drop table t1; diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index d839b8a3af8..109d84b2b8a 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -35,7 +35,7 @@ call foo(); ERROR HY000: PROCEDURE foo does not exist drop procedure if exists foo; Warnings: -Warning 1275 PROCEDURE foo does not exist +Warning 1281 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 8bbe773ed01..55f49d49b87 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -311,7 +311,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1285 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1291 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/distinct.test b/mysql-test/t/distinct.test index 56c00e7501c..54e50fc7147 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -326,9 +326,9 @@ drop table t1,t2; CREATE TABLE t1 ( html varchar(5) default NULL, rin int(11) default '0', - out int(11) default '0' + rout int(11) default '0' ) TYPE=MyISAM; INSERT INTO t1 VALUES ('1',1,0); -SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; +SELECT DISTINCT html,SUM(rout)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; drop table t1; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 5d46c39b601..ab3ee6a9ac6 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -32,18 +32,18 @@ create function func1() returns int return 42| # Can't create recursively ---error 1273 +--error 1279 create procedure foo() create procedure bar() set @x=3| ---error 1273 +--error 1279 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1274 +--error 1280 create procedure proc1() set @x = 42| ---error 1274 +--error 1280 create function func1() returns int return 42| @@ -51,32 +51,32 @@ drop procedure proc1| drop function func1| # Does not exist ---error 1275 +--error 1281 alter procedure foo| ---error 1275 +--error 1281 alter function foo| ---error 1275 +--error 1281 drop procedure foo| ---error 1275 +--error 1281 drop function foo| ---error 1275 +--error 1281 call foo()| drop procedure if exists foo| # LEAVE/ITERATE with no match ---error 1278 +--error 1284 create procedure foo() foo: loop leave bar; end loop| ---error 1278 +--error 1284 create procedure foo() foo: loop iterate bar; end loop| # Redefining label ---error 1279 +--error 1285 create procedure foo() foo: loop foo: loop @@ -85,14 +85,14 @@ foo: loop end loop foo| # End label mismatch ---error 1280 +--error 1286 create procedure foo() foo: loop set @x=2; end loop bar| # Referring to undef variable ---error 1281 +--error 1287 create procedure foo(out x int) begin declare y int; @@ -106,17 +106,17 @@ begin select name from mysql.proc; select type from mysql.proc; end| ---error 1282 +--error 1288 call foo()| drop procedure foo| # RETURN in FUNCTION only ---error 1283 +--error 1289 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1284 +--error 1290 create function foo() returns int begin declare x int; @@ -130,19 +130,19 @@ create procedure p(x int) create function f(x int) returns int return x+42| ---error 1288 +--error 1294 call p()| ---error 1288 +--error 1294 call p(1, 2)| ---error 1288 +--error 1294 select f()| ---error 1288 +--error 1294 select f(1, 2)| drop procedure p| drop function f| ---error 1289 +--error 1295 create procedure p(val int, out res int) begin declare x int default 0; @@ -156,7 +156,7 @@ begin end if; end| ---error 1289 +--error 1295 create procedure p(val int, out res int) begin declare x int default 0; diff --git a/sql/item.cc b/sql/item.cc index 1dc0a6358c7..775dbd95ca0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -793,7 +793,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, // store pointer on SELECT_LEX from wich item is dependent item->depended_from= last; current->mark_as_dependent(last); - if (thd->lex.describe) + if (thd->lex->describe) { char warn_buff[MYSQL_ERRMSG_SIZE]; sprintf(warn_buff, ER(ER_WARN_FIELD_RESOLVED), diff --git a/sql/lex.h b/sql/lex.h index e1223170b62..a5830ac8620 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -437,7 +437,6 @@ static SYMBOL symbols[] = { { "USE", SYM(USE_SYM),0,0}, { "USE_FRM", SYM(USE_FRM),0,0}, { "USER", SYM(USER),0,0}, - { "UNTIL", SYM(UNTIL_SYM),0,0}, { "USING", SYM(USING),0,0}, { "UTC_DATE", SYM(UTC_DATE_SYM),0,0}, { "UTC_TIME", SYM(UTC_TIME_SYM),0,0}, diff --git a/sql/sp.cc b/sql/sp.cc index 729a5f0d641..b4f9f85cd69 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -393,7 +393,7 @@ sp_add_fun_to_lex(LEX *lex, LEX_STRING fun) ls->str= sql_strmake(fun.str, fun.length); ls->length= fun.length; - hash_insert(&lex->spfuns, (byte *)ls); + my_hash_insert(&lex->spfuns, (byte *)ls); } } @@ -405,7 +405,7 @@ sp_merge_funs(LEX *dst, LEX *src) LEX_STRING *ls= (LEX_STRING *)hash_element(&src->spfuns, i); if (! hash_search(&dst->spfuns, (byte *)ls->str, ls->length)) - hash_insert(&dst->spfuns, (byte *)ls); + my_hash_insert(&dst->spfuns, (byte *)ls); } } diff --git a/sql/sp_cache.h b/sql/sp_cache.h index 68a97839ed8..5e7825d70fc 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -41,7 +41,7 @@ public: inline void insert(sp_head *sp) { - hash_insert(&m_hashtable, (const byte *)sp); + my_hash_insert(&m_hashtable, (const byte *)sp); } inline sp_head * diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index a062f1f6225..aa2af81fdee 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2588,7 +2588,7 @@ my_bool Query_cache::ask_handler_allowance(THD *thd, { DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s", tables_used->db, tables_used->alias)); - 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 DBUG_RETURN(1); } } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 78189a2054d..3a71c16c7e2 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -616,7 +616,7 @@ public: thd.current_tablenr=0; thd.version=refresh_version; thd.command=COM_DELAYED_INSERT; - thd.lex.current_select= 0; /* for my_message_sql */ + thd.lex->current_select= 0; /* for my_message_sql */ bzero((char*) &thd.net,sizeof(thd.net)); // Safety thd.system_thread=1; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 971d8a2e592..d342f971a4b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -901,7 +901,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) my_pthread_setprio(pthread_self(),WAIT_PRIOR); // save WHERE clause pointers to avoid damaging they by optimisation - for (SELECT_LEX *sl= thd->lex.all_selects_list; + for (SELECT_LEX *sl= thd->lex->all_selects_list; sl; sl= sl->next_select_in_list()) { diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 59a616fc77c..2c79c1dbaf9 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -697,22 +697,22 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) { pthread_mutex_lock(&mi->rli.data_lock); - if (thd->lex.mi.pos) + if (thd->lex->mi.pos) { mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_MASTER_POS; - mi->rli.until_log_pos= thd->lex.mi.pos; + mi->rli.until_log_pos= thd->lex->mi.pos; /* We don't check thd->lex.mi.log_file_name for NULL here since it is checked in sql_yacc.yy */ - strmake(mi->rli.until_log_name, thd->lex.mi.log_file_name, + strmake(mi->rli.until_log_name, thd->lex->mi.log_file_name, sizeof(mi->rli.until_log_name)-1); } - else if (thd->lex.mi.relay_log_pos) + else if (thd->lex->mi.relay_log_pos) { mi->rli.until_condition= RELAY_LOG_INFO::UNTIL_RELAY_POS; - mi->rli.until_log_pos= thd->lex.mi.relay_log_pos; - strmake(mi->rli.until_log_name, thd->lex.mi.relay_log_name, + mi->rli.until_log_pos= thd->lex->mi.relay_log_pos; + strmake(mi->rli.until_log_name, thd->lex->mi.relay_log_name, sizeof(mi->rli.until_log_name)-1); } else @@ -750,7 +750,7 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) pthread_mutex_unlock(&mi->rli.data_lock); } - else if (thd->lex.mi.pos || thd->lex.mi.relay_log_pos) + else if (thd->lex->mi.pos || thd->lex->mi.relay_log_pos) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED, ER(ER_UNTIL_COND_IGNORED)); -- cgit v1.2.1 From 422bb4fcc5efa70436f5bbe6246438f48fce9c60 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Oct 2003 16:50:50 +0300 Subject: Add proc table if not exists BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + scripts/mysql_fix_privilege_tables.sql | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 2249dad7149..df738f87479 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -73,6 +73,7 @@ monty@donna.mysql.fi monty@hundin.mysql.fi monty@mashka.(none) monty@mashka.mysql.fi +monty@mishka.mysql.fi monty@narttu. monty@narttu.mysql.fi monty@rescue. diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index 220bf4036db..4adc0655434 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -99,3 +99,20 @@ ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; ALTER TABLE host ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; + +# +# Create proc table if it doesn't exists +# + +CREATE TABLE IF NOT EXISTS proc ( + name char(64) binary DEFAULT '' NOT NULL, + type enum('function','procedure') NOT NULL, + body blob DEFAULT '' NOT NULL, + creator char(77) binary DEFAULT '' NOT NULL, + modified timestamp, + created timestamp, + suid enum ('N', 'Y') DEFAULT 'Y' NOT NULL, + comment char(64) binary DEFAULT '' NOT NULL, + PRIMARY KEY (name,type) +) comment='Stored Procedures'; + -- cgit v1.2.1 From 2f468db76ea345783930bacceec45f4d637b3178 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Oct 2003 17:15:24 +0300 Subject: Made SELECT INTO variable-list re-entrant, which fixes bug in stored procedures (#822) --- sql/sql_class.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2128f97e3d9..fcfbe661599 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1076,28 +1076,26 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) List_iterator_fast li(list); List_iterator_fast gl(var_list); Item *item; - my_var *mv; - LEX_STRING *ls; + local_vars.empty(); // Clear list if SP + unit= u; row_count= 0; + if (var_list.elements != list.elements) { my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); return 1; } - unit=u; while ((item=li++)) { - mv=gl++; - ls= &mv->s; + my_var *mv= gl++; 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); + Item_func_set_user_var *xx = new Item_func_set_user_var(mv->s, item); + xx->fix_fields(thd, (TABLE_LIST*) thd->lex->select_lex.table_list.first, + &item); xx->fix_length_and_dec(); vars.push_back(xx); } @@ -1105,6 +1103,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); -- cgit v1.2.1 From 869b49efe558d6604357c366b2f5594f73e9b7f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Oct 2003 12:39:12 +0200 Subject: Fixed BUG#822: Copying and clearing some things in thd/lex when executing sub-statements (selects) prevents crashes intermittent crashes. Also fixed bug in sql_yacc.yy (generated a hpop instruction when not needed). mysql-test/r/sp.result: Test-case for BUG#822. mysql-test/t/sp.test: Test-case for BUG#822. sql/sp_head.cc: Fixed BUG#822; needed to copy and clear some stuff when calling sub-statements. sql/sql_yacc.yy: Only generate hpop instruction when we actually have handlers. --- mysql-test/r/sp.result | 17 +++++++++++++++++ mysql-test/t/sp.test | 17 +++++++++++++++++ sql/sp_head.cc | 25 +++++++++++++++++++++++++ sql/sql_yacc.yy | 8 +++++--- 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 42f720c7791..c8652b25b2e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -500,6 +500,23 @@ id data hndlr3 13 delete from t1; drop procedure hndlr3; +create procedure bug822(a_id char(16), a_data int) +begin +declare n int; +select count(*) into n from t1 where id = a_id and data = a_data; +if n = 0 then +insert into t1 (id, data) values (a_id, a_data); +end if; +end; +call bug822('foo', 42); +call bug822('foo', 42); +call bug822('bar', 666); +select * from t1; +id data +foo 42 +bar 666 +delete from t1; +drop procedure bug822; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 3450b47b4e5..43deb12b379 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -589,6 +589,23 @@ delete from t1| drop procedure hndlr3| +create procedure bug822(a_id char(16), a_data int) +begin + declare n int; + select count(*) into n from t1 where id = a_id and data = a_data; + if n = 0 then + insert into t1 (id, data) values (a_id, a_data); + end if; +end| + +call bug822('foo', 42)| +call bug822('foo', 42)| +call bug822('bar', 666)| +select * from t1| +delete from t1| +drop procedure bug822| + + # # Some "real" examples # diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f34cb39ab7d..87a4114eba5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -481,6 +481,13 @@ sp_head::restore_lex(THD *thd) // Update some state in the old one first oldlex->ptr= sublex->ptr; oldlex->next_state= sublex->next_state; + // Save WHERE clause pointers to avoid damaging by optimisation + for (SELECT_LEX *sl= sublex->all_selects_list ; + sl ; + sl= sl->next_select_in_list()) + { + sl->prep_where= sl->where; + } // Collect some data from the sub statement lex. sp_merge_funs(oldlex, sublex); @@ -578,14 +585,31 @@ 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 + Item *freelist; int res; 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 + freelist= thd->free_list; + thd->free_list= NULL; + thd->query_id= query_id++; + + // Copy WHERE clause pointers to avoid damaging by optimisation + // Also clear ref_pointer_arrays. + for (SELECT_LEX *sl= m_lex->all_selects_list ; + sl ; + sl= sl->next_select_in_list()) + { + sl->ref_pointer_array= 0; + if (sl->prep_where) + sl->where= sl->prep_where->copy_andor_structure(thd); + DBUG_ASSERT(sl->join == 0); + } res= mysql_execute_command(thd); + if (thd->lock || thd->open_tables || thd->derived_tables) { thd->proc_info="closing tables"; @@ -593,6 +617,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) } thd->lex= olex; // Restore the other lex + thd->free_list= freelist; *nextp = m_ip+1; DBUG_RETURN(res); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index dc896e36dc0..06c9908dae8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1644,13 +1644,15 @@ sp_unlabeled_control: LEX *lex= Lex; sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; - sp_instr_hpop *i; sp->backpatch(ctx->pop_label()); ctx->pop_pvar($3.vars); ctx->pop_cond($3.conds); - i= new sp_instr_hpop(sp->instructions(), $3.hndlrs); - sp->add_instr(i); + if ($3.hndlrs) + { + sp_instr_hpop *i= new sp_instr_hpop(sp->instructions(),$3.hndlrs); + sp->add_instr(i); + } } | LOOP_SYM sp_proc_stmts END LOOP_SYM -- cgit v1.2.1 From 4379cbcf3056a33f41ddf489828203a6c03e793f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Oct 2003 17:38:12 +0200 Subject: Check that a FUNCTION contains RETURN and that we actually get a return value. include/mysqld_error.h: New error codes/messages for missing RETURNs in FUNCTIONs. mysql-test/r/sp-error.result: New error tests for missing RETURNs in FUNCTIONs. mysql-test/t/sp-error.test: New error tests for missing RETURNs in FUNCTIONs. sql/share/czech/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/danish/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/dutch/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/english/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/estonian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/french/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/german/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/greek/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/hungarian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/italian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/japanese/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/korean/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/norwegian-ny/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/norwegian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/polish/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/portuguese/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/romanian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/russian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/serbian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/slovak/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/spanish/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/swedish/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/share/ukrainian/errmsg.txt: New error codes/messages for missing RETURNs in FUNCTIONs. sql/sp_head.h: Check that a FUNCTION contains RETURN. sql/sql_parse.cc: Check that a FUNCTION contains RETURN. sql/sql_yacc.yy: Check that a FUNCTION contains RETURN. --- include/mysqld_error.h | 4 +++- mysql-test/r/sp-error.result | 17 +++++++++++++++++ mysql-test/t/sp-error.test | 23 +++++++++++++++++++++++ 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/sp_head.cc | 16 ++++++++++++++-- sql/sp_head.h | 1 + sql/sql_parse.cc | 7 +++++++ sql/sql_yacc.yy | 1 + 30 files changed, 112 insertions(+), 3 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 7f317e93604..18283d576ad 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -312,4 +312,6 @@ #define ER_QUERY_INTERRUPTED 1293 #define ER_SP_WRONG_NO_OF_ARGS 1294 #define ER_SP_COND_MISMATCH 1295 -#define ER_ERROR_MESSAGES 296 +#define ER_SP_NORETURN 1296 +#define ER_SP_NORETURNEND 1297 +#define ER_ERROR_MESSAGES 298 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 109d84b2b8a..d90aef7f609 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -121,3 +121,20 @@ set res = 1; end if; end; ERROR HY000: Undefined CONDITION: bar +create function f(val int) returns int +begin +declare x int; +set x = val+3; +end; +ERROR HY000: No RETURN found in FUNCTION f +create function f(val int) returns int +begin +declare x int; +set x = val+3; +if x < 4 then +return x; +end if; +end; +select f(10); +ERROR HY000: FUNCTION f ended without RETURN +drop function f; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index ab3ee6a9ac6..ba2805bfb0c 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -171,4 +171,27 @@ begin end if; end| +--error 1296 +create function f(val int) returns int +begin + declare x int; + + set x = val+3; +end| + +create function f(val int) returns int +begin + declare x int; + + set x = val+3; + if x < 4 then + return x; + end if; +end| + +--error 1297 +select f(10)| + +drop function f| + delimiter ;| diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 384eb42f6f1..d572b3e4b29 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -308,3 +308,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index e621faea5fe..c83c6ce000e 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -302,3 +302,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index b5a30826996..7001dc859b9 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -310,3 +310,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 1d791bd8609..3936957fad8 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 03c66e69a04..7d85d53b9ce 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -304,3 +304,5 @@ character-set=latin7 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 79cef951367..a3dcdea06c0 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 2e821cbcaab..59735b8bb5d 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -308,3 +308,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 083c158b775..bcfd619a0a1 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -299,3 +299,5 @@ character-set=greek "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index f48f9002186..c4a4cdb1fb6 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 6aa63898d7b..3e1034c8c4a 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 674cf949c37..eb2e456fa66 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -301,3 +301,5 @@ character-set=ujis "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index e39178a3a8a..82f55bb7b02 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -299,3 +299,5 @@ character-set=euckr "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index ccb8fa61fed..74b5fbfbb65 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 7ef83310089..ac08124cf26 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index faa4a4fae10..86dd51da336 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -303,3 +303,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 8ba445c9c31..6e55a8c071e 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -300,3 +300,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 094b5fd76cb..50521fbef94 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -303,3 +303,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index a51ecd4934b..f4ef5415136 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -301,3 +301,5 @@ character-set=koi8r "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index f5a5b88410e..83adc33c73b 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -294,3 +294,5 @@ character-set=cp1250 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 02a2f281374..fc4cb769bc8 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -307,3 +307,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 007f2b457f9..129df358d2e 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 7cde684afe3..e17e20aa5f5 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 4ff6754079d..cb29db0330e 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -304,3 +304,5 @@ character-set=koi8u "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 87a4114eba5..82afb9305f0 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -120,7 +120,8 @@ sp_head::operator delete(void *ptr, size_t size) } sp_head::sp_head() - : Sql_alloc(), m_simple_case(FALSE), m_multi_results(FALSE), m_free_list(NULL) + : Sql_alloc(), m_has_return(FALSE), m_simple_case(FALSE), + m_multi_results(FALSE), m_free_list(NULL) { DBUG_ENTER("sp_head::sp_head"); @@ -321,7 +322,18 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) ret= execute(thd); if (ret == 0) - *resp= nctx->get_result(); + { + Item *it= nctx->get_result(); + + if (it) + *resp= it; + else + { + my_printf_error(ER_SP_NORETURNEND, ER(ER_SP_NORETURNEND), MYF(0), + m_name.str); + ret= -1; + } + } thd->spcont= octx; DBUG_RETURN(ret); diff --git a/sql/sp_head.h b/sql/sp_head.h index e7dbd3f68a6..a68a1bf83ef 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -47,6 +47,7 @@ public: int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE enum enum_field_types m_returns; // For FUNCTIONs only + my_bool m_has_return; // For FUNCTIONs only my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise my_bool m_multi_results; // TRUE if a procedure with SELECT(s) uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 93f5bf99ebe..5c61247136f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3226,6 +3226,13 @@ mysql_execute_command(THD *thd) } } #endif + if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && + !lex->sphead->m_has_return) + { + net_printf(thd, ER_SP_NORETURN, name); + goto error; + } + res= lex->sphead->create(thd); switch (res) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 06c9908dae8..c9fb5e0db41 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1424,6 +1424,7 @@ sp_proc_stmt: $2, lex->sphead->m_returns); lex->sphead->add_instr(i); + lex->sphead->m_has_return= TRUE; } } | IF sp_if END IF {} -- cgit v1.2.1 From d2574b928e728cbe4c0551b91c528ea13b6dc579 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Oct 2003 11:13:25 +0300 Subject: after review patch (SCRUM) sql/sql_parse.cc: already fixed in right way sql/udf_example.cc: not used function tests/udf_test.res: added test of AS tests/udf_test: added test of AS --- sql/sql_parse.cc | 2 -- sql/udf_example.cc | 3 --- tests/udf_test | 2 +- tests/udf_test.res | 12 ++++++------ 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 103dde10814..93f5bf99ebe 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2939,8 +2939,6 @@ mysql_execute_command(THD *thd) break; #ifdef HAVE_DLOPEN sp_head *sph= sp_find_function(thd, &lex->udf.name); - // close & unlock table opened by sp_find_function - close_thread_tables(thd); if (sph) { net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str); diff --git a/sql/udf_example.cc b/sql/udf_example.cc index 397a5051aa2..6748be5a06f 100644 --- a/sql/udf_example.cc +++ b/sql/udf_example.cc @@ -991,7 +991,6 @@ avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error ) extern "C" { my_bool myfunc_argument_name_init(UDF_INIT *initid, UDF_ARGS *args, char *message); -void myfunc_argument_name_deinit(UDF_INIT *initid); char *myfunc_argument_name(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *null_value, char *error); @@ -1011,8 +1010,6 @@ my_bool myfunc_argument_name_init(UDF_INIT *initid, UDF_ARGS *args, return 0; } -void myfunc_argument_name_deinit(UDF_INIT *initid) {} - char *myfunc_argument_name(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *null_value, char *error) diff --git a/tests/udf_test b/tests/udf_test index 2bdacc34d13..15ad640f984 100644 --- a/tests/udf_test +++ b/tests/udf_test @@ -21,7 +21,7 @@ create temporary table t1 (a int,b double); insert into t1 values (1,5),(1,4),(2,8),(3,9),(4,11); select avgcost(a,b) from t1; select avgcost(a,b) from t1 group by a; -select a, myfunc_argument_name(a) from t1; +select a, myfunc_argument_name(a), myfunc_argument_name(a as b) from t1; drop table t1; DROP FUNCTION metaphon; diff --git a/tests/udf_test.res b/tests/udf_test.res index cd65d3794d8..de9e9969f3a 100644 --- a/tests/udf_test.res +++ b/tests/udf_test.res @@ -116,12 +116,12 @@ avgcost(a,b) select a, myfunc_argument_name(a) from t1; -------------- -a myfunc_argument_name(a) -1 a -1 a -2 a -3 a -4 a +a myfunc_argument_name(a) myfunc_argument_name(a as b) +1 a b +1 a b +2 a b +3 a b +4 a b 5 rows in set -------------- -- cgit v1.2.1 From 04c6b9b8d8c10fd83ab80f1a3e2d6bd58b34b825 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Oct 2003 16:57:21 +0200 Subject: WL#962: Added simple, read-only, non-scrolling, asensitive cursors in SPs, using the (updated) Protocol_cursor class. Also did some bug fixes. Docs/sp-imp-spec.txt: Added CURSOR docs (and fixed typos) Docs/sp-implemented.txt: Updated for CURSORs include/mysqld_error.h: New error codes/messages for CURSORs libmysqld/Makefile.am: SP cursors now needs this. mysql-test/r/sp-error.result: New tests for cursors. mysql-test/r/sp.result: New tests for cursors. mysql-test/t/sp-error.test: New tests for cursors. mysql-test/t/sp.test: New tests for cursors. sql/protocol.cc: We now always have Protocol_cursor (SPs use it) sql/protocol.h: Fixed bugs in Protocol_cursor (for SPs) sql/protocol_cursor.cc: Fixed bugs in Protocol_cursor (for SPs) sql/share/czech/errmsg.txt: New error codes/messages for CURSORs sql/share/danish/errmsg.txt: New error codes/messages for CURSORs sql/share/dutch/errmsg.txt: New error codes/messages for CURSORs sql/share/english/errmsg.txt: New error codes/messages for CURSORs sql/share/estonian/errmsg.txt: New error codes/messages for CURSORs sql/share/french/errmsg.txt: New error codes/messages for CURSORs sql/share/german/errmsg.txt: New error codes/messages for CURSORs sql/share/greek/errmsg.txt: New error codes/messages for CURSORs sql/share/hungarian/errmsg.txt: New error codes/messages for CURSORs sql/share/italian/errmsg.txt: New error codes/messages for CURSORs sql/share/japanese/errmsg.txt: New error codes/messages for CURSORs sql/share/korean/errmsg.txt: New error codes/messages for CURSORs sql/share/norwegian-ny/errmsg.txt: New error codes/messages for CURSORs sql/share/norwegian/errmsg.txt: New error codes/messages for CURSORs sql/share/polish/errmsg.txt: New error codes/messages for CURSORs sql/share/portuguese/errmsg.txt: New error codes/messages for CURSORs sql/share/romanian/errmsg.txt: New error codes/messages for CURSORs sql/share/russian/errmsg.txt: New error codes/messages for CURSORs sql/share/serbian/errmsg.txt: New error codes/messages for CURSORs sql/share/slovak/errmsg.txt: New error codes/messages for CURSORs sql/share/spanish/errmsg.txt: New error codes/messages for CURSORs sql/share/swedish/errmsg.txt: New error codes/messages for CURSORs sql/share/ukrainian/errmsg.txt: New error codes/messages for CURSORs sql/sp_head.cc: Added cursor support. Also fixed problems with item_lists, where pointers and ref_pointer_arrays. sql/sp_head.h: Added cursor support sql/sp_pcontext.cc: Added cursor support sql/sp_pcontext.h: Added cursor support sql/sp_rcontext.cc: Added cursor support, in particular the new sp_cursor class. sql/sp_rcontext.h: Added cursor support, in particular the new sp_cursor class. sql/sql_lex.h: We sometimes need to copy item_lists in LEX when executing substatements in SPs sql/sql_yacc.yy: Added minimal cursor support (not the full syntax yet). --- Docs/sp-imp-spec.txt | 148 ++++++++++++++++++++++++++++++++++-- Docs/sp-implemented.txt | 9 ++- include/mysqld_error.h | 10 ++- libmysqld/Makefile.am | 2 +- mysql-test/r/sp-error.result | 82 ++++++++++++++++++++ mysql-test/r/sp.result | 27 +++++++ mysql-test/t/sp-error.test | 106 ++++++++++++++++++++++++++ mysql-test/t/sp.test | 31 ++++++++ sql/protocol.cc | 9 --- sql/protocol.h | 8 +- sql/protocol_cursor.cc | 12 +-- sql/share/czech/errmsg.txt | 8 ++ sql/share/danish/errmsg.txt | 8 ++ sql/share/dutch/errmsg.txt | 8 ++ sql/share/english/errmsg.txt | 8 ++ sql/share/estonian/errmsg.txt | 8 ++ sql/share/french/errmsg.txt | 8 ++ sql/share/german/errmsg.txt | 8 ++ sql/share/greek/errmsg.txt | 8 ++ sql/share/hungarian/errmsg.txt | 8 ++ sql/share/italian/errmsg.txt | 8 ++ sql/share/japanese/errmsg.txt | 8 ++ sql/share/korean/errmsg.txt | 8 ++ sql/share/norwegian-ny/errmsg.txt | 8 ++ sql/share/norwegian/errmsg.txt | 8 ++ sql/share/polish/errmsg.txt | 8 ++ sql/share/portuguese/errmsg.txt | 8 ++ sql/share/romanian/errmsg.txt | 8 ++ sql/share/russian/errmsg.txt | 8 ++ sql/share/serbian/errmsg.txt | 8 ++ sql/share/slovak/errmsg.txt | 8 ++ sql/share/spanish/errmsg.txt | 8 ++ sql/share/swedish/errmsg.txt | 8 ++ sql/share/ukrainian/errmsg.txt | 8 ++ sql/sp_head.cc | 153 +++++++++++++++++++++++++++++++++---- sql/sp_head.h | 129 ++++++++++++++++++++++++++++++- sql/sp_pcontext.cc | 42 ++++++++++- sql/sp_pcontext.h | 28 ++++++- sql/sp_rcontext.cc | 146 ++++++++++++++++++++++++++++++++++- sql/sp_rcontext.h | 79 ++++++++++++++++++- sql/sql_lex.h | 1 + sql/sql_yacc.yy | 155 ++++++++++++++++++++++++++++++++++---- 42 files changed, 1290 insertions(+), 71 deletions(-) diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index 1b72026c427..dee26ab38c0 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -11,7 +11,7 @@ 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 + There are three 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 @@ -186,7 +186,7 @@ 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 + A PROCEDURE is just stored in 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 @@ -293,7 +293,7 @@ So, stored functions must be handled in a simpilar way, and as a consequence, UDFs and functions must not have the same name. - - Detecting and parsing a FUNCTION invokation + - Detecting and parsing a FUNCTION invocation The existance of UDFs are checked during the lexical analysis (in sql_lex.cc:find_keyword()). This has the drawback that they must @@ -319,7 +319,7 @@ "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 + point of invocation; 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 @@ -478,6 +478,67 @@ 7 sp_instr_hpop(2) + - Cursors + + For stored procedures to be really useful, you want to have cursors. + MySQL doesn't yet have "real" cursor support (with API and ODBC support, + allowing updating, arbitrary scrolling, etc), but a simple asensitive, + non-scrolling, read-only cursor can be implemented in SPs using the + class Protocol_cursor. + This class intecepts the creation and sending of results sets and instead + stores it in-memory, as MYSQL_FIELDS and MYSQL_ROWS (as in the client API). + + To support this, we need the usual name binding support in sp_pcontext + (similar to variables and conditions) to keep track on declared cursor + names, and a corresponding run-time mechanism in sp_rcontext. + Cursors are lexically scoped like everything with a body or BEGIN/END + block, so they are pushed and poped as usual (see conditions and variables + above). + The basic operations on a cursor are OPEN, FETCH and CLOSE, which will + each have a corresponding instruction. In addition, we need instructions + to push a new cursor (this will encapsulate the LEX of the SELECT statement + of the cursor), and a pop instruction: + - sp_instr_cpush + Push a cursor to the sp_rcontext. This instruction contains the LEX + for the select statement + - sp_instr_cpop + Pop a number of cursors from the sp_rcontext. + - sp_instr_copen + Open a cursor: This will execute the select and get the result set + in a sepeate memroot. + - sp_instr_cfetch + Fetch the next row from the in-memory result set. The instruction + contains a list of the variables (frame offsets) to set. + - sp_instr_cclose + Free the result set. + + A cursor is a separate class, sp_cursor (defined in sp_rcontex.h) which + encapsulates the basic operations used by the above instructions. + This class contains the LEX, Protocol_cursor object, and its memroot, + as well as the cursor's current state. + Compiling and executing is fairly straight-forward. sp_instr_copen is + a subclass of sp_instr_stmt and uses its mechanism to execute a + substatement. + + - Example: + + begin + declare x int; + declare c cursor for select a from t1; + + open c; + fetch c into x; + close c; + end + + Pos. Instruction + 0 sp_instr_cpush('select a from ...') + 1 sp_instr_copen(0) # The 0'th cursor + 2 sp_instr_cfetch(0) # Contains the variable list + 3 sp_instr_cclose(0) + 4 sp_instr_cpop(1) + + - Class and function APIs This is an outline of the key types. Some types and other details in the actual files have been omitted for readability. @@ -569,6 +630,18 @@ // Returns the handler count uint handlers(); + + // Push a cursor + void push_cursor(LEX_STRING *name); + + // Find a cursor + my_bool find_cursor(LEX_STRING *name, uint *poff); + + // Pop 'num' cursors + void pop_cursor(uint num); + + // Return the number of cursors + uint cursors(); } @@ -589,8 +662,9 @@ class sp_rcontext { - // 'fsize' is the max size of the context, 'hmax' the number of handlers - sp_rcontext(uint fsize, uint hmax); + // 'fsize' is the max size of the context, 'hmax' the number of handlers, + // 'cmax' the number of cursors + sp_rcontext(uint fsize, uint hmax, , uint cmax); // Push value (parameter) 'i' to the frame void push_item(Item *i); @@ -645,6 +719,18 @@ // Restore saved variables from to frame index 'fp' and up. void restore_variables(uint fp); + // Push a cursor for the statement (lex) + void push_cursor(LEX *lex); + + // Pop 'count' cursors + void pop_cursors(uint count); + + // Pop all cursors + void pop_all_cursors(); + + // Get the 'i'th cursor + sp_cursor *get_cursor(uint i); + } @@ -709,6 +795,7 @@ bool suid, char *comment, uint commentlen); } + - Instructions - The base class: @@ -816,6 +903,55 @@ int execute(THD *thd, uint *nextp); } + - Push a CURSOR + class sp_instr_cpush : public sp_instr_stmt + { + // Push a cursor for statement 'lex' + sp_instr_cpush(uint ip, LEX *lex) + + int execute(THD *thd, uint *nextp); + } + + - Pop CURSORs + class sp_instr_cpop : public sp_instr_stmt + { + // Pop 'count' cursors + sp_instr_cpop(uint ip, uint count) + + int execute(THD *thd, uint *nextp); + } + + - Open a CURSOR + class sp_instr_copen : public sp_instr_stmt + { + // Open the 'c'th cursor + sp_instr_copen(uint ip, uint c); + + int execute(THD *thd, uint *nextp); + } + + - Close a CURSOR + class sp_instr_cclose : public sp_instr + { + // Close the 'c'th cursor + sp_instr_cclose(uint ip, uint c); + + int execute(THD *thd, uint *nextp); + } + + - Fetch a row with CURSOR + class sp_instr_cfetch : public sp_instr + { + // Fetch next with the 'c'th cursor + sp_instr_cfetch(uint ip, uint c); + + int execute(THD *thd, uint *nextp); + + // Add a target variable for the fetch + void add_to_varlist(struct sp_pvar *var); + } + + - Utility functions: sp.h #define SP_OK 0 diff --git a/Docs/sp-implemented.txt b/Docs/sp-implemented.txt index 5ce09ae3af4..c9112d75e43 100644 --- a/Docs/sp-implemented.txt +++ b/Docs/sp-implemented.txt @@ -8,8 +8,7 @@ Summary of Not Yet Implemented: - Access control - Routine characteristics (mostly used for external languages) - SQL-99 COMMIT (related to BEGIN/END) - - DECLARE CURSOR ... - - FOR-loops (as it requires cursors) + - FOR-loops - CASCADE/RESTRICT for ALTER and DROP - ALTER/DROP METHOD (as it implies User Defined Types) - SIGNAL and RESIGNAL, and UNDO handlers @@ -25,6 +24,7 @@ Summary of what's implemented: - "Non-query" FUNCTIONs only - Prepared SP caching - CONDITIONs and HANDLERs + - Simple read-only CURSORs. List of what's implemented: @@ -86,6 +86,11 @@ List of what's implemented: The semantics of CONDITIONs is expanded to allow catching MySQL error codes as well. UNDO handlers are not implemented (since we don't have SQL-99 style transaction control yet). + - Simple read-only CURSORs are implemented, but not yet any of the + optional arguments to DECLARE (SCROLL, SENSITIVE, etc) or FETCH + (NEXT, PRIOR, etc). Cursors are ASENSITIVE, READ-ONLY, non-SCROLLing. + (The additional syntax will be added for completeness, but for the + most part unsupported with the current underlying cursor mechanism.) Closed questions: diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 18283d576ad..34caaee4e6a 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -314,4 +314,12 @@ #define ER_SP_COND_MISMATCH 1295 #define ER_SP_NORETURN 1296 #define ER_SP_NORETURNEND 1297 -#define ER_ERROR_MESSAGES 298 +#define ER_SP_BAD_CURSOR_QUERY 1298 +#define ER_SP_BAD_CURSOR_SELECT 1299 +#define ER_SP_CURSOR_MISMATCH 1300 +#define ER_SP_CURSOR_ALREADY_OPEN 1301 +#define ER_SP_CURSOR_NOT_OPEN 1302 +#define ER_SP_UNDECLARED_VAR 1303 +#define ER_SP_WRONG_NO_OF_FETCH_ARGS 1304 +#define ER_SP_FETCH_NO_DATA 1305 +#define ER_ERROR_MESSAGES 306 diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 080da0c7725..a75efd47914 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -56,7 +56,7 @@ sqlsources = 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 protocol_cursor.cc \ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index d90aef7f609..ef8b2ac1552 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -138,3 +138,85 @@ end; select f(10); ERROR HY000: FUNCTION f ended without RETURN drop function f; +create procedure p() +begin +declare c cursor for insert into test.t1 values ("foo", 42); +open c; +close c; +end; +ERROR HY000: Cursor statement must be a SELECT +create procedure p() +begin +declare x int; +declare c cursor for select * into x from test.t limit 1; +open c; +close c; +end; +ERROR HY000: Cursor SELECT must not have INTO +create procedure p() +begin +declare c cursor for select * from test.t; +open cc; +close c; +end; +ERROR HY000: Undefined CURSOR: cc +drop table if exists t1; +create table t1 (val int); +create procedure p() +begin +declare c cursor for select * from test.t1; +open c; +open c; +close c; +end; +call p(); +ERROR HY000: Cursor is already open +drop procedure p; +create procedure p() +begin +declare c cursor for select * from test.t1; +open c; +close c; +close c; +end; +call p(); +ERROR HY000: Cursor is not open +drop procedure p; +drop table t1; +drop table if exists t1; +create table t1 (val int, x float); +insert into t1 values (42, 3.1), (19, 1.2); +create procedure p() +begin +declare c cursor for select * from t1; +declare x int; +open c; +fetch c into x, y; +close c; +end; +ERROR HY000: Undeclared variable: y +create procedure p() +begin +declare c cursor for select * from t1; +declare x int; +open c; +fetch c into x; +close c; +end; +call p(); +ERROR HY000: Wrong number of FETCH variables +drop procedure p; +create procedure p() +begin +declare c cursor for select * from t1; +declare x int; +declare y float; +declare z int; +open c; +fetch c into x, y, z; +close c; +end; +call p(); +ERROR HY000: Wrong number of FETCH variables +drop procedure p; +drop table t1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index c8652b25b2e..3339c93a0be 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -500,6 +500,33 @@ id data hndlr3 13 delete from t1; drop procedure hndlr3; +create procedure cur1() +begin +declare done int default 0; +declare continue handler for 1305 set done = 1; +declare c cursor for select * from test.t2; +declare a char(16); +declare b int; +declare c double; +open c; +repeat +fetch c into a, b, c; +if not done then +insert into test.t1 values (a, b+c); +end if; +until done end repeat; +close c; +end; +insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14); +call cur1(); +select * from t1; +id data +foo 40 +bar 15 +zap 663 +delete from t1; +delete from t2; +drop procedure cur1; create procedure bug822(a_id char(16), a_data int) begin declare n int; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index ba2805bfb0c..c075e96cc78 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -194,4 +194,110 @@ select f(10)| drop function f| +--error 1298 +create procedure p() +begin + declare c cursor for insert into test.t1 values ("foo", 42); + + open c; + close c; +end| + +--error 1299 +create procedure p() +begin + declare x int; + declare c cursor for select * into x from test.t limit 1; + + open c; + close c; +end| + +--error 1300 +create procedure p() +begin + declare c cursor for select * from test.t; + + open cc; + close c; +end| + +--disable_warnings +drop table if exists t1| +--enable_warnings +create table t1 (val int)| + +create procedure p() +begin + declare c cursor for select * from test.t1; + + open c; + open c; + close c; +end| +--error 1301 +call p()| +drop procedure p| + +create procedure p() +begin + declare c cursor for select * from test.t1; + + open c; + close c; + close c; +end| +--error 1302 +call p()| +drop procedure p| + +drop table t1| + +--disable_warnings +drop table if exists t1| +--enable_warnings +create table t1 (val int, x float)| +insert into t1 values (42, 3.1), (19, 1.2)| + +--error 1303 +create procedure p() +begin + declare c cursor for select * from t1; + declare x int; + + open c; + fetch c into x, y; + close c; +end| + +create procedure p() +begin + declare c cursor for select * from t1; + declare x int; + + open c; + fetch c into x; + close c; +end| +--error 1304 +call p()| +drop procedure p| + +create procedure p() +begin + declare c cursor for select * from t1; + declare x int; + declare y float; + declare z int; + + open c; + fetch c into x, y, z; + close c; +end| +--error 1304 +call p()| +drop procedure p| + +drop table t1| + delimiter ;| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 43deb12b379..724180c65bf 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -588,7 +588,38 @@ select * from t1| delete from t1| drop procedure hndlr3| +# +# Cursors +# +create procedure cur1() +begin + declare done int default 0; + declare continue handler for 1305 set done = 1; + declare c cursor for select * from test.t2; + declare a char(16); + declare b int; + declare c double; + + open c; + repeat + fetch c into a, b, c; + if not done then + insert into test.t1 values (a, b+c); + end if; + until done end repeat; + close c; +end| +insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14)| +call cur1()| +select * from t1| +delete from t1| +delete from t2| +drop procedure cur1| + +# +# BUG#822 +# create procedure bug822(a_id char(16), a_data int) begin declare n int; diff --git a/sql/protocol.cc b/sql/protocol.cc index 35a299e37bf..2ad12e56ff7 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1145,12 +1145,3 @@ bool Protocol_prep::store_time(TIME *tm) buff[0]=(char) length; // Length is stored first return packet->append(buff, length+1, PACKET_BUFFET_EXTRA_ALLOC); } - -#ifdef EMBEDDED_LIBRARY -/* Should be removed when we define the Protocol_cursor's future */ -bool Protocol_cursor::write() -{ - return Protocol_simple::write(); -} -#endif - diff --git a/sql/protocol.h b/sql/protocol.h index 94fd303e259..6aa9b6414ae 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -47,17 +47,13 @@ public: Protocol(THD *thd) { init(thd); } virtual ~Protocol() {} void init(THD* thd); - bool send_fields(List *list, uint flag); + virtual bool send_fields(List *list, uint flag); bool send_records_num(List *list, ulonglong records); bool store(I_List *str_list); bool store(const char *from, CHARSET_INFO *cs); String *storage_packet() { return packet; } inline void free() { packet->free(); } -#ifndef EMBEDDED_LIBRARY - bool write(); -#else virtual bool write(); -#endif inline bool store(uint32 from) { return store_long((longlong) from); } inline bool store(longlong from) @@ -158,6 +154,7 @@ public: Protocol_cursor(THD *thd, MEM_ROOT *ini_alloc) :Protocol_simple(thd), alloc(ini_alloc) {} bool prepare_for_send(List *item_list) { + row_count= 0; fields= NULL; data= NULL; prev_record= &data; @@ -165,6 +162,7 @@ public: } bool send_fields(List *list, uint flag); bool write(); + uint get_field_count() { return field_count; } }; void send_warning(THD *thd, uint sql_errno, const char *err=0); diff --git a/sql/protocol_cursor.cc b/sql/protocol_cursor.cc index 19e3bb06d74..abb391fbd67 100644 --- a/sql/protocol_cursor.cc +++ b/sql/protocol_cursor.cc @@ -51,6 +51,7 @@ bool Protocol_cursor::send_fields(List *list, uint flag) client_field->name= strdup_root(alloc, server_field.col_name); client_field->org_table= strdup_root(alloc, server_field.org_table_name); client_field->org_name= strdup_root(alloc, server_field.org_col_name); + client_field->catalog= strdup_root(alloc, ""); client_field->length= server_field.length; client_field->type= server_field.type; client_field->flags= server_field.flags; @@ -60,6 +61,7 @@ bool Protocol_cursor::send_fields(List *list, uint flag) client_field->name_length= strlen(client_field->name); client_field->org_name_length= strlen(client_field->org_name); client_field->org_table_length= strlen(client_field->org_table); + client_field->catalog_length= 0; client_field->charsetnr= server_field.charsetnr; if (INTERNAL_NUM_FIELD(client_field)) @@ -100,17 +102,17 @@ bool Protocol_cursor::write() byte *to; new_record= (MYSQL_ROWS *)alloc_root(alloc, - sizeof(MYSQL_ROWS) + (field_count + 1)*sizeof(char *) + packet->length()); + sizeof(MYSQL_ROWS) + (field_count + 1)*sizeof(char *) + packet->length()); if (!new_record) goto err; data= (byte **)(new_record + 1); new_record->data= (char **)data; - to= (byte *)(fields + field_count + 1); + to= (byte *)data + (field_count + 1)*sizeof(char *); for (; cur_field < fields_end; ++cur_field, ++data) { - if ((len=net_field_length((uchar **)&cp))) + if ((len= net_field_length((uchar **)&cp)) == 0) { *data= 0; } @@ -121,6 +123,7 @@ bool Protocol_cursor::write() // TODO error signal send_error(thd, CR_MALFORMED_PACKET); return TRUE; } + *data= to; memcpy(to,(char*) cp,len); to[len]=0; to+=len+1; @@ -129,6 +132,7 @@ bool Protocol_cursor::write() cur_field->max_length=len; } } + *data= 0; *prev_record= new_record; prev_record= &new_record->next; @@ -139,5 +143,3 @@ bool Protocol_cursor::write() // TODO error signal send_error(thd, ER_OUT_OF_RESOURCES); return TRUE; } - - diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index d572b3e4b29..b21a65342aa 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -310,3 +310,11 @@ character-set=latin2 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index c83c6ce000e..7b2c114d456 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -304,3 +304,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 7001dc859b9..13b2802b8ba 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -312,3 +312,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 3936957fad8..3e58da13cf2 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -301,3 +301,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 7d85d53b9ce..3a30c65cd58 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -306,3 +306,11 @@ character-set=latin7 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index a3dcdea06c0..40edf256b57 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -301,3 +301,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 59735b8bb5d..66df9eb519d 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -310,3 +310,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index bcfd619a0a1..4777d09df46 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -301,3 +301,11 @@ character-set=greek "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index c4a4cdb1fb6..b3aeb507016 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -303,3 +303,11 @@ character-set=latin2 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 3e1034c8c4a..5b83f699791 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -301,3 +301,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index eb2e456fa66..5916c5f8a32 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -303,3 +303,11 @@ character-set=ujis "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 82f55bb7b02..154ed0d9b6f 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -301,3 +301,11 @@ character-set=euckr "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 74b5fbfbb65..4ff587bcee1 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -303,3 +303,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index ac08124cf26..b8a47078bcc 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -303,3 +303,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 86dd51da336..546d24adc9f 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -305,3 +305,11 @@ character-set=latin2 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 6e55a8c071e..69d573b53af 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -302,3 +302,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 50521fbef94..af7b26c9ef1 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -305,3 +305,11 @@ character-set=latin2 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index f4ef5415136..435c9c5193a 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -303,3 +303,11 @@ character-set=koi8r "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 83adc33c73b..2c7dc25e0ac 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -296,3 +296,11 @@ character-set=cp1250 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index fc4cb769bc8..3596b73682b 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -309,3 +309,11 @@ character-set=latin2 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 129df358d2e..d24153d29d2 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -303,3 +303,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index e17e20aa5f5..3931ce9718e 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -301,3 +301,11 @@ character-set=latin1 "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index cb29db0330e..0f69481aefe 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -306,3 +306,11 @@ character-set=koi8u "Undefined CONDITION: %s" "No RETURN found in FUNCTION %s" "FUNCTION %s ended without RETURN" +"Cursor statement must be a SELECT" +"Cursor SELECT must not have INTO" +"Undefined CURSOR: %s" +"Cursor is already open" +"Cursor is not open" +"Undeclared variable: %s" +"Wrong number of FETCH variables" +"No data to FETCH" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 82afb9305f0..bea4d7a34be 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -289,6 +289,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) uint csize = m_pcont->max_framesize(); uint params = m_pcont->params(); uint hmax = m_pcont->handlers(); + uint cmax = m_pcont->cursors(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; uint i; @@ -304,7 +305,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) } // QQ Should have some error checking here? (types, etc...) - nctx= new sp_rcontext(csize, hmax); + nctx= new sp_rcontext(csize, hmax, cmax); for (i= 0 ; i < params && i < argcount ; i++) { sp_pvar_t *pvar = m_pcont->find_pvar(i); @@ -335,6 +336,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) } } + nctx->pop_all_cursors(); // To avoid memory leaks after an error thd->spcont= octx; DBUG_RETURN(ret); } @@ -349,6 +351,7 @@ sp_head::execute_procedure(THD *thd, List *args) uint csize = m_pcont->max_framesize(); uint params = m_pcont->params(); uint hmax = m_pcont->handlers(); + uint cmax = m_pcont->cursors(); sp_rcontext *octx = thd->spcont; sp_rcontext *nctx = NULL; my_bool tmp_octx = FALSE; // True if we have allocated a temporary octx @@ -360,17 +363,17 @@ sp_head::execute_procedure(THD *thd, List *args) DBUG_RETURN(-1); } - if (csize > 0 || hmax > 0) + if (csize > 0 || hmax > 0 || cmax > 0) { uint i; List_iterator_fast li(*args); Item *it; - nctx = new sp_rcontext(csize, hmax); + nctx= new sp_rcontext(csize, hmax, cmax); if (! octx) { // Create a temporary old context - octx = new sp_rcontext(csize, hmax); - tmp_octx = TRUE; + octx= new sp_rcontext(csize, hmax, cmax); + tmp_octx= TRUE; } // QQ: Should do type checking? for (i = 0 ; (it= li++) && i < params ; i++) @@ -443,13 +446,14 @@ sp_head::execute_procedure(THD *thd, List *args) } } } - - if (tmp_octx) - thd->spcont= NULL; - else - thd->spcont= octx; } + if (tmp_octx) + octx= NULL; + if (nctx) + nctx->pop_all_cursors(); // To avoid memory leaks after an error + thd->spcont= octx; + DBUG_RETURN(ret); } @@ -596,12 +600,20 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_stmt::execute"); DBUG_PRINT("info", ("command: %d", m_lex->sql_command)); + int res= exec_stmt(thd, m_lex); + *nextp = m_ip+1; + DBUG_RETURN(res); +} + +int +sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) +{ LEX *olex; // The other lex Item *freelist; int res; olex= thd->lex; // Save the other lex - thd->lex= m_lex; // Use my own lex + thd->lex= lex; // Use my own lex thd->lex->thd = thd; // QQ Not reentrant! thd->lex->unit.thd= thd; // QQ Not reentrant freelist= thd->free_list; @@ -610,10 +622,19 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) // Copy WHERE clause pointers to avoid damaging by optimisation // Also clear ref_pointer_arrays. - for (SELECT_LEX *sl= m_lex->all_selects_list ; + for (SELECT_LEX *sl= lex->all_selects_list ; sl ; sl= sl->next_select_in_list()) { + List_iterator_fast li(sl->item_list); + + if (sl->with_wild) + { + // Copy item_list + sl->item_list_copy.empty(); + while (Item *it= li++) + sl->item_list_copy.push_back(it); + } sl->ref_pointer_array= 0; if (sl->prep_where) sl->where= sl->prep_where->copy_andor_structure(thd); @@ -628,11 +649,22 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) close_thread_tables(thd); /* Free tables */ } + for (SELECT_LEX *sl= lex->all_selects_list ; + sl ; + sl= sl->next_select_in_list()) + { + if (sl->with_wild) + { + // Restore item_list + sl->item_list.empty(); + while (Item *it= sl->item_list_copy.pop()) + sl->item_list.push_back(it); + } + } thd->lex= olex; // Restore the other lex thd->free_list= freelist; - *nextp = m_ip+1; - DBUG_RETURN(res); + return res; } // @@ -747,3 +779,96 @@ sp_instr_hreturn::execute(THD *thd, uint *nextp) *nextp= thd->spcont->pop_hstack(); DBUG_RETURN(0); } + +// +// sp_instr_cpush +// +int +sp_instr_cpush::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_cpush::execute"); + thd->spcont->push_cursor(m_lex); + *nextp= m_ip+1; + DBUG_RETURN(0); +} + +sp_instr_cpush::~sp_instr_cpush() +{ + if (m_lex) + delete m_lex; +} + +// +// sp_instr_cpop +// +int +sp_instr_cpop::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_cpop::execute"); + thd->spcont->pop_cursors(m_count); + *nextp= m_ip+1; + DBUG_RETURN(0); +} + +// +// sp_instr_copen +// +int +sp_instr_copen::execute(THD *thd, uint *nextp) +{ + sp_cursor *c= thd->spcont->get_cursor(m_cursor); + int res; + DBUG_ENTER("sp_instr_copen::execute"); + + if (! c) + res= -1; + else + { + LEX *lex= c->pre_open(thd); + + if (! lex) + res= -1; + else + res= exec_stmt(thd, lex); + c->post_open(thd, (res == 0 ? TRUE : FALSE)); + } + + *nextp= m_ip+1; + DBUG_RETURN(res); +} + +// +// sp_instr_cclose +// +int +sp_instr_cclose::execute(THD *thd, uint *nextp) +{ + sp_cursor *c= thd->spcont->get_cursor(m_cursor); + int res; + DBUG_ENTER("sp_instr_cclose::execute"); + + if (! c) + res= -1; + else + res= c->close(thd); + *nextp= m_ip+1; + DBUG_RETURN(res); +} + +// +// sp_instr_cfetch +// +int +sp_instr_cfetch::execute(THD *thd, uint *nextp) +{ + sp_cursor *c= thd->spcont->get_cursor(m_cursor); + int res; + DBUG_ENTER("sp_instr_cfetch::execute"); + + if (! c) + res= -1; + else + res= c->fetch(thd, &m_varlist); + *nextp= m_ip+1; + DBUG_RETURN(res); +} diff --git a/sql/sp_head.h b/sql/sp_head.h index a68a1bf83ef..b582d37a185 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -33,10 +33,9 @@ Item_result sp_map_result_type(enum enum_field_types type); struct sp_label; - class sp_instr; - struct sp_cond_type; +struct sp_pvar; class sp_head : public Sql_alloc { @@ -278,6 +277,10 @@ public: return m_lex; } +protected: + + int exec_stmt(THD *thd, LEX *lex); // Execute a statement + private: LEX *m_lex; // My own lex @@ -503,4 +506,126 @@ private: }; // class sp_instr_hreturn : public sp_instr +class sp_instr_cpush : public sp_instr +{ + sp_instr_cpush(const sp_instr_cpush &); /* Prevent use of these */ + void operator=(sp_instr_cpush &); + +public: + + sp_instr_cpush(uint ip, LEX *lex) + : sp_instr(ip), m_lex(lex) + {} + + virtual ~sp_instr_cpush(); + + virtual int execute(THD *thd, uint *nextp); + +private: + + LEX *m_lex; + +}; // class sp_instr_cpush : public sp_instr + + +class sp_instr_cpop : public sp_instr +{ + sp_instr_cpop(const sp_instr_cpop &); /* Prevent use of these */ + void operator=(sp_instr_cpop &); + +public: + + sp_instr_cpop(uint ip, uint count) + : sp_instr(ip), m_count(count) + {} + + virtual ~sp_instr_cpop() + {} + + virtual int execute(THD *thd, uint *nextp); + +private: + + uint m_count; + +}; // class sp_instr_cpop : public sp_instr + + +class sp_instr_copen : public sp_instr_stmt +{ + sp_instr_copen(const sp_instr_copen &); /* Prevent use of these */ + void operator=(sp_instr_copen &); + +public: + + sp_instr_copen(uint ip, uint c) + : sp_instr_stmt(ip), m_cursor(c) + {} + + virtual ~sp_instr_copen() + {} + + virtual int execute(THD *thd, uint *nextp); + +private: + + uint m_cursor; // Stack index + +}; // class sp_instr_copen : public sp_instr_stmt + + +class sp_instr_cclose : public sp_instr +{ + sp_instr_cclose(const sp_instr_cclose &); /* Prevent use of these */ + void operator=(sp_instr_cclose &); + +public: + + sp_instr_cclose(uint ip, uint c) + : sp_instr(ip), m_cursor(c) + {} + + virtual ~sp_instr_cclose() + {} + + virtual int execute(THD *thd, uint *nextp); + +private: + + uint m_cursor; + +}; // class sp_instr_cclose : public sp_instr + + +class sp_instr_cfetch : public sp_instr +{ + sp_instr_cfetch(const sp_instr_cfetch &); /* Prevent use of these */ + void operator=(sp_instr_cfetch &); + +public: + + sp_instr_cfetch(uint ip, uint c) + : sp_instr(ip), m_cursor(c) + { + m_varlist.empty(); + } + + virtual ~sp_instr_cfetch() + {} + + virtual int execute(THD *thd, uint *nextp); + + void add_to_varlist(struct sp_pvar *var) + { + m_varlist.push_back(var); + } + +private: + + uint m_cursor; + List m_varlist; + +}; // class sp_instr_cfetch : public sp_instr + + #endif /* _SP_HEAD_H_ */ diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index a192d78b9a3..3730230d47d 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -27,10 +27,11 @@ #include "sp_head.h" sp_pcontext::sp_pcontext() - : Sql_alloc(), m_params(0), m_framesize(0), m_handlers(0), m_genlab(0) + : Sql_alloc(), m_params(0), m_framesize(0), m_handlers(0), m_cursmax(0) { VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8)); VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8)); + VOID(my_init_dynamic_array(&m_cursor, sizeof(LEX_STRING), 16, 8)); m_label.empty(); } @@ -39,6 +40,7 @@ sp_pcontext::destroy() { delete_dynamic(&m_pvar); delete_dynamic(&m_cond); + delete_dynamic(&m_cursor); m_label.empty(); } @@ -124,8 +126,6 @@ sp_pcontext::push_cond(LEX_STRING *name, sp_cond_type_t *val) if (p) { - if (m_cond.elements == m_framesize) - m_framesize += 1; p->name.str= name->str; p->name.length= name->length; p->val= val; @@ -155,3 +155,39 @@ sp_pcontext::find_cond(LEX_STRING *name) } return NULL; } + +void +sp_pcontext::push_cursor(LEX_STRING *name) +{ + LEX_STRING n; + + n.str= name->str; + n.length= name->length; + insert_dynamic(&m_cursor, (gptr)&n); + if (m_cursor.elements > m_cursmax) + m_cursmax= m_cursor.elements; +} + +/* + * See comment for find_pvar() above + */ +my_bool +sp_pcontext::find_cursor(LEX_STRING *name, uint *poff) +{ + uint i = m_cursor.elements; + + while (i-- > 0) + { + LEX_STRING n; + + get_dynamic(&m_cursor, (gptr)&n, i); + if (my_strnncoll(system_charset_info, + (const uchar *)name->str, name->length, + (const uchar *)n.str, n.length) == 0) + { + *poff= i; + return TRUE; + } + } + return FALSE; +} diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 6fb56faccf6..23be38edcbf 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -29,7 +29,7 @@ typedef enum sp_param_inout } sp_param_mode_t; -typedef struct +typedef struct sp_pvar { LEX_STRING name; enum enum_field_types type; @@ -200,17 +200,41 @@ class sp_pcontext : public Sql_alloc return m_handlers; } + // + // Cursors + // + + void + push_cursor(LEX_STRING *name); + + my_bool + find_cursor(LEX_STRING *name, uint *poff); + + inline void + pop_cursor(uint num) + { + while (num--) + pop_dynamic(&m_cursor); + } + + inline uint + cursors() + { + return m_cursmax; + } + private: uint m_params; // The number of parameters uint m_framesize; // The maximum framesize uint m_handlers; // The total number of handlers + uint m_cursmax; // The maximum number of cursors DYNAMIC_ARRAY m_pvar; // Parameters/variables DYNAMIC_ARRAY m_cond; // Conditions + DYNAMIC_ARRAY m_cursor; // Cursors List m_label; // The label list - uint m_genlab; // Gen. label counter }; // class sp_pcontext : public Sql_alloc diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 79d02d843ea..d73f3ed6dd7 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -23,16 +23,20 @@ #endif #include "mysql_priv.h" +#include "mysql.h" +#include "sp_head.h" #include "sp_rcontext.h" #include "sp_pcontext.h" -sp_rcontext::sp_rcontext(uint fsize, uint hmax) - : m_count(0), m_fsize(fsize), m_result(NULL), m_hcount(0), m_hsp(0) +sp_rcontext::sp_rcontext(uint fsize, uint hmax, uint cmax) + : m_count(0), m_fsize(fsize), m_result(NULL), m_hcount(0), m_hsp(0), + m_hfound(-1), m_ccount(0) { m_frame= (Item **)sql_alloc(fsize * sizeof(Item*)); m_outs= (int *)sql_alloc(fsize * sizeof(int)); m_handler= (sp_handler_t *)sql_alloc(hmax * sizeof(sp_handler_t)); m_hstack= (uint *)sql_alloc(hmax * sizeof(uint)); + m_cstack= (sp_cursor **)sql_alloc(cmax * sizeof(sp_cursor *)); m_saved.empty(); } @@ -93,3 +97,141 @@ sp_rcontext::restore_variables(uint fp) while (i-- > fp) m_frame[i]= m_saved.pop(); } + +void +sp_rcontext::push_cursor(LEX *lex) +{ + m_cstack[m_ccount++]= new sp_cursor(lex); +} + +void +sp_rcontext::pop_cursors(uint count) +{ + while (count--) + { + delete m_cstack[--m_ccount]; + } +} + + +/* + * + * sp_cursor + * + */ + +// We have split this in two to make it easy for sp_instr_copen +// to reuse the sp_instr::exec_stmt() code. +LEX * +sp_cursor::pre_open(THD *thd) +{ + int res; + + if (m_isopen) + { + send_error(thd, ER_SP_CURSOR_ALREADY_OPEN); + return NULL; + } + + bzero((char *)&m_mem_root, sizeof(m_mem_root)); + init_alloc_root(&m_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + if ((m_prot= new Protocol_cursor(thd, &m_mem_root)) == NULL) + return NULL; + + m_oprot= thd->protocol; // Save the original protocol + thd->protocol= m_prot; + + m_ovio= thd->net.vio; // Prevent send_eof() + thd->net.vio= 0; + return m_lex; +} + +void +sp_cursor::post_open(THD *thd, my_bool isopen) +{ + thd->net.vio= m_ovio; // Restore the originals + thd->protocol= m_oprot; + m_isopen= isopen; + m_current_row= m_prot->data; +} + +int +sp_cursor::close(THD *thd) +{ + if (! m_isopen) + { + send_error(thd, ER_SP_CURSOR_NOT_OPEN); + return -1; + } + destroy(); + return 0; +} + +void +sp_cursor::destroy() +{ + delete m_prot; + m_prot= NULL; + free_root(&m_mem_root, MYF(0)); + bzero((char *)&m_mem_root, sizeof(m_mem_root)); + m_isopen= FALSE; +} + +int +sp_cursor::fetch(THD *thd, List *vars) +{ + List_iterator_fast li(*vars); + sp_pvar_t *pv; + MYSQL_ROW row; + uint fldcount; + MYSQL_FIELD *fields= m_prot->fields; + + if (! m_isopen) + { + send_error(thd, ER_SP_CURSOR_NOT_OPEN); + return -1; + } + + if (m_current_row == NULL) + { + send_error(thd, ER_SP_FETCH_NO_DATA); + return -1; + } + + row= m_current_row->data; + for (fldcount= 0 ; (pv= li++) ; fldcount++) + { + Item *it; + const char *s; + + if (fldcount >= m_prot->get_field_count()) + { + send_error(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS); + return -1; + } + s= row[fldcount]; + switch (sp_map_result_type(pv->type)) + { + case INT_RESULT: + it= new Item_int(s); + break; + case REAL_RESULT: + it= new Item_real(s, strlen(s)); + break; + default: + { + uint len= strlen(s); + it= new Item_string(thd->strmake(s, len), len, thd->db_charset); + break; + } + } + thd->spcont->set_item(pv->offset, it); + } + if (fldcount < m_prot->get_field_count()) + { + send_error(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS); + return -1; + } + m_current_row= m_current_row->next; + return 0; +} diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index fe954ed0d94..027f2f74789 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -23,6 +23,8 @@ #endif struct sp_cond_type; +struct sp_cursor; +struct sp_pvar; #define SP_HANDLER_NONE 0 #define SP_HANDLER_EXIT 1 @@ -44,7 +46,7 @@ class sp_rcontext : public Sql_alloc public: - sp_rcontext(uint fsize, uint hmax); + sp_rcontext(uint fsize, uint hmax, uint cmax); ~sp_rcontext() { @@ -155,22 +157,93 @@ class sp_rcontext : public Sql_alloc void restore_variables(uint fp); + void + push_cursor(LEX *lex); + + void + pop_cursors(uint count); + + void + pop_all_cursors() + { + pop_cursors(m_ccount); + } + + inline sp_cursor * + get_cursor(uint i) + { + return m_cstack[i]; + } + private: uint m_count; uint m_fsize; Item **m_frame; int *m_outs; + Item *m_result; // For FUNCTIONs + sp_handler_t *m_handler; uint m_hcount; uint *m_hstack; uint m_hsp; - int m_hfound; // Set by find_handler; -1 if not found - List m_saved; // Saved variables + sp_cursor **m_cstack; + uint m_ccount; + }; // class sp_rcontext : public Sql_alloc + +class sp_cursor : public Sql_alloc +{ +public: + + sp_cursor(LEX *lex) + : m_lex(lex), m_isopen(0), m_current_row(NULL) + { + /* Empty */ + } + + virtual ~sp_cursor() + { + destroy(); + } + + // We have split this in two to make it easy for sp_instr_copen + // to reuse the sp_instr::exec_stmt() code. + LEX * + pre_open(THD *thd); + void + post_open(THD *thd, my_bool isopen); + + int + close(THD *thd); + + inline my_bool + is_open() + { + return m_isopen; + } + + int + fetch(THD *, List *vars); + +private: + + MEM_ROOT m_mem_root; // My own mem_root + LEX *m_lex; + Protocol_cursor *m_prot; + my_bool m_isopen; + Vio *m_ovio; // Original vio + Protocol *m_oprot; // Original protcol + MYSQL_ROWS *m_current_row; + + void + destroy(); + +}; // class sp_cursor : public Sql_alloc + #endif /* _SP_RCONTEXT_H_ */ diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 99a58f5fbf9..c836ff1ba38 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -348,6 +348,7 @@ public: enum olap_type olap; SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */ List item_list; /* list of fields & expressions */ + List item_list_copy; /* For SPs */ List interval_list, use_index, *use_index_ptr, ignore_index, *ignore_index_ptr; /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c9fb5e0db41..58c1680a5f3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -86,7 +86,8 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) st_select_lex *select_lex; chooser_compare_func_creator boolfunc2creator; struct sp_cond_type *spcondtype; - struct { int vars, conds, hndlrs; } spblock; + struct { int vars, conds, hndlrs, curs; } spblock; + struct st_lex *lex; } %{ @@ -748,6 +749,7 @@ END_OF_INPUT %type sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list %type sp_cond sp_hcond %type sp_decls sp_decl +%type sp_cursor_stmt %type '-' '+' '*' '/' '%' '(' ')' @@ -1189,13 +1191,14 @@ sp_proc_stmts: sp_decls: /* Empty */ { - $$.vars= $$.conds= $$.hndlrs= 0; + $$.vars= $$.conds= $$.hndlrs= $$.curs= 0; } | sp_decls sp_decl ';' { $$.vars= $1.vars + $2.vars; $$.conds= $1.conds + $2.conds; $$.hndlrs= $1.hndlrs + $2.hndlrs; + $$.curs= $1.curs + $2.curs; } ; @@ -1222,12 +1225,12 @@ sp_decl: } } $$.vars= $2; - $$.conds= $$.hndlrs= 0; + $$.conds= $$.hndlrs= $$.curs= 0; } | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond { YYTHD->lex->spcont->push_cond(&$2, $5); - $$.vars= $$.hndlrs= 0; + $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; } | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM @@ -1260,14 +1263,49 @@ sp_decl: sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */ } lex->sphead->backpatch(hlab); - $$.vars= $$.conds= 0; + $$.vars= $$.conds= $$.curs= 0; $$.hndlrs= $6; } -/* QQ Not yet | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_instr_cpush *i= new sp_instr_cpush(sp->instructions(), $5); + + sp->add_instr(i); + lex->spcont->push_cursor(&$2); $$.vars= $$.conds= $$.hndlrs= 0; - }*/ + $$.curs= 1; + } + ; + +sp_cursor_stmt: + { + Lex->sphead->reset_lex(YYTHD); + + /* We use statement here just be able to get a better + error message. Using 'select' works too, but will then + result in a generic "syntax error" if a non-select + statement is given. */ + } + statement + { + LEX *lex= Lex; + + if (lex->sql_command != SQLCOM_SELECT) + { + send_error(YYTHD, ER_SP_BAD_CURSOR_QUERY); + YYABORT; + } + if (lex->result) + { + send_error(YYTHD, ER_SP_BAD_CURSOR_SELECT); + YYABORT; + } + lex->sp_lex_in_use= TRUE; + $$= lex; + lex->sphead->restore_lex(YYTHD); + } ; sp_handler_type: @@ -1506,11 +1544,96 @@ sp_proc_stmt: } } | OPEN_SYM ident - {} - | FETCH_SYM ident INTO select_var_list_init - {} + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_copen *i; + + if (! lex->spcont->find_cursor(&$2, &offset)) + { + net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + YYABORT; + } + i= new sp_instr_copen(sp->instructions(), offset); + sp->add_instr(i); + } + | FETCH_SYM ident INTO + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_cfetch *i; + + if (! lex->spcont->find_cursor(&$2, &offset)) + { + net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + YYABORT; + } + i= new sp_instr_cfetch(sp->instructions(), offset); + sp->add_instr(i); + } + sp_fetch_list + { } | CLOSE_SYM ident - {} + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_cclose *i; + + if (! lex->spcont->find_cursor(&$2, &offset)) + { + net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + YYABORT; + } + i= new sp_instr_cclose(sp->instructions(), offset); + sp->add_instr(i); + } + ; + +sp_fetch_list: + ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + if (!spc || !(spv = spc->find_pvar(&$1))) + { + net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str); + YYABORT; + } + else + { /* An SP local variable */ + sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); + + i->add_to_varlist(spv); + spv->isset= TRUE; + } + } + | + sp_fetch_list ',' ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + if (!spc || !(spv = spc->find_pvar(&$3))) + { + net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $3.str); + YYABORT; + } + else + { /* An SP local variable */ + sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); + + i->add_to_varlist(spv); + spv->isset= TRUE; + } + } ; sp_if: @@ -1649,11 +1772,11 @@ sp_unlabeled_control: sp->backpatch(ctx->pop_label()); ctx->pop_pvar($3.vars); ctx->pop_cond($3.conds); + ctx->pop_cursor($3.curs); if ($3.hndlrs) - { - sp_instr_hpop *i= new sp_instr_hpop(sp->instructions(),$3.hndlrs); - sp->add_instr(i); - } + sp->add_instr(new sp_instr_hpop(sp->instructions(),$3.hndlrs)); + if ($3.curs) + sp->add_instr(new sp_instr_cpop(sp->instructions(), $3.curs)); } | LOOP_SYM sp_proc_stmts END LOOP_SYM @@ -4206,7 +4329,7 @@ select_var_ident: sp_pvar_t *t; if (!(t=lex->spcont->find_pvar(&$1))) { - send_error(lex->thd, ER_SYNTAX_ERROR); + send_error(lex->thd, ER_SP_UNDECLARED_VAR); YYABORT; } if (! lex->result) -- cgit v1.2.1 From 776784b8215044bc320af5b43a1cbd100d6b944b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Oct 2003 12:59:28 +0200 Subject: Fix for BUG#1495: Evaluate items before setting a local variable with SELECT INTO. Also copy and restore order_list and group_list for selects in SPs. mysql-test/r/sp.result: Test for BUG#1495, and an additional cursor test. mysql-test/t/sp.test: Test for BUG#1495, and an additional cursor test. sql/sp_head.cc: Fix BUG#1495: renamed eval_func_item() into sp_eval_func_item() and made it non-static. Also need to copy and restore order_list and group_list pointers before and after execution of a substatement. (Which means these must always be properly initialized for all queries.) sql/sp_rcontext.cc: Fix BUG#1495: Evaluate and set a local variable (for SELECT INTO). sql/sp_rcontext.h: Fix BUG#1495: Evaluate and set a local variable (for SELECT INTO). sql/sql_class.cc: Fix BUG#1495: Evaluate and set a local variable (for SELECT INTO). sql/sql_class.h: Fix BUG#1495: Evaluate and set a local variable (for SELECT INTO); need type for this. sql/sql_parse.cc: order_list and group_list must be initialized in select_lex for all queries, to make SP sub statement execution work. sql/sql_yacc.yy: Type needed for setting local variables. sql/table.h: Need a copy of the Item* pointer when executing sub-statements in SPs. (Since it's modified and must be restored afterwards.) --- mysql-test/r/sp.result | 59 +++++++++++++++++++++++++++++++++++++++++++++- mysql-test/t/sp.test | 63 +++++++++++++++++++++++++++++++++++++++++++++++++- sql/sp_head.cc | 47 +++++++++++++++++++++++++++---------- sql/sp_rcontext.cc | 8 +++++++ sql/sp_rcontext.h | 3 +++ sql/sql_class.cc | 2 +- sql/sql_class.h | 5 +++- sql/sql_parse.cc | 2 ++ sql/sql_yacc.yy | 4 ++-- sql/table.h | 1 + 10 files changed, 176 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 3339c93a0be..789c78dc109 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -524,9 +524,44 @@ id data foo 40 bar 15 zap 663 +drop procedure cur1; +create table t3 ( s char(16), i int ); +create procedure cur2() +begin +declare done int default 0; +declare continue handler for 1305 set done = 1; +declare c1 cursor for select id,data from test.t1; +declare c2 cursor for select i from test.t2; +open c1; +open c2; +repeat +begin +declare a char(16); +declare b,c int; +fetch c1 into a, b; +fetch c2 into c; +if not done then +if b < c then +insert into test.t3 values (a, b); +else +insert into test.t3 values (a, c); +end if; +end if; +end; +until done end repeat; +close c1; +close c2; +end; +call cur2(); +select * from t3; +s i +foo 40 +bar 3 +zap 663 delete from t1; delete from t2; -drop procedure cur1; +drop table t3; +drop procedure cur2; create procedure bug822(a_id char(16), a_data int) begin declare n int; @@ -544,6 +579,28 @@ foo 42 bar 666 delete from t1; drop procedure bug822; +create procedure bug1495() +begin +declare x int; +select data into x from t1 order by id limit 1; +if x > 10 then +insert into t1 values ("less", x-10); +else +insert into t1 values ("more", x+10); +end if; +end; +insert into t1 values ('foo', 12); +call bug1495(); +delete from t1 where id='foo'; +insert into t1 values ('bar', 7); +call bug1495(); +delete from t1 where id='bar'; +select * from t1; +id data +less 2 +more 17 +delete from t1; +drop procedure bug1495; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 724180c65bf..29b9b9285ef 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -613,9 +613,45 @@ end| insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14)| call cur1()| select * from t1| +drop procedure cur1| + +create table t3 ( s char(16), i int )| + +create procedure cur2() +begin + declare done int default 0; + declare continue handler for 1305 set done = 1; + declare c1 cursor for select id,data from test.t1; + declare c2 cursor for select i from test.t2; + + open c1; + open c2; + repeat + begin + declare a char(16); + declare b,c int; + + fetch c1 into a, b; + fetch c2 into c; + if not done then + if b < c then + insert into test.t3 values (a, b); + else + insert into test.t3 values (a, c); + end if; + end if; + end; + until done end repeat; + close c1; + close c2; +end| + +call cur2()| +select * from t3| delete from t1| delete from t2| -drop procedure cur1| +drop table t3| +drop procedure cur2| # # BUG#822 @@ -636,6 +672,31 @@ select * from t1| delete from t1| drop procedure bug822| +# +# BUG#1495 +# +create procedure bug1495() +begin + declare x int; + + select data into x from t1 order by id limit 1; + if x > 10 then + insert into t1 values ("less", x-10); + else + insert into t1 values ("more", x+10); + end if; +end| + +insert into t1 values ('foo', 12)| +call bug1495()| +delete from t1 where id='foo'| +insert into t1 values ('bar', 7)| +call bug1495()| +delete from t1 where id='bar'| +select * from t1| +delete from t1| +drop procedure bug1495| + # # Some "real" examples diff --git a/sql/sp_head.cc b/sql/sp_head.cc index bea4d7a34be..521e5577577 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -47,10 +47,10 @@ sp_map_result_type(enum enum_field_types type) /* Evaluate a (presumed) func item. Always returns an item, the parameter ** if nothing else. */ -static Item * -eval_func_item(THD *thd, Item *it, enum enum_field_types type) +Item * +sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) { - DBUG_ENTER("eval_func_item"); + DBUG_ENTER("sp_eval_func_item"); it= it->this_item(); DBUG_PRINT("info", ("type: %d", type)); @@ -310,7 +310,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) { sp_pvar_t *pvar = m_pcont->find_pvar(i); - nctx->push_item(eval_func_item(thd, *argp++, pvar->type)); + nctx->push_item(sp_eval_func_item(thd, *argp++, pvar->type)); } // Close tables opened for subselect in argument list close_thread_tables(thd); @@ -387,7 +387,7 @@ sp_head::execute_procedure(THD *thd, List *args) if (pvar->mode == sp_param_out) nctx->push_item(NULL); // OUT else - nctx->push_item(eval_func_item(thd, it, pvar->type)); // IN or INOUT + nctx->push_item(sp_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) @@ -626,10 +626,10 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) sl ; sl= sl->next_select_in_list()) { - List_iterator_fast li(sl->item_list); - if (sl->with_wild) { + List_iterator_fast li(sl->item_list); + // Copy item_list sl->item_list_copy.empty(); while (Item *it= li++) @@ -638,7 +638,18 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) sl->ref_pointer_array= 0; if (sl->prep_where) sl->where= sl->prep_where->copy_andor_structure(thd); - DBUG_ASSERT(sl->join == 0); + for (ORDER *order= (ORDER *)sl->order_list.first ; + order ; + order= order->next) + { + order->item_copy= order->item; + } + for (ORDER *group= (ORDER *)sl->group_list.first ; + group ; + group= group->next) + { + group->item_copy= group->item; + } } res= mysql_execute_command(thd); @@ -660,6 +671,18 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) while (Item *it= sl->item_list_copy.pop()) sl->item_list.push_back(it); } + for (ORDER *order= (ORDER *)sl->order_list.first ; + order ; + order= order->next) + { + order->item= order->item_copy; + } + for (ORDER *group= (ORDER *)sl->group_list.first ; + group ; + group= group->next) + { + group->item= group->item_copy; + } } thd->lex= olex; // Restore the other lex thd->free_list= freelist; @@ -675,7 +698,7 @@ 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)); + thd->spcont->set_item(m_offset, sp_eval_func_item(thd, m_value, m_type)); *nextp = m_ip+1; DBUG_RETURN(0); } @@ -701,7 +724,7 @@ 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); + Item *it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (it->val_int()) *nextp = m_dest; @@ -718,7 +741,7 @@ 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); + Item *it= sp_eval_func_item(thd, m_expr, MYSQL_TYPE_TINY); if (! it->val_int()) *nextp = m_dest; @@ -734,7 +757,7 @@ int sp_instr_freturn::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_freturn::execute"); - thd->spcont->set_result(eval_func_item(thd, m_value, m_type)); + thd->spcont->set_result(sp_eval_func_item(thd, m_value, m_type)); *nextp= UINT_MAX; DBUG_RETURN(0); } diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index d73f3ed6dd7..07fd08b0074 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -40,6 +40,14 @@ sp_rcontext::sp_rcontext(uint fsize, uint hmax, uint cmax) m_saved.empty(); } +void +sp_rcontext::set_item_eval(uint idx, Item *i, enum_field_types type) +{ + extern Item *sp_eval_func_item(THD *thd, Item *it, enum_field_types type); + + set_item(idx, sp_eval_func_item(current_thd, i, type)); +} + int sp_rcontext::find_handler(uint sql_errno) { diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 027f2f74789..e69ac9bf4b4 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -69,6 +69,9 @@ class sp_rcontext : public Sql_alloc m_frame[idx] = i; } + void + set_item_eval(uint idx, Item *i, enum_field_types type); + inline Item * get_item(uint idx) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index fcfbe661599..487ae14f4cd 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1137,7 +1137,7 @@ bool select_dumpvar::send_data(List &items) { if ((yy=var_li++)) { - thd->spcont->set_item(yy->get_offset(), item); + thd->spcont->set_item_eval(yy->get_offset(), item, zz->type); } } else diff --git a/sql/sql_class.h b/sql/sql_class.h index 19bf451be22..f7c9fb58513 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1123,7 +1123,10 @@ public: LEX_STRING s; bool local; uint offset; - my_var (LEX_STRING& j, bool i, uint o) : s(j), local(i), offset(o) {} + enum_field_types type; + my_var (LEX_STRING& j, bool i, uint o, enum_field_types t) + :s(j), local(i), offset(o), type(t) + {} ~my_var() {} }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5c61247136f..3299b73a49c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3724,6 +3724,8 @@ mysql_init_query(THD *thd, bool lexonly) lex->select_lex.prev= &lex->unit.slave; lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0; lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list); + lex->select_lex.init_order(); + lex->select_lex.group_list.empty(); lex->describe= 0; lex->derived_tables= FALSE; lex->lock_option= TL_READ; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1b65b9e87c0..c488b43ee6b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4351,7 +4351,7 @@ select_var_ident: { LEX *lex=Lex; if (lex->result) - ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0)); + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0,(enum_field_types)0)); else YYABORT; } @@ -4370,7 +4370,7 @@ select_var_ident: YYABORT; else { - ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset)); + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset,t->type)); t->isset= TRUE; } } diff --git a/sql/table.h b/sql/table.h index 7b4e5745732..afa6665c8cd 100644 --- a/sql/table.h +++ b/sql/table.h @@ -26,6 +26,7 @@ class st_select_lex_unit; typedef struct st_order { struct st_order *next; Item **item; /* Point at item in select fields */ + Item **item_copy; /* For SPs; the original item ptr */ bool asc; /* true if ascending */ bool free_me; /* true if item isn't shared */ bool in_field_list; /* true if in select field list */ -- cgit v1.2.1 From 9aa680a016e1957bad6f2ba09e7b5f6327e71edc Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Oct 2003 19:03:37 +0200 Subject: Fix for BUG#1547: "SELECT ... WHERE field = var" sometimes give the wrong result in SPs Two missing methods added to Item_splocal + test case. mysql-test/r/sp.result: Test case for BUG#1547 mysql-test/t/sp.test: Test case for BUG#1547 sql/item.h: Fix for BUG#1547: "SELECT ... WHERE field = var" sometimes give the wrong result in SPs Added missing methods to Item_splocal to get the correct compare function and make the optimizer do the right thing. --- mysql-test/r/sp.result | 21 +++++++++++++++++++++ mysql-test/t/sp.test | 22 ++++++++++++++++++++++ sql/item.h | 10 ++++++++++ 3 files changed, 53 insertions(+) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 789c78dc109..cec4f7a9935 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -601,6 +601,27 @@ less 2 more 17 delete from t1; drop procedure bug1495; +create procedure bug1547(s char(16)) +begin +declare x int; +select data into x from t1 where s = id limit 1; +if x > 10 then +insert into t1 values ("less", x-10); +else +insert into t1 values ("more", x+10); +end if; +end; +insert into t1 values ("foo", 12), ("bar", 7); +call bug1547("foo"); +call bug1547("bar"); +select * from t1; +id data +foo 12 +bar 7 +less 2 +more 17 +delete from t1; +drop procedure bug1547; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 29b9b9285ef..230a76721a4 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -697,6 +697,28 @@ select * from t1| delete from t1| drop procedure bug1495| +# +# BUG#1547 +# +create procedure bug1547(s char(16)) +begin + declare x int; + + select data into x from t1 where s = id limit 1; + if x > 10 then + insert into t1 values ("less", x-10); + else + insert into t1 values ("more", x+10); + end if; +end| + +insert into t1 values ("foo", 12), ("bar", 7)| +call bug1547("foo")| +call bug1547("bar")| +select * from t1| +delete from t1| +drop procedure bug1547| + # # Some "real" examples diff --git a/sql/item.h b/sql/item.h index 9cd68e91273..a2ee8e4ec7f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -266,6 +266,16 @@ public: this_item()->make_field(field); } + inline Item_result result_type() const + { + return this_const_item()->result_type(); + } + + inline bool const_item() const + { + return FALSE; + } + }; -- cgit v1.2.1 From 12a0546da376a492b40e3b63c45470fa42ba3010 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 15:45:27 +0200 Subject: Handle user variables (@-vars) as OUT and INOUT parameters in SPs. mysql-test/r/sp.result: Test cases for user variables (@-vars) as OUT and INOUT parameters. mysql-test/t/sp.test: Test cases for user variables (@-vars) as OUT and INOUT parameters. sql/item_func.h: We need to be able to detect Item_func_get_user_vars when used as arguments to SPs. sql/sp_head.cc: Handle user variables (@-vars) as OUT and INOUT parameters. But we still just ignore it, if it's anything else. --- mysql-test/r/sp.result | 16 +++++++++++++++- mysql-test/t/sp.test | 20 ++++++++++++++++++-- sql/item_func.h | 5 ++++- sql/sp_head.cc | 40 +++++++++++++++++++++++----------------- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index cec4f7a9935..ab253112ab3 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -93,8 +93,12 @@ id data zip 100 delete from t1; drop procedure zip; -drop procedure zap; drop procedure bar; +call zap(7, @zap); +select @zap; +@zap +8 +drop procedure zap; create procedure c1(x int) call c2("c", x); create procedure c2(s char(16), x int) @@ -132,7 +136,17 @@ io1 1 delete from t1; drop procedure iotest; drop procedure inc2; +create procedure incr(inout x int) +call inc(x); +select @zap; +@zap +8 +call incr(@zap); +select @zap; +@zap +9 drop procedure inc; +drop procedure incr; create procedure cbv1() begin declare y int default 3; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 230a76721a4..91d4fd45d3f 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -122,9 +122,14 @@ call zip("zip", 99)| select * from t1| delete from t1| drop procedure zip| -drop procedure zap| drop procedure bar| +# Top-level OUT parameter +call zap(7, @zap)| +select @zap| + +drop procedure zap| + # "Deep" calls... create procedure c1(x int) @@ -165,8 +170,19 @@ select * from t1| delete from t1| drop procedure iotest| drop procedure inc2| -drop procedure inc| +# Propagating top-level @-vars +create procedure incr(inout x int) + call inc(x)| + +# Before +select @zap| +call incr(@zap)| +# After +select @zap| + +drop procedure inc| +drop procedure incr| # Call-by-value test # The expected result is: diff --git a/sql/item_func.h b/sql/item_func.h index b15dea77c56..649ddfb9f78 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -46,7 +46,8 @@ public: SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC, SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING, - SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN}; + SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, + GUSERVAR_FUNC}; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL }; enum Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } @@ -926,6 +927,8 @@ public: Item_func_get_user_var(LEX_STRING a): Item_func(), name(a) {} user_var_entry *get_entry(); + enum Functype functype() const { return GUSERVAR_FUNC; } + LEX_STRING get_name() { return name; } double val(); longlong val_int(); String *val_str(String* str); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 521e5577577..3f3838a0650 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -389,7 +389,8 @@ sp_head::execute_procedure(THD *thd, List *args) else nctx->push_item(sp_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!!! + // QQ: We can check for global variables here, or should we do it + // while parsing? if (pvar->mode == sp_param_in) nctx->set_oindex(i, -1); // IN else // OUT or INOUT @@ -427,22 +428,27 @@ sp_head::execute_procedure(THD *thd, List *args) if (! tmp_octx) octx->set_item(nctx->get_oindex(i), nctx->get_item(i)); else - { // A global user variable -#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. - // 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 + { + // QQ Currently we just silently ignore non-user-variable arguments. + // We should check this during parsing, when setting up the call + // above + if (it->type() == Item::FUNC_ITEM) + { + Item_func *fi= static_cast(it); + + if (fi->functype() == Item_func::GUSERVAR_FUNC) + { // A global user variable + Item *item= nctx->get_item(i); + Item_func_set_user_var *suv; + Item_func_get_user_var *guv= + static_cast(fi); + + suv= new Item_func_set_user_var(guv->get_name(), item); + suv->fix_fields(thd, NULL, &item); + suv->fix_length_and_dec(); + suv->update(); + } + } } } } -- cgit v1.2.1 From 82e5115ae7cf9f8fbd85b6f95df5a49219ccc660 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Oct 2003 17:13:49 +0200 Subject: Bugfix. Local variables are now initialized to null. mysql-test/r/sp.result: New test case for bugfix (when a variable is not set due to an exception). mysql-test/t/sp.test: New test case for bugfix (when a variable is not set due to an exception). sql/item.h: Local variables are initialized to null. sql/sp_head.cc: Local variables are initialized to null. --- mysql-test/r/sp.result | 16 ++++++++++++++++ mysql-test/t/sp.test | 23 +++++++++++++++++++++++ sql/item.h | 4 +++- sql/sp_head.cc | 16 +++++++++++----- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ab253112ab3..899ce6cbcec 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -514,6 +514,22 @@ id data hndlr3 13 delete from t1; drop procedure hndlr3; +create procedure hndlr4() +begin +declare x int default 0; +declare val int; # No default +declare continue handler for sqlexception set x=1; +select data into val from test.t1 where id='z' limit 1; # No hits +if val < 10 then +insert into test.t1 values ('z', 10); +end if; +end; +call hndlr4(); +select * from t1; +id data +z 10 +delete from t1; +drop procedure hndlr4; create procedure cur1() begin declare done int default 0; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 91d4fd45d3f..733e6ad07ec 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -604,6 +604,29 @@ select * from t1| delete from t1| drop procedure hndlr3| + +# Variables might be uninitialized when using handlers +# (Otherwise the compiler can detect if a variable is not set, but +# not in this case.) +create procedure hndlr4() +begin + declare x int default 0; + declare val int; # No default + declare continue handler for sqlexception set x=1; + + select data into val from test.t1 where id='z' limit 1; # No hits + + if val < 10 then + insert into test.t1 values ('z', 10); + end if; +end| + +call hndlr4()| +select * from t1| +delete from t1| +drop procedure hndlr4| + + # # Cursors # diff --git a/sql/item.h b/sql/item.h index a2ee8e4ec7f..3b764c8c166 100644 --- a/sql/item.h +++ b/sql/item.h @@ -229,7 +229,9 @@ public: Item_splocal(uint offset) : m_offset(offset) - {} + { + Item::maybe_null= TRUE; + } Item *this_item(); Item *this_const_item() const; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 3f3838a0650..c2c22317aa1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -401,11 +401,17 @@ sp_head::execute_procedure(THD *thd, List *args) 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 - // unassigned variable anyway (which should be detected by the parser). - for (; i < csize ; i++) - nctx->push_item(NULL); + // Default all variables to null (those with default clauses will + // be set by an set instruction). + { + Item_null *nit= NULL; // Re-use this, and only create if needed + for (; i < csize ; i++) + { + if (! nit) + nit= new Item_null(); + nctx->push_item(nit); + } + } thd->spcont= nctx; } -- cgit v1.2.1 From 2b1dc5f35d5bf773378a36a14399987635be7127 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Oct 2003 16:59:45 +0200 Subject: Bugfix; added another method to Item_splocal, updated tests, and added previous fix to functions as well. mysql-test/r/sp.result: Modified test to trap yet another bug (now fixed). mysql-test/t/sp.test: Modified test to trap yet another bug (now fixed). sql/item.h: Another bugfix; need to override yet another method in Item_splocal. sql/sp_head.cc: Completed previous initialization bug; now for FUNCTIONs. too. --- mysql-test/r/sp.result | 15 ++++++++------- mysql-test/t/sp.test | 18 ++++++++++++------ sql/item.h | 4 ++++ sql/sp_head.cc | 14 +++++++++++--- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 899ce6cbcec..4f9c1ed5f7e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -514,21 +514,21 @@ id data hndlr3 13 delete from t1; drop procedure hndlr3; +drop table if exists t3; +create table t3 ( id char(16), data int ); create procedure hndlr4() begin declare x int default 0; declare val int; # No default declare continue handler for sqlexception set x=1; -select data into val from test.t1 where id='z' limit 1; # No hits -if val < 10 then -insert into test.t1 values ('z', 10); -end if; +select data into val from test.t3 where id='z' limit 1; # No hits +insert into test.t3 values ('z', val); end; call hndlr4(); -select * from t1; +select * from t3; id data -z 10 -delete from t1; +z NULL +drop table t3; drop procedure hndlr4; create procedure cur1() begin @@ -555,6 +555,7 @@ foo 40 bar 15 zap 663 drop procedure cur1; +drop table if exists t3; create table t3 ( s char(16), i int ); create procedure cur2() begin diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 733e6ad07ec..ad5dbe9f25e 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -608,22 +608,25 @@ drop procedure hndlr3| # Variables might be uninitialized when using handlers # (Otherwise the compiler can detect if a variable is not set, but # not in this case.) +--disable_warnings +drop table if exists t3| +--enable_warnings +create table t3 ( id char(16), data int )| + create procedure hndlr4() begin declare x int default 0; declare val int; # No default declare continue handler for sqlexception set x=1; - select data into val from test.t1 where id='z' limit 1; # No hits + select data into val from test.t3 where id='z' limit 1; # No hits - if val < 10 then - insert into test.t1 values ('z', 10); - end if; + insert into test.t3 values ('z', val); end| call hndlr4()| -select * from t1| -delete from t1| +select * from t3| +drop table t3| drop procedure hndlr4| @@ -654,6 +657,9 @@ call cur1()| select * from t1| drop procedure cur1| +--disable_warnings +drop table if exists t3| +--enable_warnings create table t3 ( s char(16), i int )| create procedure cur2() diff --git a/sql/item.h b/sql/item.h index 3b764c8c166..95982a079b6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -278,6 +278,10 @@ public: return FALSE; } + inline int save_in_field(Field *field, bool no_conversions) + { + return this_item()->save_in_field(field, no_conversions); + } }; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c2c22317aa1..88d81f25a76 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -316,9 +316,17 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) 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++) - nctx->push_item(NULL); + // Default all variables to null (those with default clauses will + // be set by an set instruction). + { + Item_null *nit= NULL; // Re-use this, and only create if needed + for (; i < csize ; i++) + { + if (! nit) + nit= new Item_null(); + nctx->push_item(nit); + } + } thd->spcont= nctx; ret= execute(thd); -- cgit v1.2.1 From 562a04d593ca9a179b851e1d71d30e764e55f7ad Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Oct 2003 12:08:35 +0200 Subject: WL#1265: Fix proper ALTER/DROP support in the SP cache. New sp_cache C API. When an SP is dropped, old caches (in other threads) become invalid and are cleared. Also, the caches in THD are only created on demand. Docs/sp-imp-spec.txt: Brough the SP cache docs up-to-date. sql/mysqld.cc: Initialize SP cache. sql/sp.cc: New C API for SP cache. sql/sp_cache.cc: New C API for sp_cache. The class sp_cache is still used, but not directly. The C functions makes takes care of updating caches when SPs are dropped. (This is done in the simplest possible way, by simply detecting drops and then clear all old caches.) The API is also designed so that the sp_cache is created on demand. sql/sp_cache.h: New C API for sp_cache. The class sp_cache is still used, but not directly. The C functions makes takes care of updating caches when SPs are dropped. The API is also designed so that the sp_cache is created on demand. sql/sql_class.cc: The new sp_cache API creates the caches on demand, to avoid allocating it when it's not needed. --- Docs/sp-imp-spec.txt | 98 ++++++++++++++++++++++++++++++++++++++-------------- sql/mysqld.cc | 2 ++ sql/sp.cc | 20 +++++------ sql/sp_cache.cc | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ sql/sp_cache.h | 32 +++++++++++++++++ sql/sql_class.cc | 16 ++++----- 6 files changed, 217 insertions(+), 44 deletions(-) diff --git a/Docs/sp-imp-spec.txt b/Docs/sp-imp-spec.txt index dee26ab38c0..6fee125fbea 100644 --- a/Docs/sp-imp-spec.txt +++ b/Docs/sp-imp-spec.txt @@ -79,8 +79,7 @@ - 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). + procedure in the mysql.proc table (or the internal cache). - Parsing CREATE PROCEDURE ... @@ -335,23 +334,12 @@ 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. + Note: Even with an in-memory cache, 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 @@ -537,7 +525,64 @@ 2 sp_instr_cfetch(0) # Contains the variable list 3 sp_instr_cclose(0) 4 sp_instr_cpop(1) - + + + + - The SP cache + + There are two ways to cache SPs: + + 1) one global cache, share by all threads/connections, + 2) one cache per thread. + + There are pros and cons with both methods: + + 1) Pros: Save memory, each SP only read from table once, + Cons: Needs locking (= serialization at access), requires thread-safe + data structures, + 2) Pros: Fast, no locking required (almost), limited thread-safe + requirement, + Cons: Uses more memory, each SP read from table once per thread. + + Unfortunately, we cannot use alternative 1 for the time being, as most + of the datastructures to be cached (lex and items) are not reentrant + and thread-safe. (Things are modifed at execution, we have THD pointers + stored everywhere, etc.) + This leaves us with alternative 2, one cache per thread; or actually + two, since we keep FUNCTIONs and PROCEDUREs in separate caches. + This is not that terrible; the only case when it will perform + significantly worse than a global cache is when we have an application + where new threads are connecting, calling a procedure, and disconnecting, + over and over again. + + The cache implementation itself is simple and straightforward, a hashtable + wrapped in a class and a C API (see APIs below). + + There is however one issue with multiple caches: dropping and altering + procedures. Normally, this should be a very rare event in a running + system; it's typically something you do during development and testing, + so it's not unthinkable that we would simply ignore the issue and let + any threads running with a cached version of an SP keep doing so until + its disconnected. + But assuming we want to keep the caches consistent with respect to drop + and alter, it can be done: + + 1) A global counter is needed, initialized to 0 at start. + 2) At each DROP or ALTER, increase the counter by one. + 3) Each cache has its own copy of the counter, copied at the last read. + 4) When looking up a name in the cache, first check if the global counter + is larger than the local copy. + If so, clear the cache and return "not found", and update the local + counter; otherwise, lookup as usual. + + This minimizes the cost to a single brief lock for the access of an + integer when operating normally. Only in the event of an actual drop or + alter, is the cache cleared. This may seem to be drastic, but since we + assume that this is a rare event, it's not a problem. + It would of course be possible to have a much more fine-grained solution, + keeping track of each SP, but the overhead of doing so is not worth the + effort. + - Class and function APIs This is an outline of the key types. Some types and other details @@ -991,19 +1036,20 @@ - The cache: sp_cache.h - class sp_cache - { - sp_cache(); - - void init(); + /* Initialize the SP caching once at startup */ + void sp_cache_init(); - void cleanup(); + /* Clear the cache *cp and set *cp to NULL */ + void sp_cache_clear(sp_cache **cp); - void insert(sp_head *sp); + /* Insert an SP to cache. If **cp points to NULL, it's set to a + new cache */ + void sp_cache_insert(sp_cache **cp, sp_head *sp); - sp_head *lookup(char *name, uint namelen); + /* Lookup an SP in cache */ + sp_head *sp_cache_lookup(sp_cache **cp, char *name, uint namelen); - void remove(sp_head *sp); - } + /* Remove an SP from cache */ + void sp_cache_remove(sp_cache **cp, sp_head *sp); -- diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 33964feac52..cb7c1fcf211 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -38,6 +38,7 @@ #include #include #include "sp_rcontext.h" +#include "sp_cache.h" #define mysqld_charset &my_charset_latin1 @@ -2140,6 +2141,7 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST); (void) pthread_cond_init(&COND_rpl_status, NULL); #endif + sp_cache_init(); /* Parameter for threads created for connections */ (void) pthread_attr_init(&connection_attrib); (void) pthread_attr_setdetachstate(&connection_attrib, diff --git a/sql/sp.cc b/sql/sp.cc index b4f9f85cd69..b1cdad4f619 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -251,13 +251,13 @@ sp_find_procedure(THD *thd, LEX_STRING *name) DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); - sp= thd->sp_proc_cache->lookup(name->str, name->length); + sp= sp_cache_lookup(&thd->sp_proc_cache, name->str, name->length); if (! sp) { if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, name->str, name->length, &sp) == SP_OK) { - thd->sp_proc_cache->insert(sp); + sp_cache_insert(&thd->sp_proc_cache, sp); } } @@ -286,10 +286,10 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) sp_head *sp; int ret; - sp= thd->sp_proc_cache->lookup(name, namelen); + sp= sp_cache_lookup(&thd->sp_proc_cache, name, namelen); if (sp) { - thd->sp_proc_cache->remove(sp); + sp_cache_remove(&thd->sp_proc_cache, sp); delete sp; } ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen); @@ -312,7 +312,7 @@ sp_find_function(THD *thd, LEX_STRING *name) DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); - sp= thd->sp_func_cache->lookup(name->str, name->length); + sp= sp_cache_lookup(&thd->sp_func_cache, name->str, name->length); if (! sp) { if (db_find_routine(thd, TYPE_ENUM_FUNCTION, @@ -344,10 +344,10 @@ sp_drop_function(THD *thd, char *name, uint namelen) sp_head *sp; int ret; - sp= thd->sp_func_cache->lookup(name, namelen); + sp= sp_cache_lookup(&thd->sp_func_cache, name, namelen); if (sp) { - thd->sp_func_cache->remove(sp); + sp_cache_remove(&thd->sp_func_cache, sp); delete sp; } ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen); @@ -363,7 +363,7 @@ sp_function_exists(THD *thd, LEX_STRING *name) bool ret= FALSE; bool opened= FALSE; - if (thd->sp_func_cache->lookup(name->str, name->length) || + if (sp_cache_lookup(&thd->sp_func_cache, name->str, name->length) || db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, name->str, name->length, TL_READ, &table, &opened) == SP_OK) @@ -419,7 +419,7 @@ sp_cache_functions(THD *thd, LEX *lex) { LEX_STRING *ls= (LEX_STRING *)hash_element(h, i); - if (! thd->sp_func_cache->lookup(ls->str, ls->length)) + if (! sp_cache_lookup(&thd->sp_func_cache, ls->str, ls->length)) { sp_head *sp; LEX *oldlex= thd->lex; @@ -434,7 +434,7 @@ sp_cache_functions(THD *thd, LEX *lex) thd->lex= oldlex; if (ret) break; - thd->sp_func_cache->insert(sp); + sp_cache_insert(&thd->sp_func_cache, sp); } else { diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 1b8816ee0f4..84e3565d543 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -22,6 +22,98 @@ #include "sp_cache.h" #include "sp_head.h" +static pthread_mutex_t Cversion_lock; +static ulong Cversion = 0; + +void +sp_cache_init() +{ + pthread_mutex_init(&Cversion_lock, MY_MUTEX_INIT_FAST); +} + +void +sp_cache_clear(sp_cache **cp) +{ + sp_cache *c= *cp; + + if (c) + { + delete c; + *cp= NULL; + } +} + +void +sp_cache_insert(sp_cache **cp, sp_head *sp) +{ + sp_cache *c= *cp; + + if (! c) + c= new sp_cache(); + if (c) + { + ulong v; + + pthread_mutex_lock(&Cversion_lock); // LOCK + v= Cversion; + pthread_mutex_unlock(&Cversion_lock); // UNLOCK + + if (c->version < v) + { + if (*cp) + c->remove_all(); + c->version= v; + } + c->insert(sp); + if (*cp == NULL) + *cp= c; + } +} + +sp_head * +sp_cache_lookup(sp_cache **cp, char *name, uint namelen) +{ + ulong v; + sp_cache *c= *cp; + + if (! c) + return NULL; + + pthread_mutex_lock(&Cversion_lock); // LOCK + v= Cversion; + pthread_mutex_unlock(&Cversion_lock); // UNLOCK + + if (c->version < v) + { + c->remove_all(); + c->version= v; + return NULL; + } + return c->lookup(name, namelen); +} + +void +sp_cache_remove(sp_cache **cp, sp_head *sp) +{ + sp_cache *c= *cp; + + if (c) + { + ulong v; + + pthread_mutex_lock(&Cversion_lock); // LOCK + v= Cversion++; + pthread_mutex_unlock(&Cversion_lock); // UNLOCK + + if (c->version < v) + c->remove_all(); + else + c->remove(sp); + c->version= v+1; + } +} + + static byte * hash_get_key_for_sp_head(const byte *ptr, uint *plen, my_bool first) @@ -44,6 +136,7 @@ sp_cache::init() { hash_init(&m_hashtable, system_charset_info, 0, 0, 0, hash_get_key_for_sp_head, 0, 0); + version= 0; } void diff --git a/sql/sp_cache.h b/sql/sp_cache.h index 5e7825d70fc..f5b330f6755 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -23,11 +23,36 @@ #endif class sp_head; +class sp_cache; + +/* Initialize the SP caching once at startup */ +void sp_cache_init(); + +/* Clear the cache *cp and set *cp to NULL */ +void sp_cache_clear(sp_cache **cp); + +/* Insert an SP to cache. If 'cp' points to NULL, it's set to a new cache */ +void sp_cache_insert(sp_cache **cp, sp_head *sp); + +/* Lookup an SP in cache */ +sp_head *sp_cache_lookup(sp_cache **cp, char *name, uint namelen); + +/* Remove an SP from cache */ +void sp_cache_remove(sp_cache **cp, sp_head *sp); + + +/* + * + * The cache class. Don't use this directly, use the C API above + * + */ class sp_cache { public: + ulong version; + sp_cache(); ~sp_cache(); @@ -56,6 +81,13 @@ public: hash_delete(&m_hashtable, (byte *)sp); } + inline void + remove_all() + { + cleanup(); + init(); + } + private: HASH m_hashtable; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 487ae14f4cd..025b1d7429d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -156,8 +156,8 @@ THD::THD():user_time(0), is_fatal_error(0), (hash_get_key) get_var_key, (hash_free_key) free_user_var, 0); - sp_proc_cache= new sp_cache(); - sp_func_cache= new sp_cache(); + sp_proc_cache= NULL; + sp_func_cache= NULL; /* For user vars replication*/ if (opt_bin_log) @@ -260,8 +260,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); - sp_proc_cache->init(); - sp_func_cache->init(); + sp_cache_clear(&sp_proc_cache); + sp_cache_clear(&sp_func_cache); } @@ -285,8 +285,8 @@ void THD::cleanup(void) close_temporary_tables(this); delete_dynamic(&user_var_events); hash_free(&user_vars); - sp_proc_cache->cleanup(); - sp_func_cache->cleanup(); + sp_cache_clear(&sp_proc_cache); + sp_cache_clear(&sp_func_cache); if (global_read_lock) unlock_global_read_lock(this); if (ull) @@ -328,8 +328,8 @@ THD::~THD() } #endif - delete sp_proc_cache; - delete sp_func_cache; + sp_cache_clear(&sp_proc_cache); + sp_cache_clear(&sp_func_cache); DBUG_PRINT("info", ("freeing host")); if (host != localhost) // If not pointer to constant -- cgit v1.2.1 From 7e8cc90a8b3ca552c4a81047becb439bad475e96 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Oct 2003 18:13:14 +0200 Subject: Bugfix of previous WL#1265 commit. Need a sp_cache_remove() function with implicit name lookup to make the WL task to work. It's a cleaner and more convenient interface anyway... sql/sp.cc: Modified sp_cache_remove() function calls; just remove by name. sql/sp_cache.cc: Modified sp_cache_remove() function. Get name and lookup/remove, return the removed entry, if any. sql/sp_cache.h: Modified sp_cache_remove() function. Get name and lookup/remove, return the removed entry, if any. --- sql/sp.cc | 10 ++-------- sql/sp_cache.cc | 8 +++++--- sql/sp_cache.h | 12 ++++++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index b1cdad4f619..7076778532f 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -286,12 +286,9 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) sp_head *sp; int ret; - sp= sp_cache_lookup(&thd->sp_proc_cache, name, namelen); + sp= sp_cache_remove(&thd->sp_proc_cache, name, namelen); if (sp) - { - sp_cache_remove(&thd->sp_proc_cache, sp); delete sp; - } ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen); DBUG_RETURN(ret); @@ -344,12 +341,9 @@ sp_drop_function(THD *thd, char *name, uint namelen) sp_head *sp; int ret; - sp= sp_cache_lookup(&thd->sp_func_cache, name, namelen); + sp= sp_cache_remove(&thd->sp_func_cache, name, namelen); if (sp) - { - sp_cache_remove(&thd->sp_func_cache, sp); delete sp; - } ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen); DBUG_RETURN(ret); diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 84e3565d543..7e9d5f92ef0 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -92,10 +92,11 @@ sp_cache_lookup(sp_cache **cp, char *name, uint namelen) return c->lookup(name, namelen); } -void -sp_cache_remove(sp_cache **cp, sp_head *sp) +sp_head * +sp_cache_remove(sp_cache **cp, char *name, uint namelen) { sp_cache *c= *cp; + sp_head *sp= NULL; if (c) { @@ -108,9 +109,10 @@ sp_cache_remove(sp_cache **cp, sp_head *sp) if (c->version < v) c->remove_all(); else - c->remove(sp); + sp= c->remove(name, namelen); c->version= v+1; } + return sp; } diff --git a/sql/sp_cache.h b/sql/sp_cache.h index f5b330f6755..3d38d6f1d1f 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -38,7 +38,7 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp); sp_head *sp_cache_lookup(sp_cache **cp, char *name, uint namelen); /* Remove an SP from cache */ -void sp_cache_remove(sp_cache **cp, sp_head *sp); +sp_head *sp_cache_remove(sp_cache **cp, char *name, uint namelen); /* @@ -75,10 +75,14 @@ public: return (sp_head *)hash_search(&m_hashtable, (const byte *)name, namelen); } - inline void - remove(sp_head *sp) + inline sp_head * + remove(char *name, uint namelen) { - hash_delete(&m_hashtable, (byte *)sp); + sp_head *sp= lookup(name, namelen); + + if (sp) + hash_delete(&m_hashtable, (byte *)sp); + return sp; } inline void -- cgit v1.2.1 From 4cc803c4dc70ad73f733963d747ae85f29fbbfb6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 Oct 2003 16:11:51 +0400 Subject: small merge bug fixed sql/item_sum.h: fixed merge bug --- sql/item_sum.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_sum.h b/sql/item_sum.h index 78d887782e2..c6fed46a338 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -387,7 +387,7 @@ class Item_sum_hybrid :public Item_sum Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value), sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type), hybrid_field_type(item.hybrid_field_type),cmp_sign(item.cmp_sign), - used_table_cache(used_table_cache), cmp_charset(item.cmp_charset) {} + used_table_cache(item.used_table_cache), cmp_charset(item.cmp_charset) {} bool fix_fields(THD *, TABLE_LIST *, Item **); table_map used_tables() const { return used_table_cache; } bool const_item() const { return !used_table_cache; } -- cgit v1.2.1 From ec3a39dc67e264eadb0b924dd7f872f566c8b2dc Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 Oct 2003 16:06:51 +0200 Subject: Post-merge fixes. mysql-test/r/sp-error.result: Post-merge fixes. Error codes renumbered. mysql-test/r/sp.result: Post-merge fixes. Error codes renumbered. mysql-test/r/variables.result: Post-merge fixes. Error codes renumbered. mysql-test/t/sp-error.test: Post-merge fixes. Error codes renumbered. mysql-test/t/sp.test: Post-merge fixes. Error codes renumbered. sql/item_subselect.cc: Post-merge fixes. thd->lex is a pointer. sql/slave.cc: Post-merge fixes. Undid imported patch that's not 5.0 compatible. sql/sql_parse.cc: Post-merge fixes. Changed access API calls, and fixed merge error. sql/sql_table.cc: Post-merge fixes. No update log in 5.0. --- mysql-test/r/query_cache.result | 4 +-- mysql-test/r/sp-error.result | 2 +- mysql-test/r/sp.result | 4 +-- mysql-test/r/variables.result | 2 +- mysql-test/t/sp-error.test | 66 ++++++++++++++++++++--------------------- mysql-test/t/sp.test | 4 +-- sql/item_subselect.cc | 8 ++--- sql/slave.cc | 5 ++-- sql/sql_parse.cc | 6 ++-- sql/sql_table.cc | 1 - 10 files changed, 51 insertions(+), 51 deletions(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 3cc0b3e9852..619f44f457d 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -762,7 +762,7 @@ Variable_name Value Qcache_queries_in_cache 0 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 44 +Qcache_inserts 48 show status like "Qcache_hits"; Variable_name Value Qcache_hits 12 @@ -775,7 +775,7 @@ Variable_name Value Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 45 +Qcache_inserts 49 show status like "Qcache_hits"; Variable_name Value Qcache_hits 13 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index ef8b2ac1552..4cd1c4c961c 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -35,7 +35,7 @@ call foo(); ERROR HY000: PROCEDURE foo does not exist drop procedure if exists foo; Warnings: -Warning 1281 PROCEDURE foo does not exist +Warning 1282 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 4f9c1ed5f7e..05bb2348442 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -533,7 +533,7 @@ drop procedure hndlr4; create procedure cur1() begin declare done int default 0; -declare continue handler for 1305 set done = 1; +declare continue handler for 1306 set done = 1; declare c cursor for select * from test.t2; declare a char(16); declare b int; @@ -560,7 +560,7 @@ create table t3 ( s char(16), i int ); create procedure cur2() begin declare done int default 0; -declare continue handler for 1305 set done = 1; +declare continue handler for 1306 set done = 1; declare c1 cursor for select id,data from test.t1; declare c2 cursor for select i from test.t2; open c1; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 709bf2d65eb..986d82012a2 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -345,7 +345,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1291 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1292 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 c075e96cc78..7c541029452 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -32,18 +32,18 @@ create function func1() returns int return 42| # Can't create recursively ---error 1279 +--error 1280 create procedure foo() create procedure bar() set @x=3| ---error 1279 +--error 1280 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1280 +--error 1281 create procedure proc1() set @x = 42| ---error 1280 +--error 1281 create function func1() returns int return 42| @@ -51,32 +51,32 @@ drop procedure proc1| drop function func1| # Does not exist ---error 1281 +--error 1282 alter procedure foo| ---error 1281 +--error 1282 alter function foo| ---error 1281 +--error 1282 drop procedure foo| ---error 1281 +--error 1282 drop function foo| ---error 1281 +--error 1282 call foo()| drop procedure if exists foo| # LEAVE/ITERATE with no match ---error 1284 +--error 1285 create procedure foo() foo: loop leave bar; end loop| ---error 1284 +--error 1285 create procedure foo() foo: loop iterate bar; end loop| # Redefining label ---error 1285 +--error 1286 create procedure foo() foo: loop foo: loop @@ -85,14 +85,14 @@ foo: loop end loop foo| # End label mismatch ---error 1286 +--error 1287 create procedure foo() foo: loop set @x=2; end loop bar| # Referring to undef variable ---error 1287 +--error 1288 create procedure foo(out x int) begin declare y int; @@ -106,17 +106,17 @@ begin select name from mysql.proc; select type from mysql.proc; end| ---error 1288 +--error 1289 call foo()| drop procedure foo| # RETURN in FUNCTION only ---error 1289 +--error 1290 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1290 +--error 1291 create function foo() returns int begin declare x int; @@ -130,19 +130,19 @@ create procedure p(x int) create function f(x int) returns int return x+42| ---error 1294 +--error 1295 call p()| ---error 1294 +--error 1295 call p(1, 2)| ---error 1294 +--error 1295 select f()| ---error 1294 +--error 1295 select f(1, 2)| drop procedure p| drop function f| ---error 1295 +--error 1296 create procedure p(val int, out res int) begin declare x int default 0; @@ -156,7 +156,7 @@ begin end if; end| ---error 1295 +--error 1296 create procedure p(val int, out res int) begin declare x int default 0; @@ -171,7 +171,7 @@ begin end if; end| ---error 1296 +--error 1297 create function f(val int) returns int begin declare x int; @@ -189,12 +189,12 @@ begin end if; end| ---error 1297 +--error 1298 select f(10)| drop function f| ---error 1298 +--error 1299 create procedure p() begin declare c cursor for insert into test.t1 values ("foo", 42); @@ -203,7 +203,7 @@ begin close c; end| ---error 1299 +--error 1300 create procedure p() begin declare x int; @@ -213,7 +213,7 @@ begin close c; end| ---error 1300 +--error 1301 create procedure p() begin declare c cursor for select * from test.t; @@ -235,7 +235,7 @@ begin open c; close c; end| ---error 1301 +--error 1302 call p()| drop procedure p| @@ -247,7 +247,7 @@ begin close c; close c; end| ---error 1302 +--error 1303 call p()| drop procedure p| @@ -259,7 +259,7 @@ drop table if exists t1| create table t1 (val int, x float)| insert into t1 values (42, 3.1), (19, 1.2)| ---error 1303 +--error 1304 create procedure p() begin declare c cursor for select * from t1; @@ -279,7 +279,7 @@ begin fetch c into x; close c; end| ---error 1304 +--error 1305 call p()| drop procedure p| @@ -294,7 +294,7 @@ begin fetch c into x, y, z; close c; end| ---error 1304 +--error 1305 call p()| drop procedure p| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ad5dbe9f25e..ebc07f8fca8 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -636,7 +636,7 @@ drop procedure hndlr4| create procedure cur1() begin declare done int default 0; - declare continue handler for 1305 set done = 1; + declare continue handler for 1306 set done = 1; declare c cursor for select * from test.t2; declare a char(16); declare b int; @@ -665,7 +665,7 @@ create table t3 ( s char(16), i int )| create procedure cur2() begin declare done int default 0; - declare continue handler for 1305 set done = 1; + declare continue handler for 1306 set done = 1; declare c1 cursor for select id,data from test.t1; declare c2 cursor for select i from test.t2; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 07d2d0ec0df..278348bc2d6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -544,14 +544,14 @@ Item_in_subselect::single_value_transformer(JOIN *join, func == &Item_bool_func2::lt_creator)); } // left expression belong to outer select - SELECT_LEX *current= thd->lex.current_select, *up; - thd->lex.current_select= up= current->return_after_parsing(); + SELECT_LEX *current= thd->lex->current_select, *up; + thd->lex->current_select= up= current->return_after_parsing(); if (left_expr->fix_fields(thd, up->get_table_list(), 0)) { - thd->lex.current_select= current; + thd->lex->current_select= current; DBUG_RETURN(RES_ERROR); } - thd->lex.current_select= current; + thd->lex->current_select= current; substitution= (*func)(left_expr, subs); DBUG_RETURN(RES_OK); } diff --git a/sql/slave.cc b/sql/slave.cc index 348c3e29c8c..59d9c53e950 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1086,12 +1086,11 @@ static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi) BINLOG_FORMAT_323_GEQ_57 ; break; case '4': + case '5': mi->old_format = BINLOG_FORMAT_CURRENT; break; default: - /* 5.0 is not supported */ - errmsg = "Master reported an unrecognized MySQL version. Note that 4.0 \ -slaves can't replicate a 5.0 or newer master."; + errmsg = "Master reported unrecognized MySQL version"; break; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b659806ec85..1fbf57d8cb3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3024,6 +3024,8 @@ mysql_execute_command(THD *thd) if (!(res = mysql_create_function(thd,&lex->udf))) send_ok(thd); #else + res= -1; +#endif break; } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -3344,7 +3346,7 @@ mysql_execute_command(THD *thd) LINT_INIT(smrx); // In case the arguments are subselects... - if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || + if (tables && ((res= check_table_access(thd, SELECT_ACL, tables, 0)) || (res= open_and_lock_tables(thd, tables)))) { break; @@ -3425,7 +3427,7 @@ mysql_execute_command(THD *thd) udf_func *udf = find_udf(lex->udf.name.str, lex->udf.name.length); if (udf) { - if (check_access(thd, DELETE_ACL, "mysql", 0, 1)) + if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0)) goto error; if (!(res = mysql_drop_function(thd,&lex->udf.name))) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 458dd15babb..b4a9d14796c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1800,7 +1800,6 @@ int mysql_discard_or_import_tablespace(THD *thd, error=1; if (error) 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); -- cgit v1.2.1 From e48a6c6c29f0a465bfb0b560e5ab9af882161f67 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 Oct 2003 17:34:11 +0200 Subject: Undid previous fix (as it will be fixed by a merge). --- sql/item_sum.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_sum.h b/sql/item_sum.h index c6fed46a338..78d887782e2 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -387,7 +387,7 @@ class Item_sum_hybrid :public Item_sum Item_sum(thd, item), value(item.value), tmp_value(item.tmp_value), sum(item.sum), sum_int(item.sum_int), hybrid_type(item.hybrid_type), hybrid_field_type(item.hybrid_field_type),cmp_sign(item.cmp_sign), - used_table_cache(item.used_table_cache), cmp_charset(item.cmp_charset) {} + used_table_cache(used_table_cache), cmp_charset(item.cmp_charset) {} bool fix_fields(THD *, TABLE_LIST *, Item **); table_map used_tables() const { return used_table_cache; } bool const_item() const { return !used_table_cache; } -- cgit v1.2.1 From f89c6de8e33619b4c9231aa70c7aea851be06fbc Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Oct 2003 15:43:49 +0100 Subject: Fix BUG#1656: Have to initialize OUT parameters too, in case they're not later set by the procedure. mysql-test/r/sp.result: Test case for BUG#1656 mysql-test/t/sp.test: Test case for BUG#1656 --- mysql-test/r/sp.result | 11 +++++++++++ mysql-test/t/sp.test | 17 +++++++++++++++++ sql/sp_head.cc | 18 ++++++++++-------- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 05bb2348442..c5cd1c6a1b9 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -653,6 +653,17 @@ less 2 more 17 delete from t1; drop procedure bug1547; +drop table if exists t70; +create table t70 (s1 int,s2 int); +insert into t70 values (1,2); +create procedure bug1656(out p1 int, out p2 int) +select * into p1, p1 from t70; +call bug1656(@1, @2); +select @1, @2; +@1 @2 +2 NULL +drop table t70; +drop procedure bug1656; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ebc07f8fca8..83fabcce34e 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -764,6 +764,23 @@ select * from t1| delete from t1| drop procedure bug1547| +# +# BUG#1656 +# +--disable_warnings +drop table if exists t70| +--enable_warnings +create table t70 (s1 int,s2 int)| +insert into t70 values (1,2)| + +create procedure bug1656(out p1 int, out p2 int) + select * into p1, p1 from t70| + +call bug1656(@1, @2)| +select @1, @2| +drop table t70| +drop procedure bug1656| + # # Some "real" examples diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 88d81f25a76..88bd299ccd5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -373,6 +373,7 @@ sp_head::execute_procedure(THD *thd, List *args) if (csize > 0 || hmax > 0 || cmax > 0) { + Item_null *nit= NULL; // Re-use this, and only create if needed uint i; List_iterator_fast li(*args); Item *it; @@ -393,7 +394,11 @@ sp_head::execute_procedure(THD *thd, List *args) else { if (pvar->mode == sp_param_out) - nctx->push_item(NULL); // OUT + { + if (! nit) + nit= new Item_null(); + nctx->push_item(nit); // OUT + } else nctx->push_item(sp_eval_func_item(thd, it,pvar->type)); // IN or INOUT // Note: If it's OUT or INOUT, it must be a variable. @@ -411,14 +416,11 @@ sp_head::execute_procedure(THD *thd, List *args) // The rest of the frame are local variables which are all IN. // Default all variables to null (those with default clauses will // be set by an set instruction). + for (; i < csize ; i++) { - Item_null *nit= NULL; // Re-use this, and only create if needed - for (; i < csize ; i++) - { - if (! nit) - nit= new Item_null(); - nctx->push_item(nit); - } + if (! nit) + nit= new Item_null(); + nctx->push_item(nit); } thd->spcont= nctx; } -- cgit v1.2.1 From 6ec8273477f039cdac4ae8fb8614df771bbebce5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Oct 2003 21:39:55 +0000 Subject: Worklog #1280, (Stage 1 Implementation) This is a starting work to remove handler name dependencies from the Lex/Parser. sql/handler.h: WorkLog #1280, Stage 1 sql/lex.h: WorkLog #1280, Stage 1 sql/sql_yacc.yy: WorkLog #1280, Stage 1 sql/handler.cc: Use latin1 for string comparison BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + sql/handler.cc | 43 +++++++++++++++++++++++++++++++++++++++---- sql/handler.h | 1 + sql/lex.h | 6 ------ sql/sql_yacc.yy | 25 ++++++++----------------- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index df738f87479..7f15c86a343 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -5,6 +5,7 @@ Administrator@fred. Miguel@light.local Sinisa@sinisa.nasamreza.org WAX@sergbook.mysql.com +acurtis@pcgem.rdg.cyberkinetica.com administrador@light.hegel.local ahlentz@co3064164-a.rochd1.qld.optusnet.com.au akishkin@work.mysql.com diff --git a/sql/handler.cc b/sql/handler.cc index e14e326792d..0dc6860e207 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -70,6 +70,37 @@ const char *tx_isolation_names[] = TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", tx_isolation_names}; +enum db_type ha_resolve_by_name(char *name, uint namelen) +{ + enum db_type result = DB_TYPE_UNKNOWN; + if (!my_strcasecmp(&my_charset_latin1, name, "HEAP") || + !my_strcasecmp(&my_charset_latin1, name, "MEMORY")) { + result = DB_TYPE_HEAP; + } else + if (!my_strcasecmp(&my_charset_latin1, name, "MRG_MYISAM") || + !my_strcasecmp(&my_charset_latin1, name, "MERGE")) { + result = DB_TYPE_MRG_MYISAM; + } else + if (!my_strcasecmp(&my_charset_latin1, name, "MYISAM")) { + result = DB_TYPE_MYISAM; + } else + if (!my_strcasecmp(&my_charset_latin1, name, "BDB") || + !my_strcasecmp(&my_charset_latin1, name, "BERKELEYDB")) { + result = DB_TYPE_BERKELEY_DB; + } else + if (!my_strcasecmp(&my_charset_latin1, name, "INNODB") || + !my_strcasecmp(&my_charset_latin1, name, "INNOBASE")) { + result = DB_TYPE_INNODB; + } else + if (!my_strcasecmp(&my_charset_latin1, name, "ISAM")) { + result = DB_TYPE_ISAM; + } else + if (!my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { + result = (enum db_type) current_thd->variables.table_type; + } + return result; +} + /* Use other database handler if databasehandler is not incompiled */ enum db_type ha_checktype(enum db_type database_type) @@ -77,18 +108,21 @@ enum db_type ha_checktype(enum db_type database_type) switch (database_type) { #ifdef HAVE_BERKELEY_DB case DB_TYPE_BERKELEY_DB: - return(berkeley_skip ? DB_TYPE_MYISAM : database_type); + if (berkeley_skip) break; + return (database_type); #endif #ifdef HAVE_INNOBASE_DB case DB_TYPE_INNODB: - return(innodb_skip ? DB_TYPE_MYISAM : database_type); + if (innodb_skip) break; + return (database_type); #endif #ifndef NO_HASH case DB_TYPE_HASH: #endif #ifdef HAVE_ISAM case DB_TYPE_ISAM: - return (isam_skip ? DB_TYPE_MYISAM : database_type); + if (isam_skip) break; + return (database_type); case DB_TYPE_MRG_ISAM: return (isam_skip ? DB_TYPE_MRG_MYISAM : database_type); #else @@ -102,7 +136,8 @@ enum db_type ha_checktype(enum db_type database_type) default: break; } - return(DB_TYPE_MYISAM); /* Use this as default */ + /* Use this as default */ + return((enum db_type) current_thd->variables.table_type); } /* ha_checktype */ diff --git a/sql/handler.h b/sql/handler.h index b74e06c6edf..36ac2365291 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -378,6 +378,7 @@ extern TYPELIB ha_table_typelib, tx_isolation_typelib; #define ha_supports_generate(T) (T != DB_TYPE_INNODB) +enum db_type ha_resolve_by_name(char *name, uint namelen); handler *get_new_handler(TABLE *table, enum db_type db_type); my_off_t ha_get_ptr(byte *ptr, uint pack_length); void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos); diff --git a/sql/lex.h b/sql/lex.h index a5830ac8620..b429c5b409c 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -194,7 +194,6 @@ static SYMBOL symbols[] = { { "HAVING", SYM(HAVING),0,0}, { "HANDLER", SYM(HANDLER_SYM),0,0}, { "HASH", SYM(HASH_SYM),0,0}, - { "HEAP", SYM(HEAP_SYM),0,0}, { "HELP", SYM(HELP_SYM),0,0}, { "HIGH_PRIORITY", SYM(HIGH_PRIORITY),0,0}, { "HOUR", SYM(HOUR_SYM),0,0}, @@ -228,7 +227,6 @@ static SYMBOL symbols[] = { { "IF", SYM(IF),0,0}, { "IS", SYM(IS),0,0}, { "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}, @@ -280,9 +278,7 @@ static SYMBOL symbols[] = { { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, { "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0}, { "MEDIUMINT", SYM(MEDIUMINT),0,0}, - { "MERGE", SYM(MERGE_SYM),0,0}, { "MEDIUM", SYM(MEDIUM_SYM),0,0}, - { "MEMORY", SYM(MEMORY_SYM),0,0}, { "MICROSECOND", SYM(MICROSECOND_SYM),0,0}, { "MIDDLEINT", SYM(MEDIUMINT),0,0}, /* For powerbuilder */ { "MIN_ROWS", SYM(MIN_ROWS),0,0}, @@ -296,8 +292,6 @@ static SYMBOL symbols[] = { { "MULTILINESTRING", SYM(MULTILINESTRING),0,0}, { "MULTIPOINT", SYM(MULTIPOINT),0,0}, { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0}, - { "MRG_MYISAM", SYM(MERGE_SYM),0,0}, - { "MYISAM", SYM(MYISAM_SYM),0,0}, { "NAMES", SYM(NAMES_SYM),0,0}, { "NATURAL", SYM(NATURAL),0,0}, { "NATIONAL", SYM(NATIONAL_SYM),0,0}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c488b43ee6b..012ddaac66f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -254,7 +254,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token GROUP %token HAVING %token HASH_SYM -%token HEAP_SYM %token HEX_NUM %token HIGH_PRIORITY %token HOSTS_SYM @@ -269,7 +268,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token INTO %token IN_SYM %token ISOLATION -%token ISAM_SYM %token JOIN_SYM %token KEYS %token KEY_SYM @@ -309,10 +307,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token MAX_QUERIES_PER_HOUR %token MAX_UPDATES_PER_HOUR %token MEDIUM_SYM -%token MERGE_SYM -%token MEMORY_SYM %token MIN_ROWS -%token MYISAM_SYM %token NAMES_SYM %token NATIONAL_SYM %token NATURAL @@ -1963,13 +1958,14 @@ create_table_option: | INDEX DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; }; table_types: - ISAM_SYM { $$= DB_TYPE_ISAM; } - | MYISAM_SYM { $$= DB_TYPE_MYISAM; } - | MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; } - | HEAP_SYM { $$= DB_TYPE_HEAP; } - | MEMORY_SYM { $$= DB_TYPE_HEAP; } - | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } - | INNOBASE_SYM { $$= DB_TYPE_INNODB; }; + ident_or_text + { + $$ = ha_resolve_by_name($1.str,$1.length); + if ($$ == DB_TYPE_UNKNOWN) { + net_printf(YYTHD, ER_UNKNOWN_TABLE, $1.str); + YYABORT; + } + }; row_types: DEFAULT { $$= ROW_TYPE_DEFAULT; } @@ -5502,14 +5498,12 @@ keyword: | GLOBAL_SYM {} | HANDLER_SYM {} | HASH_SYM {} - | HEAP_SYM {} | HELP_SYM {} | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} | INDEXES {} | ISOLATION {} - | ISAM_SYM {} | ISSUER_SYM {} | INNOBASE_SYM {} | INSERT_METHOD {} @@ -5540,8 +5534,6 @@ keyword: | MAX_QUERIES_PER_HOUR {} | MAX_UPDATES_PER_HOUR {} | MEDIUM_SYM {} - | MERGE_SYM {} - | MEMORY_SYM {} | MICROSECOND_SYM {} | MINUTE_SYM {} | MIN_ROWS {} @@ -5551,7 +5543,6 @@ keyword: | MULTILINESTRING {} | MULTIPOINT {} | MULTIPOLYGON {} - | MYISAM_SYM {} | NAMES_SYM {} | NATIONAL_SYM {} | NCHAR_SYM {} -- cgit v1.2.1 From 43289bef37ed464de401735a5c9df9914f5862cb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Oct 2003 10:25:45 +0100 Subject: Added more error handling for abnormal cases (like a broken mysql.proc table). sql/sp.cc: Added more error handling for abnormal cases (like a broken mysql.proc table), and made the field indexing clearer, using defines instead of explicit numbers. --- sql/sp.cc | 60 ++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 7076778532f..6ca020b5eaa 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -26,7 +26,17 @@ * */ -// *opened=true means we opened ourselves +#define MYSQL_PROC_FIELD_NAME 0 +#define MYSQL_PROC_FIELD_TYPE 1 +#define MYSQL_PROC_FIELD_DEFINITION 2 +#define MYSQL_PROC_FIELD_CREATOR 3 +#define MYSQL_PROC_FIELD_MODIFIED 4 +#define MYSQL_PROC_FIELD_CREATED 5 +#define MYSQL_PROC_FIELD_SUID 6 +#define MYSQL_PROC_FIELD_COMMENT 7 +#define MYSQL_PROC_FIELD_COUNT 8 + +/* *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) @@ -102,23 +112,33 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) 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) + + if (table->fields != MYSQL_PROC_FIELD_COUNT) + { + ret= SP_GET_FIELD_FAILED; + goto done; + } + + if ((defstr= get_field(&thd->mem_root, + table->field[MYSQL_PROC_FIELD_DEFINITION])) == NULL) { ret= SP_GET_FIELD_FAILED; goto done; } // Get additional information - if ((creator= get_field(&thd->mem_root, table->field[3])) == NULL) + if ((creator= get_field(&thd->mem_root, + table->field[MYSQL_PROC_FIELD_CREATOR])) == NULL) { ret= SP_GET_FIELD_FAILED; goto done; } - modified= table->field[4]->val_int(); - created= table->field[5]->val_int(); + modified= table->field[MYSQL_PROC_FIELD_MODIFIED]->val_int(); + created= table->field[MYSQL_PROC_FIELD_CREATED]->val_int(); - if ((ptr= get_field(&thd->mem_root, table->field[6])) == NULL) + if ((ptr= get_field(&thd->mem_root, + table->field[MYSQL_PROC_FIELD_SUID])) == NULL) { ret= SP_GET_FIELD_FAILED; goto done; @@ -126,7 +146,8 @@ 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[MYSQL_PROC_FIELD_COMMENT]->val_str(&str, &str); + ptr= 0; if ((length= str.length())) ptr= strmake_root(&thd->mem_root, str.ptr(), length); @@ -195,15 +216,25 @@ db_create_routine(THD *thd, int type, restore_record(table, default_values); // 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); - ((Field_timestamp *)table->field[5])->set_time(); + if (table->fields != MYSQL_PROC_FIELD_COUNT) + { + ret= SP_GET_FIELD_FAILED; + goto done; + } + table->field[MYSQL_PROC_FIELD_NAME]->store(name, namelen, + system_charset_info); + table->field[MYSQL_PROC_FIELD_TYPE]->store((longlong)type); + table->field[MYSQL_PROC_FIELD_DEFINITION]->store(def, deflen, + system_charset_info); + table->field[MYSQL_PROC_FIELD_CREATOR]->store(creator, + (uint)strlen(creator), + system_charset_info); + ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time(); if (suid) - table->field[6]->store((longlong)suid); + table->field[MYSQL_PROC_FIELD_SUID]->store((longlong)suid); if (comment) - table->field[7]->store(comment, commentlen, system_charset_info); + table->field[MYSQL_PROC_FIELD_COMMENT]->store(comment, commentlen, + system_charset_info); if (table->file->write_row(table->record[0])) ret= SP_WRITE_ROW_FAILED; @@ -211,6 +242,7 @@ db_create_routine(THD *thd, int type, ret= SP_OK; } +done: close_thread_tables(thd); DBUG_RETURN(ret); } -- cgit v1.2.1 From 2e6484f5832757ba2ef6d5416ae79d466b6679f6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Oct 2003 16:26:08 +0000 Subject: Revert behaviour change introduced in WL1280. Fixes tests. sql/handler.cc: Revert behaviour to pass tests --- sql/handler.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/handler.cc b/sql/handler.cc index 817aac85876..3a8ea107735 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -137,7 +137,11 @@ enum db_type ha_checktype(enum db_type database_type) break; } /* Use this as default */ +#if 0 return((enum db_type) current_thd->variables.table_type); +#else + return(DB_TYPE_MYISAM); +#endif } /* ha_checktype */ -- cgit v1.2.1 From c9232c60e2ec287932158b6d820352dd98e85fd7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Nov 2003 19:34:56 +0100 Subject: Various bug fixes: - Duplicate parameters/variables, conditions and cursors (not allowed). - ITERATE in labelled BEGIN-END (not allowed). - Missing SQLSTATE [VALUE] keywords in CONDITION/HANDLER declaration (added). - Empty BEGIN-END (now allowed). - End label (now optional). include/mysqld_error.h: New error code for duplicate things (vars et al) in SPs. mysql-test/r/sp-error.result: New error tests for ITERATE in begin-end block and duplicate variables, conditions and cursors. mysql-test/r/sp.result: New tests for empty begin-end blocks, overriding local variables outside scope only, leave a begin-end block, and SQLSTATE [VALUE] words for CONDITION/HANDLER declarations. mysql-test/t/sp-error.test: New error tests for ITERATE in begin-end block and duplicate variables, conditions and cursors. mysql-test/t/sp.test: New tests for empty begin-end blocks, overriding local variables outside scope only, leave a begin-end block, and SQLSTATE [VALUE] words for CONDITION/HANDLER declarations. sql/lex.h: New SQLSTATE keyword. sql/share/czech/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/danish/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/dutch/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/english/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/estonian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/french/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/german/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/greek/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/hungarian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/italian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/japanese/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/korean/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/norwegian-ny/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/norwegian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/polish/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/portuguese/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/romanian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/russian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/serbian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/slovak/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/spanish/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/swedish/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/share/ukrainian/errmsg.txt: New error message for duplicate things (vars et al) in SPs. sql/sp_pcontext.cc: Keep track on scope limits for error checking of duplicate variables, conditions and cursors. sql/sp_pcontext.h: Keep track on scope limits for error checking of duplicate variables, conditions and cursors. Also need to flag BEGIN labels to check for illegal ITERATEs. sql/sql_yacc.yy: End-labels in SPs loop and begin-end blocks are now optional. SQLSTATE [VALUE] added to syntax for sqlstates. Check for duplicate variable, condition and cursor declarations, but only in the same scope. Empty BEGIN-END statements now allowed. Check if ITERATE is referring to a BEGIN label. --- include/mysqld_error.h | 3 +- mysql-test/r/sp-error.result | 31 ++++++++++ mysql-test/r/sp.result | 37 +++++++++++- mysql-test/t/sp-error.test | 32 ++++++++++ mysql-test/t/sp.test | 47 ++++++++++++++- sql/lex.h | 1 + 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_pcontext.cc | 67 ++++++++++++++++++--- sql/sp_pcontext.h | 20 ++++++- sql/sql_yacc.yy | 119 +++++++++++++++++++++++++++++--------- 32 files changed, 336 insertions(+), 44 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index f12cdda257a..4304235055f 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -323,4 +323,5 @@ #define ER_SP_UNDECLARED_VAR 1304 #define ER_SP_WRONG_NO_OF_FETCH_ARGS 1305 #define ER_SP_FETCH_NO_DATA 1306 -#define ER_ERROR_MESSAGES 307 +#define ER_SP_DUP_THING 1307 +#define ER_ERROR_MESSAGES 308 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 4cd1c4c961c..2ece3e61d1d 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -47,6 +47,11 @@ iterate bar; end loop; ERROR HY000: ITERATE with no matching label: bar create procedure foo() +foo: begin +iterate foo; +end; +ERROR HY000: ITERATE with no matching label: foo +create procedure foo() foo: loop foo: loop set @x=2; @@ -219,4 +224,30 @@ end; call p(); ERROR HY000: Wrong number of FETCH variables drop procedure p; +create procedure p(in x int, x char(10)) +begin +end; +ERROR HY000: Duplicate parameter: x +create function p(x int, x char(10)) +begin +end; +ERROR HY000: Duplicate parameter: x +create procedure p() +begin +declare x float; +declare x int; +end; +ERROR HY000: Duplicate parameter: x +create procedure p() +begin +declare c condition for 1064; +declare c condition for 1065; +end; +ERROR HY000: Duplicate condition: c +create procedure p() +begin +declare c cursor for select * from t1; +declare c cursor for select field from t1; +end; +ERROR HY000: Duplicate cursor: c drop table t1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index c5cd1c6a1b9..4f66dafbe81 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -36,6 +36,20 @@ select * from t1; id data bar 666 delete from t1; +create procedure empty() +begin +end; +call empty(); +drop procedure empty; +create procedure scope(a int, b float) +begin +declare b int; +declare c float; +begin +declare c int; +end; +end; +drop procedure scope; create procedure two(x1 char(16), x2 char(16), y int) begin insert into test.t1 values (x1, y); @@ -256,7 +270,7 @@ insert into test.t1 values ("d", x); set x = x-1; leave hmm; insert into test.t1 values ("x", x); -end while hmm; +end while; call d(3); select * from t1; id data @@ -335,6 +349,21 @@ h1 1 h? 17 delete from t1; drop procedure h; +create procedure i(x int) +foo: +begin +if x = 0 then +leave foo; +end if; +insert into test.t1 values ("i", x); +end foo; +call i(0); +call i(3); +select * from t1; +id data +i 3 +delete from t1; +drop procedure i; create procedure into_test(x char(16), y int) begin insert into test.t1 values (x, y); @@ -461,6 +490,8 @@ create procedure hndlr1(val int) begin declare x int default 0; declare foo condition for 1146; +declare bar condition for sqlstate '42S98'; # Just for testing syntax +declare zip condition for sqlstate value '42S99'; # Just for testing syntax declare continue handler for foo set x = 1; insert into test.t666 values ("hndlr1", val); # Non-existing table if (x) then @@ -477,7 +508,7 @@ create procedure hndlr2(val int) begin declare x int default 0; begin -declare exit handler for '42S02' set x = 1; +declare exit handler for sqlstate '42S02' set x = 1; insert into test.t666 values ("hndlr2", val); # Non-existing table end; insert into test.t1 values ("hndlr2", x); @@ -744,7 +775,7 @@ end if; set s = s+1; end; end if; -end loop again; +end loop; end; create procedure ip(m int unsigned) begin diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 7c541029452..09a1e196786 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -74,6 +74,11 @@ create procedure foo() foo: loop iterate bar; end loop| +--error 1285 +create procedure foo() +foo: begin + iterate foo; +end| # Redefining label --error 1286 @@ -298,6 +303,33 @@ end| call p()| drop procedure p| +--error 1307 +create procedure p(in x int, x char(10)) +begin +end| +--error 1307 +create function p(x int, x char(10)) +begin +end| +--error 1307 +create procedure p() +begin + declare x float; + declare x int; +end| +--error 1307 +create procedure p() +begin + declare c condition for 1064; + declare c condition for 1065; +end| +--error 1307 +create procedure p() +begin + declare c cursor for select * from t1; + declare c cursor for select field from t1; +end| + drop table t1| delimiter ;| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 83fabcce34e..b9f62d4fb0a 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -59,6 +59,28 @@ delete from t1; # Now for multiple statements... delimiter |; +# Empty statement +create procedure empty() +begin +end| + +call empty()| +drop procedure empty| + +# Scope test. This is legal (warnings might be possible in the future, +# but for the time being, we just accept it). +create procedure scope(a int, b float) +begin + declare b int; + declare c float; + + begin + declare c int; + end; +end| + +drop procedure scope| + # Two statements. create procedure two(x1 char(16), x2 char(16), y int) begin @@ -313,7 +335,7 @@ hmm: while x > 0 do set x = x-1; leave hmm; insert into test.t1 values ("x", x); -end while hmm| +end while| call d(3)| select * from t1| @@ -393,6 +415,23 @@ delete from t1| drop procedure h| +# It's actually possible to LEAVE a BEGIN-END block +create procedure i(x int) +foo: +begin + if x = 0 then + leave foo; + end if; + insert into test.t1 values ("i", x); +end foo| + +call i(0)| +call i(3)| +select * from t1| +delete from t1| +drop procedure i| + + # SELECT INTO local variables create procedure into_test(x char(16), y int) begin @@ -543,6 +582,8 @@ create procedure hndlr1(val int) begin declare x int default 0; declare foo condition for 1146; + declare bar condition for sqlstate '42S98'; # Just for testing syntax + declare zip condition for sqlstate value '42S99'; # Just for testing syntax declare continue handler for foo set x = 1; insert into test.t666 values ("hndlr1", val); # Non-existing table @@ -561,7 +602,7 @@ begin declare x int default 0; begin - declare exit handler for '42S02' set x = 1; + declare exit handler for sqlstate '42S02' set x = 1; insert into test.t666 values ("hndlr2", val); # Non-existing table end; @@ -864,7 +905,7 @@ begin set s = s+1; end; end if; - end loop again; + end loop; end| create procedure ip(m int unsigned) diff --git a/sql/lex.h b/sql/lex.h index 8fbf504076b..f4368cacb5d 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -386,6 +386,7 @@ static SYMBOL symbols[] = { { "SPATIAL", SYM(SPATIAL_SYM),0,0}, { "SPECIFIC", SYM(SPECIFIC_SYM),0,0}, { "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM),0,0}, + { "SQLSTATE", SYM(SQLSTATE_SYM),0,0}, { "SQLWARNING", SYM(SQLWARNING_SYM),0,0}, { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT),0,0}, { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT),0,0}, diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 7e992880c45..1f85a5fb84b 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -319,3 +319,4 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index b2bb5f58525..f66b1492433 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -313,3 +313,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index f8e5fafa198..d4ea5803390 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -321,3 +321,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 085a1e7389f..b52762aaac9 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -310,3 +310,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index b70649390b6..18201380fbd 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -315,3 +315,4 @@ character-set=latin7 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 10c3c72c371..c5912d59d23 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -310,3 +310,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 37d15882798..cc3a9d88a45 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 9ea7b97f07f..b64a1971e35 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -310,3 +310,4 @@ character-set=greek "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 99246b28298..911cf3a09b6 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -312,3 +312,4 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 18ecc9e4539..152bd2dd922 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -310,3 +310,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index e17cfa9c315..963642a6348 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -312,3 +312,4 @@ character-set=ujis "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 9e1e85c959b..7f721cd999e 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -310,3 +310,4 @@ character-set=euckr "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 798434f9720..ab9c428e3b0 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -312,3 +312,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 58f607b91ae..29e14d3b580 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -312,3 +312,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 4770cd5332e..c0caecfd5a0 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index e0d93563665..4044abdbcb2 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -311,3 +311,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index d715847c27e..1fdcec122b8 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index d96a4fca293..9736cf23d2b 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -312,3 +312,4 @@ character-set=koi8r "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index cb6645dd67f..d95500183f0 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -305,3 +305,4 @@ character-set=cp1250 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 6f1f6a7e267..2cf355e2659 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -318,3 +318,4 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index ceb0458a2ac..53d3c26b990 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -312,3 +312,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index bb2711fd0b3..ac9ac52c0f3 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -310,3 +310,4 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 5cdac39ce93..3e3e06d31ea 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -315,3 +315,4 @@ character-set=koi8u "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" +"Duplicate %s: %s" diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 3730230d47d..b7e23c9f5ad 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -32,6 +32,7 @@ sp_pcontext::sp_pcontext() VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8)); VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8)); VOID(my_init_dynamic_array(&m_cursor, sizeof(LEX_STRING), 16, 8)); + VOID(my_init_dynamic_array(&m_scopes, sizeof(sp_scope_t), 16, 8)); m_label.empty(); } @@ -41,23 +42,52 @@ sp_pcontext::destroy() delete_dynamic(&m_pvar); delete_dynamic(&m_cond); delete_dynamic(&m_cursor); + delete_dynamic(&m_scopes); m_label.empty(); } +void +sp_pcontext::push_scope() +{ + sp_scope_t s; + + s.vars= m_pvar.elements; + s.conds= m_cond.elements; + s.curs= m_cursor.elements; + insert_dynamic(&m_scopes, (gptr)&s); +} + +void +sp_pcontext::pop_scope() +{ + (void)pop_dynamic(&m_scopes); +} + /* 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. +** ...and, this is only called during parsing. */ sp_pvar_t * -sp_pcontext::find_pvar(LEX_STRING *name) +sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped) { uint i = m_pvar.elements; + uint limit; - while (i-- > 0) + if (! scoped || m_scopes.elements == 0) + limit= 0; + else + { + sp_scope_t s; + + get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1); + limit= s.vars; + } + + while (i-- > limit) { sp_pvar_t *p; @@ -101,6 +131,7 @@ sp_pcontext::push_label(char *name, uint ip) { lab->name= name; lab->ip= ip; + lab->isbegin= FALSE; m_label.push_front(lab); } return lab; @@ -137,11 +168,22 @@ sp_pcontext::push_cond(LEX_STRING *name, sp_cond_type_t *val) * See comment for find_pvar() above */ sp_cond_type_t * -sp_pcontext::find_cond(LEX_STRING *name) +sp_pcontext::find_cond(LEX_STRING *name, my_bool scoped) { uint i = m_cond.elements; + uint limit; - while (i-- > 0) + if (! scoped || m_scopes.elements == 0) + limit= 0; + else + { + sp_scope_t s; + + get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1); + limit= s.conds; + } + + while (i-- > limit) { sp_cond_t *p; @@ -172,11 +214,22 @@ sp_pcontext::push_cursor(LEX_STRING *name) * See comment for find_pvar() above */ my_bool -sp_pcontext::find_cursor(LEX_STRING *name, uint *poff) +sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped) { uint i = m_cursor.elements; + uint limit; + + if (! scoped || m_scopes.elements == 0) + limit= 0; + else + { + sp_scope_t s; - while (i-- > 0) + get_dynamic(&m_scopes, (gptr)&s, m_scopes.elements-1); + limit= s.curs; + } + + while (i-- > limit) { LEX_STRING n; diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 23be38edcbf..02134e3604f 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -42,6 +42,7 @@ typedef struct sp_label { char *name; uint ip; // Instruction index + my_bool isbegin; // For ITERATE error checking } sp_label_t; typedef struct sp_cond_type @@ -57,6 +58,11 @@ typedef struct sp_cond sp_cond_type_t *val; } sp_cond_t; +typedef struct sp_scope +{ + uint vars, conds, curs; +} sp_scope_t; + class sp_pcontext : public Sql_alloc { sp_pcontext(const sp_pcontext &); /* Prevent use of these */ @@ -70,6 +76,13 @@ class sp_pcontext : public Sql_alloc void destroy(); + // For error checking of duplicate things + void + push_scope(); + + void + pop_scope(); + // // Parameters and variables // @@ -130,7 +143,7 @@ class sp_pcontext : public Sql_alloc // Find by name sp_pvar_t * - find_pvar(LEX_STRING *name); + find_pvar(LEX_STRING *name, my_bool scoped=0); // Find by index sp_pvar_t * @@ -182,7 +195,7 @@ class sp_pcontext : public Sql_alloc } sp_cond_type_t * - find_cond(LEX_STRING *name); + find_cond(LEX_STRING *name, my_bool scoped=0); // // Handlers @@ -208,7 +221,7 @@ class sp_pcontext : public Sql_alloc push_cursor(LEX_STRING *name); my_bool - find_cursor(LEX_STRING *name, uint *poff); + find_cursor(LEX_STRING *name, uint *poff, my_bool scoped=0); inline void pop_cursor(uint num) @@ -233,6 +246,7 @@ private: DYNAMIC_ARRAY m_pvar; // Parameters/variables DYNAMIC_ARRAY m_cond; // Conditions DYNAMIC_ARRAY m_cursor; // Cursors + DYNAMIC_ARRAY m_scopes; // For error checking List m_label; // The label list diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3eaaa4e1414..391cac37ceb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -371,6 +371,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SPATIAL_SYM %token SPECIFIC_SYM %token SQLEXCEPTION_SYM +%token SQLSTATE_SYM %token SQLWARNING_SYM %token SSL_SYM %token STARTING @@ -618,7 +619,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component - SP_FUNC ident_or_spfunc + SP_FUNC ident_or_spfunc sp_opt_label %type opt_table_alias @@ -1149,7 +1150,15 @@ sp_fdparams: sp_fdparam: ident type sp_opt_locator { - Lex->spcont->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$1, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $1.str); + YYABORT; + } + spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); } ; @@ -1167,9 +1176,16 @@ sp_pdparams: sp_pdparam: sp_opt_inout ident type sp_opt_locator { - Lex->spcont->push_pvar(&$2, - (enum enum_field_types)$3, - (sp_param_mode_t)$1); + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$2, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $2.str); + YYABORT; + } + spc->push_pvar(&$2, (enum enum_field_types)$3, + (sp_param_mode_t)$1); } ; @@ -1186,7 +1202,7 @@ sp_opt_locator: ; sp_proc_stmts: - sp_proc_stmt ';' + /* Empty */ {} | sp_proc_stmts sp_proc_stmt ';' ; @@ -1231,6 +1247,14 @@ sp_decl: } | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_cond(&$2, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_THING, "condition", $2.str); + YYABORT; + } YYTHD->lex->spcont->push_cond(&$2, $5); $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; @@ -1272,8 +1296,16 @@ sp_decl: { LEX *lex= Lex; sp_head *sp= lex->sphead; - sp_instr_cpush *i= new sp_instr_cpush(sp->instructions(), $5); + sp_pcontext *spc= lex->spcont; + uint offp; + sp_instr_cpush *i; + if (spc->find_cursor(&$2, &offp, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_THING, "cursor", $2.str); + YYABORT; + } + i= new sp_instr_cpush(sp->instructions(), $5); sp->add_instr(i); lex->spcont->push_cursor(&$2); $$.vars= $$.conds= $$.hndlrs= 0; @@ -1344,18 +1376,23 @@ sp_cond: $$->type= sp_cond_type_t::number; $$->mysqlerr= $1; } - | TEXT_STRING_literal + | SQLSTATE_SYM opt_value TEXT_STRING_literal { /* SQLSTATE */ - uint len= ($1.length < sizeof($$->sqlstate)-1 ? - $1.length : sizeof($$->sqlstate)-1); + uint len= ($3.length < sizeof($$->sqlstate)-1 ? + $3.length : sizeof($$->sqlstate)-1); $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); $$->type= sp_cond_type_t::state; - memcpy($$->sqlstate, $1.str, len); + memcpy($$->sqlstate, $3.str, len); $$->sqlstate[len]= '\0'; } ; +opt_value: + /* Empty */ {} + | VALUE_SYM {} + ; + sp_hcond: sp_cond { @@ -1390,12 +1427,28 @@ sp_hcond: sp_decl_idents: ident { - Lex->spcont->push_pvar(&$1, (enum_field_types)0, sp_param_in); + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$1, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $1.str); + YYABORT; + } + spc->push_pvar(&$1, (enum_field_types)0, sp_param_in); $$= 1; } | sp_decl_idents ',' ident { - Lex->spcont->push_pvar(&$3, (enum_field_types)0, sp_param_in); + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$3, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $3.str); + YYABORT; + } + spc->push_pvar(&$3, (enum_field_types)0, sp_param_in); $$= $1 + 1; } ; @@ -1532,7 +1585,7 @@ sp_proc_stmt: LEX *lex= Lex; sp_label_t *lab= lex->spcont->find_label($2.str); - if (! lab) + if (! lab || lab->isbegin) { net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE", $2.str); YYABORT; @@ -1736,32 +1789,43 @@ sp_labeled_control: lex->sphead->instructions()); } } - sp_unlabeled_control IDENT + sp_unlabeled_control sp_opt_label { LEX *lex= Lex; - sp_label_t *lab= lex->spcont->find_label($5.str); - if (!lab || - my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) + if ($5.str) { - net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); - YYABORT; - } - else - { - lex->spcont->pop_label(); - lex->sphead->backpatch(lab); + sp_label_t *lab= lex->spcont->find_label($5.str); + + if (!lab || + my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) + { + net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); + YYABORT; + } } + lex->sphead->backpatch(lex->spcont->pop_label()); } ; +sp_opt_label: + /* Empty */ + { $$.str= NULL; $$.length= 0; } + | IDENT + { $$= $1; } + ; + sp_unlabeled_control: BEGIN_SYM { /* 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 *lex= Lex; + sp_label_t *lab= lex->spcont->last_label(); - Lex->spcont->push_label((char *)"", 0); /* For end of block */ + lab->isbegin= TRUE; + /* Scope duplicate checking */ + lex->spcont->push_scope(); } sp_decls sp_proc_stmts @@ -1771,7 +1835,7 @@ sp_unlabeled_control: sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; - sp->backpatch(ctx->pop_label()); + sp->backpatch(ctx->last_label()); /* We always has a label */ ctx->pop_pvar($3.vars); ctx->pop_cond($3.conds); ctx->pop_cursor($3.curs); @@ -1779,6 +1843,7 @@ sp_unlabeled_control: sp->add_instr(new sp_instr_hpop(sp->instructions(),$3.hndlrs)); if ($3.curs) sp->add_instr(new sp_instr_cpop(sp->instructions(), $3.curs)); + ctx->pop_scope(); } | LOOP_SYM sp_proc_stmts END LOOP_SYM -- cgit v1.2.1 From 7b4a85050b59f6148e8ab4e6f3ae92aa1427f170 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Nov 2003 13:46:50 +0100 Subject: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) Also fixed memory leak when aborting parsing for a duplicate cursor. include/mysqld_error.h: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) mysql-test/r/sp-error.result: Fixed error message for duplicate variable. mysql-test/t/sp-error.test: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/czech/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/danish/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/dutch/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/english/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/estonian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/french/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/german/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/greek/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/hungarian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/italian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/japanese/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/korean/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/norwegian-ny/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/norwegian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/polish/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/portuguese/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/romanian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/russian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/serbian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/slovak/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/spanish/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/swedish/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) sql/share/ukrainian/errmsg.txt: Changed single generic error code/message into different ones for duplicate things. (For multi-lingual support.) --- include/mysqld_error.h | 7 +++++-- mysql-test/r/sp-error.result | 2 +- mysql-test/t/sp-error.test | 9 ++++++--- sql/share/czech/errmsg.txt | 5 ++++- sql/share/danish/errmsg.txt | 5 ++++- sql/share/dutch/errmsg.txt | 5 ++++- sql/share/english/errmsg.txt | 5 ++++- sql/share/estonian/errmsg.txt | 5 ++++- sql/share/french/errmsg.txt | 5 ++++- sql/share/german/errmsg.txt | 5 ++++- sql/share/greek/errmsg.txt | 5 ++++- sql/share/hungarian/errmsg.txt | 5 ++++- sql/share/italian/errmsg.txt | 5 ++++- sql/share/japanese/errmsg.txt | 5 ++++- sql/share/korean/errmsg.txt | 5 ++++- sql/share/norwegian-ny/errmsg.txt | 5 ++++- sql/share/norwegian/errmsg.txt | 5 ++++- sql/share/polish/errmsg.txt | 5 ++++- sql/share/portuguese/errmsg.txt | 5 ++++- sql/share/romanian/errmsg.txt | 5 ++++- sql/share/russian/errmsg.txt | 5 ++++- sql/share/serbian/errmsg.txt | 5 ++++- sql/share/slovak/errmsg.txt | 5 ++++- sql/share/spanish/errmsg.txt | 5 ++++- sql/share/swedish/errmsg.txt | 5 ++++- sql/share/ukrainian/errmsg.txt | 5 ++++- sql/sql_yacc.yy | 13 +++++++------ 27 files changed, 111 insertions(+), 35 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 4304235055f..4031d64602f 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -323,5 +323,8 @@ #define ER_SP_UNDECLARED_VAR 1304 #define ER_SP_WRONG_NO_OF_FETCH_ARGS 1305 #define ER_SP_FETCH_NO_DATA 1306 -#define ER_SP_DUP_THING 1307 -#define ER_ERROR_MESSAGES 308 +#define ER_SP_DUP_PARAM 1307 +#define ER_SP_DUP_VAR 1308 +#define ER_SP_DUP_COND 1309 +#define ER_SP_DUP_CURS 1310 +#define ER_ERROR_MESSAGES 311 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 2ece3e61d1d..82da4e0cb2e 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -237,7 +237,7 @@ begin declare x float; declare x int; end; -ERROR HY000: Duplicate parameter: x +ERROR HY000: Duplicate variable: x create procedure p() begin declare c condition for 1064; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 09a1e196786..d98385b42e0 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -311,19 +311,22 @@ end| create function p(x int, x char(10)) begin end| ---error 1307 + +--error 1308 create procedure p() begin declare x float; declare x int; end| ---error 1307 + +--error 1309 create procedure p() begin declare c condition for 1064; declare c condition for 1065; end| ---error 1307 + +--error 1310 create procedure p() begin declare c cursor for select * from t1; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 1f85a5fb84b..abad832511f 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -319,4 +319,7 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index f66b1492433..f3ee18e586f 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -313,4 +313,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index d4ea5803390..df1445d3758 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -321,4 +321,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index b52762aaac9..c38969b778c 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -310,4 +310,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 18201380fbd..885e9cd5c11 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -315,4 +315,7 @@ character-set=latin7 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index c5912d59d23..acb003fb8a4 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -310,4 +310,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index cc3a9d88a45..855db0ee094 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -322,4 +322,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index b64a1971e35..60e3adf5aae 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -310,4 +310,7 @@ character-set=greek "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 911cf3a09b6..aef2808cdd2 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -312,4 +312,7 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 152bd2dd922..429909cfa08 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -310,4 +310,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 963642a6348..1f7e4b4c103 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -312,4 +312,7 @@ character-set=ujis "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 7f721cd999e..ba2ab18f1f5 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -310,4 +310,7 @@ character-set=euckr "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index ab9c428e3b0..a72f78540f2 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -312,4 +312,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 29e14d3b580..8dbef326260 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -312,4 +312,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index c0caecfd5a0..60d7b4d83cf 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -314,4 +314,7 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 4044abdbcb2..95f959c4a18 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -311,4 +311,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 1fdcec122b8..976a897eb39 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -314,4 +314,7 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 9736cf23d2b..a446d69cd12 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -312,4 +312,7 @@ character-set=koi8r "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index d95500183f0..bd44ade9b72 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -305,4 +305,7 @@ character-set=cp1250 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 2cf355e2659..85bbced043b 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -318,4 +318,7 @@ character-set=latin2 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 53d3c26b990..ae76b53b130 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -312,4 +312,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index ac9ac52c0f3..5282e9e1fab 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -310,4 +310,7 @@ character-set=latin1 "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 3e3e06d31ea..2059e1f1cea 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -315,4 +315,7 @@ character-set=koi8u "Undeclared variable: %s" "Wrong number of FETCH variables" "No data to FETCH" -"Duplicate %s: %s" +"Duplicate parameter: %s" +"Duplicate variable: %s" +"Duplicate condition: %s" +"Duplicate cursor: %s" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 391cac37ceb..0af4b774615 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1155,7 +1155,7 @@ sp_fdparam: if (spc->find_pvar(&$1, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $1.str); + net_printf(YYTHD, ER_SP_DUP_PARAM, $1.str); YYABORT; } spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); @@ -1181,7 +1181,7 @@ sp_pdparam: if (spc->find_pvar(&$2, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $2.str); + net_printf(YYTHD, ER_SP_DUP_PARAM, $2.str); YYABORT; } spc->push_pvar(&$2, (enum enum_field_types)$3, @@ -1252,7 +1252,7 @@ sp_decl: if (spc->find_cond(&$2, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_THING, "condition", $2.str); + net_printf(YYTHD, ER_SP_DUP_COND, $2.str); YYABORT; } YYTHD->lex->spcont->push_cond(&$2, $5); @@ -1302,7 +1302,8 @@ sp_decl: if (spc->find_cursor(&$2, &offp, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_THING, "cursor", $2.str); + net_printf(YYTHD, ER_SP_DUP_CURS, $2.str); + delete $5; YYABORT; } i= new sp_instr_cpush(sp->instructions(), $5); @@ -1432,7 +1433,7 @@ sp_decl_idents: if (spc->find_pvar(&$1, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $1.str); + net_printf(YYTHD, ER_SP_DUP_VAR, $1.str); YYABORT; } spc->push_pvar(&$1, (enum_field_types)0, sp_param_in); @@ -1445,7 +1446,7 @@ sp_decl_idents: if (spc->find_pvar(&$3, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_THING, "parameter", $3.str); + net_printf(YYTHD, ER_SP_DUP_VAR, $3.str); YYABORT; } spc->push_pvar(&$3, (enum_field_types)0, sp_param_in); -- cgit v1.2.1 From 74e7758287c93fb3274a5b506cec143ba5ca1f5c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Nov 2003 13:33:47 +0100 Subject: Bugfix, handling null values. --- 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 88bd299ccd5..3a09869320f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -61,7 +61,7 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) } /* QQ How do we do this? Is there some better way? */ - if (type == MYSQL_TYPE_NULL) + if (type == MYSQL_TYPE_NULL || it->is_null()) it= new Item_null(); else { -- cgit v1.2.1 From 6c1a2b7fd21b1bc253d3fffa6082571e24fac104 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 17 Nov 2003 21:21:36 +0400 Subject: WL#1241: SHOW PROCEDURE/FUNCTION WL#1263: Support for the attributes COMMENT and SUID in CREATE/ALTER PROCEDURE/FUNCTION include/mysqld_error.h: Error code for 'alter procedure' mysql-test/r/sp-error.result: Test for WL#1241&WL#1263 mysql-test/r/sp.result: Test for WL#1241&WL#1263 mysql-test/t/sp-error.test: Test for WL#1241&WL#1263 mysql-test/t/sp.test: Test for WL#1241&WL#1263 sql/share/czech/errmsg.txt: Error massage for 'alter procedure' sql/share/danish/errmsg.txt: Error massage for 'alter procedure' sql/share/dutch/errmsg.txt: Error massage for 'alter procedure' sql/share/english/errmsg.txt: Error massage for 'alter procedure' sql/share/estonian/errmsg.txt: Error massage for 'alter procedure' sql/share/french/errmsg.txt: Error massage for 'alter procedure' sql/share/german/errmsg.txt: Error massage for 'alter procedure' sql/share/greek/errmsg.txt: Error massage for 'alter procedure' sql/share/hungarian/errmsg.txt: Error massage for 'alter procedure' sql/share/italian/errmsg.txt: Error massage for 'alter procedure' sql/share/japanese/errmsg.txt: Error massage for 'alter procedure' sql/share/korean/errmsg.txt: Error massage for 'alter procedure' sql/share/norwegian-ny/errmsg.txt: Error massage for 'alter procedure' sql/share/norwegian/errmsg.txt: Error massage for 'alter procedure' sql/share/polish/errmsg.txt: Error massage for 'alter procedure' sql/share/portuguese/errmsg.txt: Error massage for 'alter procedure' sql/share/romanian/errmsg.txt: Error massage for 'alter procedure' sql/share/russian/errmsg.txt: Error massage for 'alter procedure' sql/share/serbian/errmsg.txt: Error massage for 'alter procedure' sql/share/slovak/errmsg.txt: Error massage for 'alter procedure' sql/share/spanish/errmsg.txt: Error massage for 'alter procedure' sql/share/swedish/errmsg.txt: Error massage for 'alter procedure' sql/share/ukrainian/errmsg.txt: Error massage for 'alter procedure' --- include/mysqld_error.h | 3 +- mysql-test/r/sp-error.result | 5 + mysql-test/r/sp.result | 52 ++++++++ mysql-test/t/sp-error.test | 6 + mysql-test/t/sp.test | 18 +++ sql/lex.h | 4 + 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 | 261 +++++++++++++++++++++++++++++++++++++- sql/sp.h | 22 ++++ sql/sp_head.cc | 61 +++++++-- sql/sp_head.h | 22 +++- sql/sql_lex.h | 8 ++ sql/sql_parse.cc | 77 +++++++++-- sql/sql_yacc.yy | 70 +++++++++- 36 files changed, 600 insertions(+), 32 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 4031d64602f..196e4cd5154 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -327,4 +327,5 @@ #define ER_SP_DUP_VAR 1308 #define ER_SP_DUP_COND 1309 #define ER_SP_DUP_CURS 1310 -#define ER_ERROR_MESSAGES 311 +#define ER_SP_CANT_ALTER 1311 +#define ER_ERROR_MESSAGES 312 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 82da4e0cb2e..58905a74507 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -187,6 +187,11 @@ end; call p(); ERROR HY000: Cursor is not open drop procedure p; +alter procedure bar3 SECURITY INVOKER; +ERROR HY000: PROCEDURE bar3 does not exist +alter procedure bar3 name +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; +ERROR 42000: Identifier name 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' is too long drop table t1; drop table if exists t1; create table t1 (val int, x float); diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 4f66dafbe81..990a8b7c2da 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -734,6 +734,9 @@ n f 19 121645100408832000 20 2432902008176640000 drop table fac; +show function status like '%f%'; +Name Type Creator Modified Created Suid Comment +fac function root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y drop procedure ifac; drop function fac; drop table if exists primes; @@ -794,6 +797,38 @@ set p = p+2; end; end while; end; +show create procedure opp; +Procedure Create Procedure +opp create procedure opp(n bigint unsigned, out pp bool) +begin +declare r double; +declare b, s bigint unsigned default 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; +end +show procedure status like '%p%'; +Name Type Creator Modified Created Suid Comment +ip procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y +opp procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y call ip(200); select * from primes where i=45 or i=100 or i=199; i p @@ -803,5 +838,22 @@ i p drop table primes; drop procedure opp; drop procedure ip; +create procedure bar(x char(16), y int) +comment "111111111111" SECURITY INVOKER +insert into test.t1 values (x, y); +show procedure status like 'bar'; +Name Type Creator Modified Created Suid Comment +bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 N 111111111111 +alter procedure bar name bar2 comment "2222222222" SECURITY DEFINER; +alter procedure bar2 name bar comment "3333333333"; +alter procedure bar; +show create procedure bar; +Procedure Create Procedure +bar create procedure bar(x char(16), y int) +comment "111111111111" SECURITY INVOKER +insert into test.t1 values (x, y) +show procedure status like 'bar'; +Name Type Creator Modified Created Suid Comment +bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y 3333333333 drop table t1; drop table t2; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index d98385b42e0..38f5a34a7bb 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -256,6 +256,12 @@ end| call p()| drop procedure p| +--error 1282 +alter procedure bar3 SECURITY INVOKER| +--error 1059 +alter procedure bar3 name +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| + drop table t1| --disable_warnings diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index b9f62d4fb0a..5b2c9bf18f5 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -852,6 +852,8 @@ end| call ifac(20)| select * from fac| drop table fac| +--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' +show function status like '%f%'| drop procedure ifac| drop function fac| @@ -928,6 +930,9 @@ begin end; end while; end| +show create procedure opp| +--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' +show procedure status like '%p%'| # This isn't the fastest way in the world to compute prime numbers, so # don't be too ambitious. ;-) @@ -939,6 +944,19 @@ drop table primes| drop procedure opp| drop procedure ip| +# Comment & suid +create procedure bar(x char(16), y int) + comment "111111111111" SECURITY INVOKER + insert into test.t1 values (x, y)| +--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' +show procedure status like 'bar'| +alter procedure bar name bar2 comment "2222222222" SECURITY DEFINER| +alter procedure bar2 name bar comment "3333333333"| +alter procedure bar| +show create procedure bar| +--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' +show procedure status like 'bar'| + delimiter ;| drop table t1; drop table t2; diff --git a/sql/lex.h b/sql/lex.h index f4368cacb5d..b267cdda66a 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -130,6 +130,7 @@ static SYMBOL symbols[] = { { "DECLARE", SYM(DECLARE_SYM),0,0}, { "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0}, { "DEFAULT", SYM(DEFAULT),0,0}, + { "DEFINER", SYM(DEFINER),0,0}, { "DELAYED", SYM(DELAYED_SYM),0,0}, { "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0}, { "DELETE", SYM(DELETE_SYM),0,0}, @@ -232,6 +233,7 @@ static SYMBOL symbols[] = { { "ISOLATION", SYM(ISOLATION),0,0}, { "ISSUER", SYM(ISSUER_SYM),0,0}, { "ITERATE", SYM(ITERATE_SYM),0,0}, + { "INVOKER", SYM(INVOKER),0,0}, { "JOIN", SYM(JOIN_SYM),0,0}, { "KEY", SYM(KEY_SYM),0,0}, { "KEYS", SYM(KEYS),0,0}, @@ -295,6 +297,7 @@ static SYMBOL symbols[] = { { "MULTILINESTRING", SYM(MULTILINESTRING),0,0}, { "MULTIPOINT", SYM(MULTIPOINT),0,0}, { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0}, + { "NAME", SYM(NAME_SYM),0,0}, { "NAMES", SYM(NAMES_SYM),0,0}, { "NATURAL", SYM(NATURAL),0,0}, { "NATIONAL", SYM(NATIONAL_SYM),0,0}, @@ -367,6 +370,7 @@ static SYMBOL symbols[] = { { "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0}, { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM),0,0}, + { "SECURITY", SYM(SECURITY),0,0}, { "SEPARATOR", SYM(SEPARATOR_SYM),0,0}, { "SELECT", SYM(SELECT_SYM),0,0}, { "SENSITIVE", SYM(SENSITIVE_SYM),0,0}, diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index abad832511f..56a99100a79 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -323,3 +323,4 @@ character-set=latin2 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index f3ee18e586f..cc3f0ef1fff 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -317,3 +317,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index df1445d3758..e8f8a396f60 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -325,3 +325,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index c38969b778c..82e6a3e17ef 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 885e9cd5c11..b61d44a940b 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -319,3 +319,4 @@ character-set=latin7 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index acb003fb8a4..c77f93548fe 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 855db0ee094..fc7866ef5f0 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -326,3 +326,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 60e3adf5aae..8fc2f6ed574 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -314,3 +314,4 @@ character-set=greek "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index aef2808cdd2..74ad4ce490f 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -316,3 +316,4 @@ character-set=latin2 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 429909cfa08..fc8ceedcad9 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 1f7e4b4c103..5693caae10a 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -316,3 +316,4 @@ character-set=ujis "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index ba2ab18f1f5..cc2a774374f 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -314,3 +314,4 @@ character-set=euckr "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index a72f78540f2..faed3c53ec2 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -316,3 +316,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 8dbef326260..f2474e7924f 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -316,3 +316,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 60d7b4d83cf..a86855291df 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -318,3 +318,4 @@ character-set=latin2 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 95f959c4a18..86146dddaaa 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -315,3 +315,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 976a897eb39..7648c0d224d 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -318,3 +318,4 @@ character-set=latin2 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index a446d69cd12..8d6c56bb9b6 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -316,3 +316,4 @@ character-set=koi8r "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index bd44ade9b72..fe735ff8374 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -309,3 +309,4 @@ character-set=cp1250 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 85bbced043b..4310239f772 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin2 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index ae76b53b130..05f5f8d7a71 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -316,3 +316,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 5282e9e1fab..c41dfd9b268 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin1 "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 2059e1f1cea..dee93450ccf 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -319,3 +319,4 @@ character-set=koi8u "Duplicate variable: %s" "Duplicate condition: %s" "Duplicate cursor: %s" +"Failed to ALTER %s %s" diff --git a/sql/sp.cc b/sql/sp.cc index 6ca020b5eaa..bf8cf37f293 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -230,8 +230,8 @@ db_create_routine(THD *thd, int type, (uint)strlen(creator), system_charset_info); ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time(); - if (suid) - table->field[MYSQL_PROC_FIELD_SUID]->store((longlong)suid); + if (!suid) + table->field[MYSQL_PROC_FIELD_SUID]->store((longlong) 1); if (comment) table->field[MYSQL_PROC_FIELD_COMMENT]->store(comment, commentlen, system_charset_info); @@ -268,6 +268,182 @@ db_drop_routine(THD *thd, int type, char *name, uint namelen) DBUG_RETURN(ret); } +static int +db_update_routine(THD *thd, int type, char *name, uint namelen, + char *newname, uint newnamelen, + char *comment, uint commentlen, enum suid_behaviour suid) +{ + DBUG_ENTER("db_update_routine"); + 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, &opened); + if (ret == SP_OK) + { + store_record(table,record[1]); + ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time(); + if (suid) + table->field[MYSQL_PROC_FIELD_SUID]->store((longlong) suid); + if (newname) + table->field[MYSQL_PROC_FIELD_NAME]->store(newname, + newnamelen, + system_charset_info); + if (comment) + table->field[MYSQL_PROC_FIELD_COMMENT]->store(comment, + commentlen, + system_charset_info); + if ((table->file->update_row(table->record[1],table->record[0]))) + ret= SP_WRITE_ROW_FAILED; + } + if (opened) + close_thread_tables(thd); + DBUG_RETURN(ret); +} + +struct st_used_field +{ + const char *field_name; + uint field_length; + enum enum_field_types field_type; + Field *field; +}; + +static struct st_used_field init_fields[]= +{ + { "Name", NAME_LEN, MYSQL_TYPE_STRING, 0}, + { "Type", 9, MYSQL_TYPE_STRING, 0}, + { "Creator", 77, MYSQL_TYPE_STRING, 0}, + { "Modified", 0, MYSQL_TYPE_TIMESTAMP, 0}, + { "Created", 0, MYSQL_TYPE_TIMESTAMP, 0}, + { "Suid", 1, MYSQL_TYPE_STRING, 0}, + { "Comment", NAME_LEN, MYSQL_TYPE_STRING, 0}, + { 0, 0, MYSQL_TYPE_STRING, 0} +}; + +int print_field_values(THD *thd, TABLE *table, + struct st_used_field *used_fields, + int type, const char *wild) +{ + Protocol *protocol= thd->protocol; + + if (table->field[MYSQL_PROC_FIELD_TYPE]->val_int() == type) + { + String *tmp_string= new String(); + struct st_used_field *used_field= used_fields; + get_field(&thd->mem_root, + used_field->field, + tmp_string); + if (!wild || !wild[0] || !wild_compare(tmp_string->ptr(), wild, 0)) + { + protocol->prepare_for_resend(); + protocol->store(tmp_string); + for (used_field++; + used_field->field_name; + used_field++) + { + switch (used_field->field_type) { + case MYSQL_TYPE_TIMESTAMP: + { + TIME tmp_time; + ((Field_timestamp *) used_field->field)->get_time(&tmp_time); + protocol->store(&tmp_time); + } + break; + default: + { + String *tmp_string1= new String(); + get_field(&thd->mem_root, used_field->field, tmp_string1); + protocol->store(tmp_string1); + } + break; + } + } + if (protocol->write()) + return 1; + } + } + return 0; +} + +int +db_show_routine_status(THD *thd, int type, const char *wild) +{ + DBUG_ENTER("db_show_routine_status"); + + 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_READ))) + { + DBUG_RETURN(1); + } + else + { + Item *item; + List field_list; + struct st_used_field *used_field; + st_used_field used_fields[array_elements(init_fields)]; + memcpy((char*) used_fields, (char*) init_fields, sizeof(used_fields)); + /* Init header */ + for (used_field= &used_fields[0]; + used_field->field_name; + used_field++) + { + switch (used_field->field_type) { + case MYSQL_TYPE_TIMESTAMP: + field_list.push_back(item=new Item_datetime(used_field->field_name)); + break; + default: + field_list.push_back(item=new Item_empty_string(used_field->field_name, + used_field-> + field_length)); + break; + } + } + /* Print header */ + if (thd->protocol->send_fields(&field_list,1)) + goto err_case; + + /* Init fields */ + setup_tables(&tables); + for (used_field= &used_fields[0]; + used_field->field_name; + used_field++) + { + TABLE_LIST *not_used; + Item_field *field= new Item_field("mysql", "proc", + used_field->field_name); + if (!(used_field->field= find_field_in_tables(thd, field, &tables, + ¬_used, TRUE))) + goto err_case1; + } + + table->file->index_init(0); + table->file->index_first(table->record[0]); + if (print_field_values(thd, table, used_fields, type, wild)) + goto err_case1; + while (!table->file->index_next(table->record[0])) + { + if (print_field_values(thd, table, used_fields, type, wild)) + goto err_case1; + } + send_eof(thd); + close_thread_tables(thd); + DBUG_RETURN(0); + } +err_case1: + send_eof(thd); +err_case: + close_thread_tables(thd); + DBUG_RETURN(1); +} + /* * @@ -326,6 +502,46 @@ sp_drop_procedure(THD *thd, char *name, uint namelen) DBUG_RETURN(ret); } +int +sp_update_procedure(THD *thd, char *name, uint namelen, + char *newname, uint newnamelen, + char *comment, uint commentlen, enum suid_behaviour suid) +{ + DBUG_ENTER("sp_update_procedure"); + DBUG_PRINT("enter", ("name: %*s", namelen, name)); + sp_head *sp; + int ret; + + sp= sp_cache_remove(&thd->sp_proc_cache, name, namelen); + if (sp) + delete sp; + ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, + newname, newnamelen, + comment, commentlen, suid); + + DBUG_RETURN(ret); +} + +int +sp_show_create_procedure(THD *thd, LEX_STRING *name) +{ + DBUG_ENTER("sp_show_create_procedure"); + DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + sp_head *sp; + + sp= sp_find_procedure(thd, name); + if (sp) + DBUG_RETURN(sp->show_create_procedure(thd)); + + DBUG_RETURN(1); +} + +int +db_show_status_procedure(THD *thd, const char *wild) +{ + DBUG_ENTER("db_show_status_procedure"); + DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild)); +} /* * @@ -381,6 +597,47 @@ sp_drop_function(THD *thd, char *name, uint namelen) DBUG_RETURN(ret); } +int +sp_update_function(THD *thd, char *name, uint namelen, + char *newname, uint newnamelen, + char *comment, uint commentlen, enum suid_behaviour suid) +{ + DBUG_ENTER("sp_update_procedure"); + DBUG_PRINT("enter", ("name: %*s", namelen, name)); + sp_head *sp; + int ret; + + sp= sp_cache_remove(&thd->sp_func_cache, name, namelen); + if (sp) + delete sp; + ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, + newname, newnamelen, + comment, commentlen, suid); + + DBUG_RETURN(ret); +} + +int +sp_show_create_function(THD *thd, LEX_STRING *name) +{ + DBUG_ENTER("sp_show_create_function"); + DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + sp_head *sp; + + sp= sp_find_function(thd, name); + if (sp) + DBUG_RETURN(sp->show_create_function(thd)); + + DBUG_RETURN(1); +} + +int +db_show_status_function(THD *thd, const char *wild) +{ + DBUG_ENTER("db_show_status_function"); + DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild)); +} + // QQ Temporary until the function call detection in sql_lex has been reworked. bool sp_function_exists(THD *thd, LEX_STRING *name) diff --git a/sql/sp.h b/sql/sp.h index bbf8832d55d..e7c2fba3bba 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -38,6 +38,17 @@ int sp_drop_procedure(THD *thd, char *name, uint namelen); +int +sp_update_procedure(THD *thd, char *name, uint namelen, + char *newname, uint newnamelen, + char *comment, uint commentlen, enum suid_behaviour suid); + +int +sp_show_create_procedure(THD *thd, LEX_STRING *name); + +int +db_show_status_procedure(THD *thd, const char *wild); + sp_head * sp_find_function(THD *thd, LEX_STRING *name); @@ -48,6 +59,17 @@ sp_create_function(THD *thd, char *name, uint namelen, char *def, uint deflen, int sp_drop_function(THD *thd, char *name, uint namelen); +int +sp_update_function(THD *thd, char *name, uint namelen, + char *newname, uint newnamelen, + char *comment, uint commentlen, enum suid_behaviour suid); + +int +sp_show_create_function(THD *thd, LEX_STRING *name); + +int +db_show_status_function(THD *thd, const char *wild); + // QQ Temporary until the function call detection in sql_lex has been reworked. bool sp_function_exists(THD *thd, LEX_STRING *name); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 88bd299ccd5..626addf08b0 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -131,7 +131,7 @@ sp_head::sp_head() } void -sp_head::init(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) +sp_head::init(LEX_STRING *name, LEX *lex) { DBUG_ENTER("sp_head::init"); const char *dstr = (const char*)lex->buf; @@ -141,16 +141,6 @@ sp_head::init(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid) 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_comment.length= 0; - m_comment.str= 0; - if (comment) - { - m_comment.length= comment->length; - m_comment.str= comment->str; - } - - m_suid= suid; lex->spcont= m_pcont= new sp_pcontext(); my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); DBUG_VOID_RETURN; @@ -605,7 +595,56 @@ sp_head::backpatch(sp_label_t *lab) } } +int +sp_head::show_create_procedure(THD *thd) +{ + Protocol *protocol= thd->protocol; + char buff[2048]; + String buffer(buff, sizeof(buff), system_charset_info); + int res; + List field_list; + + DBUG_ENTER("sp_head::show_create_procedure"); + DBUG_PRINT("info", ("procedure %s", m_name.str)); + + field_list.push_back(new Item_empty_string("Procedure",NAME_LEN)); + // 1024 is for not to confuse old clients + field_list.push_back(new Item_empty_string("Create Procedure", + max(buffer.length(),1024))); + if (protocol->send_fields(&field_list, 1)) + DBUG_RETURN(1); + protocol->prepare_for_resend(); + protocol->store(m_name.str, m_name.length, system_charset_info); + protocol->store(m_defstr.str, m_defstr.length, system_charset_info); + res= protocol->write(); + send_eof(thd); + DBUG_RETURN(res); +} + +int +sp_head::show_create_function(THD *thd) +{ + Protocol *protocol= thd->protocol; + char buff[2048]; + String buffer(buff, sizeof(buff), system_charset_info); + int res; + List field_list; + + DBUG_ENTER("sp_head::show_create_function"); + DBUG_PRINT("info", ("procedure %s", m_name.str)); + field_list.push_back(new Item_empty_string("Function",NAME_LEN)); + field_list.push_back(new Item_empty_string("Create Function", + max(buffer.length(),1024))); + if (protocol->send_fields(&field_list, 1)) + DBUG_RETURN(1); + protocol->prepare_for_resend(); + protocol->store(m_name.str, m_name.length, system_charset_info); + protocol->store(m_defstr.str, m_defstr.length, system_charset_info); + res= protocol->write(); + send_eof(thd); + DBUG_RETURN(res); +} // ------------------------------------------------------------------ // diff --git a/sql/sp_head.h b/sql/sp_head.h index b582d37a185..2a8f8a1e017 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -66,7 +66,21 @@ public: // Initialize after we have reset mem_root void - init(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid); + init(LEX_STRING *name, LEX *lex); + + void + init_options(LEX_STRING *comment, enum suid_behaviour suid) + { + m_comment.length= 0; + m_comment.str= 0; + if (comment) + { + m_comment.length= comment->length; + m_comment.str= comment->str; + } + m_suid= suid ? suid - 1 : 1; + } + int create(THD *thd); @@ -83,6 +97,12 @@ public: int execute_procedure(THD *thd, List *args); + int + show_create_procedure(THD *thd); + + int + show_create_function(THD *thd); + inline void add_instr(sp_instr *i) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 463205e78b0..e9cd64450fc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -79,11 +79,18 @@ enum enum_sql_command { SQLCOM_HELP, SQLCOM_DROP_USER, SQLCOM_REVOKE_ALL, SQLCOM_CHECKSUM, SQLCOM_CREATE_PROCEDURE, SQLCOM_CREATE_SPFUNCTION, SQLCOM_CALL, SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION, + SQLCOM_SHOW_CREATE_PROC, SQLCOM_SHOW_CREATE_FUNC, + SQLCOM_SHOW_STATUS_PROC, SQLCOM_SHOW_STATUS_FUNC, /* This should be the last !!! */ SQLCOM_END }; +enum suid_behaviour +{ + IS_DEFAULT_SUID= 0, IS_NOT_SUID, IS_SUID +}; + typedef List List_item; typedef struct st_lex_master_info @@ -544,6 +551,7 @@ typedef struct st_lex enum enum_enable_or_disable alter_keys_onoff; enum enum_var_type option_type; enum tablespace_op_type tablespace_op; + enum suid_behaviour suid; uint uint_geom_type; uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1fbf57d8cb3..b78aa73aa47 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3394,22 +3394,34 @@ mysql_execute_command(THD *thd) case SQLCOM_ALTER_PROCEDURE: case SQLCOM_ALTER_FUNCTION: { - sp_head *sp; - - 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) + res= -1; + uint newname_len= 0; + if (lex->name) + newname_len= strlen(lex->name); + if (newname_len > NAME_LEN) { - net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex),lex->udf.name); + net_printf(thd, ER_TOO_LONG_IDENT, lex->name); goto error; } + if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) + res= sp_update_procedure(thd, lex->udf.name.str, lex->udf.name.length, + lex->name, newname_len, lex->comment->str, + lex->comment->length, lex->suid); else + res= sp_update_function(thd, lex->udf.name.str, lex->udf.name.length, + lex->name, newname_len, lex->comment->str, + lex->comment->length, lex->suid); + switch (res) { - /* QQ This is an no-op right now, since we haven't - put the characteristics in yet. */ + case SP_OK: send_ok(thd); + break; + case SP_KEY_NOT_FOUND: + net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex),lex->udf.name); + goto error; + default: + net_printf(thd, ER_SP_CANT_ALTER, SP_COM_STRING(lex),lex->udf.name); + goto error; } break; } @@ -3463,6 +3475,51 @@ mysql_execute_command(THD *thd) } break; } + case SQLCOM_SHOW_CREATE_PROC: + { + res= -1; + if (lex->udf.name.length > NAME_LEN) + { + net_printf(thd, ER_TOO_LONG_IDENT, lex->udf.name.str); + goto error; + } + res= sp_show_create_procedure(thd, &lex->udf.name); + if (res == SP_KEY_NOT_FOUND) + { + net_printf(thd, ER_SP_DOES_NOT_EXIST, + SP_COM_STRING(lex), lex->udf.name.str); + goto error; + } + break; + } + case SQLCOM_SHOW_CREATE_FUNC: + { + if (lex->udf.name.length > NAME_LEN) + { + net_printf(thd, ER_TOO_LONG_IDENT, lex->udf.name.str); + goto error; + } + res= sp_show_create_function(thd, &lex->udf.name); + if (res == SP_KEY_NOT_FOUND) + { + net_printf(thd, ER_SP_DOES_NOT_EXIST, + SP_COM_STRING(lex), lex->udf.name.str); + goto error; + } + break; + } + case SQLCOM_SHOW_STATUS_PROC: + { + res= db_show_status_procedure(thd, (lex->wild ? + lex->wild->ptr() : NullS)); + break; + } + case SQLCOM_SHOW_STATUS_FUNC: + { + res= db_show_status_function(thd, (lex->wild ? + lex->wild->ptr() : NullS)); + break; + } default: /* Impossible */ send_ok(thd); break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0af4b774615..2e76989c558 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -137,6 +137,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CREATE %token CROSS %token CUBE_SYM +%token DEFINER %token DELETE_SYM %token DUAL_SYM %token DO_SYM @@ -269,6 +270,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token INOUT_SYM %token INTO %token IN_SYM +%token INVOKER %token ISOLATION %token JOIN_SYM %token KEYS @@ -311,6 +313,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token MEDIUM_SYM %token MIN_ROWS %token NAMES_SYM +%token NAME_SYM %token NATIONAL_SYM %token NATURAL %token NEW_SYM @@ -361,6 +364,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ROW_FORMAT_SYM %token ROW_SYM %token RTREE_SYM +%token SECURITY %token SET %token SEPARATOR_SYM %token SERIAL_SYM @@ -619,7 +623,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component - SP_FUNC ident_or_spfunc sp_opt_label + SP_FUNC ident_or_spfunc sp_opt_label sp_comment sp_newname %type opt_table_alias @@ -745,7 +749,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); union_clause union_list union_option precision subselect_start opt_and charset subselect_end select_var_list select_var_list_init help opt_len - statement + statement sp_suid END_OF_INPUT %type call sp_proc_stmts sp_proc_stmt @@ -1021,7 +1025,7 @@ create: /* Order is important here: new - reset - init */ sp= new sp_head(); sp->reset_thd_mem_root(YYTHD); - sp->init(&$3, lex, 0, 0); + sp->init(&$3, lex); sp->m_type= TYPE_ENUM_PROCEDURE; lex->sphead= sp; @@ -1037,6 +1041,10 @@ create: { Lex->spcont->set_params(); } + sp_comment sp_suid + { + Lex->sphead->init_options(&$9, Lex->suid); + } sp_proc_stmt { LEX *lex= Lex; @@ -1075,7 +1083,7 @@ create_function_tail: /* 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->init(&lex->udf.name, lex); sp->m_type= TYPE_ENUM_FUNCTION; lex->sphead= sp; @@ -1095,6 +1103,10 @@ create_function_tail: { Lex->sphead->m_returns= (enum enum_field_types)$7; } + sp_comment sp_suid + { + Lex->sphead->init_options(&$9, Lex->suid); + } sp_proc_stmt { LEX *lex= Lex; @@ -1107,6 +1119,23 @@ create_function_tail: } ; +sp_comment: + /* Empty */ { $$.str=0; } + | COMMENT_SYM TEXT_STRING_sys { $$= $2; } + ; + +sp_newname: + /* Empty */ { $$.str=0; } + | NAME_SYM ident { $$= $2; } + ; + + +sp_suid: + /* Empty */ { Lex->suid= IS_DEFAULT_SUID; } + | SECURITY DEFINER { Lex->suid= IS_SUID; } + | SECURITY INVOKER { Lex->suid= IS_NOT_SUID; } + ; + call: CALL_SYM ident_or_spfunc { @@ -2573,7 +2602,7 @@ alter: lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; } - | ALTER PROCEDURE ident + | ALTER PROCEDURE ident sp_newname sp_comment sp_suid /* QQ Characteristics missing for now */ opt_restrict { @@ -2583,8 +2612,10 @@ alter: put the characteristics in yet. */ lex->sql_command= SQLCOM_ALTER_PROCEDURE; lex->udf.name= $3; + lex->name= $4.str; + lex->comment= &$5; } - | ALTER FUNCTION_SYM ident + | ALTER FUNCTION_SYM ident sp_newname sp_comment sp_suid /* QQ Characteristics missing for now */ opt_restrict { @@ -2594,6 +2625,8 @@ alter: put the characteristics in yet. */ lex->sql_command= SQLCOM_ALTER_FUNCTION; lex->udf.name= $3; + lex->name= $4.str; + lex->comment= &$5; } ; @@ -5012,7 +5045,26 @@ show_param: | SLAVE STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - }; + } + | CREATE PROCEDURE ident + { + Lex->sql_command = SQLCOM_SHOW_CREATE_PROC; + Lex->udf.name= $3; + } + | CREATE FUNCTION_SYM ident + { + Lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; + Lex->udf.name= $3; + } + | PROCEDURE STATUS_SYM wild + { + Lex->sql_command = SQLCOM_SHOW_STATUS_PROC; + } + | FUNCTION_SYM STATUS_SYM wild + { + Lex->sql_command = SQLCOM_SHOW_STATUS_FUNC; + }; + master_or_binary: MASTER_SYM @@ -5560,6 +5612,7 @@ keyword: | DATETIME {} | DATE_SYM {} | DAY_SYM {} + | DEFINER {} | DELAY_KEY_WRITE_SYM {} | DES_KEY_FILE {} | DIRECTORY_SYM {} @@ -5595,6 +5648,7 @@ keyword: | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} + | INVOKER {} | IMPORT {} | INDEXES {} | ISOLATION {} @@ -5637,6 +5691,7 @@ keyword: | MULTILINESTRING {} | MULTIPOINT {} | MULTIPOLYGON {} + | NAME_SYM {} | NAMES_SYM {} | NATIONAL_SYM {} | NCHAR_SYM {} @@ -5680,6 +5735,7 @@ keyword: | RTREE_SYM {} | SAVEPOINT_SYM {} | SECOND_SYM {} + | SECURITY {} | SERIAL_SYM {} | SERIALIZABLE_SYM {} | SESSION_SYM {} -- cgit v1.2.1 From bd2263503d82958ced3fbf700ab4a7f9265e9dc5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Nov 2003 11:26:18 +0100 Subject: Fixed BUG#1862 (flush table in SPs didn't work). Fixed various bugs: setting local variables to NULL, SELECT INTO var now actually might work, SELECT INTO with not row now gives a "no data" warning (instead of the "empty query" error), etc. Updated test cases accordingly. mysql-test/r/sp-error.result: Corrected security syntax for alter/create procedure. mysql-test/r/sp.result: Corrected security syntax for alter/create procedure. New tests for setting local variables to null, bug fixes for SELECT INTO var, FLUSH TABLES calls (BUG#1862), and corrected "no data" warning for SELECT INTO with no rows. mysql-test/t/sp-error.test: Corrected security syntax for alter/create procedure. mysql-test/t/sp.test: Corrected security syntax for alter/create procedure. New tests for setting local variables to null, bug fixes for SELECT INTO var, FLUSH TABLES calls (BUG#1862), and corrected "no data" warning for SELECT INTO with no rows. sql/lex.h: Added SQL_SYM (and added a few _SYM suffixes for new symbols). sql/sp_head.cc: Fixed bug in the item_list copying for "with_wild" cases (list nodes ended up in the wrong memroot). Catch errors and warnings even if return values is 0 from sub-statements. Restore table_list which is zapped by SQLCOM_CREATE_TABLE and INSERT_SELECT. Set old table pointers to NULL after sub-statement call (since all tables are closed). sql/sql_class.cc: Corrected error message when no rows return by a SELECT INTO var; should be a "no data" warning. sql/sql_lex.h: Have to store the original table_list first pointer for some sub-statements in SPs. sql/sql_yacc.yy: Corrected SECURITY INVOKER/DEFINER syntax ("SQL" missing), added some _SYM suffixes, and fixed valgrind complaints for SP COMMENTs. (Also removed some now irrelevant comments.) --- mysql-test/r/sp-error.result | 2 +- mysql-test/r/sp.result | 85 ++++++++++++++++++++++++++++++++++---- mysql-test/t/sp-error.test | 2 +- mysql-test/t/sp.test | 98 ++++++++++++++++++++++++++++++++++++++++++-- sql/lex.h | 7 ++-- sql/sp_head.cc | 47 ++++++++++++++++----- sql/sql_class.cc | 14 ++----- sql/sql_lex.h | 1 + sql/sql_yacc.yy | 44 +++++++++++--------- 9 files changed, 245 insertions(+), 55 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 58905a74507..adfecc151b7 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -187,7 +187,7 @@ end; call p(); ERROR HY000: Cursor is not open drop procedure p; -alter procedure bar3 SECURITY INVOKER; +alter procedure bar3 sql security invoker; ERROR HY000: PROCEDURE bar3 does not exist alter procedure bar3 name AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 990a8b7c2da..56f6bc59087 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -75,6 +75,23 @@ id data locset 21 delete from t1; drop procedure locset; +drop table if exists t3; +create table t3 ( d date, i int, f double, s varchar(32) ); +create procedure nullset() +begin +declare ld date; +declare li int; +declare lf double; +declare ls varchar(32); +set ld = null, li = null, lf = null, ls = null; +insert into t3 values (ld, li, lf, ls); +end; +call nullset(); +select * from t3; +d i f s +NULL NULL NULL NULL +drop table t3; +drop procedure nullset; create procedure mixset(x char(16), y int) begin declare z int; @@ -390,6 +407,47 @@ into 100 100 into2 102 100 delete from t1; drop procedure into_test2; +create procedure into_test3() +begin +declare x char(16); +declare y int; +select * into x,y from test.t1 limit 1; +insert into test.t2 values (x, y, 0.0); +end; +insert into t1 values ("into3", 19); +delete from t2; +call into_test3(); +call into_test3(); +select * from t2; +s i d +into3 19 0 +into3 19 0 +delete from t1; +delete from t2; +drop procedure into_test3; +create procedure into_test4() +begin +declare x int; +select data into x from test.t1 limit 1; +insert into test.t3 values ("into4", x); +end; +delete from t1; +drop table if exists t3; +create table t3 ( s char(16), d int); +call into_test4(); +Warnings: +select * from t3; +s d +into4 NULL +insert into t1 values ("i4", 77); +call into_test4(); +select * from t3; +s d +into4 NULL +into4 77 +delete from t1; +drop table t3; +drop procedure into_test4; create procedure into_outfile(x char(16), y int) begin insert into test.t1 values (x, y); @@ -475,9 +533,6 @@ 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; @@ -551,7 +606,7 @@ create procedure hndlr4() begin declare x int default 0; declare val int; # No default -declare continue handler for sqlexception set x=1; +declare continue handler for 1306 set x=1; select data into val from test.t3 where id='z' limit 1; # No hits insert into test.t3 values ('z', val); end; @@ -695,6 +750,21 @@ select @1, @2; 2 NULL drop table t70; drop procedure bug1656; +drop table if exists t3; +create table t3(a int); +create procedure bug1862() +begin +insert into t3 values(2); +flush tables; +end; +call bug1862(); +call bug1862(); +select * from t3; +a +2 +2 +drop table t3; +drop procedure bug1862; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) @@ -839,21 +909,22 @@ drop table primes; drop procedure opp; drop procedure ip; create procedure bar(x char(16), y int) -comment "111111111111" SECURITY INVOKER +comment "111111111111" sql security invoker insert into test.t1 values (x, y); show procedure status like 'bar'; Name Type Creator Modified Created Suid Comment bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 N 111111111111 -alter procedure bar name bar2 comment "2222222222" SECURITY DEFINER; +alter procedure bar name bar2 comment "2222222222" sql security definer; alter procedure bar2 name bar comment "3333333333"; alter procedure bar; show create procedure bar; Procedure Create Procedure bar create procedure bar(x char(16), y int) -comment "111111111111" SECURITY INVOKER +comment "111111111111" sql security invoker insert into test.t1 values (x, y) show procedure status like 'bar'; Name Type Creator Modified Created Suid Comment bar procedure root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 Y 3333333333 +drop procedure bar; drop table t1; drop table t2; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 38f5a34a7bb..87f765cb7c8 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -257,7 +257,7 @@ call p()| drop procedure p| --error 1282 -alter procedure bar3 SECURITY INVOKER| +alter procedure bar3 sql security invoker| --error 1059 alter procedure bar3 name AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 5b2c9bf18f5..091a3e364ce 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -109,6 +109,29 @@ delete from t1| drop procedure locset| +# Set things to null +--disable_warnings +drop table if exists t3| +--enable_warnings +create table t3 ( d date, i int, f double, s varchar(32) )| + +create procedure nullset() +begin + declare ld date; + declare li int; + declare lf double; + declare ls varchar(32); + + set ld = null, li = null, lf = null, ls = null; + insert into t3 values (ld, li, lf, ls); +end| + +call nullset()| +select * from t3| +drop table t3| +drop procedure nullset| + + # The peculiar (non-standard) mixture of variables types in SET. create procedure mixset(x char(16), y int) begin @@ -460,6 +483,52 @@ delete from t1| drop procedure into_test2| +# SELECT * INTO ... (bug test) +create procedure into_test3() +begin + declare x char(16); + declare y int; + + select * into x,y from test.t1 limit 1; + insert into test.t2 values (x, y, 0.0); +end| + +insert into t1 values ("into3", 19)| +delete from t2| +# Two call needed for bug test +call into_test3()| +call into_test3()| +select * from t2| +delete from t1| +delete from t2| +drop procedure into_test3| + + +# SELECT INTO with no data is a warning ("no data", which we will +# not see normally). When not caught, execution proceeds. +create procedure into_test4() +begin + declare x int; + + select data into x from test.t1 limit 1; + insert into test.t3 values ("into4", x); +end| + +delete from t1| +--disable_warnings +drop table if exists t3| +--enable_warnings +create table t3 ( s char(16), d int)| +call into_test4()| +select * from t3| +insert into t1 values ("i4", 77)| +call into_test4()| +select * from t3| +delete from t1| +drop table t3| +drop procedure into_test4| + + # These two (and the two procedures above) caused an assert() to fail in # sql_base.cc:lock_tables() at some point. @@ -658,7 +727,7 @@ create procedure hndlr4() begin declare x int default 0; declare val int; # No default - declare continue handler for sqlexception set x=1; + declare continue handler for 1306 set x=1; select data into val from test.t3 where id='z' limit 1; # No hits @@ -823,6 +892,28 @@ drop table t70| drop procedure bug1656| +# +# BUG#1862 +# +--disable_warnings +drop table if exists t3| +--enable_warnings +create table t3(a int)| + +create procedure bug1862() +begin + insert into t3 values(2); + flush tables; +end| + +call bug1862()| +# the second call caused a segmentation +call bug1862()| +select * from t3| +drop table t3| +drop procedure bug1862| + + # # Some "real" examples # @@ -946,16 +1037,17 @@ drop procedure ip| # Comment & suid create procedure bar(x char(16), y int) - comment "111111111111" SECURITY INVOKER + comment "111111111111" sql security invoker insert into test.t1 values (x, y)| --replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' show procedure status like 'bar'| -alter procedure bar name bar2 comment "2222222222" SECURITY DEFINER| +alter procedure bar name bar2 comment "2222222222" sql security definer| alter procedure bar2 name bar comment "3333333333"| alter procedure bar| show create procedure bar| --replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' show procedure status like 'bar'| +drop procedure bar| delimiter ;| drop table t1; diff --git a/sql/lex.h b/sql/lex.h index b267cdda66a..b136fc63813 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -130,7 +130,7 @@ static SYMBOL symbols[] = { { "DECLARE", SYM(DECLARE_SYM),0,0}, { "DES_KEY_FILE", SYM(DES_KEY_FILE),0,0}, { "DEFAULT", SYM(DEFAULT),0,0}, - { "DEFINER", SYM(DEFINER),0,0}, + { "DEFINER", SYM(DEFINER_SYM),0,0}, { "DELAYED", SYM(DELAYED_SYM),0,0}, { "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM),0,0}, { "DELETE", SYM(DELETE_SYM),0,0}, @@ -233,7 +233,7 @@ static SYMBOL symbols[] = { { "ISOLATION", SYM(ISOLATION),0,0}, { "ISSUER", SYM(ISSUER_SYM),0,0}, { "ITERATE", SYM(ITERATE_SYM),0,0}, - { "INVOKER", SYM(INVOKER),0,0}, + { "INVOKER", SYM(INVOKER_SYM),0,0}, { "JOIN", SYM(JOIN_SYM),0,0}, { "KEY", SYM(KEY_SYM),0,0}, { "KEYS", SYM(KEYS),0,0}, @@ -370,7 +370,7 @@ static SYMBOL symbols[] = { { "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0}, { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM),0,0}, - { "SECURITY", SYM(SECURITY),0,0}, + { "SECURITY", SYM(SECURITY_SYM),0,0}, { "SEPARATOR", SYM(SEPARATOR_SYM),0,0}, { "SELECT", SYM(SELECT_SYM),0,0}, { "SENSITIVE", SYM(SENSITIVE_SYM),0,0}, @@ -389,6 +389,7 @@ static SYMBOL symbols[] = { { "SONAME", SYM(UDF_SONAME_SYM),0,0}, { "SPATIAL", SYM(SPATIAL_SYM),0,0}, { "SPECIFIC", SYM(SPECIFIC_SYM),0,0}, + { "SQL", SYM(SQL_SYM),0,0}, { "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM),0,0}, { "SQLSTATE", SYM(SQLSTATE_SYM),0,0}, { "SQLWARNING", SYM(SQLWARNING_SYM),0,0}, diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 1cdc9ac740d..106f4c58fa6 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -234,7 +234,9 @@ sp_head::execute(THD *thd) DBUG_PRINT("execute", ("Instruction %u", ip)); ret= i->execute(thd, &ip); // Check if an exception has occurred and a handler has been found - if (ret && !thd->killed && ctx) + // Note: We havo to check even if ret==0, since warnings (and some + // errors don't return a non-zero value. + if (!thd->killed && ctx) { uint hf; @@ -509,12 +511,20 @@ sp_head::restore_lex(THD *thd) // Update some state in the old one first oldlex->ptr= sublex->ptr; oldlex->next_state= sublex->next_state; - // Save WHERE clause pointers to avoid damaging by optimisation for (SELECT_LEX *sl= sublex->all_selects_list ; sl ; sl= sl->next_select_in_list()) { + // Save WHERE clause pointers to avoid damaging by optimisation sl->prep_where= sl->where; + if (sl->with_wild) + { + // Copy item_list. We will restore it before calling the + // sub-statement, so it's ok to pop them. + sl->item_list_copy.empty(); + while (Item *it= sl->item_list.pop()) + sl->item_list_copy.push_back(it); + } } // Collect some data from the sub statement lex. @@ -687,14 +697,22 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) sl ; sl= sl->next_select_in_list()) { + if (lex->sql_command == SQLCOM_CREATE_TABLE || + lex->sql_command == SQLCOM_INSERT_SELECT) + { // Destroys sl->table_list.first + sl->table_list_first_copy= sl->table_list.first; + } if (sl->with_wild) { - List_iterator_fast li(sl->item_list); + // Restore item_list + // Note: We have to do this before executing the sub-statement, + // to make sure that the list nodes are in the right + // memroot. + List_iterator_fast li(sl->item_list_copy); - // Copy item_list - sl->item_list_copy.empty(); + sl->item_list.empty(); while (Item *it= li++) - sl->item_list_copy.push_back(it); + sl->item_list.push_back(it); } sl->ref_pointer_array= 0; if (sl->prep_where) @@ -725,12 +743,19 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) sl ; sl= sl->next_select_in_list()) { - if (sl->with_wild) + TABLE_LIST *tabs; + + // We have closed all tables, get rid of pointers to them + for (tabs=(TABLE_LIST *)sl->table_list.first ; + tabs ; + tabs= tabs->next) { - // Restore item_list - sl->item_list.empty(); - while (Item *it= sl->item_list_copy.pop()) - sl->item_list.push_back(it); + tabs->table= NULL; + } + if (lex->sql_command == SQLCOM_CREATE_TABLE || + lex->sql_command == SQLCOM_INSERT_SELECT) + { // Restore sl->table_list.first + sl->table_list.first= sl->table_list_first_copy; } for (ORDER *order= (ORDER *)sl->order_list.first ; order ; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f3e57a0abbf..39e0df57ce6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1253,14 +1253,8 @@ bool select_dumpvar::send_data(List &items) bool select_dumpvar::send_eof() { - if (row_count) - { - ::send_ok(thd,row_count); - return 0; - } - else - { - my_error(ER_EMPTY_QUERY,MYF(0)); - return 1; - } + if (! row_count) + send_warning(thd, ER_SP_FETCH_NO_DATA); + ::send_ok(thd,row_count); + return 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e9cd64450fc..e33784c88b0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -362,6 +362,7 @@ public: SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */ List item_list; /* list of fields & expressions */ List item_list_copy; /* For SPs */ + byte *table_list_first_copy; /* For SPs */ List interval_list, use_index, *use_index_ptr, ignore_index, *ignore_index_ptr; /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2e76989c558..f93c9e53275 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -137,7 +137,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CREATE %token CROSS %token CUBE_SYM -%token DEFINER +%token DEFINER_SYM %token DELETE_SYM %token DUAL_SYM %token DO_SYM @@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SELECT_SYM %token SHOW %token SLAVE +%token SQL_SYM %token SQL_THREAD %token START_SYM %token STD_SYM @@ -270,7 +271,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token INOUT_SYM %token INTO %token IN_SYM -%token INVOKER +%token INVOKER_SYM %token ISOLATION %token JOIN_SYM %token KEYS @@ -364,7 +365,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ROW_FORMAT_SYM %token ROW_SYM %token RTREE_SYM -%token SECURITY +%token SECURITY_SYM %token SET %token SEPARATOR_SYM %token SERIAL_SYM @@ -1120,20 +1121,20 @@ create_function_tail: ; sp_comment: - /* Empty */ { $$.str=0; } + /* Empty */ { $$.str= 0; $$.length= 0; } | COMMENT_SYM TEXT_STRING_sys { $$= $2; } ; sp_newname: - /* Empty */ { $$.str=0; } + /* Empty */ { $$.str= 0; $$.length= 0; } | NAME_SYM ident { $$= $2; } ; sp_suid: - /* Empty */ { Lex->suid= IS_DEFAULT_SUID; } - | SECURITY DEFINER { Lex->suid= IS_SUID; } - | SECURITY INVOKER { Lex->suid= IS_NOT_SUID; } + /* Empty */ { Lex->suid= IS_DEFAULT_SUID; } + | SQL_SYM SECURITY_SYM DEFINER_SYM { Lex->suid= IS_SUID; } + | SQL_SYM SECURITY_SYM INVOKER_SYM { Lex->suid= IS_NOT_SUID; } ; call: @@ -2603,30 +2604,35 @@ alter: lex->name=$3.str; } | ALTER PROCEDURE ident sp_newname sp_comment sp_suid - /* QQ Characteristics missing for now */ opt_restrict { + THD *thd= YYTHD; 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->udf.name= $3; lex->name= $4.str; - lex->comment= &$5; + /* $5 is a yacc/bison internal struct, so we can't keep + the pointer to it for use outside the parser. */ + lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING)); + lex->comment->str= $5.str; + lex->comment->length= $5.length; } | ALTER FUNCTION_SYM ident sp_newname sp_comment sp_suid - /* QQ Characteristics missing for now */ opt_restrict { + THD *thd= YYTHD; 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; lex->name= $4.str; - lex->comment= &$5; + /* $5 is a yacc/bison internal struct, so we can't keep + the pointer to it for use outside the parser. */ + lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING)); + lex->comment= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING)); + lex->comment->str= $5.str; + lex->comment->length= $5.length; } ; @@ -5612,7 +5618,7 @@ keyword: | DATETIME {} | DATE_SYM {} | DAY_SYM {} - | DEFINER {} + | DEFINER_SYM {} | DELAY_KEY_WRITE_SYM {} | DES_KEY_FILE {} | DIRECTORY_SYM {} @@ -5648,7 +5654,7 @@ keyword: | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} - | INVOKER {} + | INVOKER_SYM {} | IMPORT {} | INDEXES {} | ISOLATION {} @@ -5735,7 +5741,7 @@ keyword: | RTREE_SYM {} | SAVEPOINT_SYM {} | SECOND_SYM {} - | SECURITY {} + | SECURITY_SYM {} | SERIAL_SYM {} | SERIALIZABLE_SYM {} | SESSION_SYM {} -- cgit v1.2.1