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
083acc29
Commit
083acc29
authored
Aug 09, 2003
by
serg@serg.mylan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BETWEEN bug fix: non-const expressions on both ends
parent
df8b7799
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
42 additions
and
29 deletions
+42
-29
mysql-test/r/range.result
mysql-test/r/range.result
+1
-1
sql/sql_select.cc
sql/sql_select.cc
+41
-28
No files found.
mysql-test/r/range.result
View file @
083acc29
...
...
@@ -240,7 +240,7 @@ t2 range x x 5 NULL 4 Using where
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
table type possible_keys key key_len ref rows Extra
t1 ref y y 5 const 1 Using where
t2 ALL x NULL NULL NULL 9
Using where
t2 ALL x NULL NULL NULL 9
Range checked for each record (index map: 1)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
table type possible_keys key key_len ref rows Extra
t1 ref y y 5 const 1 Using where
...
...
sql/sql_select.cc
View file @
083acc29
...
...
@@ -1425,28 +1425,34 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
static
void
add_key_field
(
KEY_FIELD
**
key_fields
,
uint
and_level
,
Field
*
field
,
bool
eq_func
,
Item
*
value
,
Field
*
field
,
bool
eq_func
,
Item
*
*
value
,
uint
num_values
,
table_map
usable_tables
)
{
bool
exists_optimize
=
0
;
if
(
!
(
field
->
flags
&
PART_KEY_FLAG
))
{
// Don't remove column IS NULL on a LEFT JOIN table
if
(
!
eq_func
||
!
value
||
value
->
type
()
!=
Item
::
NULL_ITEM
||
!
field
->
table
->
maybe_null
||
field
->
null_ptr
)
if
(
!
eq_func
||
(
*
value
)
->
type
()
!=
Item
::
NULL_ITEM
||
!
field
->
table
->
maybe_null
||
field
->
null_ptr
)
return
;
// Not a key. Skip it
exists_optimize
=
1
;
}
else
{
table_map
used_tables
=
0
;
if
(
value
&&
(
used_tables
=
value
->
used_tables
())
&
(
field
->
table
->
map
|
RAND_TABLE_BIT
))
bool
optimizable
=
0
;
for
(
uint
i
=
0
;
i
<
num_values
;
i
++
)
{
used_tables
|=
(
*
value
)
->
used_tables
();
if
(
!
((
*
value
)
->
used_tables
()
&
(
field
->
table
->
map
|
RAND_TABLE_BIT
)))
optimizable
=
1
;
}
if
(
!
optimizable
)
return
;
if
(
!
(
usable_tables
&
field
->
table
->
map
))
{
if
(
!
eq_func
||
!
value
||
value
->
type
()
!=
Item
::
NULL_ITEM
||
!
field
->
table
->
maybe_null
||
field
->
null_ptr
)
if
(
!
eq_func
||
(
*
value
)
->
type
()
!=
Item
::
NULL_ITEM
||
!
field
->
table
->
maybe_null
||
field
->
null_ptr
)
return
;
// Can't use left join optimize
exists_optimize
=
1
;
}
...
...
@@ -1457,12 +1463,6 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
field
->
table
->
keys_in_use_for_query
);
stat
[
0
].
keys
|=
possible_keys
;
// Add possible keys
if
(
!
value
)
{
// Probably BETWEEN or IN
stat
[
0
].
const_keys
|=
possible_keys
;
return
;
// Can't be used as eq key
}
/* Save the following cases:
Field op constant
Field LIKE constant where constant doesn't start with a wildcard
...
...
@@ -1470,24 +1470,34 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
Field op formula
Field IS NULL
Field IS NOT NULL
Field BETWEEN ...
Field IN ...
*/
stat
[
0
].
key_dependent
|=
used_tables
;
if
(
value
->
const_item
())
stat
[
0
].
const_keys
|=
possible_keys
;
bool
is_const
=
1
;
for
(
uint
i
=
0
;
i
<
num_values
;
i
++
)
is_const
&=
(
*
value
)
->
const_item
();
if
(
is_const
)
stat
[
0
].
const_keys
|=
possible_keys
;
/* We can't always use indexes when comparing a string index to a
number. cmp_type() is checked to allow compare of dates to numbers */
number. cmp_type() is checked to allow compare of dates to numbers
also eq_func is NEVER true when num_values > 1
*/
if
(
!
eq_func
||
field
->
result_type
()
==
STRING_RESULT
&&
value
->
result_type
()
!=
STRING_RESULT
&&
field
->
cmp_type
()
!=
value
->
result_type
())
(
*
value
)
->
result_type
()
!=
STRING_RESULT
&&
field
->
cmp_type
()
!=
(
*
value
)
->
result_type
())
return
;
}
}
DBUG_ASSERT
(
num_values
==
1
);
// DBUG_ASSERT(eq_func); /* QQ: Can I uncomment this ASSERT ? */
/* Store possible eq field */
(
*
key_fields
)
->
field
=
field
;
(
*
key_fields
)
->
eq_func
=
eq_func
;
(
*
key_fields
)
->
val
=
value
;
(
*
key_fields
)
->
val
=
*
value
;
(
*
key_fields
)
->
level
=
(
*
key_fields
)
->
const_level
=
and_level
;
(
*
key_fields
)
->
exists_optimize
=
exists_optimize
;
(
*
key_fields
)
++
;
...
...
@@ -1541,10 +1551,12 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
case
Item_func
:
:
OPTIMIZE_NONE
:
break
;
case
Item_func
:
:
OPTIMIZE_KEY
:
// BETWEEN or IN
if
(
cond_func
->
key_item
()
->
type
()
==
Item
::
FIELD_ITEM
)
add_key_field
(
key_fields
,
*
and_level
,
((
Item_field
*
)
(
cond_func
->
key_item
()))
->
field
,
0
,(
Item
*
)
0
,
usable_tables
);
((
Item_field
*
)
(
cond_func
->
key_item
()))
->
field
,
0
,
cond_func
->
arguments
()
+
1
,
cond_func
->
argument_count
()
-
1
,
usable_tables
);
break
;
case
Item_func
:
:
OPTIMIZE_OP
:
{
...
...
@@ -1556,7 +1568,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
add_key_field
(
key_fields
,
*
and_level
,
((
Item_field
*
)
(
cond_func
->
arguments
()[
0
]))
->
field
,
equal_func
,
(
cond_func
->
arguments
()[
1
]),
usable_tables
);
cond_func
->
arguments
()
+
1
,
1
,
usable_tables
);
}
if
(
cond_func
->
arguments
()[
1
]
->
type
()
==
Item
::
FIELD_ITEM
&&
cond_func
->
functype
()
!=
Item_func
::
LIKE_FUNC
)
...
...
@@ -1564,7 +1576,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
add_key_field
(
key_fields
,
*
and_level
,
((
Item_field
*
)
(
cond_func
->
arguments
()[
1
]))
->
field
,
equal_func
,
(
cond_func
->
arguments
()[
0
])
,
usable_tables
);
cond_func
->
arguments
(),
1
,
usable_tables
);
}
break
;
}
...
...
@@ -1572,10 +1584,11 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
/* column_name IS [NOT] NULL */
if
(
cond_func
->
arguments
()[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
Item
*
tmp
=
new
Item_null
;
add_key_field
(
key_fields
,
*
and_level
,
((
Item_field
*
)
(
cond_func
->
arguments
()[
0
]))
->
field
,
cond_func
->
functype
()
==
Item_func
::
ISNULL_FUNC
,
new
Item_null
,
usable_tables
);
&
tmp
,
1
,
usable_tables
);
}
break
;
}
...
...
@@ -3267,7 +3280,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
static
void
propagate_cond_constants
(
I_List
<
COND_CMP
>
*
save_list
,
COND
*
and_
level
,
propagate_cond_constants
(
I_List
<
COND_CMP
>
*
save_list
,
COND
*
and_
father
,
COND
*
cond
)
{
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
...
...
@@ -3293,7 +3306,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
cond_cmp
->
cmp_func
->
arguments
()[
1
]);
}
}
else
if
(
and_
level
!=
cond
&&
!
cond
->
marker
)
// In a AND group
else
if
(
and_
father
!=
cond
&&
!
cond
->
marker
)
// In a AND group
{
if
(
cond
->
type
()
==
Item
::
FUNC_ITEM
&&
(((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
EQ_FUNC
||
...
...
@@ -3311,7 +3324,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
func
->
arguments
()[
1
]
=
resolve_const_item
(
func
->
arguments
()[
1
],
func
->
arguments
()[
0
]);
func
->
update_used_tables
();
change_cond_ref_to_const
(
save_list
,
and_
level
,
and_level
,
change_cond_ref_to_const
(
save_list
,
and_
father
,
and_father
,
func
->
arguments
()[
0
],
func
->
arguments
()[
1
]);
}
...
...
@@ -3320,7 +3333,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
func
->
arguments
()[
0
]
=
resolve_const_item
(
func
->
arguments
()[
0
],
func
->
arguments
()[
1
]);
func
->
update_used_tables
();
change_cond_ref_to_const
(
save_list
,
and_
level
,
and_level
,
change_cond_ref_to_const
(
save_list
,
and_
father
,
and_father
,
func
->
arguments
()[
1
],
func
->
arguments
()[
0
]);
}
...
...
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