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
a78d1aaa
Commit
a78d1aaa
authored
Jul 24, 2018
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-16806 Add Type_handler::create_literal_item()
parent
fee46323
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
184 additions
and
154 deletions
+184
-154
sql/item.cc
sql/item.cc
+9
-5
sql/item.h
sql/item.h
+0
-28
sql/item_create.cc
sql/item_create.cc
+0
-78
sql/item_create.h
sql/item_create.h
+0
-15
sql/sql_type.cc
sql/sql_type.cc
+117
-0
sql/sql_type.h
sql/sql_type.h
+34
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+12
-14
sql/sql_yacc_ora.yy
sql/sql_yacc_ora.yy
+12
-14
No files found.
sql/item.cc
View file @
a78d1aaa
...
...
@@ -6951,14 +6951,18 @@ Item_string::make_string_literal_concat(THD *thd, const LEX_CSTRING *str)
*/
Item
*
Item_string
::
make_odbc_literal
(
THD
*
thd
,
const
LEX_CSTRING
*
typestr
)
{
enum_field_types
type
=
odbc_temporal_literal_type
(
typestr
);
Item
*
res
=
type
==
MYSQL_TYPE_STRING
?
this
:
create_temporal_literal
(
thd
,
val_str
(
NULL
),
type
,
false
);
Item_literal
*
res
;
const
Type_handler
*
h
;
if
(
collation
.
repertoire
==
MY_REPERTOIRE_ASCII
&&
str_value
.
length
()
<
MAX_DATE_STRING_REP_LENGTH
*
4
&&
(
h
=
Type_handler
::
odbc_literal_type_handler
(
typestr
))
&&
(
res
=
h
->
create_literal_item
(
thd
,
val_str
(
NULL
),
false
)))
return
res
;
/*
create_temporal_literal
() returns NULL if failed to parse the string,
h->create_literal_item
() returns NULL if failed to parse the string,
or the string format did not match the type, e.g.: {d'2001-01-01 10:10:10'}
*/
return
res
?
res
:
this
;
return
this
;
}
...
...
sql/item.h
View file @
a78d1aaa
...
...
@@ -4330,34 +4330,6 @@ class Item_string :public Item_literal
String
*
check_well_formed_result
(
bool
send_error
)
{
return
Item
::
check_well_formed_result
(
&
str_value
,
send_error
);
}
enum_field_types
odbc_temporal_literal_type
(
const
LEX_CSTRING
*
type_str
)
const
{
/*
If string is a reasonably short pure ASCII string literal,
try to parse known ODBC style date, time or timestamp literals,
e.g:
SELECT {d'2001-01-01'};
SELECT {t'10:20:30'};
SELECT {ts'2001-01-01 10:20:30'};
*/
if
(
collation
.
repertoire
==
MY_REPERTOIRE_ASCII
&&
str_value
.
length
()
<
MAX_DATE_STRING_REP_LENGTH
*
4
)
{
if
(
type_str
->
length
==
1
)
{
if
(
type_str
->
str
[
0
]
==
'd'
)
/* {d'2001-01-01'} */
return
MYSQL_TYPE_DATE
;
else
if
(
type_str
->
str
[
0
]
==
't'
)
/* {t'10:20:30'} */
return
MYSQL_TYPE_TIME
;
}
else
if
(
type_str
->
length
==
2
)
/* {ts'2001-01-01 10:20:30'} */
{
if
(
type_str
->
str
[
0
]
==
't'
&&
type_str
->
str
[
1
]
==
's'
)
return
MYSQL_TYPE_DATETIME
;
}
}
return
MYSQL_TYPE_STRING
;
// Not a temporal literal
}
Item_basic_constant
*
make_string_literal_concat
(
THD
*
thd
,
const
LEX_CSTRING
*
);
Item
*
make_odbc_literal
(
THD
*
thd
,
const
LEX_CSTRING
*
typestr
);
...
...
sql/item_create.cc
View file @
a78d1aaa
...
...
@@ -7432,84 +7432,6 @@ find_qualified_function_builder(THD *thd)
}
static
bool
have_important_literal_warnings
(
const
MYSQL_TIME_STATUS
*
status
)
{
return
(
status
->
warnings
&
~
MYSQL_TIME_NOTE_TRUNCATED
)
!=
0
;
}
/**
Builder for datetime literals:
TIME'00:00:00', DATE'2001-01-01', TIMESTAMP'2001-01-01 00:00:00'.
@param thd The current thread
@param str Character literal
@param length Length of str
@param type Type of literal (TIME, DATE or DATETIME)
@param send_error Whether to generate an error on failure
*/
Item
*
create_temporal_literal
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
enum_field_types
type
,
bool
send_error
)
{
MYSQL_TIME_STATUS
status
;
MYSQL_TIME
ltime
;
Item
*
item
=
NULL
;
sql_mode_t
flags
=
sql_mode_for_dates
(
thd
);
switch
(
type
)
{
case
MYSQL_TYPE_DATE
:
case
MYSQL_TYPE_NEWDATE
:
if
(
!
str_to_datetime
(
cs
,
str
,
length
,
&
ltime
,
flags
,
&
status
)
&&
ltime
.
time_type
==
MYSQL_TIMESTAMP_DATE
&&
!
status
.
warnings
)
item
=
new
(
thd
->
mem_root
)
Item_date_literal
(
thd
,
&
ltime
);
break
;
case
MYSQL_TYPE_DATETIME
:
if
(
!
str_to_datetime
(
cs
,
str
,
length
,
&
ltime
,
flags
,
&
status
)
&&
ltime
.
time_type
==
MYSQL_TIMESTAMP_DATETIME
&&
!
have_important_literal_warnings
(
&
status
))
item
=
new
(
thd
->
mem_root
)
Item_datetime_literal
(
thd
,
&
ltime
,
status
.
precision
);
break
;
case
MYSQL_TYPE_TIME
:
if
(
!
str_to_time
(
cs
,
str
,
length
,
&
ltime
,
0
,
&
status
)
&&
ltime
.
time_type
==
MYSQL_TIMESTAMP_TIME
&&
!
have_important_literal_warnings
(
&
status
))
item
=
new
(
thd
->
mem_root
)
Item_time_literal
(
thd
,
&
ltime
,
status
.
precision
);
break
;
default:
DBUG_ASSERT
(
0
);
}
if
(
likely
(
item
))
{
if
(
status
.
warnings
)
// e.g. a note on nanosecond truncation
{
ErrConvString
err
(
str
,
length
,
cs
);
make_truncated_value_warning
(
thd
,
Sql_condition
::
time_warn_level
(
status
.
warnings
),
&
err
,
ltime
.
time_type
,
0
);
}
return
item
;
}
if
(
send_error
)
{
const
char
*
typestr
=
(
type
==
MYSQL_TYPE_DATE
)
?
"DATE"
:
(
type
==
MYSQL_TYPE_TIME
)
?
"TIME"
:
"DATETIME"
;
ErrConvString
err
(
str
,
length
,
thd
->
variables
.
character_set_client
);
my_error
(
ER_WRONG_VALUE
,
MYF
(
0
),
typestr
,
err
.
ptr
());
}
return
NULL
;
}
static
List
<
Item
>
*
create_func_dyncol_prepare
(
THD
*
thd
,
DYNCALL_CREATE_DEF
**
dfs
,
List
<
DYNCALL_CREATE_DEF
>
&
list
)
...
...
sql/item_create.h
View file @
a78d1aaa
...
...
@@ -191,21 +191,6 @@ class Create_udf_func : public Create_func
#endif
Item
*
create_temporal_literal
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
enum_field_types
type
,
bool
send_error
);
inline
Item
*
create_temporal_literal
(
THD
*
thd
,
const
String
*
str
,
enum_field_types
type
,
bool
send_error
)
{
return
create_temporal_literal
(
thd
,
str
->
ptr
(),
str
->
length
(),
str
->
charset
(),
type
,
send_error
);
}
struct
Native_func_registry
{
LEX_CSTRING
name
;
...
...
sql/sql_type.cc
View file @
a78d1aaa
...
...
@@ -285,6 +285,32 @@ bool Type_std_attributes::count_string_length(const char *func_name,
}
/*
Find a handler by its ODBC literal data type.
@param type_str - data type name, not necessarily 0-terminated
@retval - a pointer to data type handler if type_str points
to a known ODBC literal data type, or NULL otherwise
*/
const
Type_handler
*
Type_handler
::
odbc_literal_type_handler
(
const
LEX_CSTRING
*
type_str
)
{
if
(
type_str
->
length
==
1
)
{
if
(
type_str
->
str
[
0
]
==
'd'
)
// {d'2001-01-01'}
return
&
type_handler_newdate
;
else
if
(
type_str
->
str
[
0
]
==
't'
)
// {t'10:20:30'}
return
&
type_handler_time2
;
}
else
if
(
type_str
->
length
==
2
)
// {ts'2001-01-01 10:20:30'}
{
if
(
type_str
->
str
[
0
]
==
't'
&&
type_str
->
str
[
1
]
==
's'
)
return
&
type_handler_datetime2
;
}
return
NULL
;
// Not a known ODBC literal type
}
/**
This method is used by:
- Item_user_var_as_out_param::field_type()
...
...
@@ -6663,3 +6689,94 @@ int Type_handler_real_result::stored_field_cmp_to_item(THD *thd,
return
1
;
return
0
;
}
/***************************************************************************/
static
bool
have_important_literal_warnings
(
const
MYSQL_TIME_STATUS
*
status
)
{
return
(
status
->
warnings
&
~
MYSQL_TIME_NOTE_TRUNCATED
)
!=
0
;
}
static
void
literal_warn
(
THD
*
thd
,
const
Item
*
item
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
const
MYSQL_TIME
*
ltime
,
const
MYSQL_TIME_STATUS
*
st
,
const
char
*
typestr
,
bool
send_error
)
{
if
(
likely
(
item
))
{
if
(
st
->
warnings
)
// e.g. a note on nanosecond truncation
{
ErrConvString
err
(
str
,
length
,
cs
);
make_truncated_value_warning
(
thd
,
Sql_condition
::
time_warn_level
(
st
->
warnings
),
&
err
,
ltime
->
time_type
,
0
);
}
}
else
if
(
send_error
)
{
ErrConvString
err
(
str
,
length
,
cs
);
my_error
(
ER_WRONG_VALUE
,
MYF
(
0
),
typestr
,
err
.
ptr
());
}
}
Item_literal
*
Type_handler_date_common
::
create_literal_item
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
bool
send_error
)
const
{
MYSQL_TIME_STATUS
st
;
MYSQL_TIME
ltime
;
Item_literal
*
item
=
NULL
;
sql_mode_t
flags
=
sql_mode_for_dates
(
thd
);
if
(
!
str_to_datetime
(
cs
,
str
,
length
,
&
ltime
,
flags
,
&
st
)
&&
ltime
.
time_type
==
MYSQL_TIMESTAMP_DATE
&&
!
st
.
warnings
)
item
=
new
(
thd
->
mem_root
)
Item_date_literal
(
thd
,
&
ltime
);
literal_warn
(
thd
,
item
,
str
,
length
,
cs
,
&
ltime
,
&
st
,
"DATE"
,
send_error
);
return
item
;
}
Item_literal
*
Type_handler_temporal_with_date
::
create_literal_item
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
bool
send_error
)
const
{
MYSQL_TIME_STATUS
st
;
MYSQL_TIME
ltime
;
Item_literal
*
item
=
NULL
;
sql_mode_t
flags
=
sql_mode_for_dates
(
thd
);
if
(
!
str_to_datetime
(
cs
,
str
,
length
,
&
ltime
,
flags
,
&
st
)
&&
ltime
.
time_type
==
MYSQL_TIMESTAMP_DATETIME
&&
!
have_important_literal_warnings
(
&
st
))
item
=
new
(
thd
->
mem_root
)
Item_datetime_literal
(
thd
,
&
ltime
,
st
.
precision
);
literal_warn
(
thd
,
item
,
str
,
length
,
cs
,
&
ltime
,
&
st
,
"DATETIME"
,
send_error
);
return
item
;
}
Item_literal
*
Type_handler_time_common
::
create_literal_item
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
bool
send_error
)
const
{
MYSQL_TIME_STATUS
st
;
MYSQL_TIME
ltime
;
Item_literal
*
item
=
NULL
;
if
(
!
str_to_time
(
cs
,
str
,
length
,
&
ltime
,
0
,
&
st
)
&&
ltime
.
time_type
==
MYSQL_TIMESTAMP_TIME
&&
!
have_important_literal_warnings
(
&
st
))
item
=
new
(
thd
->
mem_root
)
Item_time_literal
(
thd
,
&
ltime
,
st
.
precision
);
literal_warn
(
thd
,
item
,
str
,
length
,
cs
,
&
ltime
,
&
st
,
"TIME"
,
send_error
);
return
item
;
}
sql/sql_type.h
View file @
a78d1aaa
...
...
@@ -31,6 +31,7 @@ class Column_definition;
class
Column_definition_attributes
;
class
Item
;
class
Item_const
;
class
Item_literal
;
class
Item_param
;
class
Item_cache
;
class
Item_func_or_sum
;
...
...
@@ -1077,6 +1078,7 @@ class Type_handler
enum_field_types
type
)
const
;
public:
static
const
Type_handler
*
odbc_literal_type_handler
(
const
LEX_CSTRING
*
str
);
static
const
Type_handler
*
blob_type_handler
(
uint
max_octet_length
);
static
const
Type_handler
*
string_type_handler
(
uint
max_octet_length
);
static
const
Type_handler
*
bit_and_int_mixture_handler
(
uint
max_char_len
);
...
...
@@ -1416,6 +1418,32 @@ class Type_handler
Item
*
src
,
const
Item
*
cmp
)
const
=
0
;
virtual
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
=
0
;
/**
A builder for literals with data type name prefix, e.g.:
TIME'00:00:00', DATE'2001-01-01', TIMESTAMP'2001-01-01 00:00:00'.
@param thd The current thread
@param str Character literal
@param length Length of str
@param cs Character set of the string
@param send_error Whether to generate an error on failure
@retval A pointer to a new Item on success
NULL on error (wrong literal value, EOM)
*/
virtual
Item_literal
*
create_literal_item
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
bool
send_error
)
const
{
DBUG_ASSERT
(
0
);
return
NULL
;
}
Item_literal
*
create_literal_item
(
THD
*
thd
,
const
String
*
str
,
bool
send_error
)
const
{
return
create_literal_item
(
thd
,
str
->
ptr
(),
str
->
length
(),
str
->
charset
(),
send_error
);
}
virtual
Item
*
create_typecast_item
(
THD
*
thd
,
Item
*
item
,
const
Type_cast_attributes
&
attr
)
const
{
...
...
@@ -2894,6 +2922,8 @@ class Type_handler_time_common: public Type_handler_temporal_result
{
return
MYSQL_TIMESTAMP_TIME
;
}
Item_literal
*
create_literal_item
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
bool
send_error
)
const
;
Item
*
create_typecast_item
(
THD
*
thd
,
Item
*
item
,
const
Type_cast_attributes
&
attr
)
const
;
bool
Item_eq_value
(
THD
*
thd
,
const
Type_cmp_attributes
*
attr
,
...
...
@@ -3008,6 +3038,8 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result
{
public:
virtual
~
Type_handler_temporal_with_date
()
{}
Item_literal
*
create_literal_item
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
bool
send_error
)
const
;
bool
Item_eq_value
(
THD
*
thd
,
const
Type_cmp_attributes
*
attr
,
Item
*
a
,
Item
*
b
)
const
;
int
stored_field_cmp_to_item
(
THD
*
thd
,
Field
*
field
,
Item
*
item
)
const
;
...
...
@@ -3037,6 +3069,8 @@ class Type_handler_date_common: public Type_handler_temporal_with_date
{
return
MYSQL_TIMESTAMP_DATE
;
}
Item_literal
*
create_literal_item
(
THD
*
thd
,
const
char
*
str
,
size_t
length
,
CHARSET_INFO
*
cs
,
bool
send_error
)
const
;
Item
*
create_typecast_item
(
THD
*
thd
,
Item
*
item
,
const
Type_cast_attributes
&
attr
)
const
;
bool
Column_definition_fix_attributes
(
Column_definition
*
c
)
const
;
...
...
sql/sql_yacc.yy
View file @
a78d1aaa
...
...
@@ -9259,8 +9259,9 @@ history_point:
TIMESTAMP TEXT_STRING
{
Item *item;
if (!(item= create_temporal_literal(thd, $2.str, $2.length, YYCSCL,
MYSQL_TYPE_DATETIME, true)))
if (!(item= type_handler_datetime.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true)))
MYSQL_YYABORT;
$$= Vers_history_point(VERS_TIMESTAMP, item);
}
...
...
@@ -14801,26 +14802,23 @@ NUM_literal:
temporal_literal:
DATE_SYM TEXT_STRING
{
if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length,
YYCSCL,
MYSQL_TYPE_DATE,
true))))
if (unlikely(!($$= type_handler_newdate.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true))))
MYSQL_YYABORT;
}
| TIME_SYM TEXT_STRING
{
if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length,
YYCSCL,
MYSQL_TYPE_TIME,
true))))
if (unlikely(!($$= type_handler_time2.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true))))
MYSQL_YYABORT;
}
| TIMESTAMP TEXT_STRING
{
if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length,
YYCSCL,
MYSQL_TYPE_DATETIME,
true))))
if (unlikely(!($$= type_handler_datetime.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true))))
MYSQL_YYABORT;
}
;
...
...
sql/sql_yacc_ora.yy
View file @
a78d1aaa
...
...
@@ -9387,8 +9387,9 @@ history_point:
TIMESTAMP TEXT_STRING
{
Item *item;
if (!(item= create_temporal_literal(thd, $2.str, $2.length, YYCSCL,
MYSQL_TYPE_DATETIME, true)))
if (!(item= type_handler_datetime2.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true)))
MYSQL_YYABORT;
$$= Vers_history_point(VERS_TIMESTAMP, item);
}
...
...
@@ -15046,26 +15047,23 @@ NUM_literal:
temporal_literal:
DATE_SYM TEXT_STRING
{
if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length,
YYCSCL,
MYSQL_TYPE_DATE,
true))))
if (unlikely(!($$= type_handler_newdate.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true))))
MYSQL_YYABORT;
}
| TIME_SYM TEXT_STRING
{
if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length,
YYCSCL,
MYSQL_TYPE_TIME,
true))))
if (unlikely(!($$= type_handler_time2.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true))))
MYSQL_YYABORT;
}
| TIMESTAMP TEXT_STRING
{
if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length,
YYCSCL,
MYSQL_TYPE_DATETIME,
true))))
if (unlikely(!($$= type_handler_datetime2.create_literal_item(thd,
$2.str, $2.length,
YYCSCL, true))))
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