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
d24a2296
Commit
d24a2296
authored
Feb 19, 2004
by
igor@rurik.mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Manual merge
parent
f18e0068
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 @
d24a2296
...
...
@@ -126,8 +126,8 @@ class Item {
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 @@ class Item {
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 @@ class Item {
/* Used in sql_select.cc:eliminate_not_funcs() */
virtual
Item
*
neg_transformer
()
{
return
NULL
;
}
void
delete_self
()
{
cleanup
();
delete
this
;
}
};
...
...
@@ -304,7 +310,10 @@ class Item_splocal : public Item
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 @@ class Item_splocal : public Item
{
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 @@ class Item_ident :public Item
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 @@ class Item_field :public Item_ident
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 @@ class Item_field :public Item_ident
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 @@ class Item_string :public Item
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 @@ class Item_string :public Item
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 @@ class Item_result_field :public Item /* Item with result field */
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 @@ class Item_result_field :public Item /* Item with result field */
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 @@ class Item_ref :public Item_ident
}
Item
*
real_item
()
{
return
*
ref
;
}
void
print
(
String
*
str
);
void
cleanup
();
};
class
Item_in_subselect
;
...
...
@@ -776,7 +795,7 @@ class Item_ref_null_helper: public Item_ref
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 @@ class Item_copy_string :public Item
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 @@ class Item_cache: public Item
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 @@ class Item_cache_row: public Item_cache
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 @@ class Item_type_holder: public Item
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 @
d24a2296
...
...
@@ -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 @
d24a2296
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