// Port of sqlglot/typing/spark2.py.
///|
/// Type inference for CONCAT-family expressions (CONCAT, LPAD, RPAD).
///
/// - All-BINARY -> BINARY (the binary overload).
/// - Otherwise, if any arg has a known, non-array, non-binary type -> STRING.
/// - Else -> UNKNOWN.
fn spark2_annotate_by_similar_args(
s : TypeAnnotator,
expression : @core.Expr,
arg_keys : Array[String],
) -> Unit {
let arg_exprs : Array[@core.Expr] = []
for key in arg_keys {
match expression.get(key) {
Some(Node(e)) => arg_exprs.push(e)
Some(List(_)) =>
for e in expression.list(key) {
arg_exprs.push(e)
}
_ => ()
}
}
let result : @core.DType = if !arg_exprs.is_empty() &&
arg_exprs.iter().all(e => e.is_type([BINARY])) {
BINARY
} else if arg_exprs
.iter()
.any(e => e.get_type() is Some(_) && !e.is_type([UNKNOWN, ARRAY, BINARY])) {
TEXT
} else {
UNKNOWN
}
s.set_dtype(expression, result)
}
///|
/// Python `sqlglot.typing.spark2.EXPRESSION_METADATA`.
fn spark2_expression_metadata() -> ExprMetadata {
let m = extend_metadata(hive_expression_metadata())
returns_all(m, [Atan2, Randn], DOUBLE)
returns_all(m, [Format, Right], VARCHAR)
annotate_all(m, [ArrayFilter, Shuffle, Substring], (s, e) => {
s.annotate_by_args(e, [Key("this")])
})
returns_all(m, [Nanvl], DOUBLE)
m[AddMonths] = Returns(D(DATE))
m[ApproxQuantile] = Annotator((s, e) => {
s.annotate_by_args(
e,
[Key("this")],
array=opt_is_type(e.arg("quantile"), [ARRAY]),
)
})
m[AtTimeZone] = Returns(D(TIMESTAMP))
m[Concat] = Annotator((s, e) => {
spark2_annotate_by_similar_args(s, e, ["expressions"])
})
m[NextDay] = Returns(D(DATE))
m[Pad] = Annotator((s, e) => {
spark2_annotate_by_similar_args(s, e, ["this", "fill_pattern"])
})
m
}