Packages

An Elixir DuckDB library

Current section

Files

Jump to
exduckdb c_src duckdb src function scalar string prefix.cpp
Raw

c_src/duckdb/src/function/scalar/string/prefix.cpp

#include "duckdb/function/scalar/string_functions.hpp"
#include "duckdb/common/types/string_type.hpp"
#include "duckdb/common/exception.hpp"
namespace duckdb {
static bool PrefixFunction(const string_t &str, const string_t &pattern);
struct PrefixOperator {
template <class TA, class TB, class TR>
static inline TR Operation(TA left, TB right) {
return PrefixFunction(left, right);
}
};
static bool PrefixFunction(const string_t &str, const string_t &pattern) {
auto str_length = str.GetSize();
auto patt_length = pattern.GetSize();
if (patt_length > str_length) {
return false;
}
if (patt_length <= string_t::PREFIX_LENGTH) {
// short prefix
if (patt_length == 0) {
// length = 0, return true
return true;
}
// prefix early out
const char *str_pref = str.GetPrefix();
const char *patt_pref = pattern.GetPrefix();
for (idx_t i = 0; i < patt_length; ++i) {
if (str_pref[i] != patt_pref[i]) {
return false;
}
}
return true;
} else {
// prefix early out
const char *str_pref = str.GetPrefix();
const char *patt_pref = pattern.GetPrefix();
for (idx_t i = 0; i < string_t::PREFIX_LENGTH; ++i) {
if (str_pref[i] != patt_pref[i]) {
// early out
return false;
}
}
// compare the rest of the prefix
const char *str_data = str.GetDataUnsafe();
const char *patt_data = pattern.GetDataUnsafe();
D_ASSERT(patt_length <= str_length);
for (idx_t i = string_t::PREFIX_LENGTH; i < patt_length; ++i) {
if (str_data[i] != patt_data[i]) {
return false;
}
}
return true;
}
}
ScalarFunction PrefixFun::GetFunction() {
return ScalarFunction("prefix", // name of the function
{LogicalType::VARCHAR, LogicalType::VARCHAR}, // argument list
LogicalType::BOOLEAN, // return type
ScalarFunction::BinaryFunction<string_t, string_t, bool, PrefixOperator>);
}
void PrefixFun::RegisterFunction(BuiltinFunctions &set) {
set.AddFunction(GetFunction());
}
} // namespace duckdb