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
e08ed8a5
Commit
e08ed8a5
authored
Nov 09, 2002
by
monty@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed bug in MAX() optimization when used with JOIN and ON expressions
parent
0f14b3c2
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
131 additions
and
2 deletions
+131
-2
mysql-test/r/group_by.result
mysql-test/r/group_by.result
+36
-1
mysql-test/t/group_by.test
mysql-test/t/group_by.test
+40
-1
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+39
-0
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+3
-0
sql/opt_sum.cc
sql/opt_sum.cc
+13
-0
No files found.
mysql-test/r/group_by.result
View file @
e08ed8a5
drop table if exists t1,t2;
drop table if exists t1,t2
,t3
;
CREATE TABLE t1 (
spID int(10) unsigned,
userID int(10) unsigned,
...
...
@@ -417,3 +417,38 @@ xID xID1 Level
3 134 ***
4 185 ****
drop table t1;
CREATE TABLE t1 (
pid int(11) unsigned NOT NULL default '0',
c1id int(11) unsigned default NULL,
c2id int(11) unsigned default NULL,
value int(11) unsigned NOT NULL default '0',
UNIQUE KEY pid2 (pid,c1id,c2id),
UNIQUE KEY pid (pid,value)
) TYPE=MyISAM;
INSERT INTO t1 VALUES (1, 1, NULL, 1),(1, 2, NULL, 2),(1, NULL, 3, 3),(1, 4, NULL, 4),(1, 5, NULL, 5);
CREATE TABLE t2 (
id int(11) unsigned NOT NULL default '0',
active enum('Yes','No') NOT NULL default 'Yes',
PRIMARY KEY (id)
) TYPE=MyISAM;
INSERT INTO t2 VALUES (1, 'Yes'),(2, 'No'),(4, 'Yes'),(5, 'No');
CREATE TABLE t3 (
id int(11) unsigned NOT NULL default '0',
active enum('Yes','No') NOT NULL default 'Yes',
PRIMARY KEY (id)
);
INSERT INTO t3 VALUES (3, 'Yes');
select * from t1 AS m LEFT JOIN t2 AS c1 ON m.c1id =
c1.id AND c1.active = 'Yes' LEFT JOIN t3 AS c2 ON m.c2id = c2.id AND
c2.active = 'Yes' WHERE m.pid=1 AND (c1.id IS NOT NULL OR c2.id IS NOT NULL);
pid c1id c2id value id active id active
1 1 NULL 1 1 Yes NULL NULL
1 NULL 3 3 NULL NULL 3 Yes
1 4 NULL 4 4 Yes NULL NULL
select max(value) from t1 AS m LEFT JOIN t2 AS c1 ON
m.c1id = c1.id AND c1.active = 'Yes' LEFT JOIN t3 AS c2 ON m.c2id =
c2.id AND c2.active = 'Yes' WHERE m.pid=1 AND (c1.id IS NOT NULL OR c2.id IS
NOT NULL);
max(value)
4
drop table t1,t2,t3;
mysql-test/t/group_by.test
View file @
e08ed8a5
...
...
@@ -2,7 +2,7 @@
# Test of group (Failed for Lars Hoss <lh@pbm.de>)
#
drop
table
if
exists
t1
,
t2
;
drop
table
if
exists
t1
,
t2
,
t3
;
CREATE
TABLE
t1
(
spID
int
(
10
)
unsigned
,
userID
int
(
10
)
unsigned
,
...
...
@@ -312,3 +312,42 @@ insert into t1 values (1,244,NULL),(2,243,NULL),(134,223,NULL),(185,186,NULL);
select
S
.
ID
as
xID
,
S
.
ID1
as
xID1
from
t1
as
S
left
join
t1
as
yS
on
S
.
ID1
between
yS
.
ID1
and
yS
.
ID2
;
select
S
.
ID
as
xID
,
S
.
ID1
as
xID1
,
repeat
(
'*'
,
count
(
distinct
yS
.
ID
))
as
Level
from
t1
as
S
left
join
t1
as
yS
on
S
.
ID1
between
yS
.
ID1
and
yS
.
ID2
group
by
xID
order
by
xID1
;
drop
table
t1
;
#
# Problem with MAX and LEFT JOIN
#
CREATE
TABLE
t1
(
pid
int
(
11
)
unsigned
NOT
NULL
default
'0'
,
c1id
int
(
11
)
unsigned
default
NULL
,
c2id
int
(
11
)
unsigned
default
NULL
,
value
int
(
11
)
unsigned
NOT
NULL
default
'0'
,
UNIQUE
KEY
pid2
(
pid
,
c1id
,
c2id
),
UNIQUE
KEY
pid
(
pid
,
value
)
)
TYPE
=
MyISAM
;
INSERT
INTO
t1
VALUES
(
1
,
1
,
NULL
,
1
),(
1
,
2
,
NULL
,
2
),(
1
,
NULL
,
3
,
3
),(
1
,
4
,
NULL
,
4
),(
1
,
5
,
NULL
,
5
);
CREATE
TABLE
t2
(
id
int
(
11
)
unsigned
NOT
NULL
default
'0'
,
active
enum
(
'Yes'
,
'No'
)
NOT
NULL
default
'Yes'
,
PRIMARY
KEY
(
id
)
)
TYPE
=
MyISAM
;
INSERT
INTO
t2
VALUES
(
1
,
'Yes'
),(
2
,
'No'
),(
4
,
'Yes'
),(
5
,
'No'
);
CREATE
TABLE
t3
(
id
int
(
11
)
unsigned
NOT
NULL
default
'0'
,
active
enum
(
'Yes'
,
'No'
)
NOT
NULL
default
'Yes'
,
PRIMARY
KEY
(
id
)
);
INSERT
INTO
t3
VALUES
(
3
,
'Yes'
);
select
*
from
t1
AS
m
LEFT
JOIN
t2
AS
c1
ON
m
.
c1id
=
c1
.
id
AND
c1
.
active
=
'Yes'
LEFT
JOIN
t3
AS
c2
ON
m
.
c2id
=
c2
.
id
AND
c2
.
active
=
'Yes'
WHERE
m
.
pid
=
1
AND
(
c1
.
id
IS
NOT
NULL
OR
c2
.
id
IS
NOT
NULL
);
select
max
(
value
)
from
t1
AS
m
LEFT
JOIN
t2
AS
c1
ON
m
.
c1id
=
c1
.
id
AND
c1
.
active
=
'Yes'
LEFT
JOIN
t3
AS
c2
ON
m
.
c2id
=
c2
.
id
AND
c2
.
active
=
'Yes'
WHERE
m
.
pid
=
1
AND
(
c1
.
id
IS
NOT
NULL
OR
c2
.
id
IS
NOT
NULL
);
drop
table
t1
,
t2
,
t3
;
sql/item_cmpfunc.cc
View file @
e08ed8a5
...
...
@@ -1236,6 +1236,45 @@ longlong Item_cond_or::val_int()
return
0
;
}
/*
Create an AND expression from two expressions
SYNOPSIS
and_expressions()
a expression or NULL
b expression.
org_item Don't modify a if a == *org_item
If a == NULL, org_item is set to point at b,
to ensure that future calls will not modify b.
NOTES
This will not modify item pointed to by org_item or b
The idea is that one can call this in a loop and create and
'and' over all items without modifying any of the original items.
RETURN
NULL Error
Item
*/
Item
*
and_expressions
(
Item
*
a
,
Item
*
b
,
Item
**
org_item
)
{
if
(
!
a
)
return
(
*
org_item
=
(
Item
*
)
b
);
if
(
a
==
*
org_item
)
{
Item_cond
*
res
;
if
((
res
=
new
Item_cond_and
(
a
,
(
Item
*
)
b
)))
res
->
used_tables_cache
=
a
->
used_tables
()
|
b
->
used_tables
();
return
res
;
}
if
(((
Item_cond_and
*
)
a
)
->
add
((
Item
*
)
b
))
return
0
;
((
Item_cond_and
*
)
a
)
->
used_tables_cache
|=
b
->
used_tables
();
return
a
;
}
longlong
Item_func_isnull
::
val_int
()
{
/*
...
...
sql/item_cmpfunc.h
View file @
e08ed8a5
...
...
@@ -621,3 +621,6 @@ public:
longlong
val_int
();
const
char
*
func_name
()
const
{
return
"xor"
;
}
};
Item
*
and_expressions
(
Item
*
a
,
Item
*
b
,
Item
**
org_item
);
sql/opt_sum.cc
View file @
e08ed8a5
...
...
@@ -37,6 +37,19 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
bool
recalc_const_item
=
0
;
table_map
removed_tables
=
0
;
Item
*
item
;
COND
*
org_conds
=
conds
;
/* Add all ON conditions to WHERE condition */
for
(
TABLE_LIST
*
tl
=
tables
;
tl
;
tl
=
tl
->
next
)
{
if
(
tl
->
on_expr
)
conds
=
and_expressions
(
conds
,
tl
->
on_expr
,
&
org_conds
);
}
/*
Iterate through item is select part and replace COUNT(), MIN() and MAX()
with constants (if possible)
*/
while
((
item
=
it
++
))
{
...
...
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