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
fd98ed36
Commit
fd98ed36
authored
Feb 19, 2004
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Manual merge
parent
f4353d48
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
224 additions
and
138 deletions
+224
-138
sql/item.h
sql/item.h
+60
-29
sql/opt_range.cc
sql/opt_range.cc
+73
-31
sql/sql_select.cc
sql/sql_select.cc
+91
-78
No files found.
sql/item.h
View file @
fd98ed36
...
...
@@ -126,8 +126,8 @@ public:
top AND/OR ctructure of WHERE clause to protect it of
optimisation changes in prepared statements
*/
Item
(
THD
*
thd
,
Item
&
item
);
virtual
~
Item
()
{
name
=
0
;
cleanup
();
}
/*lint -e1509 */
Item
(
THD
*
thd
,
Item
*
item
);
virtual
~
Item
()
{
name
=
0
;
}
/*lint -e1509 */
void
set_name
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
);
void
init_make_field
(
Send_field
*
tmp_field
,
enum
enum_field_types
type
);
virtual
void
cleanup
()
{
fixed
=
0
;
}
...
...
@@ -206,6 +206,7 @@ public:
virtual
Item
*
get_tmp_table_item
(
THD
*
thd
)
{
return
copy_or_same
(
thd
);
}
CHARSET_INFO
*
default_charset
()
const
;
virtual
CHARSET_INFO
*
compare_collation
()
{
return
NULL
;
}
virtual
bool
walk
(
Item_processor
processor
,
byte
*
arg
)
{
...
...
@@ -239,6 +240,11 @@ public:
/* Used in sql_select.cc:eliminate_not_funcs() */
virtual
Item
*
neg_transformer
()
{
return
NULL
;
}
void
delete_self
()
{
cleanup
();
delete
this
;
}
};
...
...
@@ -304,7 +310,10 @@ public:
inline
void
make_field
(
Send_field
*
field
)
{
this_item
()
->
make_field
(
field
);
Item
*
it
=
this_item
();
it
->
set_name
(
m_name
.
str
,
m_name
.
length
,
system_charset_info
);
it
->
make_field
(
field
);
}
inline
Item_result
result_type
()
const
...
...
@@ -326,6 +335,11 @@ public:
{
str
->
append
(
m_name
.
str
,
m_name
.
length
);
}
inline
bool
send
(
Protocol
*
protocol
,
String
*
str
)
{
return
this_item
()
->
send
(
protocol
,
str
);
}
};
...
...
@@ -339,7 +353,7 @@ public:
st_select_lex
*
depended_from
;
Item_ident
(
const
char
*
db_name_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
);
Item_ident
(
THD
*
thd
,
Item_ident
&
item
);
Item_ident
(
THD
*
thd
,
Item_ident
*
item
);
const
char
*
full_name
()
const
;
bool
remove_dependence_processor
(
byte
*
arg
);
...
...
@@ -362,7 +376,7 @@ public:
item_equal
(
0
)
{
collation
.
set
(
DERIVATION_IMPLICIT
);
}
// Constructor need to process subselect with temporary tables (see Item)
Item_field
(
THD
*
thd
,
Item_field
&
item
);
Item_field
(
THD
*
thd
,
Item_field
*
item
);
Item_field
(
Field
*
field
);
enum
Type
type
()
const
{
return
FIELD_ITEM
;
}
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
;
...
...
@@ -393,6 +407,7 @@ public:
bool
get_time
(
TIME
*
ltime
);
bool
is_null
()
{
return
field
->
is_null
();
}
Item
*
get_tmp_table_item
(
THD
*
thd
);
void
cleanup
();
Item_equal
*
find_item_equal
(
COND_EQUAL
*
cond_equal
);
Item
*
equal_fields_propagator
(
byte
*
arg
);
bool
replace_equal_field_processor
(
byte
*
arg
);
...
...
@@ -583,7 +598,7 @@ public:
CHARSET_INFO
*
cs
,
Derivation
dv
=
DERIVATION_COERCIBLE
)
{
collation
.
set
(
cs
,
dv
);
str_value
.
set
(
str
,
length
,
cs
);
str_value
.
set
_or_copy_aligned
(
str
,
length
,
cs
);
/*
We have to have a different max_length than 'length' here to
ensure that we get the right length if we do use the item
...
...
@@ -599,12 +614,11 @@ public:
CHARSET_INFO
*
cs
,
Derivation
dv
=
DERIVATION_COERCIBLE
)
{
collation
.
set
(
cs
,
dv
);
str_value
.
set
(
str
,
length
,
cs
);
str_value
.
set
_or_copy_aligned
(
str
,
length
,
cs
);
max_length
=
str_value
.
numchars
()
*
cs
->
mbmaxlen
;
set_name
(
name_par
,
0
,
cs
);
decimals
=
NOT_FIXED_DEC
;
}
~
Item_string
()
{}
enum
Type
type
()
const
{
return
STRING_ITEM
;
}
double
val
()
{
...
...
@@ -671,7 +685,6 @@ class Item_varbinary :public Item
{
public:
Item_varbinary
(
const
char
*
str
,
uint
str_length
);
~
Item_varbinary
()
{}
enum
Type
type
()
const
{
return
VARBIN_ITEM
;
}
double
val
()
{
return
(
double
)
Item_varbinary
::
val_int
();
}
longlong
val_int
();
...
...
@@ -688,8 +701,8 @@ public:
Field
*
result_field
;
/* Save result here */
Item_result_field
()
:
result_field
(
0
)
{}
// Constructor used for Item_sum/Item_cond_and/or (see Item comment)
Item_result_field
(
THD
*
thd
,
Item_result_field
&
item
)
:
Item
(
thd
,
item
),
result_field
(
item
.
result_field
)
Item_result_field
(
THD
*
thd
,
Item_result_field
*
item
)
:
Item
(
thd
,
item
),
result_field
(
item
->
result_field
)
{}
~
Item_result_field
()
{}
/* Required with gcc 2.95 */
Field
*
get_tmp_table_field
()
{
return
result_field
;
}
...
...
@@ -708,20 +721,25 @@ public:
class
Item_ref
:
public
Item_ident
{
public:
Field
*
result_field
;
/* Save result here */
Field
*
result_field
;
/* Save result here */
Item
**
ref
;
Item_ref
(
const
char
*
db_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
Item_ident
(
db_par
,
table_name_par
,
field_name_par
),
ref
(
0
)
{}
Item_ref
(
Item
**
item
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
Item_ident
(
NullS
,
table_name_par
,
field_name_par
),
ref
(
item
)
{}
Item
**
hook_ptr
;
/* These two to restore */
Item
*
orig_item
;
/* things in 'cleanup()' */
Item_ref
(
Item
**
hook
,
Item
*
original
,
const
char
*
db_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
Item_ident
(
db_par
,
table_name_par
,
field_name_par
),
ref
(
0
),
hook_ptr
(
hook
),
orig_item
(
original
)
{}
Item_ref
(
Item
**
item
,
Item
**
hook
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
Item_ident
(
NullS
,
table_name_par
,
field_name_par
),
ref
(
item
),
hook_ptr
(
hook
),
orig_item
(
hook
?
*
hook
:
0
)
{}
// Constructor need to process subselect with temporary tables (see Item)
Item_ref
(
THD
*
thd
,
Item_ref
&
item
)
:
Item_ident
(
thd
,
item
),
ref
(
item
.
ref
)
{}
Item_ref
(
THD
*
thd
,
Item_ref
*
item
,
Item
**
hook
)
:
Item_ident
(
thd
,
item
),
ref
(
item
->
ref
),
hook_ptr
(
hook
),
orig_item
(
hook
?
*
hook
:
0
)
{}
enum
Type
type
()
const
{
return
REF_ITEM
;
}
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
return
ref
&&
(
*
ref
)
->
eq
(
item
,
binary_cmp
);
}
~
Item_ref
()
{
if
(
ref
&&
(
*
ref
)
&&
(
*
ref
)
!=
this
)
delete
*
ref
;
}
double
val
()
{
double
tmp
=
(
*
ref
)
->
val_result
();
...
...
@@ -766,6 +784,7 @@ public:
}
Item
*
real_item
()
{
return
*
ref
;
}
void
print
(
String
*
str
);
void
cleanup
();
};
class
Item_in_subselect
;
...
...
@@ -776,7 +795,7 @@ protected:
public:
Item_ref_null_helper
(
Item_in_subselect
*
master
,
Item
**
item
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
Item_ref
(
item
,
table_name_par
,
field_name_par
),
owner
(
master
)
{}
Item_ref
(
item
,
NULL
,
table_name_par
,
field_name_par
),
owner
(
master
)
{}
double
val
();
longlong
val_int
();
String
*
val_str
(
String
*
s
);
...
...
@@ -840,7 +859,6 @@ public:
name
=
item
->
name
;
cached_field_type
=
item
->
field_type
();
}
~
Item_copy_string
()
{
delete
item
;
}
enum
Type
type
()
const
{
return
COPY_STR_ITEM
;
}
enum
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
enum_field_types
field_type
()
const
{
return
cached_field_type
;
}
...
...
@@ -997,13 +1015,15 @@ public:
void
set_used_tables
(
table_map
map
)
{
used_table_map
=
map
;
}
virtual
bool
allocate
(
uint
i
)
{
return
0
;
};
virtual
bool
setup
(
Item
*
item
)
{
example
=
item
;
return
0
;
};
virtual
void
store
(
Item
*
)
=
0
;
void
set_len_n_dec
(
uint32
max_len
,
uint8
dec
)
virtual
bool
setup
(
Item
*
item
)
{
max_length
=
max_len
;
decimals
=
dec
;
}
example
=
item
;
max_length
=
item
->
max_length
;
decimals
=
item
->
decimals
;
collation
.
set
(
item
->
collation
);
return
0
;
};
virtual
void
store
(
Item
*
)
=
0
;
enum
Type
type
()
const
{
return
CACHE_ITEM
;
}
static
Item_cache
*
get_cache
(
Item_result
type
);
table_map
used_tables
()
const
{
return
used_table_map
;
}
...
...
@@ -1028,7 +1048,7 @@ class Item_cache_real: public Item_cache
double
value
;
public:
Item_cache_real
()
:
Item_cache
()
{}
void
store
(
Item
*
item
);
double
val
()
{
return
value
;
}
longlong
val_int
()
{
return
(
longlong
)
(
value
+
(
value
>
0
?
0.5
:
-
0.5
));
}
...
...
@@ -1101,6 +1121,11 @@ public:
bool
check_cols
(
uint
c
);
bool
null_inside
();
void
bring_value
();
void
cleanup
()
{
Item_cache
::
cleanup
();
values
=
0
;
}
};
...
...
@@ -1111,6 +1136,7 @@ class Item_type_holder: public Item
{
protected:
Item_result
item_type
;
Item_result
orig_type
;
Field
*
field_example
;
public:
Item_type_holder
(
THD
*
,
Item
*
);
...
...
@@ -1122,6 +1148,11 @@ public:
String
*
val_str
(
String
*
);
bool
join_types
(
THD
*
thd
,
Item
*
);
Field
*
example
()
{
return
field_example
;
}
void
cleanup
()
{
Item
::
cleanup
();
item_type
=
orig_type
;
}
};
...
...
sql/opt_range.cc
View file @
fd98ed36
...
...
@@ -301,10 +301,11 @@ typedef struct st_qsel_param {
uint
imerge_cost_buff_size
;
/* size of the buffer */
}
PARAM
;
static
SEL_TREE
*
get_mm_parts
(
PARAM
*
param
,
Field
*
field
,
static
SEL_TREE
*
get_mm_parts
(
PARAM
*
param
,
COND
*
cond_func
,
Field
*
field
,
Item_func
::
Functype
type
,
Item
*
value
,
Item_result
cmp_type
);
static
SEL_ARG
*
get_mm_leaf
(
PARAM
*
param
,
Field
*
field
,
KEY_PART
*
key_part
,
static
SEL_ARG
*
get_mm_leaf
(
PARAM
*
param
,
COND
*
cond_func
,
Field
*
field
,
KEY_PART
*
key_part
,
Item_func
::
Functype
type
,
Item
*
value
);
static
SEL_TREE
*
get_mm_tree
(
PARAM
*
param
,
COND
*
cond
);
static
ha_rows
check_quick_select
(
PARAM
*
param
,
uint
index
,
SEL_ARG
*
key_tree
);
...
...
@@ -612,14 +613,25 @@ SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
}
SQL_SELECT
::~
SQL_SELECT
()
void
SQL_SELECT
::
cleanup
()
{
delete
quick
;
quick
=
0
;
if
(
free_cond
)
{
free_cond
=
0
;
delete
cond
;
cond
=
0
;
}
close_cached_file
(
&
file
);
}
SQL_SELECT
::~
SQL_SELECT
()
{
cleanup
();
}
#undef index // Fix for Unixware 7
QUICK_SELECT_I
::
QUICK_SELECT_I
()
...
...
@@ -1746,7 +1758,8 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
static
SEL_TREE
*
get_mm_parts
(
PARAM
*
param
,
Field
*
field
,
Item_func
::
Functype
type
,
get_mm_parts
(
PARAM
*
param
,
COND
*
cond_func
,
Field
*
field
,
Item_func
::
Functype
type
,
Item
*
value
,
Item_result
cmp_type
)
{
DBUG_ENTER
(
"get_mm_parts"
);
...
...
@@ -1768,7 +1781,8 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
DBUG_RETURN
(
0
);
// OOM
if
(
!
value
||
!
(
value
->
used_tables
()
&
~
param
->
read_tables
))
{
sel_arg
=
get_mm_leaf
(
param
,
key_part
->
field
,
key_part
,
type
,
value
);
sel_arg
=
get_mm_leaf
(
param
,
cond_func
,
key_part
->
field
,
key_part
,
type
,
value
);
if
(
!
sel_arg
)
continue
;
if
(
sel_arg
->
type
==
SEL_ARG
::
IMPOSSIBLE
)
...
...
@@ -1794,7 +1808,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
static
SEL_ARG
*
get_mm_leaf
(
PARAM
*
param
,
Field
*
field
,
KEY_PART
*
key_part
,
get_mm_leaf
(
PARAM
*
param
,
COND
*
conf_func
,
Field
*
field
,
KEY_PART
*
key_part
,
Item_func
::
Functype
type
,
Item
*
value
)
{
uint
maybe_null
=
(
uint
)
field
->
real_maybe_null
(),
copies
;
...
...
@@ -1803,6 +1817,32 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
char
*
str
,
*
str2
;
DBUG_ENTER
(
"get_mm_leaf"
);
if
(
!
value
)
// IS NULL or IS NOT NULL
{
if
(
field
->
table
->
outer_join
)
// Can't use a key on this
DBUG_RETURN
(
0
);
if
(
!
maybe_null
)
// Not null field
DBUG_RETURN
(
type
==
Item_func
::
ISNULL_FUNC
?
&
null_element
:
0
);
if
(
!
(
tree
=
new
SEL_ARG
(
field
,
is_null_string
,
is_null_string
)))
DBUG_RETURN
(
0
);
// out of memory
if
(
type
==
Item_func
::
ISNOTNULL_FUNC
)
{
tree
->
min_flag
=
NEAR_MIN
;
/* IS NOT NULL -> X > NULL */
tree
->
max_flag
=
NO_MAX_RANGE
;
}
DBUG_RETURN
(
tree
);
}
/*
We can't use an index when comparing strings of
different collations
*/
if
(
field
->
result_type
()
==
STRING_RESULT
&&
value
->
result_type
()
==
STRING_RESULT
&&
key_part
->
image_type
==
Field
::
itRAW
&&
((
Field_str
*
)
field
)
->
charset
()
!=
conf_func
->
compare_collation
())
DBUG_RETURN
(
0
);
if
(
type
==
Item_func
::
LIKE_FUNC
)
{
bool
like_error
;
...
...
@@ -1866,22 +1906,6 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
DBUG_RETURN
(
new
SEL_ARG
(
field
,
min_str
,
max_str
));
}
if
(
!
value
)
// IS NULL or IS NOT NULL
{
if
(
field
->
table
->
outer_join
)
// Can't use a key on this
DBUG_RETURN
(
0
);
if
(
!
maybe_null
)
// Not null field
DBUG_RETURN
(
type
==
Item_func
::
ISNULL_FUNC
?
&
null_element
:
0
);
if
(
!
(
tree
=
new
SEL_ARG
(
field
,
is_null_string
,
is_null_string
)))
DBUG_RETURN
(
0
);
// out of memory
if
(
type
==
Item_func
::
ISNOTNULL_FUNC
)
{
tree
->
min_flag
=
NEAR_MIN
;
/* IS NOT NULL -> X > NULL */
tree
->
max_flag
=
NO_MAX_RANGE
;
}
DBUG_RETURN
(
tree
);
}
if
(
!
field
->
optimize_range
(
param
->
real_keynr
[
key_part
->
key
])
&&
type
!=
Item_func
::
EQ_FUNC
&&
type
!=
Item_func
::
EQUAL_FUNC
)
...
...
@@ -1895,7 +1919,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
value
->
result_type
()
!=
STRING_RESULT
&&
field
->
cmp_type
()
!=
value
->
result_type
())
DBUG_RETURN
(
0
);
if
(
value
->
save_in_field
(
field
,
1
)
>
0
)
{
/* This happens when we try to insert a NULL field in a not null column */
...
...
@@ -3097,6 +3121,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
param
->
table
->
quick_rows
[
key
]
=
records
;
param
->
table
->
quick_key_parts
[
key
]
=
param
->
max_key_part
+
1
;
}
DBUG_PRINT
(
"exit"
,
(
"Records: %lu"
,
(
ulong
)
records
));
DBUG_RETURN
(
records
);
}
...
...
@@ -3440,8 +3465,30 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
key_part
->
part_length
+=
HA_KEY_BLOB_LENGTH
;
key_part
->
null_bit
=
key_info
->
key_part
[
part
].
null_bit
;
}
if
(
!
insert_dynamic
(
&
quick
->
ranges
,(
gptr
)
&
range
))
return
quick
;
if
(
insert_dynamic
(
&
quick
->
ranges
,(
gptr
)
&
range
))
goto
err
;
/*
Add a NULL range if REF_OR_NULL optimization is used.
For example:
if we have "WHERE A=2 OR A IS NULL" we created the (A=2) range above
and have ref->null_ref_key set. Will create a new NULL range here.
*/
if
(
ref
->
null_ref_key
)
{
QUICK_RANGE
*
null_range
;
*
ref
->
null_ref_key
=
1
;
// Set null byte then create a range
if
(
!
(
null_range
=
new
QUICK_RANGE
(
ref
->
key_buff
,
ref
->
key_length
,
ref
->
key_buff
,
ref
->
key_length
,
EQ_RANGE
)))
goto
err
;
*
ref
->
null_ref_key
=
0
;
// Clear null byte
if
(
insert_dynamic
(
&
quick
->
ranges
,(
gptr
)
&
null_range
))
goto
err
;
}
return
quick
;
err:
delete
quick
;
...
...
@@ -3584,12 +3631,7 @@ int QUICK_RANGE_SELECT::get_next()
int
result
;
if
(
range
)
{
// Already read through key
/* result=((range->flag & EQ_RANGE) ?
file->index_next_same(record, (byte*) range->min_key,
range->min_length) :
file->index_next(record));
*/
result
=
((
range
->
flag
&
(
EQ_RANGE
|
GEOM_FLAG
)
)
?
result
=
((
range
->
flag
&
(
EQ_RANGE
|
GEOM_FLAG
))
?
file
->
index_next_same
(
record
,
(
byte
*
)
range
->
min_key
,
range
->
min_length
)
:
file
->
index_next
(
record
));
...
...
sql/sql_select.cc
View file @
fd98ed36
This diff is collapsed.
Click to expand it.
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