Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions datafusion/core/src/datasource/listing/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ impl ExpressionVisitor for ApplicabilityVisitor<'_> {
| Expr::Not(_)
| Expr::IsNotNull(_)
| Expr::IsNull(_)
| Expr::IsTrue(_)
| Expr::IsFalse(_)
| Expr::IsUnknown(_)
| Expr::IsNotTrue(_)
| Expr::IsNotFalse(_)
| Expr::IsNotUnknown(_)
| Expr::Negative(_)
| Expr::Cast { .. }
| Expr::TryCast { .. }
Expand Down
24 changes: 24 additions & 0 deletions datafusion/core/src/physical_plan/planner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,30 @@ fn create_physical_name(e: &Expr, is_first_expr: bool) -> Result<String> {
let expr = create_physical_name(expr, false)?;
Ok(format!("{} IS NOT NULL", expr))
}
Expr::IsTrue(expr) => {
let expr = create_physical_name(expr, false)?;
Ok(format!("{} IS TRUE", expr))
}
Expr::IsFalse(expr) => {
let expr = create_physical_name(expr, false)?;
Ok(format!("{} IS FALSE", expr))
}
Expr::IsUnknown(expr) => {
let expr = create_physical_name(expr, false)?;
Ok(format!("{} IS UNKNOWN", expr))
}
Expr::IsNotTrue(expr) => {
let expr = create_physical_name(expr, false)?;
Ok(format!("{} IS NOT TRUE", expr))
}
Expr::IsNotFalse(expr) => {
let expr = create_physical_name(expr, false)?;
Ok(format!("{} IS NOT FALSE", expr))
}
Expr::IsNotUnknown(expr) => {
let expr = create_physical_name(expr, false)?;
Ok(format!("{} IS NOT UNKNOWN", expr))
}
Expr::GetIndexedField { expr, key } => {
let expr = create_physical_name(expr, false)?;
Ok(format!("{}[{}]", expr, key))
Expand Down
48 changes: 48 additions & 0 deletions datafusion/expr/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ pub enum Expr {
IsNotNull(Box<Expr>),
/// Whether an expression is Null. This expression is never null.
IsNull(Box<Expr>),
/// Whether an expression is True. Boolean operation
IsTrue(Box<Expr>),
/// Whether an expression is False. Boolean operation
IsFalse(Box<Expr>),
/// Whether an expression is Unknown. Boolean operation
IsUnknown(Box<Expr>),
/// Whether an expression is not True. Boolean operation
IsNotTrue(Box<Expr>),
/// Whether an expression is not False. Boolean operation
IsNotFalse(Box<Expr>),
/// Whether an expression is not Unknown. Boolean operation
IsNotUnknown(Box<Expr>),
/// arithmetic negation of an expression, the operand must be of a signed numeric data type
Negative(Box<Expr>),
/// Returns the field of a [`arrow::array::ListArray`] or [`arrow::array::StructArray`] by key
Expand Down Expand Up @@ -335,6 +347,12 @@ impl Expr {
Expr::InSubquery { .. } => "InSubquery",
Expr::IsNotNull(..) => "IsNotNull",
Expr::IsNull(..) => "IsNull",
Expr::IsTrue(..) => "IsTrue",
Expr::IsFalse(..) => "IsFalse",
Expr::IsUnknown(..) => "IsUnknown",
Expr::IsNotTrue(..) => "IsNotTrue",
Expr::IsNotFalse(..) => "IsNotFalse",
Expr::IsNotUnknown(..) => "IsNotUnknown",
Expr::Literal(..) => "Literal",
Expr::Negative(..) => "Negative",
Expr::Not(..) => "Not",
Expand Down Expand Up @@ -548,6 +566,12 @@ impl fmt::Debug for Expr {
Expr::Negative(expr) => write!(f, "(- {:?})", expr),
Expr::IsNull(expr) => write!(f, "{:?} IS NULL", expr),
Expr::IsNotNull(expr) => write!(f, "{:?} IS NOT NULL", expr),
Expr::IsTrue(expr) => write!(f, "{:?} IS TRUE", expr),
Expr::IsFalse(expr) => write!(f, "{:?} IS FALSE", expr),
Expr::IsUnknown(expr) => write!(f, "{:?} IS UNKNOWN", expr),
Expr::IsNotTrue(expr) => write!(f, "{:?} IS NOT TRUE", expr),
Expr::IsNotFalse(expr) => write!(f, "{:?} IS NOT FALSE", expr),
Expr::IsNotUnknown(expr) => write!(f, "{:?} IS NOT UNKNOWN", expr),
Expr::Exists {
subquery,
negated: true,
Expand Down Expand Up @@ -799,6 +823,30 @@ fn create_name(e: &Expr, input_schema: &DFSchema) -> Result<String> {
let expr = create_name(expr, input_schema)?;
Ok(format!("{} IS NOT NULL", expr))
}
Expr::IsTrue(expr) => {
let expr = create_name(expr, input_schema)?;
Ok(format!("{} IS TRUE", expr))
}
Expr::IsFalse(expr) => {
let expr = create_name(expr, input_schema)?;
Ok(format!("{} IS FALSE", expr))
}
Expr::IsUnknown(expr) => {
let expr = create_name(expr, input_schema)?;
Ok(format!("{} IS UNKNOWN", expr))
}
Expr::IsNotTrue(expr) => {
let expr = create_name(expr, input_schema)?;
Ok(format!("{} IS NOT TRUE", expr))
}
Expr::IsNotFalse(expr) => {
let expr = create_name(expr, input_schema)?;
Ok(format!("{} IS NOT FALSE", expr))
}
Expr::IsNotUnknown(expr) => {
let expr = create_name(expr, input_schema)?;
Ok(format!("{} IS NOT UNKNOWN", expr))
}
Expr::Exists { negated: true, .. } => Ok("NOT EXISTS".to_string()),
Expr::Exists { negated: false, .. } => Ok("EXISTS".to_string()),
Expr::InSubquery { negated: true, .. } => Ok("NOT IN".to_string()),
Expand Down
8 changes: 8 additions & 0 deletions datafusion/expr/src/expr_rewriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ impl ExprRewritable for Expr {
Expr::Not(expr) => Expr::Not(rewrite_boxed(expr, rewriter)?),
Expr::IsNotNull(expr) => Expr::IsNotNull(rewrite_boxed(expr, rewriter)?),
Expr::IsNull(expr) => Expr::IsNull(rewrite_boxed(expr, rewriter)?),
Expr::IsTrue(expr) => Expr::IsTrue(rewrite_boxed(expr, rewriter)?),
Expr::IsFalse(expr) => Expr::IsFalse(rewrite_boxed(expr, rewriter)?),
Expr::IsUnknown(expr) => Expr::IsUnknown(rewrite_boxed(expr, rewriter)?),
Expr::IsNotTrue(expr) => Expr::IsNotTrue(rewrite_boxed(expr, rewriter)?),
Expr::IsNotFalse(expr) => Expr::IsNotFalse(rewrite_boxed(expr, rewriter)?),
Expr::IsNotUnknown(expr) => {
Expr::IsNotUnknown(rewrite_boxed(expr, rewriter)?)
}
Expr::Negative(expr) => Expr::Negative(rewrite_boxed(expr, rewriter)?),
Expr::Between {
expr,
Expand Down
18 changes: 16 additions & 2 deletions datafusion/expr/src/expr_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ impl ExprSchemable for Expr {
| Expr::InSubquery { .. }
| Expr::Between { .. }
| Expr::InList { .. }
| Expr::IsNotNull(_) => Ok(DataType::Boolean),
| Expr::IsNotNull(_)
| Expr::IsTrue(_)
| Expr::IsFalse(_)
| Expr::IsUnknown(_)
| Expr::IsNotTrue(_)
| Expr::IsNotFalse(_)
| Expr::IsNotUnknown(_) => Ok(DataType::Boolean),
Expr::ScalarSubquery(subquery) => {
Ok(subquery.subquery.schema().field(0).data_type().clone())
}
Expand Down Expand Up @@ -183,7 +189,15 @@ impl ExprSchemable for Expr {
| Expr::WindowFunction { .. }
| Expr::AggregateFunction { .. }
| Expr::AggregateUDF { .. } => Ok(true),
Expr::IsNull(_) | Expr::IsNotNull(_) | Expr::Exists { .. } => Ok(false),
Expr::IsNull(_)
| Expr::IsNotNull(_)
| Expr::IsTrue(_)
| Expr::IsFalse(_)
| Expr::IsUnknown(_)
| Expr::IsNotTrue(_)
| Expr::IsNotFalse(_)
| Expr::IsNotUnknown(_)
| Expr::Exists { .. } => Ok(false),
Expr::InSubquery { expr, .. } => expr.nullable(input_schema),
Expr::ScalarSubquery(subquery) => {
Ok(subquery.subquery.schema().field(0).is_nullable())
Expand Down
6 changes: 6 additions & 0 deletions datafusion/expr/src/expr_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ impl ExprVisitable for Expr {
Expr::Alias(expr, _)
| Expr::Not(expr)
| Expr::IsNotNull(expr)
| Expr::IsTrue(expr)
| Expr::IsFalse(expr)
| Expr::IsUnknown(expr)
| Expr::IsNotTrue(expr)
| Expr::IsNotFalse(expr)
| Expr::IsNotUnknown(expr)
| Expr::IsNull(expr)
| Expr::Negative(expr)
| Expr::Cast { expr, .. }
Expand Down
6 changes: 6 additions & 0 deletions datafusion/expr/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ impl ExpressionVisitor for ColumnNameVisitor<'_> {
| Expr::Not(_)
| Expr::IsNotNull(_)
| Expr::IsNull(_)
| Expr::IsTrue(_)
| Expr::IsFalse(_)
| Expr::IsUnknown(_)
| Expr::IsNotTrue(_)
| Expr::IsNotFalse(_)
| Expr::IsNotUnknown(_)
| Expr::Negative(_)
| Expr::Between { .. }
| Expr::Case { .. }
Expand Down
18 changes: 18 additions & 0 deletions datafusion/optimizer/src/common_subexpr_eliminate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,24 @@ impl ExprIdentifierVisitor<'_> {
Expr::IsNull(_) => {
desc.push_str("IsNull-");
}
Expr::IsTrue(_) => {
desc.push_str("IsTrue-");
}
Expr::IsFalse(_) => {
desc.push_str("IsFalse-");
}
Expr::IsUnknown(_) => {
desc.push_str("IsUnknown-");
}
Expr::IsNotTrue(_) => {
desc.push_str("IsNotTrue-");
}
Expr::IsNotFalse(_) => {
desc.push_str("IsNotFalse-");
}
Expr::IsNotUnknown(_) => {
desc.push_str("IsNotUnknown-");
}
Expr::Negative(_) => {
desc.push_str("Negative-");
}
Expand Down
6 changes: 6 additions & 0 deletions datafusion/optimizer/src/simplify_expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,12 @@ impl<'a> ConstEvaluator<'a> {
| Expr::Not(_)
| Expr::IsNotNull(_)
| Expr::IsNull(_)
| Expr::IsTrue(_)
| Expr::IsFalse(_)
| Expr::IsUnknown(_)
| Expr::IsNotTrue(_)
| Expr::IsNotFalse(_)
| Expr::IsNotUnknown(_)
| Expr::Negative(_)
| Expr::Between { .. }
| Expr::Case { .. }
Expand Down
31 changes: 31 additions & 0 deletions datafusion/proto/proto/datafusion.proto
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,13 @@ message LogicalExprNode {
CubeNode cube = 23;

RollupNode rollup = 24;

IsTrue is_true = 25;
IsFalse is_false = 26;
IsUnknown is_unknown = 27;
IsNotTrue is_not_true = 28;
IsNotFalse is_not_false = 29;
IsNotUnknown is_not_unknown = 30;
}
}

Expand Down Expand Up @@ -346,6 +353,30 @@ message IsNotNull {
LogicalExprNode expr = 1;
}

message IsTrue {
LogicalExprNode expr = 1;
}

message IsFalse {
LogicalExprNode expr = 1;
}

message IsUnknown {
LogicalExprNode expr = 1;
}

message IsNotTrue {
LogicalExprNode expr = 1;
}

message IsNotFalse {
LogicalExprNode expr = 1;
}

message IsNotUnknown {
LogicalExprNode expr = 1;
}

message Not {
LogicalExprNode expr = 1;
}
Expand Down
18 changes: 18 additions & 0 deletions datafusion/proto/src/from_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,24 @@ pub fn parse_expr(
ExprType::NotExpr(not) => Ok(Expr::Not(Box::new(parse_required_expr(
&not.expr, registry, "expr",
)?))),
ExprType::IsTrue(msg) => Ok(Expr::IsTrue(Box::new(parse_required_expr(
&msg.expr, registry, "expr",
)?))),
ExprType::IsFalse(msg) => Ok(Expr::IsFalse(Box::new(parse_required_expr(
&msg.expr, registry, "expr",
)?))),
ExprType::IsUnknown(msg) => Ok(Expr::IsUnknown(Box::new(parse_required_expr(
&msg.expr, registry, "expr",
)?))),
ExprType::IsNotTrue(msg) => Ok(Expr::IsNotTrue(Box::new(parse_required_expr(
&msg.expr, registry, "expr",
)?))),
ExprType::IsNotFalse(msg) => Ok(Expr::IsNotFalse(Box::new(parse_required_expr(
&msg.expr, registry, "expr",
)?))),
ExprType::IsNotUnknown(msg) => Ok(Expr::IsNotUnknown(Box::new(
parse_required_expr(&msg.expr, registry, "expr")?,
))),
ExprType::Between(between) => Ok(Expr::Between {
expr: Box::new(parse_required_expr(&between.expr, registry, "expr")?),
negated: between.negated,
Expand Down
48 changes: 48 additions & 0 deletions datafusion/proto/src/to_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,54 @@ impl TryFrom<&Expr> for protobuf::LogicalExprNode {
expr_type: Some(ExprType::IsNotNullExpr(expr)),
}
}
Expr::IsTrue(expr) => {
let expr = Box::new(protobuf::IsTrue {
expr: Some(Box::new(expr.as_ref().try_into()?)),
});
Self {
expr_type: Some(ExprType::IsTrue(expr)),
}
}
Expr::IsFalse(expr) => {
let expr = Box::new(protobuf::IsFalse {
expr: Some(Box::new(expr.as_ref().try_into()?)),
});
Self {
expr_type: Some(ExprType::IsFalse(expr)),
}
}
Expr::IsUnknown(expr) => {
let expr = Box::new(protobuf::IsUnknown {
expr: Some(Box::new(expr.as_ref().try_into()?)),
});
Self {
expr_type: Some(ExprType::IsUnknown(expr)),
}
}
Expr::IsNotTrue(expr) => {
let expr = Box::new(protobuf::IsNotTrue {
expr: Some(Box::new(expr.as_ref().try_into()?)),
});
Self {
expr_type: Some(ExprType::IsNotTrue(expr)),
}
}
Expr::IsNotFalse(expr) => {
let expr = Box::new(protobuf::IsNotFalse {
expr: Some(Box::new(expr.as_ref().try_into()?)),
});
Self {
expr_type: Some(ExprType::IsNotFalse(expr)),
}
}
Expr::IsNotUnknown(expr) => {
let expr = Box::new(protobuf::IsNotUnknown {
expr: Some(Box::new(expr.as_ref().try_into()?)),
});
Self {
expr_type: Some(ExprType::IsNotUnknown(expr)),
}
}
Expr::Between {
expr,
negated,
Expand Down
18 changes: 18 additions & 0 deletions datafusion/sql/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,24 @@ where
Expr::IsNull(nested_expr) => Ok(Expr::IsNull(Box::new(
clone_with_replacement(nested_expr, replacement_fn)?,
))),
Expr::IsTrue(nested_expr) => Ok(Expr::IsTrue(Box::new(
clone_with_replacement(nested_expr, replacement_fn)?,
))),
Expr::IsFalse(nested_expr) => Ok(Expr::IsFalse(Box::new(
clone_with_replacement(nested_expr, replacement_fn)?,
))),
Expr::IsUnknown(nested_expr) => Ok(Expr::IsUnknown(Box::new(
clone_with_replacement(nested_expr, replacement_fn)?,
))),
Expr::IsNotTrue(nested_expr) => Ok(Expr::IsNotTrue(Box::new(
clone_with_replacement(nested_expr, replacement_fn)?,
))),
Expr::IsNotFalse(nested_expr) => Ok(Expr::IsNotFalse(Box::new(
clone_with_replacement(nested_expr, replacement_fn)?,
))),
Expr::IsNotUnknown(nested_expr) => Ok(Expr::IsNotUnknown(Box::new(
clone_with_replacement(nested_expr, replacement_fn)?,
))),
Expr::Cast {
expr: nested_expr,
data_type,
Expand Down