Edit on GitHub

sqlglot.typing.bigquery

  1from __future__ import annotations
  2
  3import typing as t
  4
  5from sqlglot import exp
  6from sqlglot.typing import EXPRESSION_METADATA, TIMESTAMP_EXPRESSIONS
  7
  8if t.TYPE_CHECKING:
  9    from sqlglot.optimizer.annotate_types import TypeAnnotator
 10
 11
 12def _annotate_math_functions(self: TypeAnnotator, expression: exp.Expression) -> exp.Expression:
 13    """
 14    Many BigQuery math functions such as CEIL, FLOOR etc follow this return type convention:
 15    +---------+---------+---------+------------+---------+
 16    |  INPUT  | INT64   | NUMERIC | BIGNUMERIC | FLOAT64 |
 17    +---------+---------+---------+------------+---------+
 18    |  OUTPUT | FLOAT64 | NUMERIC | BIGNUMERIC | FLOAT64 |
 19    +---------+---------+---------+------------+---------+
 20    """
 21    this: exp.Expression = expression.this
 22
 23    self._set_type(
 24        expression,
 25        exp.DataType.Type.DOUBLE if this.is_type(*exp.DataType.INTEGER_TYPES) else this.type,
 26    )
 27    return expression
 28
 29
 30def _annotate_safe_divide(self: TypeAnnotator, expression: exp.SafeDivide) -> exp.Expression:
 31    """
 32    +------------+------------+------------+-------------+---------+
 33    | INPUT      | INT64      | NUMERIC    | BIGNUMERIC  | FLOAT64 |
 34    +------------+------------+------------+-------------+---------+
 35    | INT64      | FLOAT64    | NUMERIC    | BIGNUMERIC  | FLOAT64 |
 36    | NUMERIC    | NUMERIC    | NUMERIC    | BIGNUMERIC  | FLOAT64 |
 37    | BIGNUMERIC | BIGNUMERIC | BIGNUMERIC | BIGNUMERIC  | FLOAT64 |
 38    | FLOAT64    | FLOAT64    | FLOAT64    | FLOAT64     | FLOAT64 |
 39    +------------+------------+------------+-------------+---------+
 40    """
 41    if expression.this.is_type(*exp.DataType.INTEGER_TYPES) and expression.expression.is_type(
 42        *exp.DataType.INTEGER_TYPES
 43    ):
 44        return self._set_type(expression, exp.DataType.Type.DOUBLE)
 45
 46    return _annotate_by_args_with_coerce(self, expression)
 47
 48
 49def _annotate_by_args_with_coerce(
 50    self: TypeAnnotator, expression: exp.Expression
 51) -> exp.Expression:
 52    """
 53    +------------+------------+------------+-------------+---------+
 54    | INPUT      | INT64      | NUMERIC    | BIGNUMERIC  | FLOAT64 |
 55    +------------+------------+------------+-------------+---------+
 56    | INT64      | INT64      | NUMERIC    | BIGNUMERIC  | FLOAT64 |
 57    | NUMERIC    | NUMERIC    | NUMERIC    | BIGNUMERIC  | FLOAT64 |
 58    | BIGNUMERIC | BIGNUMERIC | BIGNUMERIC | BIGNUMERIC  | FLOAT64 |
 59    | FLOAT64    | FLOAT64    | FLOAT64    | FLOAT64     | FLOAT64 |
 60    +------------+------------+------------+-------------+---------+
 61    """
 62    self._set_type(expression, self._maybe_coerce(expression.this.type, expression.expression.type))
 63    return expression
 64
 65
 66def _annotate_by_args_approx_top(self: TypeAnnotator, expression: exp.ApproxTopK) -> exp.ApproxTopK:
 67    struct_type = exp.DataType(
 68        this=exp.DataType.Type.STRUCT,
 69        expressions=[expression.this.type, exp.DataType(this=exp.DataType.Type.BIGINT)],
 70        nested=True,
 71    )
 72    self._set_type(
 73        expression,
 74        exp.DataType(this=exp.DataType.Type.ARRAY, expressions=[struct_type], nested=True),
 75    )
 76
 77    return expression
 78
 79
 80def _annotate_concat(self: TypeAnnotator, expression: exp.Concat) -> exp.Concat:
 81    annotated = self._annotate_by_args(expression, "expressions")
 82
 83    # Args must be BYTES or types that can be cast to STRING, return type is either BYTES or STRING
 84    # https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#concat
 85    if not annotated.is_type(exp.DataType.Type.BINARY, exp.DataType.Type.UNKNOWN):
 86        self._set_type(annotated, exp.DataType.Type.VARCHAR)
 87
 88    return annotated
 89
 90
 91def _annotate_array(self: TypeAnnotator, expression: exp.Array) -> exp.Array:
 92    array_args = expression.expressions
 93
 94    # BigQuery behaves as follows:
 95    #
 96    # SELECT t, TYPEOF(t) FROM (SELECT 'foo') AS t            -- foo, STRUCT<STRING>
 97    # SELECT ARRAY(SELECT 'foo'), TYPEOF(ARRAY(SELECT 'foo')) -- foo, ARRAY<STRING>
 98    # ARRAY(SELECT ... UNION ALL SELECT ...) -- ARRAY<type from coerced projections>
 99    if len(array_args) == 1:
