Skip to main content

BindingPowerTable

Struct BindingPowerTable 

Source
pub struct BindingPowerTable {
Show 25 fields pub or: BindingPower, pub xor: BindingPower, pub and: BindingPower, pub comparison: BindingPower, pub range_predicate_override: Option<BindingPower>, pub is_predicate_override: Option<BindingPower>, pub double_equals: BindingPower, pub additive: BindingPower, pub multiplicative: BindingPower, pub exponent: BindingPower, pub string_concat: BindingPower, pub any_operator: BindingPower, pub json_get: BindingPower, pub bitwise_or: BindingPower, pub bitwise_and: BindingPower, pub bitwise_shift: BindingPower, pub bitwise_xor: BindingPower, pub prefix_not: u8, pub prefix_sign: u8, pub prefix_bitwise_not: u8, pub at_time_zone: BindingPower, pub collate: BindingPower, pub subscript: BindingPower, pub typecast: BindingPower, pub field_selection: BindingPower,
}
Expand description

Dialect-owned Pratt and render-time binding powers.

The table is field-based rather than array-indexed so adding a BinaryOperator or UnaryOperator forces this module to name its binding power. Dialects can replace the whole table on FeatureSet or build a small delta with with_binary.

Fields§

§or: BindingPower

Binding power of logical OR.

§xor: BindingPower

MySQL XOR logical exclusive-or: binds tighter than OR and looser than AND (MySQL’s OR < XOR < AND precedence). No standard operator occupies this rank, so it gets its own field rather than sharing or/and.

§and: BindingPower

Binding power of logical AND.

§comparison: BindingPower

Binding power of the comparison operators (=/</>/…).

§range_predicate_override: Option<BindingPower>

The range/pattern/membership predicate tier — [NOT] BETWEEN, [NOT] IN, [NOT] LIKE/ILIKE/SIMILAR TO. None tracks comparison (the historical placement every dialect parsed these at, so a dialect that re-associates its comparisons carries these with it); Some re-ranks them to a dedicated tier, read through range_predicate.

PostgreSQL/DuckDB place this family one tier ABOVE the comparison operators (</>/=) and below the %left Op “any other operator” rank — gram.y’s %nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR row — so a = b BETWEEN c AND d groups a = (b BETWEEN c AND d) (engine-measured on pg_query 6.1 and DuckDB json_serialize_sql); the PostgreSQL/Lenient presets set Some(RANGE_PREDICATE_ABOVE_COMPARISON). MySQL/SQLite rank BETWEEN at or below comparison (their manuals), so they leave this None and track comparison automatically, staying byte-identical. The IS [NOT] NULL/IS DISTINCT/truth-value predicates are a SEPARATE (in PostgreSQL/DuckDB, looser) tier — see is_predicate_override.

§is_predicate_override: Option<BindingPower>

The IS-family predicate tier — the postfix IS [NOT] NULL / ISNULL / NOTNULL / NOT NULL null tests, the IS [NOT] {TRUE|FALSE|UNKNOWN} truth-value tests, IS [NOT] NORMALIZED, and the infix IS [NOT] DISTINCT FROM (keyword form). None tracks comparison (MySQL/SQLite rank IS at the comparison/equality tier, so they stay byte-identical); Some re-ranks the whole family to a dedicated tier read through predicate.

PostgreSQL and DuckDB place this family one tier BELOW the comparison operators (</>/=) and above NOT — PostgreSQL gram.y’s %nonassoc IS ISNULL NOTNULL row, which sits under %nonassoc '<' '>' '=' — so a <> b IS NULL groups (a <> b) IS NULL and a IS DISTINCT FROM b = c groups a IS DISTINCT FROM (b = c) (engine-measured on PostgreSQL 16 pg_get_viewdef and DuckDB 1.5.4 json_serialize_sql); the PostgreSQL/DuckDB/Lenient presets set Some(IS_PREDICATE_BELOW_COMPARISON). Non-associative, matching both engines (a IS DISTINCT FROM b IS DISTINCT FROM c is a parse error). SQLite’s bare general IS/IS NOT and MySQL’s <=> are comparison-tier null-safe (in)equality, distinguished by spelling, and are unaffected by this override.

