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
49b29e35
Commit
49b29e35
authored
May 19, 2020
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/10.4' into 10.5
parents
3ea05d08
810b7f8e
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
190 additions
and
100 deletions
+190
-100
mysql-test/main/table_value_constr.result
mysql-test/main/table_value_constr.result
+11
-0
mysql-test/main/table_value_constr.test
mysql-test/main/table_value_constr.test
+14
-0
sql/item.cc
sql/item.cc
+30
-77
sql/item.h
sql/item.h
+128
-19
sql/mysqld.cc
sql/mysqld.cc
+1
-1
sql/share/errmsg-utf8.txt
sql/share/errmsg-utf8.txt
+2
-0
sql/sql_tvc.cc
sql/sql_tvc.cc
+2
-1
sql/sql_yacc.yy
sql/sql_yacc.yy
+2
-2
No files found.
mysql-test/main/table_value_constr.result
View file @
49b29e35
...
...
@@ -2610,3 +2610,14 @@ $$
a
0
1
#
# MDEV-21995 Server crashes in Item_field::real_type_handler with table value constructor
#
VALUES (IGNORE);
ERROR HY000: 'ignore' is not allowed in this context
VALUES (DEFAULT);
ERROR HY000: 'default' is not allowed in this context
EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE;
ERROR HY000: 'ignore' is not allowed in this context
EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT;
ERROR HY000: 'default' is not allowed in this context
mysql-test/main/table_value_constr.test
View file @
49b29e35
...
...
@@ -1339,3 +1339,17 @@ BEGIN NOT ATOMIC
END
;
$$
DELIMITER
;
$$
--
echo
#
--
echo
# MDEV-21995 Server crashes in Item_field::real_type_handler with table value constructor
--
echo
#
--
error
ER_NOT_ALLOWED_IN_THIS_CONTEXT
VALUES
(
IGNORE
);
--
error
ER_NOT_ALLOWED_IN_THIS_CONTEXT
VALUES
(
DEFAULT
);
--
error
ER_NOT_ALLOWED_IN_THIS_CONTEXT
EXECUTE
IMMEDIATE
'VALUES (?)'
USING
IGNORE
;
--
error
ER_NOT_ALLOWED_IN_THIS_CONTEXT
EXECUTE
IMMEDIATE
'VALUES (?)'
USING
DEFAULT
;
sql/item.cc
View file @
49b29e35
...
...
@@ -99,6 +99,13 @@ void item_init(void)
}
void
Item
::
raise_error_not_evaluable
()
{
Item
::
Print
tmp
(
this
,
QT_ORDINARY
);
my_error
(
ER_NOT_ALLOWED_IN_THIS_CONTEXT
,
MYF
(
0
),
tmp
.
ptr
());
}
void
Item
::
push_note_converted_to_negative_complement
(
THD
*
thd
)
{
push_warning
(
thd
,
Sql_condition
::
WARN_LEVEL_NOTE
,
ER_UNKNOWN_ERROR
,
...
...
@@ -4298,6 +4305,23 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
}
bool
Item_param
::
is_evaluable_expression
()
const
{
switch
(
state
)
{
case
SHORT_DATA_VALUE
:
case
LONG_DATA_VALUE
:
case
NULL_VALUE
:
return
true
;
case
NO_VALUE
:
return
true
;
// Not assigned yet, so we don't know
case
IGNORE_VALUE
:
case
DEFAULT_VALUE
:
break
;
}
return
false
;
}
bool
Item_param
::
can_return_value
()
const
{
// There's no "default". See comments in Item_param::save_in_field().
...
...
@@ -9229,12 +9253,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
Item_field
*
field_arg
;
Field
*
def_field
;
DBUG_ASSERT
(
fixed
==
0
);
if
(
!
arg
)
{
fixed
=
1
;
return
FALSE
;
}
DBUG_ASSERT
(
arg
);
/*
DEFAULT() do not need table field so should not ask handler to bring
...
...
@@ -9309,11 +9328,7 @@ void Item_default_value::cleanup()
void
Item_default_value
::
print
(
String
*
str
,
enum_query_type
query_type
)
{
if
(
!
arg
)
{
str
->
append
(
STRING_WITH_LEN
(
"default"
));
return
;
}
DBUG_ASSERT
(
arg
);
str
->
append
(
STRING_WITH_LEN
(
"default("
));
/*
We take DEFAULT from a field so do not need it value in case of const
...
...
@@ -9327,6 +9342,7 @@ void Item_default_value::print(String *str, enum_query_type query_type)
void
Item_default_value
::
calculate
()
{
DBUG_ASSERT
(
arg
);
if
(
field
->
default_value
)
field
->
set_default
();
DEBUG_SYNC
(
field
->
table
->
in_use
,
"after_Item_default_value_calculate"
);
...
...
@@ -9370,14 +9386,8 @@ bool Item_default_value::send(Protocol *protocol, st_value *buffer)
int
Item_default_value
::
save_in_field
(
Field
*
field_arg
,
bool
no_conversions
)
{
if
(
arg
)
{
calculate
();
return
Item_field
::
save_in_field
(
field_arg
,
no_conversions
);
}
return
field_arg
->
save_in_field_default_value
(
context
->
error_processor
==
&
view_error_processor
);
}
table_map
Item_default_value
::
used_tables
()
const
...
...
@@ -9398,13 +9408,7 @@ Item *Item_default_value::transform(THD *thd, Item_transformer transformer,
uchar
*
args
)
{
DBUG_ASSERT
(
!
thd
->
stmt_arena
->
is_stmt_prepare
());
/*
If the value of arg is NULL, then this object represents a constant,
so further transformation is unnecessary (and impossible).
*/
if
(
!
arg
)
return
0
;
DBUG_ASSERT
(
arg
);
Item
*
new_item
=
arg
->
transform
(
thd
,
transformer
,
args
);
if
(
!
new_item
)
...
...
@@ -9421,57 +9425,6 @@ Item *Item_default_value::transform(THD *thd, Item_transformer transformer,
return
(
this
->*
transformer
)(
thd
,
args
);
}
void
Item_ignore_value
::
print
(
String
*
str
,
enum_query_type
query_type
)
{
str
->
append
(
STRING_WITH_LEN
(
"ignore"
));
}
int
Item_ignore_value
::
save_in_field
(
Field
*
field_arg
,
bool
no_conversions
)
{
return
field_arg
->
save_in_field_ignore_value
(
context
->
error_processor
==
&
view_error_processor
);
}
String
*
Item_ignore_value
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
1
;
return
0
;
}
double
Item_ignore_value
::
val_real
()
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
1
;
return
0.0
;
}
longlong
Item_ignore_value
::
val_int
()
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
1
;
return
0
;
}
my_decimal
*
Item_ignore_value
::
val_decimal
(
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
1
;
return
0
;
}
bool
Item_ignore_value
::
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
)
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
1
;
return
TRUE
;
}
bool
Item_ignore_value
::
send
(
Protocol
*
protocol
,
st_value
*
buffer
)
{
DBUG_ASSERT
(
0
);
// never should be called
return
TRUE
;
}
bool
Item_insert_value
::
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
...
...
sql/item.h
View file @
49b29e35
...
...
@@ -763,6 +763,7 @@ class Item: public Value_source,
CONST_ITEM
,
NULL_ITEM
,
// Item_null or Item_param bound to NULL
COPY_STR_ITEM
,
FIELD_AVG_ITEM
,
DEFAULT_VALUE_ITEM
,
CONTEXTUALLY_TYPED_VALUE_ITEM
,
PROC_ITEM
,
COND_ITEM
,
REF_ITEM
,
FIELD_STD_ITEM
,
FIELD_VARIANCE_ITEM
,
INSERT_VALUE_ITEM
,
SUBSELECT_ITEM
,
ROW_ITEM
,
CACHE_ITEM
,
TYPE_HOLDER
,
...
...
@@ -843,6 +844,7 @@ class Item: public Value_source,
const
Tmp_field_param
*
param
,
bool
is_explicit_null
);
void
raise_error_not_evaluable
();
void
push_note_converted_to_negative_complement
(
THD
*
thd
);
void
push_note_converted_to_positive_complement
(
THD
*
thd
);
...
...
@@ -1607,6 +1609,24 @@ class Item: public Value_source,
positions. (And they can't be used before fix_fields is called for them).
*/
virtual
bool
is_order_clause_position
()
const
{
return
false
;
}
/*
Determines if the Item is an evaluable expression, that is
it can return a value, so we can call methods val_xxx(), get_date(), etc.
Most items are evaluable expressions.
Examples of non-evaluable expressions:
- Item_contextually_typed_value_specification (handling DEFAULT and IGNORE)
- Item_type_param bound to DEFAULT and IGNORE
We cannot call the mentioned methods for these Items,
their method implementations typically have DBUG_ASSERT(0).
*/
virtual
bool
is_evaluable_expression
()
const
{
return
true
;
}
bool
check_is_evaluable_expression_or_error
()
{
if
(
is_evaluable_expression
())
return
false
;
// Ok
raise_error_not_evaluable
();
return
true
;
// Error
}
/* cloning of constant items (0 if it is not const) */
virtual
Item
*
clone_item
(
THD
*
thd
)
{
return
0
;
}
/* deep copy item */
...
...
@@ -3858,6 +3878,7 @@ class Item_param :public Item_basic_value,
const
String
*
value_query_val_str
(
THD
*
thd
,
String
*
str
)
const
;
Item
*
value_clone_item
(
THD
*
thd
);
bool
is_evaluable_expression
()
const
;
bool
can_return_value
()
const
;
public:
...
...
@@ -6271,14 +6292,9 @@ class Item_default_value : public Item_field
public:
Item
*
arg
=
nullptr
;
Field
*
cached_field
=
nullptr
;
Item_default_value
(
THD
*
thd
,
Name_resolution_context
*
context_arg
)
:
Item_field
(
thd
,
context_arg
)
{}
Item_default_value
(
THD
*
thd
,
Name_resolution_context
*
context_arg
,
Item
*
a
)
:
Item_field
(
thd
,
context_arg
),
arg
(
a
)
{}
Item_default_value
(
THD
*
thd
,
Name_resolution_context
*
context_arg
,
Field
*
a
)
:
Item_field
(
thd
,
context_arg
)
{}
enum
Type
type
()
const
{
return
DEFAULT_VALUE_ITEM
;
}
bool
vcol_assignment_allowed_value
()
const
{
return
arg
==
NULL
;
}
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
;
bool
fix_fields
(
THD
*
,
Item
**
);
void
cleanup
();
...
...
@@ -6293,7 +6309,7 @@ class Item_default_value : public Item_field
bool
save_in_param
(
THD
*
thd
,
Item_param
*
param
)
{
// It should not be possible to have "EXECUTE .. USING DEFAULT(a)"
DBUG_ASSERT
(
arg
==
NULL
);
DBUG_ASSERT
(
0
);
param
->
set_default
();
return
false
;
}
...
...
@@ -6318,34 +6334,127 @@ class Item_default_value : public Item_field
Item
*
transform
(
THD
*
thd
,
Item_transformer
transformer
,
uchar
*
args
);
};
class
Item_contextually_typed_value_specification
:
public
Item
{
public:
Item_contextually_typed_value_specification
(
THD
*
thd
)
:
Item
(
thd
)
{
}
enum
Type
type
()
const
{
return
CONTEXTUALLY_TYPED_VALUE_ITEM
;
}
bool
vcol_assignment_allowed_value
()
const
{
return
true
;
}
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
{
return
false
;
}
bool
is_evaluable_expression
()
const
{
return
false
;
}
Field
*
create_tmp_field_ex
(
MEM_ROOT
*
root
,
TABLE
*
table
,
Tmp_field_src
*
src
,
const
Tmp_field_param
*
param
)
{
DBUG_ASSERT
(
0
);
return
NULL
;
}
String
*
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
true
;
return
0
;
}
double
val_real
()
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
true
;
return
0.0
;
}
longlong
val_int
()
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
true
;
return
0
;
}
my_decimal
*
val_decimal
(
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
0
);
// never should be called
null_value
=
true
;
return
0
;
}
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
)
{
DBUG_ASSERT
(
0
);
// never should be called
return
null_value
=
true
;
}
bool
send
(
Protocol
*
protocol
,
st_value
*
buffer
)
{
DBUG_ASSERT
(
0
);
return
true
;
}
const
Type_handler
*
type_handler
()
const
{
DBUG_ASSERT
(
0
);
return
&
type_handler_null
;
}
};
/*
<default specification> ::= DEFAULT
*/
class
Item_default_specification
:
public
Item_contextually_typed_value_specification
{
public:
Item_default_specification
(
THD
*
thd
)
:
Item_contextually_typed_value_specification
(
thd
)
{
}
void
print
(
String
*
str
,
enum_query_type
query_type
)
{
str
->
append
(
STRING_WITH_LEN
(
"default"
));
}
int
save_in_field
(
Field
*
field_arg
,
bool
no_conversions
)
{
return
field_arg
->
save_in_field_default_value
(
false
);
}
bool
save_in_param
(
THD
*
thd
,
Item_param
*
param
)
{
param
->
set_default
();
return
false
;
}
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_default_specification
>
(
thd
,
this
);
}
};
/**
This class is used as bulk parameter INGNORE representation.
It just do nothing when assigned to a field
This is a non-standard MariaDB extension.
*/
class
Item_ignore_value
:
public
Item_default_value
class
Item_ignore_specification
:
public
Item_contextually_typed_value_specification
{
public:
Item_ignore_value
(
THD
*
thd
,
Name_resolution_context
*
context_arg
)
:
Item_default_value
(
thd
,
context_arg
)
{};
void
print
(
String
*
str
,
enum_query_type
query_type
);
int
save_in_field
(
Field
*
field_arg
,
bool
no_conversions
);
Item_ignore_specification
(
THD
*
thd
)
:
Item_contextually_typed_value_specification
(
thd
)
{
}
void
print
(
String
*
str
,
enum_query_type
query_type
)
{
str
->
append
(
STRING_WITH_LEN
(
"ignore"
));
}
int
save_in_field
(
Field
*
field_arg
,
bool
no_conversions
)
{
return
field_arg
->
save_in_field_ignore_value
(
false
);
}
bool
save_in_param
(
THD
*
thd
,
Item_param
*
param
)
{
param
->
set_ignore
();
return
false
;
}
String
*
val_str
(
String
*
str
);
double
val_real
();
longlong
val_int
();
my_decimal
*
val_decimal
(
my_decimal
*
decimal_value
);
bool
get_date
(
THD
*
thd
,
MYSQL_TIME
*
ltime
,
date_mode_t
fuzzydate
);
bool
send
(
Protocol
*
protocol
,
st_value
*
buffer
);
Item
*
get_copy
(
THD
*
thd
)
{
return
get_item_copy
<
Item_ignore_specification
>
(
thd
,
this
);
}
};
...
...
sql/mysqld.cc
View file @
49b29e35
...
...
@@ -3607,7 +3607,7 @@ static void get_win_tzname(char* buf, size_t size)
{
0
,
0
}
};
DYNAMIC_TIME_ZONE_INFORMATION
tzinfo
;
if
(
GetDynamicTimeZoneInformation
(
&
tzinfo
)
==
TIME_ZONE_ID_
UNKNOWN
)
if
(
GetDynamicTimeZoneInformation
(
&
tzinfo
)
==
TIME_ZONE_ID_
INVALID
)
{
strncpy
(
buf
,
"unknown"
,
size
);
return
;
...
...
sql/share/errmsg-utf8.txt
View file @
49b29e35
...
...
@@ -7961,3 +7961,5 @@ ER_KEY_CONTAINS_PERIOD_FIELDS
eng "Key %`s cannot explicitly include column %`s"
ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS
eng "Key %`s cannot have WITHOUT OVERLAPS"
ER_NOT_ALLOWED_IN_THIS_CONTEXT
eng "'%-.128s' is not allowed in this context"
sql/sql_tvc.cc
View file @
49b29e35
...
...
@@ -59,7 +59,8 @@ bool fix_fields_for_tvc(THD *thd, List_iterator_fast<List_item> &li)
while replacing their values to NAME_CONST()s.
So fix only those that have not been.
*/
if
(
item
->
fix_fields_if_needed
(
thd
,
0
))
if
(
item
->
fix_fields_if_needed
(
thd
,
0
)
||
item
->
check_is_evaluable_expression_or_error
())
DBUG_RETURN
(
true
);
}
}
...
...
sql/sql_yacc.yy
View file @
49b29e35
...
...
@@ -13047,13 +13047,13 @@ expr_or_default:
expr { $$= $1;}
| DEFAULT
{
$$= new (thd->mem_root) Item_default_
value(thd, Lex->current_context()
);
$$= new (thd->mem_root) Item_default_
specification(thd
);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| IGNORE_SYM
{
$$= new (thd->mem_root) Item_ignore_
value(thd, Lex->current_context()
);
$$= new (thd->mem_root) Item_ignore_
specification(thd
);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
...
...
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