暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

Halo数据库实现Mysql字符串、标识符引用

原创 JGJ 2023-10-07
15215

1.在Halo数据库中

字符串:使用单引号(‘’)引用

select ‘halo’;

图片

标识符:可以直接引用,也可使用双引号(“”)引用

select id from test;

select “id” from “test”;

图片

其中,使用双引号引用的标识符可以包含一些特殊字符,可以是关键字,并且区分大小写

2.在Mysql数据库中

字符串:使用单引号(‘’)或双引号(“”)引用,两者功能相同

select ‘halo’;

或select “halo”;

图片

标识符:可以直接引用,也可使用反引号(``)引用

select id from test;

select `id` from `test`;

图片

其中,使用反引号引用的标识符可以包含一些特殊字符,可以是关键字,默认不区分大小写

3.具体实现

在Halo数据库的语法文件中,字符串、标识符的记号(Token)分别为Sconst、Ident,在词法文件中,具体修改如下:

第一步,添加反引号标识符识别规则,如下:

{xbtstart}      {

                  SET_YYLLOC();

                  BEGIN(xbt);

                  startlit();

              }

<xbt>{xbtstop}  {

                  char       *ident;

                  BEGIN(INITIAL);

                  if (yyextra->literallen == 0)

                      yyerror("zero-length delimited identifier");

                  // ident = litbufdup(yyscanner);

                  // if (yyextra->literallen >= NAMEDATALEN)

                  //  truncate_identifier(ident, yyextra->literallen, true);

                  ident = downcase_truncate_identifier(yyextra->literalbuf, yyextra->literallen, true);

                  yylval->str = ident;

                  return IDENT;

              }

<xbt>{xbtdouble}    {

                  addlitchar('`', yyscanner);

              }

<xbt>{xbtinside}    {

                  addlit(yytext, yyleng, yyscanner);

              }

<xbt><<EOF>>    { yyerror("unterminated backtick identifier"); }

第二步,删除单引号字符串的部分规则(如对字符串中八进制,十六进制进行转义),如下:

<xe>{xeoctesc}  {

                  unsigned char c = strtoul(yytext + 1, NULL, 8);

                  check_escape_warning(yyscanner);

                  addlitchar(c, yyscanner);

                  if (c == '\0' || IS_HIGHBIT_SET(c))

                      yyextra->saw_non_ascii = true;

              }

<xe>{xehexesc}  {

                  unsigned char c = strtoul(yytext + 2, NULL, 16);

                  check_escape_warning(yyscanner);

                  addlitchar(c, yyscanner);

                  if (c == '\0' || IS_HIGHBIT_SET(c))

                      yyextra->saw_non_ascii = true;

              }

第三步,删除与双引号有关的标识符识别规则,添加双引号字符串识别规则,结果如下:

{xdqstart}      {

                  yyextra->warn_on_first_escape = false;

                  yyextra->saw_non_ascii = false;

                  SET_YYLLOC();

                  // if (yyextra->standard_conforming_strings)

                  //  BEGIN(xdq);

                  // else

                  //  BEGIN(xde);

                  BEGIN(xde);

                  startlit();

              }

<xdq,xde>{dquote} {

                  /*

                   * When we are scanning a quoted string and see an end

                   * quote, we must look ahead for a possible continuation.

                   * If we don't see one, we know the end quote was in fact

                   * the end of the string.  To reduce the lexer table size,

                   * we use a single "xqs" state to do the lookahead for all

                   * types of strings.

                   */

                  yyextra->state_before_str_stop = YYSTATE;

                  BEGIN(xdqs);

              }

<xdqs>{dquotecontinue} {

                  /*

                   * Found a quote continuation, so return to the in-quote

                   * state and continue scanning the literal.  Nothing is

                   * added to the literal's contents.

                   */

                  BEGIN(yyextra->state_before_str_stop);

              }

<xdqs>{dquotecontinuefail} |

<xdqs>{other} |

<xdqs><<EOF>>   {

                  /*

                   * Failed to see a quote continuation.  Throw back

                   * everything after the end quote, and handle the string

                   * according to the state we were in previously.

                   */

                  yyless(0);

                  BEGIN(INITIAL);

                  switch (yyextra->state_before_str_stop)

                  {

                      case xdq:

                      case xde:

                          /*

                           * Check that the data remains valid, if it might

                           * have been made invalid by unescaping any chars.

                           */

                          if (yyextra->saw_non_ascii)

                              pg_verifymbstr(yyextra->literalbuf,

                                             yyextra->literallen,

                                             false);

                          yylval->str = litbufdup(yyscanner);

                          return SCONST;

                      default:

                          yyerror("unhandled previous state in xdqs");

                  }

              }

<xdq,xde>{xdqdouble} {

                  addlitchar('\"', yyscanner);

              }

<xdq>{xdqinside}  {

                  addlit(yytext, yyleng, yyscanner);

              }

<xde>{xdeinside}  {

                  addlit(yytext, yyleng, yyscanner);

              }

<xde>{xdeescape}  {

                  if (yytext[1] == '\"')

                  {

                      if (yyextra->backslash_quote == BACKSLASH_QUOTE_OFF ||

                          (yyextra->backslash_quote == BACKSLASH_QUOTE_SAFE_ENCODING &&

                           PG_ENCODING_IS_CLIENT_ONLY(pg_get_client_encoding())))

                          ereport(ERROR,

                                  (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),

                                   errmsg("unsafe use of \\\" in a string literal"),

                                   errhint("Use \"\" to write double quotes in strings. \\\" is insecure in client-only encodings."),

                                   lexer_errposition()));

                  }

                  if(yytext[1] == '0')

                      yytext[1] = '\0';

                  check_string_escape_warning(yytext[1], yyscanner);

                  addlitchar(unescape_single_char(yytext[1], yyscanner),

                             yyscanner);

              }

<xde>.          {

                  /* This is only needed for \ just before EOF */

                  addlitchar(yytext[0], yyscanner);

              }

<xdq,xde><<EOF>>        { yyerror("unterminated double quoted string"); }

4.结果展示

字符串:

图片

标识符:

图片

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论