1# dialects/postgresql/operators.py
2# Copyright (C) 2005-2026 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_getitem_precedence = operators._PRECEDENCE[operators.json_getitem_op]
11_eq_precedence = operators._PRECEDENCE[operators.eq]
12
13# JSON + JSONB
14ASTEXT = operators.custom_op(
15 "->>",
16 precedence=_getitem_precedence,
17 natural_self_precedent=True,
18 eager_grouping=True,
19)
20
21JSONPATH_ASTEXT = operators.custom_op(
22 "#>>",
23 precedence=_getitem_precedence,
24 natural_self_precedent=True,
25 eager_grouping=True,
26)
27
28# JSONB + HSTORE
29HAS_KEY = operators.custom_op(
30 "?",
31 precedence=_eq_precedence,
32 natural_self_precedent=True,
33 eager_grouping=True,
34 is_comparison=True,
35)
36
37HAS_ALL = operators.custom_op(
38 "?&",
39 precedence=_eq_precedence,
40 natural_self_precedent=True,
41 eager_grouping=True,
42 is_comparison=True,
43)
44
45HAS_ANY = operators.custom_op(
46 "?|",
47 precedence=_eq_precedence,
48 natural_self_precedent=True,
49 eager_grouping=True,
50 is_comparison=True,
51)
52
53# JSONB
54DELETE_PATH = operators.custom_op(
55 "#-",
56 precedence=_getitem_precedence,
57 natural_self_precedent=True,
58 eager_grouping=True,
59)
60
61PATH_EXISTS = operators.custom_op(
62 "@?",
63 precedence=_eq_precedence,
64 natural_self_precedent=True,
65 eager_grouping=True,
66 is_comparison=True,
67)
68
69PATH_MATCH = operators.custom_op(
70 "@@",
71 precedence=_eq_precedence,
72 natural_self_precedent=True,
73 eager_grouping=True,
74 is_comparison=True,
75)
76
77# JSONB + ARRAY + HSTORE + RANGE
78CONTAINS = operators.custom_op(
79 "@>",
80 precedence=_eq_precedence,
81 natural_self_precedent=True,
82 eager_grouping=True,
83 is_comparison=True,
84)
85
86CONTAINED_BY = operators.custom_op(
87 "<@",
88 precedence=_eq_precedence,
89 natural_self_precedent=True,
90 eager_grouping=True,
91 is_comparison=True,
92)
93
94# ARRAY + RANGE
95OVERLAP = operators.custom_op(
96 "&&",
97 precedence=_eq_precedence,
98 is_comparison=True,
99)
100
101# RANGE
102STRICTLY_LEFT_OF = operators.custom_op(
103 "<<", precedence=_eq_precedence, is_comparison=True
104)
105
106STRICTLY_RIGHT_OF = operators.custom_op(
107 ">>", precedence=_eq_precedence, is_comparison=True
108)
109
110NOT_EXTEND_RIGHT_OF = operators.custom_op(
111 "&<", precedence=_eq_precedence, is_comparison=True
112)
113
114NOT_EXTEND_LEFT_OF = operators.custom_op(
115 "&>", precedence=_eq_precedence, is_comparison=True
116)
117
118ADJACENT_TO = operators.custom_op(
119 "-|-", precedence=_eq_precedence, is_comparison=True
120)
121
122# HSTORE
123GETITEM = operators.custom_op(
124 "->",
125 precedence=_getitem_precedence,
126 natural_self_precedent=True,
127 eager_grouping=True,
128)