Commit c61278d8 authored by tulin@dl145b.mysql.com's avatar tulin@dl145b.mysql.com

Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0

into dl145b.mysql.com:/home/ndbdev/tomas/mysql-5.1
parents 07b4a42e e58054ad
......@@ -88,9 +88,16 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib
std_data/%.pem:
std_data/client-key.pem:
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/client-cert.pem:
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/cacert.pem:
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/server-cert.pem:
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/server-key.pem:
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
SUFFIXES = .sh
......
......@@ -126,16 +126,6 @@ sub collect_one_test_case($$$$$) {
return;
}
# FIXME temporary solution, we have a hard coded list of test cases to
# skip if we are using the embedded server
if ( $::glob_use_embedded_server and
mtr_match_any_exact($tname,\@::skip_if_embedded_server) )
{
$tinfo->{'skip'}= 1;
return;
}
# ----------------------------------------------------------------------
# Collect information about test case
# ----------------------------------------------------------------------
......
......@@ -100,31 +100,6 @@ require "lib/mtr_misc.pl";
$Devel::Trace::TRACE= 1;
my @skip_if_embedded_server=
(
"alter_table",
"bdb-deadlock",
"connect",
"flush_block_commit",
"grant2",
"grant_cache",
"grant",
"init_connect",
"innodb-deadlock",
"innodb-lock",
"mix_innodb_myisam_binlog",
"mysqlbinlog2",
"mysqlbinlog",
"mysqldump",
"mysql_protocols",
"ps_1general",
"rename",
"show_check",
"system_mysql_db_fix",
"user_var",
"variables",
);
# Used by gcov
our @mysqld_src_dirs=
(
......@@ -196,6 +171,7 @@ our $exe_mysqlbinlog;
our $exe_mysql_client_test;
our $exe_mysqld;
our $exe_mysqldump; # Called from test case
our $exe_mysqlshow; # Called from test case
our $exe_mysql_fix_system_tables;
our $exe_mysqltest;
our $exe_slave_mysqld;
......@@ -241,6 +217,7 @@ our $opt_ndbcluster_port;
our $opt_ndbconnectstring;
our $opt_no_manager; # Does nothing now, we never use manager
our $opt_manager_port; # Does nothing now, we never use manager
our $opt_old_master;
......@@ -495,6 +472,7 @@ sub command_line_setup () {
'master_port=i' => \$opt_master_myport,
'slave_port=i' => \$opt_slave_myport,
'ndbcluster_port=i' => \$opt_ndbcluster_port,
'manager-port' => \$opt_manager_port,
# Test case authoring
'record' => \$opt_record,
......@@ -823,6 +801,14 @@ sub executable_setup () {
{
$exe_mysqldump= "$glob_basedir/client/mysqldump";
}
if ( -f "$glob_basedir/client/.libs/mysqlshow" )
{
$exe_mysqlshow= "$glob_basedir/client/.libs/mysqlshow";
}
else
{
$exe_mysqlshow= "$glob_basedir/client/mysqlshow";
}
if ( -f "$glob_basedir/client/.libs/mysqlbinlog" )
{
$exe_mysqlbinlog= "$glob_basedir/client/.libs/mysqlbinlog";
......@@ -850,6 +836,7 @@ sub executable_setup () {
$path_client_bindir= "$glob_basedir/bin";
$exe_mysqltest= "$path_client_bindir/mysqltest";
$exe_mysqldump= "$path_client_bindir/mysqldump";
$exe_mysqlshow= "$path_client_bindir/mysqlshow";
$exe_mysqlbinlog= "$path_client_bindir/mysqlbinlog";
$exe_mysqladmin= "$path_client_bindir/mysqladmin";
$exe_mysql= "$path_client_bindir/mysql";
......@@ -2056,6 +2043,14 @@ sub run_mysqltest ($$) {
" --debug=d:t:A,$opt_vardir/log/mysqldump.trace";
}
my $cmdline_mysqlshow= "$exe_mysqlshow -uroot " .
"--socket=$master->[0]->{'path_mysock'} --password=";
if ( $opt_debug )
{
$cmdline_mysqlshow .=
" --debug=d:t:A,$opt_vardir/log/mysqlshow.trace";
}
my $cmdline_mysqlbinlog=
"$exe_mysqlbinlog --no-defaults --local-load=$opt_tmpdir";
......@@ -2088,6 +2083,7 @@ sub run_mysqltest ($$) {
$ENV{'MYSQL'}= $cmdline_mysql;
$ENV{'MYSQL_DUMP'}= $cmdline_mysqldump;
$ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow;
$ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog;
$ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables;
$ENV{'MYSQL_CLIENT_TEST'}= $cmdline_mysql_client_test;
......
......@@ -21,7 +21,7 @@ set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end|
ERROR HY000: This routine is declared to be non-deterministic and to modify data and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
ERROR HY000: This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
show binlog events from 98|
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # create database if not exists mysqltest1
......@@ -84,7 +84,7 @@ not deterministic
reads sql data
select * from mysqltest1.t1
alter procedure foo2 contains sql;
ERROR HY000: This routine is declared to be non-deterministic and to modify data and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
ERROR HY000: This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
drop table t1;
create table t1 (a int);
create table t2 like t1;
......@@ -97,7 +97,7 @@ grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1;
create procedure foo4()
deterministic
insert into t1 values (10);
ERROR HY000: You do not have SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
ERROR HY000: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
set global log_bin_trust_routine_creators=1;
create procedure foo4()
deterministic
......@@ -109,7 +109,7 @@ call foo4();
Got one of the listed errors
show warnings;
Level Code Message
Warning 1417 A routine failed and is declared to modify data and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
call foo3();
show warnings;
Level Code Message
......@@ -117,7 +117,7 @@ call foo4();
Got one of the listed errors
show warnings;
Level Code Message
Warning 1417 A routine failed and is declared to modify data and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
alter procedure foo4 sql security invoker;
call foo4();
show warnings;
......
......@@ -1726,3 +1726,20 @@ sum(a)
drop procedure p1;
drop view v1;
drop table t1;
create table t1 (s1 int);
create view v1 as select sum(distinct s1) from t1;
select * from v1;
sum(distinct s1)
NULL
drop view v1;
create view v1 as select avg(distinct s1) from t1;
select * from v1;
avg(distinct s1)
NULL
drop view v1;
drop table t1;
create view v1 as select cast(1 as decimal);
select * from v1;
cast(1 as decimal)
1.00
drop view v1;
......@@ -1569,3 +1569,21 @@ drop procedure p1;
drop view v1;
drop table t1;
#
# using sum(distinct ) & avg(distinct ) in views (BUG#7015)
#
create table t1 (s1 int);
create view v1 as select sum(distinct s1) from t1;
select * from v1;
drop view v1;
create view v1 as select avg(distinct s1) from t1;
select * from v1;
drop view v1;
drop table t1;
#
# using cast(... as decimal) in views (BUG#11387);
#
create view v1 as select cast(1 as decimal);
select * from v1;
drop view v1;
......@@ -468,6 +468,18 @@ class Item {
*/
virtual bool const_during_execution() const
{ return (used_tables() & ~PARAM_TABLE_BIT) == 0; }
/*
This is an essential method for correct functioning of VIEWS.
To save a view in an .frm file we need its unequivocal
definition in SQL that takes into account sql_mode and
environmental settings. Currently such definition is restored
by traversing through the parsed tree of a view and
print()'ing SQL syntax of every node to a String buffer. This
method is used to print the SQL definition of an item. The
second use of this method is for EXPLAIN EXTENDED, to print
the SQL of a query after all optimizations of the parsed tree
have been done.
*/
virtual void print(String *str_arg) { str_arg->append(full_name()); }
void print_item_w_name(String *);
virtual void update_used_tables() {}
......
......@@ -1061,6 +1061,14 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
}
void Item_decimal_typecast::print(String *str)
{
str->append("cast(", 5);
args[0]->print(str);
str->append(" as decimal)", 12);
}
double Item_func_plus::real_op()
{
double value= args[0]->val_real() + args[1]->val_real();
......@@ -4111,7 +4119,7 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
return 1; // Same item is same.
/* Check if other type is also a get_user_var() object */
if (item->type() != FUNC_ITEM ||
((Item_func*) item)->func_name() != func_name())
((Item_func*) item)->functype() != functype())
return 0;
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
return (name.length == other->name.length &&
......
......@@ -54,7 +54,8 @@ class Item_func :public Item_result_field
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC,
GUSERVAR_FUNC};
GUSERVAR_FUNC, COLLATE_FUNC,
EXTRACT_FUNC, CHAR_TYPECAST_FUNC };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }
......@@ -123,7 +124,17 @@ class Item_func :public Item_result_field
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; }
virtual Item *key_item() const { return args[0]; }
virtual const char *func_name() const { return "?"; }
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
*/
virtual const char *func_name() const= 0;
virtual bool const_item() const { return const_item_cache; }
inline Item **arguments() const { return args; }
void set_arguments(List<Item> &list);
......@@ -306,6 +317,8 @@ class Item_decimal_typecast :public Item_func
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
void fix_length_and_dec() {};
const char *func_name() const { return "decimal_typecast"; }
void print(String *);
};
......@@ -506,7 +519,7 @@ class Item_func_pow :public Item_dec_func
class Item_func_acos :public Item_dec_func
{
public:
public:
Item_func_acos(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "acos"; }
......@@ -514,7 +527,7 @@ class Item_func_acos :public Item_dec_func
class Item_func_asin :public Item_dec_func
{
public:
public:
Item_func_asin(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "asin"; }
......@@ -522,7 +535,7 @@ class Item_func_asin :public Item_dec_func
class Item_func_atan :public Item_dec_func
{
public:
public:
Item_func_atan(Item *a) :Item_dec_func(a) {}
Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
double val_real();
......@@ -531,7 +544,7 @@ class Item_func_atan :public Item_dec_func
class Item_func_cos :public Item_dec_func
{
public:
public:
Item_func_cos(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "cos"; }
......@@ -539,7 +552,7 @@ class Item_func_cos :public Item_dec_func
class Item_func_sin :public Item_dec_func
{
public:
public:
Item_func_sin(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "sin"; }
......@@ -547,7 +560,7 @@ class Item_func_sin :public Item_dec_func
class Item_func_tan :public Item_dec_func
{
public:
public:
Item_func_tan(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "tan"; }
......@@ -634,7 +647,7 @@ class Item_func_units :public Item_real_func
{
char *name;
double mul,add;
public:
public:
Item_func_units(char *name_arg,Item *a,double mul_arg,double add_arg)
:Item_real_func(a),name(name_arg),mul(mul_arg),add(add_arg) {}
double val_real();
......@@ -853,7 +866,7 @@ class Item_func_last_insert_id :public Item_int_func
class Item_func_benchmark :public Item_int_func
{
ulong loop_count;
public:
public:
Item_func_benchmark(ulong loop_count_arg,Item *expr)
:Item_int_func(expr), loop_count(loop_count_arg)
{}
......@@ -868,7 +881,7 @@ class Item_func_benchmark :public Item_int_func
class Item_udf_func :public Item_func
{
protected:
protected:
udf_handler udf;
public:
......@@ -1046,7 +1059,7 @@ class Item_func_get_lock :public Item_int_func
class Item_func_release_lock :public Item_int_func
{
String value;
public:
public:
Item_func_release_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "release_lock"; }
......@@ -1058,7 +1071,7 @@ class Item_func_release_lock :public Item_int_func
class Item_master_pos_wait :public Item_int_func
{
String value;
public:
public:
Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {}
Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
longlong val_int();
......
......@@ -2297,7 +2297,7 @@ bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const
return 0;
Item_func *item_func=(Item_func*) item;
if (arg_count != item_func->arg_count ||
func_name() != item_func->func_name())
functype() != item_func->functype())
return 0;
Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item;
if (collation.collation != item_func_sc->collation.collation)
......
......@@ -573,6 +573,7 @@ class Item_func_binary :public Item_str_func
max_length=args[0]->max_length;
}
void print(String *str);
const char *func_name() const { return "cast_as_binary"; }
};
......@@ -648,6 +649,7 @@ class Item_func_set_collation :public Item_str_func
void fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "collate"; }
enum Functype func_type() const { return COLLATE_FUNC; }
void print(String *str);
Item_field *filed_for_view_update()
{
......
......@@ -86,7 +86,6 @@ void Item_sum::make_field(Send_field *tmp_field)
void Item_sum::print(String *str)
{
str->append(func_name());
str->append('(');
for (uint i=0 ; i < arg_count ; i++)
{
if (i)
......@@ -2425,13 +2424,6 @@ longlong Item_sum_count_distinct::val_int()
}
void Item_sum_count_distinct::print(String *str)
{
str->append("count(distinct ", 15);
args[0]->print(str);
str->append(')');
}
/****************************************************************************
** Functions to handle dynamic loadable aggregates
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
......@@ -2466,6 +2458,20 @@ void Item_udf_sum::cleanup()
}
void Item_udf_sum::print(String *str)
{
str->append(func_name());
str->append('(');
for (uint i=0 ; i < arg_count ; i++)
{
if (i)
str->append(',');
args[i]->print(str);
}
str->append(')');
}
Item *Item_sum_udf_float::copy_or_same(THD* thd)
{
return new (thd->mem_root) Item_sum_udf_float(thd, this);
......
......@@ -81,7 +81,22 @@ class Item_sum :public Item_result_field
virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual const char *func_name() const { return "?"; }
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
NOTE: for Items inherited from Item_sum, func_name() return part of
function name till first argument (including '(') to make difference in
names for functions with 'distinct' clause and without 'distinct' and
also to make printing of items inherited from Item_sum uniform.
*/
virtual const char *func_name() const= 0;
virtual Item *result_item(Field *field)
{ return new Item_field(field);}
table_map used_tables() const { return ~(table_map) 0; } /* Not used */
......@@ -159,7 +174,7 @@ class Item_sum_sum :public Item_sum_num
void reset_field();
void update_field();
void no_rows_in_result() {}
const char *func_name() const { return "sum"; }
const char *func_name() const { return "sum("; }
Item *copy_or_same(THD* thd);
};
......@@ -200,7 +215,6 @@ class Item_sum_distinct :public Item_sum_num
enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
void reset_field() {} // not used
void update_field() {} // not used
const char *func_name() const { return "sum_distinct"; }
virtual void no_rows_in_result() {}
void fix_length_and_dec();
enum Item_result result_type () const { return val.traits->type(); }
......@@ -224,7 +238,7 @@ class Item_sum_sum_distinct :public Item_sum_distinct
Item_sum_sum_distinct(Item *item_arg) :Item_sum_distinct(item_arg) {}
enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
const char *func_name() const { return "sum_distinct"; }
const char *func_name() const { return "sum(distinct "; }
Item *copy_or_same(THD* thd) { return new Item_sum_sum_distinct(thd, this); }
};
......@@ -243,7 +257,7 @@ class Item_sum_avg_distinct: public Item_sum_distinct
void fix_length_and_dec();
virtual void calculate_val_and_count();
enum Sumfunctype sum_func () const { return AVG_DISTINCT_FUNC; }
const char *func_name() const { return "avg_distinct"; }
const char *func_name() const { return "avg(distinct "; }
Item *copy_or_same(THD* thd) { return new Item_sum_avg_distinct(thd, this); }
};
......@@ -272,7 +286,7 @@ class Item_sum_count :public Item_sum_int
void reset_field();
void cleanup();
void update_field();
const char *func_name() const { return "count"; }
const char *func_name() const { return "count("; }
Item *copy_or_same(THD* thd);
};
......@@ -326,12 +340,11 @@ class Item_sum_count_distinct :public Item_sum_int
longlong val_int();
void reset_field() { return ;} // Never called
void update_field() { return ; } // Never called
const char *func_name() const { return "count_distinct"; }
const char *func_name() const { return "count(distinct "; }
bool setup(THD *thd);
void make_unique();
Item *copy_or_same(THD* thd);
void no_rows_in_result() {}
void print(String *str);
};
......@@ -389,7 +402,7 @@ class Item_sum_avg :public Item_sum_sum
Item *result_item(Field *field)
{ return new Item_avg_field(hybrid_type, this); }
void no_rows_in_result() {}
const char *func_name() const { return "avg"; }
const char *func_name() const { return "avg("; }
Item *copy_or_same(THD* thd);
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
};
......@@ -466,7 +479,7 @@ class Item_sum_variance : public Item_sum_num
Item *result_item(Field *field)
{ return new Item_variance_field(this); }
void no_rows_in_result() {}
const char *func_name() const { return "variance"; }
const char *func_name() const { return "variance("; }
Item *copy_or_same(THD* thd);
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
enum Item_result result_type () const { return hybrid_type; }
......@@ -501,7 +514,7 @@ class Item_sum_std :public Item_sum_variance
double val_real();
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
const char *func_name() const { return "std("; }
Item *copy_or_same(THD* thd);
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
......@@ -565,7 +578,7 @@ class Item_sum_min :public Item_sum_hybrid
enum Sumfunctype sum_func () const {return MIN_FUNC;}
bool add();
const char *func_name() const { return "min"; }
const char *func_name() const { return "min("; }
Item *copy_or_same(THD* thd);
};
......@@ -578,7 +591,7 @@ class Item_sum_max :public Item_sum_hybrid
enum Sumfunctype sum_func () const {return MAX_FUNC;}
bool add();
const char *func_name() const { return "max"; }
const char *func_name() const { return "max("; }
Item *copy_or_same(THD* thd);
};
......@@ -609,7 +622,7 @@ class Item_sum_or :public Item_sum_bit
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {}
bool add();
const char *func_name() const { return "bit_or"; }
const char *func_name() const { return "bit_or("; }
Item *copy_or_same(THD* thd);
};
......@@ -620,7 +633,7 @@ class Item_sum_and :public Item_sum_bit
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {}
Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
bool add();
const char *func_name() const { return "bit_and"; }
const char *func_name() const { return "bit_and("; }
Item *copy_or_same(THD* thd);
};
......@@ -630,7 +643,7 @@ class Item_sum_xor :public Item_sum_bit
Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
bool add();
const char *func_name() const { return "bit_xor"; }
const char *func_name() const { return "bit_xor("; }
Item *copy_or_same(THD* thd);
};
......@@ -668,6 +681,7 @@ class Item_udf_sum : public Item_sum
void reset_field() {};
void update_field() {};
void cleanup();
void print(String *str);
};
......
......@@ -2158,7 +2158,7 @@ bool Item_extract::eq(const Item *item, bool binary_cmp) const
if (this == item)
return 1;
if (item->type() != FUNC_ITEM ||
func_name() != ((Item_func*)item)->func_name())
functype() != ((Item_func*)item)->functype())
return 0;
Item_extract* ie= (Item_extract*)item;
......@@ -2176,7 +2176,7 @@ bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
if (this == item)
return 1;
if (item->type() != FUNC_ITEM ||
func_name() != ((Item_func*)item)->func_name())
functype() != ((Item_func*)item)->functype())
return 0;
Item_char_typecast *cast= (Item_char_typecast*)item;
......
......@@ -637,6 +637,7 @@ class Item_extract :public Item_int_func
Item_extract(interval_type type_arg, Item *a)
:Item_int_func(a), int_type(type_arg) {}
longlong val_int();
enum Functype functype() const { return EXTRACT_FUNC; }
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
......@@ -689,6 +690,7 @@ class Item_char_typecast :public Item_typecast
public:
Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg)
:Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {}
enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "cast_as_char"; }
const char* cast_type() const { return "char"; };
......@@ -790,6 +792,7 @@ class Item_func_add_time :public Item_str_func
return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin));
}
void print(String *str);
const char *func_name() const { return "add_time"; }
};
class Item_func_timediff :public Item_str_func
......
......@@ -30,6 +30,7 @@ class Item_func_unique_users :public Item_real_func
double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
void fix_length_and_dec() { decimals=0; max_length=6; }
void print(String *str) { str->append("0.0", 3); }
const char *func_name() const { return "unique_users"; }
};
......@@ -58,4 +59,5 @@ class Item_sum_unique_users :public Item_sum_num
}
void print(String *str) { str->append("0.0", 3); }
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
const char *func_name() const { return "sum_unique_users"; }
};
......@@ -5347,11 +5347,11 @@ ER_SP_NO_RETSET_IN_FUNC 0A000
ER_CANT_CREATE_GEOMETRY_OBJECT 22003
eng "Cannot get geometry object from data you send to the GEOMETRY field"
ER_FAILED_ROUTINE_BREAK_BINLOG
eng "A routine failed and is declared to modify data and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes"
eng "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes"
ER_BINLOG_UNSAFE_ROUTINE
eng "This routine is declared to be non-deterministic and to modify data and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
eng "This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
ER_BINLOG_CREATE_ROUTINE_NEED_SUPER
eng "You do not have SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
eng "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
ER_EXEC_STMT_WITH_OPEN_CURSOR
eng "You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it."
ER_STMT_HAS_NO_OPEN_CURSOR
......
......@@ -13151,13 +13151,14 @@ static void test_bug9643()
static void test_bug11111()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
char buf[2][20];
long len[2];
MYSQL_STMT *stmt;
MYSQL_BIND bind[2];
char buf[2][20];
ulong len[2];
int i;
int rc;
const char * query = "SELECT DISTINCT f1,ff2 FROM v1";
const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
myheader("test_bug11111");
rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
......@@ -13175,24 +13176,27 @@ static void test_bug11111()
rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
myquery(rc);
stmt = mysql_stmt_init(mysql);
stmt= mysql_stmt_init(mysql);
mysql_stmt_prepare(stmt, query, strlen(query));
mysql_stmt_execute(stmt);
for (i=0; i < 2; i++) {
memset(&bind[i], '\0', sizeof(MYSQL_BIND));
bzero(bind, sizeof(bind));
for (i=0; i < 2; i++)
{
bind[i].buffer_type= MYSQL_TYPE_STRING;
bind[i].buffer= (gptr *)&buf[i];
bind[i].buffer_length= 20;
bind[i].length= &len[i];
}
if (mysql_stmt_bind_result(stmt, bind))
printf("Error: %s\n", mysql_stmt_error(stmt));
rc= mysql_stmt_bind_result(stmt, bind);
check_execute(stmt, rc);
mysql_stmt_fetch(stmt);
printf("return: %s", buf[1]);
rc= mysql_stmt_fetch(stmt);
check_execute(stmt, rc);
if (!opt_silent)
printf("return: %s", buf[1]);
DIE_UNLESS(!strcmp(buf[1],"1"));
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop view v1");
......@@ -13262,6 +13266,59 @@ static void test_bug10729()
myquery(rc);
}
/*
Check that mysql_next_result works properly in case when one of
the statements used in a multi-statement query is erroneous
*/
static void test_bug9992()
{
MYSQL *mysql1;
MYSQL_RES* res ;
int rc;
myheader("test_bug9992");
if (!opt_silent)
printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
mysql1= mysql_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
CLIENT_MULTI_STATEMENTS))
{
fprintf(stderr, "Failed to connect to the database\n");
DIE_UNLESS(0);
}
/* Sic: SHOW DATABASE is incorrect syntax. */
rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
if (rc)
{
fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
DIE_UNLESS(0);
}
if (!opt_silent)
printf("Testing mysql_store_result/mysql_next_result..\n");
res= mysql_store_result(mysql1);
DIE_UNLESS(res);
mysql_free_result(res);
rc= mysql_next_result(mysql1);
DIE_UNLESS(rc == 1); /* Got errors, as expected */
if (!opt_silent)
fprintf(stdout, "Got error, sa expected:\n [%d] %s\n",
mysql_errno(mysql1), mysql_error(mysql1));
mysql_close(mysql1);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
......@@ -13496,6 +13553,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug9643", test_bug9643 },
{ "test_bug10729", test_bug10729 },
{ "test_bug11111", test_bug11111 },
{ "test_bug9992", test_bug9992 },
{ 0, 0 }
};
......@@ -13600,23 +13658,6 @@ static void print_test_output()
}
}
static void check_mupltiquery_bug9992()
{
MYSQL_RES* res ;
mysql_query(mysql,"SHOW TABLES;SHOW DATABASE;SELECT 1;");
fprintf(stdout, "\n\n!!! check_mupltiquery_bug9992 !!!\n");
do
{
if (!(res= mysql_store_result(mysql)))
return;
mysql_free_result(res);
} while (!mysql_next_result(mysql));
fprintf(stdout, "\n\n!!! SUCCESS !!!\n");
return;
}
/***************************************************************************
main routine
***************************************************************************/
......@@ -13682,10 +13723,7 @@ int main(int argc, char **argv)
}
client_disconnect(); /* disconnect from server */
client_connect(CLIENT_MULTI_STATEMENTS);
check_mupltiquery_bug9992();
client_disconnect();
free_defaults(defaults_argv);
print_test_output();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment