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
2885d552
Commit
2885d552
authored
Dec 10, 2002
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Plain Diff
merging
parents
6db77efb
3172a451
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
574 additions
and
82 deletions
+574
-82
mysql-test/r/row.result
mysql-test/r/row.result
+130
-0
mysql-test/t/row.test
mysql-test/t/row.test
+59
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+174
-25
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+163
-50
sql/item_row.cc
sql/item_row.cc
+20
-3
sql/item_row.h
sql/item_row.h
+9
-3
sql/sql_list.h
sql/sql_list.h
+9
-1
sql/sql_select.cc
sql/sql_select.cc
+10
-0
No files found.
mysql-test/r/row
_test
.result
→
mysql-test/r/row.result
View file @
2885d552
select row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
row(1,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3))
1
select row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3));
row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3))
0
select row(1,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
row(1,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3))
1
select row(10,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3));
row(10,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3))
NULL
select row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a'));
row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a'))
1
select row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3));
row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3))
1
select row('a',0,3) IN (row(3,2,3), row('a','a','3'), row(1,3,3));
row('a',0,3) IN (row(3,2,3), row('a','a','3'), row(1,3,3))
1
select row('a',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
row('a',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3))
1
select row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3));
row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3))
NULL
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,4)));
row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,4)))
1
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,4));
Cardinality error (more/less than 2 columns)
select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,NULL)));
row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,NULL)))
NULL
SELECT ROW(1,2,3)=ROW(1,2,3);
ROW(1,2,3)=ROW(1,2,3)
1
...
...
@@ -36,9 +71,20 @@ ROW('test',2,3.33)=ROW('test',2,3.33)
1
SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4);
Cardinality error (more/less than 3 columns)
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,33));
ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,33))
1
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,3));
ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,3))
0
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,NULL));
ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,NULL))
NULL
SELECT ROW('test',2,ROW(3,33))=ROW('test',2,4);
Cardinality error (more/less than 2 columns)
drop table if exists t1;
create table t1 ( a int, b int, c int);
insert into t1 values (1,2,3), (2,3,1), (3,2,1);
insert into t1 values (1,2,3), (2,3,1), (3,2,1)
, (1,2,NULL)
;
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
a b c
1 2 3
...
...
@@ -48,6 +94,30 @@ select * from t1 where ROW(1,2,3)<ROW(a,b,c);
a b c
2 3 1
3 2 1
select ROW(a,2,3) IN(row(1,b,c), row(2,3,1)) from t1;
ROW(a,2,3) IN(row(1,b,c), row(2,3,1))
1
0
0
NULL
select ROW(c,2,3) IN(row(1,b,a), row(2,3,1)) from t1;
ROW(c,2,3) IN(row(1,b,a), row(2,3,1))
0
0
1
NULL
select ROW(a,b,c) IN(row(1,2,3), row(3,2,1)) from t1;
ROW(a,b,c) IN(row(1,2,3), row(3,2,1))
1
0
1
NULL
select ROW(1,2,3) IN(row(a,b,c), row(1,2,3)) from t1;
ROW(1,2,3) IN(row(a,b,c), row(1,2,3))
1
1
1
1
drop table t1;
select ROW(1,1);
Cardinality error (more/less than 1 columns)
...
...
mysql-test/t/row
_test
.test
→
mysql-test/t/row.test
View file @
2885d552
select
row
(
1
,
2
,
3
)
IN
(
row
(
3
,
2
,
3
),
row
(
1
,
2
,
3
),
row
(
1
,
3
,
3
));
select
row
(
10
,
2
,
3
)
IN
(
row
(
3
,
2
,
3
),
row
(
1
,
2
,
3
),
row
(
1
,
3
,
3
));
select
row
(
1
,
2
,
3
)
IN
(
row
(
3
,
NULL
,
3
),
row
(
1
,
2
,
3
),
row
(
1
,
3
,
3
));
select
row
(
10
,
2
,
3
)
IN
(
row
(
3
,
NULL
,
3
),
row
(
1
,
2
,
3
),
row
(
1
,
3
,
3
));
select
row
(
'a'
,
1.5
,
3
)
IN
(
row
(
1
,
2
,
3
),
row
(
'a'
,
1.5
,
3
),
row
(
'a'
,
'a'
,
'a'
));
select
row
(
'a'
,
0
,
3
)
IN
(
row
(
3
,
2
,
3
),
row
(
'a'
,
'0'
,
'3'
),
row
(
1
,
3
,
3
));
select
row
(
'a'
,
0
,
3
)
IN
(
row
(
3
,
2
,
3
),
row
(
'a'
,
'a'
,
'3'
),
row
(
1
,
3
,
3
));
select
row
(
'a'
,
1.5
,
3
)
IN
(
row
(
3
,
NULL
,
3
),
row
(
'a'
,
1.5
,
3
),
row
(
1
,
3
,
3
));
select
row
(
'b'
,
1.5
,
3
)
IN
(
row
(
3
,
NULL
,
3
),
row
(
'a'
,
1.5
,
3
),
row
(
1
,
3
,
3
));
select
row
(
1
,
2
,
row
(
3
,
4
))
IN
(
row
(
3
,
2
,
row
(
3
,
4
)),
row
(
1
,
2
,
row
(
3
,
4
)));
--
error
1239
select
row
(
1
,
2
,
row
(
3
,
4
))
IN
(
row
(
3
,
2
,
row
(
3
,
4
)),
row
(
1
,
2
,
4
));
select
row
(
1
,
2
,
row
(
3
,
4
))
IN
(
row
(
3
,
2
,
row
(
3
,
4
)),
row
(
1
,
2
,
row
(
3
,
NULL
)));
SELECT
ROW
(
1
,
2
,
3
)
=
ROW
(
1
,
2
,
3
);
SELECT
ROW
(
2
,
2
,
3
)
=
ROW
(
1
+
1
,
2
,
3
);
SELECT
ROW
(
1
,
2
,
3
)
=
ROW
(
1
+
1
,
2
,
3
);
...
...
@@ -12,12 +26,21 @@ SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5));
SELECT
ROW
(
'test'
,
2
,
3.33
)
=
ROW
(
'test'
,
2
,
3.33
);
--
error
1239
SELECT
ROW
(
'test'
,
2
,
3.33
)
=
ROW
(
'test'
,
2
,
3.33
,
4
);
SELECT
ROW
(
'test'
,
2
,
ROW
(
3
,
33
))
=
ROW
(
'test'
,
2
,
ROW
(
3
,
33
));
SELECT
ROW
(
'test'
,
2
,
ROW
(
3
,
33
))
=
ROW
(
'test'
,
2
,
ROW
(
3
,
3
));
SELECT
ROW
(
'test'
,
2
,
ROW
(
3
,
33
))
=
ROW
(
'test'
,
2
,
ROW
(
3
,
NULL
));
--
error
1239
SELECT
ROW
(
'test'
,
2
,
ROW
(
3
,
33
))
=
ROW
(
'test'
,
2
,
4
);
drop
table
if
exists
t1
;
create
table
t1
(
a
int
,
b
int
,
c
int
);
insert
into
t1
values
(
1
,
2
,
3
),
(
2
,
3
,
1
),
(
3
,
2
,
1
);
insert
into
t1
values
(
1
,
2
,
3
),
(
2
,
3
,
1
),
(
3
,
2
,
1
)
,
(
1
,
2
,
NULL
)
;
select
*
from
t1
where
ROW
(
1
,
2
,
3
)
=
ROW
(
a
,
b
,
c
);
select
*
from
t1
where
ROW
(
0
,
2
,
3
)
=
ROW
(
a
,
b
,
c
);
select
*
from
t1
where
ROW
(
1
,
2
,
3
)
<
ROW
(
a
,
b
,
c
);
select
ROW
(
a
,
2
,
3
)
IN
(
row
(
1
,
b
,
c
),
row
(
2
,
3
,
1
))
from
t1
;
select
ROW
(
c
,
2
,
3
)
IN
(
row
(
1
,
b
,
a
),
row
(
2
,
3
,
1
))
from
t1
;
select
ROW
(
a
,
b
,
c
)
IN
(
row
(
1
,
2
,
3
),
row
(
3
,
2
,
1
))
from
t1
;
select
ROW
(
1
,
2
,
3
)
IN
(
row
(
a
,
b
,
c
),
row
(
1
,
2
,
3
))
from
t1
;
drop
table
t1
;
--
error
1239
...
...
sql/item_cmpfunc.cc
View file @
2885d552
...
...
@@ -144,7 +144,14 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
}
if
((
comparators
=
(
Arg_comparator
*
)
sql_alloc
(
sizeof
(
Arg_comparator
)
*
n
)))
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
if
((
*
a
)
->
el
(
i
)
->
cols
()
!=
(
*
b
)
->
el
(
i
)
->
cols
())
{
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
(
*
a
)
->
el
(
i
)
->
cols
());
return
1
;
}
comparators
[
i
].
set_cmp_func
(
owner
,
(
*
a
)
->
addr
(
i
),
(
*
b
)
->
addr
(
i
));
}
else
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
...
...
@@ -1047,6 +1054,11 @@ static int cmp_double(double *a,double *b)
return
*
a
<
*
b
?
-
1
:
*
a
==
*
b
?
0
:
1
;
}
static
int
cmp_row
(
cmp_item_row
*
a
,
cmp_item_row
*
b
)
{
return
a
->
compare
(
b
);
}
int
in_vector
::
find
(
Item
*
item
)
{
byte
*
result
=
get_value
(
item
);
...
...
@@ -1069,7 +1081,6 @@ int in_vector::find(Item *item)
return
(
int
)
((
*
compare
)(
base
+
start
*
size
,
result
)
==
0
);
}
in_string
::
in_string
(
uint
elements
,
qsort_cmp
cmp_func
)
:
in_vector
(
elements
,
sizeof
(
String
),
cmp_func
),
tmp
(
buff
,
sizeof
(
buff
),
default_charset_info
)
{}
...
...
@@ -1096,6 +1107,29 @@ byte *in_string::get_value(Item *item)
return
(
byte
*
)
item
->
val_str
(
&
tmp
);
}
in_row
::
in_row
(
uint
elements
,
Item
*
item
)
{
DBUG_ENTER
(
"in_row::in_row"
);
base
=
(
char
*
)
new
cmp_item_row
[
elements
];
size
=
sizeof
(
cmp_item_row
);
compare
=
(
qsort_cmp
)
cmp_row
;
tmp
.
store_value
(
item
);
DBUG_VOID_RETURN
;
}
byte
*
in_row
::
get_value
(
Item
*
item
)
{
tmp
.
store_value
(
item
);
return
(
byte
*
)
&
tmp
;
}
void
in_row
::
set
(
uint
pos
,
Item
*
item
)
{
DBUG_ENTER
(
"in_row::set"
);
DBUG_PRINT
(
"enter"
,
(
"pos %u item 0x%lx"
,
pos
,
(
ulong
)
item
));
((
cmp_item_row
*
)
base
)[
pos
].
store_value_by_template
(
&
tmp
,
item
);
DBUG_VOID_RETURN
;
}
in_longlong
::
in_longlong
(
uint
elements
)
:
in_vector
(
elements
,
sizeof
(
longlong
),(
qsort_cmp
)
cmp_longlong
)
...
...
@@ -1108,13 +1142,12 @@ void in_longlong::set(uint pos,Item *item)
byte
*
in_longlong
::
get_value
(
Item
*
item
)
{
tmp
=
item
->
val_int
();
tmp
=
item
->
val_int
();
if
(
item
->
null_value
)
return
0
;
/* purecov: inspected */
return
0
;
return
(
byte
*
)
&
tmp
;
}
in_double
::
in_double
(
uint
elements
)
:
in_vector
(
elements
,
sizeof
(
double
),(
qsort_cmp
)
cmp_double
)
{}
...
...
@@ -1126,12 +1159,146 @@ void in_double::set(uint pos,Item *item)
byte
*
in_double
::
get_value
(
Item
*
item
)
{
tmp
=
item
->
val
();
tmp
=
item
->
val
();
if
(
item
->
null_value
)
return
0
;
/* purecov: inspected */
return
(
byte
*
)
&
tmp
;
}
cmp_item
*
cmp_item
::
get_comparator
(
Item
*
item
)
{
switch
(
item
->
result_type
())
{
case
STRING_RESULT
:
if
(
item
->
binary
())
return
new
cmp_item_binary_string
;
else
return
new
cmp_item_sort_string
;
break
;
case
INT_RESULT
:
return
new
cmp_item_int
;
break
;
case
REAL_RESULT
:
return
new
cmp_item_real
;
break
;
case
ROW_RESULT
:
return
new
cmp_item_row
;
break
;
}
return
0
;
// to satisfy compiler :)
}
cmp_item
*
cmp_item_sort_string
::
make_same
()
{
return
new
cmp_item_sort_string_in_static
();
}
cmp_item
*
cmp_item_binary_string
::
make_same
()
{
return
new
cmp_item_binary_string_in_static
();
}
cmp_item
*
cmp_item_int
::
make_same
()
{
return
new
cmp_item_int
();
}
cmp_item
*
cmp_item_real
::
make_same
()
{
return
new
cmp_item_real
();
}
cmp_item
*
cmp_item_row
::
make_same
()
{
return
new
cmp_item_row
();
}
void
cmp_item_row
::
store_value
(
Item
*
item
)
{
n
=
item
->
cols
();
if
((
comparators
=
(
cmp_item
**
)
sql_alloc
(
sizeof
(
cmp_item
*
)
*
n
)))
{
item
->
null_value
=
0
;
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
((
comparators
[
i
]
=
cmp_item
::
get_comparator
(
item
->
el
(
i
))))
{
comparators
[
i
]
->
store_value
(
item
->
el
(
i
));
item
->
null_value
|=
item
->
el
(
i
)
->
null_value
;
}
else
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
current_thd
->
fatal_error
=
1
;
return
;
}
}
else
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
current_thd
->
fatal_error
=
1
;
return
;
}
}
void
cmp_item_row
::
store_value_by_template
(
cmp_item
*
t
,
Item
*
item
)
{
cmp_item_row
*
tmpl
=
(
cmp_item_row
*
)
t
;
if
(
tmpl
->
n
!=
item
->
cols
())
{
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
tmpl
->
n
);
return
;
}
n
=
tmpl
->
n
;
if
((
comparators
=
(
cmp_item
**
)
sql_alloc
(
sizeof
(
cmp_item
*
)
*
n
)))
{
item
->
null_value
=
0
;
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
((
comparators
[
i
]
=
tmpl
->
comparators
[
i
]
->
make_same
()))
{
comparators
[
i
]
->
store_value_by_template
(
tmpl
->
comparators
[
i
],
item
->
el
(
i
));
item
->
null_value
|=
item
->
el
(
i
)
->
null_value
;
}
else
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
current_thd
->
fatal_error
=
1
;
return
;
}
}
else
{
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
current_thd
->
fatal_error
=
1
;
return
;
}
}
int
cmp_item_row
::
cmp
(
Item
*
arg
)
{
arg
->
null_value
=
0
;
if
(
arg
->
cols
()
!=
n
)
{
my_error
(
ER_CARDINALITY_COL
,
MYF
(
0
),
n
);
return
1
;
}
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
(
comparators
[
i
]
->
cmp
(
arg
->
el
(
i
)))
{
arg
->
null_value
|=
arg
->
el
(
i
)
->
null_value
;
return
1
;
}
return
0
;
}
int
cmp_item_row
::
compare
(
cmp_item
*
c
)
{
int
res
;
cmp_item_row
*
cmp
=
(
cmp_item_row
*
)
c
;
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
((
res
=
comparators
[
i
]
->
compare
(
cmp
->
comparators
[
i
])))
return
res
;
return
0
;
}
void
Item_func_in
::
fix_length_and_dec
()
{
...
...
@@ -1151,8 +1318,7 @@ void Item_func_in::fix_length_and_dec()
array
=
new
in_double
(
arg_count
);
break
;
case
ROW_RESULT
:
// This case should never be choosen
DBUG_ASSERT
(
0
);
array
=
new
in_row
(
arg_count
,
item
);
break
;
}
uint
j
=
0
;
...
...
@@ -1169,24 +1335,7 @@ void Item_func_in::fix_length_and_dec()
}
else
{
switch
(
item
->
result_type
())
{
case
STRING_RESULT
:
if
(
item
->
binary
())
in_item
=
new
cmp_item_binary_string
;
else
in_item
=
new
cmp_item_sort_string
;
break
;
case
INT_RESULT
:
in_item
=
new
cmp_item_int
;
break
;
case
REAL_RESULT
:
in_item
=
new
cmp_item_real
;
break
;
case
ROW_RESULT
:
// This case should never be choosen
DBUG_ASSERT
(
0
);
break
;
}
in_item
=
cmp_item
::
get_comparator
(
item
);
}
maybe_null
=
item
->
maybe_null
;
max_length
=
2
;
...
...
sql/item_cmpfunc.h
View file @
2885d552
...
...
@@ -17,6 +17,8 @@
/* compare and test functions */
#include "assert.h"
#ifdef __GNUC__
#pragma interface
/* gcc class implementation */
#endif
...
...
@@ -38,16 +40,12 @@ class Arg_comparator: public Sql_alloc
Arg_comparator
()
{};
Arg_comparator
(
Item
**
a1
,
Item
**
a2
)
:
a
(
a1
),
b
(
a2
)
{};
inline
void
seta
(
Item
**
item
)
{
a
=
item
;
}
inline
void
setb
(
Item
**
item
)
{
b
=
item
;
}
int
set_compare_func
(
Item_bool_func2
*
owner
,
Item_result
type
);
inline
int
set_compare_func
(
Item_bool_func2
*
owner
)
{
return
set_compare_func
(
owner
,
item_cmp_type
((
*
a
)
->
result_type
(),
(
*
b
)
->
result_type
()));
}
inline
int
set_cmp_func
(
Item_bool_func2
*
owner
,
Item
**
a1
,
Item
**
a2
,
Item_result
type
)
...
...
@@ -379,6 +377,7 @@ class in_vector :public Sql_alloc
uint
count
;
public:
uint
used_count
;
in_vector
()
{}
in_vector
(
uint
elements
,
uint
element_length
,
qsort_cmp
cmp_func
)
:
base
((
char
*
)
sql_calloc
(
elements
*
element_length
)),
size
(
element_length
),
compare
(
cmp_func
),
count
(
elements
),
...
...
@@ -393,7 +392,6 @@ class in_vector :public Sql_alloc
int
find
(
Item
*
item
);
};
class
in_string
:
public
in_vector
{
char
buff
[
80
];
...
...
@@ -405,7 +403,6 @@ class in_string :public in_vector
byte
*
get_value
(
Item
*
item
);
};
class
in_longlong
:
public
in_vector
{
longlong
tmp
;
...
...
@@ -415,7 +412,6 @@ class in_longlong :public in_vector
byte
*
get_value
(
Item
*
item
);
};
class
in_double
:
public
in_vector
{
double
tmp
;
...
...
@@ -425,7 +421,6 @@ class in_double :public in_vector
byte
*
get_value
(
Item
*
item
);
};
/*
** Classes for easy comparing of non const items
*/
...
...
@@ -435,74 +430,191 @@ class cmp_item :public Sql_alloc
public:
cmp_item
()
{}
virtual
~
cmp_item
()
{}
virtual
void
store_value
(
Item
*
item
)
=
0
;
virtual
int
cmp
(
Item
*
item
)
=
0
;
virtual
void
store_value
(
Item
*
item
)
=
0
;
virtual
int
cmp
(
Item
*
item
)
=
0
;
// for optimized IN with row
virtual
int
compare
(
cmp_item
*
item
)
=
0
;
static
cmp_item
*
get_comparator
(
Item
*
);
virtual
cmp_item
*
make_same
()
=
0
;
virtual
void
store_value_by_template
(
cmp_item
*
tmpl
,
Item
*
item
)
{
store_value
(
item
);
}
};
class
cmp_item_string
:
public
cmp_item
{
protected:
String
*
value_res
;
public:
friend
class
cmp_item_sort_string
;
friend
class
cmp_item_binary_string
;
friend
class
cmp_item_sort_string_in_static
;
friend
class
cmp_item_binary_string_in_static
;
};
class
cmp_item_sort_string
:
public
cmp_item
{
protected:
class
cmp_item_sort_string
:
public
cmp_item_string
{
protected:
char
value_buff
[
80
];
String
value
,
*
value_res
;
String
value
;
public:
cmp_item_sort_string
()
:
value
(
value_buff
,
sizeof
(
value_buff
),
default_charset_info
)
{}
cmp_item_sort_string
()
:
value
(
value_buff
,
sizeof
(
value_buff
),
default_charset_info
)
{}
void
store_value
(
Item
*
item
)
{
value_res
=
item
->
val_str
(
&
value
);
}
{
value_res
=
item
->
val_str
(
&
value
);
}
int
cmp
(
Item
*
arg
)
{
char
buff
[
80
];
String
tmp
(
buff
,
sizeof
(
buff
),
default_charset_info
),
*
res
;
if
(
!
(
res
=
arg
->
val_str
(
&
tmp
)))
return
1
;
/* Can't be right */
return
sortcmp
(
value_res
,
res
);
}
{
char
buff
[
80
];
String
tmp
(
buff
,
sizeof
(
buff
),
default_charset_info
),
*
res
;
if
(
!
(
res
=
arg
->
val_str
(
&
tmp
)))
return
1
;
/* Can't be right */
return
sortcmp
(
value_res
,
res
);
}
int
compare
(
cmp_item
*
c
)
{
cmp_item_string
*
cmp
=
(
cmp_item_string
*
)
c
;
return
sortcmp
(
value_res
,
cmp
->
value_res
);
}
cmp_item
*
make_same
();
};
class
cmp_item_binary_string
:
public
cmp_item_sort_string
{
public:
cmp_item_binary_string
()
{}
int
cmp
(
Item
*
arg
)
{
char
buff
[
80
];
String
tmp
(
buff
,
sizeof
(
buff
),
default_charset_info
),
*
res
;
if
(
!
(
res
=
arg
->
val_str
(
&
tmp
)))
return
1
;
/* Can't be right */
return
stringcmp
(
value_res
,
res
);
}
{
char
buff
[
80
];
String
tmp
(
buff
,
sizeof
(
buff
),
default_charset_info
),
*
res
;
if
(
!
(
res
=
arg
->
val_str
(
&
tmp
)))
return
1
;
/* Can't be right */
return
stringcmp
(
value_res
,
res
);
}
int
compare
(
cmp_item
*
c
)
{
cmp_item_string
*
cmp
=
(
cmp_item_string
*
)
c
;
return
stringcmp
(
value_res
,
cmp
->
value_res
);
}
cmp_item
*
make_same
();
};
class
cmp_item_int
:
public
cmp_item
{
longlong
value
;
public:
void
store_value
(
Item
*
item
)
{
value
=
item
->
val_int
();
}
{
value
=
item
->
val_int
();
}
int
cmp
(
Item
*
arg
)
{
return
value
!=
arg
->
val_int
();
}
{
return
value
!=
arg
->
val_int
();
}
int
compare
(
cmp_item
*
c
)
{
cmp_item_int
*
cmp
=
(
cmp_item_int
*
)
c
;
return
(
value
<
cmp
->
value
)
?
-
1
:
((
value
==
cmp
->
value
)
?
0
:
1
);
}
cmp_item
*
make_same
();
};
class
cmp_item_real
:
public
cmp_item
{
double
value
;
public:
void
store_value
(
Item
*
item
)
{
value
=
item
->
val
();
}
{
value
=
item
->
val
();
}
int
cmp
(
Item
*
arg
)
{
return
value
!=
arg
->
val
();
}
{
return
value
!=
arg
->
val
();
}
int
compare
(
cmp_item
*
c
)
{
cmp_item_real
*
cmp
=
(
cmp_item_real
*
)
c
;
return
(
value
<
cmp
->
value
)
?
-
1
:
((
value
==
cmp
->
value
)
?
0
:
1
);
}
cmp_item
*
make_same
();
};
class
cmp_item_row
:
public
cmp_item
{
cmp_item
**
comparators
;
uint
n
;
public:
cmp_item_row
()
:
comparators
(
0
),
n
(
0
)
{}
~
cmp_item_row
()
{
if
(
comparators
)
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
if
(
comparators
[
i
])
delete
comparators
[
i
];
}
void
store_value
(
Item
*
item
);
int
cmp
(
Item
*
arg
);
int
compare
(
cmp_item
*
arg
);
cmp_item
*
make_same
();
void
store_value_by_template
(
cmp_item
*
tmpl
,
Item
*
);
};
class
in_row
:
public
in_vector
{
cmp_item_row
tmp
;
public:
in_row
(
uint
elements
,
Item
*
);
void
set
(
uint
pos
,
Item
*
item
);
byte
*
get_value
(
Item
*
item
);
};
/*
cmp_item for optimized IN with row (right part string, which never
be changed)
*/
class
cmp_item_sort_string_in_static
:
public
cmp_item_string
{
protected:
String
value
;
public:
cmp_item_sort_string_in_static
()
{}
void
store_value
(
Item
*
item
)
{
value_res
=
item
->
val_str
(
&
value
);
}
int
cmp
(
Item
*
item
)
{
// Should never be called
DBUG_ASSERT
(
0
);
return
1
;
}
int
compare
(
cmp_item
*
c
)
{
cmp_item_string
*
cmp
=
(
cmp_item_string
*
)
c
;
return
sortcmp
(
value_res
,
cmp
->
value_res
);
}
cmp_item
*
make_same
()
{
return
new
cmp_item_sort_string_in_static
();
}
};
class
cmp_item_binary_string_in_static
:
public
cmp_item_sort_string_in_static
{
public:
cmp_item_binary_string_in_static
()
{}
int
compare
(
cmp_item
*
c
)
{
cmp_item_string
*
cmp
=
(
cmp_item_string
*
)
c
;
return
stringcmp
(
value_res
,
cmp
->
value_res
);
}
cmp_item
*
make_same
()
{
return
new
cmp_item_binary_string_in_static
();
}
};
class
Item_func_in
:
public
Item_int_func
{
...
...
@@ -512,12 +624,15 @@ class Item_func_in :public Item_int_func
bool
have_null
;
public:
Item_func_in
(
Item
*
a
,
List
<
Item
>
&
list
)
:
Item_int_func
(
list
),
item
(
a
),
array
(
0
),
in_item
(
0
),
have_null
(
0
)
{}
:
Item_int_func
(
list
),
item
(
a
),
array
(
0
),
in_item
(
0
),
have_null
(
0
)
{
allowed_arg_cols
=
item
->
cols
();
}
longlong
val_int
();
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
)
{
bool
res
=
(
item
->
check_cols
(
1
)
||
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
// We do not check item->cols(), because allowed_arg_cols assigned from it
bool
res
=
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
with_sum_func
=
with_sum_func
||
item
->
with_sum_func
;
return
res
;
...
...
@@ -541,8 +656,6 @@ class Item_func_in :public Item_int_func
}
};
/* Functions used by where clause */
class
Item_func_isnull
:
public
Item_bool_func
...
...
sql/item_row.cc
View file @
2885d552
...
...
@@ -18,8 +18,10 @@
#include "assert.h"
Item_row
::
Item_row
(
List
<
Item
>
&
arg
)
:
Item
(),
array_holder
(
1
)
Item
(),
array_holder
(
1
)
,
used_tables_cache
(
0
),
const_item_cache
(
1
)
{
//TODO: think placing 2-3 component items in item (as it done for function)
if
((
arg_count
=
arg
.
elements
))
items
=
(
Item
**
)
sql_alloc
(
sizeof
(
Item
*
)
*
arg_count
);
else
...
...
@@ -45,16 +47,31 @@ void Item_row::illegal_method_call(const char *method)
bool
Item_row
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tabl
,
Item
**
ref
)
{
tables
=
0
;
null_value
=
0
;
maybe_null
=
0
;
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
items
[
i
]
->
fix_fields
(
thd
,
tabl
,
items
+
i
))
return
1
;
tables
|=
items
[
i
]
->
used_tables
();
used_tables_cache
|=
items
[
i
]
->
used_tables
();
const_item_cache
&=
items
[
i
]
->
const_item
();
maybe_null
|=
items
[
i
]
->
maybe_null
;
}
return
0
;
}
void
Item_row
::
update_used_tables
()
{
used_tables_cache
=
0
;
const_item_cache
=
1
;
for
(
uint
i
=
0
;
i
<
arg_count
;
i
++
)
{
items
[
i
]
->
update_used_tables
();
used_tables_cache
|=
items
[
i
]
->
used_tables
();
const_item_cache
&=
items
[
i
]
->
const_item
();
}
}
bool
Item_row
::
check_cols
(
uint
c
)
{
if
(
c
!=
arg_count
)
...
...
sql/item_row.h
View file @
2885d552
...
...
@@ -17,13 +17,17 @@
class
Item_row
:
public
Item
{
bool
array_holder
;
table_map
tables
;
table_map
used_tables_cache
;
bool
const_item_cache
;
uint
arg_count
;
Item
**
items
;
public:
Item_row
(
List
<
Item
>
&
);
Item_row
(
Item_row
*
item
)
:
Item
(),
array_holder
(
0
),
tables
(
item
->
tables
),
arg_count
(
item
->
arg_count
),
Item
(),
array_holder
(
0
),
used_tables_cache
(
item
->
used_tables_cache
),
const_item_cache
(
item
->
const_item_cache
),
arg_count
(
item
->
arg_count
),
items
(
item
->
items
)
{}
...
...
@@ -56,8 +60,10 @@ class Item_row: public Item
return
0
;
};
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
);
table_map
used_tables
()
const
{
return
tables
;
};
table_map
used_tables
()
const
{
return
used_tables_cache
;
};
bool
const_item
()
const
{
return
const_item_cache
;
};
enum
Item_result
result_type
()
const
{
return
ROW_RESULT
;
}
void
update_used_tables
();
virtual
uint
cols
()
{
return
arg_count
;
}
virtual
Item
*
el
(
uint
i
)
{
return
items
[
i
];
}
...
...
sql/sql_list.h
View file @
2885d552
...
...
@@ -25,8 +25,16 @@
class
Sql_alloc
{
public:
static
void
*
operator
new
(
size_t
size
)
{
return
(
void
*
)
sql_alloc
((
uint
)
size
);
}
static
void
*
operator
new
(
size_t
size
)
{
return
(
void
*
)
sql_alloc
((
uint
)
size
);
}
static
void
*
operator
new
[](
size_t
size
)
{
return
(
void
*
)
sql_alloc
((
uint
)
size
);
}
static
void
operator
delete
(
void
*
ptr
,
size_t
size
)
{}
/*lint -e715 */
static
void
operator
delete
[](
void
*
ptr
,
size_t
size
)
{}
#ifdef HAVE_purify
bool
dummy
;
inline
Sql_alloc
()
:
dummy
(
0
)
{}
...
...
sql/sql_select.cc
View file @
2885d552
...
...
@@ -791,6 +791,16 @@ JOIN::exec()
HA_POS_ERROR
)))
DBUG_VOID_RETURN
;
/*
We don't have to store rows in temp table that doesn't match HAVING if:
- we are sorting the table and writing complete group rows to the
temp table.
- We are using DISTINCT without resolving the distinct as a GROUP BY
on all columns.
If having is not handled here, it will be checked before the row
is sent to the client.
*/
if
(
having_list
&&
(
sort_and_group
||
(
exec_tmp_table
->
distinct
&&
!
group_list
)))
having
=
having_list
;
...
...
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