Skip to content

Commit

Permalink
First version of the SQL INSTR function
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduardo Almeida committed Mar 17, 2020
1 parent 9673b6c commit 106c634
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 67 deletions.
23 changes: 12 additions & 11 deletions src/function/scalar/string/CMakeLists.txt
@@ -1,14 +1,15 @@
add_library_unity(duckdb_func_string
OBJECT
reverse.cpp
caseconvert.cpp
concat.cpp
length.cpp
like.cpp
printf.cpp
regexp.cpp
substring.cpp
instr.cpp)
add_library_unity(
duckdb_func_string
OBJECT
reverse.cpp
caseconvert.cpp
concat.cpp
length.cpp
like.cpp
printf.cpp
regexp.cpp
substring.cpp
instr.cpp)
set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:duckdb_func_string>
PARENT_SCOPE)
67 changes: 33 additions & 34 deletions src/function/scalar/string/instr.cpp
Expand Up @@ -20,46 +20,45 @@ struct InstrOperator {
};

static int32_t instr(string_t haystack, string_t needle) {
int32_t string_position=0;
unsigned char firstChar;
int32_t string_position = 0;
unsigned char firstChar;

// Getting information about the needle and the haystack
auto input_haystack = haystack.GetData();
auto input_needle = needle.GetData();
auto size_haystack = haystack.GetSize();
auto size_needle = needle.GetSize();
// Getting information about the needle and the haystack
auto input_haystack = haystack.GetData();
auto input_needle = needle.GetData();
auto size_haystack = haystack.GetSize();
auto size_needle = needle.GetSize();

// Needle needs something to proceed
// Haystack should be bigger than the needle
if((size_needle>0) && (size_haystack>=size_needle)){
firstChar=input_needle[0];

// find the positions with the first letter
while(size_haystack>0){
char b = input_haystack[0];
// Needle needs something to proceed
// Haystack should be bigger than the needle
if ((size_needle > 0) && (size_haystack >= size_needle)) {
firstChar = input_needle[0];

// Compare the first letter and with that compare Needle to the Haystack
if((b==firstChar)&&((memcmp(input_haystack, input_needle, size_needle)==0))){
string_position += (b & 0xC0) != 0x80;
return string_position;
}
string_position += (b & 0xC0) != 0x80;
size_haystack--;
input_haystack++;
}
// find the positions with the first letter
while (size_haystack > 0) {
char b = input_haystack[0];

// Did not find the needle
string_position=0;
}
return string_position;
// Compare the first letter and with that compare Needle to the Haystack
if ((b == firstChar) && ((memcmp(input_haystack, input_needle, size_needle) == 0))) {
string_position += (b & 0xC0) != 0x80;
return string_position;
}
string_position += (b & 0xC0) != 0x80;
size_haystack--;
input_haystack++;
}

// Did not find the needle
string_position = 0;
}
return string_position;
}

void InstrFun::RegisterFunction(BuiltinFunctions &set) {
set.AddFunction(ScalarFunction("instr", // name of the function
{SQLType::VARCHAR,
SQLType::VARCHAR}, // argument list
SQLType::INTEGER, // return type
ScalarFunction::BinaryFunction<string_t, string_t, int32_t, InstrOperator, true>));
set.AddFunction(ScalarFunction("instr", // name of the function
{SQLType::VARCHAR, SQLType::VARCHAR}, // argument list
SQLType::INTEGER, // return type
ScalarFunction::BinaryFunction<string_t, string_t, int32_t, InstrOperator, true>));
}

} // namespace duckdb
} // namespace duckdb
2 changes: 1 addition & 1 deletion src/include/duckdb/function/scalar/string_functions.hpp
Expand Up @@ -63,7 +63,7 @@ struct InstrFun {

struct RegexpMatchesBindData : public FunctionData {
RegexpMatchesBindData(std::unique_ptr<re2::RE2> constant_pattern, string range_min, string range_max,
bool range_success);
bool range_success);
~RegexpMatchesBindData();

std::unique_ptr<re2::RE2> constant_pattern;
Expand Down
25 changes: 13 additions & 12 deletions test/sql/function/CMakeLists.txt
@@ -1,15 +1,16 @@
add_library_unity(test_sql_function
OBJECT
test_math.cpp
test_concat.cpp
test_function_resolution.cpp
test_unary_operators.cpp
test_substring.cpp
test_table_function.cpp
test_regex.cpp
test_stringfunctions.cpp
test_trigo.cpp
test_instr.cpp)
add_library_unity(
test_sql_function
OBJECT
test_math.cpp
test_concat.cpp
test_function_resolution.cpp
test_unary_operators.cpp
test_substring.cpp
test_table_function.cpp
test_regex.cpp
test_stringfunctions.cpp
test_trigo.cpp
test_instr.cpp)
set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:test_sql_function>
PARENT_SCOPE)
18 changes: 9 additions & 9 deletions test/sql/function/test_instr.cpp
Expand Up @@ -5,11 +5,11 @@ using namespace duckdb;
using namespace std;

/* Test Case disclaimer
*
* Assertions built using the Domain Testing technique
* at: https://bbst.courses/wp-content/uploads/2018/01/Kaner-Intro-to-Domain-Testing-2018.pdf
*
*/
*
* Assertions built using the Domain Testing technique
* at: https://bbst.courses/wp-content/uploads/2018/01/Kaner-Intro-to-Domain-Testing-2018.pdf
*
*/
TEST_CASE("Instr test", "[function]") {
unique_ptr<QueryResult> result;
DuckDB db(nullptr);
Expand Down Expand Up @@ -41,15 +41,15 @@ TEST_CASE("Instr test", "[function]") {
REQUIRE(CHECK_COLUMN(result, 0, {2, 0, 0, Value()}));

// Test multiple letters at the end
result = con.Query("SELECT instr(s,'lo') FROM strings");
result = con.Query("SELECT instr(s,'lo') FROM strings");
REQUIRE(CHECK_COLUMN(result, 0, {4, 0, 0, Value()}));

// Test no match
result = con.Query("SELECT instr(s,'he-man') FROM strings");
REQUIRE(CHECK_COLUMN(result, 0, {0, 0, 0, Value()}));

// Test matching needle in multiple rows
result = con.Query("SELECT instr(s,'o'),s FROM strings");
// Test matching needle in multiple rows
result = con.Query("SELECT instr(s,'o'),s FROM strings");
REQUIRE(CHECK_COLUMN(result, 0, {5, 2, 0, Value()}));
REQUIRE(CHECK_COLUMN(result, 1, {"hello", "world", "b", Value()}));

Expand All @@ -60,4 +60,4 @@ TEST_CASE("Instr test", "[function]") {
REQUIRE(CHECK_COLUMN(result, 0, {Value(), Value(), Value(), Value()}));
result = con.Query("SELECT instr(NULL,NULL) FROM strings");
REQUIRE(CHECK_COLUMN(result, 0, {Value(), Value(), Value(), Value()}));
}
}

0 comments on commit 106c634

Please sign in to comment.