Update scansup.cpp #17

Open
Erkfapx9w wants to merge 2 commits from Erkfapx9w/openGauss-server:master into master
2 changed files with 64 additions and 128 deletions

View File

@ -1,90 +1,52 @@
/* -------------------------------------------------------------------------
*
* kwlookup.cpp
* lexical token lookup for key words in openGauss
*
* NB - this file is also used by ECPG and several frontend programs in
* src/bin/ including pg_dump and psql
*
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/common/backend/parser/kwlookup.cpp
*
* -------------------------------------------------------------------------
*/
/* use c.h so this can be built as either frontend or backend */
#include "c.h"
#include <ctype.h>
#include "parser/keywords.h"
/*
* ScanKeywordLookup - see if a given word is a keyword
*
* Returns a pointer to the ScanKeyword table entry, or NULL if no match.
*
* The match is done case-insensitively. Note that we deliberately use a
* dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
* even if we are in a locale where tolower() would produce more or different
* translations. This is to conform to the SQL99 spec, which says that
* keywords are to be matched in this way even though non-keyword identifiers
* receive a different case-normalization mapping.
*/
//返回指向ScanKeyword表项的指针如果不匹配则返回NULL。
/* 匹配是不区分大小写的。注意,我们故意使用简化的大小写转换,只将'A'-' Z'翻译成'a'-' z'即使我们在tolower()会产生更多或不同的翻译。这是为了符合SQL99规范该规范规定即使非关键字标识符接收不同的大小写规范化映射也要以这种方式匹配关键字。*/
//用于判断信息的关键字从而将关键词返回为具体的token给程序
const ScanKeyword* ScanKeywordLookup(const char* text, const ScanKeyword* keywords, int num_keywords)
{
int len, i;
char word[NAMEDATALEN] = {0};
const ScanKeyword* low = NULL;
const ScanKeyword* high = NULL;
if (text == NULL) {
return NULL;
}
len = strlen(text);
/* We assume all keywords are shorter than NAMEDATALEN. */
/* 我们假设所有关键字都比NAMEDATALEN短。 */
if (len >= NAMEDATALEN) {
return NULL;
}
/*
* Apply an ASCII-only downcasing. We must not use tolower() since it may
* produce the wrong translation in some locales (eg, Turkish).
ascII的下标使tolower()()
*/
for (i = 0; i < len; i++) {
char ch = text[i];
if (ch >= 'A' && ch <= 'Z') {
ch += 'a' - 'A';
}
word[i] = ch;
}
word[len] = '\0';
/*
* Now do a binary search using plain strcmp() comparison.
*使strcmp()
*/
low = keywords;
high = keywords + (num_keywords - 1);
while (low <= high) {
const ScanKeyword* middle = NULL;
int difference;
middle = low + (high - low) / 2;
difference = strcmp(middle->name, word);
if (difference == 0) {
return middle;
} else if (difference < 0) {
}
//如果middle->name比word短返回-1
else if (difference < 0) {
low = middle + 1;
} else {
}
//如果middle->name比word长返回1
else {
high = middle - 1;
}
}
return NULL;
}
}

View File

@ -43,76 +43,57 @@ char* scanstr(const char* s)
newStr = (char*)palloc(len + 1); /* string cannot get longer */
for (i = 0, j = 0; i < len; i++) {
if (s[i] == '\'') {
/*
* Note: if scanner is working right, unescaped quotes can only
* appear in pairs, so there should be another character.
*/
i++;
newStr[j] = s[i];
} else if (s[i] == '\\') {
i++;
switch (s[i]) {
case 'b':
newStr[j] = '\b';
break;
case 'f':
newStr[j] = '\f';
break;
case 'n':
newStr[j] = '\n';
break;
case 'r':
newStr[j] = '\r';
break;
case 't':
newStr[j] = '\t';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': {
int k;
unsigned long octVal = 0;
for (i = 0, j = 0; i < len; i++) {
if (s[i] == '\'') {
i++;
newStr[j] = s[i];//说明不是转义字符
} else if (s[i] == '\\') {
i++;
switch (s[i]) {
case 'b':
newStr[j] = '\b';
break;
case 'f':
newStr[j] = '\f';
break;
case 'n':
newStr[j] = '\n';
break;
case 'r':
newStr[j] = '\r';
break;
case 't':
newStr[j] = '\t';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': {
int k;
unsigned long octVal = 0;
for (k = 0; s[i + k] >= '0' && s[i + k] <= '7' && k < 3; k++){
octVal = (octVal << 3) + (s[i + k] - '0');
}
i += k - 1;
newStr[j] = ((char)octVal);
} break;
default:
newStr[j] = s[i];
break;
} /* switch */
} /* s[i] == '\\' */
else {
newStr[j] = s[i];
}
j++;
}
newStr[j] = '\0';
for (k = 0; s[i + k] >= '0' && s[i + k] <= '7' && k < 3; k++){
octVal = (octVal << 3) + (s[i + k] - '0');
}
i += k - 1;
newStr[j] = ((char)octVal);
} break;
default:
newStr[j] = s[i];
break;
} /* switch */
} /* s[i] == '\\' */
else {
newStr[j] = s[i];
}
j++;
}
newStr[j] = '\0';
return newStr;
}
/*
* downcase_truncate_identifier() --- do appropriate downcasing and
* truncation of an unquoted identifier. Optionally warn of truncation.
*
* Returns a palloc'd string containing the adjusted identifier.
*
* Note: in some usages the passed string is not null-terminated.
*
* Note: the API of this function is designed to allow for downcasing
* transformations that increase the string length, but we don't yet
* support that. If you want to implement it, you'll need to fix
* SplitIdentifierString() in utils/adt/varlena.c.
*/
//对未加引号的标识符进行适当的大小写转换和截断。可选的截断警告。
char* downcase_truncate_identifier(const char* ident, int len, bool warn)
{
char* result = NULL;
@ -180,15 +161,8 @@ void truncate_identifier(char* ident, int len, bool warn)
}
}
/*
* scanner_isspace() --- return TRUE if flex scanner considers char whitespace
*
* This should be used instead of the potentially locale-dependent isspace()
* function when it's important to match the lexer's behavior.
*
* In principle we might need similar functions for isalnum etc, but for the
* moment only isspace seems needed.
*/
// 如果flex scanner识别出字符空白则返回TRUE
bool scanner_isspace(char ch)
{
/* This must match scan.l's list of {space} characters */