Adaptive comment
This commit is contained in:
@ -250,6 +250,14 @@ int ObParser::parse(
|
|||||||
ObCharset::is_valid_collation(connection_collation_)
|
ObCharset::is_valid_collation(connection_collation_)
|
||||||
? (ObCharset::charset_type_by_coll(connection_collation_) != CHARSET_UTF8MB4)
|
? (ObCharset::charset_type_by_coll(connection_collation_) != CHARSET_UTF8MB4)
|
||||||
: false;
|
: false;
|
||||||
|
parse_result.malloc_pool_ = allocator_;
|
||||||
|
parse_result.sql_mode_ = sql_mode_;
|
||||||
|
parse_result.need_parameterize_ = (FP_MODE == parse_mode || FP_PARAMERIZE_AND_FILTER_HINT_MODE == parse_mode);
|
||||||
|
parse_result.minus_ctx_.pos_ = -1;
|
||||||
|
parse_result.minus_ctx_.raw_sql_offset_ = -1;
|
||||||
|
parse_result.charset_info_ = ObCharset::get_charset(connection_collation_);
|
||||||
|
parse_result.connection_collation_ = connection_collation_;
|
||||||
|
parse_result.mysql_compatible_comment_ = false;
|
||||||
|
|
||||||
if (parse_result.is_fp_ || parse_result.is_dynamic_sql_) {
|
if (parse_result.is_fp_ || parse_result.is_dynamic_sql_) {
|
||||||
int64_t new_length = parse_result.is_fp_ ? stmt.length() + 1 : stmt.length() * 2;
|
int64_t new_length = parse_result.is_fp_ ? stmt.length() + 1 : stmt.length() * 2;
|
||||||
|
|||||||
@ -249,6 +249,8 @@ typedef struct {
|
|||||||
const struct ObCharsetInfo* charset_info_;
|
const struct ObCharsetInfo* charset_info_;
|
||||||
int last_well_formed_len_;
|
int last_well_formed_len_;
|
||||||
bool may_bool_value_; // used for true/false in sql parser
|
bool may_bool_value_; // used for true/false in sql parser
|
||||||
|
int connection_collation_; // connection collation
|
||||||
|
bool mysql_compatible_comment_; // whether the parser is parsing "/*! xxxx */"
|
||||||
|
|
||||||
#ifdef SQL_PARSER_COMPILATION
|
#ifdef SQL_PARSER_COMPILATION
|
||||||
TokenPosInfo* comment_list_;
|
TokenPosInfo* comment_list_;
|
||||||
|
|||||||
@ -10,6 +10,9 @@
|
|||||||
* See the Mulan PubL v2 for more details.
|
* See the Mulan PubL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* unput() change the yyin but it doesn't change ParserResult->input_sql_.
|
||||||
|
// use unput() function may have unexpected result while copy string.
|
||||||
|
*/
|
||||||
%option noyywrap nounput noinput nodefault case-insensitive
|
%option noyywrap nounput noinput nodefault case-insensitive
|
||||||
%option noyyalloc noyyrealloc noyyfree
|
%option noyyalloc noyyrealloc noyyfree
|
||||||
%option reentrant bison-bridge bison-locations
|
%option reentrant bison-bridge bison-locations
|
||||||
@ -84,6 +87,10 @@ btend {backtick}
|
|||||||
btdouble {backtick}{backtick}
|
btdouble {backtick}{backtick}
|
||||||
btcontent [^`]+
|
btcontent [^`]+
|
||||||
|
|
||||||
|
mysql_compatible_comment_with_version \/\*\![0-9]{5}
|
||||||
|
mysql_compatible_comment_without_version \/\*\!
|
||||||
|
mysql_compatible_comment_end \*\/
|
||||||
|
|
||||||
rowidPattern (WITH{whitespace}ROWID)
|
rowidPattern (WITH{whitespace}ROWID)
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@ -1139,6 +1146,14 @@ Timestamp{whitespace}?\"[^\"]*\" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{mysql_compatible_comment_without_version} {
|
||||||
|
// if is a mysql comment without version. For example, /*!any sql str*/
|
||||||
|
// mysql_comment without version, processed as common sql str;
|
||||||
|
// place before `c_cmt_begin` to avoid (the '/*!') being hidden by '/*')
|
||||||
|
ParseResult *p = (ParseResult *)yyextra;
|
||||||
|
p->mysql_compatible_comment_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
{c_cmt_begin} {
|
{c_cmt_begin} {
|
||||||
BEGIN(in_c_comment);
|
BEGIN(in_c_comment);
|
||||||
#ifdef SQL_PARSER_COMPILATION
|
#ifdef SQL_PARSER_COMPILATION
|
||||||
@ -1171,6 +1186,25 @@ BEGIN(in_c_comment);
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{mysql_compatible_comment_end} {
|
||||||
|
//for mysql compatible comment:
|
||||||
|
// only "*/" should be matched, duplicated '*' (e.g., "***/") will report a error.
|
||||||
|
ParseResult *p = (ParseResult *)yyextra;
|
||||||
|
if (p->mysql_compatible_comment_){
|
||||||
|
p->mysql_compatible_comment_ = false;
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
} else {
|
||||||
|
// The sql could be "select */*!xxx*/ from t1;". We can't directly raise a syntax
|
||||||
|
// error here. We should treat the "*/" as '*' and '/' by return '*' and unput '/';
|
||||||
|
|
||||||
|
// yyless will change the yytext and yyleng.
|
||||||
|
char c_ret = yytext[0];
|
||||||
|
yyless(1);
|
||||||
|
p->yycolumn_ = p->yycolumn_ - 1;
|
||||||
|
return c_ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<in_c_comment><<EOF>> {
|
<in_c_comment><<EOF>> {
|
||||||
yyerror(yylloc, yyextra, "unterminated log_level string\n");
|
yyerror(yylloc, yyextra, "unterminated log_level string\n");
|
||||||
return PARSER_SYNTAX_ERROR;
|
return PARSER_SYNTAX_ERROR;
|
||||||
@ -1401,6 +1435,15 @@ BEGIN(in_c_comment);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{mysql_compatible_comment_with_version} {
|
||||||
|
// comment with version: /*!50600 any sql str*/
|
||||||
|
// comment without version: /*!any sql str*/
|
||||||
|
// we do not add a start_condition, since some sql string need to be processed in INITIAL state.
|
||||||
|
// instead of a new start_condition, we use a extra field (mysql_compatible_comment_) to mark the adaptive comment.
|
||||||
|
ParseResult *p = (ParseResult *)yyextra;
|
||||||
|
p->mysql_compatible_comment_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
[\n] {
|
[\n] {
|
||||||
yylineno ++;
|
yylineno ++;
|
||||||
if (IS_FAST_PARAMETERIZE) {
|
if (IS_FAST_PARAMETERIZE) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -320,7 +320,6 @@ const char* get_type_name(int type)
|
|||||||
case T_FUN_SYS_TIME_TO_SEC : return "T_FUN_SYS_TIME_TO_SEC";
|
case T_FUN_SYS_TIME_TO_SEC : return "T_FUN_SYS_TIME_TO_SEC";
|
||||||
case T_FUN_SYS_SEC_TO_TIME : return "T_FUN_SYS_SEC_TO_TIME";
|
case T_FUN_SYS_SEC_TO_TIME : return "T_FUN_SYS_SEC_TO_TIME";
|
||||||
case T_FUN_SYS_INTERVAL : return "T_FUN_SYS_INTERVAL";
|
case T_FUN_SYS_INTERVAL : return "T_FUN_SYS_INTERVAL";
|
||||||
case T_FUN_SYS_CONVERT_TZ : return "T_FUN_SYS_CONVERT_TZ";
|
|
||||||
case T_FUN_UDF : return "T_FUN_UDF";
|
case T_FUN_UDF : return "T_FUN_UDF";
|
||||||
case T_FUN_SYS_SUBTIME : return "T_FUN_SYS_SUBTIME";
|
case T_FUN_SYS_SUBTIME : return "T_FUN_SYS_SUBTIME";
|
||||||
case T_FUN_SYS_SQRT : return "T_FUN_SYS_SQRT";
|
case T_FUN_SYS_SQRT : return "T_FUN_SYS_SQRT";
|
||||||
@ -520,6 +519,7 @@ const char* get_type_name(int type)
|
|||||||
case T_FUN_SYS_UTC_TIME : return "T_FUN_SYS_UTC_TIME";
|
case T_FUN_SYS_UTC_TIME : return "T_FUN_SYS_UTC_TIME";
|
||||||
case T_FUN_SYS_UTC_DATE : return "T_FUN_SYS_UTC_DATE";
|
case T_FUN_SYS_UTC_DATE : return "T_FUN_SYS_UTC_DATE";
|
||||||
case T_FUN_SYS_TIME_FORMAT : return "T_FUN_SYS_TIME_FORMAT";
|
case T_FUN_SYS_TIME_FORMAT : return "T_FUN_SYS_TIME_FORMAT";
|
||||||
|
case T_FUN_SYS_CONVERT_TZ : return "T_FUN_SYS_CONVERT_TZ";
|
||||||
case T_FUN_SYS_END : return "T_FUN_SYS_END";
|
case T_FUN_SYS_END : return "T_FUN_SYS_END";
|
||||||
case T_MAX_OP : return "T_MAX_OP";
|
case T_MAX_OP : return "T_MAX_OP";
|
||||||
case T_FUN_MATCH_AGAINST : return "T_FUN_MATCH_AGAINST";
|
case T_FUN_MATCH_AGAINST : return "T_FUN_MATCH_AGAINST";
|
||||||
|
|||||||
Reference in New Issue
Block a user