PostgreSQL中的Rules有什么作用
发表于:2024-11-30 作者:千家信息网编辑
千家信息网最后更新 2024年11月30日,本篇内容介绍了"PostgreSQL中的Rules有什么作用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有
千家信息网最后更新 2024年11月30日PostgreSQL中的Rules有什么作用
本篇内容介绍了"PostgreSQL中的Rules有什么作用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
Flex输入文件由四部分组成:
%{Declarations%}Definitions%%Rules%%User subroutines
Rules
在Flex的模式文件中,%%和%%之间的内容被称为规则(rules),每一行表示一条规则,每条规则由匹配模式(pattern)和 动作(action)组成。其中模式在前面,用正则表达式表示,动作在后面,即C代码。每当一个模式被匹配到时,后面的C代码将被执行。
Flex会将规则翻译成名为yylex的函数,该函数扫描输入文件(默认标准输入),当扫描到一个完整的、最长的、可以和某条规则的正则表达式所匹配的输入时,函数会执行此规则后面的C代码。如果代码中没有return语句,则执行完毕后,yylex会继续运行,开始下一轮的扫描和匹配。注意:当有多条规则的模式被匹配到时, yylex会优先选择匹配长度最长的那条规则,如果有匹配长度相等的规则,则选择排在最前面的那条规则。
PG中的规则定义如下:
%%{whitespace} { //--------- 空白字符 //忽略,不作任何处理 /* ignore */ }{xcstart} { //--------- C风格注释 /* Set location in case of syntax error in comment */ //设置位置,以防注释中的语法错误 SET_YYLLOC(); //深度 yyextra->xcdepth = 0; //进入xc状态 BEGIN(xc); /* Put back any characters past slash-star; see above */ //把斜杠星后的字符放回去 // 注意:"/*"是2个字符,从位置2(偏移从0起算)开始把之后的字符放回去 yyless(2); }{xcstart} { //遇到下一层的注释,深度+1 (yyextra->xcdepth)++; /* Put back any characters past slash-star; see above */ //类似的,把之后的字符放回去 yyless(2); } {xcstop} { //层次≤0,回到INITIAL状态,否则层次减1 if (yyextra->xcdepth <= 0) BEGIN(INITIAL); else (yyextra->xcdepth)--; } {xcinside} { //注释里面的内容,忽略 /* ignore */ } {op_chars} { //注释里面的内容,忽略 /* ignore */ } \*+ { //注释里面的内容,忽略 /* ignore */ } < > { yyerror("unterminated /* comment"); }//遇到结束符,出错{xbstart} { /* Binary bit type. * At some point we should simply pass the string * forward to the parser and label it there. * In the meantime, place a leading "b" on the string * to mark it for the input routine as a binary string. */ //--------- 二进制位串 //在某些点上,我们应该简单的把字符串向前传递给解析器并标记它 //在此期间,设置一个打头的字符"b"以标记该输入为二进制串 SET_YYLLOC(); BEGIN(xb); startlit(); addlitchar('b', yyscanner); } {quotestop} | {quotefail} { yyless(1); BEGIN(INITIAL); yylval->str = litbufdup(yyscanner); return BCONST; } {xhinside} | {xbinside} { addlit(yytext, yyleng, yyscanner); } {quotecontinue} | {quotecontinue} { /* ignore */ } < > { yyerror("unterminated bit string literal"); }{xhstart} { //------------- 十六进制串 /* Hexadecimal bit type. * At some point we should simply pass the string * forward to the parser and label it there. * In the meantime, place a leading "x" on the string * to mark it for the input routine as a hex string. */ SET_YYLLOC(); BEGIN(xh); startlit(); addlitchar('x', yyscanner); } {quotestop} | {quotefail} { yyless(1); BEGIN(INITIAL); yylval->str = litbufdup(yyscanner); return XCONST; } < > { yyerror("unterminated hexadecimal string literal"); }{xnstart} { //------------- 国家字符 /* National character. * We will pass this along as a normal character string, * but preceded with an internally-generated "NCHAR". */ const ScanKeyword *keyword; SET_YYLLOC(); yyless(1); /* eat only 'n' this time */ keyword = ScanKeywordLookup("nchar", yyextra->keywords, yyextra->num_keywords); if (keyword != NULL) { yylval->keyword = keyword->name; return keyword->value; } else { /* If NCHAR isn't a keyword, just return "n" */ yylval->str = pstrdup("n"); return IDENT; } }{xqstart} { yyextra->warn_on_first_escape = true; yyextra->saw_non_ascii = false; SET_YYLLOC(); if (yyextra->standard_conforming_strings) BEGIN(xq); else BEGIN(xe); startlit(); }{xestart} { yyextra->warn_on_first_escape = false; yyextra->saw_non_ascii = false; SET_YYLLOC(); BEGIN(xe); startlit(); }{xusstart} { SET_YYLLOC(); if (!yyextra->standard_conforming_strings) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("unsafe use of string constant with Unicode escapes"), errdetail("String constants with Unicode escapes cannot be used when standard_conforming_strings is off."), lexer_errposition())); BEGIN(xus); startlit(); } {quotestop} | {quotefail} { yyless(1); BEGIN(INITIAL); /* * 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; } {quotestop} | {quotefail} { /* throw back all but the quote */ yyless(1); /* xusend state looks for possible UESCAPE */ BEGIN(xusend); } {whitespace} { /* stay in xusend state over whitespace */ } < > | {other} | {xustop1} { /* no UESCAPE after the quote, throw back everything */ yyless(0); BEGIN(INITIAL); yylval->str = litbuf_udeescape('\\', yyscanner); return SCONST; } {xustop2} { /* found UESCAPE after the end quote */ BEGIN(INITIAL); if (!check_uescapechar(yytext[yyleng - 2])) { SET_YYLLOC(); ADVANCE_YYLLOC(yyleng - 2); yyerror("invalid Unicode escape character"); } yylval->str = litbuf_udeescape(yytext[yyleng - 2], yyscanner); return SCONST; } {xqdouble} { addlitchar('\'', yyscanner); } {xqinside} { addlit(yytext, yyleng, yyscanner); } {xeinside} { addlit(yytext, yyleng, yyscanner); } {xeunicode} { pg_wchar c = strtoul(yytext + 2, NULL, 16); check_escape_warning(yyscanner); if (is_utf16_surrogate_first(c)) { yyextra->utf16_first_part = c; BEGIN(xeu); } else if (is_utf16_surrogate_second(c)) yyerror("invalid Unicode surrogate pair"); else addunicode(c, yyscanner); } {xeunicode} { pg_wchar c = strtoul(yytext + 2, NULL, 16); if (!is_utf16_surrogate_second(c)) yyerror("invalid Unicode surrogate pair"); c = surrogate_pair_to_codepoint(yyextra->utf16_first_part, c); addunicode(c, yyscanner); BEGIN(xe); } . { yyerror("invalid Unicode surrogate pair"); } \n { yyerror("invalid Unicode surrogate pair"); } < > { yyerror("invalid Unicode surrogate pair"); } {xeunicodefail} { ereport(ERROR, (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE), errmsg("invalid Unicode escape"), errhint("Unicode escapes must be \\uXXXX or \\UXXXXXXXX."), lexer_errposition())); } {xeescape} { 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 quotes in strings. \\' is insecure in client-only encodings."), lexer_errposition())); } check_string_escape_warning(yytext[1], yyscanner); addlitchar(unescape_single_char(yytext[1], yyscanner), yyscanner); } {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; } {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; } {quotecontinue} { /* ignore */ } . { /* This is only needed for \ just before EOF */ addlitchar(yytext[0], yyscanner); } < > { yyerror("unterminated quoted string"); }{dolqdelim} { SET_YYLLOC(); yyextra->dolqstart = pstrdup(yytext); BEGIN(xdolq); startlit(); }{dolqfailed} { SET_YYLLOC(); /* throw back all but the initial "$" */ yyless(1); /* and treat it as {other} */ return yytext[0]; } {dolqdelim} { if (strcmp(yytext, yyextra->dolqstart) == 0) { pfree(yyextra->dolqstart); yyextra->dolqstart = NULL; BEGIN(INITIAL); yylval->str = litbufdup(yyscanner); return SCONST; } else { /* * When we fail to match $...$ to dolqstart, transfer * the $... part to the output, but put back the final * $ for rescanning. Consider $delim$...$junk$delim$ */ addlit(yytext, yyleng - 1, yyscanner); yyless(yyleng - 1); } } {dolqinside} { addlit(yytext, yyleng, yyscanner); } {dolqfailed} { addlit(yytext, yyleng, yyscanner); } . { /* This is only needed for $ inside the quoted text */ addlitchar(yytext[0], yyscanner); } < > { yyerror("unterminated dollar-quoted string"); }{xdstart} { SET_YYLLOC(); BEGIN(xd); startlit(); }{xuistart} { SET_YYLLOC(); BEGIN(xui); startlit(); } {xdstop} { 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); yylval->str = ident; return IDENT; } {dquote} { yyless(1); /* xuiend state looks for possible UESCAPE */ BEGIN(xuiend); } {whitespace} { /* stay in xuiend state over whitespace */ } < > | {other} | {xustop1} { /* no UESCAPE after the quote, throw back everything */ char *ident; int identlen; yyless(0); BEGIN(INITIAL); if (yyextra->literallen == 0) yyerror("zero-length delimited identifier"); ident = litbuf_udeescape('\\', yyscanner); identlen = strlen(ident); if (identlen >= NAMEDATALEN) truncate_identifier(ident, identlen, true); yylval->str = ident; return IDENT; } {xustop2} { /* found UESCAPE after the end quote */ char *ident; int identlen; BEGIN(INITIAL); if (yyextra->literallen == 0) yyerror("zero-length delimited identifier"); if (!check_uescapechar(yytext[yyleng - 2])) { SET_YYLLOC(); ADVANCE_YYLLOC(yyleng - 2); yyerror("invalid Unicode escape character"); } ident = litbuf_udeescape(yytext[yyleng - 2], yyscanner); identlen = strlen(ident); if (identlen >= NAMEDATALEN) truncate_identifier(ident, identlen, true); yylval->str = ident; return IDENT; } {xddouble} { addlitchar('"', yyscanner); } {xdinside} { addlit(yytext, yyleng, yyscanner); } < > { yyerror("unterminated quoted identifier"); }{xufailed} { char *ident; SET_YYLLOC(); /* throw back all but the initial u/U */ yyless(1); /* and treat it as {identifier} */ ident = downcase_truncate_identifier(yytext, yyleng, true); yylval->str = ident; return IDENT; }{typecast} { SET_YYLLOC(); return TYPECAST; }{dot_dot} { SET_YYLLOC(); return DOT_DOT; }{colon_equals} { SET_YYLLOC(); return COLON_EQUALS; }{equals_greater} { SET_YYLLOC(); return EQUALS_GREATER; }{less_equals} { SET_YYLLOC(); return LESS_EQUALS; }{greater_equals} { SET_YYLLOC(); return GREATER_EQUALS; }{less_greater} { /* We accept both "<>" and "!=" as meaning NOT_EQUALS */ SET_YYLLOC(); return NOT_EQUALS; }{not_equals} { /* We accept both "<>" and "!=" as meaning NOT_EQUALS */ SET_YYLLOC(); return NOT_EQUALS; }{self} { SET_YYLLOC(); return yytext[0]; }{operator} { /* * Check for embedded slash-star or dash-dash; those * are comment starts, so operator must stop there. * Note that slash-star or dash-dash at the first * character will match a prior rule, not this one. */ int nchars = yyleng; char *slashstar = strstr(yytext, "/*"); char *dashdash = strstr(yytext, "--"); if (slashstar && dashdash) { /* if both appear, take the first one */ if (slashstar > dashdash) slashstar = dashdash; } else if (!slashstar) slashstar = dashdash; if (slashstar) nchars = slashstar - yytext; /* * For SQL compatibility, '+' and '-' cannot be the * last char of a multi-char operator unless the operator * contains chars that are not in SQL operators. * The idea is to lex '=-' as two operators, but not * to forbid operator names like '?-' that could not be * sequences of SQL operators. */ if (nchars > 1 && (yytext[nchars - 1] == '+' || yytext[nchars - 1] == '-')) { int ic; for (ic = nchars - 2; ic >= 0; ic--) { char c = yytext[ic]; if (c == '~' || c == '!' || c == '@' || c == '#' || c == '^' || c == '&' || c == '|' || c == '`' || c == '?' || c == '%') break; } if (ic < 0) { /* * didn't find a qualifying character, so remove * all trailing [+-] */ do { nchars--; } while (nchars > 1 && (yytext[nchars - 1] == '+' || yytext[nchars - 1] == '-')); } } SET_YYLLOC(); if (nchars < yyleng) { /* Strip the unwanted chars from the token */ yyless(nchars); /* * If what we have left is only one char, and it's * one of the characters matching "self", then * return it as a character token the same way * that the "self" rule would have. */ if (nchars == 1 && strchr(",()[].;:+-*/%^<>=", yytext[0])) return yytext[0]; /* * Likewise, if what we have left is two chars, and * those match the tokens ">=", "<=", "=>", "<>" or * "!=", then we must return the appropriate token * rather than the generic Op. */ if (nchars == 2) { if (yytext[0] == '=' && yytext[1] == '>') return EQUALS_GREATER; if (yytext[0] == '>' && yytext[1] == '=') return GREATER_EQUALS; if (yytext[0] == '<' && yytext[1] == '=') return LESS_EQUALS; if (yytext[0] == '<' && yytext[1] == '>') return NOT_EQUALS; if (yytext[0] == '!' && yytext[1] == '=') return NOT_EQUALS; } } /* * Complain if operator is too long. Unlike the case * for identifiers, we make this an error not a notice- * and-truncate, because the odds are we are looking at * a syntactic mistake anyway. */ if (nchars >= NAMEDATALEN) yyerror("operator too long"); yylval->str = pstrdup(yytext); return Op; }{param} { SET_YYLLOC(); yylval->ival = atol(yytext + 1); return PARAM; }{integer} { SET_YYLLOC(); return process_integer_literal(yytext, yylval); }{decimal} { SET_YYLLOC(); yylval->str = pstrdup(yytext); return FCONST; }{decimalfail} { /* throw back the .., and treat as integer */ yyless(yyleng - 2); SET_YYLLOC(); return process_integer_literal(yytext, yylval); }{real} { SET_YYLLOC(); yylval->str = pstrdup(yytext); return FCONST; }{realfail1} { /* * throw back the [Ee], and treat as {decimal}. Note * that it is possible the input is actually {integer}, * but since this case will almost certainly lead to a * syntax error anyway, we don't bother to distinguish. */ yyless(yyleng - 1); SET_YYLLOC(); yylval->str = pstrdup(yytext); return FCONST; }{realfail2} { /* throw back the [Ee][+-], and proceed as above */ yyless(yyleng - 2); SET_YYLLOC(); yylval->str = pstrdup(yytext); return FCONST; }{identifier} { //---------- 标识符 const ScanKeyword *keyword; char *ident; SET_YYLLOC(); /* Is it a keyword? */ //是否关键字? keyword = ScanKeywordLookup(yytext, yyextra->keywords, yyextra->num_keywords); if (keyword != NULL) { //是,则返回关键字值 yylval->keyword = keyword->name; return keyword->value; } /* * No. Convert the identifier to lower case, and truncate * if necessary. */ //如果不是关键字,则设置为小写字母,如需要则截断 ident = downcase_truncate_identifier(yytext, yyleng, true); yylval->str = ident; return IDENT; }{other} { SET_YYLLOC(); return yytext[0]; }< > { SET_YYLLOC(); yyterminate(); }%%
"PostgreSQL中的Rules有什么作用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
规则
字符
内容
注释
模式
输入
代码
关键
关键字
函数
文件
作用
最长
二进制
位置
到时
动作
层次
更多
标记
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
域管理服务器的硬件要求
wps数据库怎么下载文献
local怎么登录数据库
国际银行网络安全
网络技术的发展对工作的影响
中国移动网络安全中心
h3c服务器h3c服务器
2009互联网数据库
数据库系统保存在内磁盘吗
网络技术方向所需专业知识
上海驿悠互联网科技有限公司
手机老连不到服务器怎么办
大型软件开发设计的角色
恐惧饥饿服务器一直崩
山西方便软件开发介绍
四川冲击波网络技术有限公司
戴尔服务器死机
svn服务器架设
计算机网络技术第一章教程
网络安全为什么查滴滴
安徽工程大学网络安全教育平台
上海软件开发正规平台
淮北系统软件开发需要多少钱
数据库字段不一样 如何导入
数据库表存储容量预估
瀑布模型最大的优点是将软件开发
cisco计算机网络技术
java软件开发毕业项目
黑市宝箱便宜的服务器
国内中转 服务器