pglast.precedence — Operators precedence logic¶
The functions here answer the question “does this node need to be wrapped in parentheses when it is used as an operand of that other expression?”, which cannot be decided by looking at a node alone: the same node needs parens in one slot and not in another.
The vocabulary mirrors the PostgreSQL grammar rules: an expression is printed either in an
a_expr, a b_expr or a c_expr context, and the rule that handles a node determines
its precedence.
- class pglast.precedence.ExprContext(*values)¶
Which grammar rule a value is being printed into.
This is internal vocabulary: it is never user visible.
- class pglast.precedence.ExprPrec(*values)¶
The precedence of the expression, from the loosest to the tightest.
The value mirrors the order in which the corresponding rules appear in the PostgreSQL grammar, so that a node binding looser than another has a smaller value.
- ADD = 7¶
+ -
- AND = 1¶
AND
- AT = 10¶
AT TIME ZONE,AT LOCAL
- ATOM = 13¶
c_expr, typecasts, and anything else that cannot be split apart
- BETWEEN = 5¶
BETWEEN IN LIKE ILIKE SIMILAR(non-associative)
- COLLATE = 11¶
COLLATE
- COMPARISON = 4¶
< > = <= >= <>(non-associative)
- EXP = 9¶
^
- IS = 3¶
IS,ISNULL,NOTNULL(non-associative)
- MUL = 8¶
* / %
- NOT = 2¶
NOT(right-associative)
- OP = 6¶
Op/OPERATOR, i.e. all other operators
- OR = 0¶
OR
- UMINUS = 12¶
unary
+ -(right-associative)
- class pglast.precedence.Side(*values)¶
The side of an operator an operand appears on.
- pglast.precedence.expr_precedence(node, stream)¶
Return the precedence of the grammar rule that node is printed by.
- Parameters:
node – an .ast.Node instance
stream – the stream that is printing the node
- Returns:
ExprPrec
- pglast.precedence.is_b_expr_rule(node, stream)¶
Whether node is handled by a
b_exprrule, so it may appear in ab_exprcontext.- Parameters:
node – an .ast.Node instance
stream – the stream that is printing the node
- Returns:
bool
Everything that is not handled by a
b_exprrule (e.g.NOT,IS NULL,COLLATE,AT TIME ZONE) is only handled by thea_exprrule and needs explicit parens when used in ab_exprcontext.
- pglast.precedence.is_subquery_comparison_form(node)¶
Whether node is a subquery comparison form:
x = ANY (...),x < ALL (...).- Parameters:
node – an .ast.Node instance
- Returns:
bool
x IN (...)and the like. As the left operand of an operator at the same precedence these never need parens (seeneeds_parens_for_precedence()); at any other precedence the normal rules apply, since dropping parens there can reassociate the expression or fail to parse:d = x = ANY(c)is rejected outright, andd || x = ANY(c)reparses with the comparison swallowing the concatenation.
- pglast.precedence.needs_parens_as_c_expr(node, stream)¶
Whether node needs parens when used in a
c_exprcontext.- Parameters:
node – an .ast.Node instance
stream – the stream that is printing the node
- Returns:
bool
- pglast.precedence.needs_parens_for_precedence(node, parent_prec, side, stream)¶
Whether node needs parens as the side operand of an expression with parent_prec.
- pglast.precedence.operator_precedence(name)¶
Return the precedence of operator name.
- Parameters:
name – the
A_Expr.nameslot- Returns:
ExprPrec
OPERATOR(schema.op)always has the precedence ofOp.
- pglast.precedence.special_function_name(node, stream)¶
Return the qualified name of the special function that stream will use to print node.
- Parameters:
node – an .ast.Node instance
stream – the stream that is printing the node
- Returns:
either
Noneor the qualified name of a registered special function
Only the functions whose alternate form changes the precedence of the node matter here:
pg_catalog.timezone()is printed asAT TIME ZONEandpg_catalog.is_normalized()asIS ... NORMALIZED, both only when thespecial_functionsoption is enabled. Deferring to the stream keeps this in sync with what is actually emitted.
- pglast.precedence.subquery_operator_precedence(name)¶
Return the precedence of operator name, as used in a subquery comparison.
- Parameters:
name – the
A_Expr.nameorSubLink.operNameslot- Returns:
ExprPrec
A subquery comparison using one of the
LIKE/ILIKEoperators is printed in that keyword form, so the operator binds likeBETWEEN; everything else behaves as inoperator_precedence().