Below is the list of changes that have just been committed into a local
5.0 repository of cmiller. When cmiller 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
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-11-02 17:39:52-05:00, cmiller@stripped +31 -0
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-maint
MERGE: 1.2248.2.91
mysql-test/mysql-test-run.pl@stripped, 2006-11-02 17:39:50-05:00, cmiller@stripped +3 -0
Manual merge.
MERGE: 1.116.1.1
mysql-test/r/innodb_mysql.result@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.10.1.1
mysql-test/r/ps.result@stripped, 2006-11-02 17:39:50-05:00, cmiller@stripped +0 -0
Manual merge.
MERGE: 1.76.1.1
mysql-test/r/view.result@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.180.1.1
mysql-test/t/ctype_utf8.test@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.87.1.11
mysql-test/t/im_daemon_life_cycle.imtest@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.5.1.1
mysql-test/t/innodb_mysql.test@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.8.1.2
mysql-test/t/ps.test@stripped, 2006-11-02 17:39:50-05:00, cmiller@stripped +0 -1
Manual merge.
MERGE: 1.72.1.3
mysql-test/t/sp-error.test@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.108.1.2
mysql-test/t/sp.test@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.202.1.2
mysql-test/t/view.test@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.167.1.1
sql/ha_innodb.cc@stripped, 2006-11-02 17:34:16-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.300.1.1
sql/handler.cc@stripped, 2006-11-02 17:34:17-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.220.1.3
sql/item_func.cc@stripped, 2006-11-02 17:34:17-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.307.1.3
sql/mysqld.cc@stripped, 2006-11-02 17:34:17-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.576.1.2
sql/set_var.cc@stripped, 2006-11-02 17:34:17-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.168.1.2
sql/sp.cc@stripped, 2006-11-02 17:34:17-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.120.1.1
sql/sql_class.h@stripped, 2006-11-02 17:34:17-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.305.1.1
sql/sql_delete.cc@stripped, 2006-11-02 17:34:17-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.179.4.1
sql/sql_lex.cc@stripped, 2006-11-02 17:34:18-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.201.1.3
sql/sql_lex.h@stripped, 2006-11-02 17:34:18-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.225.1.6
sql/sql_parse.cc@stripped, 2006-11-02 17:34:18-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.582.1.4
sql/sql_prepare.cc@stripped, 2006-11-02 17:34:18-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.182.2.1
sql/sql_select.cc@stripped, 2006-11-02 17:34:19-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.467.1.1
sql/sql_table.cc@stripped, 2006-11-02 17:34:19-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.322.1.2
sql/sql_trigger.cc@stripped, 2006-11-02 17:34:19-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.56.1.1
sql/sql_union.cc@stripped, 2006-11-02 17:34:19-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.132.1.1
sql/sql_view.cc@stripped, 2006-11-02 17:34:19-05:00, cmiller@stripped +0 -1
Auto merged
MERGE: 1.92.3.4
sql/sql_yacc.yy@stripped, 2006-11-02 17:34:19-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.491.1.2
sql/table.cc@stripped, 2006-11-02 17:34:20-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.231.1.7
tests/mysql_client_test.c@stripped, 2006-11-02 17:34:20-05:00, cmiller@stripped +0 -0
Auto merged
MERGE: 1.209.1.5
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: cmiller
# Host: zippy.cornsilk.net
# Root: /home/cmiller/work/mysql/mysql-5.0-maint/RESYNC
--- 1.222/sql/handler.cc 2006-11-02 17:40:00 -05:00
+++ 1.223/sql/handler.cc 2006-11-02 17:40:00 -05:00
@@ -1774,12 +1774,22 @@ void handler::print_error(int error, myf
/* Write the dupplicated key in the error message */
char key[MAX_KEY_LENGTH];
String str(key,sizeof(key),system_charset_info);
+
+ if (key_nr == MAX_KEY)
+ {
+ /* Key is unknown */
+ str.copy("", 0, system_charset_info);
+ key_nr= -1;
+ }
+ else
+ {
key_unpack(&str,table,(uint) key_nr);
uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_DUP_ENTRY));
if (str.length() >= max_length)
{
str.length(max_length-4);
str.append(STRING_WITH_LEN("..."));
+ }
}
my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1);
DBUG_VOID_RETURN;
--- 1.577/sql/mysqld.cc 2006-11-02 17:40:00 -05:00
+++ 1.578/sql/mysqld.cc 2006-11-02 17:40:00 -05:00
@@ -2641,19 +2641,43 @@ static int init_common_variables(const c
/* connections and databases needs lots of files */
{
- uint files, wanted_files;
+ uint files, wanted_files, max_open_files;
- wanted_files= 10+(uint) max(max_connections*5,
- max_connections+table_cache_size*2);
- set_if_bigger(wanted_files, open_files_limit);
- files= my_set_max_open_files(wanted_files);
+ /* MyISAM requires two file handles per table. */
+ wanted_files= 10+max_connections+table_cache_size*2;
+ /*
+ We are trying to allocate no less than max_connections*5 file
+ handles (i.e. we are trying to set the limit so that they will
+ be available). In addition, we allocate no less than how much
+ was already allocated. However below we report a warning and
+ recompute values only if we got less file handles than were
+ explicitly requested. No warning and re-computation occur if we
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+ max_open_files= max(max(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
if (files < wanted_files)
{
if (!open_files_limit)
{
- max_connections= (ulong) min((files-10),max_connections);
- table_cache_size= (ulong) max((files-10-max_connections)/2,64);
+ /*
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+ max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+ not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+ table_cache_size= (ulong) min(max((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
DBUG_PRINT("warning",
("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
files, max_connections, table_cache_size));
@@ -5943,8 +5967,8 @@ The minimum value for this variable is 4
0, 0, 0, 0},
{"table_cache", OPT_TABLE_CACHE,
"The number of open tables for all threads.", (gptr*) &table_cache_size,
- (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L,
- 0, 1, 0},
+ (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG,
+ TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
{"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT, "Timeout in "
"seconds to wait for a table level lock before returning an error. Used"
" only if the connection has active cursors.",
--- 1.307/sql/sql_class.h 2006-11-02 17:40:00 -05:00
+++ 1.308/sql/sql_class.h 2006-11-02 17:40:00 -05:00
@@ -646,12 +646,17 @@ typedef struct system_status_var
ulong com_stmt_reset;
ulong com_stmt_close;
+ /*
+ Status variables which it does not make sense to add to
+ global status variable counter
+ */
double last_query_cost;
} STATUS_VAR;
/*
- This is used for 'show status'. It must be updated to the last ulong
- variable in system_status_var
+ This is used for 'SHOW STATUS'. It must be updated to the last ulong
+ variable in system_status_var which is makes sens to add to the global
+ counter
*/
#define last_system_status_var com_stmt_close
--- 1.204/sql/sql_lex.cc 2006-11-02 17:40:00 -05:00
+++ 1.205/sql/sql_lex.cc 2006-11-02 17:40:00 -05:00
@@ -150,7 +150,6 @@ void lex_start(THD *thd, uchar *buf,uint
lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0;
lex->leaf_tables_insert= 0;
- lex->variables_used= 0;
lex->empty_field_list_on_rset= 0;
lex->select_lex.select_number= 1;
lex->next_state=MY_LEX_START;
@@ -1635,9 +1634,18 @@ void Query_tables_list::reset_query_tabl
query_tables_last= &query_tables;
query_tables_own_last= 0;
if (init)
- hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
+ {
+ /*
+ We delay real initialization of hash (and therefore related
+ memory allocation) until first insertion into this hash.
+ */
+ hash_clear(&sroutines);
+ }
else if (sroutines.records)
+ {
+ /* Non-zero sroutines.records means that hash was initialized. */
my_hash_reset(&sroutines);
+ }
sroutines_list.empty();
sroutines_list_own_last= sroutines_list.next;
sroutines_list_own_elements= 0;
--- 1.587/sql/sql_parse.cc 2006-11-02 17:40:00 -05:00
+++ 1.588/sql/sql_parse.cc 2006-11-02 17:40:00 -05:00
@@ -3054,11 +3054,6 @@ end_with_restore_list:
case SQLCOM_ALTER_TABLE:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
-#if defined(DONT_ALLOW_SHOW_COMMANDS)
- my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
- MYF(0)); /* purecov: inspected */
- goto error;
-#else
{
ulong priv=0;
if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
@@ -3124,7 +3119,6 @@ end_with_restore_list:
}
break;
}
-#endif /*DONT_ALLOW_SHOW_COMMANDS*/
case SQLCOM_RENAME_TABLE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -3381,8 +3375,16 @@ end_with_restore_list:
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
lex->update_list, lex->value_list,
lex->duplicates, lex->ignore);
+
+ /*
+ If we have inserted into a VIEW, and the base table has
+ AUTO_INCREMENT column, but this column is not accessible through
+ a view, then we should restore LAST_INSERT_ID to the value it
+ had before the statement.
+ */
if (first_table->view && !first_table->contain_auto_increment)
- thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
+ thd->last_insert_id= thd->current_insert_id;
+
break;
}
case SQLCOM_REPLACE_SELECT:
@@ -3443,8 +3445,15 @@ end_with_restore_list:
select_lex->table_list.first= (byte*) first_table;
}
+ /*
+ If we have inserted into a VIEW, and the base table has
+ AUTO_INCREMENT column, but this column is not accessible through
+ a view, then we should restore LAST_INSERT_ID to the value it
+ had before the statement.
+ */
if (first_table->view && !first_table->contain_auto_increment)
- thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it
+ thd->last_insert_id= thd->current_insert_id;
+
break;
}
case SQLCOM_TRUNCATE:
@@ -5808,14 +5817,19 @@ void mysql_parse(THD *thd, char *inBuf,
DBUG_ASSERT(thd->net.report_error);
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
thd->is_fatal_error));
- query_cache_abort(&thd->net);
- lex->unit.cleanup();
+
+ /*
+ The first thing we do after parse error is freeing sp_head to
+ ensure that we have restored original memroot.
+ */
if (thd->lex->sphead)
{
/* Clean up after failed stored procedure/function */
delete thd->lex->sphead;
thd->lex->sphead= NULL;
}
+ query_cache_abort(&thd->net);
+ lex->unit.cleanup();
}
thd->proc_info="freeing items";
thd->end_statement();
--- 1.470/sql/sql_select.cc 2006-11-02 17:40:00 -05:00
+++ 1.471/sql/sql_select.cc 2006-11-02 17:40:00 -05:00
@@ -11574,7 +11574,7 @@ part_of_refkey(TABLE *table,Field *field
for (uint part=0 ; part < ref_parts ; part++,key_part++)
if (field->eq(key_part->field) &&
- !(key_part->key_part_flag & HA_PART_KEY_SEG))
+ !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART)))
return table->reginfo.join_tab->ref.items[part];
}
return (Item*) 0;
--- 1.324/sql/sql_table.cc 2006-11-02 17:40:00 -05:00
+++ 1.325/sql/sql_table.cc 2006-11-02 17:40:00 -05:00
@@ -2934,208 +2934,6 @@ err:
}
-#ifdef NOT_USED
-/*
- CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
- the proper arguments. This isn't very fast but it should work for most
- cases.
- One should normally create all indexes with CREATE TABLE or ALTER TABLE.
-*/
-
-int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
-{
- List<create_field> fields;
- List<Alter_drop> drop;
- List<Alter_column> alter;
- HA_CREATE_INFO create_info;
- int rc;
- uint idx;
- uint db_options;
- uint key_count;
- TABLE *table;
- Field **f_ptr;
- KEY *key_info_buffer;
- char path[FN_REFLEN+1];
- DBUG_ENTER("mysql_create_index");
-
- /*
- Try to use online generation of index.
- This requires that all indexes can be created online.
- Otherwise, the old alter table procedure is executed.
-
- Open the table to have access to the correct table handler.
- */
- if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
- DBUG_RETURN(-1);
-
- /*
- The add_index method takes an array of KEY structs for the new indexes.
- Preparing a new table structure generates this array.
- It needs a list with all fields of the table, which does not need to
- be correct in every respect. The field names are important.
- */
- for (f_ptr= table->field; *f_ptr; f_ptr++)
- {
- create_field *c_fld= new create_field(*f_ptr, *f_ptr);
- c_fld->unireg_check= Field::NONE; /*avoid multiple auto_increments*/
- fields.push_back(c_fld);
- }
- bzero((char*) &create_info,sizeof(create_info));
- create_info.db_type=DB_TYPE_DEFAULT;
- create_info.default_table_charset= thd->variables.collation_database;
- db_options= 0;
- if (mysql_prepare_table(thd, &create_info, &fields,
- &keys, /*tmp_table*/ 0, &db_options, table->file,
- &key_info_buffer, key_count,
- /*select_field_count*/ 0))
- DBUG_RETURN(-1);
-
- /*
- Check if all keys can be generated with the add_index method.
- If anyone cannot, then take the old way.
- */
- for (idx=0; idx< key_count; idx++)
- {
- DBUG_PRINT("info", ("creating index %s", key_info_buffer[idx].name));
- if (!(table->file->index_ddl_flags(key_info_buffer+idx)&
- (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
- break ;
- }
- if ((idx < key_count)|| !key_count)
- {
- /* Re-initialize the create_info, which was changed by prepare table. */
- bzero((char*) &create_info,sizeof(create_info));
- create_info.db_type=DB_TYPE_DEFAULT;
- create_info.default_table_charset= thd->variables.collation_database;
- /* Cleanup the fields list. We do not want to create existing fields. */
- fields.delete_elements();
- if (real_alter_table(thd, table_list->db, table_list->table_name,
- &create_info, table_list, table,
- fields, keys, drop, alter, 0, (ORDER*)0,
- ALTER_ADD_INDEX, DUP_ERROR))
- /* Don't need to free((gptr) key_info_buffer);*/
- DBUG_RETURN(-1);
- }
- else
- {
- if (table->file->add_index(table, key_info_buffer, key_count)||
- build_table_path(path, sizeof(path), table_list->db,
- (lower_case_table_names == 2) ?
- table_list->alias : table_list->table_name,
- reg_ext) == 0 ||
- mysql_create_frm(thd, path, &create_info,
- fields, key_count, key_info_buffer, table->file))
- /* don't need to free((gptr) key_info_buffer);*/
- DBUG_RETURN(-1);
- }
- /* don't need to free((gptr) key_info_buffer);*/
- DBUG_RETURN(0);
-}
-
-
-int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list,
- List<Alter_drop> &drop)
-{
- List<create_field> fields;
- List<Key> keys;
- List<Alter_column> alter;
- HA_CREATE_INFO create_info;
- uint idx;
- uint db_options;
- uint key_count;
- uint *key_numbers;
- TABLE *table;
- Field **f_ptr;
- KEY *key_info;
- KEY *key_info_buffer;
- char path[FN_REFLEN];
- DBUG_ENTER("mysql_drop_index");
-
- /*
- Try to use online generation of index.
- This requires that all indexes can be created online.
- Otherwise, the old alter table procedure is executed.
-
- Open the table to have access to the correct table handler.
- */
- if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
- DBUG_RETURN(-1);
-
- /*
- The drop_index method takes an array of key numbers.
- It cannot get more entries than keys in the table.
- */
- key_numbers= (uint*) thd->alloc(sizeof(uint*)*table->keys);
- key_count= 0;
-
- /*
- Get the number of each key and check if it can be created online.
- */
- List_iterator<Alter_drop> drop_it(drop);
- Alter_drop *drop_key;
- while ((drop_key= drop_it++))
- {
- /* Find the key in the table. */
- key_info=table->key_info;
- for (idx=0; idx< table->keys; idx++, key_info++)
- {
- if (!my_strcasecmp(system_charset_info, key_info->name, drop_key->name))
- break;
- }
- if (idx>= table->keys)
- {
- my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop_key->name);
- /*don't need to free((gptr) key_numbers);*/
- DBUG_RETURN(-1);
- }
- /*
- Check if the key can be generated with the add_index method.
- If anyone cannot, then take the old way.
- */
- DBUG_PRINT("info", ("dropping index %s", table->key_info[idx].name));
- if (!(table->file->index_ddl_flags(table->key_info+idx)&
- (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
- break ;
- key_numbers[key_count++]= idx;
- }
-
- bzero((char*) &create_info,sizeof(create_info));
- create_info.db_type=DB_TYPE_DEFAULT;
- create_info.default_table_charset= thd->variables.collation_database;
-
- if ((drop_key)|| (drop.elements<= 0))
- {
- if (real_alter_table(thd, table_list->db, table_list->table_name,
- &create_info, table_list, table,
- fields, keys, drop, alter, 0, (ORDER*)0,
- ALTER_DROP_INDEX, DUP_ERROR))
- /*don't need to free((gptr) key_numbers);*/
- DBUG_RETURN(-1);
- }
- else
- {
- db_options= 0;
- if (table->file->drop_index(table, key_numbers, key_count)||
- mysql_prepare_table(thd, &create_info, &fields,
- &keys, /*tmp_table*/ 0, &db_options, table->file,
- &key_info_buffer, key_count,
- /*select_field_count*/ 0)||
- build_table_path(path, sizeof(path), table_list->db,
- (lower_case_table_names == 2) ?
- table_list->alias : table_list->table_name,
- reg_ext) == 0 ||
- mysql_create_frm(thd, path, &create_info,
- fields, key_count, key_info_buffer, table->file))
- /*don't need to free((gptr) key_numbers);*/
- DBUG_RETURN(-1);
- }
-
- /*don't need to free((gptr) key_numbers);*/
- DBUG_RETURN(0);
-}
-#endif /* NOT_USED */
-
-
/*
Alter table
*/
--- 1.493/sql/sql_yacc.yy 2006-11-02 17:40:01 -05:00
+++ 1.494/sql/sql_yacc.yy 2006-11-02 17:40:01 -05:00
@@ -650,11 +650,8 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token UNIX_TIMESTAMP
%token UNKNOWN_SYM
%token UNLOCK_SYM
-%token UNLOCK_SYM
%token UNSIGNED
%token UNTIL_SYM
-%token UNTIL_SYM
-%token UPDATE_SYM
%token UPDATE_SYM
%token UPGRADE_SYM
%token USAGE
@@ -749,7 +746,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%type <item>
literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
- bool_term bool_factor bool_test bool_pri
+ variable variable_aux bool_term bool_factor bool_test bool_pri
predicate bit_expr bit_term bit_factor value_expr term factor
table_wild simple_expr udf_expr
expr_or_default set_expr_or_default interval_expr
@@ -1447,11 +1444,16 @@ call:
lex->value_list.empty();
sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
}
- '(' sp_cparam_list ')' {}
+ opt_sp_cparam_list {}
;
/* CALL parameters */
-sp_cparam_list:
+opt_sp_cparam_list:
+ /* Empty */
+ | '(' opt_sp_cparams ')'
+ ;
+
+opt_sp_cparams:
/* Empty */
| sp_cparams
;
@@ -4325,32 +4327,7 @@ simple_expr:
}
| literal
| param_marker
- | '@' ident_or_text SET_VAR expr
- {
- $$= new Item_func_set_user_var($2,$4);
- LEX *lex= Lex;
- lex->uncacheable(UNCACHEABLE_RAND);
- lex->variables_used= 1;
- }
- | '@' ident_or_text
- {
- $$= new Item_func_get_user_var($2);
- LEX *lex= Lex;
- lex->uncacheable(UNCACHEABLE_RAND);
- lex->variables_used= 1;
- }
- | '@' '@' opt_var_ident_type ident_or_text opt_component
- {
-
- if ($4.str && $5.str && check_reserved_words(&$4))
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- if (!($$= get_system_var(YYTHD, $3, $4, $5)))
- YYABORT;
- Lex->variables_used= 1;
- }
+ | variable
| sum_expr
| simple_expr OR_OR_SYM simple_expr
{ $$= new Item_func_concat($1, $3); }
@@ -5060,6 +5037,46 @@ sum_expr:
$5->empty();
};
+variable:
+ '@'
+ {
+ if (! Lex->parsing_options.allows_variable)
+ {
+ my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+ YYABORT;
+ }
+ }
+ variable_aux
+ {
+ $$= $3;
+ }
+ ;
+
+variable_aux:
+ ident_or_text SET_VAR expr
+ {
+ $$= new Item_func_set_user_var($1, $3);
+ LEX *lex= Lex;
+ lex->uncacheable(UNCACHEABLE_RAND);
+ }
+ | ident_or_text
+ {
+ $$= new Item_func_get_user_var($1);
+ LEX *lex= Lex;
+ lex->uncacheable(UNCACHEABLE_RAND);
+ }
+ | '@' opt_var_ident_type ident_or_text opt_component
+ {
+ if ($3.str && $4.str && check_reserved_words(&$3))
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
+ }
+ if (!($$= get_system_var(YYTHD, $2, $3, $4)))
+ YYABORT;
+ }
+ ;
+
opt_distinct:
/* empty */ { $$ = 0; }
|DISTINCT { $$ = 1; };
@@ -5166,7 +5183,7 @@ when_list2:
/* Warning - may return NULL in case of incomplete SELECT */
table_ref:
table_factor { $$=$1; }
- | join_table { $$=$1; }
+ | join_table
{
LEX *lex= Lex;
if (!($$= lex->current_select->nest_last_join(lex->thd)))
@@ -5208,7 +5225,7 @@ join_table:
| table_ref normal_join table_ref
ON
{
- YYERROR_UNLESS($1 && ($$=$3));
+ YYERROR_UNLESS($1 && $3);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
@@ -5223,7 +5240,7 @@ join_table:
| table_ref STRAIGHT_JOIN table_factor
ON
{
- YYERROR_UNLESS($1 && ($$=$3));
+ YYERROR_UNLESS($1 && $3);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
@@ -5490,6 +5507,13 @@ select_derived_init:
SELECT_SYM
{
LEX *lex= Lex;
+
+ if (! lex->parsing_options.allows_derived)
+ {
+ my_error(ER_VIEW_SELECT_DERIVED, MYF(0));
+ YYABORT;
+ }
+
SELECT_LEX *sel= lex->current_select;
TABLE_LIST *embedding;
if (!sel->embedding || sel->end_nested_join(lex->thd))
@@ -5849,6 +5873,13 @@ procedure_clause:
| PROCEDURE ident /* Procedure name */
{
LEX *lex=Lex;
+
+ if (! lex->parsing_options.allows_select_procedure)
+ {
+ my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE");
+ YYABORT;
+ }
+
if (&lex->select_lex != lex->current_select)
{
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
@@ -5948,28 +5979,40 @@ select_var_ident:
;
into:
- INTO OUTFILE TEXT_STRING_filesystem
+ INTO
+ {
+ if (! Lex->parsing_options.allows_select_into)
+ {
+ my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
+ YYABORT;
+ }
+ }
+ into_destination
+ ;
+
+into_destination:
+ OUTFILE TEXT_STRING_filesystem
{
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- if (!(lex->exchange= new sql_exchange($3.str, 0)) ||
+ if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
!(lex->result= new select_export(lex->exchange)))
YYABORT;
}
opt_field_term opt_line_term
- | INTO DUMPFILE TEXT_STRING_filesystem
+ | DUMPFILE TEXT_STRING_filesystem
{
LEX *lex=Lex;
if (!lex->describe)
{
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- if (!(lex->exchange= new sql_exchange($3.str,1)))
+ if (!(lex->exchange= new sql_exchange($2.str,1)))
YYABORT;
if (!(lex->result= new select_dump(lex->exchange)))
YYABORT;
}
}
- | INTO select_var_list_init
+ | select_var_list_init
{
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
}
@@ -7129,8 +7172,13 @@ param_marker:
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
- Item_param *item= new Item_param((uint) (lex->tok_start -
- (uchar *) thd->query));
+ Item_param *item;
+ if (! lex->parsing_options.allows_variable)
+ {
+ my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+ YYABORT;
+ }
+ item= new Item_param((uint) (lex->tok_start - (uchar *) thd->query));
if (!($$= item) || lex->param_list.push_back(item))
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
@@ -7250,6 +7298,12 @@ simple_ident:
if (spc && (spv = spc->find_variable(&$1)))
{
/* We're compiling a stored procedure and found a variable */
+ if (! lex->parsing_options.allows_variable)
+ {
+ my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+ YYABORT;
+ }
+
Item_splocal *splocal;
splocal= new Item_splocal($1, spv->offset, spv->type,
lex->tok_start_prev -
@@ -7259,7 +7313,6 @@ simple_ident:
splocal->m_sp= lex->sphead;
#endif
$$ = (Item*) splocal;
- lex->variables_used= 1;
lex->safe_to_cache_query=0;
}
else
@@ -9107,6 +9160,24 @@ view_list:
;
view_select:
+ {
+ LEX *lex= Lex;
+ lex->parsing_options.allows_variable= FALSE;
+ lex->parsing_options.allows_select_into= FALSE;
+ lex->parsing_options.allows_select_procedure= FALSE;
+ lex->parsing_options.allows_derived= FALSE;
+ }
+ view_select_aux
+ {
+ LEX *lex= Lex;
+ lex->parsing_options.allows_variable= TRUE;
+ lex->parsing_options.allows_select_into= TRUE;
+ lex->parsing_options.allows_select_procedure= TRUE;
+ lex->parsing_options.allows_derived= TRUE;
+ }
+ ;
+
+view_select_aux:
SELECT_SYM remember_name select_init2
{
THD *thd=YYTHD;
--- 1.234/sql/table.cc 2006-11-02 17:40:01 -05:00
+++ 1.235/sql/table.cc 2006-11-02 17:40:01 -05:00
@@ -834,7 +834,7 @@ int openfrm(THD *thd, const char *name,
as we need to test for NULL = NULL.
*/
if (field->real_maybe_null())
- key_part->key_part_flag|= HA_PART_KEY_SEG;
+ key_part->key_part_flag|= HA_NULL_PART;
}
else
{ // Error: shorten key
--- 1.133/sql/sql_union.cc 2006-11-02 17:40:01 -05:00
+++ 1.134/sql/sql_union.cc 2006-11-02 17:40:01 -05:00
@@ -496,7 +496,12 @@ bool st_select_lex_unit::exec()
DBUG_RETURN(res);
}
/* Needed for the following test and for records_at_start in next loop */
- table->file->info(HA_STATUS_VARIABLE);
+ int error= table->file->info(HA_STATUS_VARIABLE);
+ if(error)
+ {
+ table->file->print_error(error, MYF(0));
+ DBUG_RETURN(1);
+ }
if (found_rows_for_union && !sl->braces &&
select_limit_cnt != HA_POS_ERROR)
{
--- 1.12/mysql-test/r/innodb_mysql.result 2006-11-02 17:40:01 -05:00
+++ 1.13/mysql-test/r/innodb_mysql.result 2006-11-02 17:40:01 -05:00
@@ -303,6 +303,22 @@ b
c
d
drop table t1,t4;
+DROP TABLE IF EXISTS t2, t1;
+CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
+CREATE TABLE t2 (
+i INT NOT NULL,
+FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
+) ENGINE= InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+DELETE IGNORE FROM t1 WHERE i = 1;
+Warnings:
+Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION)
+SELECT * FROM t1, t2;
+i i
+1 1
+DROP TABLE t2, t1;
+End of 4.1 tests.
create table t1 (
a varchar(30), b varchar(30), primary key(a), key(b)
) engine=innodb;
--- 1.12/mysql-test/t/innodb_mysql.test 2006-11-02 17:40:01 -05:00
+++ 1.13/mysql-test/t/innodb_mysql.test 2006-11-02 17:40:01 -05:00
@@ -267,6 +267,36 @@ select distinct a1 from t4 where pk_col
drop table t1,t4;
+
+#
+# BUG#18819: DELETE IGNORE hangs on foreign key parent delete
+#
+# The bug itself does not relate to InnoDB, but we have to use foreign
+# keys to reproduce it.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t2, t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB;
+CREATE TABLE t2 (
+ i INT NOT NULL,
+ FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION
+) ENGINE= InnoDB;
+
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+
+DELETE IGNORE FROM t1 WHERE i = 1;
+
+SELECT * FROM t1, t2;
+
+DROP TABLE t2, t1;
+
+
+--echo End of 4.1 tests.
+
+
#
# Bug #6142: a problem with the empty innodb table
# (was part of group_min_max.test)
--- 1.6/mysql-test/t/im_daemon_life_cycle.imtest 2006-11-02 17:40:01 -05:00
+++ 1.7/mysql-test/t/im_daemon_life_cycle.imtest 2006-11-02 17:40:01 -05:00
@@ -8,6 +8,9 @@
--source include/im_check_env.inc
+# Turn on reconnect, not on by default anymore
+--enable_reconnect
+
###########################################################################
# Kill the IM main process and check that the IM Angel will restart the main
--- 1.91/mysql-test/t/ctype_utf8.test 2006-11-02 17:40:01 -05:00
+++ 1.92/mysql-test/t/ctype_utf8.test 2006-11-02 17:40:01 -05:00
@@ -1232,17 +1232,21 @@ drop table if exists t1;
# Bug#19960: Inconsistent results when joining
# InnoDB tables using partial UTF8 indexes
#
+--disable_warnings
CREATE TABLE t1 (
colA int(11) NOT NULL,
colB varchar(255) character set utf8 NOT NULL,
PRIMARY KEY (colA)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+--enable_warnings
INSERT INTO t1 (colA, colB) VALUES (1, 'foo'), (2, 'foo bar');
+--disable_warnings
CREATE TABLE t2 (
colA int(11) NOT NULL,
colB varchar(255) character set utf8 NOT NULL,
KEY bad (colA,colB(3))
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+--enable_warnings
INSERT INTO t2 (colA, colB) VALUES (1, 'foo'),(2, 'foo bar');
SELECT * FROM t1 JOIN t2 ON t1.colA=t2.colA AND t1.colB=t2.colB
WHERE t1.colA < 3;
--- 1.183/mysql-test/r/view.result 2006-11-02 17:40:01 -05:00
+++ 1.184/mysql-test/r/view.result 2006-11-02 17:40:01 -05:00
@@ -1980,7 +1980,7 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`r
drop view v1;
drop table t1;
set sql_mode='strict_all_tables';
-CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB;
+CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL);
CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1;
CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2;
INSERT INTO t1 (col1) VALUES(12);
@@ -2032,7 +2032,7 @@ f3 f1
1 3
drop view v1;
drop table t1;
-CREATE TABLE t1 (f1 char) ENGINE = innodb;
+CREATE TABLE t1 (f1 char);
INSERT INTO t1 VALUES ('A');
CREATE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES('B');
--- 1.169/mysql-test/t/view.test 2006-11-02 17:40:01 -05:00
+++ 1.170/mysql-test/t/view.test 2006-11-02 17:40:01 -05:00
@@ -1793,7 +1793,7 @@ drop table t1;
# underlying tables (BUG#6443)
#
set sql_mode='strict_all_tables';
-CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB;
+CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL);
CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1;
CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2;
-- error 1364
@@ -1849,7 +1849,7 @@ drop table t1;
#
# Test for bug #11771: wrong query_id in SELECT * FROM <view>
#
-CREATE TABLE t1 (f1 char) ENGINE = innodb;
+CREATE TABLE t1 (f1 char);
INSERT INTO t1 VALUES ('A');
CREATE VIEW v1 AS SELECT * FROM t1;
--- 1.97/sql/sql_view.cc 2006-11-02 17:40:01 -05:00
+++ 1.98/sql/sql_view.cc 2006-11-02 17:40:01 -05:00
@@ -212,6 +212,7 @@ fill_defined_view_parts (THD *thd, TABLE
SYNOPSIS
mysql_create_view()
thd - thread handler
+ views - views to create
mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
RETURN VALUE
@@ -219,7 +220,7 @@ fill_defined_view_parts (THD *thd, TABLE
TRUE Error
*/
-bool mysql_create_view(THD *thd,
+bool mysql_create_view(THD *thd, TABLE_LIST *views,
enum_view_create_mode mode)
{
LEX *lex= thd->lex;
@@ -532,6 +533,50 @@ bool mysql_create_view(THD *thd,
}
VOID(pthread_mutex_lock(&LOCK_open));
res= mysql_register_view(thd, view, mode);
+
+ if (mysql_bin_log.is_open())
+ {
+ String buff;
+ const LEX_STRING command[3]=
+ {{(char *)STRING_WITH_LEN("CREATE ")},
+ {(char *)STRING_WITH_LEN("ALTER ")},
+ {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}};
+
+ buff.append(command[thd->lex->create_view_mode].str,
+ command[thd->lex->create_view_mode].length);
+ view_store_options(thd, views, &buff);
+ buff.append(STRING_WITH_LEN("VIEW "));
+
+ /* Test if user supplied a db (ie: we did not use thd->db) */
+ if (views->db && views->db[0] &&
+ (thd->db == NULL || strcmp(views->db, thd->db)))
+ {
+ append_identifier(thd, &buff, views->db,
+ views->db_length);
+ buff.append('.');
+ }
+ append_identifier(thd, &buff, views->table_name,
+ views->table_name_length);
+ if (lex->view_list.elements)
+ {
+ List_iterator_fast<LEX_STRING> names(lex->view_list);
+ LEX_STRING *name;
+ int i;
+
+ for (i= 0; name= names++; i++)
+ {
+ buff.append(i ? ", " : "(");
+ append_identifier(thd, &buff, name->str, name->length);
+ }
+ buff.append(')');
+ }
+ buff.append(STRING_WITH_LEN(" AS "));
+ buff.append(views->source.str, views->source.length);
+
+ Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
+
VOID(pthread_mutex_unlock(&LOCK_open));
if (view->revision != 1)
query_cache_invalidate3(thd, view, 0);
@@ -1290,12 +1335,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
char *wrong_object_db= NULL, *wrong_object_name= NULL;
bool error= FALSE;
+ VOID(pthread_mutex_lock(&LOCK_open));
for (view= views; view; view= view->next_local)
{
strxnmov(path, FN_REFLEN, mysql_data_home, "/", view->db, "/",
view->table_name, reg_ext, NullS);
(void) unpack_filename(path, path);
- VOID(pthread_mutex_lock(&LOCK_open));
type= FRMTYPE_ERROR;
if (access(path, F_OK) ||
FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used)))
@@ -1307,7 +1352,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
name);
- VOID(pthread_mutex_unlock(&LOCK_open));
continue;
}
if (type == FRMTYPE_TABLE)
@@ -1324,15 +1368,22 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
non_existant_views.append(',');
non_existant_views.append(String(view->table_name,system_charset_info));
}
- VOID(pthread_mutex_unlock(&LOCK_open));
continue;
}
if (my_delete(path, MYF(MY_WME)))
error= TRUE;
query_cache_invalidate3(thd, view, 0);
sp_cache_invalidate();
- VOID(pthread_mutex_unlock(&LOCK_open));
}
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+ Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
+
+ VOID(pthread_mutex_unlock(&LOCK_open));
+
if (error)
{
DBUG_RETURN(TRUE);
--- 1.57/sql/sql_trigger.cc 2006-11-02 17:40:01 -05:00
+++ 1.58/sql/sql_trigger.cc 2006-11-02 17:40:01 -05:00
@@ -36,17 +36,17 @@ static File_option triggers_file_paramet
{
{
{(char *) STRING_WITH_LEN("triggers") },
- offsetof(class Table_triggers_list, definitions_list),
+ my_offsetof(class Table_triggers_list, definitions_list),
FILE_OPTIONS_STRLIST
},
{
{(char *) STRING_WITH_LEN("sql_modes") },
- offsetof(class Table_triggers_list, definition_modes_list),
+ my_offsetof(class Table_triggers_list, definition_modes_list),
FILE_OPTIONS_ULLLIST
},
{
{(char *) STRING_WITH_LEN("definers") },
- offsetof(class Table_triggers_list, definers_list),
+ my_offsetof(class Table_triggers_list, definers_list),
FILE_OPTIONS_STRLIST
},
{ { 0, 0 }, 0, FILE_OPTIONS_STRING }
@@ -55,7 +55,7 @@ static File_option triggers_file_paramet
File_option sql_modes_parameters=
{
{(char*) STRING_WITH_LEN("sql_modes") },
- offsetof(class Table_triggers_list, definition_modes_list),
+ my_offsetof(class Table_triggers_list, definition_modes_list),
FILE_OPTIONS_ULLLIST
};
--- 1.140/mysql-test/mysql-test-run.pl 2006-11-02 17:40:01 -05:00
+++ 1.141/mysql-test/mysql-test-run.pl 2006-11-02 17:40:01 -05:00
@@ -1615,7 +1615,13 @@ sub environment_setup () {
$ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'port'};
$ENV{'MYSQL_TCP_PORT'}= $mysqld_variables{'port'};
+ $ENV{'IM_PATH_SOCK'}= $instance_manager->{path_sock};
+ $ENV{'IM_USERNAME'}= $instance_manager->{admin_login};
+ $ENV{'IM_PASSWORD'}= $instance_manager->{admin_password};
$ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set
+
+ $ENV{'EXE_MYSQL'}= $exe_mysql;
+
# ----------------------------------------------------
# Setup env for NDB
--- 1.301/sql/ha_innodb.cc 2006-11-02 17:40:01 -05:00
+++ 1.302/sql/ha_innodb.cc 2006-11-02 17:40:01 -05:00
@@ -6563,7 +6563,8 @@ ha_innobase::store_lock(
&& lock_type != TL_IGNORE)) {
/* The OR cases above are in this order:
- 1) MySQL is doing LOCK TABLES ... READ LOCAL, or
+ 1) MySQL is doing LOCK TABLES ... READ LOCAL, or we
+ are processing a stored procedure or function, or
2) (we do not know when TL_READ_HIGH_PRIORITY is used), or
3) this is a SELECT ... IN SHARE MODE, or
4) we are doing a complex SQL statement like
@@ -6625,7 +6626,8 @@ ha_innobase::store_lock(
single transaction stored procedure call deterministic
(if it does not use a consistent read). */
- if (lock_type == TL_READ && thd->in_lock_tables) {
+ if (lock_type == TL_READ
+ && thd->lex->sql_command == SQLCOM_LOCK_TABLES) {
/* We come here if MySQL is processing LOCK TABLES
... READ LOCAL. MyISAM under that table lock type
reads the table as it was at the time the lock was
@@ -6684,8 +6686,7 @@ ha_innobase::store_lock(
(MySQL does have thd->in_lock_tables TRUE there). */
if (lock_type == TL_READ_NO_INSERT
- && (!thd->in_lock_tables
- || thd->lex->sql_command == SQLCOM_CALL)) {
+ && thd->lex->sql_command != SQLCOM_LOCK_TABLES) {
lock_type = TL_READ;
}
--- 1.109/mysql-test/t/sp-error.test 2006-11-02 17:40:01 -05:00
+++ 1.110/mysql-test/t/sp-error.test 2006-11-02 17:40:01 -05:00
@@ -1768,6 +1768,47 @@ END;
#
+# BUG#20953: create proc with a create view that uses local
+# vars/params should fail to create
+#
+# See test case for what syntax is forbidden in a view.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT);
+
+# We do not have to drop this procedure and view because they won't be
+# created.
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
+--error ER_VIEW_SELECT_CLAUSE
+CREATE PROCEDURE bug20953()
+ CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
+--error ER_VIEW_SELECT_DERIVED
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1;
+--error ER_VIEW_SELECT_VARIABLE
+CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
+delimiter |;
+--error ER_VIEW_SELECT_VARIABLE
+CREATE PROCEDURE bug20953()
+BEGIN
+ DECLARE i INT;
+ CREATE VIEW v AS SELECT i;
+END |
+delimiter ;|
+--error ER_VIEW_SELECT_VARIABLE
+PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
+
+DROP TABLE t1;
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
--- 1.204/mysql-test/t/sp.test 2006-11-02 17:40:01 -05:00
+++ 1.205/mysql-test/t/sp.test 2006-11-02 17:40:01 -05:00
@@ -6423,6 +6423,170 @@ SELECT bug21493(Member_ID) FROM t3|
DROP FUNCTION bug21493|
DROP TABLE t3,t4|
+#
+# Bug#20028 Function with select return no data
+#
+
+--disable_warnings
+drop function if exists func_20028_a|
+drop function if exists func_20028_b|
+drop function if exists func_20028_c|
+drop procedure if exists proc_20028_a|
+drop procedure if exists proc_20028_b|
+drop procedure if exists proc_20028_c|
+drop table if exists table_20028|
+--enable_warnings
+
+create table table_20028 (i int)|
+
+SET @save_sql_mode=@@sql_mode|
+
+SET sql_mode=''|
+
+create function func_20028_a() returns integer
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+ return ifnull(temp, 0);
+end|
+
+create function func_20028_b() returns integer
+begin
+ return func_20028_a();
+end|
+
+create function func_20028_c() returns integer
+begin
+ declare div_zero integer;
+ set SQL_MODE='TRADITIONAL';
+ select 1/0 into div_zero;
+ return div_zero;
+end|
+
+create procedure proc_20028_a()
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+end|
+
+create procedure proc_20028_b()
+begin
+ call proc_20028_a();
+end|
+
+create procedure proc_20028_c()
+begin
+ declare div_zero integer;
+ set SQL_MODE='TRADITIONAL';
+ select 1/0 into div_zero;
+end|
+
+select func_20028_a()|
+select func_20028_b()|
+--error ER_DIVISION_BY_ZERO
+select func_20028_c()|
+call proc_20028_a()|
+call proc_20028_b()|
+--error ER_DIVISION_BY_ZERO
+call proc_20028_c()|
+
+SET sql_mode='TRADITIONAL'|
+
+drop function func_20028_a|
+drop function func_20028_b|
+drop function func_20028_c|
+drop procedure proc_20028_a|
+drop procedure proc_20028_b|
+drop procedure proc_20028_c|
+
+create function func_20028_a() returns integer
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+ return ifnull(temp, 0);
+end|
+
+create function func_20028_b() returns integer
+begin
+ return func_20028_a();
+end|
+
+create function func_20028_c() returns integer
+begin
+ declare div_zero integer;
+ set SQL_MODE='';
+ select 1/0 into div_zero;
+ return div_zero;
+end|
+
+create procedure proc_20028_a()
+begin
+ declare temp integer;
+ select i into temp from table_20028 limit 1;
+end|
+
+create procedure proc_20028_b()
+begin
+ call proc_20028_a();
+end|
+
+create procedure proc_20028_c()
+begin
+ declare div_zero integer;
+ set SQL_MODE='';
+ select 1/0 into div_zero;
+end|
+
+select func_20028_a()|
+select func_20028_b()|
+select func_20028_c()|
+call proc_20028_a()|
+call proc_20028_b()|
+call proc_20028_c()|
+
+SET @@sql_mode=@save_sql_mode|
+
+drop function func_20028_a|
+drop function func_20028_b|
+drop function func_20028_c|
+drop procedure proc_20028_a|
+drop procedure proc_20028_b|
+drop procedure proc_20028_c|
+drop table table_20028|
+
+#
+# Bug#21462 Stored procedures with no arguments require parenthesis
+#
+
+--disable_warnings
+drop procedure if exists proc_21462_a|
+drop procedure if exists proc_21462_b|
+--enable_warnings
+
+create procedure proc_21462_a()
+begin
+ select "Called A";
+end|
+
+create procedure proc_21462_b(x int)
+begin
+ select "Called B";
+end|
+
+call proc_21462_a|
+call proc_21462_a()|
+-- error ER_SP_WRONG_NO_OF_ARGS
+call proc_21462_a(1)|
+
+-- error ER_SP_WRONG_NO_OF_ARGS
+call proc_21462_b|
+-- error ER_SP_WRONG_NO_OF_ARGS
+call proc_21462_b()|
+call proc_21462_b(1)|
+
+drop procedure proc_21462_a|
+drop procedure proc_21462_b|
+
--echo End of 5.0 tests
--- 1.121/sql/sp.cc 2006-11-02 17:40:01 -05:00
+++ 1.122/sql/sp.cc 2006-11-02 17:40:01 -05:00
@@ -1392,6 +1392,10 @@ static bool add_used_routine(LEX *lex, Q
const LEX_STRING *key,
TABLE_LIST *belong_to_view)
{
+ hash_init_opt(&lex->sroutines, system_charset_info,
+ Query_tables_list::START_SROUTINES_HASH_SIZE,
+ 0, 0, sp_sroutine_key, 0, 0);
+
if (!hash_search(&lex->sroutines, (byte *)key->str, key->length))
{
Sroutine_hash_entry *rn=
--- 1.79/mysql-test/r/ps.result 2006-11-02 17:40:01 -05:00
+++ 1.80/mysql-test/r/ps.result 2006-11-02 17:40:01 -05:00
@@ -1476,4 +1476,21 @@ i
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
DROP PROCEDURE IF EXISTS p1;
+flush status;
+prepare sq from 'show status like "slow_queries"';
+execute sq;
+Variable_name Value
+Slow_queries 0
+prepare no_index from 'select 1 from information_schema.tables limit 1';
+execute sq;
+Variable_name Value
+Slow_queries 0
+execute no_index;
+1
+1
+execute sq;
+Variable_name Value
+Slow_queries 1
+deallocate prepare no_index;
+deallocate prepare sq;
End of 5.0 tests.
--- 1.75/mysql-test/t/ps.test 2006-11-02 17:40:01 -05:00
+++ 1.76/mysql-test/t/ps.test 2006-11-02 17:40:01 -05:00
@@ -988,6 +988,7 @@ execute stmt;
drop temporary table t1;
deallocate prepare stmt;
+
#
# BUG#22085: Crash on the execution of a prepared statement that
# uses an IN subquery with aggregate functions in HAVING
@@ -1040,7 +1041,82 @@ EXECUTE STMT USING @id,@id;
DEALLOCATE PREPARE STMT;
DROP TABLE t1;
---echo End of 4.1 tests
+
+#
+# BUG#21354: (COUNT(*) = 1) not working in SELECT inside prepared
+# statement
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT, INDEX(i));
+INSERT INTO t1 VALUES (1);
+
+PREPARE stmt FROM "SELECT (COUNT(i) = 1), COUNT(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (AVG(i) = 1), AVG(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (VARIANCE(i) = 1), VARIANCE(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (STDDEV(i) = 1), STDDEV(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (BIT_OR(i) = 1), BIT_OR(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (BIT_AND(i) = 1), BIT_AND(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+PREPARE stmt FROM "SELECT (BIT_XOR(i) = 1), BIT_XOR(i) FROM t1 WHERE i = ?";
+SET @a = 0;
+EXECUTE stmt USING @a;
+SET @a = 1;
+EXECUTE stmt USING @a;
+SET @a = 0;
+EXECUTE stmt USING @a;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+
+--echo End of 4.1 tests.
+
+
+
############################# 5.0 tests start ################################
#
#
@@ -1436,6 +1512,25 @@ EXECUTE stmt USING @arg;
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
+
+#
+# BUG#21856: Prepared Statments: crash if bad create
+#
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+let $iterations= 100;
+--disable_query_log
+--disable_result_log
+while ($iterations > 0)
+{
+ --error ER_PARSE_ERROR
+ PREPARE stmt FROM "CREATE PROCEDURE p1()";
+ dec $iterations;
+}
+--enable_query_log
+--enable_result_log
#
# Bug 19764: SHOW commands end up in the slow log as table scans
--- 1.184/sql/sql_prepare.cc 2006-11-02 17:40:01 -05:00
+++ 1.185/sql/sql_prepare.cc 2006-11-02 17:40:01 -05:00
@@ -2788,6 +2788,16 @@ bool Prepared_statement::prepare(const c
error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(this);
+
+ /*
+ The first thing we do after parse error is freeing sp_head to
+ ensure that we have restored original memroot.
+ */
+ if (error && lex->sphead)
+ {
+ delete lex->sphead;
+ lex->sphead= NULL;
+ }
/*
While doing context analysis of the query (in check_prepared_statement)
we allocate a lot of additional memory: for open tables, JOINs, derived
@@ -2813,6 +2823,7 @@ bool Prepared_statement::prepare(const c
if (error == 0)
error= check_prepared_statement(this, name.str != 0);
+ /* Free sp_head if check_prepared_statement() failed. */
if (error && lex->sphead)
{
delete lex->sphead;
--- 1.210/tests/mysql_client_test.c 2006-11-02 17:40:01 -05:00
+++ 1.211/tests/mysql_client_test.c 2006-11-02 17:40:01 -05:00
@@ -121,8 +121,9 @@ static void client_disconnect();
void die(const char *file, int line, const char *expr)
{
+ fflush(stdout);
fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr);
- fflush(NULL);
+ fflush(stderr);
abort();
}
@@ -7496,10 +7497,22 @@ static void test_explain_bug()
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
0, 0, "", 3, 0);
+ if ( mysql_get_server_version(mysql) >= 50027 )
+ {
+ /* The patch for bug#23037 changes column type of DEAULT to blob */
+ verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
+ MYSQL_TYPE_BLOB, 0, 0, "", 0, 0);
+ }
+ else
+ {
verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
+ mysql_get_server_version(mysql) >= 50027 ?
+ MYSQL_TYPE_BLOB :
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
- 0, 0, "", 64, 0);
+ 0, 0, "",
+ mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
+ }
verify_prepare_field(result, 5, "Extra", "EXTRA",
mysql_get_server_version(mysql) <= 50000 ?
@@ -11977,6 +11990,19 @@ static void test_cursors_with_union()
fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
}
+
+static void test_cursors_with_procedure()
+{
+ const char *queries[]=
+ {
+ "SELECT * FROM t1 procedure analyse()"
+ };
+ myheader("test_cursors_with_procedure");
+ fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
+ fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
+}
+
+
/*
Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
should not crash server and should not hang in case of errors.
@@ -14454,6 +14480,7 @@ static void test_bug11718()
printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
"not DATE");
DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
+ mysql_free_result(res);
rc= mysql_query(mysql, "drop table t1, t2");
myquery(rc);
}
@@ -14902,6 +14929,8 @@ static void test_bug15613()
DIE_UNLESS(field[4].length == 255);
DIE_UNLESS(field[5].length == 255);
DIE_UNLESS(field[6].length == 255);
+ mysql_free_result(metadata);
+ mysql_stmt_free_result(stmt);
/* III. Cleanup */
rc= mysql_query(mysql, "drop table t1");
@@ -15078,6 +15107,9 @@ static void test_bug14169()
if (!opt_silent)
printf("GROUP_CONCAT() result type %i", field[1].type);
DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
+ mysql_free_result(res);
+ mysql_stmt_free_result(stmt);
+ mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
@@ -15142,7 +15174,7 @@ static void test_bug15752()
MYSQL mysql_local;
int rc, i;
const int ITERATION_COUNT= 100;
- char *query= "CALL p1()";
+ const char *query= "CALL p1()";
myheader("test_bug15752");
@@ -15501,6 +15533,7 @@ static struct my_tests_st my_tests[]= {
{ "test_view_insert_fields", test_view_insert_fields },
{ "test_basic_cursors", test_basic_cursors },
{ "test_cursors_with_union", test_cursors_with_union },
+ { "test_cursors_with_procedure", test_cursors_with_procedure },
{ "test_truncation", test_truncation },
{ "test_truncation_option", test_truncation_option },
{ "test_client_character_set", test_client_character_set },
| Thread |
|---|
| • bk commit into 5.0 tree (cmiller:1.2284) | Chad MILLER | 2 Nov |