cpp/velox/substrait/VeloxToSubstraitExpr.cc (533 lines of code) (raw):

/* * 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 "VeloxToSubstraitExpr.h" #include "velox/vector/FlatVector.h" namespace gluten { namespace { const ::substrait::Expression_Literal& toSubstraitNullLiteral( google::protobuf::Arena& arena, const velox::TypeKind& typeKind) { ::substrait::Expression_Literal* substraitField = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); switch (typeKind) { case velox::TypeKind::BOOLEAN: { ::substrait::Type_Boolean* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_Boolean>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_bool_(nullValue); break; } case velox::TypeKind::TINYINT: { ::substrait::Type_I8* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_I8>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_i8(nullValue); break; } case velox::TypeKind::SMALLINT: { ::substrait::Type_I16* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_I16>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_i16(nullValue); break; } case velox::TypeKind::INTEGER: { ::substrait::Type_I32* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_I32>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_i32(nullValue); break; } case velox::TypeKind::BIGINT: { ::substrait::Type_I64* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_I64>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_i64(nullValue); break; } case velox::TypeKind::VARCHAR: { ::substrait::Type_String* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_String>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_string(nullValue); break; } case velox::TypeKind::REAL: { ::substrait::Type_FP32* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_FP32>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_fp32(nullValue); break; } case velox::TypeKind::DOUBLE: { ::substrait::Type_FP64* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_FP64>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_fp64(nullValue); break; } case velox::TypeKind::ARRAY: { ::substrait::Type_List* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_List>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); substraitField->mutable_null()->set_allocated_list(nullValue); break; } case velox::TypeKind::UNKNOWN: { ::substrait::Type_UserDefined* nullValue = google::protobuf::Arena::CreateMessage<::substrait::Type_UserDefined>(&arena); nullValue->set_nullability(::substrait::Type_Nullability_NULLABILITY_NULLABLE); nullValue->set_type_reference(0); substraitField->mutable_null()->set_allocated_user_defined(nullValue); break; } default: { VELOX_UNSUPPORTED("Unsupported type '{}'", mapTypeKindToName(typeKind)); } } substraitField->set_nullable(true); return *substraitField; } const ::substrait::Expression_Literal& toSubstraitNotNullLiteral( google::protobuf::Arena& arena, const velox::variant& variantValue) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); switch (variantValue.kind()) { case velox::TypeKind::BOOLEAN: { literalExpr->set_boolean(variantValue.value<TypeKind::BOOLEAN>()); break; } case velox::TypeKind::TINYINT: { literalExpr->set_i8(variantValue.value<TypeKind::TINYINT>()); break; } case velox::TypeKind::SMALLINT: { literalExpr->set_i16(variantValue.value<TypeKind::SMALLINT>()); break; } case velox::TypeKind::INTEGER: { literalExpr->set_i32(variantValue.value<TypeKind::INTEGER>()); break; } case velox::TypeKind::BIGINT: { literalExpr->set_i64(variantValue.value<TypeKind::BIGINT>()); break; } case velox::TypeKind::REAL: { literalExpr->set_fp32(variantValue.value<TypeKind::REAL>()); break; } case velox::TypeKind::DOUBLE: { literalExpr->set_fp64(variantValue.value<TypeKind::DOUBLE>()); break; } case velox::TypeKind::TIMESTAMP: { auto vTimeStamp = variantValue.value<TypeKind::TIMESTAMP>(); auto micros = vTimeStamp.getSeconds() * 1000000 + vTimeStamp.getNanos() / 1000; literalExpr->set_timestamp(micros); break; } case velox::TypeKind::VARCHAR: { auto vCharValue = variantValue.value<StringView>(); ::substrait::Expression_Literal::VarChar* sVarChar = new ::substrait::Expression_Literal::VarChar(); sVarChar->set_value(vCharValue.data()); sVarChar->set_length(vCharValue.size()); literalExpr->set_allocated_var_char(sVarChar); break; } default: VELOX_NYI("Unsupported constant Type '{}' ", mapTypeKindToName(variantValue.kind())); } literalExpr->set_nullable(false); return *literalExpr; } template <TypeKind kind> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral( google::protobuf::Arena& arena, const typename TypeTraits<kind>::NativeType& /* value */) { VELOX_UNSUPPORTED("toSubstraitNotNullLiteral function doesn't support {} type", TypeTraits<kind>::name); // Make compiler happy. ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::BOOLEAN>( google::protobuf::Arena& arena, const bool& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); literalExpr->set_boolean(value); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::TINYINT>( google::protobuf::Arena& arena, const int8_t& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); literalExpr->set_i8(value); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::SMALLINT>( google::protobuf::Arena& arena, const int16_t& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); literalExpr->set_i16(value); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::INTEGER>( google::protobuf::Arena& arena, const int32_t& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); literalExpr->set_i32(value); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::BIGINT>( google::protobuf::Arena& arena, const int64_t& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); literalExpr->set_i64(value); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::REAL>( google::protobuf::Arena& arena, const float& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); literalExpr->set_fp32(value); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::DOUBLE>( google::protobuf::Arena& arena, const double& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); literalExpr->set_fp64(value); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::TIMESTAMP>( google::protobuf::Arena& arena, const Timestamp& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); auto micros = value.getSeconds() * 1000000 + value.getNanos() / 1000; literalExpr->set_timestamp(micros); literalExpr->set_nullable(false); return *literalExpr; } template <> const ::substrait::Expression_Literal& toSubstraitNotNullLiteral<TypeKind::VARCHAR>( google::protobuf::Arena& arena, const velox::StringView& value) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); ::substrait::Expression_Literal::VarChar* sVarChar = new ::substrait::Expression_Literal::VarChar(); sVarChar->set_value(value.data()); sVarChar->set_length(value.size()); literalExpr->set_allocated_var_char(sVarChar); literalExpr->set_nullable(false); return *literalExpr; } template <TypeKind Kind> void arrayVectorToLiteral( google::protobuf::Arena& arena, const ArrayVector* arrayVector, ::substrait::Expression_Literal_List* listLiteral, vector_size_t offset, vector_size_t size) { using T = typename TypeTraits<Kind>::NativeType; auto elements = arrayVector->elements()->as<SimpleVector<T>>(); for (auto i = offset; i < offset + size; ++i) { ::substrait::Expression_Literal* childLiteral = listLiteral->add_values(); if (elements->isNullAt(i)) { childLiteral->MergeFrom(toSubstraitNullLiteral(arena, Kind)); } else { childLiteral->MergeFrom(toSubstraitNotNullLiteral<Kind>(arena, elements->valueAt(i))); } } } template <TypeKind kind> void convertVectorValue( google::protobuf::Arena& arena, const velox::VectorPtr& vectorValue, ::substrait::Expression_Literal_Struct* litValue, ::substrait::Expression_Literal* substraitField) { const TypePtr& childType = vectorValue->type(); using T = typename TypeTraits<kind>::NativeType; auto childToFlatVec = vectorValue->as<SimpleVector<T>>(); // Get the batchSize and convert each value in it. vector_size_t flatVecSize = childToFlatVec->size(); for (int64_t i = 0; i < flatVecSize; i++) { substraitField = litValue->add_fields(); if (childToFlatVec->isNullAt(i)) { // Process the null value. substraitField->MergeFrom(toSubstraitNullLiteral(arena, childType->kind())); } else { substraitField->MergeFrom(toSubstraitNotNullLiteral<kind>(arena, childToFlatVec->valueAt(i))); } } } uint32_t getFieldIdForIntermediateNode( const std::string& exprName, const ::substrait::Expression_ReferenceSegment_StructField& structField, const RowTypePtr& inputType) { auto inputColumnType = inputType; std::vector<int32_t> ids; const auto* tmp = &structField; for (;;) { ids.push_back(tmp->field()); if (!tmp->has_child()) { break; } tmp = &tmp->child().struct_field(); } for (int32_t i = ids.size() - 1; i >= 0; --i) { inputColumnType = asRowType(inputColumnType->childAt(ids[i])); } return inputColumnType->getChildIdx(exprName); } } // namespace const ::substrait::Expression& VeloxToSubstraitExprConvertor::toSubstraitExpr( google::protobuf::Arena& arena, const core::TypedExprPtr& expr, const RowTypePtr& inputType) { ::substrait::Expression* substraitExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression>(&arena); if (auto constExpr = std::dynamic_pointer_cast<const core::ConstantTypedExpr>(expr)) { substraitExpr->mutable_literal()->MergeFrom(toSubstraitExpr(arena, constExpr)); return *substraitExpr; } if (auto callTypeExpr = std::dynamic_pointer_cast<const core::CallTypedExpr>(expr)) { substraitExpr->MergeFrom(toSubstraitExpr(arena, callTypeExpr, inputType)); return *substraitExpr; } if (auto fieldExpr = std::dynamic_pointer_cast<const core::FieldAccessTypedExpr>(expr)) { substraitExpr->mutable_selection()->MergeFrom(toSubstraitExpr(arena, fieldExpr, inputType)); return *substraitExpr; } if (auto castExpr = std::dynamic_pointer_cast<const core::CastTypedExpr>(expr)) { substraitExpr->mutable_cast()->MergeFrom(toSubstraitExpr(arena, castExpr, inputType)); return *substraitExpr; } if (auto derefExpr = std::dynamic_pointer_cast<const core::DereferenceTypedExpr>(expr)) { substraitExpr->mutable_selection()->MergeFrom(toSubstraitExpr(arena, derefExpr, inputType)); return *substraitExpr; } VELOX_UNSUPPORTED("Unsupport Expr '{}' in Substrait", expr->toString()); } const ::substrait::Expression_Cast& VeloxToSubstraitExprConvertor::toSubstraitExpr( google::protobuf::Arena& arena, const std::shared_ptr<const core::CastTypedExpr>& castExpr, const RowTypePtr& inputType) { ::substrait::Expression_Cast* substraitCastExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Cast>(&arena); std::vector<core::TypedExprPtr> castExprInputs = castExpr->inputs(); substraitCastExpr->mutable_type()->MergeFrom(typeConvertor_->toSubstraitType(arena, castExpr->type())); for (auto& arg : castExprInputs) { substraitCastExpr->mutable_input()->MergeFrom(toSubstraitExpr(arena, arg, inputType)); } if (castExpr->nullOnFailure()) { substraitCastExpr->set_failure_behavior(::substrait::Expression_Cast_FailureBehavior_FAILURE_BEHAVIOR_RETURN_NULL); } else { substraitCastExpr->set_failure_behavior( ::substrait::Expression_Cast_FailureBehavior_FAILURE_BEHAVIOR_THROW_EXCEPTION); } return *substraitCastExpr; } const ::substrait::Expression_FieldReference& VeloxToSubstraitExprConvertor::toSubstraitExpr( google::protobuf::Arena& arena, const std::shared_ptr<const core::FieldAccessTypedExpr>& fieldExpr, const RowTypePtr& inputType) { ::substrait::Expression_FieldReference* substraitFieldExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_FieldReference>(&arena); std::string exprName = fieldExpr->name(); ::substrait::Expression_ReferenceSegment_StructField* directStruct = substraitFieldExpr->mutable_direct_reference()->mutable_struct_field(); // FieldAccessTypedExpr represents one of two things: a leaf in an expression // or a dereference expression(fieldExpr->isInputColumn() == false) // for a leaf in an expression, find idx from child by exprName. // for a dereference expression, find idx from every child by exprName. if (fieldExpr->isInputColumn()) { uint32_t idx = inputType->getChildIdx(exprName); directStruct->set_field(idx); } else { auto tmp = toSubstraitExpr(arena, fieldExpr->inputs()[0], inputType).selection().direct_reference(); if (!tmp.has_struct_field()) { uint32_t idx = inputType->getChildIdx(exprName); directStruct->set_field(idx); } else { ::substrait::Expression_ReferenceSegment_StructField* childStruct = google::protobuf::Arena::CreateMessage<::substrait::Expression_ReferenceSegment_StructField>(&arena); ::substrait::Expression_ReferenceSegment* refSegment = google::protobuf::Arena::CreateMessage<::substrait::Expression_ReferenceSegment>(&arena); directStruct->MergeFrom(tmp.struct_field()); childStruct->set_field(getFieldIdForIntermediateNode(exprName, tmp.struct_field(), inputType)); refSegment->set_allocated_struct_field(childStruct); ::substrait::Expression_ReferenceSegment_StructField* innerChild = directStruct; while (innerChild->has_child()) { innerChild = innerChild->mutable_child()->mutable_struct_field(); } innerChild->set_allocated_child(refSegment); } } return *substraitFieldExpr; } const ::substrait::Expression_FieldReference& VeloxToSubstraitExprConvertor::toSubstraitExpr( google::protobuf::Arena& arena, const std::shared_ptr<const core::DereferenceTypedExpr>& derefExpr, const RowTypePtr& inputType) { ::substrait::Expression_FieldReference* substraitFieldExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_FieldReference>(&arena); ::substrait::Expression_ReferenceSegment_StructField* directStruct = substraitFieldExpr->mutable_direct_reference()->mutable_struct_field(); auto input = toSubstraitExpr(arena, derefExpr->inputs()[0], inputType); VELOX_USER_CHECK(input.has_selection(), "Non-field expression is not supported"); auto inputRef = input.selection().direct_reference(); ::substrait::Expression_ReferenceSegment_StructField* childStruct = google::protobuf::Arena::CreateMessage<::substrait::Expression_ReferenceSegment_StructField>(&arena); ::substrait::Expression_ReferenceSegment* refSegment = google::protobuf::Arena::CreateMessage<::substrait::Expression_ReferenceSegment>(&arena); directStruct->MergeFrom(inputRef.struct_field()); childStruct->set_field(derefExpr->index()); refSegment->set_allocated_struct_field(childStruct); ::substrait::Expression_ReferenceSegment_StructField* innerChild = directStruct; while (innerChild->has_child()) { innerChild = innerChild->mutable_child()->mutable_struct_field(); } innerChild->set_allocated_child(refSegment); return *substraitFieldExpr; } const ::substrait::Expression& VeloxToSubstraitExprConvertor::toSubstraitExpr( google::protobuf::Arena& arena, const std::shared_ptr<const core::CallTypedExpr>& callTypeExpr, const RowTypePtr& inputType) { ::substrait::Expression* substraitExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression>(&arena); auto inputs = callTypeExpr->inputs(); auto& functionName = callTypeExpr->name(); if (functionName != "if" && functionName != "switch") { ::substrait::Expression_ScalarFunction* scalarExpr = substraitExpr->mutable_scalar_function(); std::vector<TypePtr> types; types.reserve(callTypeExpr->inputs().size()); for (auto& typedExpr : callTypeExpr->inputs()) { types.emplace_back(typedExpr->type()); } scalarExpr->set_function_reference(extensionCollector_->getReferenceNumber(functionName, types)); for (auto& arg : inputs) { scalarExpr->add_arguments()->mutable_value()->MergeFrom(toSubstraitExpr(arena, arg, inputType)); } scalarExpr->mutable_output_type()->MergeFrom(typeConvertor_->toSubstraitType(arena, callTypeExpr->type())); } else { // For today's version of Substrait, you'd have to use IfThen if you need // the switch cases to be call typed expression. size_t inputsSize = callTypeExpr->inputs().size(); bool hasElseInput = inputsSize % 2 == 1; auto ifThenExpr = substraitExpr->mutable_if_then(); for (int i = 0; i < inputsSize / 2; i++) { auto ifClauseExpr = ifThenExpr->add_ifs(); ifClauseExpr->mutable_if_()->MergeFrom(toSubstraitExpr(arena, callTypeExpr->inputs().at(i * 2), inputType)); ifClauseExpr->mutable_then()->MergeFrom(toSubstraitExpr(arena, callTypeExpr->inputs().at(i * 2 + 1), inputType)); } if (hasElseInput) { ifThenExpr->mutable_else_()->MergeFrom( toSubstraitExpr(arena, callTypeExpr->inputs().at(inputsSize - 1), inputType)); } } return *substraitExpr; } const ::substrait::Expression_Literal& VeloxToSubstraitExprConvertor::toSubstraitExpr( google::protobuf::Arena& arena, const std::shared_ptr<const core::ConstantTypedExpr>& constExpr, ::substrait::Expression_Literal_Struct* litValue) { if (constExpr->hasValueVector()) { return toSubstraitLiteral(arena, constExpr->valueVector(), litValue); } else { return toSubstraitLiteral(arena, constExpr->value()); } } const ::substrait::Expression_Literal& VeloxToSubstraitExprConvertor::toSubstraitLiteral( google::protobuf::Arena& arena, const velox::variant& variantValue) { ::substrait::Expression_Literal* literalExpr = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); if (variantValue.isNull()) { literalExpr->MergeFrom(toSubstraitNullLiteral(arena, variantValue.kind())); } else { literalExpr->MergeFrom(toSubstraitNotNullLiteral(arena, variantValue)); } return *literalExpr; } const ::substrait::Expression_Literal_List& VeloxToSubstraitExprConvertor::toSubstraitLiteralList( google::protobuf::Arena& arena, const ArrayVector* arrayVector, vector_size_t row) { ::substrait::Expression_Literal_List* listLiteral = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal_List>(&arena); auto size = arrayVector->sizeAt(row); auto offset = arrayVector->offsetAt(row); if (arrayVector->elements()->isScalar()) { VELOX_DYNAMIC_SCALAR_TYPE_DISPATCH( arrayVectorToLiteral, arrayVector->elements()->type()->kind(), arena, arrayVector, listLiteral, offset, size); return *listLiteral; } if (arrayVector->elements()->typeKind() == TypeKind::ARRAY) { auto encoding = arrayVector->elements()->encoding(); if (encoding == VectorEncoding::Simple::ARRAY) { auto nestedArrayVector = arrayVector->elements()->as<ArrayVector>(); VELOX_CHECK_NOT_NULL(nestedArrayVector); for (auto i = offset; i < offset + size; ++i) { ::substrait::Expression_Literal* literal = listLiteral->add_values(); literal->set_allocated_list( const_cast<::substrait::Expression_Literal_List*>(&toSubstraitLiteralList(arena, nestedArrayVector, i))); } return *listLiteral; } } VELOX_NYI("Complex type literals are not supported: {}", arrayVector->elements()->type()->toString()); } const ::substrait::Expression_Literal& VeloxToSubstraitExprConvertor::toSubstraitLiteralComplex( google::protobuf::Arena& arena, const std::shared_ptr<ConstantVector<ComplexType>>& constantVector) { ::substrait::Expression_Literal* substraitField = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); if (constantVector->typeKind() == TypeKind::ARRAY) { if (constantVector->isNullAt(0)) { // Process the null value. substraitField->MergeFrom(toSubstraitNullLiteral(arena, constantVector->typeKind())); return *substraitField; } auto encoding = constantVector->valueVector()->encoding(); if (encoding == VectorEncoding::Simple::ARRAY) { auto arrayVector = constantVector->valueVector()->as<ArrayVector>(); auto row = constantVector->index(); auto size = arrayVector->sizeAt(row); if (size == 0) { substraitField->mutable_empty_list()->MergeFrom( toSubstraitLiteralEmptyList(arena, arrayVector->elements()->type())); } else { substraitField->mutable_list()->MergeFrom(toSubstraitLiteralList(arena, arrayVector, row)); } return *substraitField; } } VELOX_NYI("Complex type literals are not supported: {}", constantVector->type()->toString()); } const ::substrait::Expression_Literal& VeloxToSubstraitExprConvertor::toSubstraitLiteral( google::protobuf::Arena& arena, const velox::VectorPtr& vectorValue, ::substrait::Expression_Literal_Struct* litValue) { ::substrait::Expression_Literal* substraitField = google::protobuf::Arena::CreateMessage<::substrait::Expression_Literal>(&arena); if (vectorValue->isScalar()) { VELOX_DYNAMIC_SCALAR_TYPE_DISPATCH( convertVectorValue, vectorValue->type()->kind(), arena, vectorValue, litValue, substraitField); return *substraitField; } if (auto constantVector = std::dynamic_pointer_cast<ConstantVector<ComplexType>>(vectorValue)) { return toSubstraitLiteralComplex(arena, constantVector); } return *substraitField; } const ::substrait::Type_List& VeloxToSubstraitExprConvertor::toSubstraitLiteralEmptyList( google::protobuf::Arena& arena, const velox::TypePtr& type) { ::substrait::Type_List* emptyListLiteral = google::protobuf::Arena::CreateMessage<::substrait::Type_List>(&arena); emptyListLiteral->mutable_type()->MergeFrom(typeConvertor_->toSubstraitType(arena, type)); return *emptyListLiteral; } } // namespace gluten