This is an automated email from the ASF dual-hosted git repository.
lgbo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-gluten.git
The following commit(s) were added to refs/heads/main by this push:
new 8ebd283434 simplify subtrait parsing (#8976)
8ebd283434 is described below
commit 8ebd283434810b08c6cc110b10703cbb75216997
Author: lgbo <[email protected]>
AuthorDate: Thu Mar 13 11:41:01 2025 +0800
simplify subtrait parsing (#8976)
---
.../local-engine/Builder/SerializedPlanBuilder.cpp | 8 -----
cpp-ch/local-engine/Parser/ExpressionParser.cpp | 11 +++---
cpp-ch/local-engine/Parser/FunctionExecutor.cpp | 6 ++--
.../Parser/RelParsers/AggregateRelParser.cpp | 8 +++--
.../Parser/RelParsers/ExpandRelParser.cpp | 14 ++++----
.../Parser/RelParsers/GroupLimitRelParser.cpp | 9 ++---
.../Parser/RelParsers/JoinRelParser.cpp | 42 ++++++++--------------
.../Parser/RelParsers/MergeTreeRelParser.cpp | 8 +++--
.../Parser/RelParsers/SortParsingUtils.cpp | 22 ++++++------
.../local-engine/Parser/SerializedPlanParser.cpp | 5 ++-
.../local-engine/Parser/SubstraitParserUtils.cpp | 41 +++++++++++++++++++++
cpp-ch/local-engine/Parser/SubstraitParserUtils.h | 9 +++++
12 files changed, 110 insertions(+), 73 deletions(-)
diff --git a/cpp-ch/local-engine/Builder/SerializedPlanBuilder.cpp
b/cpp-ch/local-engine/Builder/SerializedPlanBuilder.cpp
index be5a9ca4b0..f90bd12176 100644
--- a/cpp-ch/local-engine/Builder/SerializedPlanBuilder.cpp
+++ b/cpp-ch/local-engine/Builder/SerializedPlanBuilder.cpp
@@ -312,14 +312,6 @@ void SerializedPlanBuilder::buildType(const
DB::DataTypePtr & ch_type, String &
substrait_type = pb->SerializeAsString();
}
-
-substrait::Expression * selection(int32_t field_id)
-{
- substrait::Expression * rel = new substrait::Expression();
- auto * selection = rel->mutable_selection();
-
selection->mutable_direct_reference()->mutable_struct_field()->set_field(field_id);
- return rel;
-}
substrait::Expression * scalarFunction(int32_t id, ExpressionList args)
{
substrait::Expression * rel = new substrait::Expression();
diff --git a/cpp-ch/local-engine/Parser/ExpressionParser.cpp
b/cpp-ch/local-engine/Parser/ExpressionParser.cpp
index 99bc5b3ff4..fb78066e8d 100644
--- a/cpp-ch/local-engine/Parser/ExpressionParser.cpp
+++ b/cpp-ch/local-engine/Parser/ExpressionParser.cpp
@@ -35,6 +35,7 @@
#include <Parser/FunctionParser.h>
#include <Parser/ParserContext.h>
#include <Parser/SerializedPlanParser.h>
+#include <Parser/SubstraitParserUtils.h>
#include <Parser/TypeParser.h>
#include <Poco/Logger.h>
#include <Common/BlockTypeUtils.h>
@@ -293,10 +294,11 @@ ExpressionParser::NodeRawConstPtr
ExpressionParser::parseExpression(ActionsDAG &
}
case substrait::Expression::RexTypeCase::kSelection: {
- if (!rel.selection().has_direct_reference() ||
!rel.selection().direct_reference().has_struct_field())
+ auto field_index = SubstraitParserUtils::getStructFieldIndex(rel);
+ if (!field_index)
throw DB::Exception(DB::ErrorCodes::BAD_ARGUMENTS, "Can only
have direct struct references in selections");
- const auto * field =
actions_dag.getInputs()[rel.selection().direct_reference().struct_field().field()];
+ const auto * field = actions_dag.getInputs()[*field_index];
return field;
}
@@ -521,10 +523,9 @@ ExpressionParser::expressionsToActionsDAG(const
std::vector<substrait::Expressio
for (const auto & expr : expressions)
{
- if (expr.has_selection())
+ if (auto field_index = SubstraitParserUtils::getStructFieldIndex(expr))
{
- auto position =
expr.selection().direct_reference().struct_field().field();
- auto col_name = header.getByPosition(position).name;
+ auto col_name = header.getByPosition(*field_index).name;
const DB::ActionsDAG::Node * field =
actions_dag.tryFindInOutputs(col_name);
if (!field)
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Not found
{} in actions dag's output", col_name);
diff --git a/cpp-ch/local-engine/Parser/FunctionExecutor.cpp
b/cpp-ch/local-engine/Parser/FunctionExecutor.cpp
index 2cef922ba4..93f30d55d5 100644
--- a/cpp-ch/local-engine/Parser/FunctionExecutor.cpp
+++ b/cpp-ch/local-engine/Parser/FunctionExecutor.cpp
@@ -19,6 +19,7 @@
#include <Builder/SerializedPlanBuilder.h>
#include <Core/ColumnWithTypeAndName.h>
#include <Common/BlockTypeUtils.h>
+#include <Parser/SubstraitParserUtils.h>
namespace DB
{
@@ -57,10 +58,7 @@ void FunctionExecutor::buildExpression()
[&](const auto & ) {
substrait::FunctionArgument argument;
auto * value = argument.mutable_value();
- auto * selection = value->mutable_selection();
- auto * direct_reference = selection->mutable_direct_reference();
- auto * struct_field = direct_reference->mutable_struct_field();
- struct_field->set_field(field++);
+
value->CopyFrom(SubstraitParserUtils::buildStructFieldExpression(field++));
arguments->Add(std::move(argument));
});
diff --git a/cpp-ch/local-engine/Parser/RelParsers/AggregateRelParser.cpp
b/cpp-ch/local-engine/Parser/RelParsers/AggregateRelParser.cpp
index ef98bba618..1cdf03091b 100644
--- a/cpp-ch/local-engine/Parser/RelParsers/AggregateRelParser.cpp
+++ b/cpp-ch/local-engine/Parser/RelParsers/AggregateRelParser.cpp
@@ -28,6 +28,7 @@
#include <Operator/StreamingAggregatingStep.h>
#include <Parser/AdvancedParametersParseUtil.h>
#include <Parser/AggregateFunctionParser.h>
+#include <Parser/SubstraitParserUtils.h>
#include <Processors/QueryPlan/AggregatingStep.h>
#include <Processors/QueryPlan/ExpressionStep.h>
#include <Processors/QueryPlan/MergingAggregatedStep.h>
@@ -186,10 +187,13 @@ void AggregateRelParser::setup(DB::QueryPlanPtr
query_plan, const substrait::Rel
if (aggregate_rel->groupings_size() == 1)
{
for (const auto & expr :
aggregate_rel->groupings(0).grouping_expressions())
- if (expr.has_selection() &&
expr.selection().has_direct_reference())
-
grouping_keys.push_back(input_header.getByPosition(expr.selection().direct_reference().struct_field().field()).name);
+ {
+ auto field_index = SubstraitParserUtils::getStructFieldIndex(expr);
+ if (field_index)
+
grouping_keys.push_back(input_header.getByPosition(*field_index).name);
else
throw Exception(ErrorCodes::BAD_ARGUMENTS, "unsupported group
expression: {}", expr.DebugString());
+ }
}
else if (aggregate_rel->groupings_size() != 0)
{
diff --git a/cpp-ch/local-engine/Parser/RelParsers/ExpandRelParser.cpp
b/cpp-ch/local-engine/Parser/RelParsers/ExpandRelParser.cpp
index 7d31fcf2bc..d261bc5dd6 100644
--- a/cpp-ch/local-engine/Parser/RelParsers/ExpandRelParser.cpp
+++ b/cpp-ch/local-engine/Parser/RelParsers/ExpandRelParser.cpp
@@ -23,6 +23,7 @@
#include <Operator/AdvancedExpandStep.h>
#include <Operator/ExpandStep.h>
#include <Parser/RelParsers/RelParser.h>
+#include <Parser/SubstraitParserUtils.h>
#include <Processors/QueryPlan/QueryPlan.h>
#include <Common/logger_useful.h>
@@ -83,18 +84,17 @@ ExpandField ExpandRelParser::buildExpandField(const
DB::Block & header, const su
for (int i = 0; i < expand_col_size; ++i)
{
const auto & project_expr =
projections.switching_field().duplicates(i);
- if (project_expr.has_selection())
+ if (auto field_index =
SubstraitParserUtils::getStructFieldIndex(project_expr))
{
- auto field =
project_expr.selection().direct_reference().struct_field().field();
kinds.push_back(ExpandFieldKind::EXPAND_FIELD_KIND_SELECTION);
- fields.push_back(field);
- if (field >= header.columns())
+ fields.push_back(*field_index);
+ if (*field_index >= header.columns())
{
throw DB::Exception(
- DB::ErrorCodes::LOGICAL_ERROR, "Field index out of
range: {}, header: {}", field, header.dumpStructure());
+ DB::ErrorCodes::LOGICAL_ERROR, "Field index out of
range: {}, header: {}", *field_index, header.dumpStructure());
}
- updateType(types[i], header.getByPosition(field).type);
- const auto & name = header.getByPosition(field).name;
+ updateType(types[i], header.getByPosition(*field_index).type);
+ const auto & name = header.getByPosition(*field_index).name;
if (names[i].empty())
{
if (distinct_names.contains(name))
diff --git a/cpp-ch/local-engine/Parser/RelParsers/GroupLimitRelParser.cpp
b/cpp-ch/local-engine/Parser/RelParsers/GroupLimitRelParser.cpp
index 6359959ebc..597d90adaa 100644
--- a/cpp-ch/local-engine/Parser/RelParsers/GroupLimitRelParser.cpp
+++ b/cpp-ch/local-engine/Parser/RelParsers/GroupLimitRelParser.cpp
@@ -36,6 +36,7 @@
#include <Parser/AdvancedParametersParseUtil.h>
#include <Parser/RelParsers/SortParsingUtils.h>
#include <Parser/RelParsers/SortRelParser.h>
+#include <Parser/SubstraitParserUtils.h>
#include <Processors/QueryPlan/ExpressionStep.h>
#include <Processors/QueryPlan/FilterStep.h>
#include <Processors/QueryPlan/QueryPlan.h>
@@ -100,8 +101,8 @@ static std::vector<size_t> parsePartitionFields(const
google::protobuf::Repeated
{
std::vector<size_t> fields;
for (const auto & expr : expressions)
- if (expr.has_selection())
-
fields.push_back(static_cast<size_t>(expr.selection().direct_reference().struct_field().field()));
+ if (auto field_index = SubstraitParserUtils::getStructFieldIndex(expr))
+ fields.push_back(*field_index);
else if (expr.has_literal())
continue;
else
@@ -115,8 +116,8 @@ std::vector<size_t> parseSortFields(const
google::protobuf::RepeatedPtrField<sub
for (const auto sort_field : sort_fields)
if (sort_field.expr().has_literal())
continue;
- else if (sort_field.expr().has_selection())
-
fields.push_back(static_cast<size_t>(sort_field.expr().selection().direct_reference().struct_field().field()));
+ else if (auto field_index =
SubstraitParserUtils::getStructFieldIndex(sort_field.expr()))
+ fields.push_back(*field_index);
else
throw DB::Exception(DB::ErrorCodes::BAD_ARGUMENTS, "Unknown
expression: {}", sort_field.expr().DebugString());
return fields;
diff --git a/cpp-ch/local-engine/Parser/RelParsers/JoinRelParser.cpp
b/cpp-ch/local-engine/Parser/RelParsers/JoinRelParser.cpp
index 1842e8e107..9355777b44 100644
--- a/cpp-ch/local-engine/Parser/RelParsers/JoinRelParser.cpp
+++ b/cpp-ch/local-engine/Parser/RelParsers/JoinRelParser.cpp
@@ -31,6 +31,7 @@
#include <Parser/AdvancedParametersParseUtil.h>
#include <Parser/ExpressionParser.h>
#include <Parsers/ASTIdentifier.h>
+#include <Parser/SubstraitParserUtils.h>
#include <Processors/QueryPlan/ExpressionStep.h>
#include <Processors/QueryPlan/FilterStep.h>
#include <Processors/QueryPlan/JoinStep.h>
@@ -114,10 +115,9 @@ std::unordered_set<DB::JoinTableSide>
JoinRelParser::extractTableSidesFromExpres
table_sides.insert(table_sides_from_arg.begin(),
table_sides_from_arg.end());
}
}
- else if (expr.has_selection() && expr.selection().has_direct_reference()
&& expr.selection().direct_reference().has_struct_field())
+ else if (auto field = SubstraitParserUtils::getStructFieldIndex(expr))
{
- auto pos = expr.selection().direct_reference().struct_field().field();
- if (pos < left_header.columns())
+ if (*field < left_header.columns())
table_sides.insert(DB::JoinTableSide::Left);
else
table_sides.insert(DB::JoinTableSide::Right);
@@ -272,15 +272,10 @@ DB::QueryPlanPtr JoinRelParser::parseJoin(const
substrait::JoinRel & join, DB::Q
auto input_header = left->getCurrentHeader();
DB::ActionsDAG
filter_is_not_null_dag{input_header.getColumnsWithTypeAndName()};
// when is_null_aware_anti_join is true, there is only one
join key
- const auto * key_field =
filter_is_not_null_dag.getInputs()[join.expression()
-
.scalar_function()
-
.arguments()
-
.at(0)
-
.value()
-
.selection()
-
.direct_reference()
-
.struct_field()
-
.field()];
+ auto field_index =
SubstraitParserUtils::getStructFieldIndex(join.expression().scalar_function().arguments(0).value());
+ if (!field_index)
+ throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "The
join key is not found in the expression.");
+ const auto * key_field =
filter_is_not_null_dag.getInputs()[*field_index];
auto result_node =
filter_is_not_null_dag.tryFindInOutputs(key_field->result_name);
// add a function isNotNull to filter the null key on the left
side
@@ -480,12 +475,12 @@ void JoinRelParser::collectJoinKeys(
size_t left_pos = 0, right_pos = 0;
for (const auto & arg :
current_expr->scalar_function().arguments())
{
- if (!arg.value().has_selection() ||
!arg.value().selection().has_direct_reference()
- ||
!arg.value().selection().direct_reference().has_struct_field())
+ auto field_index =
SubstraitParserUtils::getStructFieldIndex(arg.value());
+ if (!field_index)
{
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "A
column reference is expected");
}
- auto col_pos_ref =
arg.value().selection().direct_reference().struct_field().field();
+ auto col_pos_ref = *field_index;
if (col_pos_ref < left_header.columns())
{
left_pos = col_pos_ref;
@@ -550,8 +545,7 @@ bool JoinRelParser::applyJoinFilter(
std::vector<substrait::Expression> exprs;
for (size_t i = 0; i < header.columns(); ++i)
{
- substrait::Expression expr;
-
expr.mutable_selection()->mutable_direct_reference()->mutable_struct_field()->set_field(i);
+ substrait::Expression expr =
SubstraitParserUtils::buildStructFieldExpression(i);
exprs.emplace_back(expr);
}
return exprs;
@@ -680,23 +674,17 @@ bool JoinRelParser::couldRewriteToMultiJoinOnClauses(
dfs_visit_and_expr(and_exprs, args[1].value());
};
- auto get_field_ref = [](const substrait::Expression & e) ->
std::optional<Int32>
- {
- if (e.has_selection() && e.selection().has_direct_reference() &&
e.selection().direct_reference().has_struct_field())
- return
std::optional<Int32>(e.selection().direct_reference().struct_field().field());
- return {};
- };
auto visit_equal_expr = [&](const substrait::Expression & e) ->
std::optional<std::pair<String, String>>
{
if (!check_function("equals", e))
return {};
const auto & args = e.scalar_function().arguments();
- auto l_field_ref = get_field_ref(args[0].value());
- auto r_field_ref = get_field_ref(args[1].value());
+ auto l_field_ref =
SubstraitParserUtils::getStructFieldIndex(args[0].value());
+ auto r_field_ref =
SubstraitParserUtils::getStructFieldIndex(args[1].value());
if (!l_field_ref.has_value() || !r_field_ref.has_value())
return {};
- size_t l_pos = static_cast<size_t>(*l_field_ref);
- size_t r_pos = static_cast<size_t>(*r_field_ref);
+ size_t l_pos = *l_field_ref;
+ size_t r_pos = *r_field_ref;
size_t l_cols = left_header.columns();
size_t total_cols = l_cols + right_header.columns();
diff --git a/cpp-ch/local-engine/Parser/RelParsers/MergeTreeRelParser.cpp
b/cpp-ch/local-engine/Parser/RelParsers/MergeTreeRelParser.cpp
index 7483627d29..4c8c59fe21 100644
--- a/cpp-ch/local-engine/Parser/RelParsers/MergeTreeRelParser.cpp
+++ b/cpp-ch/local-engine/Parser/RelParsers/MergeTreeRelParser.cpp
@@ -317,9 +317,11 @@ void MergeTreeRelParser::collectColumns(const
substrait::Expression & rel, NameS
}
case substrait::Expression::RexTypeCase::kSelection: {
- const size_t idx =
rel.selection().direct_reference().struct_field().field();
- if (const Names names = block.getNames(); names.size() > idx)
- columns.insert(names[idx]);
+ auto idx = SubstraitParserUtils::getStructFieldIndex(rel);
+ if (!idx)
+ throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Selection
node must have direct reference.");
+ if (const Names names = block.getNames(); names.size() > *idx)
+ columns.insert(names[*idx]);
return;
}
diff --git a/cpp-ch/local-engine/Parser/RelParsers/SortParsingUtils.cpp
b/cpp-ch/local-engine/Parser/RelParsers/SortParsingUtils.cpp
index 70cacf0633..c45849d972 100644
--- a/cpp-ch/local-engine/Parser/RelParsers/SortParsingUtils.cpp
+++ b/cpp-ch/local-engine/Parser/RelParsers/SortParsingUtils.cpp
@@ -20,6 +20,7 @@
#include <Poco/Logger.h>
#include <Common/Exception.h>
#include <Common/logger_useful.h>
+#include <Parser/SubstraitParserUtils.h>
namespace DB::ErrorCodes
{
@@ -33,16 +34,18 @@ DB::SortDescription parseSortFields(const DB::Block &
header, const google::prot
{
DB::SortDescription description;
for (const auto & expr : expressions)
- if (expr.has_selection())
+ {
+ auto field_index = SubstraitParserUtils::getStructFieldIndex(expr);
+ if (field_index)
{
- auto pos =
expr.selection().direct_reference().struct_field().field();
- const auto & col_name = header.getByPosition(pos).name;
+ const auto & col_name = header.getByPosition(*field_index).name;
description.push_back(DB::SortColumnDescription(col_name, 1, -1));
}
else if (expr.has_literal())
continue;
else
throw DB::Exception(DB::ErrorCodes::BAD_ARGUMENTS, "Unknow
expression as sort field: {}", expr.DebugString());
+ }
return description;
}
@@ -58,17 +61,16 @@ DB::SortDescription parseSortFields(const DB::Block &
header, const google::prot
if (sort_field.expr().has_literal())
continue;
- if (!sort_field.expr().has_selection() ||
!sort_field.expr().selection().has_direct_reference()
- ||
!sort_field.expr().selection().direct_reference().has_struct_field())
+ auto field_index =
SubstraitParserUtils::getStructFieldIndex(sort_field.expr());
+ if(!field_index)
{
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Unsupport sort
field");
}
- auto field_pos =
sort_field.expr().selection().direct_reference().struct_field().field();
auto direction_iter = direction_map.find(sort_field.direction());
if (direction_iter == direction_map.end())
throw DB::Exception(DB::ErrorCodes::LOGICAL_ERROR, "Unsuppor sort
direction: {}", sort_field.direction());
- const auto & col_name = header.getByPosition(field_pos).name;
+ const auto & col_name = header.getByPosition(*field_index).name;
sort_descr.emplace_back(col_name, direction_iter->second.first,
direction_iter->second.second);
}
return sort_descr;
@@ -86,13 +88,13 @@ buildSQLLikeSortDescription(const DB::Block & header, const
google::protobuf::Re
auto it = order_directions.find(sort_field.direction());
if (it == order_directions.end())
throw DB::Exception(DB::ErrorCodes::BAD_ARGUMENTS, "Unknow sort
direction: {}", sort_field.direction());
- if (!sort_field.expr().has_selection())
+ auto field_index =
SubstraitParserUtils::getStructFieldIndex(sort_field.expr());
+ if (!field_index)
{
throw DB::Exception(
DB::ErrorCodes::BAD_ARGUMENTS, "Sort field must be a column
reference. but got {}", sort_field.DebugString());
}
- auto ref =
sort_field.expr().selection().direct_reference().struct_field().field();
- const auto & col_name = header.getByPosition(ref).name;
+ const auto & col_name = header.getByPosition(*field_index).name;
if (n)
ostr << String(",");
// the col_name may contain '#' which can may ch fail to parse.
diff --git a/cpp-ch/local-engine/Parser/SerializedPlanParser.cpp
b/cpp-ch/local-engine/Parser/SerializedPlanParser.cpp
index 4fbe710eeb..cbe0e5089e 100644
--- a/cpp-ch/local-engine/Parser/SerializedPlanParser.cpp
+++ b/cpp-ch/local-engine/Parser/SerializedPlanParser.cpp
@@ -416,10 +416,9 @@ void NonNullableColumnsResolver::visitNonNullable(const
substrait::Expression &
visitNonNullable(scalar_function.arguments(1).value());
}
}
- else if (expr.has_selection())
+ else if (auto field_index =
SubstraitParserUtils::getStructFieldIndex(expr))
{
- const auto & selection = expr.selection();
- auto column_pos = selection.direct_reference().struct_field().field();
+ const auto & column_pos = *field_index;
auto column_name = header.getByPosition(column_pos).name;
collected_columns.insert(column_name);
}
diff --git a/cpp-ch/local-engine/Parser/SubstraitParserUtils.cpp
b/cpp-ch/local-engine/Parser/SubstraitParserUtils.cpp
new file mode 100644
index 0000000000..055ec856c1
--- /dev/null
+++ b/cpp-ch/local-engine/Parser/SubstraitParserUtils.cpp
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <Parser/SubstraitParserUtils.h>
+#include "substrait/algebra.pb.h"
+namespace local_engine::SubstraitParserUtils
+{
+std::optional<size_t> getStructFieldIndex(const substrait::Expression & e)
+{
+ if (!e.has_selection())
+ return {};
+ const auto & select = e.selection();
+ if (!select.has_direct_reference())
+ return {};
+ const auto & ref = select.direct_reference();
+ if (!ref.has_struct_field())
+ return {};
+ return ref.struct_field().field();
+}
+
+substrait::Expression buildStructFieldExpression(size_t index)
+{
+ substrait::Expression e;
+
e.mutable_selection()->mutable_direct_reference()->mutable_struct_field()->set_field(index);
+ return e;
+}
+
+}
diff --git a/cpp-ch/local-engine/Parser/SubstraitParserUtils.h
b/cpp-ch/local-engine/Parser/SubstraitParserUtils.h
index c020d96d8e..a9e21ba579 100644
--- a/cpp-ch/local-engine/Parser/SubstraitParserUtils.h
+++ b/cpp-ch/local-engine/Parser/SubstraitParserUtils.h
@@ -17,9 +17,12 @@
#pragma once
#include <string>
+#include <optional>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/wrappers.pb.h>
+#include <substrait/plan.pb.h>
#include <Common/Exception.h>
+#include "substrait/algebra.pb.h"
namespace DB::ErrorCodes
{
@@ -74,4 +77,10 @@ inline std::string toString(const google::protobuf::Any &
any)
sv.ParseFromString(any.value());
return sv.value();
}
+
+namespace SubstraitParserUtils
+{
+ std::optional<size_t> getStructFieldIndex(const substrait::Expression & e);
+ substrait::Expression buildStructFieldExpression(size_t index);
+}
} // namespace local_engine
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]