PostgreSQL中的Rules有什么作用
发表于:2025-02-19 作者:千家信息网编辑
千家信息网最后更新 2025年02月19日,本篇内容介绍了"PostgreSQL中的Rules有什么作用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有
千家信息网最后更新 2025年02月19日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安全错误
数据库的锁怎样保障安全
国防科大网络安全学科评估排名
sql数据库创建表
保险业网络安全监管
我的世界无规则服务器咋样建造
安徽省超级服务器云主机
大专联校网络安全竞赛2017
自贡网络安全工作研讨会
石油公司服务器设备安全制度
宝塔安装oracle数据库
中国网络安全协会杜跃进
国内数据库市场现状
网络安全技能竞赛颁奖词
计算机网络技术优秀简历
网络安全法高分答题攻略
应聘软件开发工程师面试问题
网络安全发生的风险增大时
国产 数据库 tidb
r和t的计算数据库
计算机网络技术个人简历
网络安全预防诈骗手抄报图片
江西哪个专科软件开发专业好
工控网络技术实训报告
安全警告数据库
eis 网络安全加速
苏州常见软件开发注意事项
临漳县网信办网络安全检查
广州ai服务器生产厂商
梦幻西游最近有什么服务器
服务器电源引脚图
网站服务器网络