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
7f2b3267
Commit
7f2b3267
authored
May 04, 2005
by
tulin@dl145b.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into dl145b.mysql.com:/home/ndbdev/tomas/mysql-5.1
parents
daff7c94
c78b2d25
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
214 additions
and
9 deletions
+214
-9
mysql-test/r/ps.result
mysql-test/r/ps.result
+25
-0
mysql-test/r/type_datetime.result
mysql-test/r/type_datetime.result
+1
-1
mysql-test/t/ps.test
mysql-test/t/ps.test
+27
-0
sql/item.cc
sql/item.cc
+132
-1
sql/item.h
sql/item.h
+25
-4
sql/item_func.cc
sql/item_func.cc
+3
-2
support-files/mysql.server.sh
support-files/mysql.server.sh
+1
-1
No files found.
mysql-test/r/ps.result
View file @
7f2b3267
...
@@ -570,3 +570,28 @@ id
...
@@ -570,3 +570,28 @@ id
deallocate prepare stmt|
deallocate prepare stmt|
drop procedure p1|
drop procedure p1|
drop table t1|
drop table t1|
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
create table t1 (c1 int(11) not null, c2 int(11) not null,
primary key (c1,c2), key c2 (c2), key c1 (c1));
insert into t1 values (200887, 860);
insert into t1 values (200887, 200887);
select * from t1 where (c1=200887 and c2=200887) or c2=860;
c1 c2
200887 860
200887 200887
prepare stmt from
"select * from t1 where (c1=200887 and c2=200887) or c2=860";
execute stmt;
c1 c2
200887 860
200887 200887
prepare stmt from
"select * from t1 where (c1=200887 and c2=?) or c2=?";
set @a=200887, @b=860;
execute stmt using @a, @b;
c1 c2
200887 860
200887 200887
deallocate prepare stmt;
mysql-test/r/type_datetime.result
View file @
7f2b3267
...
@@ -88,7 +88,7 @@ date numfacture expedition
...
@@ -88,7 +88,7 @@ date numfacture expedition
0000-00-00 00:00:00 1212 0001-00-00 00:00:00
0000-00-00 00:00:00 1212 0001-00-00 00:00:00
EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
EXPLAIN SELECT * FROM t1 WHERE expedition='0001-00-00 00:00:00';
id select_type table type possible_keys key key_len ref rows Extra
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref expedition expedition 8 const 1
Using where
1 SIMPLE t1 ref expedition expedition 8 const 1
drop table t1;
drop table t1;
create table t1 (a datetime not null, b datetime not null);
create table t1 (a datetime not null, b datetime not null);
insert into t1 values (now(), now());
insert into t1 values (now(), now());
...
...
mysql-test/t/ps.test
View file @
7f2b3267
...
@@ -587,3 +587,30 @@ deallocate prepare stmt|
...
@@ -587,3 +587,30 @@ deallocate prepare stmt|
drop
procedure
p1
|
drop
procedure
p1
|
drop
table
t1
|
drop
table
t1
|
delimiter
;
|
delimiter
;
|
#
# Bug#9096 "select doesn't return all matched records if prepared statements
# is used"
# The bug was is bad co-operation of the optimizer's algorithm which determines
# which keys can be used to execute a query, constants propagation
# part of the optimizer and parameter markers used by prepared statements.
drop
table
if
exists
t1
;
create
table
t1
(
c1
int
(
11
)
not
null
,
c2
int
(
11
)
not
null
,
primary
key
(
c1
,
c2
),
key
c2
(
c2
),
key
c1
(
c1
));
insert
into
t1
values
(
200887
,
860
);
insert
into
t1
values
(
200887
,
200887
);
select
*
from
t1
where
(
c1
=
200887
and
c2
=
200887
)
or
c2
=
860
;
prepare
stmt
from
"select * from t1 where (c1=200887 and c2=200887) or c2=860"
;
execute
stmt
;
prepare
stmt
from
"select * from t1 where (c1=200887 and c2=?) or c2=?"
;
set
@
a
=
200887
,
@
b
=
860
;
# this query did not return all matching rows
execute
stmt
using
@
a
,
@
b
;
deallocate
prepare
stmt
;
sql/item.cc
View file @
7f2b3267
...
@@ -558,6 +558,11 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
...
@@ -558,6 +558,11 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
bool
Item
::
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
bool
Item
::
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
{
/*
Note, that this is never TRUE if item is a Item_param:
for all basic constants we have special checks, and Item_param's
type() can be only among basic constant types.
*/
return
type
()
==
item
->
type
()
&&
name
&&
item
->
name
&&
return
type
()
==
item
->
type
()
&&
name
&&
item
->
name
&&
!
my_strcasecmp
(
system_charset_info
,
name
,
item
->
name
);
!
my_strcasecmp
(
system_charset_info
,
name
,
item
->
name
);
}
}
...
@@ -602,7 +607,7 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
...
@@ -602,7 +607,7 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
bool
Item_string
::
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
bool
Item_string
::
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
{
if
(
type
()
==
item
->
type
())
if
(
type
()
==
item
->
type
()
&&
item
->
basic_const_item
()
)
{
{
if
(
binary_cmp
)
if
(
binary_cmp
)
return
!
stringcmp
(
&
str_value
,
&
item
->
str_value
);
return
!
stringcmp
(
&
str_value
,
&
item
->
str_value
);
...
@@ -1444,6 +1449,24 @@ void Item_decimal::print(String *str)
...
@@ -1444,6 +1449,24 @@ void Item_decimal::print(String *str)
}
}
bool
Item_decimal
::
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
if
(
type
()
==
item
->
type
()
&&
item
->
basic_const_item
())
{
/*
We need to cast off const to call val_decimal(). This should
be OK for a basic constant. Additionally, we can pass 0 as
a true decimal constant will return its internal decimal
storage and ignore the argument.
*/
Item
*
arg
=
(
Item
*
)
item
;
my_decimal
*
value
=
arg
->
val_decimal
(
0
);
return
!
my_decimal_cmp
(
&
decimal_value
,
value
);
}
return
0
;
}
String
*
Item_float
::
val_str
(
String
*
str
)
String
*
Item_float
::
val_str
(
String
*
str
)
{
{
// following assert is redundant, because fixed=1 assigned in constructor
// following assert is redundant, because fixed=1 assigned in constructor
...
@@ -2195,6 +2218,72 @@ bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
...
@@ -2195,6 +2218,72 @@ bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
}
}
bool
Item_param
::
basic_const_item
()
const
{
if
(
state
==
NO_VALUE
||
state
==
TIME_VALUE
)
return
FALSE
;
return
TRUE
;
}
Item
*
Item_param
::
new_item
()
{
/* see comments in the header file */
switch
(
state
)
{
case
NULL_VALUE
:
return
new
Item_null
(
name
);
case
INT_VALUE
:
return
new
Item_int
(
name
,
value
.
integer
,
max_length
);
case
REAL_VALUE
:
return
new
Item_float
(
name
,
value
.
real
,
decimals
,
max_length
);
case
STRING_VALUE
:
case
LONG_DATA_VALUE
:
return
new
Item_string
(
name
,
str_value
.
c_ptr_quick
(),
str_value
.
length
(),
str_value
.
charset
());
case
TIME_VALUE
:
break
;
case
NO_VALUE
:
default:
DBUG_ASSERT
(
0
);
};
return
0
;
}
bool
Item_param
::
eq
(
const
Item
*
arg
,
bool
binary_cmp
)
const
{
Item
*
item
;
if
(
!
basic_const_item
()
||
!
arg
->
basic_const_item
()
||
arg
->
type
()
!=
type
())
return
FALSE
;
/*
We need to cast off const to call val_int(). This should be OK for
a basic constant.
*/
item
=
(
Item
*
)
arg
;
switch
(
state
)
{
case
NULL_VALUE
:
return
TRUE
;
case
INT_VALUE
:
return
value
.
integer
==
item
->
val_int
()
&&
unsigned_flag
==
item
->
unsigned_flag
;
case
REAL_VALUE
:
return
value
.
real
==
item
->
val_real
();
case
STRING_VALUE
:
case
LONG_DATA_VALUE
:
if
(
binary_cmp
)
return
!
stringcmp
(
&
str_value
,
&
item
->
str_value
);
return
!
sortcmp
(
&
str_value
,
&
item
->
str_value
,
collation
.
collation
);
default:
break
;
}
return
FALSE
;
}
/* End of Item_param related */
void
Item_param
::
print
(
String
*
str
)
void
Item_param
::
print
(
String
*
str
)
{
{
if
(
state
==
NO_VALUE
)
if
(
state
==
NO_VALUE
)
...
@@ -3412,6 +3501,22 @@ int Item_decimal::save_in_field(Field *field, bool no_conversions)
...
@@ -3412,6 +3501,22 @@ int Item_decimal::save_in_field(Field *field, bool no_conversions)
}
}
bool
Item_int
::
eq
(
const
Item
*
arg
,
bool
binary_cmp
)
const
{
/* No need to check for null value as basic constant can't be NULL */
if
(
arg
->
basic_const_item
()
&&
arg
->
type
()
==
type
())
{
/*
We need to cast off const to call val_int(). This should be OK for
a basic constant.
*/
Item
*
item
=
(
Item
*
)
arg
;
return
item
->
val_int
()
==
value
&&
item
->
unsigned_flag
==
unsigned_flag
;
}
return
FALSE
;
}
Item_num
*
Item_uint
::
neg
()
Item_num
*
Item_uint
::
neg
()
{
{
Item_decimal
*
item
=
new
Item_decimal
(
value
,
0
);
Item_decimal
*
item
=
new
Item_decimal
(
value
,
0
);
...
@@ -3499,6 +3604,21 @@ void Item_float::print(String *str)
...
@@ -3499,6 +3604,21 @@ void Item_float::print(String *str)
In number context this is a longlong value.
In number context this is a longlong value.
*/
*/
bool
Item_float
::
eq
(
const
Item
*
arg
,
bool
binary_cmp
)
const
{
if
(
arg
->
basic_const_item
()
&&
arg
->
type
()
==
type
())
{
/*
We need to cast off const to call val_int(). This should be OK for
a basic constant.
*/
Item
*
item
=
(
Item
*
)
arg
;
return
item
->
val_real
()
==
value
;
}
return
FALSE
;
}
inline
uint
char_val
(
char
X
)
inline
uint
char_val
(
char
X
)
{
{
return
(
uint
)
(
X
>=
'0'
&&
X
<=
'9'
?
X
-
'0'
:
return
(
uint
)
(
X
>=
'0'
&&
X
<=
'9'
?
X
-
'0'
:
...
@@ -3569,6 +3689,17 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions)
...
@@ -3569,6 +3689,17 @@ int Item_hex_string::save_in_field(Field *field, bool no_conversions)
}
}
bool
Item_hex_string
::
eq
(
const
Item
*
arg
,
bool
binary_cmp
)
const
{
if
(
arg
->
basic_const_item
()
&&
arg
->
type
()
==
type
())
{
if
(
binary_cmp
)
return
!
stringcmp
(
&
str_value
,
&
arg
->
str_value
);
return
!
sortcmp
(
&
str_value
,
&
arg
->
str_value
,
collation
.
collation
);
}
return
FALSE
;
}
/*
/*
bin item.
bin item.
In string context this is a binary string.
In string context this is a binary string.
...
...
sql/item.h
View file @
7f2b3267
...
@@ -434,7 +434,7 @@ public:
...
@@ -434,7 +434,7 @@ public:
virtual
table_map
not_null_tables
()
const
{
return
used_tables
();
}
virtual
table_map
not_null_tables
()
const
{
return
used_tables
();
}
/*
/*
Returns true if this is a simple constant item like an integer, not
Returns true if this is a simple constant item like an integer, not
a constant expression
a constant expression
. Used in the optimizer to propagate basic constants.
*/
*/
virtual
bool
basic_const_item
()
const
{
return
0
;
}
virtual
bool
basic_const_item
()
const
{
return
0
;
}
/* cloning of constant items (0 if it is not const) */
/* cloning of constant items (0 if it is not const) */
...
@@ -914,7 +914,6 @@ public:
...
@@ -914,7 +914,6 @@ public:
bool
convert_str_value
(
THD
*
thd
);
bool
convert_str_value
(
THD
*
thd
);
Item
*
new_item
()
{
return
new
Item_param
(
pos_in_query
);
}
/*
/*
If value for parameter was not set we treat it as non-const
If value for parameter was not set we treat it as non-const
so noone will use parameters value in fix_fields still
so noone will use parameters value in fix_fields still
...
@@ -923,12 +922,29 @@ public:
...
@@ -923,12 +922,29 @@ public:
virtual
table_map
used_tables
()
const
virtual
table_map
used_tables
()
const
{
return
state
!=
NO_VALUE
?
(
table_map
)
0
:
PARAM_TABLE_BIT
;
}
{
return
state
!=
NO_VALUE
?
(
table_map
)
0
:
PARAM_TABLE_BIT
;
}
void
print
(
String
*
str
);
void
print
(
String
*
str
);
/* parameter never equal to other parameter of other item */
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
return
0
;
}
bool
is_null
()
bool
is_null
()
{
DBUG_ASSERT
(
state
!=
NO_VALUE
);
return
state
==
NULL_VALUE
;
}
{
DBUG_ASSERT
(
state
!=
NO_VALUE
);
return
state
==
NULL_VALUE
;
}
bool
basic_const_item
()
const
;
/*
This method is used to make a copy of a basic constant item when
propagating constants in the optimizer. The reason to create a new
item and not use the existing one is not precisely known (2005/04/16).
Probably we are trying to preserve tree structure of items, in other
words, avoid pointing at one item from two different nodes of the tree.
Return a new basic constant item if parameter value is a basic
constant, assert otherwise. This method is called only if
basic_const_item returned TRUE.
*/
Item
*
new_item
();
/*
Implement by-value equality evaluation if parameter value
is set and is a basic constant (integer, real or string).
Otherwise return FALSE.
*/
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
;
};
};
class
Item_int
:
public
Item_num
class
Item_int
:
public
Item_num
{
{
public:
public:
...
@@ -956,6 +972,7 @@ public:
...
@@ -956,6 +972,7 @@ public:
void
cleanup
()
{}
void
cleanup
()
{}
void
print
(
String
*
str
);
void
print
(
String
*
str
);
Item_num
*
neg
()
{
value
=
-
value
;
return
this
;
}
Item_num
*
neg
()
{
value
=
-
value
;
return
this
;
}
bool
eq
(
const
Item
*
,
bool
binary_cmp
)
const
;
};
};
...
@@ -1022,8 +1039,10 @@ public:
...
@@ -1022,8 +1039,10 @@ public:
unsigned_flag
=
!
decimal_value
.
sign
();
unsigned_flag
=
!
decimal_value
.
sign
();
return
this
;
return
this
;
}
}
bool
eq
(
const
Item
*
,
bool
binary_cmp
)
const
;
};
};
class
Item_float
:
public
Item_num
class
Item_float
:
public
Item_num
{
{
char
*
presentation
;
char
*
presentation
;
...
@@ -1059,6 +1078,7 @@ public:
...
@@ -1059,6 +1078,7 @@ public:
{
return
new
Item_float
(
name
,
value
,
decimals
,
max_length
);
}
{
return
new
Item_float
(
name
,
value
,
decimals
,
max_length
);
}
Item_num
*
neg
()
{
value
=
-
value
;
return
this
;
}
Item_num
*
neg
()
{
value
=
-
value
;
return
this
;
}
void
print
(
String
*
str
);
void
print
(
String
*
str
);
bool
eq
(
const
Item
*
,
bool
binary_cmp
)
const
;
};
};
...
@@ -1198,6 +1218,7 @@ public:
...
@@ -1198,6 +1218,7 @@ public:
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_VARCHAR
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_VARCHAR
;
}
// to prevent drop fixed flag (no need parent cleanup call)
// to prevent drop fixed flag (no need parent cleanup call)
void
cleanup
()
{}
void
cleanup
()
{}
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
;
};
};
...
...
sql/item_func.cc
View file @
7f2b3267
...
@@ -1395,11 +1395,12 @@ void Item_func_neg::fix_length_and_dec()
...
@@ -1395,11 +1395,12 @@ void Item_func_neg::fix_length_and_dec()
/*
/*
If this is in integer context keep the context as integer if possible
If this is in integer context keep the context as integer if possible
(This is how multiplication and other integer functions works)
(This is how multiplication and other integer functions works)
Use val() to get value as arg_type doesn't mean that item is
Item_int or Item_real due to existence of Item_param.
*/
*/
if
(
hybrid_type
==
INT_RESULT
&&
if
(
hybrid_type
==
INT_RESULT
&&
args
[
0
]
->
type
()
==
INT_ITEM
&&
args
[
0
]
->
type
()
==
INT_ITEM
&&
((
ulonglong
)
((
Item_uint
*
)
args
[
0
])
->
value
>=
((
ulonglong
)
args
[
0
]
->
val_int
()
>=
(
ulonglong
)
LONGLONG_MIN
))
(
ulonglong
)
LONGLONG_MIN
))
{
{
/*
/*
Ensure that result is converted to DECIMAL, as longlong can't hold
Ensure that result is converted to DECIMAL, as longlong can't hold
...
...
support-files/mysql.server.sh
View file @
7f2b3267
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
# started and shut down when the systems goes down.
# started and shut down when the systems goes down.
# Comments to support chkconfig on RedHat Linux
# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345
90 20
# chkconfig: 2345
64 36
# description: A very fast and reliable SQL database engine.
# description: A very fast and reliable SQL database engine.
# Comments to support LSB init script conventions
# Comments to support LSB init script conventions
...
...
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