Skip to content

Commit 9072da6

Browse files
pravindrapraveenbingo
authored andcommitted
GDV-56: [C++] Add support for sql regex functions (apache#86)
- add a registry for "function holders" implemented in cpp - the function holder is instantiated at expression decomposition time - at eval time, the registered fn gets an extra param (the . function holder)
1 parent 4526468 commit 9072da6

22 files changed

Lines changed: 591 additions & 216 deletions

cpp/src/gandiva/codegen/CMakeLists.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ set(SRC_FILES annotator.cc
3535
function_signature.cc
3636
llvm_generator.cc
3737
llvm_types.cc
38+
like_holder.cc
3839
projector.cc
3940
selection_vector.cc
41+
regex_util.cc
4042
status.cc
4143
tree_expr_builder.cc
4244
${BC_FILE_PATH_CC})
@@ -84,17 +86,16 @@ install(
8486

8587
#args: label test-file src-files
8688
add_gandiva_unit_test(bitmap_accumulator_test.cc bitmap_accumulator.cc)
87-
add_gandiva_unit_test(dex_llvm_test.cc)
8889
add_gandiva_unit_test(engine_llvm_test.cc engine.cc llvm_types.cc status.cc configuration.cc ${BC_FILE_PATH_CC})
8990
add_gandiva_unit_test(function_signature_test.cc function_signature.cc)
9091
add_gandiva_unit_test(function_registry_test.cc function_registry.cc function_signature.cc)
9192
add_gandiva_unit_test(llvm_types_test.cc llvm_types.cc)
92-
add_gandiva_unit_test(llvm_generator_test.cc llvm_generator.cc engine.cc llvm_types.cc expr_decomposer.cc function_registry.cc annotator.cc status.cc bitmap_accumulator.cc configuration.cc function_signature.cc ${BC_FILE_PATH_CC})
93+
add_gandiva_unit_test(llvm_generator_test.cc llvm_generator.cc regex_util.cc engine.cc llvm_types.cc expr_decomposer.cc function_registry.cc annotator.cc status.cc bitmap_accumulator.cc configuration.cc function_signature.cc like_holder.cc regex_util.cc ${BC_FILE_PATH_CC})
9394
add_gandiva_unit_test(annotator_test.cc annotator.cc function_signature.cc)
94-
add_gandiva_unit_test(tree_expr_test.cc tree_expr_builder.cc expr_decomposer.cc annotator.cc function_registry.cc function_signature.cc)
95-
add_gandiva_unit_test(expr_decomposer_test.cc expr_decomposer.cc tree_expr_builder.cc annotator.cc function_registry.cc function_signature.cc)
95+
add_gandiva_unit_test(tree_expr_test.cc tree_expr_builder.cc expr_decomposer.cc annotator.cc function_registry.cc function_signature.cc like_holder.cc regex_util.cc status.cc)
96+
add_gandiva_unit_test(expr_decomposer_test.cc expr_decomposer.cc tree_expr_builder.cc annotator.cc function_registry.cc function_signature.cc like_holder.cc regex_util.cc status.cc)
9697
add_gandiva_unit_test(status_test.cc status.cc)
9798
add_gandiva_unit_test(expression_registry_test.cc llvm_types.cc expression_registry.cc function_signature.cc function_registry.cc)
9899
add_gandiva_unit_test(selection_vector_test.cc selection_vector.cc status.cc)
99100
add_gandiva_unit_test(lru_cache_test.cc)
100-
101+
add_gandiva_unit_test(like_holder_test.cc like_holder.cc regex_util.cc status.cc)

cpp/src/gandiva/codegen/dex.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "codegen/dex_visitor.h"
2222
#include "codegen/field_descriptor.h"
2323
#include "codegen/func_descriptor.h"
24+
#include "codegen/function_holder.h"
2425
#include "codegen/literal_holder.h"
2526
#include "codegen/native_function.h"
2627
#include "codegen/value_validity_pair.h"
@@ -104,20 +105,24 @@ class LocalBitMapValidityDex : public Dex {
104105
class FuncDex : public Dex {
105106
public:
106107
FuncDex(FuncDescriptorPtr func_descriptor, const NativeFunction *native_function,
107-
const ValueValidityPairVector &args)
108+
FunctionHolderPtr function_holder, const ValueValidityPairVector &args)
108109
: func_descriptor_(func_descriptor),
109110
native_function_(native_function),
111+
function_holder_(function_holder),
110112
args_(args) {}
111113

112114
FuncDescriptorPtr func_descriptor() const { return func_descriptor_; }
113115

114116
const NativeFunction *native_function() const { return native_function_; }
115117

118+
FunctionHolderPtr function_holder() const { return function_holder_; }
119+
116120
const ValueValidityPairVector &args() const { return args_; }
117121

118122
private:
119123
FuncDescriptorPtr func_descriptor_;
120124
const NativeFunction *native_function_;
125+
FunctionHolderPtr function_holder_;
121126
ValueValidityPairVector args_;
122127
};
123128

@@ -127,8 +132,9 @@ class NonNullableFuncDex : public FuncDex {
127132
public:
128133
NonNullableFuncDex(FuncDescriptorPtr func_descriptor,
129134
const NativeFunction *native_function,
135+
FunctionHolderPtr function_holder,
130136
const ValueValidityPairVector &args)
131-
: FuncDex(func_descriptor, native_function, args) {}
137+
: FuncDex(func_descriptor, native_function, function_holder, args) {}
132138

133139
void Accept(DexVisitor &visitor) override { visitor.Visit(*this); }
134140
};
@@ -139,8 +145,9 @@ class NullableNeverFuncDex : public FuncDex {
139145
public:
140146
NullableNeverFuncDex(FuncDescriptorPtr func_descriptor,
141147
const NativeFunction *native_function,
148+
FunctionHolderPtr function_holder,
142149
const ValueValidityPairVector &args)
143-
: FuncDex(func_descriptor, native_function, args) {}
150+
: FuncDex(func_descriptor, native_function, function_holder, args) {}
144151

145152
void Accept(DexVisitor &visitor) override { visitor.Visit(*this); }
146153
};
@@ -151,8 +158,9 @@ class NullableInternalFuncDex : public FuncDex {
151158
public:
152159
NullableInternalFuncDex(FuncDescriptorPtr func_descriptor,
153160
const NativeFunction *native_function,
161+
FunctionHolderPtr function_holder,
154162
const ValueValidityPairVector &args, int local_bitmap_idx)
155-
: FuncDex(func_descriptor, native_function, args),
163+
: FuncDex(func_descriptor, native_function, function_holder, args),
156164
local_bitmap_idx_(local_bitmap_idx) {}
157165

158166
void Accept(DexVisitor &visitor) override { visitor.Visit(*this); }

cpp/src/gandiva/codegen/dex_llvm_test.cc

Lines changed: 0 additions & 147 deletions
This file was deleted.

cpp/src/gandiva/codegen/expr_decomposer.cc

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "codegen/annotator.h"
2323
#include "codegen/dex.h"
24+
#include "codegen/function_holder_registry.h"
2425
#include "codegen/function_registry.h"
2526
#include "codegen/node.h"
2627
#include "gandiva/function_signature.h"
@@ -53,10 +54,19 @@ Status ExprDecomposer::Visit(const FunctionNode &node) {
5354
// decompose the children.
5455
std::vector<ValueValidityPairPtr> args;
5556
for (auto &child : node.children()) {
56-
child->Accept(*this);
57+
auto status = child->Accept(*this);
58+
GANDIVA_RETURN_NOT_OK(status);
59+
5760
args.push_back(result());
5861
}
5962

63+
// Make a function holder, if required.
64+
std::shared_ptr<FunctionHolder> holder;
65+
if (native_function->needs_holder()) {
66+
auto status = FunctionHolderRegistry::Make(desc->name(), node, &holder);
67+
GANDIVA_RETURN_NOT_OK(status);
68+
}
69+
6070
if (native_function->result_nullable_type() == RESULT_NULL_IF_NULL) {
6171
// These functions are decomposable, merge the validity bits of the children.
6272

@@ -68,11 +78,13 @@ Status ExprDecomposer::Visit(const FunctionNode &node) {
6878
decomposed->validity_exprs().end());
6979
}
7080

71-
auto value_dex = std::make_shared<NonNullableFuncDex>(desc, native_function, args);
81+
auto value_dex =
82+
std::make_shared<NonNullableFuncDex>(desc, native_function, holder, args);
7283
result_ = std::make_shared<ValueValidityPair>(merged_validity, value_dex);
7384
} else if (native_function->result_nullable_type() == RESULT_NULL_NEVER) {
7485
// These functions always output valid results. So, no validity dex.
75-
auto value_dex = std::make_shared<NullableNeverFuncDex>(desc, native_function, args);
86+
auto value_dex =
87+
std::make_shared<NullableNeverFuncDex>(desc, native_function, holder, args);
7688
result_ = std::make_shared<ValueValidityPair>(value_dex);
7789
} else {
7890
DCHECK(native_function->result_nullable_type() == RESULT_NULL_INTERNAL);
@@ -81,8 +93,8 @@ Status ExprDecomposer::Visit(const FunctionNode &node) {
8193
int local_bitmap_idx = annotator_.AddLocalBitMap();
8294
auto validity_dex = std::make_shared<LocalBitMapValidityDex>(local_bitmap_idx);
8395

84-
auto value_dex = std::make_shared<NullableInternalFuncDex>(desc, native_function,
85-
args, local_bitmap_idx);
96+
auto value_dex = std::make_shared<NullableInternalFuncDex>(
97+
desc, native_function, holder, args, local_bitmap_idx);
8698
result_ = std::make_shared<ValueValidityPair>(validity_dex, value_dex);
8799
}
88100
return Status::OK();
@@ -91,16 +103,19 @@ Status ExprDecomposer::Visit(const FunctionNode &node) {
91103
// Decompose an IfNode
92104
Status ExprDecomposer::Visit(const IfNode &node) {
93105
// Add a local bitmap to track the output validity.
94-
node.condition()->Accept(*this);
106+
auto status = node.condition()->Accept(*this);
107+
GANDIVA_RETURN_NOT_OK(status);
95108
auto condition_vv = result();
96109

97110
int local_bitmap_idx = PushThenEntry(node);
98-
node.then_node()->Accept(*this);
111+
status = node.then_node()->Accept(*this);
112+
GANDIVA_RETURN_NOT_OK(status);
99113
auto then_vv = result();
100114
PopThenEntry(node);
101115

102116
PushElseEntry(node, local_bitmap_idx);
103-
node.else_node()->Accept(*this);
117+
status = node.else_node()->Accept(*this);
118+
GANDIVA_RETURN_NOT_OK(status);
104119
auto else_vv = result();
105120
bool is_terminal_else = PopElseEntry(node);
106121

@@ -118,7 +133,9 @@ Status ExprDecomposer::Visit(const BooleanNode &node) {
118133
// decompose the children.
119134
std::vector<ValueValidityPairPtr> args;
120135
for (auto &child : node.children()) {
121-
child->Accept(*this);
136+
auto status = child->Accept(*this);
137+
GANDIVA_RETURN_NOT_OK(status);
138+
122139
args.push_back(result());
123140
}
124141

cpp/src/gandiva/codegen/expr_decomposer.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@ class ExprDecomposer : public NodeVisitor {
3636
explicit ExprDecomposer(const FunctionRegistry &registry, Annotator &annotator)
3737
: registry_(registry), annotator_(annotator) {}
3838

39-
ValueValidityPairPtr Decompose(const Node &root) {
40-
root.Accept(*this);
41-
return result();
39+
Status Decompose(const Node &root, ValueValidityPairPtr *out) {
40+
auto status = root.Accept(*this);
41+
if (status.ok()) {
42+
*out = std::move(result_);
43+
}
44+
return status;
4245
}
4346

4447
private:

cpp/src/gandiva/codegen/expression_registry.cc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,26 @@ ExpressionRegistry::~ExpressionRegistry() {}
2929

3030
const ExpressionRegistry::FunctionSignatureIterator
3131
ExpressionRegistry::function_signature_begin() {
32-
return FunctionSignatureIterator(function_registry_->begin(),
33-
function_registry_->end());
32+
return FunctionSignatureIterator(function_registry_->begin());
3433
}
3534

3635
const ExpressionRegistry::FunctionSignatureIterator
3736
ExpressionRegistry::function_signature_end() const {
38-
return FunctionSignatureIterator(function_registry_->end(), function_registry_->end());
37+
return FunctionSignatureIterator(function_registry_->end());
3938
}
4039

4140
bool ExpressionRegistry::FunctionSignatureIterator::operator!=(
4241
const FunctionSignatureIterator &func_sign_it) {
43-
return func_sign_it.it != this->it;
42+
return func_sign_it.it_ != this->it_;
4443
}
4544

4645
FunctionSignature ExpressionRegistry::FunctionSignatureIterator::operator*() {
47-
return (*it).signature();
46+
return (*it_).signature();
4847
}
4948

5049
ExpressionRegistry::iterator ExpressionRegistry::FunctionSignatureIterator::operator++(
5150
int increment) {
52-
return it++;
51+
return it_++;
5352
}
5453

5554
DataTypeVector ExpressionRegistry::supported_types_ =

0 commit comments

Comments
 (0)