From 90f1ed34cde0977420a66e1a367e9b11e7a78372 Mon Sep 17 00:00:00 2001 From: slbaiyi Date: Thu, 1 Dec 2022 16:55:15 +0800 Subject: [PATCH] commit 3 --- src/bin/psql/mainloop.cpp | 24 ++++++++----------- src/bin/psql/mainloop.h | 4 ++++ src/bin/psql/psqlscan.l | 14 +++++++++++ src/common/backend/parser/scan.l | 1 + src/test/regress/expected/mysql_delimiter.out | 15 ++++++++---- src/test/regress/sql/mysql_delimiter.sql | 2 ++ 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/bin/psql/mainloop.cpp b/src/bin/psql/mainloop.cpp index ec50865bb..436af81ef 100644 --- a/src/bin/psql/mainloop.cpp +++ b/src/bin/psql/mainloop.cpp @@ -197,13 +197,12 @@ static char* get_correct_str(char*str, const char *delimiter_name, bool is_new_l } } if (is_new_lines && is_delimiter) { - /* 是delimiter命令,进行赋值,采用第一个参数。*/ + /* delimiter command, looking for the first parameter */ Size deliSlen = strlen(str) + strlen(delimiter_name) + DELIMITER_LENGTH; char *deliResultTemp = (char *)pg_malloc(deliSlen); char *start = deliResultTemp; int length = end - str_temp; - char *deliStrTemp = pg_strdup(str); - char *temp_pos = deliStrTemp; + char *temp_pos = str; bool is_spec_type = false; while(length--) { *start++ = *temp_pos++; @@ -214,19 +213,18 @@ static char* get_correct_str(char*str, const char *delimiter_name, bool is_new_l } if (*temp_pos != '\0') { if (*temp_pos != ';') { - if (*temp_pos == '\'' || *temp_pos == '\"' || *temp_pos == '`') { + if (JudgeQuteType(*temp_pos)) { quoted_type = *temp_pos; *start++ = *temp_pos++; - quoted = false; + quoted = true; } - /* 判断是不是特殊字符 */ - if (!((*temp_pos == '\'' || *temp_pos == '\"' || *temp_pos == '`')) && !((*temp_pos >= 'a' && *temp_pos <='z') || (*temp_pos >= 'A' && *temp_pos <= 'Z'))) { + if (JudgeSpecialType(*temp_pos)) { is_spec_type = true; *start++ = *temp_pos++; } for (; *temp_pos; temp_pos++) { - bool is_spec = (!((*temp_pos == '\'' || *temp_pos == '\"' || *temp_pos == '`')) && !((*temp_pos >= 'a' && *temp_pos <='z') || (*temp_pos >= 'A' && *temp_pos <= 'Z'))) ? true : false; - if ((is_spec_type && !is_spec) || (!is_spec_type && is_spec)) + bool is_spec = JudgeSpecialType(*temp_pos) ? true : false; + if (!quoted && ((is_spec_type ^ is_spec) || *temp_pos == ';')) break; *start++ = *temp_pos; if ((!quoted && *temp_pos == ' ') || (quoted && *temp_pos == quoted_type)) @@ -239,12 +237,10 @@ static char* get_correct_str(char*str, const char *delimiter_name, bool is_new_l *start = '\0'; char* deliResult = (char *) pg_malloc(deliSlen); - rc = sprintf_s(deliResult, deliSlen, "%s %s", deliResultTemp, delimiter_name); + rc = sprintf_s(deliResult, deliSlen, "%s \"%s\"", deliResultTemp, delimiter_name); securec_check_ss_c(rc, "", ""); free(str_temp); str_temp =NULL; - free(deliStrTemp); - deliStrTemp =NULL; free(deliResultTemp); deliResultTemp =NULL; return deliResult; @@ -252,7 +248,7 @@ static char* get_correct_str(char*str, const char *delimiter_name, bool is_new_l free(str_temp); str_temp =NULL; - if (!((*delimiter_name >= 'a' && *delimiter_name <='z') || (*delimiter_name >= 'A' && *delimiter_name <= 'Z'))) { + if (!JudgeAlphType(*delimiter_name)) { return pg_strdup(str); } Size slen = 2 * strlen(str) + 1; @@ -276,7 +272,7 @@ static char* get_correct_str(char*str, const char *delimiter_name, bool is_new_l } else { if (in == special_str) { special_str = 0; - } else if (!special_str && (in == '\'' || in == '"' || in == '`')) { + } else if (!special_str && JudgeQuteType(in)) { special_str = (char)in; } *temp++ = *pos; diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h index 2d2947a31..c63a2d1f0 100644 --- a/src/bin/psql/mainloop.h +++ b/src/bin/psql/mainloop.h @@ -10,6 +10,10 @@ #include "postgres_fe.h" +#define JudgeQuteType(value) ((value == '\'' || value == '\"' || value == '`')) +#define JudgeAlphType(value) ((value >= 'a' && value <='z') || (value >= 'A' && value <= 'Z')) +#define JudgeSpecialType(value) (!JudgeQuteType(value) && !JudgeAlphType(value)) + int MainLoop(FILE* source, char* querystring = NULL); #endif /* MAINLOOP_H */ diff --git a/src/bin/psql/psqlscan.l b/src/bin/psql/psqlscan.l index dd9a18085..02bb3f172 100644 --- a/src/bin/psql/psqlscan.l +++ b/src/bin/psql/psqlscan.l @@ -148,6 +148,7 @@ typedef struct PsqlScanStateData bool include_ora_comment; /* dont igore comment when ture, such as single line comment after function/procedure param */ bool is_b_format; char *delimiter_name; + bool is_end_state; /* judge end state */ } PsqlScanStateData; static PsqlScanState cur_state; /* current state while active */ @@ -752,6 +753,11 @@ other . {xdstop} { BEGIN(INITIAL); ECHO; + if (cur_state->is_end_state) { + RESET_XP_STATUS() ; + return LEXRES_SEMI; + cur_state->is_end_state = false; + } } {xuistop1} { yyless(1); @@ -767,6 +773,12 @@ other . } {xdinside} { ECHO; + if ((lex_param->begin_state == BEGIN_CURSOR || + ( !lex_param->declare_encountered && cur_state->paren_depth == 0)) + && judge_end_state(yytext)) + { + cur_state->is_end_state = true; + } } {xufailed} { @@ -1429,6 +1441,7 @@ psql_scan(PsqlScanState state, BEGIN(state->start_state); state->is_b_format = is_b_format; + state->is_end_state = false; if (is_b_format) { if (state->delimiter_name) { free(state->delimiter_name); @@ -1603,6 +1616,7 @@ psql_scan_reset(PsqlScanState state) state->butt_num = 0; state->declare_encountered = false; state->is_b_format = false; + state->is_end_state = false; if (state->delimiter_name) { free(state->delimiter_name); } diff --git a/src/common/backend/parser/scan.l b/src/common/backend/parser/scan.l index 238bf6d73..caef638b9 100755 --- a/src/common/backend/parser/scan.l +++ b/src/common/backend/parser/scan.l @@ -761,6 +761,7 @@ other . ident = litbufdup(yyscanner); if (yyextra->literallen >= NAMEDATALEN && u_sess->parser_cxt.is_load_copy == false && u_sess->parser_cxt.isForbidTruncate == false) truncate_identifier(ident, yyextra->literallen, yyextra->warnOnTruncateIdent); + set_is_delimiter_name(ident,yyscanner); yylval->str = ident; yyextra->ident_quoted = true; yyextra->is_hint_str = false; diff --git a/src/test/regress/expected/mysql_delimiter.out b/src/test/regress/expected/mysql_delimiter.out index d9345d684..f32788897 100644 --- a/src/test/regress/expected/mysql_delimiter.out +++ b/src/test/regress/expected/mysql_delimiter.out @@ -46,8 +46,8 @@ select 1// delimiter ;// --Test delimiter length delimiter aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; -ERROR: syntax error at or near ";" -LINE 1: delimiter aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ; +ERROR: syntax error at or near "";"" +LINE 1: delimiter aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ";" ^ --Test delimiter % delimiter %; @@ -112,9 +112,16 @@ select 1kkasda (1 row) delimiter -ERROR: syntax error at or near "kkasda" -LINE 1: delimiter kkasda +ERROR: syntax error at or near ""kkasda"" +LINE 1: delimiter "kkasda" ^ +delimiter "sdsd sd" +select 1"sdsd sd" + ?column? +---------- + 1 +(1 row) + delimiter ; \c regression drop database my_test; diff --git a/src/test/regress/sql/mysql_delimiter.sql b/src/test/regress/sql/mysql_delimiter.sql index 28131f34f..0990dfaa3 100644 --- a/src/test/regress/sql/mysql_delimiter.sql +++ b/src/test/regress/sql/mysql_delimiter.sql @@ -54,6 +54,8 @@ delimiter zz sdsd aasds delimiter kkasda "sdsd" sdsda select 1kkasda delimiter +delimiter "sdsd sd" +select 1"sdsd sd" delimiter ; \c regression