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
edb71b0c
Commit
edb71b0c
authored
Aug 28, 2009
by
Mattias Jonsson
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
83112949
2c5e2278
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1924 additions
and
68 deletions
+1924
-68
mysql-test/include/partition_date_range.inc
mysql-test/include/partition_date_range.inc
+63
-0
mysql-test/r/partition_pruning.result
mysql-test/r/partition_pruning.result
+1274
-0
mysql-test/r/partition_range.result
mysql-test/r/partition_range.result
+2
-2
mysql-test/t/partition_pruning.test
mysql-test/t/partition_pruning.test
+351
-0
sql-common/my_time.c
sql-common/my_time.c
+1
-3
sql/item.cc
sql/item.cc
+39
-11
sql/item.h
sql/item.h
+11
-4
sql/item_timefunc.cc
sql/item_timefunc.cc
+25
-6
sql/mysql_priv.h
sql/mysql_priv.h
+2
-1
sql/opt_range.cc
sql/opt_range.cc
+14
-12
sql/partition_info.h
sql/partition_info.h
+1
-0
sql/share/errmsg.txt
sql/share/errmsg.txt
+8
-8
sql/sql_partition.cc
sql/sql_partition.cc
+72
-6
sql/sql_table.cc
sql/sql_table.cc
+61
-15
No files found.
mysql-test/include/partition_date_range.inc
0 → 100644
View file @
edb71b0c
# Created for verifying bug#20577.
# expects TABLE t1 (... , a DATE, ...)
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
<
'1001-01-01'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
<=
'1001-01-01'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
>=
'1001-01-01'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
>
'1001-01-01'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
=
'1001-01-01'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
<
'1001-00-00'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
<=
'1001-00-00'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
>=
'1001-00-00'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
>
'1001-00-00'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
=
'1001-00-00'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
<
'1999-02-31'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
<=
'1999-02-31'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
>=
'1999-02-31'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
>
'1999-02-31'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
=
'1999-02-31'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0000-00-00'
AND
'1002-00-00'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0000-00-00'
AND
'1001-01-01'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0001-01-02'
AND
'1002-00-00'
;
--
sorted_result
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0001-01-01'
AND
'1001-01-01'
;
if
(
$explain_partitions
)
{
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
<
'1001-01-01'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
<=
'1001-01-01'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
>=
'1001-01-01'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
>
'1001-01-01'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
=
'1001-01-01'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
<
'1001-00-00'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
<=
'1001-00-00'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
>=
'1001-00-00'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
>
'1001-00-00'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
=
'1001-00-00'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
<
'1999-02-31'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
<=
'1999-02-31'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
>=
'1999-02-31'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
>
'1999-02-31'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
=
'1999-02-31'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0000-00-00'
AND
'1002-00-00'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0000-00-00'
AND
'1001-01-01'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0001-01-02'
AND
'1002-00-00'
;
EXPLAIN
PARTITIONS
SELECT
*
FROM
t1
WHERE
a
BETWEEN
'0001-01-01'
AND
'1001-01-01'
;
}
mysql-test/r/partition_pruning.result
View file @
edb71b0c
This diff is collapsed.
Click to expand it.
mysql-test/r/partition_range.result
View file @
edb71b0c
...
@@ -745,7 +745,7 @@ a
...
@@ -745,7 +745,7 @@ a
EXPLAIN PARTITIONS SELECT * FROM t1
EXPLAIN PARTITIONS SELECT * FROM t1
WHERE a >= '2004-07-01' AND a <= '2004-09-30';
WHERE a >= '2004-07-01' AND a <= '2004-09-30';
id select_type table partitions type possible_keys key key_len ref rows Extra
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p
407,p408,p409 ALL NULL NULL NULL NULL 9
Using where
1 SIMPLE t1 p
3xx,p407,p408,p409 ALL NULL NULL NULL NULL 18
Using where
SELECT * from t1
SELECT * from t1
WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR
WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR
(a >= '2005-07-01' AND a <= '2005-09-30');
(a >= '2005-07-01' AND a <= '2005-09-30');
...
@@ -772,7 +772,7 @@ EXPLAIN PARTITIONS SELECT * from t1
...
@@ -772,7 +772,7 @@ EXPLAIN PARTITIONS SELECT * from t1
WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR
WHERE (a >= '2004-07-01' AND a <= '2004-09-30') OR
(a >= '2005-07-01' AND a <= '2005-09-30');
(a >= '2005-07-01' AND a <= '2005-09-30');
id select_type table partitions type possible_keys key key_len ref rows Extra
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p
407,p408,p409,p507,p508,p509 ALL NULL NULL NULL NULL 18
Using where
1 SIMPLE t1 p
3xx,p407,p408,p409,p507,p508,p509 ALL NULL NULL NULL NULL 27
Using where
DROP TABLE t1;
DROP TABLE t1;
create table t1 (a int);
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
...
...
mysql-test/t/partition_pruning.test
View file @
edb71b0c
This diff is collapsed.
Click to expand it.
sql-common/my_time.c
View file @
edb71b0c
...
@@ -450,9 +450,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
...
@@ -450,9 +450,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
}
}
}
}
DBUG_RETURN
(
l_time
->
time_type
=
DBUG_RETURN
(
l_time
->
time_type
);
(
number_of_fields
<=
3
?
MYSQL_TIMESTAMP_DATE
:
MYSQL_TIMESTAMP_DATETIME
));
err:
err:
bzero
((
char
*
)
l_time
,
sizeof
(
*
l_time
));
bzero
((
char
*
)
l_time
,
sizeof
(
*
l_time
));
...
...
sql/item.cc
View file @
edb71b0c
...
@@ -6853,14 +6853,21 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
...
@@ -6853,14 +6853,21 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
}
}
/**
/**
Return true if the value stored in the field is equal to the const
Compare the value stored in field, with the original item.
item.
We need to use this on the range optimizer because in some cases
@param field field which the item is converted and stored in
we can't store the value in the field without some precision/character loss.
@param item original item
@return Return an integer greater than, equal to, or less than 0 if
the value stored in the field is greater than, equal to,
or less than the original item
@note We only use this on the range optimizer/partition pruning,
because in some cases we can't store the value in the field
without some precision/character loss.
*/
*/
bool
field_is_equal_to_item
(
Field
*
field
,
Item
*
item
)
int
stored_field_cmp_to_item
(
Field
*
field
,
Item
*
item
)
{
{
Item_result
res_type
=
item_cmp_type
(
field
->
result_type
(),
Item_result
res_type
=
item_cmp_type
(
field
->
result_type
(),
...
@@ -6871,28 +6878,49 @@ bool field_is_equal_to_item(Field *field,Item *item)
...
@@ -6871,28 +6878,49 @@ bool field_is_equal_to_item(Field *field,Item *item)
char
field_buff
[
MAX_FIELD_WIDTH
];
char
field_buff
[
MAX_FIELD_WIDTH
];
String
item_tmp
(
item_buff
,
sizeof
(
item_buff
),
&
my_charset_bin
),
*
item_result
;
String
item_tmp
(
item_buff
,
sizeof
(
item_buff
),
&
my_charset_bin
),
*
item_result
;
String
field_tmp
(
field_buff
,
sizeof
(
field_buff
),
&
my_charset_bin
);
String
field_tmp
(
field_buff
,
sizeof
(
field_buff
),
&
my_charset_bin
);
enum_field_types
field_type
;
item_result
=
item
->
val_str
(
&
item_tmp
);
item_result
=
item
->
val_str
(
&
item_tmp
);
if
(
item
->
null_value
)
if
(
item
->
null_value
)
return
1
;
// This must be true
return
0
;
field
->
val_str
(
&
field_tmp
);
field
->
val_str
(
&
field_tmp
);
return
!
stringcmp
(
&
field_tmp
,
item_result
);
/*
If comparing DATE with DATETIME, append the time-part to the DATE.
So that the strings are equally formatted.
A DATE converted to string is 10 characters, and a DATETIME converted
to string is 19 characters.
*/
field_type
=
field
->
type
();
if
(
field_type
==
MYSQL_TYPE_DATE
&&
item_result
->
length
()
==
19
)
field_tmp
.
append
(
" 00:00:00"
);
else
if
(
field_type
==
MYSQL_TYPE_DATETIME
&&
item_result
->
length
()
==
10
)
item_result
->
append
(
" 00:00:00"
);
return
stringcmp
(
&
field_tmp
,
item_result
);
}
}
if
(
res_type
==
INT_RESULT
)
if
(
res_type
==
INT_RESULT
)
return
1
;
// Both whe
re of type int
return
0
;
// Both a
re of type int
if
(
res_type
==
DECIMAL_RESULT
)
if
(
res_type
==
DECIMAL_RESULT
)
{
{
my_decimal
item_buf
,
*
item_val
,
my_decimal
item_buf
,
*
item_val
,
field_buf
,
*
field_val
;
field_buf
,
*
field_val
;
item_val
=
item
->
val_decimal
(
&
item_buf
);
item_val
=
item
->
val_decimal
(
&
item_buf
);
if
(
item
->
null_value
)
if
(
item
->
null_value
)
return
1
;
// This must be true
return
0
;
field_val
=
field
->
val_decimal
(
&
field_buf
);
field_val
=
field
->
val_decimal
(
&
field_buf
);
return
!
my_decimal_cmp
(
item_val
,
field_val
);
return
my_decimal_cmp
(
item_val
,
field_val
);
}
}
double
result
=
item
->
val_real
();
double
result
=
item
->
val_real
();
if
(
item
->
null_value
)
if
(
item
->
null_value
)
return
0
;
double
field_result
=
field
->
val_real
();
if
(
field_result
<
result
)
return
-
1
;
else
if
(
field_result
>
result
)
return
1
;
return
1
;
return
result
==
field
->
val_real
()
;
return
0
;
}
}
Item_cache
*
Item_cache
::
get_cache
(
const
Item
*
item
)
Item_cache
*
Item_cache
::
get_cache
(
const
Item
*
item
)
...
...
sql/item.h
View file @
edb71b0c
...
@@ -397,13 +397,20 @@ public:
...
@@ -397,13 +397,20 @@ public:
from INT_RESULT, may be NULL, or are unsigned.
from INT_RESULT, may be NULL, or are unsigned.
It will be possible to address this issue once the related partitioning bugs
It will be possible to address this issue once the related partitioning bugs
(BUG#16002, BUG#15447, BUG#13436) are fixed.
(BUG#16002, BUG#15447, BUG#13436) are fixed.
The NOT_NULL enums are used in TO_DAYS, since TO_DAYS('2001-00-00') returns
NULL which puts those rows into the NULL partition, but
'2000-12-31' < '2001-00-00' < '2001-01-01'. So special handling is needed
for this (see Bug#20577).
*/
*/
typedef
enum
monotonicity_info
typedef
enum
monotonicity_info
{
{
NON_MONOTONIC
,
/* none of the below holds */
NON_MONOTONIC
,
/* none of the below holds */
MONOTONIC_INCREASING
,
/* F() is unary and (x < y) => (F(x) <= F(y)) */
MONOTONIC_INCREASING
,
/* F() is unary and (x < y) => (F(x) <= F(y)) */
MONOTONIC_STRICT_INCREASING
/* F() is unary and (x < y) => (F(x) < F(y)) */
MONOTONIC_INCREASING_NOT_NULL
,
/* But only for valid/real x and y */
MONOTONIC_STRICT_INCREASING
,
/* F() is unary and (x < y) => (F(x) < F(y)) */
MONOTONIC_STRICT_INCREASING_NOT_NULL
/* But only for valid/real x and y */
}
enum_monotonicity_info
;
}
enum_monotonicity_info
;
/*************************************************************************/
/*************************************************************************/
...
@@ -576,8 +583,8 @@ public:
...
@@ -576,8 +583,8 @@ public:
left_endp FALSE <=> The interval is "x < const" or "x <= const"
left_endp FALSE <=> The interval is "x < const" or "x <= const"
TRUE <=> The interval is "x > const" or "x >= const"
TRUE <=> The interval is "x > const" or "x >= const"
incl_endp IN
TRU
E <=> the comparison is '<' or '>'
incl_endp IN
FALS
E <=> the comparison is '<' or '>'
FALSE
<=> the comparison is '<=' or '>='
TRUE
<=> the comparison is '<=' or '>='
OUT The same but for the "F(x) $CMP$ F(const)" comparison
OUT The same but for the "F(x) $CMP$ F(const)" comparison
DESCRIPTION
DESCRIPTION
...
@@ -3118,4 +3125,4 @@ void mark_select_range_as_dependent(THD *thd,
...
@@ -3118,4 +3125,4 @@ void mark_select_range_as_dependent(THD *thd,
extern
Cached_item
*
new_Cached_item
(
THD
*
thd
,
Item
*
item
);
extern
Cached_item
*
new_Cached_item
(
THD
*
thd
,
Item
*
item
);
extern
Item_result
item_cmp_type
(
Item_result
a
,
Item_result
b
);
extern
Item_result
item_cmp_type
(
Item_result
a
,
Item_result
b
);
extern
void
resolve_const_item
(
THD
*
thd
,
Item
**
ref
,
Item
*
cmp_item
);
extern
void
resolve_const_item
(
THD
*
thd
,
Item
**
ref
,
Item
*
cmp_item
);
extern
bool
field_is_equal_to_item
(
Field
*
field
,
Item
*
item
);
extern
int
stored_field_cmp_to_item
(
Field
*
field
,
Item
*
item
);
sql/item_timefunc.cc
View file @
edb71b0c
...
@@ -960,9 +960,9 @@ enum_monotonicity_info Item_func_to_days::get_monotonicity_info() const
...
@@ -960,9 +960,9 @@ enum_monotonicity_info Item_func_to_days::get_monotonicity_info() const
if
(
args
[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
if
(
args
[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
{
if
(
args
[
0
]
->
field_type
()
==
MYSQL_TYPE_DATE
)
if
(
args
[
0
]
->
field_type
()
==
MYSQL_TYPE_DATE
)
return
MONOTONIC_STRICT_INCREASING
;
return
MONOTONIC_STRICT_INCREASING
_NOT_NULL
;
if
(
args
[
0
]
->
field_type
()
==
MYSQL_TYPE_DATETIME
)
if
(
args
[
0
]
->
field_type
()
==
MYSQL_TYPE_DATETIME
)
return
MONOTONIC_INCREASING
;
return
MONOTONIC_INCREASING
_NOT_NULL
;
}
}
return
NON_MONOTONIC
;
return
NON_MONOTONIC
;
}
}
...
@@ -973,12 +973,27 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
...
@@ -973,12 +973,27 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
MYSQL_TIME
ltime
;
MYSQL_TIME
ltime
;
longlong
res
;
longlong
res
;
if
(
get_arg0_date
(
&
ltime
,
TIME_NO_ZERO_DATE
))
int
dummy
;
/* unused */
if
(
get_arg0_date
(
&
ltime
,
TIME_FUZZY_DATE
))
{
{
/* got NULL, leave the incl_endp intact */
/* got NULL, leave the incl_endp intact */
return
LONGLONG_MIN
;
return
LONGLONG_MIN
;
}
}
res
=
(
longlong
)
calc_daynr
(
ltime
.
year
,
ltime
.
month
,
ltime
.
day
);
res
=
(
longlong
)
calc_daynr
(
ltime
.
year
,
ltime
.
month
,
ltime
.
day
);
/* Set to NULL if invalid date, but keep the value */
null_value
=
check_date
(
&
ltime
,
(
ltime
.
year
||
ltime
.
month
||
ltime
.
day
),
(
TIME_NO_ZERO_IN_DATE
|
TIME_NO_ZERO_DATE
),
&
dummy
);
if
(
null_value
)
{
/*
Even if the evaluation return NULL, the calc_daynr is useful for pruning
*/
if
(
args
[
0
]
->
field_type
()
!=
MYSQL_TYPE_DATE
)
*
incl_endp
=
TRUE
;
return
res
;
}
if
(
args
[
0
]
->
field_type
()
==
MYSQL_TYPE_DATE
)
if
(
args
[
0
]
->
field_type
()
==
MYSQL_TYPE_DATE
)
{
{
...
@@ -991,15 +1006,19 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
...
@@ -991,15 +1006,19 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
point to day bound ("strictly less" comparison stays intact):
point to day bound ("strictly less" comparison stays intact):
col < '2007-09-15 00:00:00' -> TO_DAYS(col) < TO_DAYS('2007-09-15')
col < '2007-09-15 00:00:00' -> TO_DAYS(col) < TO_DAYS('2007-09-15')
col > '2007-09-15 23:59:59' -> TO_DAYS(col) > TO_DAYS('2007-09-15')
which is different from the general case ("strictly less" changes to
which is different from the general case ("strictly less" changes to
"less or equal"):
"less or equal"):
col < '2007-09-15 12:34:56' -> TO_DAYS(col) <= TO_DAYS('2007-09-15')
col < '2007-09-15 12:34:56' -> TO_DAYS(col) <= TO_DAYS('2007-09-15')
*/
*/
if
(
!
left_endp
&&
!
(
ltime
.
hour
||
ltime
.
minute
||
ltime
.
second
||
if
((
!
left_endp
&&
!
(
ltime
.
hour
||
ltime
.
minute
||
ltime
.
second
||
ltime
.
second_part
))
ltime
.
second_part
))
||
;
/* do nothing */
(
left_endp
&&
ltime
.
hour
==
23
&&
ltime
.
minute
==
59
&&
ltime
.
second
==
59
))
/* do nothing */
;
else
else
*
incl_endp
=
TRUE
;
*
incl_endp
=
TRUE
;
return
res
;
return
res
;
...
...
sql/mysql_priv.h
View file @
edb71b0c
...
@@ -2277,7 +2277,8 @@ enum enum_explain_filename_mode
...
@@ -2277,7 +2277,8 @@ enum enum_explain_filename_mode
{
{
EXPLAIN_ALL_VERBOSE
=
0
,
EXPLAIN_ALL_VERBOSE
=
0
,
EXPLAIN_PARTITIONS_VERBOSE
,
EXPLAIN_PARTITIONS_VERBOSE
,
EXPLAIN_PARTITIONS_AS_COMMENT
EXPLAIN_PARTITIONS_AS_COMMENT
,
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
};
};
uint
explain_filename
(
const
char
*
from
,
char
*
to
,
uint
to_length
,
uint
explain_filename
(
const
char
*
from
,
char
*
to
,
uint
to_length
,
enum_explain_filename_mode
explain_mode
);
enum_explain_filename_mode
explain_mode
);
...
...
sql/opt_range.cc
View file @
edb71b0c
...
@@ -5826,6 +5826,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
...
@@ -5826,6 +5826,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
{
{
tree
=
new
(
alloc
)
SEL_ARG
(
field
,
0
,
0
);
tree
=
new
(
alloc
)
SEL_ARG
(
field
,
0
,
0
);
tree
->
type
=
SEL_ARG
::
IMPOSSIBLE
;
tree
->
type
=
SEL_ARG
::
IMPOSSIBLE
;
field
->
table
->
in_use
->
variables
.
sql_mode
=
orig_sql_mode
;
goto
end
;
goto
end
;
}
}
else
else
...
@@ -5855,13 +5856,16 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
...
@@ -5855,13 +5856,16 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
but we'll need to convert '>' to '>=' and '<' to '<='. This will
but we'll need to convert '>' to '>=' and '<' to '<='. This will
be done together with other types at the end of this function
be done together with other types at the end of this function
(grep for
field_is_equal
_to_item)
(grep for
stored_field_cmp
_to_item)
*/
*/
}
}
else
else
{
field
->
table
->
in_use
->
variables
.
sql_mode
=
orig_sql_mode
;
goto
end
;
goto
end
;
}
}
}
}
}
/*
/*
guaranteed at this point: err > 0; field and const of same type
guaranteed at this point: err > 0; field and const of same type
...
@@ -5930,7 +5934,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
...
@@ -5930,7 +5934,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
switch
(
type
)
{
switch
(
type
)
{
case
Item_func
:
:
LT_FUNC
:
case
Item_func
:
:
LT_FUNC
:
if
(
field_is_equal_to_item
(
field
,
value
)
)
if
(
stored_field_cmp_to_item
(
field
,
value
)
==
0
)
tree
->
max_flag
=
NEAR_MAX
;
tree
->
max_flag
=
NEAR_MAX
;
/* fall through */
/* fall through */
case
Item_func
:
:
LE_FUNC
:
case
Item_func
:
:
LE_FUNC
:
...
@@ -5944,11 +5948,16 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
...
@@ -5944,11 +5948,16 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
break
;
break
;
case
Item_func
:
:
GT_FUNC
:
case
Item_func
:
:
GT_FUNC
:
/* Don't use open ranges for partial key_segments */
/* Don't use open ranges for partial key_segments */
if
(
field_is_equal_to_item
(
field
,
value
)
&&
if
(
(
!
(
key_part
->
flag
&
HA_PART_KEY_SEG
)
)
&&
!
(
key_part
->
flag
&
HA_PART_KEY_SEG
))
(
stored_field_cmp_to_item
(
field
,
value
)
<=
0
))
tree
->
min_flag
=
NEAR_MIN
;
tree
->
min_flag
=
NEAR_MIN
;
/* fall through */
tree
->
max_flag
=
NO_MAX_RANGE
;
break
;
case
Item_func
:
:
GE_FUNC
:
case
Item_func
:
:
GE_FUNC
:
/* Don't use open ranges for partial key_segments */
if
((
!
(
key_part
->
flag
&
HA_PART_KEY_SEG
))
&&
(
stored_field_cmp_to_item
(
field
,
value
)
<
0
))
tree
->
min_flag
=
NEAR_MIN
;
tree
->
max_flag
=
NO_MAX_RANGE
;
tree
->
max_flag
=
NO_MAX_RANGE
;
break
;
break
;
case
Item_func
:
:
SP_EQUALS_FUNC
:
case
Item_func
:
:
SP_EQUALS_FUNC
:
...
@@ -6439,13 +6448,6 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
...
@@ -6439,13 +6448,6 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
return
0
;
// Can't optimize this
return
0
;
// Can't optimize this
}
}
if
((
key1
->
min_flag
|
key2
->
min_flag
)
&
GEOM_FLAG
)
{
key1
->
free_tree
();
key2
->
free_tree
();
return
0
;
// Can't optimize this
}
key1
->
use_count
--
;
key1
->
use_count
--
;
key2
->
use_count
--
;
key2
->
use_count
--
;
SEL_ARG
*
e1
=
key1
->
first
(),
*
e2
=
key2
->
first
(),
*
new_tree
=
0
;
SEL_ARG
*
e1
=
key1
->
first
(),
*
e2
=
key2
->
first
(),
*
new_tree
=
0
;
...
...
sql/partition_info.h
View file @
edb71b0c
...
@@ -300,6 +300,7 @@ static inline void init_single_partition_iterator(uint32 part_id,
...
@@ -300,6 +300,7 @@ static inline void init_single_partition_iterator(uint32 part_id,
{
{
part_iter
->
part_nums
.
start
=
part_iter
->
part_nums
.
cur
=
part_id
;
part_iter
->
part_nums
.
start
=
part_iter
->
part_nums
.
cur
=
part_id
;
part_iter
->
part_nums
.
end
=
part_id
+
1
;
part_iter
->
part_nums
.
end
=
part_id
+
1
;
part_iter
->
ret_null_part
=
part_iter
->
ret_null_part_orig
=
FALSE
;
part_iter
->
get_next
=
get_next_partition_id_range
;
part_iter
->
get_next
=
get_next_partition_id_range
;
}
}
...
...
sql/share/errmsg.txt
View file @
edb71b0c
...
@@ -6184,17 +6184,17 @@ ER_FUNC_INEXISTENT_NAME_COLLISION 42000
...
@@ -6184,17 +6184,17 @@ ER_FUNC_INEXISTENT_NAME_COLLISION 42000
# When updating these, please update EXPLAIN_FILENAME_MAX_EXTRA_LENGTH in
# When updating these, please update EXPLAIN_FILENAME_MAX_EXTRA_LENGTH in
# mysql_priv.h with the new maximal additional length for explain_filename.
# mysql_priv.h with the new maximal additional length for explain_filename.
ER_DATABASE_NAME
ER_DATABASE_NAME
eng "Database
`%s`
"
eng "Database"
swe "Databas
`%s`
"
swe "Databas"
ER_TABLE_NAME
ER_TABLE_NAME
eng "Table
`%s`
"
eng "Table"
swe "Tabell
`%s`
"
swe "Tabell"
ER_PARTITION_NAME
ER_PARTITION_NAME
eng "Partition
`%s`
"
eng "Partition"
swe "Partition
`%s`
"
swe "Partition"
ER_SUBPARTITION_NAME
ER_SUBPARTITION_NAME
eng "Subpartition
`%s`
"
eng "Subpartition"
swe "Subpartition
`%s`
"
swe "Subpartition"
ER_TEMPORARY_NAME
ER_TEMPORARY_NAME
eng "Temporary"
eng "Temporary"
swe "Temporr"
swe "Temporr"
...
...
sql/sql_partition.cc
View file @
edb71b0c
...
@@ -2766,8 +2766,24 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
...
@@ -2766,8 +2766,24 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
if
(
part_info
->
part_expr
->
null_value
)
if
(
part_info
->
part_expr
->
null_value
)
{
{
/*
Special handling for MONOTONIC functions that can return NULL for
values that are comparable. I.e.
'2000-00-00' can be compared to '2000-01-01' but TO_DAYS('2000-00-00')
returns NULL which cannot be compared used <, >, <=, >= etc.
Otherwise, just return the the first index (lowest value).
*/
enum_monotonicity_info
monotonic
;
monotonic
=
part_info
->
part_expr
->
get_monotonicity_info
();
if
(
monotonic
!=
MONOTONIC_INCREASING_NOT_NULL
&&
monotonic
!=
MONOTONIC_STRICT_INCREASING_NOT_NULL
)
{
/* F(col) can not return NULL, return index with lowest value */
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
}
if
(
unsigned_flag
)
if
(
unsigned_flag
)
part_func_value
-=
0x8000000000000000ULL
;
part_func_value
-=
0x8000000000000000ULL
;
DBUG_ASSERT
(
part_info
->
no_list_values
);
DBUG_ASSERT
(
part_info
->
no_list_values
);
...
@@ -2916,11 +2932,29 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
...
@@ -2916,11 +2932,29 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
if
(
part_info
->
part_expr
->
null_value
)
if
(
part_info
->
part_expr
->
null_value
)
{
{
uint32
ret_part_id
=
0
;
/*
Special handling for MONOTONIC functions that can return NULL for
values that are comparable. I.e.
'2000-00-00' can be compared to '2000-01-01' but TO_DAYS('2000-00-00')
returns NULL which cannot be compared used <, >, <=, >= etc.
Otherwise, just return the first partition
(may be included if not left endpoint)
*/
enum_monotonicity_info
monotonic
;
monotonic
=
part_info
->
part_expr
->
get_monotonicity_info
();
if
(
monotonic
!=
MONOTONIC_INCREASING_NOT_NULL
&&
monotonic
!=
MONOTONIC_STRICT_INCREASING_NOT_NULL
)
{
/* F(col) can not return NULL, return partition with lowest value */
if
(
!
left_endpoint
&&
include_endpoint
)
if
(
!
left_endpoint
&&
include_endpoint
)
ret_part_id
=
1
;
DBUG_RETURN
(
1
);
DBUG_RETURN
(
ret_part_id
);
DBUG_RETURN
(
0
);
}
}
}
if
(
unsigned_flag
)
if
(
unsigned_flag
)
part_func_value
-=
0x8000000000000000ULL
;
part_func_value
-=
0x8000000000000000ULL
;
if
(
left_endpoint
&&
!
include_endpoint
)
if
(
left_endpoint
&&
!
include_endpoint
)
...
@@ -6696,6 +6730,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
...
@@ -6696,6 +6730,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
Field
*
field
=
part_info
->
part_field_array
[
0
];
Field
*
field
=
part_info
->
part_field_array
[
0
];
uint32
max_endpoint_val
;
uint32
max_endpoint_val
;
get_endpoint_func
get_endpoint
;
get_endpoint_func
get_endpoint
;
bool
can_match_multiple_values
;
/* is not '=' */
uint
field_len
=
field
->
pack_length_in_rec
();
uint
field_len
=
field
->
pack_length_in_rec
();
part_iter
->
ret_null_part
=
part_iter
->
ret_null_part_orig
=
FALSE
;
part_iter
->
ret_null_part
=
part_iter
->
ret_null_part_orig
=
FALSE
;
...
@@ -6734,6 +6769,23 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
...
@@ -6734,6 +6769,23 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
else
else
assert
(
0
);
assert
(
0
);
can_match_multiple_values
=
(
flags
||
!
min_value
||
!
max_value
||
memcmp
(
min_value
,
max_value
,
field_len
));
if
(
can_match_multiple_values
&&
(
part_info
->
part_type
==
RANGE_PARTITION
||
part_info
->
has_null_value
))
{
/* Range scan on RANGE or LIST partitioned table */
enum_monotonicity_info
monotonic
;
monotonic
=
part_info
->
part_expr
->
get_monotonicity_info
();
if
(
monotonic
==
MONOTONIC_INCREASING_NOT_NULL
||
monotonic
==
MONOTONIC_STRICT_INCREASING_NOT_NULL
)
{
/* col is NOT NULL, but F(col) can return NULL, add NULL partition */
part_iter
->
ret_null_part
=
part_iter
->
ret_null_part_orig
=
TRUE
;
}
}
/*
/*
Find minimum: Do special handling if the interval has left bound in form
Find minimum: Do special handling if the interval has left bound in form
" NULL <= X ":
" NULL <= X ":
...
@@ -6765,6 +6817,14 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
...
@@ -6765,6 +6817,14 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
store_key_image_to_rec
(
field
,
min_value
,
field_len
);
store_key_image_to_rec
(
field
,
min_value
,
field_len
);
bool
include_endp
=
!
test
(
flags
&
NEAR_MIN
);
bool
include_endp
=
!
test
(
flags
&
NEAR_MIN
);
part_iter
->
part_nums
.
start
=
get_endpoint
(
part_info
,
1
,
include_endp
);
part_iter
->
part_nums
.
start
=
get_endpoint
(
part_info
,
1
,
include_endp
);
if
(
!
can_match_multiple_values
&&
part_info
->
part_expr
->
null_value
)
{
/* col = x and F(x) = NULL -> only search NULL partition */
part_iter
->
part_nums
.
cur
=
part_iter
->
part_nums
.
start
=
0
;
part_iter
->
part_nums
.
end
=
0
;
part_iter
->
ret_null_part
=
part_iter
->
ret_null_part_orig
=
TRUE
;
return
1
;
}
part_iter
->
part_nums
.
cur
=
part_iter
->
part_nums
.
start
;
part_iter
->
part_nums
.
cur
=
part_iter
->
part_nums
.
start
;
if
(
part_iter
->
part_nums
.
start
==
max_endpoint_val
)
if
(
part_iter
->
part_nums
.
start
==
max_endpoint_val
)
return
0
;
/* No partitions */
return
0
;
/* No partitions */
...
@@ -6959,7 +7019,13 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
...
@@ -6959,7 +7019,13 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
{
{
if
(
part_iter
->
part_nums
.
cur
>=
part_iter
->
part_nums
.
end
)
if
(
part_iter
->
part_nums
.
cur
>=
part_iter
->
part_nums
.
end
)
{
{
if
(
part_iter
->
ret_null_part
)
{
part_iter
->
ret_null_part
=
FALSE
;
return
0
;
/* NULL always in first range partition */
}
part_iter
->
part_nums
.
cur
=
part_iter
->
part_nums
.
start
;
part_iter
->
part_nums
.
cur
=
part_iter
->
part_nums
.
start
;
part_iter
->
ret_null_part
=
part_iter
->
ret_null_part_orig
;
return
NOT_A_PARTITION_ID
;
return
NOT_A_PARTITION_ID
;
}
}
else
else
...
@@ -6987,7 +7053,7 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
...
@@ -6987,7 +7053,7 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
uint32
get_next_partition_id_list
(
PARTITION_ITERATOR
*
part_iter
)
uint32
get_next_partition_id_list
(
PARTITION_ITERATOR
*
part_iter
)
{
{
if
(
part_iter
->
part_nums
.
cur
=
=
part_iter
->
part_nums
.
end
)
if
(
part_iter
->
part_nums
.
cur
>
=
part_iter
->
part_nums
.
end
)
{
{
if
(
part_iter
->
ret_null_part
)
if
(
part_iter
->
ret_null_part
)
{
{
...
...
sql/sql_table.cc
View file @
edb71b0c
...
@@ -72,7 +72,7 @@ static void wait_for_kill_signal(THD *thd)
...
@@ -72,7 +72,7 @@ static void wait_for_kill_signal(THD *thd)
@brief Helper function for explain_filename
@brief Helper function for explain_filename
*/
*/
static
char
*
add_identifier
(
char
*
to_p
,
const
char
*
end_p
,
static
char
*
add_identifier
(
char
*
to_p
,
const
char
*
end_p
,
const
char
*
name
,
uint
name_len
,
int
errcode
)
const
char
*
name
,
uint
name_len
,
bool
add_quotes
)
{
{
uint
res
;
uint
res
;
uint
errors
;
uint
errors
;
...
@@ -92,18 +92,44 @@ static char* add_identifier(char *to_p, const char * end_p,
...
@@ -92,18 +92,44 @@ static char* add_identifier(char *to_p, const char * end_p,
res
=
strconvert
(
&
my_charset_filename
,
conv_name
,
system_charset_info
,
res
=
strconvert
(
&
my_charset_filename
,
conv_name
,
system_charset_info
,
conv_string
,
FN_REFLEN
,
&
errors
);
conv_string
,
FN_REFLEN
,
&
errors
);
if
(
!
res
||
errors
)
if
(
!
res
||
errors
)
{
DBUG_PRINT
(
"error"
,
(
"strconvert of '%s' failed with %u (errors: %u)"
,
conv_name
,
res
,
errors
));
conv_name
=
name
;
conv_name
=
name
;
}
else
else
{
{
DBUG_PRINT
(
"info"
,
(
"conv '%s' -> '%s'"
,
conv_name
,
conv_string
));
DBUG_PRINT
(
"info"
,
(
"conv '%s' -> '%s'"
,
conv_name
,
conv_string
));
conv_name
=
conv_string
;
conv_name
=
conv_string
;
}
}
if
(
errcode
)
if
(
add_quotes
&&
(
end_p
-
to_p
>
2
))
to_p
+=
my_snprintf
(
to_p
,
end_p
-
to_p
,
ER
(
errcode
),
conv_name
);
{
*
(
to_p
++
)
=
'`'
;
while
(
*
conv_name
&&
(
end_p
-
to_p
-
1
)
>
0
)
{
uint
length
=
my_mbcharlen
(
system_charset_info
,
*
conv_name
);
if
(
!
length
)
length
=
1
;
if
(
length
==
1
&&
*
conv_name
==
'`'
)
{
if
((
end_p
-
to_p
)
<
3
)
break
;
*
(
to_p
++
)
=
'`'
;
*
(
to_p
++
)
=
*
(
conv_name
++
);
}
else
if
(
length
<
(
end_p
-
to_p
))
{
to_p
=
strnmov
(
to_p
,
conv_name
,
length
);
conv_name
+=
length
;
}
else
else
to_p
+=
my_snprintf
(
to_p
,
end_p
-
to_p
,
"`%s`"
,
conv_name
);
break
;
/* string already filled */
return
to_p
;
}
to_p
=
strnmov
(
to_p
,
"`"
,
end_p
-
to_p
);
}
else
to_p
=
strnmov
(
to_p
,
conv_name
,
end_p
-
to_p
);
DBUG_RETURN
(
to_p
);
}
}
...
@@ -135,6 +161,8 @@ static char* add_identifier(char *to_p, const char * end_p,
...
@@ -135,6 +161,8 @@ static char* add_identifier(char *to_p, const char * end_p,
[,[ Temporary| Renamed] Partition `p`
[,[ Temporary| Renamed] Partition `p`
[, Subpartition `sp`]] *|
[, Subpartition `sp`]] *|
(| is really a /, and it is all in one line)
(| is really a /, and it is all in one line)
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING ->
same as above but no quotes are added.
@retval Length of returned string
@retval Length of returned string
*/
*/
...
@@ -245,28 +273,39 @@ uint explain_filename(const char *from,
...
@@ -245,28 +273,39 @@ uint explain_filename(const char *from,
part_name_len
-=
5
;
part_name_len
-=
5
;
}
}
}
}
else
table_name_len
=
strlen
(
table_name
);
if
(
db_name
)
if
(
db_name
)
{
{
if
(
explain_mode
==
EXPLAIN_ALL_VERBOSE
)
if
(
explain_mode
==
EXPLAIN_ALL_VERBOSE
)
{
{
to_p
=
add_identifier
(
to_p
,
end_p
,
db_name
,
db_name_len
,
to_p
=
strnmov
(
to_p
,
ER
(
ER_DATABASE_NAME
),
end_p
-
to_p
);
ER_DATABASE_NAME
);
*
(
to_p
++
)
=
' '
;
to_p
=
add_identifier
(
to_p
,
end_p
,
db_name
,
db_name_len
,
1
);
to_p
=
strnmov
(
to_p
,
", "
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
", "
,
end_p
-
to_p
);
}
}
else
else
{
{
to_p
=
add_identifier
(
to_p
,
end_p
,
db_name
,
db_name_len
,
0
);
to_p
=
add_identifier
(
to_p
,
end_p
,
db_name
,
db_name_len
,
(
explain_mode
!=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
));
to_p
=
strnmov
(
to_p
,
"."
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
"."
,
end_p
-
to_p
);
}
}
}
}
if
(
explain_mode
==
EXPLAIN_ALL_VERBOSE
)
if
(
explain_mode
==
EXPLAIN_ALL_VERBOSE
)
to_p
=
add_identifier
(
to_p
,
end_p
,
table_name
,
table_name_len
,
{
ER_TABLE_NAME
);
to_p
=
strnmov
(
to_p
,
ER
(
ER_TABLE_NAME
),
end_p
-
to_p
);
*
(
to_p
++
)
=
' '
;
to_p
=
add_identifier
(
to_p
,
end_p
,
table_name
,
table_name_len
,
1
);
}
else
else
to_p
=
add_identifier
(
to_p
,
end_p
,
table_name
,
table_name_len
,
0
);
to_p
=
add_identifier
(
to_p
,
end_p
,
table_name
,
table_name_len
,
(
explain_mode
!=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
));
if
(
part_name
)
if
(
part_name
)
{
{
if
(
explain_mode
==
EXPLAIN_PARTITIONS_AS_COMMENT
)
if
(
explain_mode
==
EXPLAIN_PARTITIONS_AS_COMMENT
||
explain_mode
==
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
)
to_p
=
strnmov
(
to_p
,
" /* "
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
" /* "
,
end_p
-
to_p
);
else
if
(
explain_mode
==
EXPLAIN_PARTITIONS_VERBOSE
)
else
if
(
explain_mode
==
EXPLAIN_PARTITIONS_VERBOSE
)
to_p
=
strnmov
(
to_p
,
" "
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
" "
,
end_p
-
to_p
);
...
@@ -280,15 +319,22 @@ uint explain_filename(const char *from,
...
@@ -280,15 +319,22 @@ uint explain_filename(const char *from,
to_p
=
strnmov
(
to_p
,
ER
(
ER_RENAMED_NAME
),
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
ER
(
ER_RENAMED_NAME
),
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
" "
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
" "
,
end_p
-
to_p
);
}
}
to_p
=
strnmov
(
to_p
,
ER
(
ER_PARTITION_NAME
),
end_p
-
to_p
);
*
(
to_p
++
)
=
' '
;
to_p
=
add_identifier
(
to_p
,
end_p
,
part_name
,
part_name_len
,
to_p
=
add_identifier
(
to_p
,
end_p
,
part_name
,
part_name_len
,
ER_PARTITION_NAME
);
(
explain_mode
!=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
));
if
(
subpart_name
)
if
(
subpart_name
)
{
{
to_p
=
strnmov
(
to_p
,
", "
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
", "
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
ER
(
ER_SUBPARTITION_NAME
),
end_p
-
to_p
);
*
(
to_p
++
)
=
' '
;
to_p
=
add_identifier
(
to_p
,
end_p
,
subpart_name
,
subpart_name_len
,
to_p
=
add_identifier
(
to_p
,
end_p
,
subpart_name
,
subpart_name_len
,
ER_SUBPARTITION_NAME
);
(
explain_mode
!=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
));
}
}
if
(
explain_mode
==
EXPLAIN_PARTITIONS_AS_COMMENT
)
if
(
explain_mode
==
EXPLAIN_PARTITIONS_AS_COMMENT
||
explain_mode
==
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
)
to_p
=
strnmov
(
to_p
,
" */"
,
end_p
-
to_p
);
to_p
=
strnmov
(
to_p
,
" */"
,
end_p
-
to_p
);
}
}
DBUG_PRINT
(
"exit"
,
(
"to '%s'"
,
to
));
DBUG_PRINT
(
"exit"
,
(
"to '%s'"
,
to
));
...
...
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