summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2005-01-24 14:25:44 +0200
committerunknown <bell@sanja.is.com.ua>2005-01-24 14:25:44 +0200
commitd514a06a86d689065590b0115799f06fa109a70b (patch)
treec7cc550280db3a3aa5ebbaf150e21859bd79257b /sql
parent1850f74925d1b84f41a8caf40562ddb72ebfd5af (diff)
downloadmariadb-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.h9
-rw-r--r--sql/item_func.cc18
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/item_subselect.cc6
-rw-r--r--sql/sql_lex.h1
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();