Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
b63f2303
Commit
b63f2303
authored
Dec 19, 2002
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
row IN subselects (SCRUM)
parent
54c7afd2
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
353 additions
and
48 deletions
+353
-48
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+31
-0
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+14
-0
sql/item.cc
sql/item.cc
+109
-0
sql/item.h
sql/item.h
+69
-1
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+20
-7
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+5
-4
sql/item_row.cc
sql/item_row.cc
+8
-1
sql/item_row.h
sql/item_row.h
+1
-0
sql/item_subselect.cc
sql/item_subselect.cc
+78
-19
sql/item_subselect.h
sql/item_subselect.h
+7
-5
sql/sql_class.cc
sql/sql_class.cc
+3
-3
sql/sql_class.h
sql/sql_class.h
+2
-2
sql/sql_yacc.yy
sql/sql_yacc.yy
+6
-6
No files found.
mysql-test/r/subselect.result
View file @
b63f2303
...
...
@@ -773,3 +773,34 @@ a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where
2 0 b
NULL NULL NULL
drop table t1,t2;
drop table if exists t;
create table t (a int, b real, c varchar(10));
insert into t values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
select ROW(1, 1, 'a') IN (select a,b,c from t);
ROW(1, 1, 'a') IN (select a,b,c from t)
1
select ROW(1, 2, 'a') IN (select a,b,c from t);
ROW(1, 2, 'a') IN (select a,b,c from t)
NULL
select ROW(1, 1, 'a') IN (select b,a,c from t);
ROW(1, 1, 'a') IN (select b,a,c from t)
1
select ROW(1, 1, 'a') IN (select a,b,c from t where a is not null);
ROW(1, 1, 'a') IN (select a,b,c from t where a is not null)
1
select ROW(1, 2, 'a') IN (select a,b,c from t where a is not null);
ROW(1, 2, 'a') IN (select a,b,c from t where a is not null)
0
select ROW(1, 1, 'a') IN (select b,a,c from t where a is not null);
ROW(1, 1, 'a') IN (select b,a,c from t where a is not null)
1
select ROW(1, 1, 'a') IN (select a,b,c from t where c='b' or c='a');
ROW(1, 1, 'a') IN (select a,b,c from t where c='b' or c='a')
1
select ROW(1, 2, 'a') IN (select a,b,c from t where c='b' or c='a');
ROW(1, 2, 'a') IN (select a,b,c from t where c='b' or c='a')
NULL
select ROW(1, 1, 'a') IN (select b,a,c from t where c='b' or c='a');
ROW(1, 1, 'a') IN (select b,a,c from t where c='b' or c='a')
1
drop table if exists t;
mysql-test/t/subselect.test
View file @
b63f2303
...
...
@@ -434,3 +434,17 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t
select
a
,
(
select
a
,
b
,
c
from
t1
where
t1
.
a
=
t2
.
a
)
=
ROW
(
a
,
3
,
'b'
),(
select
c
from
t1
where
a
=
t2
.
a
)
from
t2
;
select
a
,
(
select
a
,
b
,
c
from
t1
where
t1
.
a
=
t2
.
a
)
=
ROW
(
a
,
4
,
'c'
),(
select
c
from
t1
where
a
=
t2
.
a
)
from
t2
;
drop
table
t1
,
t2
;
drop
table
if
exists
t
;
create
table
t
(
a
int
,
b
real
,
c
varchar
(
10
));
insert
into
t
values
(
1
,
1
,
'a'
),
(
2
,
2
,
'b'
),
(
NULL
,
2
,
'b'
);
select
ROW
(
1
,
1
,
'a'
)
IN
(
select
a
,
b
,
c
from
t
);
select
ROW
(
1
,
2
,
'a'
)
IN
(
select
a
,
b
,
c
from
t
);
select
ROW
(
1
,
1
,
'a'
)
IN
(
select
b
,
a
,
c
from
t
);
select
ROW
(
1
,
1
,
'a'
)
IN
(
select
a
,
b
,
c
from
t
where
a
is
not
null
);
select
ROW
(
1
,
2
,
'a'
)
IN
(
select
a
,
b
,
c
from
t
where
a
is
not
null
);
select
ROW
(
1
,
1
,
'a'
)
IN
(
select
b
,
a
,
c
from
t
where
a
is
not
null
);
select
ROW
(
1
,
1
,
'a'
)
IN
(
select
a
,
b
,
c
from
t
where
c
=
'b'
or
c
=
'a'
);
select
ROW
(
1
,
2
,
'a'
)
IN
(
select
a
,
b
,
c
from
t
where
c
=
'b'
or
c
=
'a'
);
select
ROW
(
1
,
1
,
'a'
)
IN
(
select
b
,
a
,
c
from
t
where
c
=
'b'
or
c
=
'a'
);
drop
table
if
exists
t
;
sql/item.cc
View file @
b63f2303
...
...
@@ -498,6 +498,27 @@ bool Item_asterisk_remover::fix_fields(THD *thd,
DBUG_RETURN
(
res
);
}
bool
Item_ref_on_list_position
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
reference
)
{
ref
=
0
;
List_iterator
<
Item
>
li
(
list
);
Item
*
item
;
uint
i
=
0
;
for
(;
(
item
=
li
++
)
&&
i
<
pos
;
i
++
);
if
(
i
==
pos
)
{
ref
=
li
.
ref
();
return
Item_ref_null_helper
::
fix_fields
(
thd
,
tables
,
reference
);
}
else
{
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
pos
);
return
1
;
}
}
double
Item_ref_null_helper
::
val
()
{
double
tmp
=
(
*
ref
)
->
val_result
();
...
...
@@ -1196,6 +1217,8 @@ Item_cache* Item_cache::get_cache(Item_result type)
return
new
Item_cache_real
();
case
STRING_RESULT
:
return
new
Item_cache_str
();
case
ROW_RESULT
:
return
new
Item_cache_row
();
default:
// should never be in real life
DBUG_ASSERT
(
0
);
...
...
@@ -1241,6 +1264,92 @@ longlong Item_cache_str::val_int()
return
(
longlong
)
0
;
}
bool
Item_cache_row
::
allocate
(
uint
num
)
{
n
=
num
;
THD
*
thd
=
current_thd
;
if
(
!
(
values
=
(
Item_cache
**
)
thd
->
calloc
(
sizeof
(
Item_cache
*
)
*
n
)))
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
thd
->
fatal_error
=
1
;
return
1
;
}
return
0
;
}
bool
Item_cache_row
::
setup
(
Item
*
item
)
{
if
(
!
values
&&
allocate
(
item
->
cols
()))
return
1
;
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
if
(
!
(
values
[
i
]
=
Item_cache
::
get_cache
(
item
->
el
(
i
)
->
result_type
())))
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
current_thd
->
fatal_error
=
1
;
return
1
;
}
values
[
i
]
->
setup
(
item
->
el
(
i
));
}
return
0
;
}
void
Item_cache_row
::
store
(
Item
*
item
)
{
null_value
=
0
;
item
->
bring_value
();
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
values
[
i
]
->
store
(
item
->
el
(
i
));
null_value
|=
values
[
i
]
->
null_value
;
}
}
void
Item_cache_row
::
illegal_method_call
(
const
char
*
method
)
{
DBUG_ENTER
(
"Item_cache_row::illegal_method_call"
);
DBUG_PRINT
(
"error"
,
(
"!!! %s method was called for row item"
,
method
));
DBUG_ASSERT
(
0
);
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
1
);
DBUG_VOID_RETURN
;
}
bool
Item_cache_row
::
check_cols
(
uint
c
)
{
if
(
c
!=
n
)
{
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
c
);
return
1
;
}
return
0
;
}
bool
Item_cache_row
::
null_inside
()
{
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
if
(
values
[
i
]
->
cols
()
>
1
)
{
if
(
values
[
i
]
->
null_inside
())
return
1
;
}
else
{
values
[
i
]
->
val_int
();
if
(
values
[
i
]
->
null_value
)
return
1
;
}
}
return
0
;
}
void
Item_cache_row
::
bring_value
()
{
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
values
[
i
]
->
bring_value
();
return
;
}
/*****************************************************************************
** Instantiate templates
*****************************************************************************/
...
...
sql/item.h
View file @
b63f2303
...
...
@@ -501,7 +501,7 @@ protected:
Item_in_subselect
*
owner
;
public:
Item_ref_null_helper
(
Item_in_subselect
*
master
,
Item
**
item
,
char
*
table_name_par
,
char
*
field_name_par
)
:
char
*
table_name_par
,
char
*
field_name_par
)
:
Item_ref
(
item
,
table_name_par
,
field_name_par
),
owner
(
master
)
{}
double
val
();
longlong
val_int
();
...
...
@@ -509,6 +509,24 @@ public:
bool
get_date
(
TIME
*
ltime
,
bool
fuzzydate
);
};
/*
Used to find item in list of select items after '*' items processing.
*/
class
Item_ref_on_list_position
:
public
Item_ref_null_helper
{
protected:
List
<
Item
>
&
list
;
uint
pos
;
public:
Item_ref_on_list_position
(
Item_in_subselect
*
master
,
List
<
Item
>
&
li
,
uint
num
,
char
*
table_name
,
char
*
field_name
)
:
Item_ref_null_helper
(
master
,
0
,
table_name
,
field_name
),
list
(
li
),
pos
(
num
)
{}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
};
/*
To resolve '*' field moved to condition
and register NULL values
...
...
@@ -642,6 +660,8 @@ public:
class
Item_cache
:
public
Item
{
public:
virtual
bool
allocate
(
uint
i
)
{
return
0
;
};
virtual
bool
setup
(
Item
*
)
{
return
0
;
};
virtual
void
store
(
Item
*
)
=
0
;
void
set_len_n_dec
(
uint32
max_len
,
uint8
dec
)
{
...
...
@@ -705,6 +725,54 @@ public:
CHARSET_INFO
*
charset
()
const
{
return
value
->
charset
();
};
};
class
Item_cache_row
:
public
Item_cache
{
Item_cache
**
values
;
uint
n
;
public:
Item_cache_row
()
:
values
(
0
),
n
(
2
)
{
fixed
=
1
;
null_value
=
1
;
}
/*
'allocate' used only in row transformer, to preallocate space for row
cache.
*/
bool
allocate
(
uint
num
);
/*
'setup' is needed only by row => it not called by simple row subselect
(only by IN subselect (in subselect optimizer))
*/
bool
setup
(
Item
*
item
);
void
store
(
Item
*
item
);
void
illegal_method_call
(
const
char
*
);
void
make_field
(
Send_field
*
)
{
illegal_method_call
((
const
char
*
)
"make_field"
);
};
double
val
()
{
illegal_method_call
((
const
char
*
)
"val"
);
return
0
;
};
longlong
val_int
()
{
illegal_method_call
((
const
char
*
)
"val_int"
);
return
0
;
};
String
*
val_str
(
String
*
)
{
illegal_method_call
((
const
char
*
)
"val_str"
);
return
0
;
};
enum
Item_result
result_type
()
const
{
return
ROW_RESULT
;
}
uint
cols
()
{
return
n
;
}
Item
*
el
(
uint
i
)
{
return
values
[
i
];
}
Item
**
addr
(
uint
i
)
{
return
(
Item
**
)
(
values
+
i
);
}
bool
check_cols
(
uint
c
);
bool
null_inside
();
void
bring_value
();
};
extern
Item_buff
*
new_Item_buff
(
Item
*
item
);
extern
Item_result
item_cmp_type
(
Item_result
a
,
Item_result
b
);
extern
Item
*
resolve_const_item
(
Item
*
item
,
Item
*
cmp_item
);
...
...
sql/item_cmpfunc.cc
View file @
b63f2303
...
...
@@ -274,12 +274,19 @@ int Arg_comparator::compare_e_row()
return
1
;
}
bool
Item_in_optimizer
::
preallocate_row
()
{
if
((
cache
=
Item_cache
::
get_cache
(
ROW_RESULT
)))
return
0
;
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
current_thd
->
fatal_error
=
1
;
return
1
;
}
bool
Item_in_optimizer
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
if
(
args
[
0
]
->
check_cols
(
allowed_arg_cols
)
||
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
))
if
(
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
))
return
1
;
if
(
args
[
0
]
->
maybe_null
)
maybe_null
=
1
;
...
...
@@ -288,15 +295,21 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
with_sum_func
=
args
[
0
]
->
with_sum_func
;
used_tables_cache
=
args
[
0
]
->
used_tables
();
const_item_cache
=
args
[
0
]
->
const_item
();
if
(
!
(
cache
=
Item_cache
::
get_cache
(
args
[
0
]
->
result_type
())))
if
(
!
cache
&&
!
(
cache
=
Item_cache
::
get_cache
(
args
[
0
]
->
result_type
())))
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
thd
->
fatal_error
=
1
;
return
1
;
}
if
(
args
[
1
]
->
check_cols
(
allowed_arg_cols
)
||
args
[
1
]
->
fix_fields
(
thd
,
tables
,
args
))
cache
->
setup
(
args
[
0
]);
if
(
args
[
1
]
->
fix_fields
(
thd
,
tables
,
args
))
return
1
;
Item_in_subselect
*
sub
=
(
Item_in_subselect
*
)
args
[
1
];
if
(
args
[
0
]
->
cols
()
!=
sub
->
engine
->
cols
())
{
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
args
[
0
]
->
cols
());
return
1
;
}
if
(
args
[
1
]
->
maybe_null
)
maybe_null
=
1
;
with_sum_func
=
with_sum_func
||
args
[
1
]
->
with_sum_func
;
...
...
@@ -1215,7 +1228,7 @@ void cmp_item_row::store_value(Item *item)
{
THD
*
thd
=
current_thd
;
n
=
item
->
cols
();
if
((
comparators
=
(
cmp_item
**
)
thd
->
alloc
(
sizeof
(
cmp_item
*
)
*
n
)))
if
((
comparators
=
(
cmp_item
**
)
thd
->
c
alloc
(
sizeof
(
cmp_item
*
)
*
n
)))
{
item
->
bring_value
();
item
->
null_value
=
0
;
...
...
sql/item_cmpfunc.h
View file @
b63f2303
...
...
@@ -91,14 +91,15 @@ class Item_in_optimizer: public Item_bool_func
protected:
Item_cache
*
cache
;
public:
Item_in_optimizer
(
Item
*
a
,
Item
*
b
)
:
Item_bool_func
(
a
,
b
),
cache
(
0
)
{}
Item_in_optimizer
(
Item
*
a
,
Item_in_subselect
*
b
)
:
Item_bool_func
(
a
,
(
Item
*
)
b
),
cache
(
0
)
{}
// used by row in transformer
bool
preallocate_row
();
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
);
bool
is_null
();
longlong
val_int
();
Item
**
get_cache
()
{
return
(
Item
**
)
&
cache
;
}
Item_cache
**
get_cache
()
{
return
&
cache
;
}
};
class
Item_bool_func2
:
public
Item_int_func
...
...
sql/item_row.cc
View file @
b63f2303
...
...
@@ -41,7 +41,7 @@ void Item_row::illegal_method_call(const char *method)
DBUG_ENTER
(
"Item_row::illegal_method_call"
);
DBUG_PRINT
(
"error"
,
(
"!!! %s method was called for row item"
,
method
));
DBUG_ASSERT
(
0
);
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
arg_count
);
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
1
);
DBUG_VOID_RETURN
;
}
...
...
@@ -100,3 +100,10 @@ bool Item_row::null_inside()
}
return
0
;
}
void
Item_row
::
bring_value
()
{
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
items
[
i
]
->
bring_value
();
return
;
}
sql/item_row.h
View file @
b63f2303
...
...
@@ -70,4 +70,5 @@ public:
Item
**
addr
(
uint
i
)
{
return
items
+
i
;
}
bool
check_cols
(
uint
c
);
bool
null_inside
();
void
bring_value
();
};
sql/item_subselect.cc
View file @
b63f2303
...
...
@@ -127,36 +127,36 @@ inline table_map Item_subselect::used_tables() const
return
(
table_map
)
engine
->
depended
()
?
1L
:
0L
;
}
Item_single
val_subselect
::
Item_singleval
_subselect
(
THD
*
thd
,
Item_single
row_subselect
::
Item_singlerow
_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
)
:
Item_subselect
(),
value
(
0
)
{
DBUG_ENTER
(
"Item_single
val_subselect::Item_singleval
_subselect"
);
init
(
thd
,
select_lex
,
new
select_single
val
_subselect
(
this
));
DBUG_ENTER
(
"Item_single
row_subselect::Item_singlerow
_subselect"
);
init
(
thd
,
select_lex
,
new
select_single
row
_subselect
(
this
));
max_columns
=
1
;
maybe_null
=
1
;
max_columns
=
UINT_MAX
;
DBUG_VOID_RETURN
;
}
void
Item_single
val
_subselect
::
reset
()
void
Item_single
row
_subselect
::
reset
()
{
null_value
=
1
;
if
(
value
)
value
->
null_value
=
1
;
}
void
Item_single
val
_subselect
::
store
(
uint
i
,
Item
*
item
)
void
Item_single
row
_subselect
::
store
(
uint
i
,
Item
*
item
)
{
row
[
i
]
->
store
(
item
);
}
enum
Item_result
Item_single
val
_subselect
::
result_type
()
const
enum
Item_result
Item_single
row
_subselect
::
result_type
()
const
{
return
engine
->
type
();
}
void
Item_single
val
_subselect
::
fix_length_and_dec
()
void
Item_single
row
_subselect
::
fix_length_and_dec
()
{
if
((
max_columns
=
engine
->
cols
())
==
1
)
{
...
...
@@ -182,12 +182,12 @@ void Item_singleval_subselect::fix_length_and_dec()
}
}
uint
Item_single
val
_subselect
::
cols
()
uint
Item_single
row
_subselect
::
cols
()
{
return
engine
->
cols
();
}
bool
Item_single
val
_subselect
::
check_cols
(
uint
c
)
bool
Item_single
row
_subselect
::
check_cols
(
uint
c
)
{
if
(
c
!=
engine
->
cols
())
{
...
...
@@ -197,7 +197,7 @@ bool Item_singleval_subselect::check_cols(uint c)
return
0
;
}
bool
Item_single
val
_subselect
::
null_inside
()
bool
Item_single
row
_subselect
::
null_inside
()
{
for
(
uint
i
=
0
;
i
<
max_columns
;
i
++
)
{
...
...
@@ -207,12 +207,12 @@ bool Item_singleval_subselect::null_inside()
return
0
;
}
void
Item_single
val
_subselect
::
bring_value
()
void
Item_single
row
_subselect
::
bring_value
()
{
engine
->
exec
();
}
double
Item_single
val
_subselect
::
val
()
double
Item_single
row
_subselect
::
val
()
{
if
(
!
engine
->
exec
()
&&
!
value
->
null_value
)
{
...
...
@@ -226,7 +226,7 @@ double Item_singleval_subselect::val ()
}
}
longlong
Item_single
val
_subselect
::
val_int
()
longlong
Item_single
row
_subselect
::
val_int
()
{
if
(
!
engine
->
exec
()
&&
!
value
->
null_value
)
{
...
...
@@ -240,7 +240,7 @@ longlong Item_singleval_subselect::val_int ()
}
}
String
*
Item_single
val
_subselect
::
val_str
(
String
*
str
)
String
*
Item_single
row
_subselect
::
val_str
(
String
*
str
)
{
if
(
!
engine
->
exec
()
&&
!
value
->
null_value
)
{
...
...
@@ -293,7 +293,7 @@ Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
left_expr
=
left_exp
;
func
=
f
;
init
(
thd
,
select_lex
,
new
select_exists_subselect
(
this
));
max_columns
=
UINT_MAX
;
max_columns
=
1
;
reset
();
// We need only 1 row to determinate existence
select_lex
->
master_unit
()
->
global_parameters
->
select_limit
=
1
;
...
...
@@ -305,6 +305,7 @@ void Item_exists_subselect::fix_length_and_dec()
{
decimals
=
0
;
max_length
=
1
;
max_columns
=
engine
->
cols
();
}
double
Item_exists_subselect
::
val
()
...
...
@@ -409,7 +410,7 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
As far as Item_ref_in_optimizer do not substitude itself on fix_fields
we can use same item for all selects.
*/
Item
*
expr
=
new
Item_ref
(
optimizer
->
get_cache
(),
Item
*
expr
=
new
Item_ref
(
(
Item
**
)
optimizer
->
get_cache
(),
(
char
*
)
"<no matter>"
,
(
char
*
)
"<left expr>"
);
select_lex
->
master_unit
()
->
dependent
=
1
;
...
...
@@ -440,7 +441,7 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
sl
->
having
=
item
;
else
if
(
sl
->
where
)
sl
->
where
=
new
Item_cond_and
(
sl
->
having
,
item
);
sl
->
where
=
new
Item_cond_and
(
sl
->
where
,
item
);
else
sl
->
where
=
item
;
}
...
...
@@ -498,10 +499,68 @@ void Item_in_subselect::single_value_transformer(st_select_lex *select_lex,
DBUG_VOID_RETURN
;
}
void
Item_in_subselect
::
row_value_transformer
(
st_select_lex
*
select_lex
,
Item
*
left_expr
)
{
DBUG_ENTER
(
"Item_in_subselect::row_value_transformer"
);
Item_in_optimizer
*
optimizer
;
substitution
=
optimizer
=
new
Item_in_optimizer
(
left_expr
,
this
);
if
(
!
optimizer
)
{
current_thd
->
fatal_error
=
1
;
DBUG_VOID_RETURN
;
}
select_lex
->
master_unit
()
->
dependent
=
1
;
uint
n
=
left_expr
->
cols
();
if
(
optimizer
->
preallocate_row
()
||
(
*
optimizer
->
get_cache
())
->
allocate
(
n
))
DBUG_VOID_RETURN
;
for
(
SELECT_LEX
*
sl
=
select_lex
;
sl
;
sl
=
sl
->
next_select
())
{
select_lex
->
dependent
=
1
;
Item
*
item
=
0
;
List_iterator_fast
<
Item
>
li
(
sl
->
item_list
);
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
Item
*
func
=
new
Item_ref_on_list_position
(
this
,
sl
->
item_list
,
i
,
(
char
*
)
"<no matter>"
,
(
char
*
)
"<list ref>"
);
func
=
Item_bool_func2
::
eq_creator
(
new
Item_ref
((
*
optimizer
->
get_cache
())
->
addr
(
i
),
(
char
*
)
"<no matter>"
,
(
char
*
)
"<left expr>"
),
func
);
if
(
!
item
)
item
=
func
;
else
item
=
new
Item_cond_and
(
item
,
func
);
}
if
(
sl
->
having
||
sl
->
with_sum_func
||
sl
->
group_list
.
first
||
!
sl
->
table_list
.
elements
)
if
(
sl
->
having
)
sl
->
having
=
new
Item_cond_and
(
sl
->
having
,
item
);
else
sl
->
having
=
item
;
else
if
(
sl
->
where
)
sl
->
where
=
new
Item_cond_and
(
sl
->
where
,
item
);
else
sl
->
where
=
item
;
}
DBUG_VOID_RETURN
;
}
void
Item_in_subselect
::
select_transformer
(
st_select_lex
*
select_lex
)
{
single_value_transformer
(
select_lex
,
left_expr
,
&
Item_bool_func2
::
eq_creator
);
if
(
left_expr
->
cols
()
==
1
)
single_value_transformer
(
select_lex
,
left_expr
,
&
Item_bool_func2
::
eq_creator
);
else
row_value_transformer
(
select_lex
,
left_expr
);
}
void
Item_allany_subselect
::
select_transformer
(
st_select_lex
*
select_lex
)
...
...
sql/item_subselect.h
View file @
b63f2303
...
...
@@ -86,18 +86,19 @@ public:
bool
check_loop
(
uint
id
);
friend
class
select_subselect
;
friend
class
Item_in_optimizer
;
};
/* single value subselect */
class
Item_cache
;
class
Item_single
val
_subselect
:
public
Item_subselect
class
Item_single
row
_subselect
:
public
Item_subselect
{
protected:
Item_cache
*
value
,
**
row
;
public:
Item_single
val
_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
);
Item_single
val_subselect
(
Item_singleval
_subselect
*
item
)
:
Item_single
row
_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
);
Item_single
row_subselect
(
Item_singlerow
_subselect
*
item
)
:
Item_subselect
(
item
)
{
value
=
item
->
value
;
...
...
@@ -109,7 +110,7 @@ public:
double
val
();
longlong
val_int
();
String
*
val_str
(
String
*
);
Item
*
new_item
()
{
return
new
Item_single
val
_subselect
(
this
);
}
Item
*
new_item
()
{
return
new
Item_single
row
_subselect
(
this
);
}
enum
Item_result
result_type
()
const
;
void
fix_length_and_dec
();
...
...
@@ -120,7 +121,7 @@ public:
bool
null_inside
();
void
bring_value
();
friend
class
select_single
val
_subselect
;
friend
class
select_single
row
_subselect
;
};
/* exists subselect */
...
...
@@ -174,6 +175,7 @@ public:
virtual
void
select_transformer
(
st_select_lex
*
select_lex
);
void
single_value_transformer
(
st_select_lex
*
select_lex
,
Item
*
left_expr
,
compare_func_creator
func
);
void
row_value_transformer
(
st_select_lex
*
select_lex
,
Item
*
left_expr
);
longlong
val_int
();
double
val
();
String
*
val_str
(
String
*
);
...
...
sql/sql_class.cc
View file @
b63f2303
...
...
@@ -916,10 +916,10 @@ select_subselect::select_subselect(Item_subselect *item)
this
->
item
=
item
;
}
bool
select_single
val
_subselect
::
send_data
(
List
<
Item
>
&
items
)
bool
select_single
row
_subselect
::
send_data
(
List
<
Item
>
&
items
)
{
DBUG_ENTER
(
"select_single
val
_subselect::send_data"
);
Item_single
val_subselect
*
it
=
(
Item_singleval
_subselect
*
)
item
;
DBUG_ENTER
(
"select_single
row
_subselect::send_data"
);
Item_single
row_subselect
*
it
=
(
Item_singlerow
_subselect
*
)
item
;
if
(
it
->
assigned
())
{
my_message
(
ER_SUBSELECT_NO_1_ROW
,
ER
(
ER_SUBSELECT_NO_1_ROW
),
MYF
(
0
));
...
...
sql/sql_class.h
View file @
b63f2303
...
...
@@ -824,10 +824,10 @@ public:
};
/* Single value subselect interface class */
class
select_single
val
_subselect
:
public
select_subselect
class
select_single
row
_subselect
:
public
select_subselect
{
public:
select_single
val
_subselect
(
Item_subselect
*
item
)
:
select_subselect
(
item
){}
select_single
row
_subselect
(
Item_subselect
*
item
)
:
select_subselect
(
item
){}
bool
send_data
(
List
<
Item
>
&
items
);
};
...
...
sql/sql_yacc.yy
View file @
b63f2303
...
...
@@ -587,7 +587,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
using_list expr_or_default set_expr_or_default
param_marker single
val_subselect singleval
_subselect_init
param_marker single
row_subselect singlerow
_subselect_init
exists_subselect exists_subselect_init
%type <item_list>
...
...
@@ -2017,7 +2017,7 @@ simple_expr:
$$= new Item_row(*$5);
}
| EXISTS exists_subselect { $$= $2; }
| single
val
_subselect { $$= $1; }
| single
row
_subselect { $$= $1; }
| '{' ident expr '}' { $$= $3; }
| MATCH ident_list_arg AGAINST '(' expr ')'
{ Select->add_ftfunc_to_list((Item_func_match *)
...
...
@@ -4487,17 +4487,17 @@ union_option:
/* empty */ {}
| ALL {Select->master_unit()->union_option= 1;};
single
val
_subselect:
subselect_start single
val
_subselect_init
single
row
_subselect:
subselect_start single
row
_subselect_init
subselect_end
{
$$= $2;
};
single
val
_subselect_init:
single
row
_subselect_init:
select_init2
{
$$= new Item_single
val
_subselect(YYTHD,
$$= new Item_single
row
_subselect(YYTHD,
Lex->current_select->master_unit()->
first_select());
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment