blob: 6e482c20830616beccae2d0f43ca9c2f041111a4 [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.
**/
#ifndef QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_HPP_
#define QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_HPP_
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "catalog/CatalogTypedefs.hpp"
#include "expressions/Expression.hpp"
#include "expressions/Expressions.pb.h"
#include "storage/StorageBlockInfo.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/ColumnVector.hpp"
#include "utility/Macros.hpp"
namespace quickstep {
class ColumnVectorCache;
class Type;
class ValueAccessor;
struct SubBlocksReference;
/** \addtogroup Expressions
* @{
*/
/**
* @brief Base class for anything which evaluates to a Scalar value.
**/
class Scalar : public Expression {
public:
/**
* @brief The possible provenance of Scalar values.
**/
enum ScalarDataSource {
kLiteral = 0,
kAttribute,
kUnaryExpression,
kBinaryExpression,
kCaseExpression,
kSharedExpression,
kNumScalarDataSources // Not a real ScalarDataSource, exists for counting purposes.
};
/**
* @brief Strings naming the elements in ScalarDataSource.
* @note String literals are defined out-of-line in Scalar.cpp
**/
static const char *kScalarDataSourceNames[kNumScalarDataSources];
~Scalar() override {
}
std::string getName() const override {
return kScalarDataSourceNames[
static_cast<std::underlying_type<ScalarDataSource>::type>(getDataSource())];
}
/**
* @brief Serialize this scalar in Protocol Buffer form.
*
* @return The Protocol Buffer representation of this scalar object.
**/
virtual serialization::Scalar getProto() const = 0;
/**
* @brief Make a deep copy of this Scalar.
*
* @return A cloned copy of this Scalar.
**/
virtual Scalar* clone() const = 0;
/**
* @brief Get the type of scalar value represented.
*
* @return The Type of the Scalar.
**/
inline const Type& getType() const {
return type_;
}
/**
* @brief Get the provenance of this scalar value.
*
* @return The source of this Scalar's data.
**/
virtual ScalarDataSource getDataSource() const = 0;
/**
* @brief Get this Scalar's value for the given tuple from a ValueAccessor.
* @note This only works for Scalars which can be evaluated for a single
* table. Use getValueForJoinedTuples() where necessary.
*
* @param accessor The ValueAccessor that will be used to access the tuple to
* evaluate this Scalar for.
* @param tuple The ID of the tuple in accessor (the absolute position) to
* evaluate this Scalar for.
* @return The value of this scalar for the given tuple in the given
* TupleStorageSubBlock.
**/
virtual TypedValue getValueForSingleTuple(const ValueAccessor &accessor,
const tuple_id tuple) const = 0;
/**
* @brief Get this Scalar's value for the given pair of joined tuples.
*
* @param left_accessor The ValueAccessor that the first of the joined
* tuples can be read from (this does NOT necessarily correspond to
* the left operand of a binary operation).
* @param left_relation_id The ID of the relation that left_tuple_store
* belongs to.
* @param left_tuple_id The ID of the tuple in left_tuple_store to evaluate
* this Scalar for.
* @param right_accessor The ValueAccessor that the second of the joined
* tuples can be read from (this does NOT necessarily correspond to
* the right operand of a binary operation).
* @param right_relation_id The ID of the relation that right_tuple_store
* belongs to.
* @param right_tuple_id The ID of the tuple in right_tuple_store to evaluate
* this Scalar for.
* @return The value of this scalar for the given tuples.
**/
virtual TypedValue getValueForJoinedTuples(
const ValueAccessor &left_accessor,
const relation_id left_relation_id,
const tuple_id left_tuple_id,
const ValueAccessor &right_accessor,
const relation_id right_relation_id,
const tuple_id right_tuple_id) const = 0;
/**
* @brief Determine whether this Scalar's value is static (i.e. whether it is
* the same regardless of tuple).
*
* @return Whether this Scalar's value is static.
**/
virtual bool hasStaticValue() const {
return false;
}
/**
* @brief Get this Scalar's static value.
* @warning hasStaticValue() should be called first to check whether a static
* value actually exists.
*
* @return This Scalar's static value.
**/
virtual const TypedValue& getStaticValue() const;
/**
* @brief If it is possible to get this Scalar's values directly from a
* ValueAccessor, return the attribute_id that should be used to get
* values.
*
* @return The attribute_id of this Scalar's values using a ValueAccessor,
* or -1 if values can not be obtained directly from a ValueAccessor.
**/
virtual attribute_id getAttributeIdForValueAccessor() const {
return -1;
}
/**
* @brief If it is possible to get this Scalar's values directly from a
* ValueAccessor, return the ID of the relation that such a
* ValueAccessor should belong to.
*
* @return The relation_id for ValueAccessors that can directly produce this
* Scalar's values, or -1 if values can not be obtained directly from
* a ValueAccessor.
**/
virtual relation_id getRelationIdForValueAccessor() const {
return -1;
}
/**
* @brief Get this Scalar's values for all tuples accesible via a
* ValueAccessor.
*
* @param accessor A ValueAccessor which this Scalar will be evaluated over.
* @param sub_blocks_ref If non-NULL, contains references to the
* TupleStorageSubBlock that produced accessor and any IndexSubBlocks
* in the same StorageBlock. These sub-blocks may be used for
* fast-path (non-scan) evaluation of Predicates embedded in this
* scalar (e.g. WHEN predicates in ScalarCaseExpression). May be NULL,
* in which case scan-based evaluation is always used.
* @param cv_cache If non-NULL, used as memoization table that is updated and
* looked up during evaluation, for results of common subexpressions.
* @return A ColumnVector of this Scalar's values for each tuple accesible
* via accessor.
**/
virtual ColumnVectorPtr getAllValues(ValueAccessor *accessor,
const SubBlocksReference *sub_blocks_ref,
ColumnVectorCache *cv_cache) const = 0;
/**
* @brief Get this Scalar's value for all specified joined tuples from two
* ValueAccessors.
*
* @param left_relation_id The ID of the left relation in the join.
* @param left_accessor A ValueAccessor which will be used to access tuples
* from the left relation.
* @param right_relation_id The ID of the right relation in the join.
* @param right_accessor A ValueAccessor which will be used to access tuples
* from the right relation.
* @param joined_tuple_ids A series of pairs of tuple ids from the left and
* right relations that will be joined.
* @param cv_cache If non-NULL, used as memoization table that is updated and
* looked up during evaluation, for results of common subexpressions.
* @return A ColumnVector of this Scalar's values for all the joined tuples
* specified by joined_tuple_ids.
**/
virtual ColumnVectorPtr getAllValuesForJoin(
const relation_id left_relation_id,
ValueAccessor *left_accessor,
const relation_id right_relation_id,
ValueAccessor *right_accessor,
const std::vector<std::pair<tuple_id, tuple_id>> &joined_tuple_ids,
ColumnVectorCache *cv_cache) const = 0;
protected:
void getFieldStringItems(
std::vector<std::string> *inline_field_names,
std::vector<std::string> *inline_field_values,
std::vector<std::string> *non_container_child_field_names,
std::vector<const Expression*> *non_container_child_fields,
std::vector<std::string> *container_child_field_names,
std::vector<std::vector<const Expression*>> *container_child_fields) const override;
explicit Scalar(const Type &type)
: Expression(), type_(type) {}
const Type &type_;
private:
DISALLOW_COPY_AND_ASSIGN(Scalar);
};
/** @} */
} // namespace quickstep
#endif // QUICKSTEP_EXPRESSIONS_SCALAR_SCALAR_HPP_