MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / fold_cast

Function fold_cast

nodedb-sql/src/planner/const_fold.rs:73–151  ·  view source on GitHub ↗

Fold a CAST at plan time. Only applies when the inner expression is already a constant. The `to_type` string comes from sqlparser's `format!("{data_type}")` output, so parameterised types like `NUMERIC(5,1)` must be matched by prefix.

(inner: SqlValue, to_type: &str)

Source from the content-addressed store, hash-verified

71/// a constant. The `to_type` string comes from sqlparser's `format!("{data_type}")`
72/// output, so parameterised types like `NUMERIC(5,1)` must be matched by prefix.
73fn fold_cast(inner: SqlValue, to_type: &str) -> Option<SqlValue> {
74 let upper = to_type.to_uppercase();
75 // Strip any precision/scale suffix: "NUMERIC(5,1)""NUMERIC".
76 let base = upper
77 .split('(')
78 .next()
79 .map(str::trim)
80 .unwrap_or(upper.as_str());
81
82 match base {
83 "NUMERIC" | "DECIMAL" => match inner {
84 SqlValue::Decimal(d) => Some(SqlValue::Decimal(d)),
85 SqlValue::Int(i) => Some(SqlValue::Decimal(rust_decimal::Decimal::from(i))),
86 SqlValue::Float(f) => rust_decimal::Decimal::try_from(f)
87 .ok()
88 .map(SqlValue::Decimal),
89 SqlValue::String(s) => rust_decimal::Decimal::from_str_exact(&s)
90 .ok()
91 .map(SqlValue::Decimal),
92 _ => None,
93 },
94 "INTEGER" | "INT" | "BIGINT" | "SMALLINT" | "INT2" | "INT4" | "INT8" => match inner {
95 SqlValue::Int(i) => Some(SqlValue::Int(i)),
96 SqlValue::Decimal(d) => {
97 rust_decimal::prelude::ToPrimitive::to_i64(&d).map(SqlValue::Int)
98 }
99 SqlValue::Float(f) => {
100 if f.is_finite() {
101 Some(SqlValue::Int(f as i64))
102 } else {
103 None
104 }
105 }
106 SqlValue::String(s) => s.parse::<i64>().ok().map(SqlValue::Int),
107 _ => None,
108 },
109 "FLOAT" | "DOUBLE" | "REAL" | "FLOAT4" | "FLOAT8" | "DOUBLE PRECISION" => match inner {
110 SqlValue::Float(f) => Some(SqlValue::Float(f)),
111 SqlValue::Int(i) => Some(SqlValue::Float(i as f64)),
112 SqlValue::Decimal(d) => {
113 rust_decimal::prelude::ToPrimitive::to_f64(&d).map(SqlValue::Float)
114 }
115 SqlValue::String(s) => s.parse::<f64>().ok().map(SqlValue::Float),
116 _ => None,
117 },
118 "TEXT" | "VARCHAR" | "CHAR" | "CHARACTER VARYING" | "CHARACTER" | "BPCHAR" => match inner {
119 SqlValue::String(s) => Some(SqlValue::String(s)),
120 SqlValue::Int(i) => Some(SqlValue::String(i.to_string())),
121 SqlValue::Float(f) => Some(SqlValue::String(f.to_string())),
122 SqlValue::Decimal(d) => Some(SqlValue::String(d.to_string())),
123 SqlValue::Bool(b) => Some(SqlValue::String(b.to_string())),
124 _ => None,
125 },
126 "BOOL" | "BOOLEAN" => match inner {
127 SqlValue::Bool(b) => Some(SqlValue::Bool(b)),
128 SqlValue::Int(i) => Some(SqlValue::Bool(i != 0)),
129 SqlValue::String(s) => match s.to_lowercase().as_str() {
130 "true" | "t" | "yes" | "1" | "on" => Some(SqlValue::Bool(true)),

Callers 1

fold_constantFunction · 0.85

Calls 5

to_f64Function · 0.85
to_stringMethod · 0.80
nextMethod · 0.45
as_strMethod · 0.45
okMethod · 0.45

Tested by

no test coverage detected