#include "binder/expression/expression_util.h"
#include "expression_evaluator/expression_evaluator_utils.h"
#include "function/string/functions/base_regexp_function.h"
#include "function/string/vector_string_functions.h"
#include "re2.h"
namespace lbug {
namespace function {
using namespace common;
struct RegexFullMatchBindData : public FunctionBindData {
regex::RE2 pattern;
explicit RegexFullMatchBindData(common::logical_type_vec_t paramTypes, std::string patternInStr)
: FunctionBindData{std::move(paramTypes), common::LogicalType::BOOL()},
pattern{patternInStr} {}
std::unique_ptr<FunctionBindData> copy() const override {
return std::make_unique<RegexFullMatchBindData>(copyVector(paramTypes), pattern.pattern());
}
};
struct RegexpFullMatch {
static void operation(string_t& left, string_t& right, uint8_t& result) {
result = RE2::FullMatch(left.getAsString(),
BaseRegexpOperation::parseCypherPattern(right.getAsString()));
}
};
struct RegexpFullMatchStaticPattern : BaseRegexpOperation {
static void operation(string_t& left, string_t& , uint8_t& result,
common::ValueVector& , common::ValueVector& ,
common::ValueVector& , void* dataPtr) {
auto regexFullMatchBindData = reinterpret_cast<RegexFullMatchBindData*>(dataPtr);
result = RE2::FullMatch(left.getAsString(), regexFullMatchBindData->pattern);
}
};
static std::unique_ptr<FunctionBindData> regexFullMatchBindFunc(const ScalarBindFuncInput& input) {
if (input.arguments[1]->expressionType == ExpressionType::LITERAL) {
auto value = evaluator::ExpressionEvaluatorUtils::evaluateConstantExpression(
input.arguments[1], input.context);
input.definition->ptrCast<ScalarFunction>()->execFunc =
ScalarFunction::BinaryExecWithBindData<string_t, string_t, uint8_t,
RegexpFullMatchStaticPattern>;
input.definition->ptrCast<ScalarFunction>()->selectFunc =
ScalarFunction::BinarySelectWithBindData<string_t, string_t,
RegexpFullMatchStaticPattern>;
auto patternInStr = value.getValue<std::string>();
return std::make_unique<RegexFullMatchBindData>(
binder::ExpressionUtil::getDataTypes(input.arguments),
BaseRegexpOperation::parseCypherPattern(patternInStr));
} else {
return FunctionBindData::getSimpleBindData(input.arguments, LogicalType::BOOL());
}
}
function_set RegexpFullMatchFunction::getFunctionSet() {
function_set functionSet;
auto scalarFunc = make_unique<ScalarFunction>(name,
std::vector<LogicalTypeID>{LogicalTypeID::STRING, LogicalTypeID::STRING},
LogicalTypeID::BOOL,
ScalarFunction::BinaryExecFunction<string_t, string_t, uint8_t, RegexpFullMatch>,
ScalarFunction::BinarySelectFunction<string_t, string_t, RegexpFullMatch>);
scalarFunc->bindFunc = regexFullMatchBindFunc;
functionSet.emplace_back(std::move(scalarFunc));
return functionSet;
}
} }