PostgreSQL查询引擎——General Expressions Grammar之restricted expression

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

General expressions语法规则定义在src/backend/parser/gram.y文件中其是表达式语法的核心。有两种表达式类型a_expr是不受限制的类型b_expr是必须在某些地方使用的子集以避免移位/减少冲突。例如我们不能将BETWEEN作为BETWEEN a_expr AND a_exp因为AND的使用与AND作为布尔运算符冲突。因此b_exprBETWEEN中使用我们从b_expr中删除布尔关键字。请注意( a_expr )b_expr因此始终可以使用无限制表达式方法是用括号将其括起来。c_expra_exprb_expr共同的所有乘积它被分解出来只是为了消除冗余编码。注意涉及多个terminal token的产出productions。默认情况下bison将为此类productions分配其最后一个terminal的优先级但在几乎所有情况下您都希望它是第一个terminal的优先权否则你不会得到你期望的行为因此我们可以自由使用%prec注释来设置优先级。
在这里插入图片描述
b_expr代表Restricted expressions它是复杂表达式a_expr的子集AND, NOT, IS, and IN是a_expr的关键字这些关键字在b_expr使用会存在歧义。b_expr is a subset of the complete expression syntax defined by a_expr. Presently, AND, NOT, IS, and IN are the a_expr keywords that would cause trouble in the places where b_expr is used. For simplicity, we just eliminate all the boolean-keyword-operator productions from b_expr.

b_expr:		c_expr
				{ $$ = $1; }
			| b_expr TYPECAST Typename
				{ $$ = makeTypeCast($1, $3, @2); }
			| '+' b_expr					%prec UMINUS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
			| '-' b_expr					%prec UMINUS
				{ $$ = doNegate($2, @1); }
			| b_expr '+' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
			| b_expr '-' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
			| b_expr '*' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
			| b_expr '/' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
			| b_expr '%' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
			| b_expr '^' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
			| b_expr '<' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
			| b_expr '>' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
			| b_expr '=' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
			| b_expr LESS_EQUALS b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $3, @2); }
			| b_expr GREATER_EQUALS b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); }
			| b_expr NOT_EQUALS b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); }
			| b_expr qual_Op b_expr				%prec Op
				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
			| qual_Op b_expr					%prec Op
				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
			| b_expr qual_Op					%prec POSTFIXOP
				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }
			| b_expr IS DISTINCT FROM b_expr		%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2); }
			| b_expr IS NOT DISTINCT FROM b_expr	%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2); }
			| b_expr IS OF '(' type_list ')'		%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2); }
			| b_expr IS NOT OF '(' type_list ')'	%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2); }
			| b_expr IS DOCUMENT_P					%prec IS
				{ $$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2); }
			| b_expr IS NOT DOCUMENT_P				%prec IS
				{ $$ = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2), @2); }

表达式强转

在这里插入图片描述
b_expr TYPECAST Typename是表达式强转的规则其中主要关注SimpleTypename所代表的规则。除了GenericType之外的规则和PostgreSQL查询引擎——General Expressions Grammar之AexprConst中介绍的常量类型强转类似这里仅仅关注GenericType。

SimpleTypename:
			GenericType								{ $$ = $1; }
			| Numeric								{ $$ = $1; }
			| Bit									{ $$ = $1; }
			| Character								{ $$ = $1; }
			| ConstDatetime							{ $$ = $1; }
			| ConstInterval opt_interval
				{ $$ = $1; $$->typmods = $2; }
			| ConstInterval '(' Iconst ')'
				{ $$ = $1; $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), makeIntConst($3, @3)); }
		;

GenericType涵盖所有没有标准规定的特殊语法的类型名称包括限定名称。我们还允许类型修饰符。为了避免对函数调用的解析冲突这里必须将修饰符显示为expr_list但解析分析只接受它们的常量。GenericType covers all type names that don’t have special syntax mandated by the standard, including qualified names. We also allow type modifiers. To avoid parsing conflicts against function invocations, the modifiers have to be shown as expr_list here, but parse analysis will only accept constants for them.

GenericType:
			type_function_name opt_type_modifiers
				{ $$ = makeTypeName($1); $$->typmods = $2; $$->location = @1; }
			| type_function_name attrs opt_type_modifiers
				{ $$ = makeTypeNameFromNameList(lcons(makeString($1), $2)); $$->typmods = $3; $$->location = @1; }
opt_type_modifiers: '(' expr_list ')'				{ $$ = $2; }
					| /* EMPTY */					{ $$ = NIL; }

表达式强转的规则不同之处在于opt_array_bounds和ARRAY对于arrayBounds成员取值的影响以及使用SETOF需要将setof成员设置为true。

Typename:	SimpleTypename opt_array_bounds
				{ $$ = $1; $$->arrayBounds = $2; }
			| SETOF SimpleTypename opt_array_bounds
				{ $$ = $2; $$->arrayBounds = $3; $$->setof = true; }
			/* SQL standard syntax, currently only one-dimensional */
			| SimpleTypename ARRAY '[' Iconst ']'
				{ $$ = $1; $$->arrayBounds = list_make1(makeInteger($4)); }
			| SETOF SimpleTypename ARRAY '[' Iconst ']'
				{ $$ = $2; $$->arrayBounds = list_make1(makeInteger($5)); $$->setof = true; }
			| SimpleTypename ARRAY
				{ $$ = $1; $$->arrayBounds = list_make1(makeInteger(-1)); }
			| SETOF SimpleTypename ARRAY
				{ $$ = $2; $$->arrayBounds = list_make1(makeInteger(-1)); $$->setof = true; }
opt_array_bounds:
			opt_array_bounds '[' ']'
					{  $$ = lappend($1, makeInteger(-1)); }
			| opt_array_bounds '[' Iconst ']'
					{  $$ = lappend($1, makeInteger($3)); }
			| /*EMPTY*/
					{  $$ = NIL; }

运算符

请添加图片描述

			| '+' b_expr					%prec UMINUS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
			| '-' b_expr					%prec UMINUS
				{ $$ = doNegate($2, @1); }
			| b_expr '+' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
			| b_expr '-' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
			| b_expr '*' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
			| b_expr '/' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
			| b_expr '%' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
			| b_expr '^' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
			| b_expr '<' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
			| b_expr '>' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
			| b_expr '=' b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
			| b_expr LESS_EQUALS b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $3, @2); }
			| b_expr GREATER_EQUALS b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $3, @2); }
			| b_expr NOT_EQUALS b_expr
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<>", $1, $3, @2); }
			| b_expr qual_Op b_expr				%prec Op
				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
			| qual_Op b_expr					%prec Op
				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
			| b_expr qual_Op					%prec POSTFIXOP
				{ $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }
			| b_expr IS DISTINCT FROM b_expr		%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2); }
			| b_expr IS NOT DISTINCT FROM b_expr	%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2); }
			| b_expr IS OF '(' type_list ')'		%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2); }
			| b_expr IS NOT OF '(' type_list ')'	%prec IS
				{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2); }
			| b_expr IS DOCUMENT_P					%prec IS
				{ $$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2); }
			| b_expr IS NOT DOCUMENT_P				%prec IS
				{ $$ = makeNotExpr(makeXmlExpr(IS_DOCUMENT, NULL, NIL, list_make1($1), @2), @2); }

https://www.developerastrid.com/sql/sql-predicates/

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6