alamb commented on code in PR #4490:
URL: https://github.com/apache/arrow-datafusion/pull/4490#discussion_r1042053551
##########
datafusion/expr/src/expr_schema.rs:
##########
@@ -23,12 +23,20 @@ use crate::{aggregate_function, function, window_function};
use arrow::compute::can_cast_types;
use arrow::datatypes::DataType;
use datafusion_common::{DFField, DFSchema, DataFusionError, ExprSchema,
Result};
+use log::debug;
/// trait to allow expr to typable with respect to a schema
pub trait ExprSchemable {
/// given a schema, return the type of the expr
fn get_type<S: ExprSchema>(&self, schema: &S) -> Result<DataType>;
+ /// given a schema and param data types, return the type of the expr
+ fn get_type_with_params<S: ExprSchema>(
Review Comment:
I tried to figure out a better way to do this without having to change the
trait, and I can't really see one. Eventually I think we would probably want to
make `get_type_with_param` the only call so that parameters are supported
everywhere -- but I can see how that would be a massive change 🤔
The other thing I was thinking is that we could potentially move the
parameters to `DFSchema` itself 🤔
##########
datafusion/expr/src/logical_plan/builder.rs:
##########
@@ -45,6 +45,8 @@ use std::any::Any;
use std::convert::TryFrom;
use std::{collections::HashMap, sync::Arc};
+use super::Prepare;
Review Comment:
Perhaps this could be combined with the rest of the similar structures (e.g.
`Aggregate, `Explain`, etc above)
##########
datafusion/expr/src/expr.rs:
##########
@@ -244,6 +244,8 @@ pub enum Expr {
/// List of grouping set expressions. Only valid in the context of an
aggregate
/// GROUP BY expression list
GroupingSet(GroupingSet),
+ /// A place holder for parameters in a prepared statement.
Review Comment:
```suggestion
/// A place holder for parameters in a prepared statement.
/// (e.g. `$foo` or `$1`)
```
##########
datafusion/expr/src/expr_schema.rs:
##########
@@ -120,13 +138,44 @@ impl ExprSchemable for Expr {
ref right,
ref op,
}) => binary_operator_data_type(
- &left.get_type(schema)?,
+ &left.get_type_with_params(schema, param_data_types)?,
op,
- &right.get_type(schema)?,
+ &right.get_type_with_params(schema, param_data_types)?,
),
Expr::Like { .. } | Expr::ILike { .. } | Expr::SimilarTo { .. } =>
{
Ok(DataType::Boolean)
}
+ // Return the type of the corresponding param defined in
param_data_types of `PREPARE my_plan(param_data_types)`
+ Expr::Placeholder(param) => {
+ // param is $1, $2, $3, ...
+ // Let convert it to index: 0, 1, 2, ...
+ let index = param[1..].parse::<usize>();
Review Comment:
If we require the parameters to be `usize` I recommend we do this validation
much earlier and then store the `usize` in placeholder
```rust
enum Expr {
...
PlaceHolder::Placeholder(usize)
...
}
```
##########
datafusion/expr/src/logical_plan/builder.rs:
##########
@@ -272,11 +279,31 @@ impl LogicalPlanBuilder {
/// Apply a filter
pub fn filter(&self, expr: impl Into<Expr>) -> Result<Self> {
+ self.filter_with_params(expr, &[])
+ }
+
+ /// Apply a filter wit provided data types for params of prepared
statement
+ pub fn filter_with_params(
Review Comment:
I am worried about this approach -- now clients will have to know if they
should call `filter` or `filter_with_params` depending on the context.
Can you think of any way to avoid it?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]