diff options
author | unknown <bell@sanja.is.com.ua> | 2005-01-24 14:25:44 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2005-01-24 14:25:44 +0200 |
commit | d514a06a86d689065590b0115799f06fa109a70b (patch) | |
tree | c7cc550280db3a3aa5ebbaf150e21859bd79257b /sql | |
parent | 1850f74925d1b84f41a8caf40562ddb72ebfd5af (diff) | |
download | mariadb-git-d514a06a86d689065590b0115799f06fa109a70b.tar.gz |
fixed column number fetchinmg for subqueries. (BUG#8020)
fixed cols() method call (it have to be called only after fix_fields())
mysql-test/r/subselect.result:
Comparison subquery with * and row
mysql-test/t/subselect.test:
Comparison subquery with * and row
sql/item_cmpfunc.h:
initialization allowed_arg_cols for autodetection
sql/item_func.cc:
support of allowed_arg_cols autodetection by first argument
sql/item_func.h:
commant
sql/item_subselect.cc:
correct column number fetching for subqueries
sql/sql_lex.h:
method to check that UNION is prepared
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.h | 9 | ||||
-rw-r--r-- | sql/item_func.cc | 18 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/item_subselect.cc | 6 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 |
5 files changed, 31 insertions, 7 deletions
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 6834799688d..061ed468b78 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -213,7 +213,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2 public: Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b) { - allowed_arg_cols= a->cols(); + allowed_arg_cols= 0; // Fetch this value from first argument } Item *neg_transformer(THD *thd); virtual Item *negated_item(); @@ -390,7 +390,10 @@ class Item_func_interval :public Item_int_func double *intervals; public: Item_func_interval(Item_row *a) - :Item_int_func(a),row(a),intervals(0) { allowed_arg_cols= a->cols(); } + :Item_int_func(a),row(a),intervals(0) + { + allowed_arg_cols= 0; // Fetch this value from first argument + } longlong val_int(); void fix_length_and_dec(); const char *func_name() const { return "interval"; } @@ -743,7 +746,7 @@ class Item_func_in :public Item_int_func Item_func_in(List<Item> &list) :Item_int_func(list), array(0), in_item(0), have_null(0) { - allowed_arg_cols= args[0]->cols(); + allowed_arg_cols= 0; // Fetch this value from first argument } longlong val_int(); void fix_length_and_dec(); diff --git a/sql/item_func.cc b/sql/item_func.cc index 7125f4704b8..bff49541252 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -303,10 +303,24 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) We can't yet set item to *arg as fix_fields may change *arg We shouldn't call fix_fields() twice, so check 'fixed' field first */ - if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) || - (*arg)->check_cols(allowed_arg_cols)) + if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg))) return 1; /* purecov: inspected */ + item= *arg; + + if (allowed_arg_cols) + { + if (item->check_cols(allowed_arg_cols)) + return 1; + } + else + { + /* we have to fetch allowed_arg_cols from first argument */ + DBUG_ASSERT(arg == args); // it is first argument + allowed_arg_cols= item->cols(); + DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more + } + if (item->maybe_null) maybe_null=1; diff --git a/sql/item_func.h b/sql/item_func.h index ce2b34499d6..8a5347d675e 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -32,6 +32,10 @@ class Item_func :public Item_result_field { protected: Item **args, *tmp_arg[2]; + /* + Allowed numbers of columns in result (usually 1, which means scalar value) + 0 means get this number from first argument + */ uint allowed_arg_cols; public: uint arg_count; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8516ea76a7e..2597427253c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1421,13 +1421,15 @@ int subselect_indexsubquery_engine::exec() uint subselect_single_select_engine::cols() { - return select_lex->item_list.elements; + DBUG_ASSERT(select_lex->join); // should be called after fix_fields() + return select_lex->join->fields_list.elements; } uint subselect_union_engine::cols() { - return unit->first_select()->item_list.elements; + DBUG_ASSERT(unit->is_prepared()); // should be called after fix_fields() + return unit->types.elements; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e2e0bc61c23..7cb71607edf 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -371,6 +371,7 @@ public: ulong init_prepare_fake_select_lex(THD *thd); int change_result(select_subselect *result, select_subselect *old_result); + inline bool is_prepared() { return prepared; } friend void lex_start(THD *thd, uchar *buf, uint length); friend int subselect_union_engine::exec(); |