From 2eb623a4f0db979c9d41513368fd569d7de88d7e Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 21 Nov 2002 11:01:33 +0200 Subject: [PATCH 01/10] prevent using references on sum function (except HAVING clouse of current select) and forward references --- include/mysqld_error.h | 3 +- mysql-test/r/subselect.result | 12 ++++++-- mysql-test/t/subselect.test | 11 ++++++-- sql/item.cc | 46 +++++++++++++++++++++++++++++-- sql/item.h | 1 + sql/item_cmpfunc.cc | 2 ++ sql/item_func.cc | 1 + sql/item_func.h | 1 + sql/item_strfunc.cc | 2 ++ sql/item_subselect.cc | 1 + sql/item_sum.cc | 2 ++ sql/item_sum.h | 1 + sql/item_uniq.h | 6 +++- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + 36 files changed, 104 insertions(+), 8 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 456d675a045..82d08cef0d4 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -260,4 +260,5 @@ #define ER_UNKNOWN_STMT_HANDLER 1241 #define ER_CORRUPT_HELP_DB 1242 #define ER_CYCLIC_REFERENCE 1243 -#define ER_ERROR_MESSAGES 244 +#define ER_ILLEGAL_REFERENCE 1244 +#define ER_ERROR_MESSAGES 245 diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index e54e1fb0fef..df56a43e5ba 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -9,9 +9,9 @@ SELECT (SELECT (SELECT 0 UNION SELECT 0)); (SELECT (SELECT 0 UNION SELECT 0)) 0 SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; -Cyclic reference on subqueries +Reference 'a' not supported (forward reference in item list) SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; -Cyclic reference on subqueries +Reference 'b' not supported (forward reference in item list) drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); @@ -20,6 +20,8 @@ create table t4 (a int, b int); insert into t1 values (2); insert into t2 values (1,7),(2,7); insert into t4 values (4,8),(3,8),(5,9); +select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1; +Reference 'a1' not supported (forward reference in item list) select (select a from t1 where t1.a=t2.a), a from t2; (select a from t1 where t1.a=t2.a) a NULL 1 @@ -278,6 +280,12 @@ PRIMARY KEY (`numeropost`,`numreponse`), UNIQUE KEY `numreponse` (`numreponse`), KEY `pseudo` (`pseudo`,`numeropost`) ) TYPE=MyISAM; +SELECT (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=a),numreponse FROM (SELECT * FROM threadhardwarefr7) as a; +Reference 'numreponse' not supported (forward reference in item list) +SELECT numreponse, (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=a) FROM (SELECT * FROM threadhardwarefr7) as a; +Unknown column 'a' in 'having clause' +SELECT numreponse, (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=1) FROM (SELECT * FROM threadhardwarefr7) as a; +numreponse (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=1) INSERT INTO threadhardwarefr7 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test'); EXPLAIN SELECT numreponse FROM threadhardwarefr7 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM threadhardwarefr7 WHERE numeropost='1'); Subselect returns more than 1 record diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 7a507be4ed2..68deebd2177 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1,9 +1,9 @@ select (select 2); SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); --- error 1243 +-- error 1244 SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; --- error 1243 +-- error 1244 SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); @@ -13,6 +13,8 @@ create table t4 (a int, b int); insert into t1 values (2); insert into t2 values (1,7),(2,7); insert into t4 values (4,8),(3,8),(5,9); +-- error 1244 +select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1; select (select a from t1 where t1.a=t2.a), a from t2; select (select a from t1 where t1.a=t2.b), a from t2; select (select a from t1), a from t2; @@ -176,6 +178,11 @@ CREATE TABLE `threadhardwarefr7` ( UNIQUE KEY `numreponse` (`numreponse`), KEY `pseudo` (`pseudo`,`numeropost`) ) TYPE=MyISAM; +-- error 1244 +SELECT (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=a),numreponse FROM (SELECT * FROM threadhardwarefr7) as a; +-- error 1054 +SELECT numreponse, (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=a) FROM (SELECT * FROM threadhardwarefr7) as a; +SELECT numreponse, (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=1) FROM (SELECT * FROM threadhardwarefr7) as a; INSERT INTO threadhardwarefr7 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test'); -- error 1240 EXPLAIN SELECT numreponse FROM threadhardwarefr7 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM threadhardwarefr7 WHERE numeropost='1'); diff --git a/sql/item.cc b/sql/item.cc index 48ec11d02c2..b56486c5027 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -34,7 +34,8 @@ void item_init(void) item_user_lock_init(); } -Item::Item() +Item::Item(): + fixed(0) { marker=0; maybe_null=null_value=with_sum_func=unsigned_flag=0; @@ -139,6 +140,7 @@ CHARSET_INFO * Item::thd_charset() const Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) { set_field(f); + fixed= 1; // This item is not needed in fix_fields } @@ -438,6 +440,7 @@ bool Item::fix_fields(THD *thd, struct st_table_list *list, Item ** ref) { + fixed= 1; return 0; } @@ -459,23 +462,48 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) */ SELECT_LEX *last= 0; + Item **refer= (Item **)not_found_item; // Prevent using outer fields in subselects, that is not supported now if (thd->lex.current_select->linkage != DERIVED_TABLE_TYPE) for (SELECT_LEX *sl= thd->lex.current_select->outer_select(); sl; sl= sl->outer_select()) + { if ((tmp= find_field_in_tables(thd, this, (last= sl)->get_table_list(), 0)) != not_found_field) break; + if((refer= find_item_in_list(this, (last= sl)->item_list, + REPORT_EXCEPT_NOT_FOUND)) != + (Item **)not_found_item) + break; + + } if (!tmp) return -1; - else if (tmp == not_found_field) + else if (!refer) + return 1; + else if (tmp == not_found_field && refer == (Item **)not_found_item) { // call to return error code find_field_in_tables(thd, this, tables, 1); return -1; } + else if (refer != (Item **)not_found_item) + { + Item_ref *r; + *ref= r= new Item_ref((char *)db_name, (char *)table_name, + (char *)field_name); + if (!r) + return 1; + int res; + if ((res= r->fix_fields(thd, tables, ref))) + return res; + r->depended_from= last; + thd->lex.current_select->mark_as_dependent(last); + thd->add_possible_loop(r); + return 0; + } else { depended_from= last; @@ -507,6 +535,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 1; return (*ref)->fix_fields(thd, tables, ref); } + fixed= 1; return 0; } @@ -885,6 +914,19 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) maybe_null= (*ref)->maybe_null; decimals= (*ref)->decimals; } + if (((*ref)->with_sum_func && + (depended_from || + !(thd->lex.current_select->linkage != GLOBAL_OPTIONS_TYPE && + thd->lex.current_select->select_lex()->having_fix_field))) || + !(*ref)->fixed) + { + my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, + ((*ref)->with_sum_func? + "reference on group function": + "forward reference in item list")); + return 1; + } + fixed= 1; return 0; } diff --git a/sql/item.h b/sql/item.h index c67c16c50ad..7228b5dc785 100644 --- a/sql/item.h +++ b/sql/item.h @@ -46,6 +46,7 @@ public: my_bool null_value; /* if item is null */ my_bool unsigned_flag; my_bool with_sum_func; + my_bool fixed; /* If item fixed with fix_fields */ // alloc & destruct is done as start of select using sql_alloc Item(); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 74eb5734ecf..a3c8328bb06 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1152,6 +1152,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (thd) thd->cond_count+=list.elements; fix_length_and_dec(); + fixed= 1; return 0; } @@ -1425,6 +1426,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } else maybe_null=1; + fixed= 1; return 0; } diff --git a/sql/item_func.cc b/sql/item_func.cc index aa39b3cc857..140d432b794 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -123,6 +123,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } } fix_length_and_dec(); + fixed= 1; return 0; } diff --git a/sql/item_func.h b/sql/item_func.h index 581809fc9cb..4dd9088c5c8 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -742,6 +742,7 @@ public: bool res= udf.fix_fields(thd, tables, this, arg_count, args); used_tables_cache= udf.used_tables_cache; const_item_cache= udf.const_item_cache; + fixed= 1; return res; } Item_result result_type () const { return udf.result_type(); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1a561c9eb34..6a0aaa3b032 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2065,6 +2065,7 @@ bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables, I const_item_cache=args[0]->const_item(); set_charset(conv_charset); fix_length_and_dec(); + fixed= 1; return 0; } @@ -2099,6 +2100,7 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, used_tables_cache=args[0]->used_tables(); const_item_cache=args[0]->const_item(); fix_length_and_dec(); + fixed= 1; return 0; } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 1f1944026ef..01ce5fad4a6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -92,6 +92,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } fix_length_and_dec(); } + fixed= 1; return res; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index db4c45fc412..9c7a73a6904 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -135,6 +135,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) null_value=1; fix_length_and_dec(); thd->allow_sum_func=1; // Allow group functions + fixed= 1; return 0; } @@ -165,6 +166,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) null_value=1; fix_length_and_dec(); thd->allow_sum_func=1; // Allow group functions + fixed= 1; return 0; } diff --git a/sql/item_sum.h b/sql/item_sum.h index 3e67f1e3624..cc49ac8578f 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -384,6 +384,7 @@ public: const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + fixed= 1; return udf.fix_fields(thd,tables,this,this->arg_count,this->args); } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } diff --git a/sql/item_uniq.h b/sql/item_uniq.h index f0d1d353cfb..2004be63de2 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -43,5 +43,9 @@ public: bool add() { return 0; } void reset_field() {} void update_field(int offset) {} - bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { return 0;} + bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) + { + fixed= 1; + return 0; + } }; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index d43a433da06..14414326c06 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -254,3 +254,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 3a947bcbe38..8bc6cec83ee 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -248,3 +248,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 1cb81849be1..9b4865ffdf3 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -256,3 +256,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 6e96fdb393e..8057e218be6 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -245,3 +245,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 394c40c5778..206d9c69568 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -250,3 +250,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index b18d3f8fb38..b675985c310 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -245,3 +245,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 49ea31dd05b..6fb265df3e4 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -248,3 +248,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index b203c63949b..f72bf188140 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -245,3 +245,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 07081e689ad..7fb896a5632 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -247,3 +247,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 0a380e2b48f..93e4bee9b11 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -245,3 +245,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 2e0a083ca06..62d3c249e8d 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -247,3 +247,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 19fcf98e3c7..f74b159dd64 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -245,3 +245,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 810aaf38f74..82ab76821f7 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -247,3 +247,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index a74a0a910b8..ab1a1833011 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -247,3 +247,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index efde31ff4c9..111261bbe84 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -249,3 +249,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index e90d5844b9b..03dab8ebe5c 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -245,3 +245,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 18f0bf7f79d..93e25ef637a 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -249,3 +249,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 790d738031c..4427104f2ef 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -248,3 +248,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Циклическая ссылка на подзапрос", +"Ссылка '%-.64s' не поддерживается (%s)", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index e8186d38a5b..ad6bfe90129 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -241,3 +241,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 216d46fcd3a..55837225b60 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -253,3 +253,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 5076b1b6679..ed26f8b9e98 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -246,3 +246,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index a3bb40fb4f5..dd836493ca8 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -245,3 +245,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", +"Reference '%-.64s' not supported (%s)", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 426c2a14e3b..801e8ff4112 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -250,3 +250,4 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Циклiчне посилання на пiдзапит", +"Посилання '%-.64s' не пiдтримуется (%s)", From 4d7a8801961bcd218b0190ec169e654aa442adb7 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 21 Nov 2002 16:04:59 +0200 Subject: [PATCH 02/10] after merging fix --- include/mysqld_error.h | 2 +- mysql-test/t/subselect.test | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 11d831fe85a..ed83c5e57a8 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -261,5 +261,5 @@ #define ER_CORRUPT_HELP_DB 1242 #define ER_CYCLIC_REFERENCE 1243 #define ER_AUTO_CONVERT 1244 -#define ER_ILLEGAL_REFERENCE 1246 +#define ER_ILLEGAL_REFERENCE 1245 #define ER_ERROR_MESSAGES 246 diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 68deebd2177..b9edd0e3396 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1,9 +1,9 @@ select (select 2); SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); --- error 1244 +-- error 1245 SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; --- error 1244 +-- error 1245 SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); @@ -13,7 +13,7 @@ create table t4 (a int, b int); insert into t1 values (2); insert into t2 values (1,7),(2,7); insert into t4 values (4,8),(3,8),(5,9); --- error 1244 +-- error 1245 select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1; select (select a from t1 where t1.a=t2.a), a from t2; select (select a from t1 where t1.a=t2.b), a from t2; @@ -178,7 +178,7 @@ CREATE TABLE `threadhardwarefr7` ( UNIQUE KEY `numreponse` (`numreponse`), KEY `pseudo` (`pseudo`,`numeropost`) ) TYPE=MyISAM; --- error 1244 +-- error 1245 SELECT (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=a),numreponse FROM (SELECT * FROM threadhardwarefr7) as a; -- error 1054 SELECT numreponse, (SELECT numeropost FROM threadhardwarefr7 HAVING numreponse=a) FROM (SELECT * FROM threadhardwarefr7) as a; From b74c43f4753da8ccd76a97e34d09813960db85f6 Mon Sep 17 00:00:00 2001 From: "venu@myvenu.com" <> Date: Fri, 22 Nov 2002 10:04:42 -0800 Subject: [PATCH 03/10] protocol fixups --- libmysql/errmsg.c | 6 +- libmysql/libmysql.c | 291 ++++++++++++++++++++++++-------------- libmysql/libmysql.def | 20 ++- sql/item.cc | 17 +-- sql/item.h | 13 +- sql/mysql_priv.h | 2 +- sql/sql_class.h | 3 +- sql/sql_error.cc | 2 +- sql/sql_prepare.cc | 317 +++++++++++++++++++++++------------------- 9 files changed, 398 insertions(+), 273 deletions(-) diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c index 0945aed6772..4b8613f460d 100644 --- a/libmysql/errmsg.c +++ b/libmysql/errmsg.c @@ -58,7 +58,7 @@ const char *client_errors[]= "No parameters exists in the statement", "Invalid parameter number", "Can't send long data for non string or binary data types (parameter: %d)", - "Using not supported parameter type: %d (parameter: %d)" + "Using un supported parameter type: %d (parameter: %d)" "Shared memory (%lu)", "Can't open shared memory. Request event don't create (%lu)", "Can't open shared memory. Answer event don't create (%lu)", @@ -111,7 +111,7 @@ const char *client_errors[]= "No parameters exists in the statement", "Invalid parameter number", "Can't send long data for non string or binary data types (parameter: %d)", - "Using not supported parameter type: %d (parameter: %d)" + "Using un supported parameter type: %d (parameter: %d)" "Shared memory (%lu)", "Can't open shared memory. Request event don't create (%lu)", "Can't open shared memory. Answer event don't create (%lu)", @@ -162,7 +162,7 @@ const char *client_errors[]= "No parameters exists in the statement", "Invalid parameter number", "Can't send long data for non string or binary data types (parameter: %d)", - "Using not supported parameter type: %d (parameter: %d)" + "Using un supported parameter type: %d (parameter: %d)" "Shared memory (%lu)", "Can't open shared memory. Request event don't create (%lu)", "Can't open shared memory. Answer event don't create (%lu)", diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 0bb6b54bee5..0912f8997f9 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -927,7 +927,8 @@ static const char *default_options[]= "character-sets-dir", "default-character-set", "interactive-timeout", "connect-timeout", "local-infile", "disable-local-infile", "replication-probe", "enable-reads-from-master", "repl-parse-query", - "ssl-cipher","protocol", "shared_memory_base_name", + "ssl-cipher","protocol", + "shared_memory_base_name", NullS }; @@ -1736,11 +1737,10 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , Free strings in the SSL structure and clear 'use_ssl' flag. NB! Errors are not reported until you do mysql_real_connect. **************************************************************************/ - static void mysql_ssl_free(MYSQL *mysql __attribute__((unused))) { -#ifdef HAVE_OPENSSL +#ifdef HAVE_OPENSLL my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); @@ -1754,7 +1754,7 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) mysql->options.ssl_cipher= 0; mysql->options.use_ssl = FALSE; mysql->connector_fd = 0; -#endif /* HAVE_OPENSSL */ +#endif /* HAVE_OPENSLL */ } /************************************************************************** @@ -2567,7 +2567,7 @@ get_info: { mysql->affected_rows= net_field_length_ll(&pos); mysql->insert_id= net_field_length_ll(&pos); - if (mysql->server_capabilities & CLIENT_PROTOCOL_41) + if (protocol_41(mysql)) { mysql->server_status=uint2korr(pos); pos+=2; mysql->warning_count=uint2korr(pos); pos+=2; @@ -3650,10 +3650,10 @@ MYSQL_STMT *STDCALL mysql_prepare(MYSQL *mysql, const char *query, ulong length) { MYSQL_STMT *stmt; - DBUG_ENTER("mysql_real_prepare"); + DBUG_ENTER("mysql_prepare"); DBUG_ASSERT(mysql != 0); -#ifdef EXTRA_CHECK_ARGUMENTS +#ifdef CHECK_EXTRA_ARGUMENTS if (!query) { set_mysql_error(mysql, CR_NULL_POINTER); @@ -3674,7 +3674,6 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) mysql_stmt_close(stmt); DBUG_RETURN(0); } - stmt->state= MY_ST_PREPARE; init_alloc_root(&stmt->mem_root,8192,0); if (read_prepare_result(mysql, stmt)) @@ -3682,8 +3681,8 @@ mysql_prepare(MYSQL *mysql, const char *query, ulong length) mysql_stmt_close(stmt); DBUG_RETURN(0); } - - stmt->mysql= mysql; + stmt->state= MY_ST_PREPARE; + stmt->mysql= mysql; DBUG_PRINT("info", ("Parameter count: %ld", stmt->param_count)); DBUG_RETURN(stmt); } @@ -3819,7 +3818,7 @@ static void store_param_str(NET *net, MYSQL_BIND *param) ulong length= *param->length; char *to= (char *) net_store_length((char *) net->write_pos, length); memcpy(to, param->buffer, length); - net->write_pos+= length; + net->write_pos= to+length; } @@ -3853,17 +3852,19 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param) MYSQL *mysql= stmt->mysql; NET *net = &mysql->net; DBUG_ENTER("store_param"); - DBUG_PRINT("enter",("type : %d, buffer :%lx", param->buffer_type, - param->buffer)); - - /* Allocate for worst case (long string) */ - if ((my_realloc_str(net, 9 + *param->length))) - return 1; - if (!param->buffer) + DBUG_PRINT("enter",("type: %d, buffer:%lx, length: %d", param->buffer_type, + param->buffer ? param->buffer : "0", *param->length)); + + if (param->is_null || param->buffer_type == MYSQL_TYPE_NULL) store_param_null(net, param); else + { + /* Allocate for worst case (long string) */ + if ((my_realloc_str(net, 9 + *param->length))) + DBUG_RETURN(1); (*param->store_param_func)(net, param); - DBUG_RETURN(1); + } + DBUG_RETURN(0); } @@ -3875,13 +3876,13 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) { MYSQL *mysql= stmt->mysql; NET *net= &mysql->net; - char buff[4]; + char buff[MYSQL_STMT_HEADER]; DBUG_ENTER("execute"); DBUG_PRINT("enter",("packet: %s, length :%d",packet ? packet :" ", length)); mysql->last_used_con= mysql; int4store(buff, stmt->stmt_id); /* Send stmt id to server */ - if (advanced_command(mysql, COM_EXECUTE, buff, sizeof(buff), packet, + if (advanced_command(mysql, COM_EXECUTE, buff, MYSQL_STMT_HEADER, packet, length, 1) || mysql_read_query_result(mysql)) { @@ -3889,12 +3890,14 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) DBUG_RETURN(1); } stmt->state= MY_ST_EXECUTE; - - if (stmt->bind) + mysql_free_result(stmt->result); +#if USED_IN_FETCH + if (stmt->res_buffers) /* Result buffers exists, cache results */ { mysql_free_result(stmt->result); stmt->result= mysql_store_result(mysql); } + #endif DBUG_RETURN(0); } @@ -3905,8 +3908,6 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) int STDCALL mysql_execute(MYSQL_STMT *stmt) { - ulong length; - uint null_count; DBUG_ENTER("mysql_execute"); if (stmt->state == MY_ST_UNKNOWN) @@ -3920,14 +3921,18 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt) NET *net= &stmt->mysql->net; MYSQL_BIND *param, *param_end; char *param_data; - my_bool result; + ulong length; + uint null_count; + my_bool result; - if (!stmt->params) +#ifdef CHECK_EXTRA_ARGUMENTS + if (!stmt->param_buffers) { /* Parameters exists, but no bound buffers */ set_stmt_error(stmt, CR_NOT_ALL_PARAMS_BOUND); DBUG_RETURN(1); } +#endif net_clear(net); /* Sets net->write_pos */ /* Reserve place for null-marker bytes */ null_count= (stmt->param_count+7) /8; @@ -3936,10 +3941,9 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt) param_end= stmt->params + stmt->param_count; /* In case if buffers (type) altered, indicate to server */ - *(net->write_pos)++= (uchar) stmt->types_supplied; - if (!stmt->types_supplied) + *(net->write_pos)++= (uchar) stmt->send_types_to_server; + if (stmt->send_types_to_server) { - stmt->types_supplied=1; /* Store types of parameters in first in first package that is sent to the server. @@ -3953,21 +3957,22 @@ int STDCALL mysql_execute(MYSQL_STMT *stmt) /* Check for long data which has not been propery given/terminated */ if (param->is_long_data) { - if (!param->long_ended) - DBUG_RETURN(MYSQL_NEED_DATA); + if (!param->long_ended) + DBUG_RETURN(MYSQL_NEED_DATA); } else if (store_param(stmt, param)) - DBUG_RETURN(1); + DBUG_RETURN(1); } length= (ulong) (net->write_pos - net->buff); /* TODO: Look into avoding the following memdup */ - if (!(param_data= my_memdup((byte *) net->buff, length, MYF(0)))) + if (!(param_data= my_memdup( net->buff, length, MYF(0)))) { set_stmt_error(stmt, CR_OUT_OF_MEMORY); DBUG_RETURN(1); } net->write_pos= net->buff; /* Reset for net_write() */ result= execute(stmt, param_data, length); + stmt->send_types_to_server=0; my_free(param_data, MYF(MY_WME)); DBUG_RETURN(result); } @@ -4030,15 +4035,19 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind) param->param_number); DBUG_RETURN(1); } + /* If param->length is not given, change it to point to bind_length. This way we can always use *param->length to get the length of data */ if (!param->length) param->length= ¶m->bind_length; - + /* Setup data copy functions for the different supported types */ switch (param->buffer_type) { + case MYSQL_TYPE_NULL: + param->is_null=1; + break; case MYSQL_TYPE_TINY: param->bind_length= 1; param->store_param_func= store_param_tinyint; @@ -4060,12 +4069,13 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind) param->store_param_func= store_param_float; break; case MYSQL_TYPE_DOUBLE: - param->bind_length= 4; + param->bind_length= 8; param->store_param_func= store_param_double; break; case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: param->bind_length= param->buffer_length; @@ -4078,7 +4088,8 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind) } } /* We have to send/resendtype information to MySQL */ - stmt->types_supplied= 0; + stmt->send_types_to_server= 1; + stmt->param_buffers= 1; DBUG_RETURN(0); } @@ -4152,6 +4163,73 @@ mysql_send_long_data(MYSQL_STMT *stmt, uint param_number, Fetch-bind related implementations *********************************************************************/ +/**************************************************************************** + Functions to fetch data to application buffers + + All functions has the following characteristics: + + SYNOPSIS + fetch_result_xxx() + param MySQL bind param + row Row value + + RETURN VALUES + 0 ok + 1 Error (Can't alloc net->buffer) +****************************************************************************/ + + +static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row) +{ + *param->buffer= (uchar) **row; + *row++; +} + +static void fetch_result_short(MYSQL_BIND *param, uchar **row) +{ + short value= *(short *)row; + int2store(param->buffer, value); + *row+=2; +} + +static void fetch_result_int32(MYSQL_BIND *param, uchar **row) +{ + int32 value= *(int32 *)row; + int4store(param->buffer, value); + *row+=4; +} + +static void fetch_result_int64(MYSQL_BIND *param, uchar **row) +{ + longlong value= *(longlong *)row; + int8store(param->buffer, value); + *row+=8; +} + +static void fetch_result_float(MYSQL_BIND *param, uchar **row) +{ + float value; + float4get(value,*row); + float4store(param->buffer, *row); + *row+=4; +} + +static void fetch_result_double(MYSQL_BIND *param, uchar **row) +{ + double value; + float8get(value,*row); + float8store(param->buffer, value); + *row+=8; +} + +static void fetch_result_str(MYSQL_BIND *param, uchar **row) +{ + ulong length= net_field_length(row); + memcpy(param->buffer, (char *)*row, length); + *param->length= length; + *row+=length; +} + /* Setup the bind buffers for resultset processing */ @@ -4163,21 +4241,62 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) DBUG_ENTER("mysql_bind_result"); DBUG_ASSERT(stmt != 0); -#ifdef EXTRA_CHECK_ARGUMENTS +#ifdef CHECK_EXTRA_ARGUMENTS if (!bind) { set_stmt_error(stmt, CR_NULL_POINTER); DBUG_RETURN(1); } #endif - bind_count= stmt->result->field_count; + bind_count= stmt->field_count; memcpy((char*) stmt->bind, (char*) bind, sizeof(MYSQL_BIND)*bind_count); for (param= stmt->bind, end= param+bind_count; param < end ; param++) { - /* TODO: Set up convert functions like in mysql_bind_param */ + /* Setup data copy functions for the different supported types */ + switch (param->buffer_type) { + case MYSQL_TYPE_TINY: + param->bind_length= 1; + param->fetch_result= fetch_result_tinyint; + break; + case MYSQL_TYPE_SHORT: + param->bind_length= 2; + param->fetch_result= fetch_result_short; + break; + case MYSQL_TYPE_LONG: + param->bind_length= 4; + param->fetch_result= fetch_result_int32; + break; + case MYSQL_TYPE_LONGLONG: + param->bind_length= 8; + param->fetch_result= fetch_result_int64; + break; + case MYSQL_TYPE_FLOAT: + param->bind_length= 4; + param->fetch_result= fetch_result_float; + break; + case MYSQL_TYPE_DOUBLE: + param->bind_length= 8; + param->fetch_result= fetch_result_double; + break; + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + param->length= ¶m->buffer_length; + param->fetch_result= fetch_result_str; + break; + default: + sprintf(stmt->last_error, ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE), + param->buffer_type, param->param_number); + DBUG_RETURN(1); + } + if (!param->length) + param->length= ¶m->bind_length; } + stmt->res_buffers= 1; DBUG_RETURN(0); } @@ -4187,16 +4306,16 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) */ static my_bool -my_fetch_row(MYSQL_STMT *stmt, MYSQL_RES *result, const byte *row) +stmt_fetch_row(MYSQL_STMT *stmt, uchar **row) { MYSQL_BIND *bind, *end; - uchar *null_ptr= (uchar*) row, bit; - - result->row_count++; - row+= (result->field_count+7)/8; - /* Copy complete row to application buffers */ + uchar *null_ptr= (uchar*) *row, bit; + + *row+= (stmt->field_count+7)/8; bit=1; - for (bind= stmt->bind, end= (MYSQL_BIND *) bind + result->field_count; + + /* Copy complete row to application buffers */ + for (bind= stmt->bind, end= (MYSQL_BIND *) bind + stmt->field_count; bind < end; bind++) { @@ -4205,7 +4324,7 @@ my_fetch_row(MYSQL_STMT *stmt, MYSQL_RES *result, const byte *row) else { bind->is_null= 0; - row= (byte*) (*bind->fetch_result)(bind, (char*) row); + (*bind->fetch_result)(bind, row); } if (! (bit<<=1) & 255) { @@ -4216,12 +4335,9 @@ my_fetch_row(MYSQL_STMT *stmt, MYSQL_RES *result, const byte *row) return 0; } - -static int -read_binary_data(MYSQL *mysql) -{ - ulong pkt_len; - if ((pkt_len= net_safe_read(mysql)) == packet_error) +static int read_binary_data(MYSQL *mysql) +{ + if (packet_error == net_safe_read(mysql)) return -1; if (mysql->net.read_pos[0]) return 1; /* End of data */ @@ -4235,57 +4351,30 @@ read_binary_data(MYSQL *mysql) int STDCALL mysql_fetch(MYSQL_STMT *stmt) { - MYSQL_RES *result; + MYSQL *mysql= stmt->mysql; DBUG_ENTER("mysql_fetch"); - result= stmt->result; - if (!result) - DBUG_RETURN(MYSQL_NO_DATA); - - if (!result->data) + if (stmt->res_buffers) { - MYSQL *mysql= stmt->mysql; - if (!result->eof) + int res; + if (!(res= read_binary_data(mysql))) { - int res; - if (!(res= read_binary_data(result->handle))) - DBUG_RETURN((int) my_fetch_row(stmt, result, - (byte*) mysql->net.read_pos+1)); - DBUG_PRINT("info", ("end of data")); - result->eof= 1; - result->handle->status= MYSQL_STATUS_READY; - - /* Don't clear handle in mysql_free_results */ - result->handle= 0; - if (res < 0) /* Network error */ - { - set_stmt_errmsg(stmt,(char *)mysql->net.last_error, - mysql->net.last_errno); - DBUG_RETURN(MYSQL_STATUS_ERROR); - } + if (stmt->res_buffers) + DBUG_RETURN((int) stmt_fetch_row(stmt,(uchar **) &mysql->net.read_pos+1)); + DBUG_RETURN(0); + } + DBUG_PRINT("info", ("end of data")); + mysql->status= MYSQL_STATUS_READY; + + if (res < 0) /* Network error */ + { + set_stmt_errmsg(stmt,(char *)mysql->net.last_error, + mysql->net.last_errno); + DBUG_RETURN(MYSQL_STATUS_ERROR); } DBUG_RETURN(MYSQL_NO_DATA); /* no more data */ } - { - /* - For prepared statements, the row data is a string of binary bytes, - not a set of string pointers as for normal statements - It's however convenient to use the data pointer also for prepared - statements. - */ - MYSQL_ROW values; - if (!result->data_cursor) - { - DBUG_PRINT("info", ("end of data")); - result->current_row= (MYSQL_ROW) NULL; - DBUG_RETURN(MYSQL_NO_DATA); - } - values= result->data_cursor->data; - result->data_cursor= result->data_cursor->next; - - DBUG_RETURN((int) my_fetch_row(stmt,result, (byte*) values)); - } - DBUG_RETURN(0); + DBUG_RETURN(0); //?? do we need to set MYSQL_STATUS_READY ? } @@ -4302,17 +4391,15 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt) my_bool error=0; DBUG_ENTER("mysql_stmt_close"); - if (stmt->state) + if (stmt->state != MY_ST_UNKNOWN) { char buff[4]; int4store(buff, stmt->stmt_id); error= simple_command(stmt->mysql, COM_CLOSE_STMT, buff, 4, 0); } - + mysql_free_result(stmt->result); free_root(&stmt->mem_root, MYF(0)); my_free((gptr) stmt->query, MYF(MY_WME | MY_ALLOW_ZERO_PTR)); - my_free((gptr) stmt->bind, MY_ALLOW_ZERO_PTR); - my_free((gptr) stmt->params, MY_ALLOW_ZERO_PTR); my_free((gptr) stmt, MYF(MY_WME)); DBUG_RETURN(error); } diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index a7fb4d378e5..0d650467665 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -102,8 +102,24 @@ EXPORTS mysql_add_slave mysql_warning_count mysql_warnings - - + mysql_prepare + mysql_execute + mysql_param_count + mysql_bind_param + mysql_bind_result + mysql_prepare_result + mysql_stmt_close + mysql_stmt_error + mysql_stmt_errno + mysql_fetch + mysql_send_long_data + mysql_multi_query + mysql_next_result + mysql_commit + mysql_rollback + mysql_autocommit + + diff --git a/sql/item.cc b/sql/item.cc index 48ec11d02c2..cd321488548 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -315,32 +315,27 @@ void Item_param::set_null() void Item_param::set_int(longlong i) { int_value=(longlong)i; - item_result_type = INT_RESULT; item_type = INT_ITEM; } void Item_param::set_double(double value) { real_value=value; - item_result_type = REAL_RESULT; item_type = REAL_ITEM; } -void Item_param::set_value(const char *str, uint length, CHARSET_INFO *cs) +void Item_param::set_value(const char *str, uint length) { - str_value.set(str,length,cs); - item_result_type = STRING_RESULT; + str_value.set(str,length,thd_charset()); item_type = STRING_ITEM; } -void Item_param::set_longdata(const char *str, ulong length, CHARSET_INFO *cs) -{ - /* TODO: Fix this for binary handling by making use of - buffer_type.. - */ - str_value.append(str,length); +void Item_param::set_longdata(const char *str, ulong length) +{ + str_value.append(str,length); + long_data_supplied= 1; } diff --git a/sql/item.h b/sql/item.h index c67c16c50ad..490317f9bc9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -186,8 +186,8 @@ public: Item_param(char *name_par=0) { name= name_par ? name_par : (char*) "?"; - long_data_supplied = false; - item_type = STRING_ITEM; + long_data_supplied= false; + item_type= STRING_ITEM; item_result_type = STRING_RESULT; } enum Type type() const { return item_type; } @@ -199,12 +199,13 @@ public: void set_null(); void set_int(longlong i); void set_double(double i); - void set_value(const char *str, uint length, CHARSET_INFO *cs); - void set_long_str(const char *str, ulong length, CHARSET_INFO *cs); - void set_long_binary(const char *str, ulong length, CHARSET_INFO *cs); - void set_longdata(const char *str, ulong length, CHARSET_INFO *cs); + void set_value(const char *str, uint length); + void set_long_str(const char *str, ulong length); + void set_long_binary(const char *str, ulong length); + void set_longdata(const char *str, ulong length); void set_long_end(); void reset() {} + void (*setup_param_func)(Item_param *param, uchar **pos); enum Item_result result_type () const { return item_result_type; } Item *new_item() { return new Item_param(name); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c9b95963c32..98afe2681df 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -509,7 +509,7 @@ int mysqld_show_column_types(THD *thd); int mysqld_help (THD *thd, const char *text); /* sql_prepare.cc */ -int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used); +int compare_prep_stmt(void *not_used, PREP_STMT *stmt, ulong *key); void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used); bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length); void mysql_stmt_execute(THD *thd, char *packet); diff --git a/sql/sql_class.h b/sql/sql_class.h index a619e8e3aff..20abfe64fe0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -325,7 +325,7 @@ typedef struct st_prep_stmt uint param_count; uint last_errno; char last_error[MYSQL_ERRMSG_SIZE]; - bool error_in_prepare, long_data_used; + bool error_in_prepare, long_data_used, param_inited; } PREP_STMT; @@ -510,7 +510,6 @@ public: bool safe_to_cache_query; bool volatile killed; bool prepare_command; - Item_param *params; // Pointer to array of params /* If we do a purge of binary logs, log index info of the threads diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 3d6a0fa24aa..768c54c202e 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -115,7 +115,7 @@ static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"}; my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) { List field_list; - DBUG_ENTER("mysqld_show_errors"); + DBUG_ENTER("mysqld_show_warnings"); field_list.push_back(new Item_empty_string("Level", 7)); field_list.push_back(new Item_int("Code",0,4)); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 08377a10501..4bc66778ffb 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -30,10 +30,11 @@ Prepare: Prepare-execute: - Server gets the command 'COM_EXECUTE' to execute the - previously prepared query. - - If there is are any parameters, then replace the markers with the - data supplied by client with the following format: - [types_specified(0/1)][type][length][data] .. [type][length].. + previously prepared query. If there is any param markers; then client + will send the data in the following format: + [null_bits][types_specified(0/1)][[length][data]][[length][data] .. [length][data]. + - Replace the param items with this new data. If it is a first execute + or types altered by client; then setup the conversion routines. - Execute the query without re-parsing and send back the results to client @@ -53,33 +54,9 @@ Long data handling: #include // for DEBUG_ASSERT() #include // for isspace() -extern int yyparse(void); -static ulong get_param_length(uchar **packet); -static uint get_buffer_type(uchar **packet); -static bool param_is_null(uchar **packet); -static bool setup_param_fields(THD *thd,List ¶ms); -static uchar* setup_param_field(Item_param *item_param, uchar *pos, - uint buffer_type); -static void setup_longdata_field(Item_param *item_param, uchar *pos); -static bool setup_longdata(THD *thd,List ¶ms); -static bool send_prepare_results(PREP_STMT *stmt); -static bool parse_prepare_query(PREP_STMT *stmt, char *packet, uint length); -static bool mysql_send_insert_fields(PREP_STMT *stmt, TABLE_LIST *table_list, - List &fields, - List &values_list, - thr_lock_type lock_type); -static bool mysql_test_insert_fields(PREP_STMT *stmt, TABLE_LIST *table_list, - List &fields, - List &values_list, - thr_lock_type lock_type); -static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list, - List &fields, List &values, - COND *conds,thr_lock_type lock_type); -static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, - List &fields, List &values, - COND *conds, ORDER *order, ORDER *group, - Item *having,thr_lock_type lock_type); +#define IS_PARAM_NULL(pos, param_no) pos[param_no/8] & (1 << param_no & 7) +extern int yyparse(void); /* Find prepared statement in thd @@ -114,9 +91,9 @@ static PREP_STMT *find_prepared_statement(THD *thd, ulong stmt_id, Compare two prepared statements; Used to find a prepared statement */ -int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used) +int compare_prep_stmt(void *not_used, PREP_STMT *stmt, ulong *key) { - return (a->stmt_id < b->stmt_id) ? -1 : (a->stmt_id == b->stmt_id) ? 0 : 1; + return (stmt->stmt_id == *key) ? 0 : (stmt->stmt_id < *key) ? -1 : 1; } @@ -132,22 +109,23 @@ int compare_prep_stmt(PREP_STMT *a, PREP_STMT *b, void *not_used) */ void free_prep_stmt(PREP_STMT *stmt, TREE_FREE mode, void *not_used) -{ - free_root(&stmt->mem_root, MYF(0)); +{ free_items(stmt->free_list); + free_root(&stmt->mem_root, MYF(0)); } /* Send prepared stmt info to client after prepare */ -bool send_prep_stmt(PREP_STMT *stmt, uint columns) +static bool send_prep_stmt(PREP_STMT *stmt, uint columns) { + NET *net=&stmt->thd->net; char buff[8]; int4store(buff, stmt->stmt_id); int2store(buff+4, columns); int2store(buff+6, stmt->param_count); - return my_net_write(&stmt->thd->net, buff, sizeof(buff)); + return (my_net_write(net, buff, sizeof(buff)) || net_flush(net)); } /* @@ -156,43 +134,15 @@ bool send_prep_stmt(PREP_STMT *stmt, uint columns) TODO: Not yet ready */ -bool send_item_params(PREP_STMT *stmt) +static bool send_item_params(PREP_STMT *stmt) { +#if 0 char buff[1]; buff[0]=0; - return my_net_write(&stmt->thd->net, buff, sizeof(buff)); -} - - - -/* - Read the buffer type, this happens only first time -*/ - -static uint get_buffer_type(uchar **packet) -{ - reg1 uchar *pos= *packet; - (*packet)+= 2; - return (uint) uint2korr(pos); -} - - -/* - Check for NULL param data - - RETURN VALUES - 0 Value was not NULL - 1 Value was NULL -*/ - -static bool param_is_null(uchar **packet) -{ - reg1 uchar *pos= *packet; - if (*pos == 251) - { - (*packet)++; + if (my_net_write(&stmt->thd->net, buff, sizeof(buff))) return 1; - } + send_eof(stmt->thd); +#endif return 0; } @@ -222,60 +172,103 @@ static ulong get_param_length(uchar **packet) (*packet)+=9; // Must be 254 when here return (ulong) uint4korr(pos+1); } + /* + Setup param conversion routines -/* - Read and return the data for parameters supplied by client + setup_param_xx() + param Parameter Item + pos Input data buffer + + All these functions reads the data from pos and sets up that data + through 'param' and advances the buffer position to predifined + length position. + + Make a note that the NULL handling is examined at first execution + (i.e. when input types altered) and for all subsequent executions + we don't read any values for this. + + RETURN VALUES + */ -static uchar* setup_param_field(Item_param *item_param, - uchar *pos, uint buffer_type) +static void setup_param_tiny(Item_param *param, uchar **pos) { - if (param_is_null(&pos)) - { - item_param->set_null(); - return(pos); - } - switch (buffer_type) { + param->set_int((longlong)(**pos)); + *pos+= 1; +} + +static void setup_param_short(Item_param *param, uchar **pos) +{ + param->set_int((longlong)sint2korr(*pos)); + *pos+= 2; +} + +static void setup_param_int32(Item_param *param, uchar **pos) +{ + param->set_int((longlong)sint4korr(*pos)); + *pos+= 4; +} + +static void setup_param_int64(Item_param *param, uchar **pos) +{ + param->set_int((longlong)sint8korr(*pos)); + *pos+= 8; +} + +static void setup_param_float(Item_param *param, uchar **pos) +{ + float data; + float4get(data,*pos); + param->set_double((double) data); + *pos+= 4; +} + +static void setup_param_double(Item_param *param, uchar **pos) +{ + double data; + float8get(data,*pos); + param->set_double((double) data); + *pos+= 8; +} + +static void setup_param_str(Item_param *param, uchar **pos) +{ + ulong len=get_param_length(pos); + param->set_value((const char *)*pos, len); + *pos+=len; +} + +static void setup_param_functions(Item_param *param, uchar read_pos) +{ + switch (read_pos) { case FIELD_TYPE_TINY: - item_param->set_int((longlong)(*pos)); - pos += 1; + param->setup_param_func= setup_param_tiny; + param->item_result_type = INT_RESULT; break; case FIELD_TYPE_SHORT: - item_param->set_int((longlong)sint2korr(pos)); - pos += 2; - break; - case FIELD_TYPE_INT24: - item_param->set_int((longlong)sint4korr(pos)); - pos += 3; + param->setup_param_func= setup_param_short; + param->item_result_type = INT_RESULT; break; case FIELD_TYPE_LONG: - item_param->set_int((longlong)sint4korr(pos)); - pos += 4; + param->setup_param_func= setup_param_int32; + param->item_result_type = INT_RESULT; break; case FIELD_TYPE_LONGLONG: - item_param->set_int((longlong)sint8korr(pos)); - pos += 8; + param->setup_param_func= setup_param_int64; + param->item_result_type = INT_RESULT; break; case FIELD_TYPE_FLOAT: - float data; - float4get(data,pos); - item_param->set_double((double) data); - pos += 4; + param->setup_param_func= setup_param_float; + param->item_result_type = REAL_RESULT; break; case FIELD_TYPE_DOUBLE: - double j; - float8get(j,pos) - item_param->set_double(j); - pos += 8; + param->setup_param_func= setup_param_double; + param->item_result_type = REAL_RESULT; break; default: - { - ulong len=get_param_length(&pos); - item_param->set_value((const char*)pos,len,current_thd->thd_charset); - pos+=len; - } + param->setup_param_func= setup_param_str; + param->item_result_type = STRING_RESULT; } - return(pos); } /* @@ -283,42 +276,45 @@ static uchar* setup_param_field(Item_param *item_param, from client .. */ -static bool setup_param_fields(THD *thd, PREP_STMT *stmt) -{ - DBUG_ENTER("setup_param_fields"); -#ifdef READY_TO_BE_USED - Item_param *item_param; - ulong param_count=0; - uchar *pos=(uchar*) thd->net.read_pos+1;// skip command type +static bool setup_params_data(THD *thd, PREP_STMT *stmt) +{ + List ¶ms= thd->lex.param_list; + List_iterator param_iterator(params); + Item_param *param; + DBUG_ENTER("setup_params_data"); - - if (*pos++) // No types supplied, read only param data - { - while ((item_param=(Item_param *)it++) && - (param_count++ < stmt->param_count)) - { - if (item_param->long_data_supplied) - continue; + uchar *pos=(uchar*) thd->net.read_pos+1+MYSQL_STMT_HEADER; //skip header + uchar *read_pos= pos+(stmt->param_count+7) / 8; //skip null bits + ulong param_no; - if (!(pos=setup_param_field(item_param,pos,item_param->buffer_type))) - DBUG_RETURN(1); + if (*read_pos++) //types supplied / first execute + { + /* + First execute or types altered by the client, setup the + conversion routines for all parameters (one time) + */ + while ((param= (Item_param *)param_iterator++)) + { + if (!param->long_data_supplied) + { + setup_param_functions(param,*read_pos); + read_pos+= 2; + } } - } - else // Types supplied, read and store it along with param data + param_iterator.rewind(); + } + param_no= 0; + while ((param= (Item_param *)param_iterator++)) { - while ((item_param=(Item_param *)it++) && - (param_count++ < thd->param_count)) + if (!param->long_data_supplied) { - if (item_param->long_data_supplied) - continue; - - if (!(pos=setup_param_field(item_param,pos, - item_param->buffer_type= - (enum_field_types) get_buffer_type(&pos)))) - DBUG_RETURN(1); + if (IS_PARAM_NULL(pos,param_no)) + param->maybe_null=param->null_value=1; + else + param->setup_param_func(param,&read_pos); } + param_no++; } -#endif DBUG_RETURN(0); } @@ -583,6 +579,8 @@ static bool send_prepare_results(PREP_STMT *stmt) Rest fall through to default category, no parsing for non-DML statements */ + if (send_prep_stmt(stmt, 0)) + goto abort; } } DBUG_RETURN(0); @@ -597,7 +595,7 @@ abort: */ static bool parse_prepare_query(PREP_STMT *stmt, - char *packet, uint length) + char *packet, uint length) { bool error= 1; THD *thd= stmt->thd; @@ -607,6 +605,7 @@ static bool parse_prepare_query(PREP_STMT *stmt, mysql_init_query(thd); thd->prepare_command=true; thd->safe_to_cache_query= 0; + thd->lex.param_count=0; LEX *lex=lex_start(thd, (uchar*) packet, length); if (!yyparse() && !thd->fatal_error) @@ -615,6 +614,25 @@ static bool parse_prepare_query(PREP_STMT *stmt, DBUG_RETURN(error); } +/* + Initialize parameter items in statement +*/ +static bool init_param_items(THD *thd, PREP_STMT *stmt) +{ +#if TO_BE_TESTED + Item_param **to; + if (!(to= (Item_param *) + my_malloc(sizeof(Item_param*) * stmt->param_count, MYF(MY_WME)))) + return 1; + List ¶ms= thd->lex.param_list; + List_iterator param_iterator(params); + while ((to++ = (Item_param *)param_iterator++)) + { + DBUG_PRINT("info",("param: %lx", to)); + } + return 0; +#endif +} /* Parse the query and send the total number of parameters @@ -648,10 +666,15 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) goto err; if (!(specialflag & SPECIAL_NO_PRIOR)) - my_pthread_setprio(pthread_self(),WAIT_PRIOR); - - stmt.mem_root= thd->mem_root; + my_pthread_setprio(pthread_self(),WAIT_PRIOR); +#if 0 + if (init_param_items(thd, &stmt)) + goto err; +#endif + stmt.mem_root= thd->mem_root; + tree_insert(&thd->prepared_statements, (void *)&stmt, 0, (void *)0); thd->mem_root= thd_root; // restore main mem_root + thd->last_prepared_stmt= &stmt; DBUG_RETURN(0); err: @@ -685,11 +708,11 @@ void mysql_stmt_execute(THD *thd, char *packet) /* Check if we got an error when sending long data */ if (stmt->error_in_prepare) { - send_error(thd); + send_error(thd, stmt->last_errno, stmt->last_error); DBUG_VOID_RETURN; } - if (stmt->param_count && setup_param_fields(thd, stmt)) + if (stmt->param_count && setup_params_data(thd, stmt)) DBUG_VOID_RETURN; MEM_ROOT thd_root= thd->mem_root; @@ -705,6 +728,8 @@ void mysql_stmt_execute(THD *thd, char *packet) */ mysql_execute_command(thd); + thd->last_prepared_stmt= stmt; + if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); @@ -768,8 +793,10 @@ void mysql_stmt_close(THD *thd, char *packet) send_error(thd); DBUG_VOID_RETURN; } + stmt->param= 0; + my_free((char *)stmt->param, MYF(MY_ALLOW_ZERO_PTR)); /* Will call free_prep_stmt() */ - tree_delete(&thd->prepared_statements, (void*) stmt, NULL); + tree_delete(&thd->prepared_statements, (void*) &stmt, (void *)0); thd->last_prepared_stmt=0; DBUG_VOID_RETURN; } @@ -800,17 +827,16 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length) DBUG_ENTER("mysql_stmt_get_longdata"); /* The following should never happen */ - if (packet_length < 9) + if (packet_length < MYSQL_LONG_DATA_HEADER+1) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "get_longdata"); DBUG_VOID_RETURN; } - pos++; // skip command type at first position ulong stmt_id= uint4korr(pos); uint param_number= uint2korr(pos+4); uint param_type= uint2korr(pos+6); - pos+=8; // Point to data + pos+=MYSQL_LONG_DATA_HEADER; // Point to data if (!(stmt=find_prepared_statement(thd, stmt_id, "get_longdata"))) { @@ -829,7 +855,8 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length) sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "get_longdata"); DBUG_VOID_RETURN; } - stmt->param[param_number].set_longdata(pos, packet_length-9, current_thd->thd_charset); + stmt->param[param_number].set_longdata(pos, packet_length-9); stmt->long_data_used= 1; DBUG_VOID_RETURN; } + From 47b51f613ee8ff0547625bc442e15ce955e35201 Mon Sep 17 00:00:00 2001 From: "venu@myvenu.com" <> Date: Fri, 22 Nov 2002 10:21:29 -0800 Subject: [PATCH 04/10] merge --- libmysql/libmysql.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 0912f8997f9..47df7acb0b1 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -242,7 +242,7 @@ my_bool my_connect(my_socket s, const struct sockaddr *name, { tv.tv_sec = (long) timeout; tv.tv_usec = 0; -#if defined(HPUX) && defined(THREAD) +#if defined(HPUX10) && defined(THREAD) if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) >= 0) break; #else @@ -928,7 +928,9 @@ static const char *default_options[]= "connect-timeout", "local-infile", "disable-local-infile", "replication-probe", "enable-reads-from-master", "repl-parse-query", "ssl-cipher","protocol", - "shared_memory_base_name", +red_memory_base_name", + + NullS }; @@ -1737,6 +1739,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , Free strings in the SSL structure and clear 'use_ssl' flag. NB! Errors are not reported until you do mysql_real_connect. **************************************************************************/ + static void mysql_ssl_free(MYSQL *mysql __attribute__((unused))) { @@ -1807,6 +1810,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, #endif init_sigpipe_variables DBUG_ENTER("mysql_real_connect"); + LINT_INIT(host_info); DBUG_PRINT("enter",("host: %s db: %s user: %s", host ? host : "(Null)", @@ -2188,15 +2192,18 @@ Try also with PIPE or TCP/IP options->ssl_capath, options->ssl_cipher))) { - /* TODO: Change to SSL error */ - net->last_errno= CR_SERVER_LOST; + net->last_errno= CR_SSL_CONNECTION_ERROR; strmov(net->last_error,ER(net->last_errno)); goto error; } DBUG_PRINT("info", ("IO layer change in progress...")); - /* TODO: Add proper error checking here, with return error message */ - sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), - mysql->net.vio, (long) (mysql->options.connect_timeout)); + if(sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), + mysql->net.vio, (long) (mysql->options.connect_timeout))) + { + net->last_errno= CR_SSL_CONNECTION_ERROR; + strmov(net->last_error,ER(net->last_errno)); + goto error; + } DBUG_PRINT("info", ("IO layer change done!")); } #endif /* HAVE_OPENSSL */ From 93fdc6a584fd3d49e23c78c16aa068b7c83a46be Mon Sep 17 00:00:00 2001 From: "venu@myvenu.com" <> Date: Fri, 22 Nov 2002 10:52:52 -0800 Subject: [PATCH 05/10] libmysql.c: fix merge conflict --- libmysql/libmysql.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 47df7acb0b1..410be65660f 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -927,11 +927,8 @@ static const char *default_options[]= "character-sets-dir", "default-character-set", "interactive-timeout", "connect-timeout", "local-infile", "disable-local-infile", "replication-probe", "enable-reads-from-master", "repl-parse-query", - "ssl-cipher","protocol", -red_memory_base_name", - - - NullS + "ssl-cipher","protocol", "shared_memory_base_name", + NullS }; static TYPELIB option_types={array_elements(default_options)-1, From ec17cac968946e69469176e6bf088625593b02b3 Mon Sep 17 00:00:00 2001 From: "venu@myvenu.com" <> Date: Fri, 22 Nov 2002 11:58:20 -0800 Subject: [PATCH 06/10] Missed include/ files --- include/mysql.h | 13 +++++++++---- include/mysql_com.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/mysql.h b/include/mysql.h index ad369988084..230c0aad9df 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -57,6 +57,9 @@ typedef int my_socket; #include "mysql_com.h" #include "mysql_version.h" #include "typelib.h" +#ifndef DBUG_OFF +#define CHECK_EXTRA_ARGUMENTS +#endif extern unsigned int mysql_port; extern char *mysql_unix_port; @@ -424,7 +427,7 @@ int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, */ /* statement state */ -enum MY_STMT_STATE { MY_ST_UNKNOWN, MY_ST_PREPARE, MY_ST_EXECUTE }; +enum PREP_STMT_STATE { MY_ST_UNKNOWN, MY_ST_PREPARE, MY_ST_EXECUTE }; /* bind structure */ typedef struct st_mysql_bind @@ -442,7 +445,7 @@ typedef struct st_mysql_bind my_bool long_ended; /* All data supplied for long */ unsigned int param_number; /* For null count and error messages */ void (*store_param_func)(NET *net, struct st_mysql_bind *param); - char *(*fetch_result)(struct st_mysql_bind *, const char *row); + void (*fetch_result)(struct st_mysql_bind *, unsigned char **row); } MYSQL_BIND; @@ -462,10 +465,12 @@ typedef struct st_mysql_stmt unsigned long long_length; /* long buffer alloced length */ unsigned long stmt_id; /* Id for prepared statement */ unsigned int last_errno; /* error code */ - enum MY_STMT_STATE state; /* statement state */ + enum PREP_STMT_STATE state; /* statement state */ char last_error[MYSQL_ERRMSG_SIZE]; /* error message */ my_bool long_alloced; /* flag to indicate long alloced */ - my_bool types_supplied; /* to indicate types supply */ + my_bool send_types_to_server; /* to indicate types supply to server */ + my_bool param_buffers; /* to indicate the param bound buffers */ + my_bool res_buffers; /* to indicate the result bound buffers */ } MYSQL_STMT; diff --git a/include/mysql_com.h b/include/mysql_com.h index 5bf0394c7b0..ebb0522e9be 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -302,6 +302,7 @@ void my_thread_end(void); #endif #define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */ +#define MYSQL_STMT_HEADER 4 #define MYSQL_LONG_DATA_HEADER 8 #endif From 500e56e0d69df1ee391383dc9127efaf3d068658 Mon Sep 17 00:00:00 2001 From: "venu@myvenu.com" <> Date: Fri, 22 Nov 2002 18:30:55 -0800 Subject: [PATCH 07/10] client_test.c: Modification to new API test sql_prepare.cc: Fix for lock_types --- sql/sql_prepare.cc | 35 +- tests/client_test.c | 1358 ++++++++++++++++++++++--------------------- 2 files changed, 713 insertions(+), 680 deletions(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 4bc66778ffb..3ec12177778 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -276,8 +276,9 @@ static void setup_param_functions(Item_param *param, uchar read_pos) from client .. */ -static bool setup_params_data(THD *thd, PREP_STMT *stmt) +static bool setup_params_data(PREP_STMT *stmt) { + THD *thd= stmt->thd; List ¶ms= thd->lex.param_list; List_iterator param_iterator(params); Item_param *param; @@ -375,8 +376,7 @@ static int check_prepare_fields(THD *thd,TABLE *table, List &fields, static bool mysql_test_insert_fields(PREP_STMT *stmt, TABLE_LIST *table_list, List &fields, - List &values_list, - thr_lock_type lock_type) + List &values_list) { THD *thd= stmt->thd; TABLE *table; @@ -384,7 +384,7 @@ static bool mysql_test_insert_fields(PREP_STMT *stmt, List_item *values; DBUG_ENTER("mysql_test_insert_fields"); - if (!(table = open_ltable(thd,table_list,lock_type))) + if (!(table = open_ltable(thd,table_list,table_list->lock_type))) DBUG_RETURN(1); if ((values= its++)) @@ -427,13 +427,13 @@ static bool mysql_test_insert_fields(PREP_STMT *stmt, static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list, List &fields, List &values, - COND *conds, thr_lock_type lock_type) + COND *conds) { THD *thd= stmt->thd; TABLE *table; DBUG_ENTER("mysql_test_upd_fields"); - if (!(table = open_ltable(thd,table_list,lock_type))) + if (!(table = open_ltable(thd,table_list,table_list->lock_type))) DBUG_RETURN(1); if (setup_tables(table_list) || setup_fields(thd,table_list,fields,1,0,0) || @@ -465,7 +465,7 @@ static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list, static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, List &fields, List &values, COND *conds, ORDER *order, ORDER *group, - Item *having, thr_lock_type lock_type) + Item *having) { TABLE *table; bool hidden_group_fields; @@ -473,7 +473,7 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, List all_fields(fields); DBUG_ENTER("mysql_test_select_fields"); - if (!(table = open_ltable(thd,tables,lock_type))) + if (!(table = open_ltable(thd,tables,tables->lock_type))) DBUG_RETURN(1); thd->used_tables=0; // Updated by setup_fields @@ -546,21 +546,19 @@ static bool send_prepare_results(PREP_STMT *stmt) case SQLCOM_INSERT: if (mysql_test_insert_fields(stmt, tables, lex->field_list, - lex->many_values, lex->lock_option)) + lex->many_values)) goto abort; break; case SQLCOM_UPDATE: if (mysql_test_upd_fields(stmt, tables, select_lex->item_list, - lex->value_list, select_lex->where, - lex->lock_option)) + lex->value_list, select_lex->where)) goto abort; break; case SQLCOM_DELETE: if (mysql_test_upd_fields(stmt, tables, select_lex->item_list, - lex->value_list, select_lex->where, - lex->lock_option)) + lex->value_list, select_lex->where)) goto abort; break; @@ -568,8 +566,7 @@ static bool send_prepare_results(PREP_STMT *stmt) if (mysql_test_select_fields(stmt, tables, select_lex->item_list, lex->value_list, select_lex->where, (ORDER*) select_lex->order_list.first, - (ORDER*) select_lex->group_list.first, - select_lex->having, lex->lock_option)) + (ORDER*) select_lex->group_list.first, select_lex->having)) goto abort; break; @@ -712,11 +709,9 @@ void mysql_stmt_execute(THD *thd, char *packet) DBUG_VOID_RETURN; } - if (stmt->param_count && setup_params_data(thd, stmt)) + if (stmt->param_count && setup_params_data(stmt)) DBUG_VOID_RETURN; - MEM_ROOT thd_root= thd->mem_root; - thd->mem_root = thd->con_root; if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); @@ -726,14 +721,12 @@ void mysql_stmt_execute(THD *thd, char *packet) mysql_delete(), mysql_update() and mysql_select() to not to have re-check on setup_* and other things .. */ - mysql_execute_command(thd); - + mysql_execute_command(stmt->thd); thd->last_prepared_stmt= stmt; if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); - thd->mem_root= thd_root; DBUG_VOID_RETURN; } diff --git a/tests/client_test.c b/tests/client_test.c index a00c475129d..280df2bf717 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -48,15 +48,22 @@ #define false 0 #endif +#ifndef bzero +#define bzero(A,B) memset(A,0,B) +#endif + /* set default options */ -static char *opt_db=(char *)"test"; -static char *opt_user=(char *)"root"; -static char *opt_password=(char *)""; +static char *opt_db=0; +static char *opt_user=0; +static char *opt_password=0; static char *opt_host=0; static char *opt_unix_socket=0; static uint opt_port; static my_bool tty_password=0; +static MYSQL *mysql=0; +static char query[255]; + #define myheader(str) { printf("\n\n#######################\n"); \ printf("%s",str); \ printf("\n#######################\n"); \ @@ -64,9 +71,9 @@ static my_bool tty_password=0; #define init_bind(x) (bzero(x,sizeof(x))) -void print_error(MYSQL *mysql, const char *msg) +void print_error(const char *msg) { - if(mysql) + if (mysql) { fprintf(stderr,"\n [MySQL]%s \n",mysql_error(mysql)); } @@ -75,14 +82,14 @@ void print_error(MYSQL *mysql, const char *msg) void print_st_error(MYSQL_STMT *stmt, const char *msg) { - if(stmt) + if (stmt) { fprintf(stderr,"\n [MySQL]%s \n",mysql_stmt_error(stmt)); } else if(msg) fprintf(stderr, "%s\n", msg); } -#define myerror(mysql, msg) print_error(mysql, msg) +#define myerror(msg) print_error(msg) #define mysterror(stmt, msg) print_st_error(stmt, msg) #define myassert(x) if(x) {\ @@ -94,17 +101,17 @@ void print_st_error(MYSQL_STMT *stmt, const char *msg) exit(1);\ } -#define myquery(mysql,r) \ +#define myquery(r) \ if( r != 0) \ { \ - myerror(mysql,NULL); \ + myerror(NULL); \ myassert(true);\ } -#define myquery_r(mysql,r) \ +#define myquery_r(r) \ if( r != 0) \ { \ - myerror(mysql,NULL); \ + myerror(NULL); \ myassert_r(true);\ } @@ -115,17 +122,17 @@ if( r != 0) \ myassert(true);\ } -#define myxquery(mysql,stmt) \ +#define myxquery(stmt) \ if( stmt == 0) \ { \ - myerror(mysql,NULL); \ + myerror(NULL); \ myassert(true);\ } -#define myxquery_r(mysql,stmt) \ +#define myxquery_r(stmt) \ if( stmt == 0) \ { \ - myerror(mysql,NULL); \ + myerror(NULL); \ myassert_r(true);\ } \ else myassert(true); @@ -137,40 +144,37 @@ if( r != 0) \ myassert_r(true);\ } -#define mytest(mysql,x) if(!x) {myerror(mysql,NULL);myassert(true);} -#define mytest_r(mysql,x) if(x) {myerror(mysql,NULL);myassert(true);} +#define mytest(x) if(!x) {myerror(NULL);myassert(true);} +#define mytest_r(x) if(x) {myerror(NULL);myassert(true);} /******************************************************** * connect to the server * *********************************************************/ -MYSQL *client_connect() +static void client_connect() { - MYSQL *mysql; - myheader("client_connect"); if(!(mysql = mysql_init(NULL))) { - myerror(NULL, "mysql_init() failed"); + myerror("mysql_init() failed"); exit(0); } if (!(mysql_real_connect(mysql,opt_host,opt_user, - opt_password, opt_db, opt_port, + opt_password, opt_db ? opt_db:"test", opt_port, opt_unix_socket, 0))) { - myerror(mysql, "connection failed"); + myerror("connection failed"); exit(0); } /* set AUTOCOMMIT to ON*/ mysql_autocommit(mysql, true); - return(mysql); } /******************************************************** * close the connection * *********************************************************/ -void client_disconnect(MYSQL *mysql) +void client_disconnect() { myheader("client_disconnect"); @@ -180,39 +184,39 @@ void client_disconnect(MYSQL *mysql) /******************************************************** * query processing * *********************************************************/ -void client_query(MYSQL *mysql) +void client_query() { int rc; myheader("client_query"); rc = mysql_query(mysql,"DROP TABLE IF EXISTS myclient_test"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE myclient_test(id int primary key auto_increment,\ name varchar(20))"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE myclient_test(id int, name varchar(20))"); - myquery_r(mysql,rc); + myquery_r(rc); rc = mysql_query(mysql,"INSERT INTO myclient_test(name) VALUES('mysql')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"INSERT INTO myclient_test(name) VALUES('monty')"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_query(mysql,"INSERT INTO myclient_test(name) VALUES('venu')"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_query(mysql,"INSERT INTO myclient_test(name) VALUES('deleted')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"UPDATE myclient_test SET name='updated' WHERE name='deleted'"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_query(mysql,"UPDATE myclient_test SET id=3 WHERE name='updated'"); - myquery_r(mysql,rc); + myquery_r(rc); } /******************************************************** @@ -226,12 +230,12 @@ void my_print_dashes(MYSQL_RES *result) mysql_field_seek(result,0); fputc('\t',stdout); fputc('+', stdout); - + for(i=0; i< mysql_num_fields(result); i++) { field = mysql_fetch_field(result); for(j=0; j < field->max_length+2; j++) - fputc('-',stdout); + fputc('-',stdout); fputc('+',stdout); } fputc('\n',stdout); @@ -247,7 +251,7 @@ void my_print_result_metadata(MYSQL_RES *result) unsigned int field_count; mysql_field_seek(result,0); - fputc('\n', stdout); + fputc('\n', stdout); field_count = mysql_num_fields(result); for(i=0; i< field_count; i++) @@ -263,7 +267,7 @@ void my_print_result_metadata(MYSQL_RES *result) my_print_dashes(result); fputc('\t',stdout); fputc('|', stdout); - + mysql_field_seek(result,0); for(i=0; i< field_count; i++) { @@ -277,7 +281,7 @@ void my_print_result_metadata(MYSQL_RES *result) /******************************************************** * process the result set * *********************************************************/ -int my_process_result_set(MYSQL *mysql, MYSQL_RES *result) +int my_process_result_set(MYSQL_RES *result) { MYSQL_ROW row; MYSQL_FIELD *field; @@ -287,7 +291,7 @@ int my_process_result_set(MYSQL *mysql, MYSQL_RES *result) my_print_result_metadata(result); while((row = mysql_fetch_row(result)) != NULL) - { + { mysql_field_seek(result,0); fputc('\t',stdout); fputc('|',stdout); @@ -310,49 +314,83 @@ int my_process_result_set(MYSQL *mysql, MYSQL_RES *result) if (mysql_errno(mysql) != 0) fprintf(stderr, "\n\tmysql_fetch_row() failed\n"); - else + else fprintf(stdout,"\n\t%d rows returned\n", row_count); return(row_count); } +static void verify_col_data(const char *table, const char *col, const char *exp_data) +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + char data[255]; + int rc; + + init_bind(bind); + + bind[0].buffer_type=FIELD_TYPE_STRING; + bind[0].buffer= (char *)data; + bind[0].buffer_length= sizeof(data); + + sprintf(query, "SELECT `%s` FROM `%s`", col, table); + + printf("\n %s", query); + stmt = mysql_prepare(mysql, query, strlen(query)); + myxquery(stmt); + + rc = mysql_bind_result(stmt,bind); + mystmt(stmt, rc); + + rc = mysql_execute(stmt); + mystmt(stmt, rc); + + rc = mysql_fetch(stmt); + mystmt(stmt,rc); + + printf("\n data : %s (expected: %s)",data, exp_data); + assert(strcmp(data,exp_data)==0); + + mysql_stmt_close(stmt); +} + /******************************************************** * store result processing * *********************************************************/ -void client_store_result(MYSQL *mysql) +void client_store_result() { MYSQL_RES *result; int rc; - + myheader("client_store_result"); rc = mysql_query(mysql, "SELECT * FROM myclient_test"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - my_process_result_set(mysql,result); + my_process_result_set(result); mysql_free_result(result); } /******************************************************** * use result processing * *********************************************************/ -void client_use_result(MYSQL *mysql) +void client_use_result() { MYSQL_RES *result; int rc; myheader("client_use_result"); - rc = mysql_query(mysql, "SELECT * FROM myclient_test"); - myquery(mysql,rc); + rc = mysql_query(mysql, "SELECT * FROM myclient_test"); + myquery(rc); /* get the result */ result = mysql_use_result(mysql); - mytest(mysql,result); + mytest(result); - my_process_result_set(mysql,result); + my_process_result_set(result); mysql_free_result(result); } @@ -360,7 +398,7 @@ void client_use_result(MYSQL *mysql) /******************************************************** * query processing * *********************************************************/ -void test_debug_example(MYSQL *mysql) +void test_debug_example() { int rc; MYSQL_RES *result; @@ -368,35 +406,35 @@ void test_debug_example(MYSQL *mysql) myheader("test_debug_example"); rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_debug_example"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_debug_example(id int primary key auto_increment,\ name varchar(20),xxx int)"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_query(mysql,"INSERT INTO test_debug_example(name) VALUES('mysql')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"UPDATE test_debug_example SET name='updated' WHERE name='deleted'"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"SELECT * FROM test_debug_example"); - myquery(mysql,rc); - - result = mysql_use_result(mysql); - mytest(mysql,result); + myquery(rc); - my_process_result_set(mysql,result); + result = mysql_use_result(mysql); + mytest(result); + + my_process_result_set(result); mysql_free_result(result); rc = mysql_query(mysql,"DROP TABLE test_debug_example"); - myquery(mysql,rc); + myquery(rc); } /******************************************************** * to test autocommit feature * *********************************************************/ -void test_tran_bdb(MYSQL *mysql) +void test_tran_bdb() { MYSQL_RES *result; MYSQL_ROW row; @@ -406,75 +444,75 @@ void test_tran_bdb(MYSQL *mysql) /* set AUTOCOMMIT to OFF */ rc = mysql_autocommit(mysql, false); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_demo_transaction"); + myquery(rc); + - rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_demo_transaction"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ rc = mysql_query(mysql,"CREATE TABLE my_demo_transaction(col1 int ,col2 varchar(30)) TYPE = BDB"); - myquery(mysql,rc); + myquery(rc); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* insert a row and commit the transaction */ rc = mysql_query(mysql,"INSERT INTO my_demo_transaction VALUES(10,'venu')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* now insert the second row, and rollback the transaction */ rc = mysql_query(mysql,"INSERT INTO my_demo_transaction VALUES(20,'mysql')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_rollback(mysql); - myquery(mysql,rc); + myquery(rc); /* delete first row, and rollback it */ rc = mysql_query(mysql,"DELETE FROM my_demo_transaction WHERE col1 = 10"); - myquery(mysql,rc); + myquery(rc); rc = mysql_rollback(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM my_demo_transaction"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - my_process_result_set(mysql,result); + my_process_result_set(result); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM my_demo_transaction"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_use_result(mysql); - mytest(mysql,result); - - row = mysql_fetch_row(result); - mytest(mysql,row); - - row = mysql_fetch_row(result); - mytest_r(mysql,row); + mytest(result); - mysql_free_result(result); + row = mysql_fetch_row(result); + mytest(row); + + row = mysql_fetch_row(result); + mytest_r(row); + + mysql_free_result(result); mysql_autocommit(mysql,true); } /******************************************************** * to test autocommit feature * *********************************************************/ -void test_tran_innodb(MYSQL *mysql) +void test_tran_innodb() { MYSQL_RES *result; MYSQL_ROW row; @@ -484,68 +522,68 @@ void test_tran_innodb(MYSQL *mysql) /* set AUTOCOMMIT to OFF */ rc = mysql_autocommit(mysql, false); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_demo_transaction"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_demo_transaction"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ rc = mysql_query(mysql,"CREATE TABLE my_demo_transaction(col1 int ,col2 varchar(30)) TYPE = InnoDB"); - myquery(mysql,rc); + myquery(rc); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* insert a row and commit the transaction */ rc = mysql_query(mysql,"INSERT INTO my_demo_transaction VALUES(10,'venu')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* now insert the second row, and rollback the transaction */ rc = mysql_query(mysql,"INSERT INTO my_demo_transaction VALUES(20,'mysql')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_rollback(mysql); - myquery(mysql,rc); + myquery(rc); /* delete first row, and rollback it */ rc = mysql_query(mysql,"DELETE FROM my_demo_transaction WHERE col1 = 10"); - myquery(mysql,rc); + myquery(rc); rc = mysql_rollback(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM my_demo_transaction"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - my_process_result_set(mysql,result); + my_process_result_set(result); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM my_demo_transaction"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_use_result(mysql); - mytest(mysql,result); - + mytest(result); + row = mysql_fetch_row(result); - mytest(mysql,row); - + mytest(row); + row = mysql_fetch_row(result); - mytest_r(mysql,row); + mytest_r(row); mysql_free_result(result); - mysql_autocommit(mysql,true); + mysql_autocommit(mysql,true); } @@ -553,27 +591,26 @@ void test_tran_innodb(MYSQL *mysql) To test simple prepares of all DML statements *********************************************************/ -void test_prepare_simple(MYSQL *mysql) +void test_prepare_simple() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; - myheader("test_prepare_simple"); - - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_simple"); - myquery(mysql,rc); - + myheader("test_prepare_simple"); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_simple"); + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_prepare_simple(id int, name varchar(50))"); - myquery(mysql,rc); + myquery(rc); /* alter table */ - query = "ALTER TABLE test_prepare_simple ADD new char(20)"; + strcpy(query,"ALTER TABLE test_prepare_simple ADD new char(20)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout,"\n total parameters in alter:%d\n", param_count); @@ -581,9 +618,9 @@ void test_prepare_simple(MYSQL *mysql) mysql_stmt_close(stmt); /* insert */ - query = "INSERT INTO test_prepare_simple VALUES(?,?)"; + strcpy(query,"INSERT INTO test_prepare_simple VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout,"\n total parameters in insert:%d\n", param_count); @@ -591,9 +628,9 @@ void test_prepare_simple(MYSQL *mysql) mysql_stmt_close(stmt); /* update */ - query = "UPDATE test_prepare_simple SET id=? WHERE id=? AND name= ?"; + strcpy(query,"UPDATE test_prepare_simple SET id=? WHERE id=? AND name= ?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout,"\n total parameters in update:%d\n", param_count); @@ -601,9 +638,9 @@ void test_prepare_simple(MYSQL *mysql) mysql_stmt_close(stmt); /* delete */ - query = "DELETE FROM test_prepare_simple WHERE id=10"; + strcpy(query,"DELETE FROM test_prepare_simple WHERE id=10"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout,"\n total parameters in delete:%d\n", param_count); @@ -614,9 +651,9 @@ void test_prepare_simple(MYSQL *mysql) mysql_stmt_close(stmt); /* delete */ - query = "DELETE FROM test_prepare_simple WHERE id=?"; + strcpy(query,"DELETE FROM test_prepare_simple WHERE id=?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout,"\n total parameters in delete:%d\n", param_count); @@ -627,9 +664,9 @@ void test_prepare_simple(MYSQL *mysql) mysql_stmt_close(stmt); /* select */ - query = "SELECT * FROM test_prepare_simple WHERE id=? AND name= ?"; + strcpy(query,"SELECT * FROM test_prepare_simple WHERE id=? AND name= ?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout,"\n total parameters in select:%d\n", param_count); @@ -639,35 +676,33 @@ void test_prepare_simple(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); } /******************************************************** * to test simple prepare field results * *********************************************************/ -void test_prepare_field_result(MYSQL *mysql) +void test_prepare_field_result() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; - myheader("test_prepare_field_result"); - - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_field_result"); - myquery(mysql,rc); - + myheader("test_prepare_field_result"); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_field_result"); + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_prepare_field_result(id int, name varchar(50), extra int)"); - myquery(mysql,rc); - + myquery(rc); /* insert */ - query = "SELECT id,name FROM test_prepare_field_result WHERE id=?"; + strcpy(query,"SELECT id,name FROM test_prepare_field_result WHERE id=?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout,"\n total parameters in insert:%d\n", param_count); @@ -676,49 +711,48 @@ void test_prepare_field_result(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); } /******************************************************** * to test simple prepare field results * *********************************************************/ -void test_prepare_syntax(MYSQL *mysql) +void test_prepare_syntax() { MYSQL_STMT *stmt; int rc; - const char *query; - myheader("test_prepare_syntax"); - - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_syntax"); - myquery(mysql,rc); - + myheader("test_prepare_syntax"); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_syntax"); + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_prepare_syntax(id int, name varchar(50), extra int)"); - myquery(mysql,rc); + myquery(rc); - query = "INSERT INTO test_prepare_syntax VALUES(?"; + strcpy(query,"INSERT INTO test_prepare_syntax VALUES(?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery_r(mysql,stmt); + myxquery_r(stmt); - query = "SELECT id,name FROM test_prepare_syntax WHERE id=? AND WHERE"; + strcpy(query,"SELECT id,name FROM test_prepare_syntax WHERE id=? AND WHERE"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery_r(mysql,stmt); + myxquery_r(stmt); /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); } /******************************************************** * to test simple prepare * *********************************************************/ -void test_prepare(MYSQL *mysql) -{ +void test_prepare() +{ MYSQL_STMT *stmt; int rc,param_count; char query[200]; @@ -730,30 +764,30 @@ void test_prepare(MYSQL *mysql) double real_data; double double_data; MYSQL_RES *result; - MYSQL_BIND bind[8]; + MYSQL_BIND bind[8]; - myheader("test_prepare"); + myheader("test_prepare"); init_bind(bind); rc = mysql_autocommit(mysql, true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_prepare"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_prepare"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE my_prepare(col1 tinyint,\ col2 varchar(50), col3 int,\ col4 smallint, col5 bigint, \ col6 float, col7 double )"); - myquery(mysql,rc); + myquery(rc); /* insert by prepare */ strcpy(query,"INSERT INTO my_prepare VALUES(?,?,?,?,?,?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); @@ -765,22 +799,23 @@ void test_prepare(MYSQL *mysql) /* string */ bind[1].buffer_type=FIELD_TYPE_STRING; bind[1].buffer=str_data; + bind[1].buffer_length=sizeof(str_data); /* integer */ bind[2].buffer_type=FIELD_TYPE_LONG; - bind[2].buffer= (gptr)&int_data; + bind[2].buffer= (gptr)&int_data; /* short */ bind[3].buffer_type=FIELD_TYPE_SHORT; - bind[3].buffer= (gptr)&small_data; + bind[3].buffer= (gptr)&small_data; /* bigint */ bind[4].buffer_type=FIELD_TYPE_LONGLONG; - bind[4].buffer= (gptr)&big_data; + bind[4].buffer= (gptr)&big_data; /* float */ bind[5].buffer_type=FIELD_TYPE_DOUBLE; - bind[5].buffer= (gptr)&real_data; + bind[5].buffer= (gptr)&real_data; /* double */ bind[6].buffer_type=FIELD_TYPE_DOUBLE; - bind[6].buffer= (gptr)&double_data; - + bind[6].buffer= (gptr)&double_data; + rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); @@ -807,17 +842,17 @@ void test_prepare(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM my_prepare"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert((int)tiny_data == my_process_result_set(mysql,result)); + assert((int)tiny_data == my_process_result_set(result)); mysql_free_result(result); } @@ -825,37 +860,37 @@ void test_prepare(MYSQL *mysql) /******************************************************** * to test double comparision * *********************************************************/ -void test_double_compare(MYSQL *mysql) -{ +void test_double_compare() +{ MYSQL_STMT *stmt; int rc,param_count; char query[200],real_data[10], tiny_data; double double_data; MYSQL_RES *result; - MYSQL_BIND bind[3]; + MYSQL_BIND bind[3]; - myheader("test_double_compare"); + myheader("test_double_compare"); init_bind(bind); rc = mysql_autocommit(mysql, true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_double_compare"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_double_compare"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_double_compare(col1 tinyint,\ col2 float, col3 double )"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"INSERT INTO test_double_compare VALUES(1,10.2,34.5)"); - myquery(mysql,rc); + myquery(rc); strcpy(query, "UPDATE test_double_compare SET col1=100 WHERE col1 = ? AND col2 = ? AND COL3 = ?"); stmt = mysql_prepare(mysql,query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in update:%d\n", param_count); @@ -865,11 +900,12 @@ void test_double_compare(MYSQL *mysql) bind[0].buffer=(gptr)&tiny_data; /* string->float */ bind[1].buffer_type=FIELD_TYPE_STRING; - bind[1].buffer= (gptr)&real_data; + bind[1].buffer= (gptr)&real_data; + bind[1].buffer_length=10; /* double */ bind[2].buffer_type=FIELD_TYPE_DOUBLE; - bind[2].buffer= (gptr)&double_data; - + bind[2].buffer= (gptr)&double_data; + tiny_data = 1; strcpy(real_data,"10.2"); double_data = 34.5; @@ -881,22 +917,22 @@ void test_double_compare(MYSQL *mysql) rc = (int)mysql_affected_rows(mysql); printf("\n total affected rows:%d",rc); - + mysql_stmt_close(stmt); /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM test_double_compare"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert((int)tiny_data == my_process_result_set(mysql,result)); + assert((int)tiny_data == my_process_result_set(result)); mysql_free_result(result); } @@ -907,43 +943,43 @@ void test_double_compare(MYSQL *mysql) /******************************************************** * to test simple null * *********************************************************/ -void test_null(MYSQL *mysql) +void test_null() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; int nData=1; MYSQL_RES *result; - MYSQL_BIND bind[2]; + MYSQL_BIND bind[2]; - myheader("test_null"); + myheader("test_null"); init_bind(bind); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_null"); - myquery(mysql,rc); - + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_null"); + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_null(col1 int,col2 varchar(50))"); - myquery(mysql,rc); + myquery(rc); /* insert by prepare, wrong column name */ - query = "INSERT INTO test_null(col3,col2) VALUES(?,?)"; + strcpy(query,"INSERT INTO test_null(col3,col2) VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery_r(mysql,stmt); + myxquery_r(stmt); - query = "INSERT INTO test_null(col1,col2) VALUES(?,?)"; + strcpy(query,"INSERT INTO test_null(col1,col2) VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); assert(param_count == 2); bind[0].is_null=1; - bind[1].is_null=1; /* string data */ - + bind[0].buffer_type=MYSQL_TYPE_NULL; + bind[1]=bind[0]; /* string data */ + rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); @@ -957,19 +993,18 @@ void test_null(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM test_null"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(nData == my_process_result_set(mysql,result)); + assert(nData == my_process_result_set(result)); mysql_free_result(result); - } @@ -977,20 +1012,19 @@ void test_null(MYSQL *mysql) /******************************************************** * to test simple select * *********************************************************/ -void test_select_simple(MYSQL *mysql) +void test_select_simple() { MYSQL_STMT *stmt; int rc,length; const char query[100]; MYSQL_RES *result; - myheader("test_select_simple"); - + myheader("test_select_simple"); /* insert by prepare */ strcpy((char *)query, "SHOW TABLES FROM mysql"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); length = mysql_param_count(stmt); fprintf(stdout," total parameters in select:%d\n", length); @@ -998,25 +1032,27 @@ void test_select_simple(MYSQL *mysql) rc = mysql_execute(stmt); mystmt(stmt, rc); - + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - my_process_result_set(mysql,result); + my_process_result_set(result); mysql_free_result(result); - + + mysql_stmt_close(stmt); + #if 0 strcpy((char *)query , "SELECT @@ VERSION"); length = strlen(query); rc = mysql_query(mysql,query); - mytest(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - my_process_result_set(mysql,result); + my_process_result_set(result); mysql_free_result(result); #endif } @@ -1025,52 +1061,51 @@ void test_select_simple(MYSQL *mysql) /******************************************************** * to test simple select * *********************************************************/ -void test_select(MYSQL *mysql) +void test_select() { MYSQL_STMT *stmt; int rc,param_count=0; - const char *query; char *szData=(char *)"updated-value"; int nData=1; - MYSQL_BIND bind[2]; + MYSQL_BIND bind[2]; MYSQL_RES *result; - - myheader("test_select"); + + myheader("test_select"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_select"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_select"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_select(id int,name varchar(50))"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* insert a row and commit the transaction */ rc = mysql_query(mysql,"INSERT INTO test_select VALUES(10,'venu')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* now insert the second row, and rollback the transaction */ rc = mysql_query(mysql,"INSERT INTO test_select VALUES(20,'mysql')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); - query = "SELECT * FROM test_select WHERE id=? AND name=?"; + strcpy(query,"SELECT * FROM test_select WHERE id=? AND name=?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in select:%d\n", param_count); @@ -1081,20 +1116,21 @@ void test_select(MYSQL *mysql) szData=(char *)"venu"; bind[1].buffer_type=FIELD_TYPE_STRING; bind[1].buffer=szData; + bind[1].buffer_length=4; bind[0].buffer=(gptr)&nData; bind[0].buffer_type=FIELD_TYPE_LONG; - + rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); rc = mysql_execute(stmt); mystmt(stmt, rc); - + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert( 1 == my_process_result_set(mysql,result)); + assert( 1 == my_process_result_set(result)); mysql_free_result(result); mysql_stmt_close(stmt); @@ -1108,48 +1144,46 @@ void test_select(MYSQL *mysql) /******************************************************** * to test simple update * *********************************************************/ -void test_simple_update(MYSQL *mysql) +void test_simple_update() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; - char *szData=(char *)"updated-value"; + char szData[25]; int nData=1; MYSQL_RES *result; - MYSQL_BIND bind[2]; - + MYSQL_BIND bind[2]; - myheader("test_simple_update"); + myheader("test_simple_update"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_update"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_update"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_update(col1 int,\ col2 varchar(50), col3 int )"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"INSERT INTO test_update VALUES(1,'MySQL',100)"); - myquery(mysql,rc); - + myquery(rc); + assert(1 == mysql_affected_rows(mysql)); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* insert by prepare */ - query = "UPDATE test_update SET col2=? WHERE col1=?"; + strcpy(query,"UPDATE test_update SET col2=? WHERE col1=?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in update:%d\n", param_count); @@ -1158,9 +1192,10 @@ void test_simple_update(MYSQL *mysql) nData=1; bind[0].buffer_type=FIELD_TYPE_STRING; bind[0].buffer=szData; /* string data */ + bind[0].buffer_length=sprintf(szData,"updated-data"); bind[1].buffer=(gptr)&nData; bind[1].buffer_type=FIELD_TYPE_LONG; - + rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); @@ -1172,17 +1207,17 @@ void test_simple_update(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM test_update"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(1 == my_process_result_set(mysql,result)); + assert(1 == my_process_result_set(result)); mysql_free_result(result); } @@ -1190,53 +1225,58 @@ void test_simple_update(MYSQL *mysql) /******************************************************** * to test simple long data handling * *********************************************************/ -void test_long_data(MYSQL *mysql) +void test_long_data() { MYSQL_STMT *stmt; - int rc,param_count; - const char *query; + int rc,param_count, int_data=10; char *data=NullS; MYSQL_RES *result; - MYSQL_BIND bind[2]; - + MYSQL_BIND bind[3]; - myheader("test_long_data"); + + myheader("test_long_data"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_long_data(col1 int,\ col2 long varchar, col3 long varbinary)"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); - query = "INSERT INTO test_long_data(col2) VALUES(?)"; + rc = mysql_commit(mysql); + myquery(rc); + + strcpy(query,"INSERT INTO test_long_data(col1,col2) VALUES(?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery_r(stmt); + + strcpy(query,"INSERT INTO test_long_data(col1,col2,col3) VALUES(?,?,?)"); + stmt = mysql_prepare(mysql, query, strlen(query)); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); - assert(param_count == 1); + assert(param_count == 3); - bind[0].buffer=data; /* string data */ - bind[0].is_long_data=1; /* specify long data suppy during run-time */ + bind[0].buffer=(char *)&int_data; + bind[0].buffer_type=FIELD_TYPE_LONG; + bind[1].is_long_data=1; /* specify long data suppy during run-time */ /* Non string or binary type, error */ - bind[0].buffer_type=FIELD_TYPE_LONG; + bind[1].buffer_type=FIELD_TYPE_LONG; rc = mysql_bind_param(stmt,bind); fprintf(stdout,"mysql_bind_param() returned %d\n",rc); mystmt_r(stmt, rc); - - bind[0].buffer_type=FIELD_TYPE_STRING; + + bind[1].buffer_type=FIELD_TYPE_STRING; + bind[2]=bind[1]; rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); @@ -1247,11 +1287,11 @@ void test_long_data(MYSQL *mysql) data = (char *)"Micheal"; /* supply data in pieces */ - rc = mysql_send_long_data(stmt,0,data,7,1); + rc = mysql_send_long_data(stmt,1,data,7,1); mystmt(stmt, rc); - /* try to execute mysql_execute() now, it should return - MYSQL_NEED_DATA as the long data supply is not yet over + /* try to execute mysql_execute() now, it should return + MYSQL_NEED_DATA as the long data supply is not yet over */ rc = mysql_execute(stmt); fprintf(stdout,"mysql_execute() returned %d\n",rc); @@ -1259,13 +1299,12 @@ void test_long_data(MYSQL *mysql) /* append data again ..*/ - /* supply data in pieces */ + /* Indicate end of data */ data = (char *)" 'monty' widenius"; - rc = mysql_send_long_data(stmt,0,data,17,0); + rc = mysql_send_long_data(stmt,1,data,17,1); mystmt(stmt, rc); - /* Indiate end of data supply */ - rc = mysql_send_long_data(stmt,0,0,0,1); + rc = mysql_send_long_data(stmt,2,"Venu (venu@mysql.com",4,1); mystmt(stmt, rc); /* execute */ @@ -1274,55 +1313,54 @@ void test_long_data(MYSQL *mysql) mystmt(stmt,rc); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* now fetch the results ..*/ - rc = mysql_query(mysql,"SELECT col2 FROM test_long_data"); - myquery(mysql,rc); - + rc = mysql_query(mysql,"SELECT * FROM test_long_data"); + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(1 == my_process_result_set(mysql,result)); + assert(1 == my_process_result_set(result)); mysql_free_result(result); } /******************************************************** * to test long data (string) handling * *********************************************************/ -void test_long_data_str(MYSQL *mysql) +void test_long_data_str() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; char data[255]; long length; MYSQL_RES *result; - MYSQL_BIND bind[2]; - + MYSQL_BIND bind[2]; - myheader("test_long_data_str"); + + myheader("test_long_data_str"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data_str"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data_str"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_long_data_str(id int, longstr long varchar)"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); - query = "INSERT INTO test_long_data_str VALUES(?,?)"; + rc = mysql_commit(mysql); + myquery(rc); + + strcpy(query,"INSERT INTO test_long_data_str VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); @@ -1354,8 +1392,8 @@ void test_long_data_str(MYSQL *mysql) mystmt(stmt, rc); } - /* try to execute mysql_execute() now, it should return - MYSQL_NEED_DATA as the long data supply is not yet over + /* try to execute mysql_execute() now, it should return + MYSQL_NEED_DATA as the long data supply is not yet over */ rc = mysql_execute(stmt); fprintf(stdout,"mysql_execute() returned %d\n",rc); @@ -1374,17 +1412,17 @@ void test_long_data_str(MYSQL *mysql) mysql_stmt_close(stmt); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* now fetch the results ..*/ rc = mysql_query(mysql,"SELECT LENGTH(longstr), longstr FROM test_long_data_str"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(1 == my_process_result_set(mysql,result)); + assert(1 == my_process_result_set(result)); mysql_free_result(result); } @@ -1392,38 +1430,37 @@ void test_long_data_str(MYSQL *mysql) /******************************************************** * to test long data (string) handling * *********************************************************/ -void test_long_data_str1(MYSQL *mysql) +void test_long_data_str1() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; char *data=(char *)"MySQL AB"; int length; MYSQL_RES *result; - MYSQL_BIND bind[2]; - + MYSQL_BIND bind[2]; - myheader("test_long_data_str1"); + + myheader("test_long_data_str1"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data_str"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data_str"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_long_data_str(longstr long varchar,blb long varbinary)"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); - query = "INSERT INTO test_long_data_str VALUES(?,?)"; + rc = mysql_commit(mysql); + myquery(rc); + + strcpy(query,"INSERT INTO test_long_data_str VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); @@ -1457,8 +1494,8 @@ void test_long_data_str1(MYSQL *mysql) rc = mysql_send_long_data(stmt,1,data,2,0); mystmt(stmt, rc); } - /* try to execute mysql_execute() now, it should return - MYSQL_NEED_DATA as the long data supply is not yet over + /* try to execute mysql_execute() now, it should return + MYSQL_NEED_DATA as the long data supply is not yet over */ rc = mysql_execute(stmt); fprintf(stdout,"mysql_execute() returned %d\n",rc); @@ -1468,14 +1505,14 @@ void test_long_data_str1(MYSQL *mysql) /* Indiate end of data supply */ rc = mysql_send_long_data(stmt,1,0,0,1); mystmt(stmt, rc); - + rc = mysql_execute(stmt); fprintf(stdout,"mysql_execute() returned %d\n",rc); assert(rc == MYSQL_NEED_DATA); rc = mysql_send_long_data(stmt,0,0,0,1); mystmt(stmt, rc); - + /* execute */ rc = mysql_execute(stmt); fprintf(stdout,"mysql_execute() returned %d\n",rc); @@ -1484,17 +1521,17 @@ void test_long_data_str1(MYSQL *mysql) mysql_stmt_close(stmt); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* now fetch the results ..*/ rc = mysql_query(mysql,"SELECT LENGTH(longstr),longstr,LENGTH(blb),blb FROM test_long_data_str"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(1 == my_process_result_set(mysql,result)); + assert(1 == my_process_result_set(result)); mysql_free_result(result); } @@ -1502,38 +1539,37 @@ void test_long_data_str1(MYSQL *mysql) /******************************************************** * to test long data (binary) handling * *********************************************************/ -void test_long_data_bin(MYSQL *mysql) +void test_long_data_bin() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; char data[255]; int length; MYSQL_RES *result; - MYSQL_BIND bind[2]; - + MYSQL_BIND bind[2]; - myheader("test_long_data_bin"); + + myheader("test_long_data_bin"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data_bin"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_long_data_bin"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_long_data_bin(id int, longbin long varbinary)"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); - query = "INSERT INTO test_long_data_bin VALUES(?,?)"; + rc = mysql_commit(mysql); + myquery(rc); + + strcpy(query,"INSERT INTO test_long_data_bin VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); @@ -1564,8 +1600,8 @@ void test_long_data_bin(MYSQL *mysql) mystmt(stmt, rc); } - /* try to execute mysql_execute() now, it should return - MYSQL_NEED_DATA as the long data supply is not yet over + /* try to execute mysql_execute() now, it should return + MYSQL_NEED_DATA as the long data supply is not yet over */ rc = mysql_execute(stmt); fprintf(stdout,"mysql_execute() returned %d\n",rc); @@ -1584,17 +1620,17 @@ void test_long_data_bin(MYSQL *mysql) mysql_stmt_close(stmt); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* now fetch the results ..*/ rc = mysql_query(mysql,"SELECT LENGTH(longbin), longbin FROM test_long_data_bin"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(1 == my_process_result_set(mysql,result)); + assert(1 == my_process_result_set(result)); mysql_free_result(result); } @@ -1602,65 +1638,63 @@ void test_long_data_bin(MYSQL *mysql) /******************************************************** * to test simple delete * *********************************************************/ -void test_simple_delete(MYSQL *mysql) +void test_simple_delete() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; char szData[30]={0}; int nData=1; MYSQL_RES *result; - MYSQL_BIND bind[2]; - + MYSQL_BIND bind[2]; - myheader("test_simple_delete"); + + myheader("test_simple_delete"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_simple_delete"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_simple_delete"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_simple_delete(col1 int,\ col2 varchar(50), col3 int )"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"INSERT INTO test_simple_delete VALUES(1,'MySQL',100)"); - myquery(mysql,rc); - + myquery(rc); + assert(1 == mysql_affected_rows(mysql)); rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* insert by prepare */ - query = "DELETE FROM test_simple_delete WHERE col1=? AND col2=? AND col3=100"; + strcpy(query,"DELETE FROM test_simple_delete WHERE col1=? AND col2=? AND col3=100"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in delete:%d\n", param_count); assert(param_count == 2); nData=1; + strcpy(szData,"MySQL"); + bind[1].buffer_length = 5; bind[1].buffer_type=FIELD_TYPE_STRING; - bind[1].buffer=szData; /* string data */ + bind[1].buffer=szData; /* string data */ bind[0].buffer=(gptr)&nData; bind[0].buffer_type=FIELD_TYPE_LONG; - + rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); - strcpy(szData,"MySQL"); - //bind[1].buffer_length = 5; - nData=1; rc = mysql_execute(stmt); mystmt(stmt, rc); assert(1 == mysql_affected_rows(mysql)); @@ -1669,17 +1703,17 @@ void test_simple_delete(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM test_simple_delete"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(0 == my_process_result_set(mysql,result)); + assert(0 == my_process_result_set(result)); mysql_free_result(result); } @@ -1688,78 +1722,76 @@ void test_simple_delete(MYSQL *mysql) /******************************************************** * to test simple update * *********************************************************/ -void test_update(MYSQL *mysql) +void test_update() { MYSQL_STMT *stmt; int rc,param_count; - const char *query; - char *szData=(char *)"updated-value"; + char szData[25]; int nData=1; MYSQL_RES *result; - MYSQL_BIND bind[2]; - + MYSQL_BIND bind[2]; - myheader("test_update"); + + myheader("test_update"); init_bind(bind); rc = mysql_autocommit(mysql,true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_update"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_update"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_update(col1 int primary key auto_increment,\ col2 varchar(50), col3 int )"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); - query = "INSERT INTO test_update(col2,col3) VALUES(?,?)"; + rc = mysql_commit(mysql); + myquery(rc); + + strcpy(query,"INSERT INTO test_update(col2,col3) VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); assert(param_count == 2); /* string data */ - szData=(char *)"inserted-data"; bind[0].buffer_type=FIELD_TYPE_STRING; bind[0].buffer=szData; + bind[0].buffer_length=sprintf(szData,"inserted-data"); bind[1].buffer=(gptr)&nData; bind[1].buffer_type=FIELD_TYPE_LONG; - + rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); nData=100; rc = mysql_execute(stmt); mystmt(stmt, rc); - + assert(1 == mysql_affected_rows(mysql)); mysql_stmt_close(stmt); - /* insert by prepare */ - query = "UPDATE test_update SET col2=? WHERE col3=?"; + strcpy(query,"UPDATE test_update SET col2=? WHERE col3=?"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in update:%d\n", param_count); assert(param_count == 2); - nData=100;szData=(char *)"updated-data"; + nData=100; + - bind[0].buffer_type=FIELD_TYPE_STRING; bind[0].buffer=szData; + bind[0].buffer_length=sprintf(szData,"updated-data"); bind[1].buffer=(gptr)&nData; bind[1].buffer_type=FIELD_TYPE_LONG; - rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); @@ -1771,17 +1803,17 @@ void test_update(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM test_update"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(1 == my_process_result_set(mysql,result)); + assert(1 == my_process_result_set(result)); mysql_free_result(result); } @@ -1789,29 +1821,28 @@ void test_update(MYSQL *mysql) /******************************************************** * to test simple prepare * *********************************************************/ -void test_init_prepare(MYSQL *mysql) +void test_init_prepare() { MYSQL_STMT *stmt; int param_count, rc; - const char *query; MYSQL_RES *result; - myheader("test_init_prepare"); - - rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_prepare"); - myquery(mysql,rc); - + myheader("test_init_prepare"); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS my_prepare"); + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE my_prepare(col1 int ,col2 varchar(50))"); - myquery(mysql,rc); - - + myquery(rc); + + /* insert by prepare */ - query = "INSERT INTO my_prepare VALUES(10,'venu')"; + strcpy(query,"INSERT INTO my_prepare VALUES(10,'venu')"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); @@ -1824,17 +1855,17 @@ void test_init_prepare(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM my_prepare"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(1 == my_process_result_set(mysql,result)); + assert(1 == my_process_result_set(result)); mysql_free_result(result); } @@ -1842,55 +1873,56 @@ void test_init_prepare(MYSQL *mysql) /******************************************************** * to test simple bind result * *********************************************************/ -void test_bind_result(MYSQL *mysql) +void test_bind_result() { MYSQL_STMT *stmt; int rc; const char query[100]; int nData; char szData[100]; - MYSQL_BIND bind[2]; + MYSQL_BIND bind[2]; myheader("test_bind_result"); init_bind(bind); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_bind_result"); - myquery(mysql,rc); - + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_bind_result"); + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_bind_result(col1 int ,col2 varchar(50))"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"INSERT INTO test_bind_result VALUES(10,'venu')"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"INSERT INTO test_bind_result VALUES(20,'MySQL')"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); - /* fetch */ + rc = mysql_commit(mysql); + myquery(rc); + + /* fetch */ bind[0].buffer_type=FIELD_TYPE_LONG; bind[0].buffer= (gptr) &nData; /* integer data */ bind[1].buffer_type=FIELD_TYPE_STRING; bind[1].buffer=szData; /* string data */ - + bind[1].buffer_length=sizeof(szData); + strcpy((char *)query , "SELECT * FROM test_bind_result"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); - + myxquery(stmt); + rc = mysql_bind_result(stmt,bind); - mystmt(stmt, rc); + mystmt(stmt, rc); rc = mysql_execute(stmt); - mystmt(stmt, rc); + mystmt(stmt, rc); rc = mysql_fetch(stmt); mystmt(stmt,rc); @@ -1915,30 +1947,29 @@ void test_bind_result(MYSQL *mysql) /******************************************************** * to test simple prepare with all possible types * *********************************************************/ -void test_prepare_ext(MYSQL *mysql) +void test_prepare_ext() { MYSQL_STMT *stmt; int rc,param_count; - char *query; + char *sql; int nData=1; MYSQL_RES *result; char tData=1; short sData=10; longlong bData=20; - MYSQL_BIND bind_int[6]; + MYSQL_BIND bind_int[6]; + myheader("test_prepare_ext"); - myheader("test_prepare_ext"); - init_bind(bind_int); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_ext"); - myquery(mysql,rc); - - rc = mysql_commit(mysql); - myquery(mysql,rc); + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_ext"); + myquery(rc); - query = (char *)"CREATE TABLE test_prepare_ext\ + rc = mysql_commit(mysql); + myquery(rc); + + sql = (char *)"CREATE TABLE test_prepare_ext\ (\ c1 tinyint,\ c2 smallint,\ @@ -1973,13 +2004,13 @@ void test_prepare_ext(MYSQL *mysql) c31 enum('one','two','three'),\ c32 set('monday','tuesday','wednesday'))"; - rc = mysql_query(mysql,query); - myquery(mysql,rc); + rc = mysql_query(mysql,sql); + myquery(rc); /* insert by prepare - all integers */ - query = (char *)"INSERT INTO test_prepare_ext(c1,c2,c3,c4,c5,c6) VALUES(?,?,?,?,?,?)"; + strcpy(query,(char *)"INSERT INTO test_prepare_ext(c1,c2,c3,c4,c5,c6) VALUES(?,?,?,?,?,?)"); stmt = mysql_prepare(mysql,query, strlen(query)); - myquery(mysql,rc); + myquery(rc); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); @@ -2008,7 +2039,7 @@ void test_prepare_ext(MYSQL *mysql) /*bigint*/ bind_int[5].buffer_type=FIELD_TYPE_LONGLONG; bind_int[5].buffer= (void *)&bData; - + rc = mysql_bind_param(stmt,bind_int); mystmt(stmt, rc); @@ -2024,17 +2055,17 @@ void test_prepare_ext(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT c1,c2,c3,c4,c5,c6 FROM test_prepare_ext"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(nData == my_process_result_set(mysql,result)); + assert(nData == my_process_result_set(result)); mysql_free_result(result); } @@ -2044,93 +2075,93 @@ void test_prepare_ext(MYSQL *mysql) /******************************************************** * to test real and alias names * *********************************************************/ -void test_field_names(MYSQL *mysql) +void test_field_names() { int rc; MYSQL_RES *result; - - myheader("test_field_names"); + + myheader("test_field_names"); printf("\n%d,%d,%d",MYSQL_TYPE_DECIMAL,MYSQL_TYPE_NEWDATE,MYSQL_TYPE_ENUM); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_field_names1"); - myquery(mysql,rc); + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_field_names1"); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_field_names2"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_field_names2"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_field_names1(id int,name varchar(50))"); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_field_names2(id int,name varchar(50))"); - myquery(mysql,rc); - + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); - + myquery(rc); + /* with table name included with true column name */ rc = mysql_query(mysql,"SELECT id as 'id-alias' FROM test_field_names1"); - myquery(mysql,rc); - - result = mysql_use_result(mysql); - mytest(mysql,result); + myquery(rc); - assert(0 == my_process_result_set(mysql,result)); - mysql_free_result(result); + result = mysql_use_result(mysql); + mytest(result); + + assert(0 == my_process_result_set(result)); + mysql_free_result(result); /* with table name included with true column name */ rc = mysql_query(mysql,"SELECT t1.id as 'id-alias',test_field_names2.name FROM test_field_names1 t1,test_field_names2"); - myquery(mysql,rc); - - result = mysql_use_result(mysql); - mytest(mysql,result); + myquery(rc); - assert(0 == my_process_result_set(mysql,result)); + result = mysql_use_result(mysql); + mytest(result); + + assert(0 == my_process_result_set(result)); mysql_free_result(result); } /******************************************************** * to test warnings * *********************************************************/ -void test_warnings(MYSQL *mysql) +void test_warnings() { int rc; MYSQL_RES *result; - - myheader("test_warnings"); - rc = mysql_query(mysql,"USE test"); - myquery(mysql,rc); - - rc = mysql_query(mysql,"SHOW WARNINGS"); - myquery(mysql,rc); - + myheader("test_warnings"); + + rc = mysql_query(mysql,"USE test"); + myquery(rc); + + rc = mysql_query(mysql,"SHOW WARNINGS"); + myquery(rc); + result = mysql_use_result(mysql); - mytest(mysql,result); + mytest(result); - my_process_result_set(mysql,result); + my_process_result_set(result); mysql_free_result(result); } /******************************************************** * to test errors * *********************************************************/ -void test_errors(MYSQL *mysql) +void test_errors() { int rc; MYSQL_RES *result; - - myheader("test_errors"); - - rc = mysql_query(mysql,"SHOW ERRORS"); - myquery(mysql,rc); - - result = mysql_use_result(mysql); - mytest(mysql,result); - my_process_result_set(mysql,result); + myheader("test_errors"); + + rc = mysql_query(mysql,"SHOW ERRORS"); + myquery(rc); + + result = mysql_use_result(mysql); + mytest(result); + + my_process_result_set(result); mysql_free_result(result); } @@ -2139,36 +2170,36 @@ void test_errors(MYSQL *mysql) /******************************************************** * to test simple prepare-insert * *********************************************************/ -void test_insert(MYSQL *mysql) -{ +void test_insert() +{ MYSQL_STMT *stmt; - int rc,param_count; + int rc,param_count, length; char query[200]; char str_data[50]; char tiny_data; MYSQL_RES *result; - MYSQL_BIND bind[2]; + MYSQL_BIND bind[2]; - myheader("test_insert"); + myheader("test_insert"); rc = mysql_autocommit(mysql, true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prep_insert"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prep_insert"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_prep_insert(col1 tinyint,\ col2 varchar(50))"); - myquery(mysql,rc); + myquery(rc); /* insert by prepare */ bzero(bind, sizeof(bind)); strcpy(query,"INSERT INTO test_prep_insert VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); @@ -2180,14 +2211,15 @@ void test_insert(MYSQL *mysql) /* string */ bind[1].buffer_type=FIELD_TYPE_STRING; bind[1].buffer=str_data; - + bind[1].length=(long *)&length; + rc = mysql_bind_param(stmt,bind); mystmt(stmt, rc); /* now, execute the prepared statement to insert 10 records.. */ for (tiny_data=0; tiny_data < 3; tiny_data++) { - bind[1].buffer_length = sprintf(str_data,"MySQL%d",tiny_data); + length = sprintf(str_data,"MySQL%d",tiny_data); rc = mysql_execute(stmt); mystmt(stmt, rc); } @@ -2196,17 +2228,17 @@ void test_insert(MYSQL *mysql) /* now fetch the results ..*/ rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); /* test the results now, only one row should exists */ rc = mysql_query(mysql,"SELECT * FROM test_prep_insert"); - myquery(mysql,rc); - + myquery(rc); + /* get the result */ result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert((int)tiny_data == my_process_result_set(mysql,result)); + assert((int)tiny_data == my_process_result_set(result)); mysql_free_result(result); } @@ -2214,60 +2246,60 @@ void test_insert(MYSQL *mysql) /******************************************************** * to test simple prepare-resultset info * *********************************************************/ -void test_prepare_resultset(MYSQL *mysql) -{ +void test_prepare_resultset() +{ MYSQL_STMT *stmt; int rc,param_count; char query[200]; MYSQL_RES *result; - myheader("test_prepare_resultset"); + myheader("test_prepare_resultset"); rc = mysql_autocommit(mysql, true); - myquery(mysql,rc); + myquery(rc); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_resultset"); + myquery(rc); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_prepare_resultset"); - myquery(mysql,rc); - rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_prepare_resultset(id int,\ name varchar(50),extra double)"); - myquery(mysql,rc); + myquery(rc); /* insert by prepare */ strcpy(query,"INSERT INTO test_prepare_resultset(id,name) VALUES(?,?)"); stmt = mysql_prepare(mysql, query, strlen(query)); - myxquery(mysql,stmt); + myxquery(stmt); param_count = mysql_param_count(stmt); fprintf(stdout," total parameters in insert:%d\n", param_count); assert(param_count == 2); rc = mysql_query(mysql,"SELECT * FROM test_prepare_resultset"); - myquery(mysql,rc); + myquery(rc); /* get the prepared-result */ result = mysql_prepare_result(stmt); assert( result != 0); - my_print_result_metadata(result); + my_print_result_metadata(result); mysql_free_result(result); result = mysql_store_result(mysql); - mytest(mysql,result); + mytest(result); - assert(0 == my_process_result_set(mysql,result)); + assert(0 == my_process_result_set(result)); mysql_free_result(result); /* get the prepared-result */ result = mysql_prepare_result(stmt); assert( result != 0); - my_print_result_metadata(result); + my_print_result_metadata(result); mysql_free_result(result); - + mysql_stmt_close(stmt); } @@ -2275,21 +2307,21 @@ void test_prepare_resultset(MYSQL *mysql) * to test field flags (verify .NET provider) * *********************************************************/ -void test_field_flags(MYSQL *mysql) +void test_field_flags() { int rc; MYSQL_RES *result; MYSQL_FIELD *field; unsigned int i; - - myheader("test_field_flags"); - rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_field_flags"); - myquery(mysql,rc); - + myheader("test_field_flags"); + + rc = mysql_query(mysql,"DROP TABLE IF EXISTS test_field_flags"); + myquery(rc); + rc = mysql_commit(mysql); - myquery(mysql,rc); + myquery(rc); rc = mysql_query(mysql,"CREATE TABLE test_field_flags(id int NOT NULL AUTO_INCREMENT PRIMARY KEY,\ id1 int NOT NULL,\ @@ -2298,17 +2330,17 @@ void test_field_flags(MYSQL *mysql) id4 int NOT NULL,\ id5 int,\ KEY(id3,id4))"); - myquery(mysql,rc); + myquery(rc); rc = mysql_commit(mysql); - myquery(mysql,rc); - + myquery(rc); + /* with table name included with true column name */ rc = mysql_query(mysql,"SELECT * FROM test_field_flags"); - myquery(mysql,rc); - + myquery(rc); + result = mysql_use_result(mysql); - mytest(mysql,result); + mytest(result); mysql_field_seek(result,0); fputc('\n', stdout); @@ -2338,17 +2370,19 @@ static struct my_option myctest_long_options[] = 0, 0, 0, 0, 0}, {"database", 'D', "Database to use", (gptr*) &opt_db, (gptr*) &opt_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"host", 'h', "Connect to host", (gptr*) &opt_host, (gptr*) &opt_host, 0, GET_STR, + {"host", 'h', "Connect to host", (gptr*) &opt_host, (gptr*) &opt_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given it's asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DONT_ALLOW_USER_CHANGE {"user", 'u', "User for login if not current user", (gptr*) &opt_user, - (gptr*) &opt_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"port", 'P', "Port number to use for connection", (gptr*) &opt_port, (gptr*) &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection", (gptr*) &opt_unix_socket, - (gptr*) &opt_unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &opt_unix_socket, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -2392,9 +2426,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'p': if (argument) { + char *start=argument; my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); opt_password= my_strdup(argument, MYF(MY_FAE)); while (*argument) *argument++= 'x'; /* Destroy argument */ + if (*start) + start[1]=0; } else tty_password= 1; @@ -2402,7 +2439,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case '?': case 'I': /* Info */ usage(); - exit(1); + exit(0); break; } return 0; @@ -2416,11 +2453,11 @@ static void get_options(int argc, char **argv) load_defaults("my",load_default_groups,&argc,&argv); - if ((ho_error=handle_options(&argc, &argv, myctest_long_options, + if ((ho_error=handle_options(&argc,&argv, myctest_long_options, get_one_option))) exit(ho_error); - free_defaults(argv); + /*free_defaults(argv);*/ if (tty_password) opt_password=get_tty_password(NullS); return; @@ -2430,47 +2467,50 @@ static void get_options(int argc, char **argv) * main routine * *********************************************************/ int main(int argc, char **argv) -{ - MYSQL *mysql; - - +{ MY_INIT(argv[0]); - get_options(argc,argv); /* don't work -- options : TODO */ + get_options(argc,argv); - mysql = client_connect(); /* connect to server */ + client_connect(); /* connect to server */ + + test_null(); /* test null data handling */ + test_simple_update(); + //test_select_simple(); + //test_prepare_resultset(); + //test_select(); /* simple prepare-select */ + test_insert(); /* prepare with insert */ + //test_bind_result(); /* result bind test */ + //test_long_data(); /* long data handling in pieces */ + test_prepare_simple();/* simple prepare */ + test_prepare(); /* prepare test */ + test_prepare_simple();/* simple prepare */ + test_null(); /* test null data handling */ + test_debug_example(); /* some debugging case */ + test_update(); /* prepare-update test */ + test_simple_update(); /* simple prepare with update */ + //test_long_data(); /* long data handling in pieces */ + test_simple_delete(); /* prepare with delete */ + test_field_names(); /* test for field names */ + test_double_compare();/* float comparision */ + client_query(); /* simple client query test */ + client_store_result();/* usage of mysql_store_result() */ + client_use_result(); /* usage of mysql_use_result() */ + test_tran_bdb(); /* transaction test on BDB table type */ + test_tran_innodb(); /* transaction test on InnoDB table type */ + test_prepare_ext(); /* test prepare with all types conversion -- TODO */ + test_prepare_syntax();/* syntax check for prepares */ + //test_prepare_field_result(); /* prepare meta info */ + test_field_names(); /* test for field names */ + test_field_flags(); /* test to help .NET provider team */ + //test_long_data_str(); /* long data handling */ + //test_long_data_str1();/* yet another long data handling */ + //test_long_data_bin(); /* long binary insertion */ + test_warnings(); /* show warnings test */ + test_errors(); /* show errors test */ + //test_select_simple(); /* simple select prepare */ + //test_prepare_resultset();/* prepare meta info test */ - test_select(mysql); /* simple prepare-select */ - test_insert(mysql); /* prepare with insert */ - test_bind_result(mysql); /* result bind test */ - test_prepare(mysql); /* prepare test */ - test_prepare_simple(mysql);/* simple prepare */ - test_null(mysql); /* test null data handling */ - test_debug_example(mysql); /* some debugging case */ - test_update(mysql); /* prepare-update test */ - test_simple_update(mysql); /* simple prepare with update */ - test_long_data(mysql); /* long data handling in pieces */ - test_simple_delete(mysql); /* prepare with delete */ - test_field_names(mysql); /* test for field names */ - test_double_compare(mysql);/* float comparision */ - client_query(mysql); /* simple client query test */ - client_store_result(mysql);/* usage of mysql_store_result() */ - client_use_result(mysql); /* usage of mysql_use_result() */ - test_tran_bdb(mysql); /* transaction test on BDB table type */ - test_tran_innodb(mysql); /* transaction test on InnoDB table type */ - test_prepare_ext(mysql); /* test prepare with all types conversion -- TODO */ - test_prepare_syntax(mysql);/* syntax check for prepares */ - test_prepare_field_result(mysql); /* prepare meta info */ - test_field_names(mysql); /* test for field names */ - test_field_flags(mysql); /* test to help .NET provider team */ - test_long_data_str(mysql); /* long data handling */ - test_long_data_str1(mysql);/* yet another long data handling */ - test_long_data_bin(mysql); /* long binary insertion */ - test_warnings(mysql); /* show warnings test */ - test_errors(mysql); /* show errors test */ - test_select_simple(mysql); /* simple select prepare */ - test_prepare_resultset(mysql);/* prepare meta info test */ - - client_disconnect(mysql); /* disconnect from server */ + client_disconnect(); /* disconnect from server */ fprintf(stdout,"\ndone !!!\n"); return(0); From f6f937085fad389e37d8fada2f07939f8c87d315 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sat, 23 Nov 2002 21:55:39 +0200 Subject: [PATCH 08/10] fixed bug with thd->allow_sum_func value in subselect --- mysql-test/r/subselect.result | 3 +++ mysql-test/t/subselect.test | 1 + sql/sql_base.cc | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 91118c1e664..b6699729532 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -12,6 +12,9 @@ SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; Reference 'a' not supported (forward reference in item list) SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; Reference 'b' not supported (forward reference in item list) +SELECT (SELECT 1),MAX(1) FROM (SELECT 1); +(SELECT 1) MAX(1) +1 1 drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index b9edd0e3396..02d85dd60a1 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -5,6 +5,7 @@ SELECT (SELECT (SELECT 0 UNION SELECT 0)); SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; -- error 1245 SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; +SELECT (SELECT 1),MAX(1) FROM (SELECT 1); drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 59310fb00de..7b434eb0bfb 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2225,8 +2225,10 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) { DBUG_ENTER("setup_conds"); thd->set_query_id=1; - thd->cond_count=0; - thd->allow_sum_func=0; + + thd->cond_count= 0; + bool save_allow_sum_func= thd->allow_sum_func; + thd->allow_sum_func= 0; if (*conds) { thd->where="where clause"; @@ -2299,6 +2301,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) table->on_expr=and_conds(table->on_expr,cond_and); } } + thd->allow_sum_func= save_allow_sum_func; DBUG_RETURN(test(thd->fatal_error)); } From 1d90d98b794eb94b6be538c1e0cb277d95dd9a73 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sat, 23 Nov 2002 22:11:53 +0200 Subject: [PATCH 09/10] error messages fix --- sql/share/czech/errmsg.txt | 2 +- sql/share/danish/errmsg.txt | 2 +- sql/share/dutch/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 2 +- sql/share/estonian/errmsg.txt | 2 +- sql/share/french/errmsg.txt | 2 +- sql/share/german/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/errmsg.txt | 2 +- sql/share/italian/errmsg.txt | 2 +- sql/share/japanese/errmsg.txt | 2 +- sql/share/korean/errmsg.txt | 2 +- sql/share/norwegian-ny/errmsg.txt | 2 +- sql/share/norwegian/errmsg.txt | 2 +- sql/share/polish/errmsg.txt | 2 +- sql/share/portuguese/errmsg.txt | 2 +- sql/share/russian/errmsg.txt | 2 +- sql/share/serbian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- sql/share/spanish/errmsg.txt | 2 +- sql/share/swedish/errmsg.txt | 2 +- sql/share/ukrainian/errmsg.txt | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 9478bcdef0d..4838de12ed6 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -254,5 +254,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index b699ec7f87c..91fa06f184f 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -248,5 +248,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 9e962fdb9de..50c70ce0d2c 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -256,5 +256,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 04a3b09ce52..1c5564b9ad5 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -245,5 +245,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 5a980b441a4..8a49cc7fb69 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -250,5 +250,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index dfb4e1774d0..a8b602ee295 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -245,5 +245,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index c1ae3bb501f..cb449738d61 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -248,5 +248,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index f533d0d4d67..f6c650468b1 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -245,5 +245,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 58cce8c974e..fe47d79a101 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -247,5 +247,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 6836f318fd8..0d951857392 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -245,5 +245,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index a7ae09b9f00..df78901a6e9 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -247,5 +247,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 6e3dc5920c8..c20110e1aa5 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -245,5 +245,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index f897235e26d..c75c3ed6140 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -247,5 +247,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 3f9c6e92e12..b5a660773ab 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -247,5 +247,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 705e4c20616..c65a16bf1e4 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -249,5 +249,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 1ee15fb577e..355ae90c157 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -245,5 +245,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 19ded0473bd..35134e6d9d5 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -248,5 +248,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Циклическая ссылка на подзапрос", -"Converting column '%s' from %s to %s" +"Преобразование поля '%s' из %s в %s", "Ссылка '%-.64s' не поддерживается (%s)", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 0951cd14db6..354c0bdfac4 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -241,5 +241,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index d7cf0b62c5e..4f49aeb2f6e 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -253,5 +253,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 0a7367c7200..1bd4aed6897 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -246,5 +246,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Cyclic reference on subqueries", -"Converting column '%s' from %s to %s" +"Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index afd5c559403..af3f7ca33dd 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -245,5 +245,5 @@ "OkДnd PREPARED STATEMENT id (%ld) var given till %s", "HjДlp databasen finns inte eller Дr skadad", "Syklisk referens i subselect", -"Konvertar kolumn '%s' frЕn %s till %s" +"Konvertar kolumn '%s' frЕn %s till %s", "Reference '%-.64s' not supported (%s)", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index b5a6eec5c45..c5bfff130fd 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -250,5 +250,5 @@ "Unknown prepared statement handler (%ld) given to %s", "Help database is corrupt or does not exist", "Циклiчне посилання на пiдзапит", -"Converting column '%s' from %s to %s" +"Перетворення стовбца '%s' з %s у %s", "Посилання '%-.64s' не пiдтримуется (%s)", From 39c7302140243760a6544bcecd631260dd5729b5 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 24 Nov 2002 11:18:32 +0200 Subject: [PATCH 10/10] fix of selfreference bug --- mysql-test/r/subselect.result | 2 ++ mysql-test/t/subselect.test | 2 ++ sql/item.h | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index b6699729532..154f8ac9667 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -15,6 +15,8 @@ Reference 'b' not supported (forward reference in item list) SELECT (SELECT 1),MAX(1) FROM (SELECT 1); (SELECT 1) MAX(1) 1 1 +SELECT (SELECT a) as a; +Reference 'a' not supported (forward reference in item list) drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 02d85dd60a1..f838a27e7ff 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -6,6 +6,8 @@ SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; -- error 1245 SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; SELECT (SELECT 1),MAX(1) FROM (SELECT 1); +-- error 1245 +SELECT (SELECT a) as a; drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; create table t1 (a int); create table t2 (a int, b int); diff --git a/sql/item.h b/sql/item.h index e6b2d74c323..39e90cef561 100644 --- a/sql/item.h +++ b/sql/item.h @@ -403,8 +403,8 @@ public: :Item_ident(NullS,table_name_par,field_name_par),ref(item) {} enum Type type() const { return REF_ITEM; } bool eq(const Item *item, bool binary_cmp) const - { return (*ref)->eq(item, binary_cmp); } - ~Item_ref() { if (ref) delete *ref; } + { return ref && (*ref)->eq(item, binary_cmp); } + ~Item_ref() { if (ref && (*ref) != this) delete *ref; } double val() { double tmp=(*ref)->val_result();