| /* |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #include <memory> |
| #include <string> |
| #include <variant> |
| #include <vector> |
| |
| #include "iceberg/expression/literal.h" |
| #include "iceberg/iceberg_export.h" |
| #include "iceberg/result.h" |
| #include "iceberg/type_fwd.h" |
| |
| namespace iceberg { |
| |
| /// \brief A field schema partner to carry projection information. |
| struct ICEBERG_EXPORT FieldProjection { |
| /// \brief How the field is projected. |
| enum class Kind { |
| /// \brief The field is projected from the source with possible conversion for |
| /// supported schema evolution. |
| kProjected, |
| /// \brief Metadata column whose value is generated on demand. |
| kMetadata, |
| /// \brief The field is a constant value (e.g. partition field value) |
| kConstant, |
| /// \brief The field is missing in the source and should be filled with default value. |
| kDefault, |
| /// \brief An optional field that is not present in the source. |
| kNull, |
| }; |
| |
| /// \brief A variant to indicate how to set the value of the field. |
| /// \note `std::monostate` is used to indicate that the field is not projected. |
| /// \note `size_t` is used to indicate the field index in the source schema on the same |
| /// nesting level when `kind` is `kProjected`. |
| /// \note `Literal` is used to indicate the value of the field when `kind` is |
| /// `kConstant` or `kDefault`. |
| using From = std::variant<std::monostate, size_t, Literal>; |
| |
| /// \brief Format-specific attributes for the field. |
| /// For example, for Parquet it might store column id and level info of the projected |
| /// leaf field. |
| struct ExtraAttributes { |
| virtual ~ExtraAttributes() = default; |
| }; |
| |
| /// \brief The kind of projection of the field it partners with. |
| Kind kind; |
| /// \brief The source to set the value of the field. |
| From from; |
| /// \brief The children of the field if it is a nested field. |
| std::vector<FieldProjection> children; |
| /// \brief Format-specific attributes for the field. |
| std::shared_ptr<ExtraAttributes> attributes; |
| }; |
| |
| /// \brief A schema partner to carry projection information. |
| struct ICEBERG_EXPORT SchemaProjection { |
| std::vector<FieldProjection> fields; |
| }; |
| |
| /// \brief Project the expected schema on top of the source schema. |
| /// |
| /// \param expected_schema The expected schema. |
| /// \param source_schema The source schema. |
| /// \param prune_source Whether the source schema can be pruned to project the expected |
| /// schema on it. For example, literally a Parquet reader implementation is capable of |
| /// column pruning, so `prune_source` is set to true in this case such that the `from` |
| /// field in `FieldProjection` exactly reflects the position (relative to its nesting |
| /// level) to get the column value from the reader. |
| /// \return The projection result. |
| ICEBERG_EXPORT Result<SchemaProjection> Project(const Schema& expected_schema, |
| const Schema& source_schema, |
| bool prune_source); |
| |
| ICEBERG_EXPORT std::string_view ToString(FieldProjection::Kind kind); |
| ICEBERG_EXPORT std::string ToString(const FieldProjection& projection); |
| ICEBERG_EXPORT std::string ToString(const SchemaProjection& projection); |
| |
| } // namespace iceberg |