From 7641a3228156aab0e48c4bab5a6834b44f722d89 Mon Sep 17 00:00:00 2001 From: Lordworms <48054792+Lordworms@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:11:55 -0600 Subject: [PATCH] feat: issue #8969 adding position function (#8988) * feat: issue #8969 adding position function * reuse Instr --- datafusion/expr/src/built_in_function.rs | 2 +- datafusion/sql/src/expr/mod.rs | 19 +++++++- .../sqllogictest/test_files/position.slt | 43 +++++++++++++++++++ .../source/user-guide/sql/scalar_functions.md | 14 ++++++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 datafusion/sqllogictest/test_files/position.slt diff --git a/datafusion/expr/src/built_in_function.rs b/datafusion/expr/src/built_in_function.rs index 20b7df46e387..b1b74c16287d 100644 --- a/datafusion/expr/src/built_in_function.rs +++ b/datafusion/expr/src/built_in_function.rs @@ -1463,7 +1463,7 @@ impl BuiltinScalarFunction { BuiltinScalarFunction::Chr => &["chr"], BuiltinScalarFunction::EndsWith => &["ends_with"], BuiltinScalarFunction::InitCap => &["initcap"], - BuiltinScalarFunction::InStr => &["instr"], + BuiltinScalarFunction::InStr => &["instr", "position"], BuiltinScalarFunction::Left => &["left"], BuiltinScalarFunction::Lower => &["lower"], BuiltinScalarFunction::Lpad => &["lpad"], diff --git a/datafusion/sql/src/expr/mod.rs b/datafusion/sql/src/expr/mod.rs index b22c458b6db6..ecf510da7bce 100644 --- a/datafusion/sql/src/expr/mod.rs +++ b/datafusion/sql/src/expr/mod.rs @@ -514,7 +514,9 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { SQLExpr::Struct { values, fields } => { self.parse_struct(values, fields, schema, planner_context) } - + SQLExpr::Position { expr, r#in } => { + self.sql_position_to_expr(*expr, *r#in, schema, planner_context) + } _ => not_impl_err!("Unsupported ast node in sqltorel: {sql:?}"), } } @@ -704,7 +706,20 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { }; Ok(Expr::ScalarFunction(ScalarFunction::new(fun, args))) } - + fn sql_position_to_expr( + &self, + substr_expr: SQLExpr, + str_expr: SQLExpr, + schema: &DFSchema, + planner_context: &mut PlannerContext, + ) -> Result { + let fun = BuiltinScalarFunction::InStr; + let substr = + self.sql_expr_to_logical_expr(substr_expr, schema, planner_context)?; + let fullstr = self.sql_expr_to_logical_expr(str_expr, schema, planner_context)?; + let args = vec![fullstr, substr]; + Ok(Expr::ScalarFunction(ScalarFunction::new(fun, args))) + } fn sql_agg_with_filter_to_expr( &self, expr: SQLExpr, diff --git a/datafusion/sqllogictest/test_files/position.slt b/datafusion/sqllogictest/test_files/position.slt new file mode 100644 index 000000000000..c1141ab06943 --- /dev/null +++ b/datafusion/sqllogictest/test_files/position.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. + +# test position in select +query I +select position('world' in 'hello world'); +---- +7 + + + +# test in expression +query I +select 1000 where position('world' in 'hello world') != 100; +---- +1000 + + +# test in expression +query I +select 100000 where position('legend' in 'league of legend') = 11; +---- +100000 + + +# test in expression +query I +select 100000 where position('legend' in 'league of legend') != 11; +---- diff --git a/docs/source/user-guide/sql/scalar_functions.md b/docs/source/user-guide/sql/scalar_functions.md index ba69b53e69af..bbfbc6a8bd3e 100644 --- a/docs/source/user-guide/sql/scalar_functions.md +++ b/docs/source/user-guide/sql/scalar_functions.md @@ -641,6 +641,7 @@ nullif(expression1, expression2) - [levenshtein](#levenshtein) - [substr_index](#substr_index) - [find_in_set](#find_in_set) +- [position](#position) ### `ascii` @@ -1300,6 +1301,19 @@ regexp_replace(str, regexp, replacement, flags) - **g**: (global) Search globally and don't return after the first match. - **i**: (insensitive) Ignore case when matching. +### `position` + +Returns the position of substr in orig_str + +``` +position(substr in origstr) +``` + +#### Arguments + +- **substr**: he pattern string. +- **origstr**: The model string. + ## Time and Date Functions - [now](#now)