From 467ca505b5c5cb6f1512fc3425fd0f0b8620c099 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Jun 2005 17:27:47 +0300 Subject: [PATCH 1/6] fixed printing of sum(distinct ) & avg(distinct ) & cast(... as decimal) (BUG#7015, BUG#11387) mysql-test/r/view.result: using sum(distinct ), cast(... as decimal) & avg(distinct ) in views mysql-test/t/view.test: using sum(distinct ), cast(... as decimal) & avg(distinct ) in views sql/item.h: Add a comment for Item::print sql/item_func.cc: Use functype(), not func_name() for item equvalence detection sql/item_func.h: Missed function typoes added Add a comment for Item_func::func_name() style fix sql/item_strfunc.cc: Use functype(), not func_name() for item equvalence detection sql/item_strfunc.h: Add missing func_name and func_type sql/item_sum.cc: Item_sum func_name report beggining of function till first argument sql/item_sum.h: Item_sum func_name report beggining of function till first argument sql/item_timefunc.cc: Use functype(), not func_name() for item equvalence detection sql/item_timefunc.h: Add missing func_name and func_type sql/item_uniq.h: Add missing func_name --- mysql-test/r/view.result | 17 +++++++++++++++ mysql-test/t/view.test | 18 ++++++++++++++++ sql/item.h | 12 +++++++++++ sql/item_func.cc | 10 ++++++++- sql/item_func.h | 39 ++++++++++++++++++++++------------ sql/item_strfunc.cc | 2 +- sql/item_strfunc.h | 2 ++ sql/item_sum.cc | 22 ++++++++++++------- sql/item_sum.h | 46 ++++++++++++++++++++++++++-------------- sql/item_timefunc.cc | 4 ++-- sql/item_timefunc.h | 3 +++ sql/item_uniq.h | 2 ++ 12 files changed, 136 insertions(+), 41 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 84be086ae37..b178af1bb1c 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -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; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 0477ab0ea20..23d482254d1 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -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; diff --git a/sql/item.h b/sql/item.h index 820624afd2b..7ab03bae506 100644 --- a/sql/item.h +++ b/sql/item.h @@ -468,6 +468,18 @@ public: */ 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() {} diff --git a/sql/item_func.cc b/sql/item_func.cc index 4dc7e55f195..4d59581675c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -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 && diff --git a/sql/item_func.h b/sql/item_func.h index 1ac1449760f..e0f14ceac75 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -54,7 +54,8 @@ public: 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 @@ public: 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 &list); @@ -306,6 +317,8 @@ public: 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 @@ public: 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 @@ public: 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(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 539bed58e66..9f7a44f6f47 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -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) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6df90cebdff..8d2eb269915 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -573,6 +573,7 @@ public: max_length=args[0]->max_length; } void print(String *str); + const char *func_name() const { return "cast_as_binary"; } }; @@ -648,6 +649,7 @@ public: 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() { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index f7a158ceb5a..76f94801b49 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -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 @@ -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); diff --git a/sql/item_sum.h b/sql/item_sum.h index bb5d31b4b4f..b9a90ee5de5 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -81,7 +81,22 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: void reset_field() {}; void update_field() {}; void cleanup(); + void print(String *str); }; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 564c5e4b9cc..19386c15835 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -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; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index c8fb2b39836..5c172b4698b 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -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 @@ public: 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 diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 14b2e8d53bb..e95aa35101e 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -30,6 +30,7 @@ public: 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 @@ public: } 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"; } }; From 3e4082cd8ebea22b47bf14e3392f822c6499e0d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 18 Jun 2005 18:14:28 +0200 Subject: [PATCH 2/6] BSD make compatibility. bug#9828 --- mysql-test/Makefile.am | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 0480c83296e..0c27edb02e7 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -82,9 +82,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 From 0f92333d6e6a1e2f6350cb781b8c580d957710e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jun 2005 17:02:31 +0400 Subject: [PATCH 3/6] Fix the test for Bug#11111: coding style, a compiler warning, don't use tabs. --- tests/mysql_client_test.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 1cde3a1e978..df268a798e4 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -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"); From c4bd17c0f09551b8bf80eed10c759059dd954987 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jun 2005 17:31:20 +0400 Subject: [PATCH 4/6] Rewrite the test for Bug#9992. --- tests/mysql_client_test.c | 76 ++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index df268a798e4..8bea0a20a0f 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13266,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 */ @@ -13500,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 } }; @@ -13604,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 ***************************************************************************/ @@ -13686,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(); From ac4421442a89ce312cdb657a8318b13390a11cec Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jun 2005 17:39:08 +0200 Subject: [PATCH 5/6] correcting error messages after discussion with Paul (replication of routines). mysql-test/r/rpl_sp.result: result update sql/share/errmsg.txt: correcting error messages after discussion with Paul. --- mysql-test/r/rpl_sp.result | 10 +++++----- sql/share/errmsg.txt | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 7b3249d553a..64e09839f1b 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -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; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index a020cadc084..e7ec69fda39 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -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 From f35c177a2a754c0b09b01c59d1d958f124382c19 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jun 2005 20:06:27 +0200 Subject: [PATCH 6/6] mysql-test-run.pl: Added dummy --manager-port flag, for backward compatibility Back port from 5.0, correction of paths to SSL pem files mtr_cases.pl: Removed hard coded exclude list for embedded server mysql-test-run.pl: Set environment variable MYSQL_SHOW, to be used in test cases mysql-test/lib/mtr_cases.pl: Removed hard coded exclude list for embedded server mysql-test/mysql-test-run.pl: Added dummy --manager-port flag, for backward compatibility Back port from 5.0, correction of paths to SSL pem files --- mysql-test/lib/mtr_cases.pl | 10 ------ mysql-test/mysql-test-run.pl | 66 ++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 43 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index b4f0080a4e9..c07f10c3bf7 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -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 # ---------------------------------------------------------------------- diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 17ddebdcb2b..3f7ba38d83d 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -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"; @@ -1821,11 +1808,12 @@ sub mysqld_arguments ($$$$$) { if ( $opt_with_openssl ) { - mtr_add_arg($args, "%s--ssl-ca=%s/SSL/cacert.pem", $prefix, $glob_basedir); - mtr_add_arg($args, "%s--ssl-cert=%s/SSL/server-cert.pem", $prefix, - $glob_basedir); - mtr_add_arg($args, "%s--ssl-key=%s/SSL/server-key.pem", $prefix, - $glob_basedir); + mtr_add_arg($args, "%s--ssl-ca=%s/std_data/cacert.pem", $prefix, + $glob_mysql_test_dir); + mtr_add_arg($args, "%s--ssl-cert=%s/std_data/server-cert.pem", $prefix, + $glob_mysql_test_dir); + mtr_add_arg($args, "%s--ssl-key=%s/std_data/server-key.pem", $prefix, + $glob_mysql_test_dir); } if ( $opt_warnings ) @@ -2058,6 +2046,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"; @@ -2090,6 +2086,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; @@ -2163,9 +2160,12 @@ sub run_mysqltest ($$) { if ( $opt_with_openssl ) { - mtr_add_arg($args, "--ssl-ca=%s/SSL/cacert.pem", $glob_basedir); - mtr_add_arg($args, "--ssl-cert=%s/SSL/client-cert.pem", $glob_basedir); - mtr_add_arg($args, "--ssl-key=%s/SSL/client-key.pem", $glob_basedir); + mtr_add_arg($args, "--ssl-ca=%s/std_data/cacert.pem", + $glob_mysql_test_dir); + mtr_add_arg($args, "--ssl-cert=%s/std_data/client-cert.pem", + $glob_mysql_test_dir); + mtr_add_arg($args, "--ssl-key=%s/std_data/client-key.pem", + $glob_mysql_test_dir); } mtr_add_arg($args, "-R");