!2077 提交MySQL兼容性delimiter分割符的功能。

Merge pull request !2077 from slbaiyi/master
This commit is contained in:
opengauss-bot
2022-09-23 14:19:12 +00:00
committed by Gitee
14 changed files with 538 additions and 13 deletions

View File

@ -43,6 +43,7 @@ extern bool canAddHist;
#define DEFAULT_RETRY_TIMES 5
#define MAX_RETRY_TIMES 10
#define ERRCODE_LENGTH 5
#define DELIMITER_LENGTH 16
#if defined(__LP64__) || defined(__64BIT__)
typedef unsigned int GS_UINT32;

View File

@ -100,6 +100,144 @@ static void SetSessionTimeout(const char* session_timeout)
PQclear(StRes);
}
static void JudgeEndStateInBFormat(const char* inputLine, bool &is_b_format, char* delimiter_name, bool is_new_lines)
{
/* Convert inputLine to lowercase */
char *inputLine_temp = pg_strdup(inputLine);
inputLine_temp = pg_strtolower(inputLine_temp);
/* Determine whether the command is a delimiter command, and if so, save the result. */
static bool is_just_one_check = false;
static bool is_just_two_check = false;
PGresult* res = NULL ;
char *tokenPtr = strstr(inputLine_temp, "delimiter");
char *tokenPtr1 = strstr(inputLine_temp, "\\c" );
errno_t rc = 0;
if (!is_just_one_check) {
res = PQexec(pset.db, "show sql_compatibility");
if (res != NULL && PQresultStatus(res) == PGRES_TUPLES_OK) {
is_b_format = strcmp (PQgetvalue(res, 0, 0), "B") == 0;
}
PQclear(res);
res = NULL;
is_just_one_check = true;
}
if (tokenPtr1 != NULL) {
is_just_one_check = false;
}
if (is_b_format) {
if (!is_just_two_check && is_new_lines) {
res = PQexec(pset.db, "show delimiter_name");
if (res != NULL && PQresultStatus(res) == PGRES_TUPLES_OK) {
rc = strcpy_s(delimiter_name, DELIMITER_LENGTH, PQgetvalue(res, 0, 0));
securec_check_c(rc, "\0", "\0");
}
PQclear(res);
res = NULL;
is_just_two_check = true;
}
} else if (strcmp(delimiter_name,";") != 0) {
rc = strcpy_s(delimiter_name, DELIMITER_LENGTH, ";");
securec_check_c(rc, "\0", "\0");
}
if (tokenPtr != NULL || tokenPtr1 != NULL) {
is_just_two_check = false;
}
free(inputLine_temp);
inputLine_temp =NULL;
}
static bool is_match_delimiter_name(const char* left, const char* right)
{
if (strlen(left) < strlen(right)) {
return false;
}
while (*right) {
if (*left++ != *right++) {
return false;
}
}
return true ;
}
static char* get_correct_str(char*str, const char *delimiter_name, bool is_new_lines)
{
/* Determine whether it is a delimiter command. */
char *str_temp = pg_strdup(str);
str_temp = pg_strtolower(str_temp);
bool is_delimiter = false;
char *token = strstr(str_temp, "delimiter");
errno_t rc = 0;
if(token != NULL) {
is_delimiter = true;
char* pos = str_temp;
while(pos != token) {
if(*pos == ' ') {
pos++;
} else {
is_delimiter = false;
break;
}
}
if(is_delimiter) {
char* end = pos + strlen("delimiter");
if(*end != ' ' && *end != '\0') {
is_delimiter = false;
}
}
}
if (is_new_lines && is_delimiter && strstr(str, delimiter_name) == NULL) {
Size slen1 = strlen(str) + strlen(delimiter_name) + DELIMITER_LENGTH;
char* result1 = (char *) pg_malloc(slen1);
rc = sprintf_s(result1, slen1, "%s %s", str, delimiter_name);
securec_check_ss_c(rc, "", "");
free(str_temp);
str_temp =NULL;
return result1;
}
free(str_temp);
str_temp =NULL;
if (!((*delimiter_name >= 'a' && *delimiter_name <='z') || (*delimiter_name >= 'A' && *delimiter_name <= 'Z'))) {
return pg_strdup(str);
}
Size slen = 2 * strlen(str) + 1;
char* result = (char *) pg_malloc(slen + 2);
char* temp = result;
char* pos;
char* end_of_str = str + strlen(str);
char special_str = 0;
char in;
for (pos = str; pos < end_of_str; pos++) {
in = *pos;
if (!special_str && is_match_delimiter_name(pos , delimiter_name)) {
*temp++ =' ';
int delimiter_name_length = strlen(delimiter_name);
while ( delimiter_name_length > 0 && *pos != '\0') {
*temp++ = *pos++;
delimiter_name_length--;
}
pos--;
*temp++ = ' ';
} else {
if (in == special_str) {
special_str = 0;
} else if (!special_str && (in == '\'' || in == '"' || in == '`')) {
special_str = (char)in;
}
*temp++ = *pos;
}
}
*temp = '\0';
return result;
}
/*
* Main processing loop for reading lines of input
* and sending them to the backend.
@ -142,6 +280,9 @@ int MainLoop(FILE* source, char* querystring)
/* Save the stmts and counts info in parallel execute mode. */
int query_count = 0;
char** query_stmts = NULL;
bool is_b_format = false;
char delimiter_name[DELIMITER_LENGTH]=";";
char *line_temp = NULL;
errno_t rc = 0;
@ -318,11 +459,19 @@ int MainLoop(FILE* source, char* querystring)
/* Setting this will not have effect until next line. */
die_on_error = pset.on_error_stop;
/* Add processing of sql mode and terminator */
bool is_new_lines = query_buf->len == 0 ? true : false;
JudgeEndStateInBFormat(line, is_b_format, delimiter_name, is_new_lines);
/*
* Parse line, looking for command separators.
*/
psql_scan_setup(scan_state, line, (int)strlen(line));
if (is_b_format) {
line_temp = get_correct_str(line, delimiter_name, is_new_lines);
psql_scan_setup(scan_state, line_temp, (int)strlen(line_temp));
free(line_temp);
} else {
psql_scan_setup(scan_state, line, (int)strlen(line));
}
success = true;
line_saved_in_history = false;
@ -330,7 +479,7 @@ int MainLoop(FILE* source, char* querystring)
PsqlScanResult scan_result;
promptStatus_t prompt_tmp = prompt_status;
scan_result = psql_scan(scan_state, query_buf, &prompt_tmp);
scan_result = psql_scan(scan_state, query_buf, &prompt_tmp,is_b_format,delimiter_name);
prompt_status = prompt_tmp;
if (PQExpBufferBroken(query_buf)) {

View File

@ -39,7 +39,8 @@ extern void psql_scan_destroy(PsqlScanState state);
extern void psql_scan_setup(PsqlScanState state, const char* line, int line_len);
extern void psql_scan_finish(PsqlScanState state);
extern PsqlScanResult psql_scan(PsqlScanState state, PQExpBuffer query_buf, promptStatus_t* prompt);
extern PsqlScanResult psql_scan(PsqlScanState state, PQExpBuffer query_buf, promptStatus_t* prompt,
bool is_b_format,char* delimiter_name);
extern void psql_scan_reset(PsqlScanState state);

View File

@ -146,6 +146,8 @@ typedef struct PsqlScanStateData
For sql like "Declare foo CURSOR XXX, butt_num is 1.
Using this we can judge if the sql is a DECLARE CURSOR stmt */
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;
} PsqlScanStateData;
static PsqlScanState cur_state; /* current state while active */
@ -196,6 +198,7 @@ static void analyze_state(const char* text,PsqlScanState state);
static int upperstrcmp(const char *str1,const char *str2);
static GramIdentify keywordRead(const char* text);
static bool IsTranscationTokens(char* yytext, char* token);
static bool judge_end_state(const char* text);
#define YY_DECL int yylex(PsqlScanState lex_param)
@ -656,6 +659,13 @@ other .
RESET_XP_STATUS();
return LEXRES_SEMI;
}
if (cur_state->is_b_format == true ) {
if (strstr(yytext, cur_state->delimiter_name) != NULL && strcmp(";" ,cur_state->delimiter_name) != 0) {
RESET_XP_STATUS();
return LEXRES_SEMI;
}
}
}
}
@ -796,9 +806,13 @@ other .
";" {
ECHO;
if (lex_param->begin_state == BEGIN_CURSOR ||
bool is_end = true;
if (cur_state->is_b_format && strcmp(yytext , cur_state->delimiter_name) != 0) {
is_end = false;
}
if ((lex_param->begin_state == BEGIN_CURSOR ||
(!lex_param->declare_encountered && cur_state->paren_depth == 0))
&& is_end == true)
{
RESET_XP_STATUS();
return LEXRES_SEMI;
@ -889,6 +903,13 @@ other .
{self} {
ECHO;
if ((lex_param->begin_state == BEGIN_CURSOR ||
( !lex_param->declare_encountered && cur_state->paren_depth == 0))
&& judge_end_state(yytext))
{
RESET_XP_STATUS() ;
return LEXRES_SEMI;
}
}
{operator} {
@ -943,6 +964,13 @@ other .
yyless(nchars);
}
ECHO;
if ((lex_param->begin_state == BEGIN_CURSOR ||
( !lex_param->declare_encountered && cur_state->paren_depth == 0))
&& judge_end_state(yytext))
{
RESET_XP_STATUS() ;
return LEXRES_SEMI;
}
}
{param} {
@ -983,6 +1011,13 @@ other .
{identifier} {
ECHO;
analyze_state(yytext,(PsqlScanStateData*)lex_param);
if ((lex_param->begin_state == BEGIN_CURSOR ||
( !lex_param->declare_encountered && cur_state->paren_depth == 0))
&& judge_end_state(yytext))
{
RESET_XP_STATUS() ;
return LEXRES_SEMI;
}
}
{other} {
@ -1373,7 +1408,9 @@ psql_scan_setup(PsqlScanState state,
PsqlScanResult
psql_scan(PsqlScanState state,
PQExpBuffer query_buf,
promptStatus_t *prompt)
promptStatus_t *prompt,
bool is_b_format,
char* delimiter_name)
{
PsqlScanResult result;
int lexresult;
@ -1391,6 +1428,14 @@ psql_scan(PsqlScanState state,
yy_switch_to_buffer(state->scanbufhandle);
BEGIN(state->start_state);
state->is_b_format = is_b_format;
if (is_b_format) {
if (state->delimiter_name) {
free(state->delimiter_name);
state->delimiter_name = NULL;
}
state->delimiter_name = pg_strdup(delimiter_name);
}
/* And lex. */
lexresult = yylex((PsqlScanStateData*)state);
@ -1522,6 +1567,10 @@ psql_scan_finish(PsqlScanState state)
free(state->scanbuf);
}
state->scanbuf = NULL;
if (state->delimiter_name) {
free(state->delimiter_name);
}
state->delimiter_name = NULL;
}
/*
@ -1553,6 +1602,11 @@ psql_scan_reset(PsqlScanState state)
state->begin_state = BEGIN_UNDEFINED;
state->butt_num = 0;
state->declare_encountered = false;
state->is_b_format = false;
if (state->delimiter_name) {
free(state->delimiter_name);
}
state->delimiter_name = NULL;
}
/*
@ -2060,6 +2114,14 @@ static bool IsTranscationTokens(char* yytext, char* token)
return false;
}
static bool judge_end_state(const char* text)
{
if (cur_state->is_b_format == true) {
return (strcmp(yytext, cur_state->delimiter_name) ==0);
}
return false;
}
/*
* escape_variable --- process :'VARIABLE' or :"VARIABLE"
*

View File

@ -264,6 +264,8 @@ static bool CheckWhetherInColList(char *colname, List *col_list);
static int GetFillerColIndex(char *filler_col_name, List *col_list);
static void RemoveFillerCol(List *filler_list, List *col_list);
static int errstate;
static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStmt*n);
%}
%define api.pure
@ -372,7 +374,7 @@ static int errstate;
CreateWeakPasswordDictionaryStmt DropWeakPasswordDictionaryStmt
AlterGlobalConfigStmt DropGlobalConfigStmt
CreatePublicationStmt AlterPublicationStmt
CreateSubscriptionStmt AlterSubscriptionStmt DropSubscriptionStmt
CreateSubscriptionStmt AlterSubscriptionStmt DropSubscriptionStmt DelimiterStmt
ShrinkStmt
/* <DB4AI> */
@ -788,8 +790,7 @@ static int errstate;
%type <typnam> load_col_data_type
%type <ival64> load_col_sequence_item_sart column_sequence_item_step column_sequence_item_sart
%type <trgcharacter> trigger_order
%type <str> delimiter_str_name delimiter_str_names
/*
* Non-keyword token types. These are hard-wired into the "flex" lexer.
* They must be listed first so that their numeric codes do not depend on
@ -930,6 +931,9 @@ static int errstate;
VALID_BEGIN
DECLARE_CURSOR ON_UPDATE_TIME
START_WITH CONNECT_BY
END_OF_INPUT
END_OF_INPUT_COLON
END_OF_PROC
/* Precedence: lowest to highest */
%nonassoc COMMENT
@ -1032,6 +1036,38 @@ stmtmulti: stmtmulti ';' stmt
else
$$ = $1;
}
| stmtmulti ';' END_OF_INPUT stmt
{
if ($4 != NULL)
{
if (IsA($4, List))
{
$$ = list_concat($1, (List*)$4);
}
else
{
$$ = lappend($1, $4);
}
}
else
$$ = $1;
}
| stmtmulti END_OF_INPUT_COLON stmt
{
if ($3 != NULL)
{
if (IsA($3, List))
{
$$ = list_concat($1, (List*)$3);
}
else
{
$$ = lappend($1, $3);
}
}
else
$$ = $1;
}
|
{
#ifndef ENABLE_MULTIPLE_NODES
@ -1249,6 +1285,7 @@ stmt :
| ShrinkStmt
| /*EMPTY*/
{ $$ = NULL; }
| DelimiterStmt
;
/*****************************************************************************
@ -14399,7 +14436,7 @@ subprogram_body: {
tok = YYLEX;
/* adapt A db's label */
if (!(tok == ';' || tok == 0)
if (!(tok == ';' || (tok == 0 || tok == END_OF_PROC))
&& tok != IF_P
&& tok != CASE
&& tok != LOOP)
@ -14410,7 +14447,7 @@ subprogram_body: {
if (blocklevel == 1
&& (pre_tok == ';' || pre_tok == BEGIN_P)
&& (tok == ';' || tok == 0))
&& (tok == ';' || (tok == 0 || tok == END_OF_PROC)))
{
/* Save the end of procedure body. */
proc_e = yylloc;
@ -25774,6 +25811,43 @@ ColLabel: IDENT { $$ = $1; }
}
;
DelimiterStmt: DELIMITER delimiter_str_names END_OF_INPUT
{
VariableSetStmt *n = makeNode(VariableSetStmt);
setDelimiterName(yyscanner, $2, n);
$$ = (Node *)n;
}
| DELIMITER delimiter_str_names END_OF_INPUT_COLON
{
VariableSetStmt *n = makeNode(VariableSetStmt);
setDelimiterName(yyscanner, $2, n);
$$ = (Node *)n;
}
;
delimiter_str_names: delimiter_str_names delimiter_str_name
{
$$ = $1 ;
}
| delimiter_str_name
{
$$ = $1;
}
;
delimiter_str_name: ColId_or_Sconst
{
$$ = $1;
}
| all_Op
{
$$ = $1;
}
| ';'
{
$$ = ";";
}
;
/*
* Keyword category lists. Generally, every keyword present in
@ -28537,6 +28611,22 @@ static void RemoveFillerCol(List *filler_list, List *col_list)
return;
}
static void setDelimiterName(core_yyscan_t yyscanner, char*input, VariableSetStmt*n)
{
errno_t rc = 0;
base_yy_extra_type *yyextra = pg_yyget_extra(yyscanner);
if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) {
if (strlen(input) >= DELIMITER_LENGTH) {
parser_yyerror("syntax error");
}
n->is_local = false;
n->kind = VAR_SET_VALUE;
n->name = "delimiter_name";
n->args = list_make1(makeStringConst(input, -1));
}
}
static FuncCall* MakePriorAsFunc()
{
List *funcName = list_make1(makeString("prior"));

View File

@ -155,6 +155,7 @@ int base_yylex(YYSTYPE* lvalp, YYLTYPE* llocp, core_yyscan_t yyscanner)
int next_token;
core_YYSTYPE cur_yylval;
YYLTYPE cur_yylloc;
errno_t rc = 0;
/* Get next token --- we might already have it */
if (yyextra->lookahead_num != 0) {
@ -166,6 +167,32 @@ int base_yylex(YYSTYPE* lvalp, YYLTYPE* llocp, core_yyscan_t yyscanner)
cur_token = core_yylex(&(lvalp->core_yystype), llocp, yyscanner);
}
if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT && yyextra->lookahead_num == 0) {
bool is_last_colon;
if (cur_token == int(';')) {
is_last_colon = true;
} else {
is_last_colon = false;
}
if (yyextra->core_yy_extra.is_delimiter_name == true) {
if (strcmp(";",u_sess->attr.attr_common.delimiter_name) == 0) {
cur_token = END_OF_INPUT_COLON;
} else {
if (yyextra->core_yy_extra.is_last_colon == false ) {
cur_token = END_OF_INPUT_COLON;
} else {
cur_token = END_OF_INPUT;
}
}
}
if (yyextra->core_yy_extra.is_proc_end == true) {
cur_token = END_OF_PROC;
}
yyextra->core_yy_extra.is_proc_end = false;
yyextra->core_yy_extra.is_delimiter_name = false;
yyextra->core_yy_extra.is_last_colon = is_last_colon;
}
/* Do we need to look ahead for a possible multiword token? */
switch (cur_token) {
case NULLS_P:

View File

@ -93,6 +93,7 @@ static bool is_utf16_surrogate_first(pg_wchar c);
static bool is_utf16_surrogate_second(pg_wchar c);
static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second);
static void addunicode(pg_wchar c, yyscan_t yyscanner);
static void set_is_delimiter_name(char* text, core_yyscan_t yyscanner );
#define yyerror(msg) scanner_yyerror(msg, yyscanner)
@ -598,6 +599,7 @@ other .
BEGIN(INITIAL);
yylval->str = litbuf_udeescape('\\', yyscanner);
yyextra->is_hint_str = false;
set_is_delimiter_name(yytext,yyscanner);
return SCONST;
}
<xus>{xusstop2} {
@ -867,6 +869,7 @@ other .
/* reset is_createstmt to parse next sql */
yyextra->is_createstmt = false;
}
set_is_delimiter_name(yytext,yyscanner);
}
yyextra->is_hint_str = false;
return yytext[0];
@ -919,6 +922,7 @@ other .
}
SET_YYLLOC();
set_is_delimiter_name(yytext,yyscanner);
if (nchars < (int)yyleng)
{
@ -1144,6 +1148,7 @@ other .
ident = downcase_truncate_identifier(yytext, yyleng, yyextra->warnOnTruncateIdent);
yylval->str = ident;
yyextra->ident_quoted = false;
set_is_delimiter_name(yytext,yyscanner);
return IDENT;
}
@ -1339,6 +1344,9 @@ scanner_init(const char *str,
/* plpgsql keyword params */
yyext->isPlpgsqlKeyWord = false;
yyext->plKeywordValue = NULL;
yyext->is_delimiter_name = false;
yyext->is_last_colon = false;
yyext->is_proc_end = false;
// Added CALL for procedure and function
getDynaParamSeq("init", true, true, NULL);
@ -1420,6 +1428,24 @@ addlitchar(unsigned char ychar, core_yyscan_t yyscanner)
yyextra->literallen += 1;
}
static void set_is_delimiter_name(char* text, core_yyscan_t yyscanner)
{
if (u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) {
if (strcmp(text,u_sess->attr.attr_common.delimiter_name) == 0 && yyextra->paren_depth == 0 && !yyextra->in_slash_proc_body) {
if (strcmp(text,";") != 0) {
yyextra->query_string_locationlist = lappend_int(yyextra->query_string_locationlist, *yylloc);
yyextra->is_createstmt = false;
}
yyextra->is_delimiter_name = true;
} else {
yyextra->is_delimiter_name = false;
}
if (strcmp(text,u_sess->attr.attr_common.delimiter_name) == 0 && strcmp(text,";") != 0 && yyextra->in_slash_proc_body) {
yyextra->is_proc_end = true;
}
}
}
/*
* Create a palloc'd copy of literalbuf, adding a trailing null.

View File

@ -3295,6 +3295,18 @@ static void InitConfigureNamesString()
NULL,
NULL,
show_lcgroup_name},
{ {"delimiter_name",
PGC_USERSET,
NODE_ALL,
UNGROUPED,
gettext_noop( "Shows delimiter name."),
NULL,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE},
&u_sess->attr.attr_common.delimiter_name,
";",
NULL,
NULL,
NULL},
{{"search_path",
PGC_USERSET,
NODE_ALL,

View File

@ -236,6 +236,7 @@ typedef struct knl_session_attr_common {
void** extension_session_vars_array;
char* threadpool_reset_percent_item;
int threadpool_reset_percent_list[2];
char* delimiter_name;
} knl_session_attr_common;
#endif /* SRC_INCLUDE_KNL_KNL_SESSION_ATTR_COMMON_H_ */

View File

@ -49,6 +49,8 @@ typedef union core_YYSTYPE {
*/
#define YYLTYPE int
#define DELIMITER_LENGTH 16
/*
* Another important component of the scanner's API is the token code numbers.
* However, those are not defined in this file, because bison insists on
@ -117,6 +119,9 @@ typedef struct core_yy_extra_type {
int func_param_end; /* function and procedure param string end pos,exclude right parenthesis */
bool isPlpgsqlKeyWord;
const PlpgsqlKeywordValue* plKeywordValue;
bool is_delimiter_name;
bool is_last_colon;
bool is_proc_end;
} core_yy_extra_type;
#ifdef FRONTEND_PARSER

View File

@ -0,0 +1,99 @@
-- B db compatibility case
drop database if exists my_test;
NOTICE: database "my_test" does not exist, skipping
create database my_test dbcompatibility 'B';
\c my_test
--Test default delimiter
select 1;
?column?
----------
1
(1 row)
--Test delimiter aa
delimiter aa;
select 1aa
?column?
----------
1
(1 row)
select 1aaselect 1;aa
?column?
----------
1
(1 row)
?column?
----------
1
(1 row)
select kaa
ERROR: column "k" does not exist
LINE 1: select k aa
^
CONTEXT: referenced column: k
delimiter ;aa
--Test delimiter //
delimiter //;
select 1//
?column?
----------
1
(1 row)
delimiter ;//
--Test delimiter length
delimiter aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
ERROR: syntax error at or near ";"
LINE 1: delimiter aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
^
--Test delimiter %
delimiter %;
select 1%
?column?
----------
1
(1 row)
delimiter ;%
--Test delimiter 'Mysql'
delimiter 'Mysql';
select 1Mysql
?column?
----------
1
(1 row)
delimiter ;Mysql
--Test other
delimiter sds;
delimiter aasds
select 1aa
?column?
----------
1
(1 row)
delimiter ;aa
--
delimiter asd ss;
select 1asd
?column?
----------
1
(1 row)
delimiter ;asd
delimiter bb
delimiter aa
select 1aa
?column?
----------
1
(1 row)
delimiter ;
\c regression
drop database my_test;

View File

@ -198,6 +198,7 @@ select name,vartype,unit,min_val,max_val from pg_settings where name <> 'qunit_c
default_transaction_read_only | bool | | |
default_with_oids | bool | | |
defer_csn_cleanup_time | integer | ms | 0 | 2147483647
delimiter_name | string | | |
dfs_partition_directory_length | integer | | 92 | 7999
dirty_page_percent_max | real | | 0.1 | 1
disable_memory_protect | bool | | |

View File

@ -984,7 +984,7 @@ test: fdw_audit
test: gs_global_config_audit
test: detail declare_multiple_variable
test: gs_dump_encrypt substr
test: composite_datum_record mysql_function b_comments mysql_syntax
test: composite_datum_record mysql_function b_comments mysql_syntax mysql_delimiter
test: join_test_alias alter_ctable_compress
test: ignore/ignore_type_transform ignore/ignore_not_null_constraints ignore/ignore_unique_constraints ignore/ignore_no_matched_partition

View File

@ -0,0 +1,51 @@
-- B db compatibility case
drop database if exists my_test;
create database my_test dbcompatibility 'B';
\c my_test
--Test default delimiter
select 1;
--Test delimiter aa
delimiter aa;
select 1aa
select 1aaselect 1;aa
select kaa
delimiter ;aa
--Test delimiter //
delimiter //;
select 1//
delimiter ;//
--Test delimiter length
delimiter aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
--Test delimiter %
delimiter %;
select 1%
delimiter ;%
--Test delimiter 'Mysql'
delimiter 'Mysql';
select 1Mysql
delimiter ;Mysql
--Test other
delimiter sds;
delimiter aasds
select 1aa
delimiter ;aa
--
delimiter asd ss;
select 1asd
delimiter ;asd
delimiter bb
delimiter aa
select 1aa
delimiter ;
\c regression
drop database my_test;