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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
20232ada
Commit
20232ada
authored
Dec 27, 2002
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Plain Diff
Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/work-row-4.1
parents
d85a01db
521ec316
Changes
13
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
840 additions
and
306 deletions
+840
-306
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+103
-2
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+42
-2
sql/item.cc
sql/item.cc
+163
-31
sql/item.h
sql/item.h
+150
-83
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+54
-40
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+11
-15
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
+265
-58
sql/item_subselect.h
sql/item_subselect.h
+29
-37
sql/sql_class.cc
sql/sql_class.cc
+6
-29
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 @
20232ada
...
...
@@ -52,6 +52,54 @@ a
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
a
1
SELECT (SELECT 1,2,3) = ROW(1,2,3);
(SELECT 1,2,3) = ROW(1,2,3)
1
SELECT (SELECT 1,2,3) = ROW(1,2,1);
(SELECT 1,2,3) = ROW(1,2,1)
0
SELECT (SELECT 1,2,3) < ROW(1,2,1);
(SELECT 1,2,3) < ROW(1,2,1)
0
SELECT (SELECT 1,2,3) > ROW(1,2,1);
(SELECT 1,2,3) > ROW(1,2,1)
1
SELECT (SELECT 1,2,3) = ROW(1,2,NULL);
(SELECT 1,2,3) = ROW(1,2,NULL)
NULL
SELECT ROW(1,2,3) = (SELECT 1,2,3);
ROW(1,2,3) = (SELECT 1,2,3)
1
SELECT ROW(1,2,3) = (SELECT 1,2,1);
ROW(1,2,3) = (SELECT 1,2,1)
0
SELECT ROW(1,2,3) < (SELECT 1,2,1);
ROW(1,2,3) < (SELECT 1,2,1)
0
SELECT ROW(1,2,3) > (SELECT 1,2,1);
ROW(1,2,3) > (SELECT 1,2,1)
1
SELECT ROW(1,2,3) = (SELECT 1,2,NULL);
ROW(1,2,3) = (SELECT 1,2,NULL)
NULL
SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'a');
(SELECT 1.5,2,'a') = ROW(1.5,2,'a')
1
SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'b');
(SELECT 1.5,2,'a') = ROW(1.5,2,'b')
0
SELECT (SELECT 1.5,2,'a') = ROW('b',2,'b');
(SELECT 1.5,2,'a') = ROW('b',2,'b')
0
SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a');
(SELECT 'b',2,'a') = ROW(1.5,2,'a')
0
SELECT (SELECT 1.5,2,'a') = ROW(1.5,'c','a');
(SELECT 1.5,2,'a') = ROW(1.5,'c','a')
0
SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
(SELECT 1.5,'c','a') = ROW(1.5,2,'a')
0
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
create table t1 (a int);
create table t2 (a int, b int);
...
...
@@ -586,7 +634,7 @@ EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t index NULL id 5 NULL 2 Using where; Using index
2 DEPENDENT SUBSELECT NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
3
DEPENDENT
UNION NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 3);
id
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2);
...
...
@@ -602,7 +650,7 @@ CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin
INSERT INTO t1 values (1),(1);
UPDATE t SET id=(SELECT * FROM t1);
Subselect returns more than 1 record
drop table t;
drop table t
, t1
;
create table t (a int);
insert into t values (1),(2),(3);
select 1 IN (SELECT * from t);
...
...
@@ -711,3 +759,56 @@ This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
select 10.5 IN (SELECT * from t LIMIT 1 UNION SELECT 1.5);
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
drop table t;
create table t1 (a int, b int, c varchar(10));
create table t2 (a int);
insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
insert into t2 values (1),(2),(NULL);
select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
1 1 a
2 0 b
NULL NULL NULL
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;
a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
1 0 a
2 1 b
NULL NULL NULL
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;
a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
1 0 a
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
select ROW(1, 1, 'a') IN (select b,a,c from t limit 2);
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
drop table if exists t;
mysql-test/t/subselect.test
View file @
20232ada
...
...
@@ -26,6 +26,22 @@ select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
SELECT
1
FROM
(
SELECT
1
)
a
PROCEDURE
ANALYSE
((
SELECT
1
));
SELECT
(
SELECT
1
)
as
a
FROM
(
SELECT
1
)
b
WHERE
(
SELECT
a
)
IS
NULL
;
SELECT
(
SELECT
1
)
as
a
FROM
(
SELECT
1
)
b
WHERE
(
SELECT
a
)
IS
NOT
NULL
;
SELECT
(
SELECT
1
,
2
,
3
)
=
ROW
(
1
,
2
,
3
);
SELECT
(
SELECT
1
,
2
,
3
)
=
ROW
(
1
,
2
,
1
);
SELECT
(
SELECT
1
,
2
,
3
)
<
ROW
(
1
,
2
,
1
);
SELECT
(
SELECT
1
,
2
,
3
)
>
ROW
(
1
,
2
,
1
);
SELECT
(
SELECT
1
,
2
,
3
)
=
ROW
(
1
,
2
,
NULL
);
SELECT
ROW
(
1
,
2
,
3
)
=
(
SELECT
1
,
2
,
3
);
SELECT
ROW
(
1
,
2
,
3
)
=
(
SELECT
1
,
2
,
1
);
SELECT
ROW
(
1
,
2
,
3
)
<
(
SELECT
1
,
2
,
1
);
SELECT
ROW
(
1
,
2
,
3
)
>
(
SELECT
1
,
2
,
1
);
SELECT
ROW
(
1
,
2
,
3
)
=
(
SELECT
1
,
2
,
NULL
);
SELECT
(
SELECT
1.5
,
2
,
'a'
)
=
ROW
(
1.5
,
2
,
'a'
);
SELECT
(
SELECT
1.5
,
2
,
'a'
)
=
ROW
(
1.5
,
2
,
'b'
);
SELECT
(
SELECT
1.5
,
2
,
'a'
)
=
ROW
(
'b'
,
2
,
'b'
);
SELECT
(
SELECT
'b'
,
2
,
'a'
)
=
ROW
(
1.5
,
2
,
'a'
);
SELECT
(
SELECT
1.5
,
2
,
'a'
)
=
ROW
(
1.5
,
'c'
,
'a'
);
SELECT
(
SELECT
1.5
,
'c'
,
'a'
)
=
ROW
(
1.5
,
2
,
'a'
);
drop
table
if
exists
t1
,
t2
,
t3
,
t4
,
t5
,
t6
,
t7
,
t8
;
create
table
t1
(
a
int
);
...
...
@@ -363,7 +379,7 @@ CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin
INSERT
INTO
t1
values
(
1
),(
1
);
--
error
1240
UPDATE
t
SET
id
=
(
SELECT
*
FROM
t1
);
drop
table
t
;
drop
table
t
,
t1
;
#NULL test
...
...
@@ -417,3 +433,27 @@ select 10.5 IN (SELECT * from t LIMIT 1);
--
error
1235
select
10.5
IN
(
SELECT
*
from
t
LIMIT
1
UNION
SELECT
1.5
);
drop
table
t
;
create
table
t1
(
a
int
,
b
int
,
c
varchar
(
10
));
create
table
t2
(
a
int
);
insert
into
t1
values
(
1
,
2
,
'a'
),(
2
,
3
,
'b'
),(
3
,
4
,
'c'
);
insert
into
t2
values
(
1
),(
2
),(
NULL
);
select
a
,
(
select
a
,
b
,
c
from
t1
where
t1
.
a
=
t2
.
a
)
=
ROW
(
a
,
2
,
'a'
),(
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
,
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'
);
--
error
1235
select
ROW
(
1
,
1
,
'a'
)
IN
(
select
b
,
a
,
c
from
t
limit
2
);
drop
table
if
exists
t
;
sql/item.cc
View file @
20232ada
...
...
@@ -47,11 +47,6 @@ Item::Item():
loop_id
=
0
;
}
Item_ref_in_optimizer
::
Item_ref_in_optimizer
(
Item_in_optimizer
*
master
,
char
*
table_name_par
,
char
*
field_name_par
)
:
Item_ref
(
master
->
args
,
table_name_par
,
field_name_par
),
owner
(
master
)
{}
bool
Item
::
check_loop
(
uint
id
)
{
...
...
@@ -437,20 +432,6 @@ String *Item_copy_string::val_str(String *str)
return
&
str_value
;
}
double
Item_ref_in_optimizer
::
val
()
{
return
owner
->
get_cache
();
}
longlong
Item_ref_in_optimizer
::
val_int
()
{
return
owner
->
get_cache_int
();
}
String
*
Item_ref_in_optimizer
::
val_str
(
String
*
s
)
{
return
owner
->
get_cache_str
(
s
);
}
/*
Functions to convert item to field (for send_fields)
*/
...
...
@@ -464,18 +445,6 @@ bool Item::fix_fields(THD *thd,
return
0
;
}
bool
Item_outer_select_context_saver
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
ref
)
{
DBUG_ENTER
(
"Item_outer_select_context_saver::fix_fields"
);
bool
res
=
item
->
fix_fields
(
thd
,
0
,
// do not show current subselect fields
&
item
);
*
ref
=
item
;
DBUG_RETURN
(
res
);
}
bool
Item_asterisk_remover
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
ref
)
...
...
@@ -529,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
();
...
...
@@ -1221,6 +1211,148 @@ bool field_is_equal_to_item(Field *field,Item *item)
return
result
==
field
->
val_real
();
}
Item_cache
*
Item_cache
::
get_cache
(
Item_result
type
)
{
switch
(
type
)
{
case
INT_RESULT
:
return
new
Item_cache_int
();
case
REAL_RESULT
:
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
);
return
0
;
}
}
void
Item_cache_str
::
store
(
Item
*
item
)
{
str_value
.
set
(
buffer
,
sizeof
(
buffer
),
item
->
charset
());
value
=
item
->
str_result
(
&
str_value
);
if
((
null_value
=
item
->
null_value
))
value
=
0
;
else
if
(
value
!=
&
str_value
)
{
/*
We copy string value to avoid changing value if 'item' is table field
in queries like following (where t1.c is varchar):
select a,
(select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),
(select c from t1 where a=t2.a)
from t2;
*/
str_value
.
copy
(
*
value
);
value
=
&
str_value
;
}
}
double
Item_cache_str
::
val
()
{
if
(
value
)
return
my_strntod
(
value
->
charset
(),
value
->
ptr
(),
value
->
length
(),
(
char
**
)
0
);
else
return
(
double
)
0
;
}
longlong
Item_cache_str
::
val_int
()
{
if
(
value
)
return
my_strntoll
(
value
->
charset
(),
value
->
ptr
(),
value
->
length
(),
(
char
**
)
0
,
10
);
else
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 @
20232ada
...
...
@@ -31,12 +31,12 @@ class Item {
static
void
*
operator
new
(
size_t
size
)
{
return
(
void
*
)
sql_alloc
((
uint
)
size
);
}
static
void
operator
delete
(
void
*
ptr
,
size_t
size
)
{}
/*lint -e715 */
enum
Type
{
FIELD_ITEM
,
FUNC_ITEM
,
SUM_FUNC_ITEM
,
STRING_ITEM
,
INT_ITEM
,
REAL_ITEM
,
NULL_ITEM
,
VARBIN_ITEM
,
COPY_STR_ITEM
,
FIELD_AVG_ITEM
,
DEFAULT_ITEM
,
PROC_ITEM
,
COND_ITEM
,
REF_ITEM
,
FIELD_STD_ITEM
,
FIELD_VARIANCE_ITEM
,
CONST_ITEM
,
SUBSELECT_ITEM
,
ROW_ITEM
};
enum
Type
{
FIELD_ITEM
,
FUNC_ITEM
,
SUM_FUNC_ITEM
,
STRING_ITEM
,
INT_ITEM
,
REAL_ITEM
,
NULL_ITEM
,
VARBIN_ITEM
,
COPY_STR_ITEM
,
FIELD_AVG_ITEM
,
DEFAULT_ITEM
,
PROC_ITEM
,
COND_ITEM
,
REF_ITEM
,
FIELD_STD_ITEM
,
FIELD_VARIANCE_ITEM
,
CONST_ITEM
,
SUBSELECT_ITEM
,
ROW_ITEM
,
CACHE_ITEM
};
enum
cond_result
{
COND_UNDEF
,
COND_OK
,
COND_TRUE
,
COND_FALSE
};
String
str_value
;
/* used to store value */
...
...
@@ -103,64 +103,12 @@ class Item {
virtual
Item
**
addr
(
uint
i
)
{
return
0
;
}
virtual
bool
check_cols
(
uint
c
);
// It is not row => null inside is impossible
virtual
bool
null_inside
()
{
return
0
;
};
virtual
bool
null_inside
()
{
return
0
;
}
// used in row subselects to get value of elements
virtual
void
bring_value
()
{}
};
/*
Wrapper base class
*/
class
Item_wrapper
:
public
Item
{
protected:
Item
*
item
;
public:
/*
Following methods should not be used, because fix_fields exclude this
item (it assign '*ref' with field 'item' in derived classes)
*/
enum
Type
type
()
const
{
return
item
->
type
();
}
enum_field_types
field_type
()
const
{
return
item
->
field_type
();
}
double
val
()
{
return
item
->
val
();
}
longlong
val_int
()
{
return
item
->
val_int
();
}
String
*
val_str
(
String
*
s
)
{
return
item
->
val_str
(
s
);
}
bool
check_cols
(
uint
col
)
{
return
item
->
check_cols
(
col
);
}
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
return
item
->
eq
(
item
,
binary_cmp
);
}
bool
is_null
()
{
item
->
val_int
();
return
item
->
null_value
;
}
bool
get_date
(
TIME
*
ltime
,
bool
fuzzydate
)
{
return
(
null_value
=
item
->
get_date
(
ltime
,
fuzzydate
));
}
bool
send
(
Protocol
*
prot
,
String
*
tmp
)
{
return
item
->
send
(
prot
,
tmp
);
}
int
save_in_field
(
Field
*
field
,
bool
no_conversions
)
{
return
item
->
save_in_field
(
field
,
no_conversions
);
}
void
save_org_in_field
(
Field
*
field
)
{
item
->
save_org_in_field
(
field
);
}
enum
Item_result
result_type
()
const
{
return
item
->
result_type
();
}
table_map
used_tables
()
const
{
return
item
->
used_tables
();
}
};
/*
Save context of name resolution for Item, used in subselect transformer.
*/
class
Item_outer_select_context_saver
:
public
Item_wrapper
{
public:
Item_outer_select_context_saver
(
Item
*
it
)
{
item
=
it
;
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
};
class
st_select_lex
;
class
Item_ident
:
public
Item
{
...
...
@@ -381,7 +329,8 @@ class Item_string :public Item
name
=
(
char
*
)
str_value
.
ptr
();
decimals
=
NOT_FIXED_DEC
;
}
Item_string
(
const
char
*
name_par
,
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
)
Item_string
(
const
char
*
name_par
,
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
)
{
str_value
.
set
(
str
,
length
,
cs
);
max_length
=
length
;
...
...
@@ -392,11 +341,13 @@ class Item_string :public Item
enum
Type
type
()
const
{
return
STRING_ITEM
;
}
double
val
()
{
return
my_strntod
(
str_value
.
charset
(),
str_value
.
ptr
(),
str_value
.
length
(),(
char
**
)
NULL
);
return
my_strntod
(
str_value
.
charset
(),
str_value
.
ptr
(),
str_value
.
length
(),
(
char
**
)
0
);
}
longlong
val_int
()
{
return
my_strntoll
(
str_value
.
charset
(),
str_value
.
ptr
(),
str_value
.
length
(),(
char
**
)
0
,
10
);
return
my_strntoll
(
str_value
.
charset
(),
str_value
.
ptr
(),
str_value
.
length
(),
(
char
**
)
0
,
10
);
}
String
*
val_str
(
String
*
)
{
return
(
String
*
)
&
str_value
;
}
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
...
...
@@ -550,7 +501,7 @@ class Item_ref_null_helper: public Item_ref
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
();
...
...
@@ -558,6 +509,24 @@ class Item_ref_null_helper: public Item_ref
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
...
...
@@ -574,24 +543,6 @@ class Item_asterisk_remover :public Item_ref_null_helper
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
};
class
Item_in_optimizer
;
class
Item_ref_in_optimizer
:
public
Item_ref
{
protected:
Item_in_optimizer
*
owner
;
public:
Item_ref_in_optimizer
(
Item_in_optimizer
*
master
,
char
*
table_name_par
,
char
*
field_name_par
);
double
val
();
longlong
val_int
();
String
*
val_str
(
String
*
s
);
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
)
{
fixed
=
1
;
return
0
;
}
};
/*
The following class is used to optimize comparing of date columns
We need to save the original item, to be able to set the field to the
...
...
@@ -706,6 +657,122 @@ class Item_field_buff :public Item_buff
bool
cmp
(
void
);
};
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
)
{
max_length
=
max_len
;
decimals
=
dec
;
}
enum
Type
type
()
const
{
return
CACHE_ITEM
;
}
static
Item_cache
*
get_cache
(
Item_result
type
);
};
class
Item_cache_int
:
public
Item_cache
{
longlong
value
;
public:
Item_cache_int
()
{
fixed
=
1
;
null_value
=
1
;
}
void
store
(
Item
*
item
)
{
value
=
item
->
val_int_result
();
null_value
=
item
->
null_value
;
}
double
val
()
{
return
(
double
)
value
;
}
longlong
val_int
()
{
return
value
;
}
String
*
val_str
(
String
*
str
)
{
str
->
set
(
value
,
thd_charset
());
return
str
;
}
enum
Item_result
result_type
()
const
{
return
INT_RESULT
;
}
};
class
Item_cache_real
:
public
Item_cache
{
double
value
;
public:
Item_cache_real
()
{
fixed
=
1
;
null_value
=
1
;
}
void
store
(
Item
*
item
)
{
value
=
item
->
val_result
();
null_value
=
item
->
null_value
;
}
double
val
()
{
return
value
;
}
longlong
val_int
()
{
return
(
longlong
)
(
value
+
(
value
>
0
?
0.5
:
-
0.5
));
}
String
*
val_str
(
String
*
str
)
{
str
->
set
(
value
,
decimals
,
thd_charset
());
return
str
;
}
enum
Item_result
result_type
()
const
{
return
REAL_RESULT
;
}
};
class
Item_cache_str
:
public
Item_cache
{
char
buffer
[
80
];
String
*
value
;
public:
Item_cache_str
()
{
fixed
=
1
;
null_value
=
1
;
}
void
store
(
Item
*
item
);
double
val
();
longlong
val_int
();
String
*
val_str
(
String
*
)
{
return
value
;
}
enum
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
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 @
20232ada
...
...
@@ -247,6 +247,8 @@ int Arg_comparator::compare_e_int()
int
Arg_comparator
::
compare_row
()
{
int
res
=
0
;
(
*
a
)
->
bring_value
();
(
*
b
)
->
bring_value
();
uint
n
=
(
*
a
)
->
cols
();
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
...
...
@@ -261,6 +263,8 @@ int Arg_comparator::compare_row()
int
Arg_comparator
::
compare_e_row
()
{
int
res
=
0
;
(
*
a
)
->
bring_value
();
(
*
b
)
->
bring_value
();
uint
n
=
(
*
a
)
->
cols
();
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
...
...
@@ -270,60 +274,67 @@ int Arg_comparator::compare_e_row()
return
1
;
}
longlong
Item_in_optimizer
::
val_int
()
bool
Item_in_optimizer
::
preallocate_row
()
{
int_cache_ok
=
1
;
flt_cache_ok
=
0
;
str_cache_ok
=
0
;
int_cache
=
args
[
0
]
->
val_int_result
();
if
(
args
[
0
]
->
null_value
)
{
null_value
=
1
;
if
((
cache
=
Item_cache
::
get_cache
(
ROW_RESULT
)))
return
0
;
}
longlong
tmp
=
args
[
1
]
->
val_int_result
();
null_value
=
args
[
1
]
->
null_value
;
return
tmp
;
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
current_thd
->
fatal_error
=
1
;
return
1
;
}
longlong
Item_in_optimizer
::
get_cache_int
()
bool
Item_in_optimizer
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
if
(
!
int_cache_ok
)
if
(
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
))
return
1
;
if
(
args
[
0
]
->
maybe_null
)
maybe_null
=
1
;
if
(
args
[
0
]
->
binary
())
set_charset
(
my_charset_bin
);
with_sum_func
=
args
[
0
]
->
with_sum_func
;
used_tables_cache
=
args
[
0
]
->
used_tables
();
const_item_cache
=
args
[
0
]
->
const_item
();
if
(
!
cache
&&
!
(
cache
=
Item_cache
::
get_cache
(
args
[
0
]
->
result_type
())))
{
int_cache_ok
=
1
;
flt_cache_ok
=
0
;
str_cache_ok
=
0
;
int_cache
=
args
[
0
]
->
val_int_result
();
null_value
=
args
[
0
]
->
null_value
;
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
thd
->
fatal_error
=
1
;
return
1
;
}
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
;
}
return
int_cache
;
if
(
args
[
1
]
->
maybe_null
)
maybe_null
=
1
;
with_sum_func
=
with_sum_func
||
args
[
1
]
->
with_sum_func
;
used_tables_cache
|=
args
[
1
]
->
used_tables
();
const_item_cache
&=
args
[
1
]
->
const_item
();
return
0
;
}
double
Item_in_optimizer
::
get_cache
()
longlong
Item_in_optimizer
::
val_int
()
{
if
(
!
flt_cache_ok
)
cache
->
store
(
args
[
0
]);
if
(
cache
->
null_value
)
{
flt_cache_ok
=
1
;
int_cache_ok
=
0
;
str_cache_ok
=
0
;
flt_cache
=
args
[
0
]
->
val_result
();
null_value
=
args
[
0
]
->
null_value
;
null_value
=
1
;
return
0
;
}
return
flt_cache
;
longlong
tmp
=
args
[
1
]
->
val_int_result
();
null_value
=
args
[
1
]
->
null_value
;
return
tmp
;
}
String
*
Item_in_optimizer
::
get_cache_str
(
String
*
s
)
bool
Item_in_optimizer
::
is_null
(
)
{
if
(
!
str_cache_ok
)
{
str_cache_ok
=
1
;
int_cache_ok
=
0
;
flt_cache_ok
=
0
;
str_value
.
set
(
buffer
,
sizeof
(
buffer
),
s
->
charset
());
str_cache
=
args
[
0
]
->
str_result
(
&
str_value
);
null_value
=
args
[
0
]
->
null_value
;
}
return
str_cache
;
cache
->
store
(
args
[
0
]);
return
(
null_value
=
(
cache
->
null_value
||
args
[
1
]
->
is_null
()));
}
longlong
Item_func_eq
::
val_int
()
...
...
@@ -1217,8 +1228,9 @@ 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
;
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
((
comparators
[
i
]
=
cmp_item
::
get_comparator
(
item
->
el
(
i
))))
...
...
@@ -1252,6 +1264,7 @@ void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
n
=
tmpl
->
n
;
if
((
comparators
=
(
cmp_item
**
)
sql_alloc
(
sizeof
(
cmp_item
*
)
*
n
)))
{
item
->
bring_value
();
item
->
null_value
=
0
;
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
((
comparators
[
i
]
=
tmpl
->
comparators
[
i
]
->
make_same
()))
...
...
@@ -1284,6 +1297,7 @@ int cmp_item_row::cmp(Item *arg)
return
1
;
}
bool
was_null
=
0
;
arg
->
bring_value
();
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
(
comparators
[
i
]
->
cmp
(
arg
->
el
(
i
)))
{
...
...
sql/item_cmpfunc.h
View file @
20232ada
...
...
@@ -85,25 +85,21 @@ class Item_bool_func :public Item_int_func
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
1
;
}
};
class
Item_cache
;
class
Item_in_optimizer
:
public
Item_bool_func
{
protected:
char
buffer
[
80
];
longlong
int_cache
;
double
flt_cache
;
String
*
str_cache
;
bool
int_cache_ok
,
flt_cache_ok
,
str_cache_ok
;
public:
Item_in_optimizer
(
Item
*
a
,
Item
*
b
)
:
Item_bool_func
(
a
,
b
),
int_cache_ok
(
0
),
flt_cache_ok
(
0
),
str_cache_ok
(
0
)
{}
bool
is_null
()
{
return
test
(
args
[
0
]
->
is_null
()
||
args
[
1
]
->
is_null
());
}
Item_cache
*
cache
;
public:
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
();
double
get_cache
();
longlong
get_cache_int
();
String
*
get_cache_str
(
String
*
s
);
friend
class
Item_ref_in_optimizer
;
Item_cache
**
get_cache
()
{
return
&
cache
;
}
};
class
Item_bool_func2
:
public
Item_int_func
...
...
sql/item_row.cc
View file @
20232ada
...
...
@@ -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 @
20232ada
...
...
@@ -70,4 +70,5 @@ class Item_row: public Item
Item
**
addr
(
uint
i
)
{
return
items
+
i
;
}
bool
check_cols
(
uint
c
);
bool
null_inside
();
void
bring_value
();
};
sql/item_subselect.cc
View file @
20232ada
This diff is collapsed.
Click to expand it.
sql/item_subselect.h
View file @
20232ada
...
...
@@ -71,7 +71,7 @@ class Item_subselect :public Item_result_field
{
null_value
=
1
;
}
virtual
void
select_transformer
(
st_select_lex
*
select_lex
);
virtual
void
select_transformer
(
st_select_lex
_unit
*
unit
);
bool
assigned
()
{
return
value_assigned
;
}
void
assigned
(
bool
a
)
{
value_assigned
=
a
;
}
enum
Type
type
()
const
;
...
...
@@ -86,51 +86,42 @@ class Item_subselect :public Item_result_field
bool
check_loop
(
uint
id
);
friend
class
select_subselect
;
friend
class
Item_in_optimizer
;
};
/* single value subselect */
class
Item_singleval_subselect
:
public
Item_subselect
class
Item_cache
;
class
Item_singlerow_subselect
:
public
Item_subselect
{
protected:
longlong
int_value
;
/* Here stored integer value of this item */
double
real_value
;
/* Here stored real value of this item */
/*
Here stored string value of this item.
(str_value used only as temporary buffer, because it can be changed
by Item::save_field)
*/
String
string_value
;
enum
Item_result
res_type
;
/* type of results */
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
)
{
int_value
=
item
->
int_value
;
real_value
=
item
->
real_value
;
string_value
.
set
(
item
->
string_value
,
0
,
item
->
string_value
.
length
());
value
=
item
->
value
;
max_length
=
item
->
max_length
;
decimals
=
item
->
decimals
;
res_type
=
item
->
res_type
;
}
virtual
void
reset
()
{
null_value
=
1
;
int_value
=
0
;
real_value
=
0
;
max_length
=
4
;
res_type
=
STRING_RESULT
;
}
double
val
();
void
reset
();
void
store
(
uint
i
,
Item
*
item
);
double
val
();
longlong
val_int
();
String
*
val_str
(
String
*
);
Item
*
new_item
()
{
return
new
Item_single
val
_subselect
(
this
);
}
enum
Item_result
result_type
()
const
{
return
res_type
;
}
Item
*
new_item
()
{
return
new
Item_single
row
_subselect
(
this
);
}
enum
Item_result
result_type
()
const
;
void
fix_length_and_dec
();
friend
class
select_singleval_subselect
;
uint
cols
();
Item
*
el
(
uint
i
)
{
return
(
Item
*
)
row
[
i
];
}
Item
**
addr
(
uint
i
)
{
return
(
Item
**
)
row
+
i
;
}
bool
check_cols
(
uint
c
);
bool
null_inside
();
void
bring_value
();
friend
class
select_singlerow_subselect
;
};
/* exists subselect */
...
...
@@ -149,7 +140,7 @@ class Item_exists_subselect :public Item_subselect
}
Item_exists_subselect
()
:
Item_subselect
()
{}
v
irtual
v
oid
reset
()
void
reset
()
{
value
=
0
;
}
...
...
@@ -181,9 +172,10 @@ class Item_in_subselect :public Item_exists_subselect
null_value
=
0
;
was_null
=
0
;
}
virtual
void
select_transformer
(
st_select_lex
*
select_lex
);
void
single_value_transformer
(
st_select_lex
*
select_lex
,
virtual
void
select_transformer
(
st_select_lex
_unit
*
unit
);
void
single_value_transformer
(
st_select_lex
_unit
*
unit
,
Item
*
left_expr
,
compare_func_creator
func
);
void
row_value_transformer
(
st_select_lex_unit
*
unit
,
Item
*
left_expr
);
longlong
val_int
();
double
val
();
String
*
val_str
(
String
*
);
...
...
@@ -202,7 +194,7 @@ class Item_allany_subselect :public Item_in_subselect
Item_allany_subselect
(
THD
*
thd
,
Item
*
left_expr
,
compare_func_creator
f
,
st_select_lex
*
select_lex
);
Item_allany_subselect
(
Item_allany_subselect
*
item
);
virtual
void
select_transformer
(
st_select_lex
*
select_lex
);
virtual
void
select_transformer
(
st_select_lex
_unit
*
unit
);
};
class
subselect_engine
...
...
@@ -228,7 +220,7 @@ class subselect_engine
}
virtual
int
prepare
()
=
0
;
virtual
void
fix_length_and_dec
()
=
0
;
virtual
void
fix_length_and_dec
(
Item_cache
**
row
)
=
0
;
virtual
int
exec
()
=
0
;
virtual
uint
cols
()
=
0
;
/* return number of columnss in select */
virtual
bool
depended
()
=
0
;
/* depended from outer select */
...
...
@@ -249,7 +241,7 @@ class subselect_single_select_engine: public subselect_engine
select_subselect
*
result
,
Item_subselect
*
item
);
int
prepare
();
void
fix_length_and_dec
();
void
fix_length_and_dec
(
Item_cache
**
row
);
int
exec
();
uint
cols
();
bool
depended
();
...
...
@@ -266,7 +258,7 @@ class subselect_union_engine: public subselect_engine
select_subselect
*
result
,
Item_subselect
*
item
);
int
prepare
();
void
fix_length_and_dec
();
void
fix_length_and_dec
(
Item_cache
**
row
);
int
exec
();
uint
cols
();
bool
depended
();
...
...
sql/sql_class.cc
View file @
20232ada
...
...
@@ -917,10 +917,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
));
...
...
@@ -932,32 +932,9 @@ bool select_singleval_subselect::send_data(List<Item> &items)
DBUG_RETURN
(
0
);
}
List_iterator_fast
<
Item
>
li
(
items
);
Item
*
val_item
=
li
++
;
// Only one (single value subselect)
/*
Following val() call have to be first, because function AVG() & STD()
calculate value on it & determinate "is it NULL?".
*/
it
->
real_value
=
val_item
->
val_result
();
if
((
it
->
null_value
=
val_item
->
null_value
))
{
it
->
reset
();
}
else
{
it
->
max_length
=
val_item
->
max_length
;
it
->
decimals
=
val_item
->
decimals
;
it
->
set_charset
(
val_item
->
charset
());
it
->
int_value
=
val_item
->
val_int_result
();
String
*
s
=
val_item
->
str_result
(
&
it
->
string_value
);
if
(
s
!=
&
it
->
string_value
)
{
it
->
string_value
.
set
(
*
s
,
0
,
s
->
length
());
}
// TODO: remove when correct charset handling appeared for Item
it
->
str_value
.
set
(
*
s
,
0
,
s
->
length
());
// store charset
it
->
res_type
=
val_item
->
result_type
();
}
Item
*
val_item
;
for
(
uint
i
=
0
;
(
val_item
=
li
++
);
i
++
)
it
->
store
(
i
,
val_item
);
it
->
assigned
(
1
);
DBUG_RETURN
(
0
);
}
...
...
sql/sql_class.h
View file @
20232ada
...
...
@@ -824,10 +824,10 @@ class select_subselect :public select_result
};
/* 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 @
20232ada
...
...
@@ -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>
...
...
@@ -2018,7 +2018,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 *)
...
...
@@ -4488,17 +4488,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