bkmgit commented on a change in pull request #11882:
URL: https://github.com/apache/arrow/pull/11882#discussion_r786222578
##########
File path: cpp/src/arrow/compute/kernels/scalar_compare.cc
##########
@@ -746,6 +808,279 @@ std::shared_ptr<ScalarFunction>
MakeScalarMinMax(std::string name,
return func;
}
+template <template <BetweenOptions::Inclusive> class Op>
+std::shared_ptr<ScalarFunction> MakeBetweenFunction(std::string name,
+ const FunctionDoc* doc) {
+ using BetweenState = OptionsWrapper<BetweenOptions>;
+ static const auto kDefaultOptions = BetweenOptions::Defaults();
+ auto func =
+ std::make_shared<CompareFunction>(name, Arity::Ternary(), doc,
&kDefaultOptions);
+
+ // Add kernels for physical numeric types, temporal types done separately
+ for (const auto& types : {DurationTypes(), IntervalTypes(), NumericTypes()})
{
+ for (const auto& ty : types) {
+ auto type_id = ty->id();
+ auto exec = [type_id](KernelContext* ctx, const ExecBatch& batch, Datum*
out) {
+ // Resolve generator based on options
+ const auto& state = static_cast<const BetweenState&>(*ctx->state());
+ switch (state.options.inclusive) {
+ case BetweenOptions::Inclusive::BOTH:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes,
BooleanType,
+
Op<BetweenOptions::Inclusive::BOTH>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::LEFT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes,
BooleanType,
+
Op<BetweenOptions::Inclusive::LEFT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::RIGHT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes,
BooleanType,
+
Op<BetweenOptions::Inclusive::RIGHT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::NEITHER:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes,
BooleanType,
+
Op<BetweenOptions::Inclusive::NEITHER>>(
+ type_id)(ctx, batch, out);
+ default:
+ return Status::NotImplemented("between inclusiveness not
implemented: ",
+ state.options.ToString());
+ }
+ };
+ DCHECK_OK(func->AddKernel({ty, ty, ty}, boolean(), exec,
BetweenState::Init));
+ }
+ }
+
+ // Add timestamp kernels
+ for (const auto unit : TimeUnit::values()) {
+ InputType in_type(match::TimestampTypeUnit(unit));
+ auto type_id = Type::TIMESTAMP;
+ auto exec = [type_id](KernelContext* ctx, const ExecBatch& batch, Datum*
out) {
+ // Validate timezones in all entries or in none
+ RETURN_NOT_OK(CheckCompareTimestamps(batch));
+ // Resolve generator based on options
+ const auto& state = static_cast<const BetweenState&>(*ctx->state());
+ switch (state.options.inclusive) {
+ case BetweenOptions::Inclusive::BOTH:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::BOTH>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::LEFT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::LEFT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::RIGHT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::RIGHT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::NEITHER:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::NEITHER>>(type_id)(
+ ctx, batch, out);
+ default:
+ return Status::NotImplemented("between inclusiveness not
implemented: ",
+ state.options.ToString());
+ }
+ };
+ DCHECK_OK(func->AddKernel({in_type, in_type, in_type}, boolean(), exec,
+ BetweenState::Init));
+ }
+
+ // Add time kernels
+ for (const auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) {
+ auto type_id = Type::TIME32;
+ auto exec = [type_id](KernelContext* ctx, const ExecBatch& batch, Datum*
out) {
+ // Resolve generator based on options
+ const auto& state = static_cast<const BetweenState&>(*ctx->state());
+ switch (state.options.inclusive) {
+ case BetweenOptions::Inclusive::BOTH:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::BOTH>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::LEFT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::LEFT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::RIGHT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::RIGHT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::NEITHER:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::NEITHER>>(type_id)(
+ ctx, batch, out);
+ default:
+ return Status::NotImplemented("between inclusiveness not
implemented: ",
+ state.options.ToString());
+ }
+ };
+ InputType in_type(match::Time32TypeUnit(unit));
+ DCHECK_OK(func->AddKernel({in_type, in_type, in_type}, boolean(), exec,
+ BetweenState::Init));
+ }
+
+ for (const auto& unit : {TimeUnit::MICRO, TimeUnit::NANO}) {
+ auto type_id = Type::TIME64;
+ auto exec = [type_id](KernelContext* ctx, const ExecBatch& batch, Datum*
out) {
+ // Resolve generator based on options
+ const auto& state = static_cast<const BetweenState&>(*ctx->state());
+ switch (state.options.inclusive) {
+ case BetweenOptions::Inclusive::BOTH:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::BOTH>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::LEFT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::LEFT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::RIGHT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::RIGHT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::NEITHER:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::NEITHER>>(type_id)(
+ ctx, batch, out);
+ default:
+ return Status::NotImplemented("between inclusiveness not
implemented: ",
+ state.options.ToString());
+ }
+ };
+ InputType in_type(match::Time64TypeUnit(unit));
+ DCHECK_OK(func->AddKernel({in_type, in_type, in_type}, boolean(), exec,
+ BetweenState::Init));
+ }
+
+ // Add kernels for base binary types
+ for (const auto& ty : BaseBinaryTypes()) {
+ auto type_id = ty->id();
+ auto exec = [type_id](KernelContext* ctx, const ExecBatch& batch, Datum*
out) {
+ // Resolve generator based on options
+ const auto& state = static_cast<const BetweenState&>(*ctx->state());
+ switch (state.options.inclusive) {
+ case BetweenOptions::Inclusive::BOTH:
+ return GenerateVarBinaryBase<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::BOTH>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::LEFT:
+ return GenerateVarBinaryBase<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::LEFT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::RIGHT:
+ return GenerateVarBinaryBase<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::RIGHT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::NEITHER:
+ return GenerateVarBinaryBase<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::NEITHER>>(type_id)(
+ ctx, batch, out);
+ default:
+ return Status::NotImplemented("between inclusiveness not
implemented: ",
+ state.options.ToString());
+ }
+ };
+ DCHECK_OK(func->AddKernel({ty, ty, ty}, boolean(), exec,
BetweenState::Init));
+ }
+
+ // Add kernels for decimal types
+ for (const auto type_id : {Type::DECIMAL128, Type::DECIMAL256}) {
+ auto exec = [type_id](KernelContext* ctx, const ExecBatch& batch, Datum*
out) {
+ // Resolve generator based on options
+ const auto& state = static_cast<const BetweenState&>(*ctx->state());
+ switch (state.options.inclusive) {
+ case BetweenOptions::Inclusive::BOTH:
+ return GenerateDecimal<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::BOTH>>(type_id)(ctx, batch,
+
out);
+ case BetweenOptions::Inclusive::LEFT:
+ return GenerateDecimal<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::LEFT>>(type_id)(ctx, batch,
+
out);
+ case BetweenOptions::Inclusive::RIGHT:
+ return GenerateDecimal<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::RIGHT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::NEITHER:
+ return GenerateDecimal<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::NEITHER>>(type_id)(
+ ctx, batch, out);
+ default:
+ return Status::NotImplemented("between inclusiveness not
implemented: ",
+ state.options.ToString());
+ }
+ };
+ InputType ty(type_id);
+ DCHECK_OK(func->AddKernel({ty, ty, ty}, boolean(), exec,
BetweenState::Init));
+ }
+
+ // Add kernels for date types
+ for (const auto type_id : {Type::DATE32, Type::DATE64}) {
+ auto exec = [type_id](KernelContext* ctx, const ExecBatch& batch, Datum*
out) {
+ // Resolve generator based on options
+ const auto& state = static_cast<const BetweenState&>(*ctx->state());
+ switch (state.options.inclusive) {
+ case BetweenOptions::Inclusive::BOTH:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::BOTH>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::LEFT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::LEFT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::RIGHT:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::RIGHT>>(type_id)(
+ ctx, batch, out);
+ case BetweenOptions::Inclusive::NEITHER:
+ return GeneratePhysicalNumeric<ScalarTernaryEqualTypes, BooleanType,
+
Op<BetweenOptions::Inclusive::NEITHER>>(type_id)(
+ ctx, batch, out);
+ default:
+ return Status::NotImplemented("between inclusiveness not
implemented: ",
+ state.options.ToString());
+ }
+ };
Review comment:
Ok.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]