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
47d850a8
Commit
47d850a8
authored
Nov 06, 2009
by
Evgeny Potemkin
Browse files
Options
Browse Files
Download
Plain Diff
Auto-merged fix for the bug#34384.
parents
9ea972dc
60d358af
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
198 additions
and
40 deletions
+198
-40
sql/item.cc
sql/item.cc
+111
-18
sql/item.h
sql/item.h
+35
-15
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+43
-4
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+2
-0
sql/item_subselect.cc
sql/item_subselect.cc
+2
-0
sql/item_xmlfunc.cc
sql/item_xmlfunc.cc
+4
-2
sql/sp_rcontext.cc
sql/sp_rcontext.cc
+1
-1
No files found.
sql/item.cc
View file @
47d850a8
...
...
@@ -6940,7 +6940,22 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
Item_cache
*
Item_cache
::
get_cache
(
const
Item
*
item
)
{
switch
(
item
->
result_type
())
{
return
get_cache
(
item
,
item
->
result_type
());
}
/**
Get a cache item of given type.
@param item value to be cached
@param type required type of cache
@return cache item
*/
Item_cache
*
Item_cache
::
get_cache
(
const
Item
*
item
,
const
Item_result
type
)
{
switch
(
type
)
{
case
INT_RESULT
:
return
new
Item_cache_int
();
case
REAL_RESULT
:
...
...
@@ -6958,6 +6973,12 @@ Item_cache* Item_cache::get_cache(const Item *item)
}
}
void
Item_cache
::
store
(
Item
*
item
)
{
if
(
item
)
example
=
item
;
value_cached
=
FALSE
;
}
void
Item_cache
::
print
(
String
*
str
,
enum_query_type
query_type
)
{
...
...
@@ -6969,17 +6990,19 @@ void Item_cache::print(String *str, enum_query_type query_type)
str
->
append
(
')'
);
}
void
Item_cache_int
::
store
(
Item
*
item
)
void
Item_cache_int
::
cache_value
()
{
value
=
item
->
val_int_result
();
null_value
=
item
->
null_value
;
unsigned_flag
=
item
->
unsigned_flag
;
value_cached
=
TRUE
;
value
=
example
->
val_int_result
();
null_value
=
example
->
null_value
;
unsigned_flag
=
example
->
unsigned_flag
;
}
void
Item_cache_int
::
store
(
Item
*
item
,
longlong
val_arg
)
{
/* An explicit values is given, save it. */
value_cached
=
TRUE
;
value
=
val_arg
;
null_value
=
item
->
null_value
;
unsigned_flag
=
item
->
unsigned_flag
;
...
...
@@ -6989,6 +7012,8 @@ void Item_cache_int::store(Item *item, longlong val_arg)
String
*
Item_cache_int
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
str
->
set
(
value
,
default_charset
());
return
str
;
}
...
...
@@ -6997,21 +7022,49 @@ String *Item_cache_int::val_str(String *str)
my_decimal
*
Item_cache_int
::
val_decimal
(
my_decimal
*
decimal_val
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
int2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
unsigned_flag
,
decimal_val
);
return
decimal_val
;
}
double
Item_cache_int
::
val_real
()
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
return
(
double
)
value
;
}
void
Item_cache_real
::
store
(
Item
*
item
)
longlong
Item_cache_int
::
val_int
(
)
{
value
=
item
->
val_result
();
null_value
=
item
->
null_value
;
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
return
value
;
}
void
Item_cache_real
::
cache_value
()
{
value_cached
=
TRUE
;
value
=
example
->
val_result
();
null_value
=
example
->
null_value
;
}
double
Item_cache_real
::
val_real
()
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
return
value
;
}
longlong
Item_cache_real
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
return
(
longlong
)
rint
(
value
);
}
...
...
@@ -7019,6 +7072,8 @@ longlong Item_cache_real::val_int()
String
*
Item_cache_real
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
str
->
set_real
(
value
,
decimals
,
default_charset
());
return
str
;
}
...
...
@@ -7027,15 +7082,18 @@ String* Item_cache_real::val_str(String *str)
my_decimal
*
Item_cache_real
::
val_decimal
(
my_decimal
*
decimal_val
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
double2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
return
decimal_val
;
}
void
Item_cache_decimal
::
store
(
Item
*
item
)
void
Item_cache_decimal
::
cache_value
(
)
{
my_decimal
*
val
=
item
->
val_decimal_result
(
&
decimal_value
);
if
(
!
(
null_value
=
item
->
null_value
)
&&
val
!=
&
decimal_value
)
value_cached
=
TRUE
;
my_decimal
*
val
=
example
->
val_decimal_result
(
&
decimal_value
);
if
(
!
(
null_value
=
example
->
null_value
)
&&
val
!=
&
decimal_value
)
my_decimal2decimal
(
val
,
&
decimal_value
);
}
...
...
@@ -7043,6 +7101,8 @@ double Item_cache_decimal::val_real()
{
DBUG_ASSERT
(
fixed
);
double
res
;
if
(
!
value_cached
)
cache_value
();
my_decimal2double
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
&
res
);
return
res
;
}
...
...
@@ -7051,6 +7111,8 @@ longlong Item_cache_decimal::val_int()
{
DBUG_ASSERT
(
fixed
);
longlong
res
;
if
(
!
value_cached
)
cache_value
();
my_decimal2int
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
unsigned_flag
,
&
res
);
return
res
;
}
...
...
@@ -7058,6 +7120,8 @@ longlong Item_cache_decimal::val_int()
String
*
Item_cache_decimal
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
);
if
(
!
value_cached
)
cache_value
();
my_decimal_round
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
decimals
,
FALSE
,
&
decimal_value
);
my_decimal2string
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
0
,
0
,
0
,
str
);
...
...
@@ -7067,15 +7131,18 @@ String* Item_cache_decimal::val_str(String *str)
my_decimal
*
Item_cache_decimal
::
val_decimal
(
my_decimal
*
val
)
{
DBUG_ASSERT
(
fixed
);
if
(
!
value_cached
)
cache_value
();
return
&
decimal_value
;
}
void
Item_cache_str
::
store
(
Item
*
item
)
void
Item_cache_str
::
cache_value
(
)
{
value_buff
.
set
(
buffer
,
sizeof
(
buffer
),
item
->
collation
.
collation
);
value
=
item
->
str_result
(
&
value_buff
);
if
((
null_value
=
item
->
null_value
))
value_cached
=
TRUE
;
value_buff
.
set
(
buffer
,
sizeof
(
buffer
),
example
->
collation
.
collation
);
value
=
example
->
str_result
(
&
value_buff
);
if
((
null_value
=
example
->
null_value
))
value
=
0
;
else
if
(
value
!=
&
value_buff
)
{
...
...
@@ -7097,6 +7164,8 @@ double Item_cache_str::val_real()
DBUG_ASSERT
(
fixed
==
1
);
int
err_not_used
;
char
*
end_not_used
;
if
(
!
value_cached
)
cache_value
();
if
(
value
)
return
my_strntod
(
value
->
charset
(),
(
char
*
)
value
->
ptr
(),
value
->
length
(),
&
end_not_used
,
&
err_not_used
);
...
...
@@ -7108,6 +7177,8 @@ longlong Item_cache_str::val_int()
{
DBUG_ASSERT
(
fixed
==
1
);
int
err
;
if
(
!
value_cached
)
cache_value
();
if
(
value
)
return
my_strntoll
(
value
->
charset
(),
value
->
ptr
(),
value
->
length
(),
10
,
(
char
**
)
0
,
&
err
);
...
...
@@ -7115,9 +7186,21 @@ longlong Item_cache_str::val_int()
return
(
longlong
)
0
;
}
String
*
Item_cache_str
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
return
value
;
}
my_decimal
*
Item_cache_str
::
val_decimal
(
my_decimal
*
decimal_val
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
();
if
(
value
)
string2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
else
...
...
@@ -7128,6 +7211,8 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
int
Item_cache_str
::
save_in_field
(
Field
*
field
,
bool
no_conversions
)
{
if
(
!
value_cached
)
cache_value
();
int
res
=
Item_cache
::
save_in_field
(
field
,
no_conversions
);
return
(
is_varbinary
&&
field
->
type
()
==
MYSQL_TYPE_STRING
&&
value
->
length
()
<
field
->
field_length
)
?
1
:
res
;
...
...
@@ -7162,11 +7247,19 @@ bool Item_cache_row::setup(Item * item)
void
Item_cache_row
::
store
(
Item
*
item
)
{
for
(
uint
i
=
0
;
i
<
item_count
;
i
++
)
values
[
i
]
->
store
(
item
->
element_index
(
i
));
}
void
Item_cache_row
::
cache_value
()
{
value_cached
=
TRUE
;
null_value
=
0
;
item
->
bring_value
();
example
->
bring_value
();
for
(
uint
i
=
0
;
i
<
item_count
;
i
++
)
{
values
[
i
]
->
store
(
item
->
element_index
(
i
)
);
values
[
i
]
->
cache_value
(
);
null_value
|=
values
[
i
]
->
null_value
;
}
}
...
...
sql/item.h
View file @
47d850a8
...
...
@@ -1024,7 +1024,11 @@ class sp_head;
class
Item_basic_constant
:
public
Item
{
table_map
used_table_map
;
public:
Item_basic_constant
()
:
Item
(),
used_table_map
(
0
)
{};
void
set_used_tables
(
table_map
map
)
{
used_table_map
=
map
;
}
table_map
used_tables
()
const
{
return
used_table_map
;
}
/* to prevent drop fixed flag (no need parent cleanup call) */
void
cleanup
()
{
...
...
@@ -2889,15 +2893,25 @@ protected:
*/
Field
*
cached_field
;
enum
enum_field_types
cached_field_type
;
/*
TRUE <=> cache holds value of the last stored item (i.e actual value).
store() stores item to be cached and sets this flag to FALSE.
On the first call of val_xxx function if this flag is set to FALSE the
cache_value() will be called to actually cache value of saved item.
cache_value() will set this flag to TRUE.
*/
bool
value_cached
;
public:
Item_cache
()
:
example
(
0
),
used_table_map
(
0
),
cached_field
(
0
),
cached_field_type
(
MYSQL_TYPE_STRING
)
Item_cache
()
:
example
(
0
),
used_table_map
(
0
),
cached_field
(
0
),
cached_field_type
(
MYSQL_TYPE_STRING
),
value_cached
(
0
)
{
fixed
=
1
;
null_value
=
1
;
}
Item_cache
(
enum_field_types
field_type_arg
)
:
example
(
0
),
used_table_map
(
0
),
cached_field
(
0
),
cached_field_type
(
field_type_arg
)
example
(
0
),
used_table_map
(
0
),
cached_field
(
0
),
cached_field_type
(
field_type_arg
),
value_cached
(
0
)
{
fixed
=
1
;
null_value
=
1
;
...
...
@@ -2917,10 +2931,10 @@ public:
cached_field
=
((
Item_field
*
)
item
)
->
field
;
return
0
;
};
virtual
void
store
(
Item
*
)
=
0
;
enum
Type
type
()
const
{
return
CACHE_ITEM
;
}
enum_field_types
field_type
()
const
{
return
cached_field_type
;
}
static
Item_cache
*
get_cache
(
const
Item
*
item
);
static
Item_cache
*
get_cache
(
const
Item
*
item
,
const
Item_result
type
);
table_map
used_tables
()
const
{
return
used_table_map
;
}
virtual
void
keep_array
()
{}
virtual
void
print
(
String
*
str
,
enum_query_type
query_type
);
...
...
@@ -2932,6 +2946,8 @@ public:
{
return
this
==
item
;
}
virtual
void
store
(
Item
*
item
);
virtual
void
cache_value
()
=
0
;
};
...
...
@@ -2940,18 +2956,19 @@ class Item_cache_int: public Item_cache
protected:
longlong
value
;
public:
Item_cache_int
()
:
Item_cache
(),
value
(
0
)
{}
Item_cache_int
()
:
Item_cache
(),
value
(
0
)
{}
Item_cache_int
(
enum_field_types
field_type_arg
)
:
Item_cache
(
field_type_arg
),
value
(
0
)
{}
void
store
(
Item
*
item
);
void
store
(
Item
*
item
,
longlong
val_arg
);
double
val_real
()
{
DBUG_ASSERT
(
fixed
==
1
);
return
(
double
)
value
;
}
longlong
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
return
value
;
}
double
val_real
()
;
longlong
val_int
()
;
String
*
val_str
(
String
*
str
);
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
INT_RESULT
;
}
bool
result_as_longlong
()
{
return
TRUE
;
}
void
cache_value
();
};
...
...
@@ -2959,14 +2976,15 @@ class Item_cache_real: public Item_cache
{
double
value
;
public:
Item_cache_real
()
:
Item_cache
(),
value
(
0
)
{}
Item_cache_real
()
:
Item_cache
(),
value
(
0
)
{}
void
store
(
Item
*
item
);
double
val_real
()
{
DBUG_ASSERT
(
fixed
==
1
);
return
value
;
}
double
val_real
();
longlong
val_int
();
String
*
val_str
(
String
*
str
);
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
REAL_RESULT
;
}
void
cache_value
();
};
...
...
@@ -2977,12 +2995,12 @@ protected:
public:
Item_cache_decimal
()
:
Item_cache
()
{}
void
store
(
Item
*
item
);
double
val_real
();
longlong
val_int
();
String
*
val_str
(
String
*
str
);
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
DECIMAL_RESULT
;
}
void
cache_value
();
};
...
...
@@ -3000,14 +3018,14 @@ public:
MYSQL_TYPE_VARCHAR
&&
!
((
const
Item_field
*
)
item
)
->
field
->
has_charset
())
{}
void
store
(
Item
*
item
);
double
val_real
();
longlong
val_int
();
String
*
val_str
(
String
*
)
{
DBUG_ASSERT
(
fixed
==
1
);
return
value
;
}
String
*
val_str
(
String
*
)
;
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
CHARSET_INFO
*
charset
()
const
{
return
value
->
charset
();
};
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
void
cache_value
();
};
class
Item_cache_row
:
public
Item_cache
...
...
@@ -3017,7 +3035,8 @@ class Item_cache_row: public Item_cache
bool
save_array
;
public:
Item_cache_row
()
:
Item_cache
(),
values
(
0
),
item_count
(
2
),
save_array
(
0
)
{}
:
Item_cache
(),
values
(
0
),
item_count
(
2
),
save_array
(
0
)
{}
/*
'allocate' used only in row transformer, to preallocate space for row
...
...
@@ -3075,6 +3094,7 @@ public:
values
=
0
;
DBUG_VOID_RETURN
;
}
void
cache_value
();
};
...
...
sql/item_cmpfunc.cc
View file @
47d850a8
...
...
@@ -887,13 +887,13 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
{
enum
enum_date_cmp_type
cmp_type
;
ulonglong
const_value
=
(
ulonglong
)
-
1
;
thd
=
current_thd
;
owner
=
owner_arg
;
a
=
a1
;
b
=
a2
;
if
((
cmp_type
=
can_compare_as_dates
(
*
a
,
*
b
,
&
const_value
)))
{
thd
=
current_thd
;
owner
=
owner_arg
;
a_type
=
(
*
a
)
->
field_type
();
b_type
=
(
*
b
)
->
field_type
();
a_cache
=
0
;
...
...
@@ -901,6 +901,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
if
(
const_value
!=
(
ulonglong
)
-
1
)
{
/*
cache_converted_constant can't be used here because it can't
correctly convert a DATETIME value from string to int representation.
*/
Item_cache_int
*
cache
=
new
Item_cache_int
();
/* Mark the cache as non-const to prevent re-caching. */
cache
->
set_used_tables
(
1
);
...
...
@@ -926,8 +930,6 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
(
*
b
)
->
field_type
()
==
MYSQL_TYPE_TIME
)
{
/* Compare TIME values as integers. */
thd
=
current_thd
;
owner
=
owner_arg
;
a_cache
=
0
;
b_cache
=
0
;
is_nulls_eq
=
test
(
owner
&&
owner
->
functype
()
==
Item_func
::
EQUAL_FUNC
);
...
...
@@ -946,10 +948,46 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
return
1
;
}
a
=
cache_converted_constant
(
thd
,
a
,
&
a_cache
,
type
);
b
=
cache_converted_constant
(
thd
,
b
,
&
b_cache
,
type
);
return
set_compare_func
(
owner_arg
,
type
);
}
/**
Convert and cache a constant.
@param value [in] An item to cache
@param cache_item [out] Placeholder for the cache item
@param type [in] Comparison type
@details
When given item is a constant and its type differs from comparison type
then cache its value to avoid type conversion of this constant on each
evaluation. In this case the value is cached and the reference to the cache
is returned.
Original value is returned otherwise.
@return cache item or original value.
*/
Item
**
Arg_comparator
::
cache_converted_constant
(
THD
*
thd
,
Item
**
value
,
Item
**
cache_item
,
Item_result
type
)
{
/* Don't need cache if doing context analysis only. */
if
(
!
thd
->
is_context_analysis_only
()
&&
(
*
value
)
->
const_item
()
&&
type
!=
(
*
value
)
->
result_type
())
{
Item_cache
*
cache
=
Item_cache
::
get_cache
(
*
value
,
type
);
cache
->
store
(
*
value
);
*
cache_item
=
cache
;
return
cache_item
;
}
return
value
;
}
void
Arg_comparator
::
set_datetime_cmp_func
(
Item
**
a1
,
Item
**
b1
)
{
thd
=
current_thd
;
...
...
@@ -1588,6 +1626,7 @@ longlong Item_in_optimizer::val_int()
bool
tmp
;
DBUG_ASSERT
(
fixed
==
1
);
cache
->
store
(
args
[
0
]);
cache
->
cache_value
();
if
(
cache
->
null_value
)
{
...
...
sql/item_cmpfunc.h
View file @
47d850a8
...
...
@@ -94,6 +94,8 @@ public:
ulonglong
*
const_val_arg
);
void
set_datetime_cmp_func
(
Item
**
a1
,
Item
**
b1
);
Item
**
cache_converted_constant
(
THD
*
thd
,
Item
**
value
,
Item
**
cache
,
Item_result
type
);
static
arg_cmp_func
comparator_matrix
[
5
][
2
];
friend
class
Item_func
;
...
...
sql/item_subselect.cc
View file @
47d850a8
...
...
@@ -480,6 +480,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
void
Item_singlerow_subselect
::
store
(
uint
i
,
Item
*
item
)
{
row
[
i
]
->
store
(
item
);
row
[
i
]
->
cache_value
();
}
enum
Item_result
Item_singlerow_subselect
::
result_type
()
const
...
...
@@ -1831,6 +1832,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
if
(
!
(
row
[
i
]
=
Item_cache
::
get_cache
(
sel_item
)))
return
;
row
[
i
]
->
setup
(
sel_item
);
row
[
i
]
->
store
(
sel_item
);
}
if
(
item_list
.
elements
>
1
)
res_type
=
ROW_RESULT
;
...
...
sql/item_xmlfunc.cc
View file @
47d850a8
...
...
@@ -941,14 +941,16 @@ static Item *create_comparator(MY_XPATH *xpath,
in a loop through all of the nodes in the node set.
*/
Item
*
fake
=
new
Item_string
(
""
,
0
,
xpath
->
cs
);
Item_string
*
fake
=
new
Item_string
(
""
,
0
,
xpath
->
cs
);
/* Don't cache fake because its value will be changed during comparison.*/
fake
->
set_used_tables
(
RAND_TABLE_BIT
);
Item_nodeset_func
*
nodeset
;
Item
*
scalar
,
*
comp
;
if
(
a
->
type
()
==
Item
::
XPATH_NODESET
)
{
nodeset
=
(
Item_nodeset_func
*
)
a
;
scalar
=
b
;
comp
=
eq_func
(
oper
,
fake
,
scalar
);
comp
=
eq_func
(
oper
,
(
Item
*
)
fake
,
scalar
);
}
else
{
...
...
sql/sp_rcontext.cc
View file @
47d850a8
...
...
@@ -617,7 +617,7 @@ sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr
}
m_case_expr_holders
[
case_expr_id
]
->
store
(
case_expr_item
);
m_case_expr_holders
[
case_expr_id
]
->
cache_value
();
return
FALSE
;
}
...
...
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