1. In the Halo database
Strings: Quoted with single quotes ('')
select 'halo';
Identifiers: Can be referenced directly or quoted with double quotes ("")
select id from test;
select "id" from "test";
Among these, identifiers quoted with double quotes can contain special characters, can be keywords, and are case-sensitive.
2. In the MySQL database
Strings: Quoted with single quotes ('') or double quotes (""). Both functions are the same.
select 'halo';
or select "halo";
Among these, identifiers quoted with backticks (`) can contain special characters and can be keywords. By default, they are case-insensitive.
3. Specific Implementation
In the Halo database's syntax file, the tokens for strings and identifiers are Sconst and Ident respectively. In the lexical file, the specific modifications are as follows:
Step 1: Add backtick identifier recognition rules as follows:
{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"); }Step 2: Remove parts of the single quote string rules (such as escaping octal and hexadecimal in strings) as follows:
<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;
}Step 3: Remove the identifier recognition rules related to double quotes and add double quote string recognition rules. The result is as follows:
{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. Result Display
String:

Identifier:
