1# dialects/postgresql/operators.py
2# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
7# mypy: ignore-errors
8from ...sql import operators
9
10
11_getitem_precedence = operators._PRECEDENCE[operators.json_getitem_op]
12_eq_precedence = operators._PRECEDENCE[operators.eq]
13
14# JSON + JSONB
15ASTEXT = operators.custom_op(
16 "->>",
17 precedence=_getitem_precedence,
18 natural_self_precedent=True,
19 eager_grouping=True,
20)
21
22JSONPATH_ASTEXT = operators.custom_op(
23 "#>>",
24 precedence=_getitem_precedence,
25 natural_self_precedent=True,
26 eager_grouping=True,
27)
28
29# JSONB + HSTORE
30HAS_KEY = operators.custom_op(
31 "?",
32 precedence=_eq_precedence,
33 natural_self_precedent=True,
34 eager_grouping=True,
35 is_comparison=True,
36)
37
38HAS_ALL = operators.custom_op(
39 "?&",
40 precedence=_eq_precedence,
41 natural_self_precedent=True,
42 eager_grouping=True,
43 is_comparison=True,
44)
45
46HAS_ANY = operators.custom_op(
47 "?|",
48 precedence=_eq_precedence,
49 natural_self_precedent=True,
50 eager_grouping=True,
51 is_comparison=True,
52)
53
54# JSONB
55DELETE_PATH = operators.custom_op(
56 "#-",
57 precedence=_getitem_precedence,
58 natural_self_precedent=True,
59 eager_grouping=True,
60)
61
62PATH_EXISTS = operators.custom_op(
63 "@?",
64 precedence=_eq_precedence,
65 natural_self_precedent=True,
66 eager_grouping=True,
67 is_comparison=True,
68)
69
70PATH_MATCH = operators.custom_op(
71 "@@",
72 precedence=_eq_precedence,
73 natural_self_precedent=True,
74 eager_grouping=True,
75 is_comparison=True,
76)
77
78# JSONB + ARRAY + HSTORE + RANGE
79CONTAINS = operators.custom_op(
80 "@>",
81 precedence=_eq_precedence,
82 natural_self_precedent=True,
83 eager_grouping=True,
84 is_comparison=True,
85)
86
87CONTAINED_BY = operators.custom_op(
88 "<@",
89 precedence=_eq_precedence,
90 natural_self_precedent=True,
91 eager_grouping=True,
92 is_comparison=True,
93)
94
95# ARRAY + RANGE
96OVERLAP = operators.custom_op(
97 "&&",
98 precedence=_eq_precedence,
99 is_comparison=True,
100)
101
102# RANGE
103STRICTLY_LEFT_OF = operators.custom_op(
104 "<<", precedence=_eq_precedence, is_comparison=True
105)
106
107STRICTLY_RIGHT_OF = operators.custom_op(
108 ">>", precedence=_eq_precedence, is_comparison=True
109)
110
111NOT_EXTEND_RIGHT_OF = operators.custom_op(
112 "&<", precedence=_eq_precedence, is_comparison=True
113)
114
115NOT_EXTEND_LEFT_OF = operators.custom_op(
116 "&>", precedence=_eq_precedence, is_comparison=True
117)
118
119ADJACENT_TO = operators.custom_op(
120 "-|-", precedence=_eq_precedence, is_comparison=True
121)
122
123# HSTORE
124GETITEM = operators.custom_op(
125 "->",
126 precedence=_getitem_precedence,
127 natural_self_precedent=True,
128 eager_grouping=True,
129)