@@ -63,6 +63,11 @@ class InstrumentedExpression:
6363 def __init__ (self , expr : str ):
6464 self ._expr = expr
6565
66+ def _render_value (self , value : Any ) -> str :
67+ if isinstance (value , InstrumentedExpression ):
68+ return str (value )
69+ return json .dumps (value )
70+
6671 def __str__ (self ) -> str :
6772 return self ._expr
6873
@@ -76,61 +81,136 @@ def __neg__(self) -> "InstrumentedExpression":
7681 return InstrumentedExpression (f"-({ self ._expr } )" )
7782
7883 def __eq__ (self , value : Any ) -> "InstrumentedExpression" : # type: ignore[override]
79- return InstrumentedExpression (f"{ self ._expr } == { json . dumps (value )} " )
84+ return InstrumentedExpression (f"{ self ._expr } == { self . _render_value (value )} " )
8085
8186 def __ne__ (self , value : Any ) -> "InstrumentedExpression" : # type: ignore[override]
82- return InstrumentedExpression (f"{ self ._expr } != { json . dumps (value )} " )
87+ return InstrumentedExpression (f"{ self ._expr } != { self . _render_value (value )} " )
8388
8489 def __lt__ (self , value : Any ) -> "InstrumentedExpression" :
85- return InstrumentedExpression (f"{ self ._expr } < { json . dumps (value )} " )
90+ return InstrumentedExpression (f"{ self ._expr } < { self . _render_value (value )} " )
8691
8792 def __gt__ (self , value : Any ) -> "InstrumentedExpression" :
88- return InstrumentedExpression (f"{ self ._expr } > { json . dumps (value )} " )
93+ return InstrumentedExpression (f"{ self ._expr } > { self . _render_value (value )} " )
8994
9095 def __le__ (self , value : Any ) -> "InstrumentedExpression" :
91- return InstrumentedExpression (f"{ self ._expr } <= { json . dumps (value )} " )
96+ return InstrumentedExpression (f"{ self ._expr } <= { self . _render_value (value )} " )
9297
9398 def __ge__ (self , value : Any ) -> "InstrumentedExpression" :
94- return InstrumentedExpression (f"{ self ._expr } >= { json . dumps (value )} " )
99+ return InstrumentedExpression (f"{ self ._expr } >= { self . _render_value (value )} " )
95100
96101 def __add__ (self , value : Any ) -> "InstrumentedExpression" :
97- return InstrumentedExpression (f"{ self ._expr } + { json . dumps (value )} " )
102+ return InstrumentedExpression (f"{ self ._expr } + { self . _render_value (value )} " )
98103
99104 def __radd__ (self , value : Any ) -> "InstrumentedExpression" :
100- return InstrumentedExpression (f"{ json . dumps (value )} + { self ._expr } " )
105+ return InstrumentedExpression (f"{ self . _render_value (value )} + { self ._expr } " )
101106
102107 def __sub__ (self , value : Any ) -> "InstrumentedExpression" :
103- return InstrumentedExpression (f"{ self ._expr } - { json . dumps (value )} " )
108+ return InstrumentedExpression (f"{ self ._expr } - { self . _render_value (value )} " )
104109
105110 def __rsub__ (self , value : Any ) -> "InstrumentedExpression" :
106- return InstrumentedExpression (f"{ json . dumps (value )} - { self ._expr } " )
111+ return InstrumentedExpression (f"{ self . _render_value (value )} - { self ._expr } " )
107112
108113 def __mul__ (self , value : Any ) -> "InstrumentedExpression" :
109- return InstrumentedExpression (f"{ self ._expr } * { json . dumps (value )} " )
114+ return InstrumentedExpression (f"{ self ._expr } * { self . _render_value (value )} " )
110115
111116 def __rmul__ (self , value : Any ) -> "InstrumentedExpression" :
112- return InstrumentedExpression (f"{ json . dumps (value )} * { self ._expr } " )
117+ return InstrumentedExpression (f"{ self . _render_value (value )} * { self ._expr } " )
113118
114119 def __truediv__ (self , value : Any ) -> "InstrumentedExpression" :
115- return InstrumentedExpression (f"{ self ._expr } / { json . dumps (value )} " )
120+ return InstrumentedExpression (f"{ self ._expr } / { self . _render_value (value )} " )
116121
117122 def __rtruediv__ (self , value : Any ) -> "InstrumentedExpression" :
118- return InstrumentedExpression (f"{ json . dumps (value )} / { self ._expr } " )
123+ return InstrumentedExpression (f"{ self . _render_value (value )} / { self ._expr } " )
119124
120125 def __mod__ (self , value : Any ) -> "InstrumentedExpression" :
121- return InstrumentedExpression (f"{ self ._expr } % { json . dumps (value )} " )
126+ return InstrumentedExpression (f"{ self ._expr } % { self . _render_value (value )} " )
122127
123128 def __rmod__ (self , value : Any ) -> "InstrumentedExpression" :
124- return InstrumentedExpression (f"{ json .dumps (value )} % { self ._expr } " )
129+ return InstrumentedExpression (f"{ self ._render_value (value )} % { self ._expr } " )
130+
131+ def is_null (self ) -> "InstrumentedExpression" :
132+ """Compare the expression against NULL."""
133+ return InstrumentedExpression (f"{ self ._expr } IS NULL" )
134+
135+ def is_not_null (self ) -> "InstrumentedExpression" :
136+ """Compare the expression against NOT NULL."""
137+ return InstrumentedExpression (f"{ self ._expr } IS NOT NULL" )
138+
139+ def in_ (self , * values : Any ) -> "InstrumentedExpression" :
140+ """Test if the expression equals one of the given values."""
141+ rendered_values = ", " .join ([f"{ value } " for value in values ])
142+ return InstrumentedExpression (f"{ self ._expr } IN ({ rendered_values } )" )
143+
144+ def like (self , * patterns : str ) -> "InstrumentedExpression" :
145+ """Filter the expression using a string pattern."""
146+ if len (patterns ) == 1 :
147+ return InstrumentedExpression (
148+ f"{ self ._expr } LIKE { self ._render_value (patterns [0 ])} "
149+ )
150+ else :
151+ return InstrumentedExpression (
152+ f'{ self ._expr } LIKE ({ ", " .join ([self ._render_value (p ) for p in patterns ])} )'
153+ )
154+
155+ def rlike (self , * patterns : str ) -> "InstrumentedExpression" :
156+ """Filter the expression using a regular expression."""
157+ if len (patterns ) == 1 :
158+ return InstrumentedExpression (
159+ f"{ self ._expr } RLIKE { self ._render_value (patterns [0 ])} "
160+ )
161+ else :
162+ return InstrumentedExpression (
163+ f'{ self ._expr } RLIKE ({ ", " .join ([self ._render_value (p ) for p in patterns ])} )'
164+ )
165+
166+ def match (self , query : str ) -> "InstrumentedExpression" :
167+ """Perform a match query on the field."""
168+ return InstrumentedExpression (f"{ self ._expr } :{ self ._render_value (query )} " )
169+
170+ def asc (self ) -> "InstrumentedExpression" :
171+ """Return the field name representation for ascending sort order.
172+
173+ For use in ES|QL queries only.
174+ """
175+ return InstrumentedExpression (f"{ self ._expr } ASC" )
176+
177+ def desc (self ) -> "InstrumentedExpression" :
178+ """Return the field name representation for descending sort order.
179+
180+ For use in ES|QL queries only.
181+ """
182+ return InstrumentedExpression (f"{ self ._expr } DESC" )
183+
184+ def nulls_first (self ) -> "InstrumentedExpression" :
185+ """Return the field name representation for nulls first sort order.
186+
187+ For use in ES|QL queries only.
188+ """
189+ return InstrumentedExpression (f"{ self ._expr } NULLS FIRST" )
190+
191+ def nulls_last (self ) -> "InstrumentedExpression" :
192+ """Return the field name representation for nulls last sort order.
193+
194+ For use in ES|QL queries only.
195+ """
196+ return InstrumentedExpression (f"{ self ._expr } NULLS LAST" )
125197
126198 def where (
127- self , expr : Union [str , "InstrumentedExpression" ]
199+ self , * expressions : Union [str , "InstrumentedExpression" ]
128200 ) -> "InstrumentedExpression" :
129201 """Add a condition to be met for the row to be included.
130202
131203 Use only in expressions given in the ``STATS`` command.
132204 """
133- return InstrumentedExpression (f"{ self ._expr } WHERE { expr } " )
205+ if len (expressions ) == 1 :
206+ return InstrumentedExpression (f"{ self ._expr } WHERE { expressions [0 ]} " )
207+ else :
208+ return InstrumentedExpression (
209+ f'{ self ._expr } WHERE { " AND " .join ([f"({ expr } )" for expr in expressions ])} '
210+ )
211+
212+
213+ E = InstrumentedExpression
134214
135215
136216class InstrumentedField (InstrumentedExpression ):
@@ -178,34 +258,6 @@ def __neg__(self) -> str: # type: ignore[override]
178258 """Return the field name representation for descending sort order"""
179259 return f"-{ self ._expr } "
180260
181- def asc (self ) -> "InstrumentedField" :
182- """Return the field name representation for ascending sort order.
183-
184- For use in ES|QL queries only.
185- """
186- return InstrumentedField (f"{ self ._expr } ASC" , None )
187-
188- def desc (self ) -> "InstrumentedField" :
189- """Return the field name representation for descending sort order.
190-
191- For use in ES|QL queries only.
192- """
193- return InstrumentedField (f"{ self ._expr } DESC" , None )
194-
195- def nulls_first (self ) -> "InstrumentedField" :
196- """Return the field name representation for nulls first sort order.
197-
198- For use in ES|QL queries only.
199- """
200- return InstrumentedField (f"{ self ._expr } NULLS FIRST" , None )
201-
202- def nulls_last (self ) -> "InstrumentedField" :
203- """Return the field name representation for nulls last sort order.
204-
205- For use in ES|QL queries only.
206- """
207- return InstrumentedField (f"{ self ._expr } NULLS LAST" , None )
208-
209261 def __str__ (self ) -> str :
210262 return self ._expr
211263
0 commit comments