|
17 | 17 |
|
18 | 18 | #include "gandiva/random_generator_holder.h" |
19 | 19 | #include "gandiva/node.h" |
| 20 | +#include "gandiva/projector.h" |
| 21 | +#include "arrow/memory_pool.h" |
| 22 | +#include "arrow/status.h" |
| 23 | +#include "gandiva/tree_expr_builder.h" |
| 24 | +//#include "gandiva/tests/test_util.h" |
| 25 | +#include "arrow/type_traits.h" |
| 26 | +#include "arrow/array/builder_binary.h" |
| 27 | +#include "arrow/array/builder_primitive.h" |
| 28 | +#include "arrow/array/builder_base.h" |
| 29 | +#include <type_traits> |
| 30 | + |
20 | 31 |
|
21 | 32 | namespace gandiva { |
22 | 33 | Status RandomGeneratorHolder::Make(const FunctionNode& node, |
23 | 34 | std::shared_ptr<RandomGeneratorHolder>* holder) { |
24 | | - ARROW_RETURN_IF(node.children().size() > 1, |
25 | | - Status::Invalid("'random' function requires at most one parameter")); |
| 35 | + ARROW_RETURN_IF(node.children().size() > 2, |
| 36 | + Status::Invalid("'random' function requires at most two parameters")); |
26 | 37 |
|
27 | 38 | if (node.children().size() == 0) { |
28 | 39 | *holder = std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder()); |
29 | 40 | return Status::OK(); |
30 | 41 | } |
31 | 42 |
|
32 | 43 | auto literal = dynamic_cast<LiteralNode*>(node.children().at(0).get()); |
33 | | - ARROW_RETURN_IF(literal == nullptr, |
34 | | - Status::Invalid("'random' function requires a literal as parameter")); |
35 | | - |
36 | | - auto literal_type = literal->return_type()->id(); |
37 | | - ARROW_RETURN_IF( |
| 44 | + //ARROW_RETURN_IF(literal == nullptr, |
| 45 | + // Status::Invalid("'random' function requires a literal as parameter")); |
| 46 | + int64_t seed; |
| 47 | + if (literal != nullptr) { |
| 48 | + auto literal_type = literal->return_type()->id(); |
| 49 | + ARROW_RETURN_IF( |
38 | 50 | literal_type != arrow::Type::INT32 && literal_type != arrow::Type::INT64, |
39 | 51 | Status::Invalid("'random' function requires an int32/int64 literal as parameter")); |
40 | | - |
41 | | - if (literal_type == arrow::Type::INT32) { |
42 | | - *holder = std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder( |
43 | | - literal->is_null() ? 0 : arrow::util::get<int32_t>(literal->holder()))); |
| 52 | + if (literal_type == arrow::Type::INT32) { |
| 53 | + seed = literal->is_null() ? 0 : arrow::util::get<int32_t>(literal->holder()); |
| 54 | + } else { |
| 55 | + seed = literal->is_null() ? 0 : arrow::util::get<int64_t>(literal->holder()); |
| 56 | + } |
44 | 57 | } else { |
45 | | - *holder = std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder( |
46 | | - literal->is_null() ? 0 : arrow::util::get<int64_t>(literal->holder()))); |
| 58 | + auto first_children_node_ptr = node.children().at(0); |
| 59 | + //auto schema = arrow::schema({}); |
| 60 | + auto f0 = arrow::field("f0", arrow::float64()); |
| 61 | + auto schema = arrow::schema({f0}); |
| 62 | + std::shared_ptr<Projector> projector; |
| 63 | + // Not actually used. |
| 64 | + auto res = field("res", arrow::int32()); |
| 65 | + auto expr = TreeExprBuilder::MakeExpression(first_children_node_ptr, res); |
| 66 | + auto builder = ConfigurationBuilder(); |
| 67 | + auto config = builder.DefaultConfiguration(); |
| 68 | + auto status = Projector::Make(schema, {expr}, config, &projector); |
| 69 | + arrow::ArrayVector outputs; |
| 70 | + arrow::MemoryPool* pool = arrow::default_memory_pool(); |
| 71 | + |
| 72 | + //arrow::ArrayVector inputs; |
| 73 | + //auto in_batch = arrow::RecordBatch::Make(schema, 0, inputs); |
| 74 | + |
| 75 | + std::vector<int> input0 = {16, 10, -14, 8}; |
| 76 | + std::vector<bool> validity = {true, true, true, true}; |
| 77 | + std::shared_ptr<arrow::Array> array0; |
| 78 | + //arrow::ArrayFromVector<arrow::DoubleType, double>(validity, values, &array0); |
| 79 | + //auto array0 = MakeArrowArray<arrow::DoubleType, double>(input0, validity); |
| 80 | + |
| 81 | + auto type = arrow::TypeTraits<arrow::Int32Type>::type_singleton(); |
| 82 | + std::unique_ptr<arrow::ArrayBuilder> builder_ptr; |
| 83 | + MakeBuilder(pool, type, &builder_ptr); |
| 84 | + auto& arrow_array_builder = dynamic_cast<typename arrow::TypeTraits<arrow::Int32Type>::BuilderType&>(*builder_ptr); |
| 85 | + for (size_t i = 0; i < input0.size(); ++i) { |
| 86 | + arrow_array_builder.Append(input0[i]); |
| 87 | + } |
| 88 | + arrow_array_builder.Finish(&array0); |
| 89 | + |
| 90 | + auto in_batch = arrow::RecordBatch::Make(schema, 4, {array0}); |
| 91 | + |
| 92 | + //arrow::RecordBatch in_batch; |
| 93 | + projector->Evaluate(*in_batch, pool, &outputs); |
| 94 | + auto result_arr = std::dynamic_pointer_cast<arrow::Int32Array>(outputs.at(0)); |
| 95 | + //seed = dynamic_cast<int32_t>(result_arr->Value(0)); |
| 96 | + seed = result_arr->Value(0); |
| 97 | + } |
| 98 | + // The offset is a partition ID in spark SQL. It is used to achieve genuine random distribution globally. |
| 99 | + int32_t offset = 0; |
| 100 | + if (node.children().size() > 1) { |
| 101 | + auto offset_node = dynamic_cast<LiteralNode*>(node.children().at(1).get()); |
| 102 | + offset = offset_node->is_null() ? 0 : arrow::util::get<int32_t>(offset_node->holder()); |
47 | 103 | } |
| 104 | + *holder = std::shared_ptr<RandomGeneratorHolder>(new RandomGeneratorHolder(seed + offset)); |
48 | 105 | return Status::OK(); |
49 | 106 | } |
50 | 107 | } // namespace gandiva |
0 commit comments