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
8035ce40
Commit
8035ce40
authored
Mar 17, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DBUG_ASSERT(fixed == 0) added to fix_fields()
parent
b8c065c5
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
292 additions
and
95 deletions
+292
-95
sql/item.cc
sql/item.cc
+41
-9
sql/item.h
sql/item.h
+23
-8
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+104
-32
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+17
-12
sql/item_func.cc
sql/item_func.cc
+4
-1
sql/item_func.h
sql/item_func.h
+2
-0
sql/item_row.cc
sql/item_row.cc
+2
-0
sql/item_strfunc.h
sql/item_strfunc.h
+2
-0
sql/item_subselect.cc
sql/item_subselect.cc
+6
-5
sql/item_sum.cc
sql/item_sum.cc
+5
-0
sql/item_sum.h
sql/item_sum.h
+1
-0
sql/item_uniq.h
sql/item_uniq.h
+1
-0
sql/sql_base.cc
sql/sql_base.cc
+6
-3
sql/sql_derived.cc
sql/sql_derived.cc
+5
-1
sql/sql_select.cc
sql/sql_select.cc
+31
-20
sql/sql_select.h
sql/sql_select.h
+1
-1
sql/sql_union.cc
sql/sql_union.cc
+7
-2
tests/client_test.c
tests/client_test.c
+34
-1
No files found.
sql/item.cc
View file @
8035ce40
...
...
@@ -103,21 +103,33 @@ void Item::print_item_w_name(String *str)
Item_ident
::
Item_ident
(
const
char
*
db_name_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
db_name
(
db_name_par
),
table_name
(
table_name_par
),
field_name
(
field_name_par
),
:
changed_during_fix_field
(
0
),
db_name
(
db_name_par
),
table_name
(
table_name_par
),
field_name
(
field_name_par
),
depended_from
(
0
)
{
name
=
(
char
*
)
field_name_par
;
}
// Constructor used by Item_field & Item_ref (see Item comment)
Item_ident
::
Item_ident
(
THD
*
thd
,
Item_ident
*
item
)
:
Item
(
thd
,
item
),
Item_ident
::
Item_ident
(
THD
*
thd
,
Item_ident
*
item
)
:
Item
(
thd
,
item
),
changed_during_fix_field
(
0
),
db_name
(
item
->
db_name
),
table_name
(
item
->
table_name
),
field_name
(
item
->
field_name
),
depended_from
(
item
->
depended_from
)
{}
void
Item_ident
::
cleanup
()
{
Item
::
cleanup
();
if
(
changed_during_fix_field
)
{
*
changed_during_fix_field
=
this
;
changed_during_fix_field
=
0
;
}
}
bool
Item_ident
::
remove_dependence_processor
(
byte
*
arg
)
{
DBUG_ENTER
(
"Item_ident::remove_dependence_processor"
);
...
...
@@ -289,11 +301,14 @@ bool DTCollation::aggregate(DTCollation &dt)
return
0
;
}
Item_field
::
Item_field
(
Field
*
f
)
:
Item_ident
(
NullS
,
f
->
table_name
,
f
->
field_name
)
Item_field
::
Item_field
(
Field
*
f
)
:
Item_ident
(
NullS
,
f
->
table_name
,
f
->
field_name
)
#ifndef DBUG_OFF
,
double_fix
(
0
)
#endif
{
set_field
(
f
);
collation
.
set
(
DERIVATION_IMPLICIT
);
fixed
=
1
;
// This item is not needed in fix_fields
}
// Constructor need to process subselect with temporary tables (see Item)
...
...
@@ -301,6 +316,9 @@ Item_field::Item_field(THD *thd, Item_field *item)
:
Item_ident
(
thd
,
item
),
field
(
item
->
field
),
result_field
(
item
->
result_field
)
#ifndef DBUG_OFF
,
double_fix
(
0
)
#endif
{
collation
.
set
(
DERIVATION_IMPLICIT
);
}
...
...
@@ -786,6 +804,9 @@ bool Item::fix_fields(THD *thd,
struct
st_table_list
*
list
,
Item
**
ref
)
{
// We do not check fields which are fixed during construction
DBUG_ASSERT
(
fixed
==
0
||
type
()
==
INT_ITEM
||
type
()
==
CACHE_ITEM
);
fixed
=
1
;
return
0
;
}
...
...
@@ -847,6 +868,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
bool
Item_field
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
||
double_fix
==
0
);
if
(
!
field
)
// If field is not checked
{
TABLE_LIST
*
where
=
0
;
...
...
@@ -952,6 +974,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
ref
,
(
char
*
)
table_name
,
(
char
*
)
field_name
);
register_item_tree_changing
(
ref
);
if
(
!
rf
)
return
1
;
/*
...
...
@@ -1005,6 +1028,11 @@ void Item_field::cleanup()
{
DBUG_ENTER
(
"Item_field::cleanup"
);
Item_ident
::
cleanup
();
/*
Even if this object was created by direct link to field in setup_wild()
it will be linked correctly next tyme by name of field and table alias.
I.e. we can drop 'field'.
*/
field
=
result_field
=
0
;
DBUG_VOID_RETURN
;
}
...
...
@@ -1480,6 +1508,7 @@ bool Item_field::send(Protocol *protocol, String *buffer)
bool
Item_ref
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
reference
)
{
DBUG_ASSERT
(
fixed
==
0
);
uint
counter
;
if
(
!
ref
)
{
...
...
@@ -1585,6 +1614,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
Item_field
*
fld
;
if
(
!
((
*
reference
)
=
fld
=
new
Item_field
(
tmp
)))
return
1
;
register_item_tree_changing
(
reference
);
mark_as_dependent
(
thd
,
last
,
thd
->
lex
->
current_select
,
fld
);
return
0
;
}
...
...
@@ -1696,6 +1726,7 @@ bool Item_default_value::fix_fields(THD *thd,
struct
st_table_list
*
table_list
,
Item
**
items
)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
!
arg
)
return
0
;
if
(
arg
->
fix_fields
(
thd
,
table_list
,
&
arg
))
...
...
@@ -1744,6 +1775,7 @@ bool Item_insert_value::fix_fields(THD *thd,
struct
st_table_list
*
table_list
,
Item
**
items
)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
arg
->
fix_fields
(
thd
,
table_list
,
&
arg
))
return
1
;
...
...
sql/item.h
View file @
8035ce40
...
...
@@ -233,7 +233,7 @@ class Item {
Field
*
tmp_table_field_from_field_type
(
TABLE
*
table
);
/* Used in sql_select.cc:eliminate_not_funcs() */
virtual
Item
*
neg_transformer
()
{
return
NULL
;
}
virtual
Item
*
neg_transformer
(
THD
*
thd
)
{
return
NULL
;
}
void
delete_self
()
{
cleanup
();
...
...
@@ -245,6 +245,7 @@ class Item {
class
st_select_lex
;
class
Item_ident
:
public
Item
{
Item
**
changed_during_fix_field
;
public:
const
char
*
db_name
;
const
char
*
table_name
;
...
...
@@ -254,7 +255,9 @@ class Item_ident :public Item
const
char
*
field_name_par
);
Item_ident
(
THD
*
thd
,
Item_ident
*
item
);
const
char
*
full_name
()
const
;
void
cleanup
();
void
register_item_tree_changing
(
Item
**
ref
)
{
changed_during_fix_field
=
ref
;
}
bool
remove_dependence_processor
(
byte
*
arg
);
};
...
...
@@ -264,11 +267,17 @@ class Item_field :public Item_ident
void
set_field
(
Field
*
field
);
public:
Field
*
field
,
*
result_field
;
// Item_field() {}
#ifndef DBUG_OFF
bool
double_fix
;
#endif
Item_field
(
const
char
*
db_par
,
const
char
*
table_name_par
,
const
char
*
field_name_par
)
:
Item_ident
(
db_par
,
table_name_par
,
field_name_par
),
field
(
0
),
result_field
(
0
)
:
Item_ident
(
db_par
,
table_name_par
,
field_name_par
),
field
(
0
),
result_field
(
0
)
#ifndef DBUG_OFF
,
double_fix
(
0
)
#endif
{
collation
.
set
(
DERIVATION_IMPLICIT
);
}
// Constructor need to process subselect with temporary tables (see Item)
Item_field
(
THD
*
thd
,
Item_field
*
item
);
...
...
@@ -324,6 +333,7 @@ class Item_null :public Item
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_NULL
;
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
item
)
{
DBUG_ASSERT
(
fixed
==
0
);
bool
res
=
Item
::
fix_fields
(
thd
,
list
,
item
);
max_length
=
0
;
return
res
;
...
...
@@ -413,7 +423,8 @@ class Item_int :public Item
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
bool
basic_const_item
()
const
{
return
1
;
}
Item
*
new_item
()
{
return
new
Item_int
(
name
,
value
,
max_length
);
}
void
cleanup
()
{
fixed
=
1
;
}
// to prevent drop fixed flag
// to prevent drop fixed flag (no need parent cleanup call)
void
cleanup
()
{
fixed
=
1
;
}
void
print
(
String
*
str
);
};
...
...
@@ -422,14 +433,17 @@ class Item_uint :public Item_int
{
public:
Item_uint
(
const
char
*
str_arg
,
uint
length
)
:
Item_int
(
str_arg
,
(
longlong
)
strtoull
(
str_arg
,(
char
**
)
0
,
10
),
length
)
{}
Item_uint
(
uint32
i
)
:
Item_int
((
longlong
)
i
,
10
)
{}
Item_int
(
str_arg
,
(
longlong
)
strtoull
(
str_arg
,(
char
**
)
0
,
10
),
length
)
{
fixed
=
0
;
}
Item_uint
(
uint32
i
)
:
Item_int
((
longlong
)
i
,
10
)
{
fixed
=
0
;
}
double
val
()
{
return
ulonglong2double
((
ulonglong
)
value
);
}
String
*
val_str
(
String
*
);
Item
*
new_item
()
{
return
new
Item_uint
(
name
,
max_length
);
}
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
list
,
Item
**
item
)
{
DBUG_ASSERT
(
fixed
==
0
);
bool
res
=
Item
::
fix_fields
(
thd
,
list
,
item
);
unsigned_flag
=
1
;
return
res
;
...
...
@@ -903,7 +917,8 @@ class Item_cache: public Item
static
Item_cache
*
get_cache
(
Item_result
type
);
table_map
used_tables
()
const
{
return
used_table_map
;
}
virtual
void
keep_array
()
{}
void
cleanup
()
{
fixed
=
1
;
}
// to prevent drop fixed flag
// to prevent drop fixed flag (no need parent cleanup call)
void
cleanup
()
{
fixed
=
1
;
}
void
print
(
String
*
str
);
};
...
...
sql/item_cmpfunc.cc
View file @
8035ce40
...
...
@@ -502,7 +502,6 @@ bool Item_in_optimizer::fix_left(THD *thd,
not_null_tables_cache
=
args
[
0
]
->
not_null_tables
();
with_sum_func
=
args
[
0
]
->
with_sum_func
;
const_item_cache
=
args
[
0
]
->
const_item
();
fixed
=
1
;
return
0
;
}
...
...
@@ -510,7 +509,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
bool
Item_in_optimizer
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
if
(
fix_left
(
thd
,
tables
,
ref
))
DBUG_ASSERT
(
fixed
==
0
);
if
(
!
args
[
0
]
->
fixed
&&
fix_left
(
thd
,
tables
,
ref
))
return
1
;
if
(
args
[
0
]
->
maybe_null
)
maybe_null
=
1
;
...
...
@@ -529,6 +529,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
used_tables_cache
|=
args
[
1
]
->
used_tables
();
not_null_tables_cache
|=
args
[
1
]
->
not_null_tables
();
const_item_cache
&=
args
[
1
]
->
const_item
();
fixed
=
1
;
return
0
;
}
...
...
@@ -1755,6 +1756,7 @@ void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
bool
Item_cond
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
List_iterator
<
Item
>
li
(
list
);
Item
*
item
;
#ifndef EMBEDDED_LIBRARY
...
...
@@ -1878,14 +1880,27 @@ void Item_cond::print(String *str)
}
void
Item_cond
::
neg_arguments
()
void
Item_cond
::
neg_arguments
(
THD
*
thd
)
{
List_iterator
<
Item
>
li
(
list
);
Item
*
item
;
while
((
item
=
li
++
))
/* Apply not transformation to the arguments */
{
Item
*
new_item
=
item
->
neg_transformer
();
VOID
(
li
.
replace
(
new_item
?
new_item
:
new
Item_func_not
(
item
)));
Item
*
new_item
=
item
->
neg_transformer
(
thd
);
if
(
!
new_item
)
{
new_item
=
new
Item_func_not
(
item
);
/*
We can use 0 as tables list because Item_func_not do not use it
on fix_fields and its arguments are already fixed.
We do not check results of fix_fields, because there are not way
to return error in this functions interface, thd->net.report_error
will be checked on upper level call.
*/
new_item
->
fix_fields
(
thd
,
0
,
&
new_item
);
}
VOID
(
li
.
replace
(
new_item
));
}
}
...
...
@@ -2097,6 +2112,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
bool
Item_func_like
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
Item_bool_func2
::
fix_fields
(
thd
,
tlist
,
ref
))
return
1
;
...
...
@@ -2150,6 +2166,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
bool
Item_func_regex
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
)
||
args
[
0
]
->
check_cols
(
1
)
||
args
[
1
]
->
fix_fields
(
thd
,
tables
,
args
+
1
)
||
args
[
1
]
->
check_cols
(
1
))
return
1
;
/* purecov: inspected */
...
...
@@ -2518,6 +2535,7 @@ longlong Item_cond_xor::val_int()
SYNPOSIS
neg_transformer()
thd thread handler
DESCRIPTION
Transform the item using next rules:
...
...
@@ -2541,62 +2559,116 @@ longlong Item_cond_xor::val_int()
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
*/
Item
*
Item_func_not
::
neg_transformer
(
)
/* NOT(x) -> x */
Item
*
Item_func_not
::
neg_transformer
(
THD
*
thd
)
/* NOT(x) -> x */
{
/
* We should apply negation elimination to the argument of the NOT function */
return
eliminate_not_funcs
(
args
[
0
]);
/
/ We should apply negation elimination to the argument of the NOT function
return
eliminate_not_funcs
(
thd
,
args
[
0
]);
}
Item
*
Item_func_eq
::
neg_transformer
()
/* a = b -> a != b */
Item
*
Item_bool_rowready_func2
::
neg_transformer
(
THD
*
thd
)
{
return
new
Item_func_ne
(
args
[
0
],
args
[
1
]);
Item
*
item
=
negated_item
();
if
(
item
)
{
/*
We can use 0 as tables list because Item_func* family do not use it
on fix_fields and its arguments are already fixed.
We do not check results of fix_fields, because there are not way
to return error in this functions interface, thd->net.report_error
will be checked on upper level call.
*/
item
->
fix_fields
(
thd
,
0
,
&
item
);
}
return
item
;
}
Item
*
Item_func_ne
::
neg_transformer
()
/* a != b -> a = b */
/* a IS NULL -> a IS NOT NULL */
Item
*
Item_func_isnull
::
neg_transformer
(
THD
*
thd
)
{
return
new
Item_func_eq
(
args
[
0
],
args
[
1
]);
Item
*
item
=
new
Item_func_isnotnull
(
args
[
0
]);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
Item
*
Item_func_lt
::
neg_transformer
()
/* a < b -> a >= b */
/* a IS NOT NULL -> a IS NULL */
Item
*
Item_func_isnotnull
::
neg_transformer
(
THD
*
thd
)
{
return
new
Item_func_ge
(
args
[
0
],
args
[
1
]);
Item
*
item
=
new
Item_func_isnull
(
args
[
0
]);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
Item
*
Item_func_ge
::
neg_transformer
()
/* a >= b -> a < b */
Item
*
Item_cond_and
::
neg_transformer
(
THD
*
thd
)
/* NOT(a AND b AND ...) -> */
/* NOT a OR NOT b OR ... */
{
return
new
Item_func_lt
(
args
[
0
],
args
[
1
]);
neg_arguments
(
thd
);
Item
*
item
=
new
Item_cond_or
(
list
);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
Item
*
Item_func_gt
::
neg_transformer
()
/* a > b -> a <= b */
Item
*
Item_cond_or
::
neg_transformer
(
THD
*
thd
)
/* NOT(a OR b OR ...) -> */
/* NOT a AND NOT b AND ... */
{
return
new
Item_func_le
(
args
[
0
],
args
[
1
]);
neg_arguments
(
thd
);
Item
*
item
=
new
Item_cond_and
(
list
);
// see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
if
(
item
)
item
->
fix_fields
(
thd
,
0
,
&
item
);
return
item
;
}
Item
*
Item_func_le
::
neg_transformer
()
/* a <= b -> a > b */
Item
*
Item_func_eq
::
negated_item
()
/* a = b -> a != b */
{
return
new
Item_func_
gt
(
args
[
0
],
args
[
1
]);
return
new
Item_func_
ne
(
args
[
0
],
args
[
1
]);
}
Item
*
Item_func_isnull
::
neg_transformer
()
/* a IS NULL -> a IS NOT NULL */
Item
*
Item_func_ne
::
negated_item
()
/* a != b -> a = b */
{
return
new
Item_func_
isnotnull
(
args
[
0
]);
return
new
Item_func_
eq
(
args
[
0
],
args
[
1
]);
}
Item
*
Item_func_isnotnull
::
neg_transformer
()
/* a IS NOT NULL -> a IS NULL */
Item
*
Item_func_lt
::
negated_item
()
/* a < b -> a >= b */
{
return
new
Item_func_
isnull
(
args
[
0
]);
return
new
Item_func_
ge
(
args
[
0
],
args
[
1
]);
}
Item
*
Item_cond_and
::
neg_transformer
()
/* NOT(a AND b AND ...) -> */
/* NOT a OR NOT b OR ...
*/
Item
*
Item_func_ge
::
negated_item
()
/* a >= b -> a < b
*/
{
neg_arguments
();
return
new
Item_cond_or
(
list
);
return
new
Item_func_lt
(
args
[
0
],
args
[
1
]);
}
Item
*
Item_cond_or
::
neg_transformer
()
/* NOT(a OR b OR ...) -> */
/* NOT a AND NOT b AND ...
*/
Item
*
Item_func_gt
::
negated_item
()
/* a > b -> a <= b
*/
{
neg_arguments
();
return
new
Item_cond_and
(
list
);
return
new
Item_func_le
(
args
[
0
],
args
[
1
]);
}
Item
*
Item_func_le
::
negated_item
()
/* a <= b -> a > b */
{
return
new
Item_func_gt
(
args
[
0
],
args
[
1
]);
}
// just fake method, should never be called
Item
*
Item_bool_rowready_func2
::
negated_item
()
{
DBUG_ASSERT
(
0
);
return
0
;
}
sql/item_cmpfunc.h
View file @
8035ce40
...
...
@@ -218,6 +218,8 @@ class Item_bool_rowready_func2 :public Item_bool_func2
tmp_arg
[
1
]
=
orig_b
;
DBUG_VOID_RETURN
;
}
Item
*
neg_transformer
(
THD
*
thd
);
virtual
Item
*
negated_item
();
};
class
Item_func_not
:
public
Item_bool_func
...
...
@@ -227,7 +229,7 @@ class Item_func_not :public Item_bool_func
longlong
val_int
();
enum
Functype
functype
()
const
{
return
NOT_FUNC
;
}
const
char
*
func_name
()
const
{
return
"not"
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
};
class
Item_func_not_all
:
public
Item_func_not
...
...
@@ -254,7 +256,7 @@ class Item_func_eq :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
EQ_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"="
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
class
Item_func_equal
:
public
Item_bool_rowready_func2
...
...
@@ -267,6 +269,7 @@ class Item_func_equal :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
EQUAL_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"<=>"
;
}
Item
*
neg_transformer
(
THD
*
thd
)
{
return
0
;
}
};
...
...
@@ -279,7 +282,7 @@ class Item_func_ge :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
LE_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
">="
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
...
...
@@ -292,7 +295,7 @@ class Item_func_gt :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
LT_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
const
char
*
func_name
()
const
{
return
">"
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
...
...
@@ -305,7 +308,7 @@ class Item_func_le :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
GE_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"<="
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
...
...
@@ -318,7 +321,7 @@ class Item_func_lt :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
GT_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
const
char
*
func_name
()
const
{
return
"<"
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
...
...
@@ -331,7 +334,7 @@ class Item_func_ne :public Item_bool_rowready_func2
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_KEY
;
}
const
char
*
func_name
()
const
{
return
"<>"
;
}
Item
*
neg
_transformer
();
Item
*
neg
ated_item
();
};
...
...
@@ -409,6 +412,7 @@ class Item_func_if :public Item_func
enum
Item_result
result_type
()
const
{
return
cached_result_type
;
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tlist
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
args
[
0
]
->
top_level_item
();
return
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
);
}
...
...
@@ -726,6 +730,7 @@ class Item_func_in :public Item_int_func
void
cleanup
()
{
DBUG_ENTER
(
"Item_func_in::cleanup"
);
Item_int_func
::
cleanup
();
delete
array
;
delete
in_item
;
array
=
0
;
...
...
@@ -778,7 +783,7 @@ class Item_func_isnull :public Item_bool_func
}
table_map
not_null_tables
()
const
{
return
0
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
CHARSET_INFO
*
compare_collation
()
{
return
args
[
0
]
->
collation
.
collation
;
}
};
...
...
@@ -812,7 +817,7 @@ class Item_func_isnotnull :public Item_bool_func
const
char
*
func_name
()
const
{
return
"isnotnull"
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
table_map
not_null_tables
()
const
{
return
0
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
void
print
(
String
*
str
);
CHARSET_INFO
*
compare_collation
()
{
return
args
[
0
]
->
collation
.
collation
;
}
};
...
...
@@ -920,7 +925,7 @@ class Item_cond :public Item_bool_func
void
top_level_item
()
{
abort_on_null
=
1
;
}
void
copy_andor_arguments
(
THD
*
thd
,
Item_cond
*
item
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
void
neg_arguments
();
void
neg_arguments
(
THD
*
thd
);
};
...
...
@@ -941,7 +946,7 @@ class Item_cond_and :public Item_cond
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
};
class
Item_cond_or
:
public
Item_cond
...
...
@@ -962,7 +967,7 @@ class Item_cond_or :public Item_cond
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
}
Item
*
neg_transformer
();
Item
*
neg_transformer
(
THD
*
thd
);
};
...
...
sql/item_func.cc
View file @
8035ce40
...
...
@@ -199,6 +199,7 @@ Item_func::Item_func(THD *thd, Item_func *item)
bool
Item_func
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
Item
**
arg
,
**
arg_end
;
#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
char
buff
[
STACK_BUFF_ALLOC
];
// Max argument in function
...
...
@@ -215,7 +216,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
Item
*
item
;
/* We can't yet set item to *arg as fix_fields may change *arg */
if
((
*
arg
)
->
fix_fields
(
thd
,
tables
,
arg
)
||
if
((
!
(
*
arg
)
->
fixed
&&
(
*
arg
)
->
fix_fields
(
thd
,
tables
,
arg
)
)
||
(
*
arg
)
->
check_cols
(
allowed_arg_cols
))
return
1
;
/* purecov: inspected */
item
=
*
arg
;
...
...
@@ -2172,6 +2173,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
bool
Item_func_set_user_var
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
/* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
if
(
Item_func
::
fix_fields
(
thd
,
tables
,
ref
)
||
!
(
entry
=
get_variable
(
&
thd
->
user_vars
,
name
,
1
)))
...
...
@@ -2741,6 +2743,7 @@ void Item_func_match::init_search(bool no_order)
bool
Item_func_match
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
Item
*
item
;
LINT_INIT
(
item
);
// Safe as arg_count is > 1
...
...
sql/item_func.h
View file @
8035ce40
...
...
@@ -765,6 +765,7 @@ class Item_udf_func :public Item_func
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
bool
res
=
udf
.
fix_fields
(
thd
,
tables
,
this
,
arg_count
,
args
);
used_tables_cache
=
udf
.
used_tables_cache
;
const_item_cache
=
udf
.
const_item_cache
;
...
...
@@ -1000,6 +1001,7 @@ class Item_func_match :public Item_real_func
void
cleanup
()
{
DBUG_ENTER
(
"Item_func_match"
);
Item_real_func
::
cleanup
();
if
(
!
master
&&
ft_handler
)
{
ft_handler
->
please
->
close_search
(
ft_handler
);
...
...
sql/item_row.cc
View file @
8035ce40
...
...
@@ -55,6 +55,7 @@ void Item_row::illegal_method_call(const char *method)
bool
Item_row
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tabl
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
null_value
=
0
;
maybe_null
=
0
;
Item
**
arg
,
**
arg_end
;
...
...
@@ -78,6 +79,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
maybe_null
|=
item
->
maybe_null
;
with_sum_func
=
with_sum_func
||
item
->
with_sum_func
;
}
fixed
=
1
;
return
0
;
}
...
...
sql/item_strfunc.h
View file @
8035ce40
...
...
@@ -100,6 +100,7 @@ class Item_func_concat_ws :public Item_str_func
void
update_used_tables
();
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
return
(
separator
->
fix_fields
(
thd
,
tlist
,
&
separator
)
||
separator
->
check_cols
(
1
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
...
...
@@ -411,6 +412,7 @@ class Item_func_make_set :public Item_str_func
String
*
val_str
(
String
*
str
);
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
return
(
item
->
fix_fields
(
thd
,
tlist
,
&
item
)
||
item
->
check_cols
(
1
)
||
Item_func
::
fix_fields
(
thd
,
tlist
,
ref
));
...
...
sql/item_subselect.cc
View file @
8035ce40
...
...
@@ -102,6 +102,7 @@ Item_subselect::select_transformer(JOIN *join)
bool
Item_subselect
::
fix_fields
(
THD
*
thd_param
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
engine
->
set_thd
((
thd
=
thd_param
));
stmt
=
thd
->
current_statement
;
...
...
@@ -126,7 +127,9 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
substitution
=
0
;
fixed
=
1
;
thd
->
where
=
"checking transformed subquery"
;
int
ret
=
(
*
ref
)
->
fix_fields
(
thd
,
tables
,
ref
);
int
ret
=
0
;
if
(
!
(
*
ref
)
->
fixed
)
ret
=
(
*
ref
)
->
fix_fields
(
thd
,
tables
,
ref
);
// We can't substitute aggregate functions (like (SELECT (max(i)))
if
((
*
ref
)
->
with_sum_func
)
{
...
...
@@ -651,9 +654,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
select_lex
->
item_list
.
empty
();
select_lex
->
item_list
.
push_back
(
item
);
if
(
item
->
fix_fields
(
thd
,
join
->
tables_list
,
select_lex
->
item_list
.
head_ref
()))
goto
err
;
// fix_fields call for 'item' will be made during new subquery fix_fields
subs
=
new
Item_singlerow_subselect
(
select_lex
);
}
...
...
sql/item_sum.cc
View file @
8035ce40
...
...
@@ -162,6 +162,7 @@ Item_sum_int::val_str(String *str)
bool
Item_sum_num
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
!
thd
->
allow_sum_func
)
{
my_error
(
ER_INVALID_GROUP_FUNC_USE
,
MYF
(
0
));
...
...
@@ -191,6 +192,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
bool
Item_sum_hybrid
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
Item
*
item
=
args
[
0
];
if
(
!
thd
->
allow_sum_func
)
{
...
...
@@ -1116,6 +1118,7 @@ void Item_sum_count_distinct::cleanup()
bool
Item_sum_count_distinct
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
Item_sum_num
::
fix_fields
(
thd
,
tables
,
ref
))
return
1
;
return
0
;
...
...
@@ -1679,6 +1682,7 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct,
void
Item_func_group_concat
::
cleanup
()
{
DBUG_ENTER
(
"Item_func_group_concat::cleanup"
);
Item_sum
::
cleanup
();
/*
Free table and tree if they belong to this item (if item have not pointer
to original item from which was made copy => it own its objects )
...
...
@@ -1794,6 +1798,7 @@ void Item_func_group_concat::reset_field()
bool
Item_func_group_concat
::
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
uint
i
;
/* for loop variable */
if
(
!
thd
->
allow_sum_func
)
...
...
sql/item_sum.h
View file @
8035ce40
...
...
@@ -533,6 +533,7 @@ class Item_udf_sum : public Item_sum
const
char
*
func_name
()
const
{
return
udf
.
name
();
}
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
fixed
=
1
;
return
udf
.
fix_fields
(
thd
,
tables
,
this
,
this
->
arg_count
,
this
->
args
);
}
...
...
sql/item_uniq.h
View file @
8035ce40
...
...
@@ -48,6 +48,7 @@ class Item_sum_unique_users :public Item_sum_num
void
update_field
()
{}
bool
fix_fields
(
THD
*
thd
,
TABLE_LIST
*
tlist
,
Item
**
ref
)
{
DBUG_ASSERT
(
fixed
==
0
);
fixed
=
1
;
return
0
;
}
...
...
sql/sql_base.cc
View file @
8035ce40
...
...
@@ -2140,7 +2140,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
Item
**
ref
=
ref_pointer_array
;
while
((
item
=
it
++
))
{
if
(
item
->
fix_fields
(
thd
,
tables
,
it
.
ref
())
||
if
(
!
item
->
fixed
&&
item
->
fix_fields
(
thd
,
tables
,
it
.
ref
())
||
(
item
=
*
(
it
.
ref
()))
->
check_cols
(
1
))
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
if
(
ref
)
...
...
@@ -2322,7 +2322,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
if
(
*
conds
)
{
thd
->
where
=
"where clause"
;
if
((
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
)
||
(
*
conds
)
->
check_cols
(
1
))
if
(
!
(
*
conds
)
->
fixed
&&
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
)
||
(
*
conds
)
->
check_cols
(
1
))
DBUG_RETURN
(
1
);
not_null_tables
=
(
*
conds
)
->
not_null_tables
();
}
...
...
@@ -2334,7 +2335,9 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
/* Make a join an a expression */
thd
->
where
=
"on clause"
;
if
(
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
if
(
!
table
->
on_expr
->
fixed
&&
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
table
->
on_expr
->
check_cols
(
1
))
DBUG_RETURN
(
1
);
thd
->
lex
->
current_select
->
cond_count
++
;
...
...
sql/sql_derived.cc
View file @
8035ce40
...
...
@@ -151,7 +151,11 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
if
(
is_union
)
res
=
mysql_union
(
thd
,
lex
,
derived_result
,
unit
);
{
// execute union without clean up
if
(
!
(
res
=
unit
->
prepare
(
thd
,
derived_result
,
SELECT_NO_UNLOCK
)))
res
=
unit
->
exec
();
}
else
{
unit
->
offset_limit_cnt
=
first_select
->
offset_limit
;
...
...
sql/sql_select.cc
View file @
8035ce40
...
...
@@ -70,8 +70,10 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
uint
select_options
,
const
char
*
info
,
Item
*
having
,
Procedure
*
proc
,
SELECT_LEX_UNIT
*
unit
);
static
COND
*
optimize_cond
(
COND
*
conds
,
Item
::
cond_result
*
cond_value
);
static
COND
*
remove_eq_conds
(
COND
*
cond
,
Item
::
cond_result
*
cond_value
);
static
COND
*
optimize_cond
(
THD
*
thd
,
COND
*
conds
,
Item
::
cond_result
*
cond_value
);
static
COND
*
remove_eq_conds
(
THD
*
thd
,
COND
*
cond
,
Item
::
cond_result
*
cond_value
);
static
bool
const_expression_in_where
(
COND
*
conds
,
Item
*
item
,
Item
**
comp_item
);
static
bool
open_tmp_table
(
TABLE
*
table
);
static
bool
create_myisam_tmp_table
(
TABLE
*
table
,
TMP_TABLE_PARAM
*
param
,
...
...
@@ -286,6 +288,10 @@ JOIN::prepare(Item ***rref_pointer_array,
{
DBUG_ENTER
(
"JOIN::prepare"
);
// to prevent double initialization on EXPLAIN
if
(
optimized
)
DBUG_RETURN
(
0
);
conds
=
conds_init
;
order
=
order_init
;
group_list
=
group_init
;
...
...
@@ -315,7 +321,8 @@ JOIN::prepare(Item ***rref_pointer_array,
thd
->
where
=
"having clause"
;
thd
->
allow_sum_func
=
1
;
select_lex
->
having_fix_field
=
1
;
bool
having_fix_rc
=
(
having
->
fix_fields
(
thd
,
tables_list
,
&
having
)
||
bool
having_fix_rc
=
!
having
->
fixed
&&
(
having
->
fix_fields
(
thd
,
tables_list
,
&
having
)
||
having
->
check_cols
(
1
));
select_lex
->
having_fix_field
=
0
;
if
(
having_fix_rc
||
thd
->
net
.
report_error
)
...
...
@@ -518,7 +525,7 @@ JOIN::optimize()
}
#endif
conds
=
optimize_cond
(
conds
,
&
cond_value
);
conds
=
optimize_cond
(
thd
,
conds
,
&
cond_value
);
if
(
thd
->
net
.
report_error
)
{
error
=
1
;
...
...
@@ -4333,6 +4340,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
SYNPOSIS
eliminate_not_funcs()
thd thread handler
cond condition tree
DESCRIPTION
...
...
@@ -4349,7 +4357,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
New condition tree
*/
COND
*
eliminate_not_funcs
(
COND
*
cond
)
COND
*
eliminate_not_funcs
(
THD
*
thd
,
COND
*
cond
)
{
if
(
!
cond
)
return
cond
;
...
...
@@ -4359,7 +4367,7 @@ COND *eliminate_not_funcs(COND *cond)
Item
*
item
;
while
((
item
=
li
++
))
{
Item
*
new_item
=
eliminate_not_funcs
(
item
);
Item
*
new_item
=
eliminate_not_funcs
(
thd
,
item
);
if
(
item
!=
new_item
)
VOID
(
li
.
replace
(
new_item
));
/* replace item with a new condition */
}
...
...
@@ -4367,14 +4375,13 @@ COND *eliminate_not_funcs(COND *cond)
else
if
(
cond
->
type
()
==
Item
::
FUNC_ITEM
&&
/* 'NOT' operation? */
((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
NOT_FUNC
)
{
COND
*
new_cond
=
((
Item_func
*
)
cond
)
->
arguments
()[
0
]
->
neg_transformer
();
COND
*
new_cond
=
((
Item_func
*
)
cond
)
->
arguments
()[
0
]
->
neg_transformer
(
thd
);
if
(
new_cond
)
{
/*
Here we can delete the NOT function. Something like: delete cond;
But we don't need to do it. All items will be deleted later at once.
*/
new_cond
->
fix_fields
(
current_thd
,
0
,
&
new_cond
);
cond
=
new_cond
;
}
}
...
...
@@ -4383,7 +4390,7 @@ COND *eliminate_not_funcs(COND *cond)
static
COND
*
optimize_cond
(
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
optimize_cond
(
THD
*
thd
,
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
{
DBUG_ENTER
(
"optimize_cond"
);
if
(
!
conds
)
...
...
@@ -4393,7 +4400,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
}
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
/* eliminate NOT operators */
conds
=
eliminate_not_funcs
(
conds
);
conds
=
eliminate_not_funcs
(
thd
,
conds
);
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
/* change field = field to field = const for each found field = const */
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
...
...
@@ -4402,7 +4409,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
Remove all and-levels where CONST item != CONST item
*/
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after const change"
););
conds
=
remove_eq_conds
(
conds
,
cond_value
)
;
conds
=
remove_eq_conds
(
thd
,
conds
,
cond_value
)
;
DBUG_EXECUTE
(
"info"
,
print_where
(
conds
,
"after remove"
););
DBUG_RETURN
(
conds
);
}
...
...
@@ -4417,7 +4424,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
*/
static
COND
*
remove_eq_conds
(
COND
*
cond
,
Item
::
cond_result
*
cond_value
)
remove_eq_conds
(
THD
*
thd
,
COND
*
cond
,
Item
::
cond_result
*
cond_value
)
{
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
{
...
...
@@ -4431,7 +4438,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
Item
*
item
;
while
((
item
=
li
++
))
{
Item
*
new_item
=
remove_eq_conds
(
item
,
&
tmp_cond_value
);
Item
*
new_item
=
remove_eq_conds
(
thd
,
item
,
&
tmp_cond_value
);
if
(
!
new_item
)
li
.
remove
();
else
if
(
item
!=
new_item
)
...
...
@@ -4465,7 +4472,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
}
}
if
(
should_fix_fields
)
cond
->
fix_fields
(
current_thd
,
0
,
&
cond
);
cond
->
update_used_tables
(
);
if
(
!
((
Item_cond
*
)
cond
)
->
argument_list
()
->
elements
||
*
cond_value
!=
Item
::
COND_OK
)
...
...
@@ -4492,7 +4499,6 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
Item_func_isnull
*
func
=
(
Item_func_isnull
*
)
cond
;
Item
**
args
=
func
->
arguments
();
THD
*
thd
=
current_thd
;
if
(
args
[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
...
...
@@ -7913,10 +7919,15 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
}
order
->
in_field_list
=
0
;
Item
*
it
=
*
order
->
item
;
if
(
it
->
fix_fields
(
thd
,
tables
,
order
->
item
)
||
/*
we check it->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called
*/
if
(
!
it
->
fixed
&&
(
it
->
fix_fields
(
thd
,
tables
,
order
->
item
)
||
//'it' ressigned because fix_field can change it
(
it
=
*
order
->
item
)
->
check_cols
(
1
)
||
thd
->
is_fatal_error
)
thd
->
is_fatal_error
)
)
return
1
;
// Wrong field
uint
el
=
all_fields
.
elements
;
all_fields
.
push_front
(
it
);
// Add new field to field list
...
...
sql/sql_select.h
View file @
8035ce40
...
...
@@ -432,4 +432,4 @@ bool cp_buffer_from_ref(TABLE_REF *ref);
bool
error_if_full_join
(
JOIN
*
join
);
int
report_error
(
TABLE
*
table
,
int
error
);
int
safe_index_read
(
JOIN_TAB
*
tab
);
COND
*
eliminate_not_funcs
(
COND
*
cond
);
COND
*
eliminate_not_funcs
(
THD
*
thd
,
COND
*
cond
);
sql/sql_union.cc
View file @
8035ce40
...
...
@@ -203,6 +203,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
}
item_list
.
empty
();
// it is not single select
if
(
first_select
->
next_select
())
{
union_result
->
tmp_table_param
.
field_count
=
types
.
elements
;
...
...
@@ -222,14 +224,17 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
result_table_list
.
table
=
table
;
union_result
->
set_table
(
table
);
item_list
.
empty
();
thd_arg
->
lex
->
current_select
=
lex_select_save
;
{
Field
**
field
;
for
(
field
=
table
->
field
;
*
field
;
field
++
)
{
if
(
item_list
.
push_back
(
new
Item_field
(
*
field
)))
Item_field
*
item
=
new
Item_field
(
*
field
);
if
(
item_list
.
push_back
(
item
))
DBUG_RETURN
(
-
1
);
#ifndef DBUG_OFF
item
->
double_fix
=
0
;
#endif
}
}
}
...
...
tests/client_test.c
View file @
8035ce40
...
...
@@ -8206,7 +8206,6 @@ static void test_bug2247()
}
static
void
test_subqueries
()
{
MYSQL_STMT
*
stmt
;
...
...
@@ -8346,6 +8345,37 @@ static void test_bug2248()
myquery
(
rc
);
}
static
void
test_subqueries_ref
()
{
MYSQL_STMT
*
stmt
;
int
rc
,
i
;
const
char
*
query
=
"SELECT a as ccc from t1 where a+1=(SELECT 1+ccc from t1 where ccc+1=a+1 and a=1)"
;
myheader
(
"test_subquery_ref"
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE IF EXISTS t1"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"CREATE TABLE t1 (a int);"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t1 values (1), (2), (3), (4), (5);"
);
myquery
(
rc
);
stmt
=
mysql_prepare
(
mysql
,
query
,
strlen
(
query
));
mystmt_init
(
stmt
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
rc
=
mysql_execute
(
stmt
);
mystmt
(
stmt
,
rc
);
assert
(
1
==
my_process_stmt_result
(
stmt
));
}
mysql_stmt_close
(
stmt
);
rc
=
mysql_query
(
mysql
,
"DROP TABLE t1"
);
myquery
(
rc
);
}
/*
Read and parse arguments and MySQL options from my.cnf
...
...
@@ -8602,6 +8632,9 @@ int main(int argc, char **argv)
test_subqueries
();
/* repeatable subqueries */
test_bad_union
();
/* correct setup of UNION */
test_distinct
();
/* distinct aggregate functions */
test_subqueries_ref
();
/* outer reference in subqueries converted
Item_field -> Item_ref */
end_time
=
time
((
time_t
*
)
0
);
...
...
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