blob: d970e503cebecec3dd6db05dbe6bd5c5cc44ce57 [file]
// 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 "exec/iceberg-metadata/iceberg-row-reader.h"
#include "exec/iceberg-metadata/iceberg-metadata-scanner.h"
#include "exec/scan-node.h"
#include <jni.h>
namespace impala {
class ExecNode;
class IcebergRowReader;
class RuntimeState;
class Status;
/// Scan node for an Iceberg metadata table.
/// Iceberg API provides predefined metadata tables, these tables can be scanned through
/// the Iceberg API just like any other regular Iceberg tables. Although, Impala utilizes
/// its Parquet scanner to scan Iceberg data, due to the virtual nature of the metadata
/// tables these should be scanned with the Iceberg API.
///
/// For scanning these metadata tables this scanner calls into the JVM and creates an
/// 'IcebergMetadataScanner' object that does the scanning. Once the Iceberg scan is done,
/// the scan node starts fetching the rows one by one and materializes the Iceberg rows
/// into Impala rowbatches.
///
/// The flow of scanning is:
/// 1. Backend: gets the FeIcebergTable object from the frontend
/// 2. Backend: creates an IcebergMetadataScanner object on the Java heap
/// 3. Backend: triggers a metadata table creation and scan on the Frontend
/// 4. Frontend: creates the metadata table and executes the scan
/// 5. Backend: calls GetNext that calls the IcebergMetadataScanner's GetNext
/// 6. Frontend: IcebergMetadataScanner's GetNext iterates over the result set and returns
/// a row in StructLike format
/// 7. Backend: converts and materializes the returned StructLike object into RowBatch
///
/// Note:
/// This scan node should be executed on the coordinator, because it depends on the
/// frontend's table cache.
class IcebergMetadataScanPlanNode : public ScanPlanNode {
public:
Status CreateExecNode(RuntimeState* state, ExecNode** node) const override;
~IcebergMetadataScanPlanNode() {}
};
class IcebergMetadataScanNode : public ScanNode {
public:
IcebergMetadataScanNode(ObjectPool* pool, const IcebergMetadataScanPlanNode& pnode,
const DescriptorTbl& descs);
/// Initializes counters, executes Iceberg table scan and initializes accessors.
Status Prepare(RuntimeState* state) override;
/// Creates the Iceberg row reader.
Status Open(RuntimeState* state) override;
/// Fills the next rowbatch with the results returned by the Iceberg scan.
Status GetNext(RuntimeState* state, RowBatch* row_batch, bool* eos) override;
/// Finalize and close this operator.
void Close(RuntimeState* state) override;
private:
/// Adapter that helps preparing the metadata table and executes an Iceberg table scan
/// on Java side. Allows the ScanNode to fetch the metadata from the Java Heap.
std::unique_ptr<IcebergMetadataScanner> metadata_scanner_;
/// Helper class to transform Iceberg rows to Impala tuples.
std::unique_ptr<IcebergRowReader> iceberg_row_reader_;
// The TupleId and TupleDescriptor of the tuple that this scan node will populate.
const TupleId tuple_id_;
const TupleDescriptor* tuple_desc_ = nullptr;
/// Table and metadata table names.
const TTableName table_name_;
const string metadata_table_name_;
/// Iceberg metadata scan specific counters.
RuntimeProfile::Counter* scan_prepare_timer_;
RuntimeProfile::Counter* iceberg_api_scan_timer_;
/// Gets the FeIceberg table from the Frontend.
Status GetCatalogTable(jobject* jtable);
};
}