100        unnested = array_args[0].unnest()
101        projection_type: t.Optional[exp.DataType | exp.DataType.Type] = None
102
103        # Handle ARRAY(SELECT ...) - single SELECT query
104        if isinstance(unnested, exp.Select):
105            if (
106                (query_type := unnested.meta.get("query_type")) is not None
107                and query_type.is_type(exp.DataType.Type.STRUCT)
108                and len(query_type.expressions) == 1
109                and isinstance(col_def := query_type.expressions[0], exp.ColumnDef)
110                and (col_type := col_def.kind) is not None
111                and not col_type.is_type(exp.DataType.Type.UNKNOWN)
112            ):
113                projection_type = col_type
114
115        # Handle ARRAY(SELECT ... UNION ALL SELECT ...) - set operations
116        elif isinstance(unnested, exp.SetOperation):
117            # Get all column types for the SetOperation
118            col_types = self._get_setop_column_types(unnested)
119            # For ARRAY constructor, there should only be one projection
120            # https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#array
121            if col_types and unnested.left.selects:
122                first_col_name = unnested.left.selects[0].alias_or_name
123                projection_type = col_types.get(first_col_name)
124
125        # If we successfully determine a projection type and it's not UNKNOWN, wrap it in ARRAY
126        if projection_type and not (
127            (
128                isinstance(projection_type, exp.DataType)
129                and projection_type.is_type(exp.DataType.Type.UNKNOWN)
130            )
131            or projection_type == exp.DataType.Type.UNKNOWN
132        ):
133            element_type = (
134                projection_type.copy()
135                if isinstance(projection_type, exp.DataType)
136                else exp.DataType(this=projection_type)
137            )
138            array_type = exp.DataType(
139                this=exp.DataType.Type.ARRAY,
140                expressions=[element_type],
141                nested=True,
142            )
143            return self._set_type(expression, array_type)
144
145    return self._annotate_by_args(expression, "expressions", array=True)
146
147
148EXPRESSION_METADATA = {
149    **EXPRESSION_METADATA,
150    **{
151        expr_type: {"annotator": lambda self, e: _annotate_math_functions(self, e)}
152        for expr_type in {
153            exp.Avg,
154            exp.Ceil,
155            exp.Exp,
156            exp.Floor,
157            exp.Ln,
158            exp.Log,
159            exp.Round,
160            exp.Sqrt,
161        }
162    },
163    **{
164        expr_type: {"annotator": lambda self, e: self._annotate_by_args(e, "this")}
165        for expr_type in {
166            exp.Abs,
167            exp.ArgMax,
168            exp.ArgMin,
169            exp.DateTrunc,
170            exp.DatetimeTrunc,
171            exp.FirstValue,
172            exp.GroupConcat,
173            exp.IgnoreNulls,
174            exp.JSONExtract,
175            exp.Lead,
176            exp.Left,
177            exp.Lower,
178            exp.NthValue,
179            exp.Pad,
180            exp.PercentileDisc,
181            exp.RegexpExtract,
182            exp.RegexpReplace,
183            exp.Repeat,
184            exp.Replace,
185            exp.RespectNulls,
186            exp.Reverse,
187            exp.Right,
188            exp.SafeNegate,
189            exp.Sign,
190            exp.Substring,
191            exp.TimestampTrunc,
192            exp.Translate,
193            exp.Trim,
194            exp.Upper,
195        }
196    },
197    **{
198        expr_type: {"returns": exp.DataType.Type.BIGINT}
199        for expr_type in {
200            exp.Ascii,
201            exp.BitwiseAndAgg,
202            exp.BitwiseCount,
203            exp.BitwiseOrAgg,
204            exp.BitwiseXorAgg,
205            exp.ByteLength,
206            exp.DenseRank,
207            exp.FarmFingerprint,
208            exp.Grouping,
209            exp.LaxInt64,
210            exp.Length,
211            exp.Ntile,
212            exp.Rank,
213            exp.RangeBucket,
214            exp.RegexpInstr,
215            exp.RowNumber,
216            exp.Unicode,
217        }
218    },
219    **{
220        expr_type: {"returns": exp.DataType.Type.BINARY}
221        for expr_type in {
222            exp.ByteString,
223            exp.CodePointsToBytes,
224            exp.MD5Digest,
225            exp.SHA,
226            exp.SHA2,
227            exp.SHA1Digest,
228            exp.SHA2Digest,
229            exp.Unhex,
230        }
231    },
232    **{
233        expr_type: {"returns": exp.DataType.Type.BOOLEAN}
234        for expr_type in {
235            exp.IsInf,
236            exp.IsNan,
237            exp.JSONBool,
238            exp.LaxBool,
239        }
240    },
241    **{
242        expr_type: {"returns": exp.DataType.Type.DATETIME}
243        for expr_type in {
244            exp.ParseDatetime,
245            exp.TimestampFromParts,
246        }
247    },
248    **{
249        expr_type: {"returns": exp.DataType.Type.DOUBLE}
250        for expr_type in {
251            exp.Acos,
252            exp.Acosh,
253            exp.Asin,
254            exp.Asinh,
255            exp.Atan,
256            exp.Atan2,
257            exp.Atanh,
258            exp.Cbrt,
259            exp.Corr,
260            exp.CosineDistance,
261            exp.Cot,
262            exp.Coth,
263            exp.CovarPop,
264            exp.CovarSamp,
265            exp.Csc,
266            exp.Csch,
267            exp.CumeDist,
268            exp.EuclideanDistance,
269            exp.Float64,
270            exp.LaxFloat64,
271            exp.PercentRank,
272            exp.Rand,
273            exp.Sec,
274            exp.Sech,
275            exp.Sin,
276            exp.Sinh,
277        }
278    },
279    **{
280        expr_type: {"returns": exp.DataType.Type.JSON}
281        for expr_type in {
282            exp.JSONArray,
283            exp.JSONArrayAppend,
284            exp.JSONArrayInsert,
285            exp.JSONObject,
286            exp.JSONRemove,
287            exp.JSONSet,
288            exp.JSONStripNulls,
289        }
290    },
291    **{
292        expr_type: {"returns": exp.DataType.Type.TIME}
293        for expr_type in {
294            exp.ParseTime,
295            exp.TimeFromParts,
296            exp.TimeTrunc,
297            exp.TsOrDsToTime,
298        }
299    },
300    **{
301        expr_type: {"returns": exp.DataType.Type.VARCHAR}
302        for expr_type in {
303            exp.CodePointsToString,
304            exp.Format,
305            exp.JSONExtractScalar,
306            exp.JSONType,
307            exp.LaxString,
308            exp.LowerHex,
309            exp.MD5,
310            exp.NetHost,
311            exp.Normalize,
312            exp.SafeConvertBytesToString,
313            exp.Soundex,
314            exp.Uuid,
315        }
316    },
317    **{
318        expr_type: {"annotator": lambda self, e: _annotate_by_args_with_coerce(self, e)}
319        for expr_type in {
320            exp.PercentileCont,
321            exp.SafeAdd,
322            exp.SafeDivide,
323            exp.SafeMultiply,
324            exp.SafeSubtract,
325        }
326    },
327    **{
328        expr_type: {"annotator": lambda self, e: self._annotate_by_args(e, "this", array=True)}
329        for expr_type in {
330            exp.ApproxQuantiles,
331            exp.JSONExtractArray,
332            exp.RegexpExtractAll,
333            exp.Split,
334        }
335    },
336    **{
337        expr_type: {"returns": exp.DataType.Type.TIMESTAMPTZ} for expr_type in TIMESTAMP_EXPRESSIONS
338    },
339    exp.ApproxTopK: {"annotator": lambda self, e: _annotate_by_args_approx_top(self, e)},
340    exp.ApproxTopSum: {"annotator": lambda self, e: _annotate_by_args_approx_top(self, e)},
341    exp.Array: {"annotator": _annotate_array},
342    exp.ArrayConcat: {
343        "annotator": lambda self, e: self._annotate_by_args(e, "this", "expressions")
344    },
345    exp.Concat: {"annotator": _annotate_concat},
346    exp.DateFromUnixDate: {"returns": exp.DataType.Type.DATE},
347    exp.GenerateTimestampArray: {
348        "annotator": lambda self, e: self._set_type(
349            e, exp.DataType.build("ARRAY<TIMESTAMP>", dialect="bigquery")
350        )
351    },
352    exp.JSONFormat: {
353        "annotator": lambda self, e: self._set_type(
354            e, exp.DataType.Type.JSON if e.args.get("to_json") else exp.DataType.Type.VARCHAR
355        )
356    },
357    exp.JSONKeysAtDepth: {
358        "annotator": lambda self, e: self._set_type(
359            e, exp.DataType.build("ARRAY<VARCHAR>", dialect="bigquery")
360        )
361    },
362    exp.JSONValueArray: {
363        "annotator": lambda self, e: self._set_type(
364            e, exp.DataType.build("ARRAY<VARCHAR>", dialect="bigquery")
365        )
366    },
367    exp.Lag: {"annotator": lambda self, e: self._annotate_by_args(e, "this", "default")},
368    exp.ParseBignumeric: {"returns": exp.DataType.Type.BIGDECIMAL},
369    exp.ParseNumeric: {"returns": exp.DataType.Type.DECIMAL},
370    exp.SafeDivide: {"annotator": lambda self, e: _annotate_safe_divide(self, e)},
371    exp.ToCodePoints: {
372        "annotator": lambda self, e: self._set_type(
373            e, exp.DataType.build("ARRAY<BIGINT>", dialect="bigquery")
374        )
375    },
376}
EXPRESSION_METADATA = {<class 'sqlglot.expressions.Add'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Adjacent'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.And'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayContainsAll'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayOverlaps'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Binary'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseAnd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseLeftShift'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseOr'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseRightShift'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseXor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Collate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Connector'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Corr'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.DPipe'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Distance'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Div'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Dot'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.EQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Escape'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ExtendsLeft'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ExtendsRight'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.GT'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.GTE'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Glob'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ILike'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.IntDiv'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Is'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONArrayContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBContainsAllTopKeys'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBContainsAnyTopKeys'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBDeleteAtPath'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBExtractScalar'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONExtractScalar'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Kwarg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.LT'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.LTE'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Like'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Match'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Mod'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Mul'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.NEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.NullSafeEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.NullSafeNEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Operator'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Or'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Overlaps'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Pow'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.PropertyEQ'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.RegexpFullMatch'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RegexpILike'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RegexpLike'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.SimilarTo'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Sub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Xor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Alias'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseNot'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Neg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Not'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Paren'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.PivotAlias'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Unary'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ApproxDistinct'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixMicros'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.Length'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixSeconds'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixDate'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.CountIf'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.ArraySize'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.Int64'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixMillis'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.FromBase32'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.FromBase64'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.EndsWith'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Exists'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Any'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.StartsWith'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.In'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LogicalAnd'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LogicalOr'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Between'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.All'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Boolean'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Contains'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.DateFromParts'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.TimeStrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.TsOrDsToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.Date'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.CurrentDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.StrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DateStrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.LastDay'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DiToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.Datetime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.DatetimeSub'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.DatetimeAdd'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.CurrentDatetime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.Round'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.StddevSamp'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Stddev'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.ApproxQuantile'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Skewness'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.ToDouble'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Ln'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.VariancePop'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Pi'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Radians'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Avg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Exp'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.StddevPop'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sqrt'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.SafeDivide'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Quantile'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Log'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Variance'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sign'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.TimeDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Ceil'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Unicode'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.DateToDi'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Ascii'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.StrPosition'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TsOrDiToDi'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Levenshtein'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DatetimeDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TimestampDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.JustifyInterval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.JustifyHours'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.JustifyDays'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.Interval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.MakeInterval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.ParseJSON'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.Localtime'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.CurrentTime'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimeSub'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimeAdd'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.Time'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimestampLtzFromParts'>: {'returns': <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <class 'sqlglot.expressions.CurrentTimestampLTZ'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimestampTzFromParts'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimeStrToTime'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimestampSub'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.UnixToTime'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.StrToTime'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimestampAdd'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.CurrentTimestamp'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.Month'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfWeekIso'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Week'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Year'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfWeek'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.YearOfWeekIso'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Day'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.YearOfWeek'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.WeekOfYear'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfYear'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Quarter'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfMonth'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.UnixToStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.TimeToStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ToBase32'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Concat'>: {'annotator': <function _annotate_concat>}, <class 'sqlglot.expressions.Lower'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.TsOrDsToDateStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.GroupConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Upper'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.TimeToTimeStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ToBase64'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ConcatWs'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Chr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Initcap'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.String'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.UnixToTimeStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.RawString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Substring'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DateToDateStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Trim'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayToString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ArrayReverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.SortArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Order'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.AnyValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Window'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Filter'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.LastValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.HavingMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Abs'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArraySlice'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Limit'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayConcatAgg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayConcat'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Max'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Min'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Coalesce'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Greatest'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Least'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayFirst'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayLast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Anonymous'>: {'returns': <Type.UNKNOWN: 'UNKNOWN'>}, <class 'sqlglot.expressions.Slice'>: {'returns': <Type.UNKNOWN: 'UNKNOWN'>}, <class 'sqlglot.expressions.DateSub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DateAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DateTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Cast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.TryCast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.VarMap'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Map'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Array'>: {'annotator': <function _annotate_array>}, <class 'sqlglot.expressions.ArrayAgg'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Bracket'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Case'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Count'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.DateDiff'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.DataType'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Distinct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Explode'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Extract'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.HexString'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.GenerateSeries'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.GenerateDateArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.GenerateTimestampArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.If'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Literal'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Null'>: {'returns': <Type.NULL: 'NULL'>}, <class 'sqlglot.expressions.Nullif'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Struct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Sum'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Timestamp'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.ToMap'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Unnest'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Subquery'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Floor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Lead'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Reverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Replace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Left'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArgMin'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.NthValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RegexpReplace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.FirstValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RegexpExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RespectNulls'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Pad'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Translate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Right'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Repeat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.TimestampTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.SafeNegate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DatetimeTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArgMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.PercentileDisc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.IgnoreNulls'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.FarmFingerprint'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.RowNumber'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.Rank'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.BitwiseCount'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.RangeBucket'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.LaxInt64'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.BitwiseXorAgg'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.ByteLength'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.Ntile'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.BitwiseOrAgg'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.BitwiseAndAgg'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.Grouping'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.DenseRank'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.RegexpInstr'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.CodePointsToBytes'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.SHA2Digest'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.SHA1Digest'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.ByteString'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.SHA2'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.Unhex'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.SHA'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.MD5Digest'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.JSONBool'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.IsNan'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.IsInf'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LaxBool'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.ParseDatetime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.TimestampFromParts'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.Atanh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cbrt'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.CosineDistance'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Asinh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Acosh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Rand'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sin'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sec'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.CovarSamp'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.LaxFloat64'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Csc'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.PercentRank'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Coth'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Atan2'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.CumeDist'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.EuclideanDistance'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Atan'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Asin'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Acos'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sinh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sech'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.CovarPop'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Csch'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Float64'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cot'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.JSONStripNulls'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.JSONObject'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.JSONSet'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.JSONRemove'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.JSONArrayInsert'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.JSONArray'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.JSONArrayAppend'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.TsOrDsToTime'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimeFromParts'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.ParseTime'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimeTrunc'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.Soundex'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.LowerHex'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.NetHost'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.LaxString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.JSONType'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Normalize'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.CodePointsToString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Format'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Uuid'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.SafeConvertBytesToString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.MD5'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.SafeSubtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.SafeMultiply'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.PercentileCont'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.SafeAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Split'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONExtractArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ApproxQuantiles'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RegexpExtractAll'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ApproxTopK'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.ApproxTopSum'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.DateFromUnixDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.JSONFormat'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.JSONKeysAtDepth'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.JSONValueArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Lag'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.ParseBignumeric'>: {'returns': <Type.BIGDECIMAL: 'BIGDECIMAL'>}, <class 'sqlglot.expressions.ParseNumeric'>: {'returns': <Type.DECIMAL: 'DECIMAL'>}, <class 'sqlglot.expressions.ToCodePoints'>: {'annotator': <function <lambda>>}}