blob: f33638a5fa96f32b47219d77c4b128c7cda52745 [file] [log] [blame]
// 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 "common/global-types.h"
#include "common/status.h"
#include "runtime/collection-value-builder.h"
#include <jni.h>
#include <unordered_map>
namespace impala {
class IcebergMetadataScanner;
class MemPool;
class RuntimeState;
class ScanNode;
class Status;
class SlotDescriptor;
class Tuple;
class TupleDescriptor;
/// Row reader for Iceberg table scans, it translates a {StructLike} Java object to an
/// Impala row. It utilizes IcebergMetadataScanner to handle this translation.
class IcebergRowReader {
public:
IcebergRowReader(ScanNode* scan_node, IcebergMetadataScanner* metadata_scanner);
/// JNI setup. Creates global references for Java classes and finds method ids.
/// Initializes static members, should be called once per process lifecycle.
static Status InitJNI() WARN_UNUSED_RESULT;
/// Materialize the StructLike Java objects into Impala rows.
Status MaterializeTuple(JNIEnv* env, const jobject& struct_like_row,
const TupleDescriptor* tuple_desc, Tuple* tuple, MemPool* tuple_data_pool,
RuntimeState* state);
private:
/// Global class references created with JniUtil.
inline static jclass list_cl_ = nullptr;
inline static jclass map_cl_ = nullptr;
inline static jclass boolean_cl_ = nullptr;
inline static jclass integer_cl_ = nullptr;
inline static jclass long_cl_ = nullptr;
inline static jclass float_cl_ = nullptr;
inline static jclass double_cl_ = nullptr;
inline static jclass char_sequence_cl_ = nullptr;
inline static jclass byte_buffer_cl_ = nullptr;
/// Method references created with JniUtil.
inline static jmethodID list_size_ = nullptr;
inline static jmethodID map_size_ = nullptr;
inline static jmethodID boolean_value_ = nullptr;
inline static jmethodID integer_value_ = nullptr;
inline static jmethodID long_value_ = nullptr;
inline static jmethodID float_value_ = nullptr;
inline static jmethodID double_value_ = nullptr;
inline static jmethodID char_sequence_to_string_ = nullptr;
/// The scan node that started this row reader.
ScanNode* scan_node_;
/// IcebergMetadataScanner class, used to get and access values inside java objects.
IcebergMetadataScanner* metadata_scanner_;
/// We want to emit a warning about DECIMAL values being NULLed out at most once. This
/// member keeps track of whether the warning has already been emitted.
bool unsupported_decimal_warning_emitted_;
// Writes a Java value into the target tuple. 'struct_like_row' is only used for struct
// types. It is needed because struct children reside directly in the parent tuple of
// the struct.
Status WriteSlot(JNIEnv* env, const jobject* struct_like_row,
const jobject& accessed_value, const SlotDescriptor* slot_desc, Tuple* tuple,
MemPool* tuple_data_pool, RuntimeState* state) WARN_UNUSED_RESULT;
/// Translates the value of a Java primitive to the matching Impala type and writes it
/// into the target slot.
Status WriteBooleanSlot(JNIEnv* env, const jobject &accessed_value, void* slot)
WARN_UNUSED_RESULT;
Status WriteDateSlot(JNIEnv* env, const jobject &accessed_value, void* slot)
WARN_UNUSED_RESULT;
Status WriteIntSlot(JNIEnv* env, const jobject &accessed_value, void* slot)
WARN_UNUSED_RESULT;
Status WriteLongSlot(JNIEnv* env, const jobject &accessed_value, void* slot)
WARN_UNUSED_RESULT;
Status WriteFloatSlot(JNIEnv* env, const jobject &accessed_value, void* slot)
WARN_UNUSED_RESULT;
Status WriteDoubleSlot(JNIEnv* env, const jobject &accessed_value, void* slot)
WARN_UNUSED_RESULT;
Status WriteDecimalSlot(const SlotDescriptor* slot_desc, Tuple* tuple,
RuntimeState* state) WARN_UNUSED_RESULT;
/// Iceberg TimeStamp is parsed into TimestampValue.
Status WriteTimeStampSlot(JNIEnv* env, const jobject &accessed_value, void* slot)
WARN_UNUSED_RESULT;
template <bool IS_BINARY>
Status WriteStringOrBinarySlot(JNIEnv* env, const jobject &accessed_value, void* slot,
MemPool* tuple_data_pool) WARN_UNUSED_RESULT;
/// Nested types recursively call MaterializeTuple method with their child tuple.
Status WriteStructSlot(JNIEnv* env, const jobject &struct_like_row,
const SlotDescriptor* slot_desc, Tuple* tuple, MemPool* tuple_data_pool,
RuntimeState* state) WARN_UNUSED_RESULT;
template <bool IS_ARRAY>
Status WriteCollectionSlot(JNIEnv* env, const jobject &accessed_value,
CollectionValue* slot, const SlotDescriptor* slot_desc, MemPool* tuple_data_pool,
RuntimeState* state) WARN_UNUSED_RESULT;
Status WriteArrayItem(JNIEnv* env, const jobject& collection_scanner,
const TupleDescriptor* item_tuple_desc, Tuple* tuple,
MemPool* tuple_data_pool_collection, RuntimeState* state) WARN_UNUSED_RESULT;
Status WriteMapKeyAndValue(JNIEnv* env, const jobject& collection_scanner,
const TupleDescriptor* item_tuple_desc, Tuple* tuple,
MemPool* tuple_data_pool_collection, RuntimeState* state) WARN_UNUSED_RESULT;
/// Extracts an int32_t from a Java integer object and writes it into 'res'. 'jinteger'
/// must not be null and of type java.lang.Integer.
Status ExtractJavaInteger(JNIEnv* env, const jobject &jinteger, int32_t* res)
WARN_UNUSED_RESULT;
/// Helper method that gives back the Iceberg Java class for a ColumnType. It is
/// specified in this class, to avoid defining all the Java type classes in other
/// classes.
jclass JavaClassFromImpalaType(const ColumnType type);
};
}