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