mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-03 11:52:54 +00:00
fix: properly give placeholder types (#5760)
* fix: properly give placeholder types * chore: update sqlness
This commit is contained in:
@@ -195,6 +195,7 @@ impl MysqlInstanceShim {
|
||||
|
||||
let params = if let Some(plan) = &mut plan {
|
||||
fix_placeholder_types(plan)?;
|
||||
debug!("Plan after fix placeholder types: {:#?}", plan);
|
||||
prepared_params(
|
||||
&plan
|
||||
.get_parameter_types()
|
||||
|
||||
@@ -79,15 +79,24 @@ pub fn transform_placeholders(stmt: Statement) -> Statement {
|
||||
}
|
||||
}
|
||||
|
||||
/// Give placeholder in skip and limit `int64` data type if it is not specified
|
||||
/// Give placeholder that cast to certain type `data_type` the same data type as is cast to
|
||||
///
|
||||
/// because it seems datafusion will not give data type to placeholder if it's in limit/skip position, still unknown if this is a feature or a bug. And if a placeholder expr have no data type, datafusion will fail to extract it using `LogicalPlan::get_parameter_types`
|
||||
/// because it seems datafusion will not give data type to placeholder if it need to be cast to certain type, still unknown if this is a feature or a bug. And if a placeholder expr have no data type, datafusion will fail to extract it using `LogicalPlan::get_parameter_types`
|
||||
pub fn fix_placeholder_types(plan: &mut LogicalPlan) -> Result<()> {
|
||||
let give_placeholder_types = |mut e| {
|
||||
if let datafusion_expr::Expr::Placeholder(ph) = &mut e {
|
||||
if ph.data_type.is_none() {
|
||||
ph.data_type = Some(arrow_schema::DataType::Int64);
|
||||
Ok(Transformed::yes(e))
|
||||
let give_placeholder_types = |mut e: datafusion_expr::Expr| {
|
||||
if let datafusion_expr::Expr::Cast(cast) = &mut e {
|
||||
if let datafusion_expr::Expr::Placeholder(ph) = &mut *cast.expr {
|
||||
if ph.data_type.is_none() {
|
||||
ph.data_type = Some(cast.data_type.clone());
|
||||
common_telemetry::debug!(
|
||||
"give placeholder type {:?} to {:?}",
|
||||
cast.data_type,
|
||||
ph
|
||||
);
|
||||
Ok(Transformed::yes(e))
|
||||
} else {
|
||||
Ok(Transformed::no(e))
|
||||
}
|
||||
} else {
|
||||
Ok(Transformed::no(e))
|
||||
}
|
||||
@@ -95,26 +104,10 @@ pub fn fix_placeholder_types(plan: &mut LogicalPlan) -> Result<()> {
|
||||
Ok(Transformed::no(e))
|
||||
}
|
||||
};
|
||||
let give_placeholder_types_recursively =
|
||||
|e: datafusion_expr::Expr| e.transform(give_placeholder_types);
|
||||
*plan = std::mem::take(plan)
|
||||
.transform(|p| {
|
||||
let LogicalPlan::Limit(mut limit) = p else {
|
||||
return Ok(Transformed::no(p));
|
||||
};
|
||||
|
||||
if let Some(fetch) = &mut limit.fetch {
|
||||
*fetch = Box::new(
|
||||
std::mem::take(fetch)
|
||||
.transform(give_placeholder_types)?
|
||||
.data,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(skip) = &mut limit.skip {
|
||||
*skip = Box::new(std::mem::take(skip).transform(give_placeholder_types)?.data);
|
||||
}
|
||||
|
||||
Ok(Transformed::yes(LogicalPlan::Limit(limit)))
|
||||
})
|
||||
.transform(|p| p.map_expressions(give_placeholder_types_recursively))
|
||||
.context(DataFusionSnafu)?
|
||||
.data;
|
||||
Ok(())
|
||||
|
||||
@@ -13,16 +13,16 @@ affected_rows: 0
|
||||
-- SQLNESS PROTOCOL MYSQL
|
||||
EXECUTE stmt USING 1;
|
||||
|
||||
+----------+
|
||||
| Int64(1) |
|
||||
+----------+
|
||||
| 1 |
|
||||
+----------+
|
||||
+----+
|
||||
| $1 |
|
||||
+----+
|
||||
| 1 |
|
||||
+----+
|
||||
|
||||
-- SQLNESS PROTOCOL MYSQL
|
||||
EXECUTE stmt USING 'a';
|
||||
|
||||
Failed to parse query result, err: MySqlError { ERROR 1815 (HY000): (EngineExecuteQuery): Cast error: Cannot cast string 'a' to value of Int32 type }
|
||||
Failed to execute query, err: MySqlError { ERROR 1210 (HY000): (InvalidArguments): Invalid request parameter: Column expect type: Int32(Int32Type), actual: String(StringType) }
|
||||
|
||||
-- SQLNESS PROTOCOL MYSQL
|
||||
DEALLOCATE stmt;
|
||||
@@ -59,11 +59,11 @@ affected_rows: 0
|
||||
-- SQLNESS PROTOCOL MYSQL
|
||||
EXECUTE stmt USING 1, 'hello';
|
||||
|
||||
+----------+---------------+
|
||||
| Int64(1) | Utf8("hello") |
|
||||
+----------+---------------+
|
||||
| 1 | hello |
|
||||
+----------+---------------+
|
||||
+----+-------+
|
||||
| $1 | $2 |
|
||||
+----+-------+
|
||||
| 1 | hello |
|
||||
+----+-------+
|
||||
|
||||
-- SQLNESS PROTOCOL MYSQL
|
||||
DEALLOCATE stmt;
|
||||
|
||||
Reference in New Issue
Block a user