In addition to easy construction, DataFusion exposes APIs for simplifying such expression so they are more efficient to evaluate. This code is also used by the query engine to optimize queries.
()
| 158 | /// such expression so they are more efficient to evaluate. This code is also |
| 159 | /// used by the query engine to optimize queries. |
| 160 | fn simplify_demo() -> Result<()> { |
| 161 | // For example, lets say you have has created an expression such |
| 162 | // ts = to_timestamp("2020-09-08T12:00:00+00:00") |
| 163 | let expr = col("ts").eq(to_timestamp(vec![lit("2020-09-08T12:00:00+00:00")])); |
| 164 | |
| 165 | // Naively evaluating such an expression against a large number of |
| 166 | // rows would involve re-converting "2020-09-08T12:00:00+00:00" to a |
| 167 | // timestamp for each row which gets expensive |
| 168 | // |
| 169 | // However, DataFusion's simplification logic can do this for you |
| 170 | |
| 171 | // you need to tell DataFusion the type of column "ts": |
| 172 | let schema = Schema::new(vec![make_ts_field("ts")]).to_dfschema_ref()?; |
| 173 | |
| 174 | // And then build a simplifier |
| 175 | // the ExecutionProps carries information needed to simplify |
| 176 | // expressions, such as the current time (to evaluate `now()` |
| 177 | // correctly) |
| 178 | let context = SimplifyContext::builder() |
| 179 | .with_schema(schema) |
| 180 | .with_current_time() |
| 181 | .build(); |
| 182 | let simplifier = ExprSimplifier::new(context); |
| 183 | |
| 184 | // And then call the simplify_expr function: |
| 185 | let expr = simplifier.simplify(expr)?; |
| 186 | |
| 187 | // DataFusion has simplified the expression to a comparison with a constant |
| 188 | // ts = 1599566400000000000; Tada! |
| 189 | assert_eq!( |
| 190 | expr, |
| 191 | col("ts").eq(lit_timestamp_nano(1599566400000000000i64)) |
| 192 | ); |
| 193 | |
| 194 | // here are some other examples of what DataFusion is capable of |
| 195 | let schema = Schema::new(vec![make_field("i", DataType::Int64)]).to_dfschema_ref()?; |
| 196 | let context = SimplifyContext::builder() |
| 197 | .with_schema(Arc::clone(&schema)) |
| 198 | .with_current_time() |
| 199 | .build(); |
| 200 | let simplifier = ExprSimplifier::new(context); |
| 201 | |
| 202 | // basic arithmetic simplification |
| 203 | // i + 1 + 2 => i + 3 |
| 204 | // (note this is not done if the expr is (col("i") + lit(1) + lit(2))) |
| 205 | assert_eq!( |
| 206 | simplifier.simplify(col("i") + (lit(1) + lit(2)))?, |
| 207 | col("i") + lit(3) |
| 208 | ); |
| 209 | |
| 210 | // (i * 0) > 5 --> false (only if null) |
| 211 | assert_eq!( |
| 212 | simplifier.simplify((col("i") * lit(0)).gt(lit(5)))?, |
| 213 | lit(false) |
| 214 | ); |
| 215 | |
| 216 | // Logical simplification |
| 217 |
no test coverage detected
searching dependent graphs…