// Port of sqlglot/typing/mysql.py.
///|
let mysql_compress_longblob_types : Array[@core.DType] = [
TEXT,
MEDIUMTEXT,
LONGTEXT,
BLOB,
MEDIUMBLOB,
LONGBLOB,
JSON,
]
///|
let mysql_compress_varbinary_types : Array[@core.DType] = [
CHAR,
VARCHAR,
BINARY,
VARBINARY,
TINYBLOB,
ENUM,
INT,
BIGINT,
DECIMAL,
DOUBLE,
DATE,
DATETIME,
]
///|
fn mysql_annotate_reverse(s : TypeAnnotator, expression : @core.Expr) -> Unit {
if opt_is_type(expression.this(), [BINARY, VARBINARY, UNKNOWN]) {
s.annotate_by_args(expression, [Key("this")])
} else {
s.set_dtype(expression, VARCHAR)
}
}
///|
fn mysql_annotate_truncate(s : TypeAnnotator, expression : @core.Expr) -> Unit {
if opt_is_type(expression.this(), @core.dtype_text_types) {
s.set_dtype(expression, DOUBLE)
} else {
s.annotate_by_args(expression, [Key("this")])
}
}
///|
fn mysql_annotate_regexp_replace(
s : TypeAnnotator,
expression : @core.Expr,
) -> Unit {
let args = [
expression.this(),
expression.expression(),
expression.arg("replacement"),
]
let mut has_binary = false
for arg in args {
match arg {
Some(a) => {
if a.is_type([UNKNOWN]) {
s.set_dtype(expression, UNKNOWN)
return
}
has_binary = has_binary || a.is_type(@core.dtype_binary_types)
}
None => ()
}
}
s.set_dtype(expression, if has_binary { LONGBLOB } else { LONGTEXT })
}
///|
fn mysql_annotate_compress(s : TypeAnnotator, expression : @core.Expr) -> Unit {
let this = expression.this()
if opt_is_type(this, mysql_compress_varbinary_types) {
s.set_dtype(expression, VARBINARY)
} else if opt_is_type(this, mysql_compress_longblob_types) {
s.set_dtype(expression, LONGBLOB)
} else if opt_is_type(this, [TINYTEXT]) {
s.set_dtype(expression, BLOB)
} else {
s.set_dtype(expression, UNKNOWN)
}
}
///|
fn mysql_annotate_bit_func(s : TypeAnnotator, expression : @core.Expr) -> Unit {
let this = expression.this()
if opt_is_type(this, [UNKNOWN]) {
s.set_dtype(expression, UNKNOWN)
} else if opt_is_type(this, @core.dtype_binary_types) {
s.set_dtype(expression, VARBINARY)
} else {
s.set_dtype(expression, UBIGINT)
}
}
///|
/// Python `sqlglot.typing.mysql.EXPRESSION_METADATA`.
fn mysql_expression_metadata() -> ExprMetadata {
let m = extend_metadata(base_expression_metadata)
returns_all(m, [Atan2, MatchAgainst, StDistance], DOUBLE)
returns_all(
m,
[CurrentTimestamp, ConvertTimezone, Localtime, Localtimestamp, UtcTimestamp],
DATETIME,
)
returns_all(m, [UtcDate], DATE)
returns_all(
m,
[
Elt,
Hex,
NumberToStr,
Replace,
Stuff,
SubstringIndex,
RegexpSubstr,
Collation,
JSONType,
Uuid,
],
VARCHAR,
)
returns_all(m, [Month, Second, Week, Minute], INT)
returns_all(m, [RegexpInstr, Grouping], BIGINT)
returns_all(m, [TimeFromParts, UtcTime], TIME)
returns_all(m, [Unhex], VARBINARY)
returns_all(
m,
[
JSONObjectAgg,
JSONObject,
JSONExtract,
JSONKeys,
JSONArrayAppend,
JSONArrayInsert,
JSONRemove,
JSONSet,
],
JSON,
)
returns_all(m, [CurrentRole], LONGTEXT)
annotate_all(m, [Pad, Left, Right, Lead, Lag], (s, e) => {
s.annotate_by_args(e, [Key("this")])
})
annotate_all(m, [BitwiseAndAgg, BitwiseXorAgg, BitwiseOrAgg], (s, e) => {
mysql_annotate_bit_func(s, e)
})
m[Reverse] = Annotator((s, e) => mysql_annotate_reverse(s, e))
m[Trunc] = Annotator((s, e) => mysql_annotate_truncate(s, e))
m[RegexpReplace] = Annotator((s, e) => mysql_annotate_regexp_replace(s, e))
m[Compress] = Annotator((s, e) => mysql_annotate_compress(s, e))
m
}