patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -12,25 +12,24 @@
#include "sql_parser_base.h"
#define YY_EXTRA_TYPE void*
#define YY_EXTRA_TYPE void *
#define yyconst const
typedef void* yyscan_t;
typedef struct yy_buffer_state* YY_BUFFER_STATE;
#define IS_ORACLE_MODE(mode) (0 != (mode & SMO_ORACLE))
#define IS_ORACLE_COMPATIBLE (IS_ORACLE_MODE(p->sql_mode_))
extern int obsql_mysql_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals);
extern int obsql_mysql_yyparse(ParseResult* result);
extern int obsql_mysql_multi_fast_parse(ParseResult* p);
extern int obsql_mysql_fast_parse(ParseResult* p);
extern int obsql_mysql_yylex_destroy(yyscan_t yyscanner);
extern YY_BUFFER_STATE obsql_mysql_yy_scan_bytes(yyconst char* bytes, int len, yyscan_t yyscanner);
extern void obsql_mysql_yy_switch_to_buffer(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner);
extern void obsql_mysql_yy_delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner);
int parse_init(ParseResult* p)
typedef struct yy_buffer_state *YY_BUFFER_STATE;
extern int obsql_mysql_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals );
extern int obsql_mysql_yyparse(ParseResult *result);
extern int obsql_mysql_multi_fast_parse(ParseResult *p);
extern int obsql_mysql_multi_values_parse(ParseResult *p);
extern int obsql_mysql_fast_parse(ParseResult *p);
extern int obsql_mysql_yylex_destroy (yyscan_t yyscanner );
extern YY_BUFFER_STATE obsql_mysql_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
extern void obsql_mysql_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
extern void obsql_mysql_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
int parse_init(ParseResult *p)
{
int ret = 0; // can not include C++ file "ob_define.h"
static __thread char error_msg[MAX_ERROR_MSG] = {'\0'};
p->error_msg_ = error_msg;
if (OB_UNLIKELY(NULL == p || NULL == p->malloc_pool_)) {
ret = -1;
if (NULL != p) {
@ -38,105 +37,29 @@ int parse_init(ParseResult* p)
}
}
if (OB_LIKELY(0 == ret)) {
ret = IS_ORACLE_COMPATIBLE ? OB_PARSER_ERR_PARSE_SQL : obsql_mysql_yylex_init_extra(p, &(p->yyscan_info_));
if (OB_LIKELY( 0 == ret)) {
ret = obsql_mysql_yylex_init_extra(p, &(p->yyscan_info_));
}
return ret;
}
int parse_reset(ParseResult* p)
{
if (NULL != p) {
p->yyscan_info_ = NULL;
p->result_tree_ = NULL;
p->input_sql_ = NULL;
p->input_sql_len_ = 0;
p->malloc_pool_ = NULL;
p->extra_errno_ = 0;
p->error_msg_[0] = '\0';
p->start_col_ = 0;
p->end_col_ = 0;
p->line_ = 0;
p->yycolumn_ = 0;
p->yylineno_ = 0;
p->tmp_literal_ = NULL;
p->question_mark_ctx_.count_ = 0;
p->question_mark_ctx_.by_ordinal_ = false;
p->question_mark_ctx_.by_name_ = false;
p->question_mark_ctx_.name_ = NULL;
p->question_mark_ctx_.capacity_ = 0;
p->sql_mode_ = 0;
p->has_encount_comment_ = false;
p->is_fp_ = false;
p->is_multi_query_ = false;
p->no_param_sql_ = NULL;
p->no_param_sql_len_ = 0;
p->no_param_sql_buf_len_ = 0;
p->param_nodes_ = NULL;
p->tail_param_node_ = NULL;
p->param_node_num_ = 0;
p->token_num_ = 0;
p->is_ignore_hint_ = false;
p->is_ignore_token_ = false;
p->need_parameterize_ = false;
/*for pl*/
p->pl_parse_info_.is_pl_parse_ = false;
p->pl_parse_info_.is_pl_parse_expr_ = false;
p->pl_parse_info_.pl_ns_ = NULL;
p->pl_parse_info_.last_pl_symbol_pos_ = 0;
p->pl_parse_info_.ref_object_nodes_ = NULL;
p->pl_parse_info_.tail_ref_object_node_ = NULL;
/*for q-quote*/
p->in_q_quote_ = false;
p->minus_ctx_.pos_ = 0;
p->minus_ctx_.raw_sql_offset_ = 0;
p->minus_ctx_.has_minus_ = false;
p->minus_ctx_.is_cur_numeric_ = false;
p->is_for_trigger_ = false;
p->is_dynamic_sql_ = false;
p->is_dbms_sql_ = false;
p->is_batched_multi_enabled_split_ = false;
p->is_not_utf8_connection_ = false;
p->charset_info_ = NULL;
p->last_well_formed_len_ = 0;
p->may_bool_value_ = false;
#ifdef SQL_PARSER_COMPILATION
p->comment_list_ = NULL;
p->comment_cnt_ = 0;
p->comment_cap_ = 0;
p->realloc_cnt_ = 0;
p->stop_add_comment_ = false;
#endif
}
return 0;
}
int parse_terminate(ParseResult* p)
int parse_terminate(ParseResult *p)
{
int ret = 0;
if (OB_LIKELY(NULL != p->yyscan_info_)) {
ret = IS_ORACLE_COMPATIBLE ? OB_PARSER_ERR_PARSE_SQL : obsql_mysql_yylex_destroy(p->yyscan_info_);
ret = obsql_mysql_yylex_destroy(p->yyscan_info_);
}
return ret;
}
int parse_sql(ParseResult* p, const char* buf, size_t len)
int parse_sql(ParseResult *p, const char *buf, size_t len)
{
int ret = OB_PARSER_ERR_PARSE_SQL;
if (OB_UNLIKELY(NULL == p)) {
} else if (IS_ORACLE_COMPATIBLE) {
ret = OB_PARSER_ERR_PARSE_SQL;
} else if (OB_UNLIKELY(NULL == buf || len <= 0)) {
snprintf(p->error_msg_, MAX_ERROR_MSG, "Input SQL can not be empty");
ret = OB_PARSER_ERR_EMPTY_QUERY;
} else {
p->result_tree_ = 0;
p->error_msg_[0] = 0;
p->input_sql_ = buf;
p->input_sql_len_ = len;
p->start_col_ = 1;
@ -144,67 +67,74 @@ int parse_sql(ParseResult* p, const char* buf, size_t len)
p->line_ = 1;
p->yycolumn_ = 1;
p->yylineno_ = 1;
p->tmp_literal_ = NULL;
p->last_well_formed_len_ = 0;
#ifdef SQL_PARSER_COMPILATION
p->realloc_cnt_ = p->realloc_cnt_ <= 0 ? 10 : p->realloc_cnt_;
p->comment_cap_ = p->realloc_cnt_;
p->comment_cnt_ = 0;
p->stop_add_comment_ = false;
#endif
if (false == p->pl_parse_info_.is_pl_parse_) {
if (false == p->pl_parse_info_.is_pl_parse_) {//如果是PLParse调用的该接口,不去重置
p->question_mark_ctx_.count_ = 0;
}
// 删除SQL语句末尾的空格 (外层已做)
// while (len > 0 && ISSPACE(buf[len - 1])) {
// --len;
// }
// if (OB_UNLIKELY(len <= 0)) {
//if (OB_UNLIKELY(len <= 0)) {
// (void)snprintf(p->error_msg_, MAX_ERROR_MSG, "Input SQL can not be white space only");
// ret = OB_PARSER_ERR_EMPTY_QUERY;
// } else {
// } else {
{
int val = setjmp(p->jmp_buf_);
static __thread jmp_buf jmp_buf_;
p->jmp_buf_ = &jmp_buf_;
int val = setjmp(*(p->jmp_buf_));
if (val) {
ret = OB_PARSER_ERR_NO_MEMORY;
if (p->extra_errno_ == OB_PARSER_ERR_NO_MEMORY) {
// for error other than NO_MEMORY, we return OB_PARSER_ERR_PARSE_SQL to avoid lost connection.
ret = OB_PARSER_ERR_NO_MEMORY;
} else {
ret = OB_PARSER_ERR_PARSE_SQL;
}
#ifdef SQL_PARSER_COMPILATION
} else if (OB_ISNULL(p->comment_list_ = (TokenPosInfo*)(parse_malloc(
p->realloc_cnt_ * sizeof(TokenPosInfo), p->malloc_pool_)))) {
p->realloc_cnt_ * sizeof(TokenPosInfo),
p->malloc_pool_)))) {
ret = OB_PARSER_ERR_NO_MEMORY;
#endif
} else {
// bp = yy_scan_string(buf, p->yyscan_info_);
YY_BUFFER_STATE bp = obsql_mysql_yy_scan_bytes(buf, len, p->yyscan_info_);
obsql_mysql_yy_switch_to_buffer(bp, p->yyscan_info_);
int tmp_ret = -1;
if (p->is_fp_) {
tmp_ret = obsql_mysql_fast_parse(p);
} else if (p->is_multi_query_) {
tmp_ret = obsql_mysql_multi_fast_parse(p);
} else {
tmp_ret = obsql_mysql_yyparse(p);
}
if (0 == tmp_ret) {
ret = OB_PARSER_SUCCESS;
} else if (2 == tmp_ret) {
ret = OB_PARSER_ERR_NO_MEMORY;
} else {
if (0 != p->extra_errno_) {
ret = p->extra_errno_;
YY_BUFFER_STATE bp = obsql_mysql_yy_scan_bytes(buf, len, p->yyscan_info_);
obsql_mysql_yy_switch_to_buffer(bp, p->yyscan_info_);
int tmp_ret = -1;
if (p->is_fp_) {
tmp_ret = obsql_mysql_fast_parse(p);
} else if (p->is_multi_query_) {
tmp_ret = obsql_mysql_multi_fast_parse(p);
} else if (p->is_multi_values_parser_) {
tmp_ret = obsql_mysql_multi_values_parse(p);
} else {
ret = OB_PARSER_ERR_PARSE_SQL;
tmp_ret = obsql_mysql_yyparse(p);
}
}
obsql_mysql_yy_delete_buffer(bp, p->yyscan_info_);
if (0 == tmp_ret) {
ret = OB_PARSER_SUCCESS;
} else if (2 == tmp_ret) {
ret = OB_PARSER_ERR_NO_MEMORY;
} else {
if (0 != p->extra_errno_) {
ret = p->extra_errno_;
} else {
ret = OB_PARSER_ERR_PARSE_SQL;
}
}
obsql_mysql_yy_delete_buffer(bp, p->yyscan_info_);
}
}
}
return ret;
}
int parse_sql_stmt(ParseResult* parse_result)
int parse_sql_stmt(ParseResult *parse_result)
{
int ret = -1;
if (0 != (ret = parse_init(parse_result))) {
@ -212,14 +142,12 @@ int parse_sql_stmt(ParseResult* parse_result)
// fprintf(stderr, "init parse result failed, ret=%d\n", ret);
} else if (0 != (ret = parse_sql(parse_result, parse_result->input_sql_, parse_result->input_sql_len_))) {
// fix bug #16298144
// fprintf(stderr, "parse sql failed, ret=%d, input_sql=%.*s\n", ret, parse_result->input_sql_len_,
// parse_result->input_sql_);
// fprintf(stderr, "parse sql failed, ret=%d, input_sql=%.*s\n", ret, parse_result->input_sql_len_, parse_result->input_sql_);
}
return ret;
}
void setup_token_pos_info(
ParseNode* node __attribute__((unused)), int off __attribute__((unused)), int len __attribute__((unused)))
void setup_token_pos_info(ParseNode *node, int off, int len)
{
#ifdef SQL_PARSER_COMPILATION
node->token_off_ = off;
@ -229,8 +157,10 @@ void setup_token_pos_info(
#endif
}
int setup_token_pos_info_and_dup_string(ParseNode* node __attribute__((unused)),
ParseResult* result __attribute__((unused)), int start __attribute__((unused)), int end __attribute__((unused)))
int setup_token_pos_info_and_dup_string(ParseNode *node,
ParseResult *result,
int start,
int end)
{
int ret = OB_PARSER_SUCCESS;
#ifdef SQL_PARSER_COMPILATION
@ -238,7 +168,9 @@ int setup_token_pos_info_and_dup_string(ParseNode* node __attribute__((unused)),
node->token_len_ = end - start + 1;
if (start > end) {
ret = OB_PARSER_ERR_UNEXPECTED;
} else if (OB_UNLIKELY((NULL == (node->str_value_ = copy_expr_string(result, start, end))))) {
} else if (OB_UNLIKELY((NULL == (node->str_value_ = copy_expr_string(result,
start,
end))))) {
ret = OB_PARSER_ERR_NO_MEMORY;
} else {
node->str_len_ = end - start + 1;
@ -250,7 +182,7 @@ int setup_token_pos_info_and_dup_string(ParseNode* node __attribute__((unused)),
}
#ifdef SQL_PARSER_COMPILATION
int add_comment_list(ParseResult* p, const TokenPosInfo* info)
int add_comment_list(ParseResult *p, const TokenPosInfo *info)
{
int ret = OB_PARSER_SUCCESS;
if (OB_ISNULL(p) || OB_ISNULL(info)) {
@ -258,7 +190,7 @@ int add_comment_list(ParseResult* p, const TokenPosInfo* info)
}
if (OB_PARSER_SUCCESS == ret && p->comment_cnt_ + 1 >= p->comment_cap_) {
int alloc_cnt = p->comment_cnt_ + p->realloc_cnt_;
char* buf = parse_malloc(sizeof(TokenPosInfo) * alloc_cnt, p->malloc_pool_);
char *buf = parse_malloc(sizeof(TokenPosInfo) * alloc_cnt, p->malloc_pool_);
if (OB_ISNULL(buf)) {
ret = OB_PARSER_ERR_NO_MEMORY;
} else {
@ -276,3 +208,106 @@ int add_comment_list(ParseResult* p, const TokenPosInfo* info)
return ret;
}
#endif
void REPUT_NEG_SIGN(ParseResult *p)
{
if (p->minus_ctx_.has_minus_) {
int start_pos = p->no_param_sql_len_;
int end_pos = p->minus_ctx_.pos_;
for (; start_pos > end_pos; start_pos--) {
p->no_param_sql_[start_pos] = p->no_param_sql_[start_pos - 1];
}
p->no_param_sql_[end_pos] = '-';
p->no_param_sql_[++p->no_param_sql_len_] = '\0';
p->minus_ctx_.pos_ = -1;
p->minus_ctx_.raw_sql_offset_ = -1;
p->minus_ctx_.has_minus_ = false;
}
}
int STORE_PARAM_NODE_NEED_PARAMETERIZE(ParamList *param,
struct _ParseNode *node, ParseResult *p, const int first_column)
{
if (p->minus_ctx_.has_minus_ && p->minus_ctx_.is_cur_numeric_) {
p->no_param_sql_[p->minus_ctx_.pos_] = '?';
p->no_param_sql_len_ = p->minus_ctx_.pos_ + 1;
} else {
REPUT_NEG_SIGN(p);
p->no_param_sql_[p->no_param_sql_len_++] = '?';
}
p->no_param_sql_[p->no_param_sql_len_] = '\0';
node->pos_ = p->no_param_sql_len_ - 1;
node->raw_sql_offset_ = (p->minus_ctx_.has_minus_
&& p->minus_ctx_.is_cur_numeric_) ?
p->minus_ctx_.raw_sql_offset_ : first_column - 1;
param->node_ = node;
param->next_ = NULL;
if (NULL == p->param_nodes_) {
p->param_nodes_ = param;
} else {
p->tail_param_node_->next_ = param;
}
p->tail_param_node_ = param;
p->param_node_num_++;
p->token_num_++;
p->minus_ctx_.has_minus_ = false;
p->minus_ctx_.pos_ = -1;
p->minus_ctx_.is_cur_numeric_ = false;
p->minus_ctx_.raw_sql_offset_ = -1;
return 0;
}
int add_alias_name(ParseNode *node, ParseResult *result, int end)
{
int ret = OB_PARSER_SUCCESS;
if (NULL == node || NULL == result || NULL == node->str_value_) {
ret = OB_PARSER_ERR_UNEXPECTED;
} else {
int need_len = strlen(" as ") + node->str_len_ + 2 * strlen("\"");
if (end > result->pl_parse_info_.last_pl_symbol_pos_) {
need_len += end - result->pl_parse_info_.last_pl_symbol_pos_;
}
for (int i = 0; i < node->str_len_; ++i) {
if ('\"' == node->str_value_[i] && !(i > 0 && '\\' == node->str_value_[i - 1])) {
need_len++;
}
}
if (result->no_param_sql_len_ + need_len >= result->no_param_sql_buf_len_) {
char *buf = parse_malloc(result->no_param_sql_buf_len_ * 2, result->malloc_pool_);
if (OB_UNLIKELY(NULL == buf)) {
ret = OB_PARSER_ERR_NO_MEMORY;
} else {
memmove(buf, result->no_param_sql_, result->no_param_sql_len_);
result->no_param_sql_ = buf;
result->no_param_sql_buf_len_ = result->no_param_sql_buf_len_ * 2;
}
}
if (OB_PARSER_SUCCESS == ret) {
if (end > result->pl_parse_info_.last_pl_symbol_pos_) {
memmove(result->no_param_sql_ + result->no_param_sql_len_, result->input_sql_ + result->pl_parse_info_.last_pl_symbol_pos_, end - result->pl_parse_info_.last_pl_symbol_pos_);
result->no_param_sql_len_ += end - result->pl_parse_info_.last_pl_symbol_pos_;
result->pl_parse_info_.last_pl_symbol_pos_ = end;
}
result->no_param_sql_len_ += sprintf(result->no_param_sql_ + result->no_param_sql_len_, "%.*s", (int)strlen(" as "), " as ");
result->no_param_sql_len_ += sprintf(result->no_param_sql_ + result->no_param_sql_len_, "%.*s", (int)strlen("\""), "\"");
int index1 = 0;
int index2 = 0;
char *trans_buf = parse_malloc((int)node->str_len_ * 2, result->malloc_pool_);
if (OB_UNLIKELY(NULL == trans_buf)) {
ret = OB_PARSER_ERR_NO_MEMORY;
} else {
for (; index1 < node->str_len_; index1++) {
if ('\"' == node->str_value_[index1] && !(index1 > 0 && '\\' == node->str_value_[index1 - 1])) {
trans_buf[index2++] = '\\';
trans_buf[index2++] = '\"';
} else {
trans_buf[index2++] = node->str_value_[index1];
}
}
result->no_param_sql_len_ += sprintf(result->no_param_sql_ + result->no_param_sql_len_, "%.*s", index2, trans_buf);
result->no_param_sql_len_ += sprintf(result->no_param_sql_ + result->no_param_sql_len_, "%.*s", (int)strlen("\""), "\"");
}
}
}
return ret;
}