summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy79
1 files changed, 72 insertions, 7 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 83b5692d606..0dc8ed7037e 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -32,6 +32,7 @@
#define YYTHD ((THD *)yythd)
#define YYLIP (& YYTHD->m_parser_state->m_lip)
#define YYPS (& YYTHD->m_parser_state->m_yacc)
+#define YYCSCL YYTHD->variables.character_set_client
#define MYSQL_YACC
#define YYINITDEPTH 100
@@ -899,10 +900,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */
/*
- Currently there are 170 shift/reduce conflicts.
+ Currently there are 167 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 170
+%expect 167
/*
Comments for TOKENS.
@@ -1628,7 +1629,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
replace_lock_option opt_low_priority insert_lock_option load_data_lock
%type <item>
- literal text_literal insert_ident order_ident
+ literal text_literal insert_ident order_ident temporal_literal
simple_ident expr opt_expr opt_else sum_expr in_sum_expr
variable variable_aux bool_pri
predicate bit_expr
@@ -8741,7 +8742,48 @@ simple_expr:
MYSQL_YYABORT;
}
| '{' ident expr '}'
- { $$= $3; }
+ {
+ Item_string *item;
+ $$= NULL;
+ /*
+ If "expr" is 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 ($3->type() == Item::STRING_ITEM &&
+ (item= (Item_string *) $3) &&
+ item->collation.repertoire == MY_REPERTOIRE_ASCII &&
+ item->str_value.length() < MAX_DATE_STRING_REP_LENGTH * 4)
+ {
+ enum_field_types type= MYSQL_TYPE_STRING;
+ LEX_STRING *ls= &$2;
+ if (ls->length == 1)
+ {
+ if (ls->str[0] == 'd') /* {d'2001-01-01'} */
+ type= MYSQL_TYPE_DATE;
+ else if (ls->str[0] == 't') /* {t'10:20:30'} */
+ type= MYSQL_TYPE_TIME;
+ }
+ else if (ls->length == 2) /* {ts'2001-01-01 10:20:30'} */
+ {
+ if (ls->str[0] == 't' && ls->str[1] == 's')
+ type= MYSQL_TYPE_DATETIME;
+ }
+ if (type != MYSQL_TYPE_STRING)
+ {
+ $$= create_temporal_literal(YYTHD,
+ item->str_value.ptr(),
+ item->str_value.length(),
+ item->str_value.charset(),
+ type, false);
+ }
+ }
+ if ($$ == NULL)
+ $$= $3;
+ }
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{
$2->push_front($5);
@@ -12730,6 +12772,7 @@ signed_literal:
literal:
text_literal { $$ = $1; }
| NUM_literal { $$ = $1; }
+ | temporal_literal { $$= $1; }
| NULL_SYM
{
$$ = new (YYTHD->mem_root) Item_null();
@@ -12824,9 +12867,6 @@ literal:
$$= item_str;
}
- | DATE_SYM text_literal { $$ = $2; }
- | TIME_SYM text_literal { $$ = $2; }
- | TIMESTAMP text_literal { $$ = $2; }
;
NUM_literal:
@@ -12875,6 +12915,31 @@ NUM_literal:
}
;
+
+temporal_literal:
+ DATE_SYM TEXT_STRING
+ {
+ if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
+ MYSQL_TYPE_DATE, true)))
+ MYSQL_YYABORT;
+ }
+ | TIME_SYM TEXT_STRING
+ {
+ if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
+ MYSQL_TYPE_TIME, true)))
+ MYSQL_YYABORT;
+ }
+ | TIMESTAMP TEXT_STRING
+ {
+ if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
+ MYSQL_TYPE_DATETIME, true)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+
+
/**********************************************************************
** Creating different items.
**********************************************************************/