§double_equals: BindingPower

The == spelling of equality (BinaryOperator::Eq with EqualsSpelling::Double). Carries the comparison value in every dialect but DuckDB, where == is not the %nonassoc '=' comparison but a generic %left Op operator: it binds tighter than the comparisons and looser than additive, left-associative (1 == 2 == 3 is ((1 = 2) = 3), 1 < 2 == 3 is (1 < (2 = 3)), 1 + 1 == 2 is ((1 + 1) = 2) — measured on 1.5.4). A distinct field so this DuckDB re-ranking never disturbs the =/</> comparisons it shares BinaryOperator::Eq with; with_binary keeps the two in sync for the comparison-family callers (SQLite/MySQL move both together) and lets DuckDB move == alone.

§additive: BindingPower

Binding power of the additive operators (+/-).

§multiplicative: BindingPower

Binding power of the multiplicative operators (*///%).

§exponent: BindingPower

PostgreSQL exponentiation (^, BinaryOperator::Exponent). Its OWN precedence row in gram.y (%left '^'): tighter than multiplicative * / % and looser than the unary sign, left-associative (2 ^ 3 ^ 2 is (2 ^ 3) ^ 2, 2 ^ 3 * 2 is (2 ^ 3) * 2 — engine-measured on pg_query). Distinct from bitwise_xor: MySQL’s ^ (bitwise XOR) binds tighter than *, PostgreSQL’s ^ (power) binds tighter than * but is a different operator at a different (higher) rank, so the two never share a field. Only reachable under CaretOperator::Exponent.

§string_concat: BindingPower

Binding power of the || string-concatenation operator.

§any_operator: BindingPower

PostgreSQL’s “any other operator” rank — the precedence gram.y gives every native and user-defined symbolic operator outside the arithmetic/comparison core (%left Op OPERATOR): looser than additive +/-, tighter than the comparison/BETWEEN family. The @>/<@ containment and ->> JSON operators bind here, left-associative. It carries the same value as string_concat (|| is itself an “any other operator” in PostgreSQL) but is a distinct field so moving one does not move the other.

§json_get: BindingPower

The -> token’s rank (BinaryOperator::JsonGet, which is also the DuckDB lambda arrow — one token, one rank). In PostgreSQL/SQLite it carries the any_operator value (-> is an ordinary Op there), but DuckDB lexes -> as its own LAMBDA_ARROW grammar token ranked below every expression operator — x -> x % 2 = 0 and even x -> x OR y put the whole right side in the lambda body, and NOT x -> y takes NOT x as the left operand (measured on 1.5.4 via json_serialize_sql) — while its ->> stays at the Op rank. A distinct field so a dialect can move -> without moving ->>/@>/<@, the same split rationale as string_concat vs any_operator.

§bitwise_or: BindingPower

Bitwise OR (|). In PostgreSQL/SQLite/DuckDB the four binary bitwise operators share one rank between additive and comparison (engine-measured: 1 | 2 & 2 is (1 | 2) & 2), so the fields below carry the same standard value but stay distinct — MySQL ranks | < & < <</>> at three separate levels (its documented grammar), so a dialect moves each independently, exactly as string_concat and any_operator split.

§bitwise_and: BindingPower

Bitwise AND (&). Standard-equal to bitwise_or; tighter than it in MySQL.

§bitwise_shift: BindingPower

Bitwise shift (<< / >>, one shared rank — the two shifts never diverge in any dialect). Looser than additive everywhere; tighter than & and looser than additive in MySQL.

§bitwise_xor: BindingPower

Bitwise exclusive-or (PostgreSQL #, MySQL ^). In the standard table it carries PostgreSQL’s “any other operator” rank (looser than additive, like #); MySQL re-ranks it tighter than multiplicative (^ binds above *), so it is its own field.

§prefix_not: u8

Binding power of the prefix NOT operator.

§prefix_sign: u8

Binding power of the prefix +/- sign.

§prefix_bitwise_not: u8

Prefix bitwise complement (~). Binds like the unary sign in SQLite/MySQL, but in PostgreSQL/DuckDB it sits between the arithmetic operators and the binary bitwise family: one above bitwise_or’s left rank, so the bitwise binaries do not fold into its operand (~ 1 & 3 is (~ 1) & 3) while the tighter arithmetic does (~ 1 + 1 is ~ (1 + 1)) — both engine-measured — and the render still parenthesizes ~ (a & b) (the strict-inequality break the equal-rank case would lose).

§at_time_zone: BindingPower

expr AT TIME ZONE zone (PostgreSQL): binds tighter than the arithmetic operators and looser than COLLATE and the unary sign.

§collate: BindingPower

expr COLLATE collation (PostgreSQL): just tighter than AT TIME ZONE, just looser than the unary sign.

§subscript: BindingPower

base[index] / base[lo:hi] array subscript (PostgreSQL): binds tighter than the unary sign and looser than the :: typecast.

§typecast: BindingPower

expr::type typecast (PostgreSQL): one of the tightest-binding operators, just looser than composite field selection.

§field_selection: BindingPower

(expr).field composite field selection (PostgreSQL): the tightest of the postfix operators.

Implementations§

Source§

impl BindingPowerTable

Source

pub const STANDARD: Self

Standard M1 binding powers shared by the ANSI and PostgreSQL presets.

Source

pub const fn binary(&self, op: &BinaryOperator) -> BindingPower

Return the binary binding power for op.

Source

pub const fn prefix(&self, op: &UnaryOperator) -> u8

Return the prefix binding power for op.

Source

pub const fn predicate(&self) -> BindingPower

Return the binding power of the IS-family predicates (IS [NOT] NULL, ISNULL, NOTNULL, NOT NULL, IS [NOT] {TRUE|FALSE|UNKNOWN}, IS [NOT] NORMALIZED, and the keyword IS [NOT] DISTINCT FROM).

Defaults to comparison — returned when is_predicate_override is None, so MySQL/SQLite (which rank IS at the comparison/equality tier) carry these predicates with their comparisons — while the PostgreSQL/DuckDB/Lenient presets override it to their dedicated tier one rank below comparison. The parser climbs the family at this rank and forbids chaining them with comparisons, and render-time parenthesization reads the same level, so the two can never drift (ADR-0008).

Source

pub const fn range_predicate(&self) -> BindingPower

Return the binding power of the range/pattern/membership predicates ([NOT] BETWEEN, [NOT] IN, [NOT] LIKE/ILIKE/SIMILAR TO).

Defaults to comparison — returned when range_predicate_override is None, so a dialect that re-associates its comparisons carries these predicates with it — while the PostgreSQL/Lenient presets override it to their dedicated tighter tier. The parser climbs these predicates at this rank and the renderer parenthesizes them by it, one source of truth (ADR-0008).

Source

pub const fn with_binary(self, op: &BinaryOperator, bp: BindingPower) -> Self

Return a copy of this table with one binary operator class replaced.

Source

pub const fn needs_parens( &self, parent: &BinaryOperator, child: &BinaryOperator, side: Side, ) -> bool

Return whether a child binary expression needs parentheses under parent.

Trait Implementations§

Source§

impl Clone for BindingPowerTable

Source§

fn clone(&self) -> BindingPowerTable

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for BindingPowerTable

Source§

impl Debug for BindingPowerTable

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for BindingPowerTable

Source§

impl PartialEq for BindingPowerTable

Source§

fn eq(&self, other: &BindingPowerTable) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for BindingPowerTable

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.