This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new a9d66e2b49 minor: add a datatype casting for the updated value (#7922)
a9d66e2b49 is described below
commit a9d66e2b492843c2fb335a7dfe27fed073629b09
Author: Jonah Gao <[email protected]>
AuthorDate: Fri Oct 27 03:14:19 2023 +0800
minor: add a datatype casting for the updated value (#7922)
* minor: cast the updated value to the data type of target column
* Update datafusion/sqllogictest/test_files/update.slt
Co-authored-by: Alex Huang <[email protected]>
* Update datafusion/sqllogictest/test_files/update.slt
Co-authored-by: Alex Huang <[email protected]>
* Update datafusion/sqllogictest/test_files/update.slt
Co-authored-by: Alex Huang <[email protected]>
* fix tests
---------
Co-authored-by: Alex Huang <[email protected]>
---
datafusion/sql/src/statement.rs | 41 +++++++++++--------------
datafusion/sqllogictest/test_files/update.slt | 43 +++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 23 deletions(-)
diff --git a/datafusion/sql/src/statement.rs b/datafusion/sql/src/statement.rs
index f8504a487a..b5196c0866 100644
--- a/datafusion/sql/src/statement.rs
+++ b/datafusion/sql/src/statement.rs
@@ -31,9 +31,9 @@ use arrow_schema::DataType;
use datafusion_common::file_options::StatementOptions;
use datafusion_common::parsers::CompressionTypeVariant;
use datafusion_common::{
- not_impl_err, plan_datafusion_err, plan_err, unqualified_field_not_found,
Column,
- Constraints, DFField, DFSchema, DFSchemaRef, DataFusionError, ExprSchema,
- OwnedTableReference, Result, SchemaReference, TableReference, ToDFSchema,
+ not_impl_err, plan_datafusion_err, plan_err, unqualified_field_not_found,
+ Constraints, DFField, DFSchema, DFSchemaRef, DataFusionError,
OwnedTableReference,
+ Result, SchemaReference, TableReference, ToDFSchema,
};
use datafusion_expr::dml::{CopyOptions, CopyTo};
use datafusion_expr::expr::Placeholder;
@@ -969,12 +969,6 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
table_name.clone(),
&arrow_schema,
)?);
- let values = table_schema.fields().iter().map(|f| {
- (
- f.name().clone(),
- ast::Expr::Identifier(ast::Ident::from(f.name().as_str())),
- )
- });
// Overwrite with assignment expressions
let mut planner_context = PlannerContext::new();
@@ -992,11 +986,15 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
})
.collect::<Result<HashMap<String, Expr>>>()?;
- let values = values
- .into_iter()
- .map(|(k, v)| {
- let val = assign_map.remove(&k).unwrap_or(v);
- (k, val)
+ let values_and_types = table_schema
+ .fields()
+ .iter()
+ .map(|f| {
+ let col_name = f.name();
+ let val = assign_map.remove(col_name).unwrap_or_else(|| {
+ ast::Expr::Identifier(ast::Ident::from(col_name.as_str()))
+ });
+ (col_name, val, f.data_type())
})
.collect::<Vec<_>>();
@@ -1026,25 +1024,22 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
// Projection
let mut exprs = vec![];
- for (col_name, expr) in values.into_iter() {
+ for (col_name, expr, dt) in values_and_types.into_iter() {
let expr = self.sql_to_expr(expr, &table_schema, &mut
planner_context)?;
let expr = match expr {
datafusion_expr::Expr::Placeholder(Placeholder {
ref id,
ref data_type,
}) => match data_type {
- None => {
- let dt =
table_schema.data_type(&Column::from_name(&col_name))?;
- datafusion_expr::Expr::Placeholder(Placeholder::new(
- id.clone(),
- Some(dt.clone()),
- ))
- }
+ None =>
datafusion_expr::Expr::Placeholder(Placeholder::new(
+ id.clone(),
+ Some(dt.clone()),
+ )),
Some(_) => expr,
},
_ => expr,
};
- let expr = expr.alias(col_name);
+ let expr = expr.cast_to(dt, source.schema())?.alias(col_name);
exprs.push(expr);
}
let source = project(source, exprs)?;
diff --git a/datafusion/sqllogictest/test_files/update.slt
b/datafusion/sqllogictest/test_files/update.slt
new file mode 100644
index 0000000000..4542a26239
--- /dev/null
+++ b/datafusion/sqllogictest/test_files/update.slt
@@ -0,0 +1,43 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+##########
+## Update Tests
+##########
+
+statement ok
+create table t1(a int, b varchar, c double, d int);
+
+# Turn off the optimizer to make the logical plan closer to the initial one
+statement ok
+set datafusion.optimizer.max_passes = 0;
+
+query TT
+explain update t1 set a=1, b=2, c=3.0, d=NULL;
+----
+logical_plan
+Dml: op=[Update] table=[t1]
+--Projection: CAST(Int64(1) AS Int32) AS a, CAST(Int64(2) AS Utf8) AS b,
Float64(3) AS c, CAST(NULL AS Int32) AS d
+----TableScan: t1
+
+query TT
+explain update t1 set a=c+1, b=a, c=c+1.0, d=b;
+----
+logical_plan
+Dml: op=[Update] table=[t1]
+--Projection: CAST(t1.c + CAST(Int64(1) AS Float64) AS Int32) AS a, CAST(t1.a
AS Utf8) AS b, t1.c + Float64(1) AS c, CAST(t1.b AS Int32) AS d
+----TableScan: t1