* test * fix multi comment with ';' * fix multi comment with ';' Author: akaError <lzg020616@163.com>
This commit is contained in:
@ -21,7 +21,7 @@
|
|||||||
using namespace oceanbase::sql;
|
using namespace oceanbase::sql;
|
||||||
using namespace oceanbase::common;
|
using namespace oceanbase::common;
|
||||||
|
|
||||||
ObParser::ObParser(common::ObIAllocator& allocator, ObSQLMode mode, ObCollationType conn_collation)
|
ObParser::ObParser(common::ObIAllocator &allocator, ObSQLMode mode, ObCollationType conn_collation)
|
||||||
: allocator_(&allocator), sql_mode_(mode), connection_collation_(conn_collation)
|
: allocator_(&allocator), sql_mode_(mode), connection_collation_(conn_collation)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -30,14 +30,14 @@ ObParser::~ObParser()
|
|||||||
|
|
||||||
#define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\f' || (c) == '\v')
|
#define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\f' || (c) == '\v')
|
||||||
|
|
||||||
bool ObParser::is_pl_stmt(const ObString& stmt, bool* is_create_func)
|
bool ObParser::is_pl_stmt(const ObString &stmt, bool *is_create_func)
|
||||||
{
|
{
|
||||||
UNUSED(stmt);
|
UNUSED(stmt);
|
||||||
UNUSED(is_create_func);
|
UNUSED(is_create_func);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObParser::is_single_stmt(const ObString& stmt)
|
bool ObParser::is_single_stmt(const ObString &stmt)
|
||||||
{
|
{
|
||||||
int64_t count = 0;
|
int64_t count = 0;
|
||||||
int64_t end_trim_offset = stmt.length();
|
int64_t end_trim_offset = stmt.length();
|
||||||
@ -62,7 +62,7 @@ bool ObParser::is_single_stmt(const ObString& stmt)
|
|||||||
// Actually, sql executor only executes the first stmt(create t1) and ignore the others
|
// Actually, sql executor only executes the first stmt(create t1) and ignore the others
|
||||||
// even though try to execute stmts like 'create t1; create t2; create t3;'
|
// even though try to execute stmts like 'create t1; create t2; create t3;'
|
||||||
int ObParser::split_multiple_stmt(
|
int ObParser::split_multiple_stmt(
|
||||||
const ObString& stmt, ObIArray<ObString>& queries, ObMPParseStat& parse_stat, bool is_ret_first_stmt)
|
const ObString &stmt, ObIArray<ObString> &queries, ObMPParseStat &parse_stat, bool is_ret_first_stmt)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
|
|
||||||
@ -76,13 +76,11 @@ int ObParser::split_multiple_stmt(
|
|||||||
int64_t remain = stmt.length();
|
int64_t remain = stmt.length();
|
||||||
|
|
||||||
parse_stat.reset();
|
parse_stat.reset();
|
||||||
while (remain > 0 && ISSPACE(stmt[remain - 1])) {
|
while (remain > 0 && (ISSPACE(stmt[remain - 1]) || '\0' == stmt[remain - 1])) {
|
||||||
--remain;
|
--remain;
|
||||||
}
|
}
|
||||||
if (remain > 0 && '\0' == stmt[remain - 1]) {
|
// case like: "select * from t1;;;;;;"->"select * from t1;"
|
||||||
--remain;
|
while (remain > 1 && ';' == stmt[remain - 1] && ';' == stmt[remain - 2]) {
|
||||||
}
|
|
||||||
while (remain > 0 && ISSPACE(stmt[remain - 1])) {
|
|
||||||
--remain;
|
--remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,20 +94,32 @@ int ObParser::split_multiple_stmt(
|
|||||||
while (remain > 0 && OB_SUCC(ret) && !parse_stat.parse_fail_ && need_continue) {
|
while (remain > 0 && OB_SUCC(ret) && !parse_stat.parse_fail_ && need_continue) {
|
||||||
ObArenaAllocator allocator(CURRENT_CONTEXT->get_malloc_allocator());
|
ObArenaAllocator allocator(CURRENT_CONTEXT->get_malloc_allocator());
|
||||||
allocator.set_label("SplitMultiStmt");
|
allocator.set_label("SplitMultiStmt");
|
||||||
ObIAllocator* bak_allocator = allocator_;
|
ObIAllocator *bak_allocator = allocator_;
|
||||||
allocator_ = &allocator;
|
allocator_ = &allocator;
|
||||||
int64_t str_len = 0;
|
int64_t str_len = 0;
|
||||||
//for save memory allocate in parser, we need try find the single stmt length in advance
|
// for save memory allocate in parser, we need try find the single stmt length in advance
|
||||||
while (stmt[str_len + offset] != ';' && str_len < remain) {
|
while (str_len < remain) {
|
||||||
++ str_len;
|
if (';' == stmt[str_len + offset]) {
|
||||||
|
break;
|
||||||
|
} else if ('#' == stmt[str_len + offset]) {
|
||||||
|
while (str_len + 1 < remain && '\n' != stmt[str_len + offset + 1]) {
|
||||||
|
++str_len;
|
||||||
|
}
|
||||||
|
} else if ('-' == stmt[str_len + offset]) {
|
||||||
|
if (str_len + 1 < remain && '-' == stmt[str_len + offset + 1]) {
|
||||||
|
++str_len;
|
||||||
|
while (str_len + 1 < remain && '\n' != stmt[str_len + offset + 1]) {
|
||||||
|
++str_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++str_len;
|
||||||
}
|
}
|
||||||
str_len = str_len == remain ? str_len : str_len + 1;
|
str_len = str_len == remain ? str_len : str_len + 1;
|
||||||
ObString part(str_len, stmt.ptr() + offset);
|
ObString part(str_len, stmt.ptr() + offset);
|
||||||
ObString remain_part(remain, stmt.ptr() + offset);
|
ObString remain_part(remain, stmt.ptr() + offset);
|
||||||
//first try parse part str, because it's have less length and need less memory
|
// first try parse part str, because it's have less length and need less memory
|
||||||
if (OB_FAIL(tmp_ret = parse(part, parse_result, parse_mode, false, true))) {
|
if (OB_FAIL(tmp_ret = parse(part, parse_result, parse_mode, false, true))) {
|
||||||
//if parser part str failed, then try parse all remain part, avoid parse many times:
|
|
||||||
//bug: https://work.aone.alibaba-inc.com/issue/34642901
|
|
||||||
tmp_ret = OB_SUCCESS;
|
tmp_ret = OB_SUCCESS;
|
||||||
tmp_ret = parse(remain_part, parse_result, parse_mode);
|
tmp_ret = parse(remain_part, parse_result, parse_mode);
|
||||||
}
|
}
|
||||||
@ -118,16 +128,15 @@ int ObParser::split_multiple_stmt(
|
|||||||
if (is_ret_first_stmt) {
|
if (is_ret_first_stmt) {
|
||||||
ObString first_query(single_stmt_length, stmt.ptr());
|
ObString first_query(single_stmt_length, stmt.ptr());
|
||||||
ret = queries.push_back(first_query);
|
ret = queries.push_back(first_query);
|
||||||
need_continue = false; // only return the first stmt, so ignore the remaining stmts
|
need_continue = false; // only return the first stmt, so ignore the remaining stmts
|
||||||
} else {
|
} else {
|
||||||
ObString query(single_stmt_length,stmt.ptr() + offset);
|
ObString query(single_stmt_length, stmt.ptr() + offset);
|
||||||
ret = queries.push_back(query);
|
ret = queries.push_back(query);
|
||||||
}
|
}
|
||||||
remain -= parse_result.end_col_;
|
remain -= parse_result.end_col_;
|
||||||
offset += parse_result.end_col_;
|
offset += parse_result.end_col_;
|
||||||
if (remain < 0 || offset > stmt.length()) {
|
if (remain < 0 || offset > stmt.length()) {
|
||||||
LOG_ERROR("split_multiple_stmt data error",
|
LOG_ERROR("split_multiple_stmt data error", K(remain), K(offset), K(stmt.length()), K(ret));
|
||||||
K(remain), K(offset), K(stmt.length()), K(ret));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ObString query(static_cast<int32_t>(remain), stmt.ptr() + offset);
|
ObString query(static_cast<int32_t>(remain), stmt.ptr() + offset);
|
||||||
@ -146,10 +155,10 @@ int ObParser::split_multiple_stmt(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObParser::parse_sql(const ObString& stmt, ParseResult& parse_result, const bool no_throw_parser_error)
|
int ObParser::parse_sql(const ObString &stmt, ParseResult &parse_result, const bool no_throw_parser_error)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
ObSQLParser sql_parser(*(ObIAllocator*)(parse_result.malloc_pool_), sql_mode_);
|
ObSQLParser sql_parser(*(ObIAllocator *)(parse_result.malloc_pool_), sql_mode_);
|
||||||
if (OB_FAIL(sql_parser.parse(stmt.ptr(), stmt.length(), parse_result))) {
|
if (OB_FAIL(sql_parser.parse(stmt.ptr(), stmt.length(), parse_result))) {
|
||||||
if (!no_throw_parser_error) {
|
if (!no_throw_parser_error) {
|
||||||
LOG_INFO("failed to parse stmt as sql", K(stmt), K(ret));
|
LOG_INFO("failed to parse stmt as sql", K(stmt), K(ret));
|
||||||
@ -207,9 +216,8 @@ int ObParser::parse_sql(const ObString& stmt, ParseResult& parse_result, const b
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObParser::parse(
|
int ObParser::parse(const ObString &query, ParseResult &parse_result, ParseMode parse_mode,
|
||||||
const ObString& query, ParseResult& parse_result, ParseMode parse_mode, const bool is_batched_multi_stmt_split_on,
|
const bool is_batched_multi_stmt_split_on, const bool no_throw_parser_error)
|
||||||
const bool no_throw_parser_error)
|
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
|
|
||||||
@ -261,7 +269,7 @@ int ObParser::parse(
|
|||||||
|
|
||||||
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;
|
||||||
char* buf = (char*)parse_malloc(new_length, parse_result.malloc_pool_);
|
char *buf = (char *)parse_malloc(new_length, parse_result.malloc_pool_);
|
||||||
if (OB_UNLIKELY(NULL == buf)) {
|
if (OB_UNLIKELY(NULL == buf)) {
|
||||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||||
LOG_ERROR("no memory for parser");
|
LOG_ERROR("no memory for parser");
|
||||||
@ -288,7 +296,7 @@ int ObParser::parse(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObParser::prepare_parse(const ObString& query, void* ns, ParseResult& parse_result)
|
int ObParser::prepare_parse(const ObString &query, void *ns, ParseResult &parse_result)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
|
|
||||||
@ -311,7 +319,7 @@ int ObParser::prepare_parse(const ObString& query, void* ns, ParseResult& parse_
|
|||||||
parse_result.sql_mode_ = sql_mode_;
|
parse_result.sql_mode_ = sql_mode_;
|
||||||
parse_result.pl_parse_info_.is_pl_parse_ = true;
|
parse_result.pl_parse_info_.is_pl_parse_ = true;
|
||||||
parse_result.pl_parse_info_.is_pl_parse_expr_ = false;
|
parse_result.pl_parse_info_.is_pl_parse_expr_ = false;
|
||||||
char* buf = (char*)parse_malloc(stmt.length() * 2, parse_result.malloc_pool_);
|
char *buf = (char *)parse_malloc(stmt.length() * 2, parse_result.malloc_pool_);
|
||||||
if (OB_UNLIKELY(NULL == buf)) {
|
if (OB_UNLIKELY(NULL == buf)) {
|
||||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||||
LOG_WARN("no memory for parser");
|
LOG_WARN("no memory for parser");
|
||||||
@ -324,7 +332,7 @@ int ObParser::prepare_parse(const ObString& query, void* ns, ParseResult& parse_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
ObSQLParser sql_parser(*(ObIAllocator*)(parse_result.malloc_pool_), sql_mode_);
|
ObSQLParser sql_parser(*(ObIAllocator *)(parse_result.malloc_pool_), sql_mode_);
|
||||||
if (OB_FAIL(sql_parser.parse(stmt.ptr(), stmt.length(), parse_result))) {
|
if (OB_FAIL(sql_parser.parse(stmt.ptr(), stmt.length(), parse_result))) {
|
||||||
LOG_WARN("failed to parse the statement",
|
LOG_WARN("failed to parse the statement",
|
||||||
K(parse_result.yyscan_info_),
|
K(parse_result.yyscan_info_),
|
||||||
@ -362,7 +370,7 @@ int ObParser::prepare_parse(const ObString& query, void* ns, ParseResult& parse_
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObParser::pre_parse(const common::ObString& stmt, PreParseResult& res)
|
int ObParser::pre_parse(const common::ObString &stmt, PreParseResult &res)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
// /*tracd_id=xxx*/
|
// /*tracd_id=xxx*/
|
||||||
@ -371,7 +379,7 @@ int ObParser::pre_parse(const common::ObString& stmt, PreParseResult& res)
|
|||||||
// do_nothing
|
// do_nothing
|
||||||
} else {
|
} else {
|
||||||
int32_t pos = 0;
|
int32_t pos = 0;
|
||||||
const char* ptr = stmt.ptr();
|
const char *ptr = stmt.ptr();
|
||||||
while (pos < len && is_space(ptr[pos])) {
|
while (pos < len && is_space(ptr[pos])) {
|
||||||
pos++;
|
pos++;
|
||||||
};
|
};
|
||||||
@ -446,7 +454,7 @@ int ObParser::pre_parse(const common::ObString& stmt, PreParseResult& res)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObParser::scan_trace_id(const char* ptr, int64_t len, int32_t& pos, ObString& trace_id)
|
int ObParser::scan_trace_id(const char *ptr, int64_t len, int32_t &pos, ObString &trace_id)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
trace_id.reset();
|
trace_id.reset();
|
||||||
@ -483,7 +491,7 @@ bool ObParser::is_trace_id_end(char ch)
|
|||||||
return is_space(ch) || ch == ',' || ch == '*';
|
return is_space(ch) || ch == ',' || ch == '*';
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObParser::free_result(ParseResult& parse_result)
|
void ObParser::free_result(ParseResult &parse_result)
|
||||||
{
|
{
|
||||||
UNUSED(parse_result);
|
UNUSED(parse_result);
|
||||||
// destroy_tree(parse_result.result_tree_);
|
// destroy_tree(parse_result.result_tree_);
|
||||||
|
|||||||
Reference in New Issue
Block a user