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
3d067e7d
Commit
3d067e7d
authored
Feb 03, 2003
by
monty@mashka.mysql.fi
Browse files
Options
Browse Files
Download
Plain Diff
Merge work:/my/mysql-4.0 into mashka.mysql.fi:/home/my/mysql-4.0
parents
50ca3ba7
e3cd6352
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
158 additions
and
27 deletions
+158
-27
configure.in
configure.in
+1
-1
libmysqld/libmysqld.c
libmysqld/libmysqld.c
+1
-1
mysql-test/r/func_group.result
mysql-test/r/func_group.result
+53
-0
mysql-test/t/func_group.test
mysql-test/t/func_group.test
+27
-0
sql/item.h
sql/item.h
+1
-0
sql/item_sum.h
sql/item_sum.h
+2
-0
sql/opt_sum.cc
sql/opt_sum.cc
+67
-25
sql/sql_select.cc
sql/sql_select.cc
+6
-0
No files found.
configure.in
View file @
3d067e7d
...
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
...
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT
(
sql/mysqld.cc
)
AC_INIT
(
sql/mysqld.cc
)
AC_CANONICAL_SYSTEM
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE
(
mysql, 4.0.1
0-gamma
)
AM_INIT_AUTOMAKE
(
mysql, 4.0.1
1
)
AM_CONFIG_HEADER
(
config.h
)
AM_CONFIG_HEADER
(
config.h
)
PROTOCOL_VERSION
=
10
PROTOCOL_VERSION
=
10
...
...
libmysqld/libmysqld.c
View file @
3d067e7d
...
@@ -62,7 +62,7 @@ my_string mysql_unix_port=0;
...
@@ -62,7 +62,7 @@ my_string mysql_unix_port=0;
#define closesocket(A) close(A)
#define closesocket(A) close(A)
#endif
#endif
static
void
mysql_once_init
(
void
);
void
STDCALL
mysql_once_init
(
void
);
static
MYSQL_DATA
*
read_rows
(
MYSQL
*
mysql
,
MYSQL_FIELD
*
fields
,
static
MYSQL_DATA
*
read_rows
(
MYSQL
*
mysql
,
MYSQL_FIELD
*
fields
,
uint
field_count
);
uint
field_count
);
static
int
read_one_row
(
MYSQL
*
mysql
,
uint
fields
,
MYSQL_ROW
row
,
static
int
read_one_row
(
MYSQL
*
mysql
,
uint
fields
,
MYSQL_ROW
row
,
...
...
mysql-test/r/func_group.result
View file @
3d067e7d
...
@@ -151,3 +151,56 @@ sum(num)
...
@@ -151,3 +151,56 @@ sum(num)
45.63
45.63
51.80
51.80
drop table t1;
drop table t1;
create table t1 (a1 int, a2 char(3), key k1(a1), key k2(a2));
insert into t1 values(10,'aaa'), (10,null), (10,'bbb'), (20,'zzz');
create table t2(a1 char(3), a2 int, a3 real, key k1(a1), key k2(a2, a1));
select * from t1;
a1 a2
10 aaa
10 NULL
10 bbb
20 zzz
select min(a2) from t1;
min(a2)
aaa
select max(t1.a1), max(t2.a2) from t1, t2;
max(t1.a1) max(t2.a2)
NULL NULL
select max(t1.a1) from t1, t2;
max(t1.a1)
NULL
select max(t2.a2), max(t1.a1) from t1, t2;
max(t2.a2) max(t1.a1)
NULL NULL
explain select min(a2) from t1;
Comment
Select tables optimized away
explain select max(t1.a1), max(t2.a2) from t1, t2;
Comment
No matching min/max row
insert into t2 values('AAA', 10, 0.5);
select max(t1.a1), max(t2.a1) from t1, t2 where t2.a2=9;
max(t1.a1) max(t2.a1)
NULL NULL
select max(t2.a1), max(t1.a1) from t1, t2 where t2.a2=9;
max(t2.a1) max(t1.a1)
NULL NULL
select t1.a1, t1.a2, t2.a1, t2.a2 from t1 left outer join t2 on t1.a1=10;
a1 a2 a1 a2
10 aaa AAA 10
10 NULL AAA 10
10 bbb AAA 10
20 zzz NULL NULL
select max(t1.a2) from t1 left outer join t2 on t1.a1=10;
max(t1.a2)
zzz
select max(t1.a2) from t1 left outer join t2 on t1.a1=10 where t1.a1=20;
max(t1.a2)
zzz
select max(t1.a2) from t1 left outer join t2 on t1.a1=10 where t1.a1=10;
max(t1.a2)
bbb
select max(t2.a1) from t1 left outer join t2 on t1.a2=t2.a1 and 1=0 where t2.a1='AAA';
max(t2.a1)
NULL
drop table t1,t2;
mysql-test/t/func_group.test
View file @
3d067e7d
...
@@ -99,3 +99,30 @@ insert into t1 values (5.2,'nem'),(8.64,'monty'),(11.12,'sinisa');
...
@@ -99,3 +99,30 @@ insert into t1 values (5.2,'nem'),(8.64,'monty'),(11.12,'sinisa');
select
sum
(
num
)
from
t1
;
select
sum
(
num
)
from
t1
;
select
sum
(
num
)
from
t1
group
by
user
;
select
sum
(
num
)
from
t1
group
by
user
;
drop
table
t1
;
drop
table
t1
;
#
# Test problem with MIN() optimization in case of null values
#
create
table
t1
(
a1
int
,
a2
char
(
3
),
key
k1
(
a1
),
key
k2
(
a2
));
insert
into
t1
values
(
10
,
'aaa'
),
(
10
,
null
),
(
10
,
'bbb'
),
(
20
,
'zzz'
);
create
table
t2
(
a1
char
(
3
),
a2
int
,
a3
real
,
key
k1
(
a1
),
key
k2
(
a2
,
a1
));
select
*
from
t1
;
# The following returned NULL in 4.0.10
select
min
(
a2
)
from
t1
;
select
max
(
t1
.
a1
),
max
(
t2
.
a2
)
from
t1
,
t2
;
select
max
(
t1
.
a1
)
from
t1
,
t2
;
select
max
(
t2
.
a2
),
max
(
t1
.
a1
)
from
t1
,
t2
;
explain
select
min
(
a2
)
from
t1
;
explain
select
max
(
t1
.
a1
),
max
(
t2
.
a2
)
from
t1
,
t2
;
insert
into
t2
values
(
'AAA'
,
10
,
0.5
);
select
max
(
t1
.
a1
),
max
(
t2
.
a1
)
from
t1
,
t2
where
t2
.
a2
=
9
;
select
max
(
t2
.
a1
),
max
(
t1
.
a1
)
from
t1
,
t2
where
t2
.
a2
=
9
;
select
t1
.
a1
,
t1
.
a2
,
t2
.
a1
,
t2
.
a2
from
t1
left
outer
join
t2
on
t1
.
a1
=
10
;
select
max
(
t1
.
a2
)
from
t1
left
outer
join
t2
on
t1
.
a1
=
10
;
select
max
(
t1
.
a2
)
from
t1
left
outer
join
t2
on
t1
.
a1
=
10
where
t1
.
a1
=
20
;
select
max
(
t1
.
a2
)
from
t1
left
outer
join
t2
on
t1
.
a1
=
10
where
t1
.
a1
=
10
;
select
max
(
t2
.
a1
)
from
t1
left
outer
join
t2
on
t1
.
a2
=
t2
.
a1
and
1
=
0
where
t2
.
a1
=
'AAA'
;
drop
table
t1
,
t2
;
sql/item.h
View file @
3d067e7d
...
@@ -89,6 +89,7 @@ public:
...
@@ -89,6 +89,7 @@ public:
virtual
void
set_result_field
(
Field
*
field
)
{}
virtual
void
set_result_field
(
Field
*
field
)
{}
virtual
bool
is_result_field
()
{
return
0
;
}
virtual
bool
is_result_field
()
{
return
0
;
}
virtual
void
save_in_result_field
(
bool
no_conversions
)
{}
virtual
void
save_in_result_field
(
bool
no_conversions
)
{}
virtual
void
no_rows_in_result
()
{}
};
};
...
...
sql/item_sum.h
View file @
3d067e7d
...
@@ -69,6 +69,7 @@ public:
...
@@ -69,6 +69,7 @@ public:
void
make_field
(
Send_field
*
field
);
void
make_field
(
Send_field
*
field
);
void
print
(
String
*
str
);
void
print
(
String
*
str
);
void
fix_num_length_and_dec
();
void
fix_num_length_and_dec
();
void
no_rows_in_result
()
{
reset
();
}
virtual
bool
setup
(
THD
*
thd
)
{
return
0
;}
virtual
bool
setup
(
THD
*
thd
)
{
return
0
;}
unsigned
int
size_of
()
{
return
sizeof
(
*
this
);}
unsigned
int
size_of
()
{
return
sizeof
(
*
this
);}
};
};
...
@@ -135,6 +136,7 @@ class Item_sum_count :public Item_sum_int
...
@@ -135,6 +136,7 @@ class Item_sum_count :public Item_sum_int
bool
const_item
()
const
{
return
!
used_table_cache
;
}
bool
const_item
()
const
{
return
!
used_table_cache
;
}
enum
Sumfunctype
sum_func
()
const
{
return
COUNT_FUNC
;
}
enum
Sumfunctype
sum_func
()
const
{
return
COUNT_FUNC
;
}
void
reset
();
void
reset
();
void
no_rows_in_result
()
{
count
=
0
;
}
bool
add
();
bool
add
();
void
make_const
(
longlong
count_arg
)
{
count
=
count_arg
;
used_table_cache
=
0
;
}
void
make_const
(
longlong
count_arg
)
{
count
=
count_arg
;
used_table_cache
=
0
;
}
longlong
val_int
();
longlong
val_int
();
...
...
sql/opt_sum.cc
View file @
3d067e7d
/* Copyright (C) 2000
MySQL AB & MySQL Finland AB & TCX DataKonsult
AB
/* Copyright (C) 2000
-2003 MySQL
AB
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
...
@@ -22,28 +22,55 @@
...
@@ -22,28 +22,55 @@
static
bool
find_range_key
(
TABLE_REF
*
ref
,
Field
*
field
,
COND
*
cond
);
static
bool
find_range_key
(
TABLE_REF
*
ref
,
Field
*
field
,
COND
*
cond
);
/*****************************************************************************
/*
** This function is only called for queries with sum functions and no
Substitutes constants for some COUNT(), MIN() and MAX() functions.
** GROUP BY part.
** This substitutes constants for some COUNT(), MIN() and MAX() functions.
SYNOPSIS
** The function returns 1 if all items was resolved and -1 on impossible
opt_sum_query()
** conditions
tables Tables in query
****************************************************************************/
all_fields All fields to be returned
conds WHERE clause
NOTE:
This function is only called for queries with sum functions and no
GROUP BY part.
RETURN VALUES
0 No errors
1 if all items was resolved
-1 on impossible conditions
*/
int
opt_sum_query
(
TABLE_LIST
*
tables
,
List
<
Item
>
&
all_fields
,
COND
*
conds
)
int
opt_sum_query
(
TABLE_LIST
*
tables
,
List
<
Item
>
&
all_fields
,
COND
*
conds
)
{
{
List_iterator_fast
<
Item
>
it
(
all_fields
);
List_iterator_fast
<
Item
>
it
(
all_fields
);
int
const_result
=
1
;
int
const_result
=
1
;
bool
recalc_const_item
=
0
;
bool
recalc_const_item
=
0
;
table_map
removed_tables
=
0
;
table_map
removed_tables
=
0
,
outer_tables
=
0
,
used_tables
=
0
;
table_map
where_tables
=
0
;
Item
*
item
;
Item
*
item
;
COND
*
org_conds
=
conds
;
COND
*
org_conds
=
conds
;
/* Add all ON conditions to WHERE condition */
if
(
conds
)
where_tables
=
conds
->
used_tables
();
/* Don't replace expression on a table that is part of an outer join */
for
(
TABLE_LIST
*
tl
=
tables
;
tl
;
tl
=
tl
->
next
)
for
(
TABLE_LIST
*
tl
=
tables
;
tl
;
tl
=
tl
->
next
)
{
{
if
(
tl
->
on_expr
)
if
(
tl
->
on_expr
)
conds
=
and_expressions
(
conds
,
tl
->
on_expr
,
&
org_conds
);
{
outer_tables
|=
tl
->
table
->
map
;
/*
We can't optimise LEFT JOIN in cases where the WHERE condition
restricts the table that is used, like in:
SELECT MAX(t1.a) FROM t1 LEFT JOIN t2 join-condition
WHERE t2.field IS NULL;
*/
if
(
tl
->
table
->
map
&
where_tables
)
return
0
;
}
used_tables
|=
tl
->
table
->
map
;
}
}
/*
/*
...
@@ -68,8 +95,8 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
...
@@ -68,8 +95,8 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
TABLE_LIST
*
table
;
TABLE_LIST
*
table
;
for
(
table
=
tables
;
table
;
table
=
table
->
next
)
for
(
table
=
tables
;
table
;
table
=
table
->
next
)
{
{
if
(
table
->
on_expr
||
(
table
->
table
->
file
->
table_flags
()
&
if
(
outer_tables
||
(
table
->
table
->
file
->
table_flags
()
&
HA_NOT_EXACT_COUNT
))
HA_NOT_EXACT_COUNT
))
{
{
const_result
=
0
;
// Can't optimize left join
const_result
=
0
;
// Can't optimize left join
break
;
break
;
...
@@ -99,21 +126,35 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
...
@@ -99,21 +126,35 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
byte
key_buff
[
MAX_KEY_LENGTH
];
byte
key_buff
[
MAX_KEY_LENGTH
];
TABLE_REF
ref
;
TABLE_REF
ref
;
ref
.
key_buff
=
key_buff
;
ref
.
key_buff
=
key_buff
;
Item_field
*
item_field
=
((
Item_field
*
)
expr
);
TABLE
*
table
=
item_field
->
field
->
table
;
if
(
!
find_range_key
(
&
ref
,
((
Item_field
*
)
expr
)
->
field
,
conds
))
if
((
outer_tables
&
table
->
map
)
||
(
!
find_range_key
(
&
ref
,
item_field
->
field
,
conds
)))
{
{
const_result
=
0
;
const_result
=
0
;
break
;
break
;
}
}
TABLE
*
table
=
((
Item_field
*
)
expr
)
->
field
->
table
;
bool
error
=
table
->
file
->
index_init
((
uint
)
ref
.
key
);
bool
error
=
table
->
file
->
index_init
((
uint
)
ref
.
key
);
enum
ha_rkey_function
find_flag
=
HA_READ_KEY_OR_NEXT
;
uint
prefix_len
=
ref
.
key_length
;
/*
If we are doing MIN() on a column with NULL fields
we must read the key after the NULL column
*/
if
(
item_field
->
field
->
null_bit
)
{
ref
.
key_buff
[
ref
.
key_length
++
]
=
1
;
find_flag
=
HA_READ_AFTER_KEY
;
}
if
(
!
ref
.
key_length
)
if
(
!
ref
.
key_length
)
error
=
table
->
file
->
index_first
(
table
->
record
[
0
])
!=
0
;
error
=
table
->
file
->
index_first
(
table
->
record
[
0
])
!=
0
;
else
else
error
=
table
->
file
->
index_read
(
table
->
record
[
0
],
key_buff
,
error
=
table
->
file
->
index_read
(
table
->
record
[
0
],
key_buff
,
ref
.
key_length
,
ref
.
key_length
,
HA_READ_KEY_OR_NEXT
)
||
find_flag
)
||
key_cmp
(
table
,
key_buff
,
ref
.
key
,
ref
.
key_length
);
key_cmp
(
table
,
key_buff
,
ref
.
key
,
prefix_len
);
if
(
table
->
key_read
)
if
(
table
->
key_read
)
{
{
table
->
key_read
=
0
;
table
->
key_read
=
0
;
...
@@ -121,7 +162,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
...
@@ -121,7 +162,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
}
}
table
->
file
->
index_end
();
table
->
file
->
index_end
();
if
(
error
)
if
(
error
)
return
-
1
;
//
Impossible query
return
-
1
;
//
No rows matching where
removed_tables
|=
table
->
map
;
removed_tables
|=
table
->
map
;
}
}
else
if
(
!
expr
->
const_item
())
// This is VERY seldom false
else
if
(
!
expr
->
const_item
())
// This is VERY seldom false
...
@@ -147,13 +188,14 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
...
@@ -147,13 +188,14 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
byte
key_buff
[
MAX_KEY_LENGTH
];
byte
key_buff
[
MAX_KEY_LENGTH
];
TABLE_REF
ref
;
TABLE_REF
ref
;
ref
.
key_buff
=
key_buff
;
ref
.
key_buff
=
key_buff
;
TABLE
*
table
=
((
Item_field
*
)
expr
)
->
field
->
table
;
if
(
!
find_range_key
(
&
ref
,
((
Item_field
*
)
expr
)
->
field
,
conds
))
if
((
outer_tables
&
table
->
map
)
||
!
find_range_key
(
&
ref
,
((
Item_field
*
)
expr
)
->
field
,
conds
))
{
{
const_result
=
0
;
const_result
=
0
;
break
;
break
;
}
}
TABLE
*
table
=
((
Item_field
*
)
expr
)
->
field
->
table
;
if
((
table
->
file
->
table_flags
()
&
HA_NOT_READ_AFTER_KEY
))
if
((
table
->
file
->
table_flags
()
&
HA_NOT_READ_AFTER_KEY
))
{
{
const_result
=
0
;
const_result
=
0
;
...
@@ -203,8 +245,8 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
...
@@ -203,8 +245,8 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result
=
0
;
const_result
=
0
;
}
}
}
}
if
(
conds
&&
(
conds
->
used_tables
()
&
~
removed_tables
)
)
if
(
used_tables
!=
removed_tables
)
const_result
=
0
;
const_result
=
0
;
// We didn't remove all tables
return
const_result
;
return
const_result
;
}
}
...
...
sql/sql_select.cc
View file @
3d067e7d
...
@@ -3104,7 +3104,13 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
...
@@ -3104,7 +3104,13 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
if
(
!
(
result
->
send_fields
(
fields
,
1
)))
if
(
!
(
result
->
send_fields
(
fields
,
1
)))
{
{
if
(
send_row
)
if
(
send_row
)
{
List_iterator_fast
<
Item
>
it
(
fields
);
Item
*
item
;
while
((
item
=
it
++
))
item
->
no_rows_in_result
();
result
->
send_data
(
fields
);
result
->
send_data
(
fields
);
}
if
(
tables
)
// Not from do_select()
if
(
tables
)
// Not from do_select()
{
{
/* Close open cursors */
/* Close open cursors */
...
...
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