1#include "duckdb/function/scalar/string_functions.hpp"
2
3#include "duckdb/common/exception.hpp"
4#include "duckdb/common/vector_operations/vector_operations.hpp"
5#include "duckdb/common/vector_operations/unary_executor.hpp"
6#include "utf8proc.hpp"
7
8#include <cstring>
9
10using namespace std;
11
12namespace duckdb {
13
14static int64_t instr(string_t haystack, string_t needle) {
15 int64_t string_position = 0;
16
17 // Getting information about the needle and the haystack
18 auto haystack_data = haystack.GetData();
19 auto needle_data = needle.GetData();
20 auto location_data = strstr(haystack_data, needle_data);
21 if (location_data) {
22 auto str = reinterpret_cast<const utf8proc_uint8_t *>(haystack_data);
23 utf8proc_ssize_t len = location_data - haystack_data;
24 for (++string_position; len > 0; ++string_position) {
25 utf8proc_int32_t codepoint;
26 const auto bytes = utf8proc_iterate(str, len, &codepoint);
27 str += bytes;
28 len -= bytes;
29 }
30 }
31
32 return string_position;
33}
34
35struct InstrOperator {
36 template <class TA, class TB, class TR> static inline TR Operation(TA left, TB right) {
37 return instr(left, right);
38 }
39};
40
41void InstrFun::RegisterFunction(BuiltinFunctions &set) {
42 set.AddFunction(ScalarFunction("instr", // name of the function
43 {SQLType::VARCHAR, SQLType::VARCHAR}, // argument list
44 SQLType::BIGINT, // return type
45 ScalarFunction::BinaryFunction<string_t, string_t, int64_t, InstrOperator, true>));
46}
47
48} // namespace duckdb
49