blob: 8c5d30aa575714a5c28aedbb6a4d08c73ee39bd8 [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// 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.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
#ifndef EXPRNODE_H
#define EXPRNODE_H
/* -*-C++-*-
******************************************************************************
*
* File: ExprNode.h
* Description: Expression nodes (relational nodes and item expression nodes)
*
*
* Created: 4/28/94
* Language: C++
*
*
*
*
******************************************************************************
*/
#include "Collections.h"
#include "OperTypeEnum.h"
#include "NAStringDef.h"
// -----------------------------------------------------------------------
// contents of this file
// -----------------------------------------------------------------------
class OperatorType;
class ExprNode;
// -----------------------------------------------------------------------
// forward references
// -----------------------------------------------------------------------
class CacheWA;
class ElemDDLNode;
class RelExpr;
class ItemExpr;
class StmtDDLNode;
class StmtNode;
class TableDesc;
typedef unsigned char CmpPhase;
enum StaticOnly { NOT_STATIC_ONLY = FALSE,
STATIC_ONLY_VANILLA = TRUE,
STATIC_ONLY_WITH_WORK_FOR_PREPROCESSOR
};
// -----------------------------------------------------------------------
// class OperatorType: the type of an ExprNode or one of its derived
// class objects. The operator type should uniquely identify the class
// of the actual object used, although a particular class may use more
// than one object type (e.g. a binary arithmetic object class may
// use object types ITM_PLUS, ITM_MINUS, ITM_TIMES, ITM_DIVIDE).
// -----------------------------------------------------------------------
class OperatorType
{
public:
// conversion from and to OperatorTypeEnum
OperatorType(OperatorTypeEnum typ) { op_ = typ; }
inline operator OperatorTypeEnum () const { return op_; }
// wildcard operators
NABoolean match(OperatorTypeEnum wildcard) const;
NABoolean isWildcard() const;
private:
OperatorTypeEnum op_;
};
// -----------------------------------------------------------------------
// Operators and their arguments
// =============================
//
// An ExprNode basically represents a node in a tree. The ExprNode
// has an operator type, which identifies what it does, and it
// has links to its child nodes (also called input nodes, since
// the data usually flows up the tree to the root). There is no link
// to the parent node.
//
// An operator's arity is the number of inputs it expects.
// N-ary operators are permitted; however, any one instance must have
// a fixed arity.
// -----------------------------------------------------------------------
class ExprNode : public NABasicObject
{
public:
enum ChildCondition { ALL_CHILDREN, // all children of this node
ANY_CHILD, // one or more
ANY_CHILD_RAW, // one or more, special format
ALL_CHILDREN_RAW, // all, special format
EXACTLY_ONE_CHILD, // one only
EXACTLY_ONE_CHILD_RAW // one only, special format
};
// default constructor (assuming the max arity in the system is 2)
ExprNode(OperatorTypeEnum otype = ANY_REL_OR_ITM_OP);
// copy constructor
ExprNode(const ExprNode& s);
// virtual destructor
virtual ~ExprNode();
// access a child of an ExprNode
virtual ExprNode * getChild(Lng32 index);
virtual const ExprNode * getConstChild(Lng32 index) const;
// Method for replacing a particular child
virtual void setChild(Lng32 index, ExprNode *);
// arity of the operator (required number of children)
virtual Int32 getArity() const;
// get and set the type of the operator (usually the type
// is set by the constructor)
inline OperatorTypeEnum getOperatorType() const { return operator_; }
inline const OperatorType & getOperator() const { return operator_; }
inline void setOperatorType(OperatorTypeEnum newType)
{ operator_ = newType; }
// perform a safe type cast (return NULL ptr for illegal casts)
virtual ElemDDLNode * castToElemDDLNode();
virtual const ElemDDLNode * castToElemDDLNode() const;
virtual RelExpr * castToRelExpr();
virtual const RelExpr * castToRelExpr() const;
virtual ItemExpr * castToItemExpr();
virtual const ItemExpr * castToItemExpr() const;
virtual StmtDDLNode * castToStmtDDLNode();
virtual const StmtDDLNode * castToStmtDDLNode() const;
virtual StmtNode * castToStatementExpr();
virtual const StmtNode * castToStatementExpr()const;
// marks that bindNode() has bound the node.
void markAsBound() { bound_ = TRUE; }
// marks that bindNode() has bound the node.
void markAsUnBound() { bound_ = FALSE; }
// Returns TRUE if bindNode() has already been called on this node.
NABoolean nodeIsBound() const { return bound_; }
// --------------------------------------------------------------------
// transformNode
//
// transformNode() is an overloaded name, which is used for a set
// of methods that implement the transformation phase of query
// normalization.
//
// We use the term query tree for a tree of relational operators,
// each of which can contain none or more scalar expression trees.
// The transformations performed by transformNode() brings scalar
// expressions into a canonical form. The effect of most such
// transformations is local to the scalar expression tree.
// However, the transformation of a subquery requires a semijoin
// to be performed between the relational operator that contains
// the subquery and the query tree for the subquery. The effect
// of such a subquery transformation is therefore visible not
// only in the scalar expression tree but also in the relational
// expression tree.
//
// Originally, transformNode() was a virtual method on ExprNode.
// The relational as well as scalar expressions are derived from
// ExprNode and used to provide proprietary implementations for it.
// However, relational and scalar expressions have different
// processing requirements during the transformation phase. Hence,
// each of them now support a virtual transformNode() method that
// differ in their interfaces.
//
// --------------------------------------------------------------------
void markAsTransformed() { transformed_ = TRUE; }
NABoolean nodeIsTransformed() const { return transformed_; }
void markAsUnTransformed() { transformed_ = FALSE; }
// --------------------------------------------------------------------
// normalizeNode()
//
// normalizeNode() brings a query tree that consists of relational
// operators into a canonical form. It also rewrites predicates
// using the transitive closure of values that is computed by
// transformNode().
//
// This method is invoked on relational as well as item operators.
//
// --------------------------------------------------------------------
void markAsNormalized() { normalized_ = TRUE; }
NABoolean nodeIsNormalized() const { return normalized_; }
void markAsSemanticQueryOptimized() { semanticQueryOptimized_ = TRUE; }
NABoolean nodeIsSemanticQueryOptimized() const { return semanticQueryOptimized_; }
void markAsPreCodeGenned() { preCodeGenned_ = TRUE; }
void unmarkAsPreCodeGenned() { preCodeGenned_ = FALSE; }
NABoolean nodeIsPreCodeGenned() const { return preCodeGenned_; }
// get a printable string that identifies the operator
virtual const NAString getText() const;
const NAString getTextUpper() const
{ NAString t(getText()); t.toUpper(); return t; }
// The next method is used to get the text to be used in
// case of errors -- virtual, so if redefined it can differ from
// getTextUpper() to return the text for all syntactically equivalent names;
// e.g., an error while processing UPPER or UCASE, which are
// processed similarly and are resolved at parse time to the
// same ItemExpr, would get the text
// "UPPER or UCASE".
//## Yuk -- embedded English text -- this is not per I18N standards!
virtual const NAString getTextForError() const
{ return getTextUpper(); }
// print node on a stream
virtual void print(FILE * f = stdout,
const char * prefix = "",
const char * suffix = "") const;
// produce an ascii-version of the object (for display or saving into a file)
virtual void unparse(NAString &result,
PhaseEnum phase = DEFAULT_PHASE,
UnparseFormatEnum form = USER_FORMAT,
TableDesc * tabId = NULL) const ;
// add all the expressions that are local to this
// node to an existing list of expressions (used by GUI tool)
// and add a string describing the function of the child, too
virtual void addLocalExpr(LIST(ExprNode *) &xlist,
LIST(NAString) &llist) const;
// display the tree on an X display
void displayTree();
enum Cacheability { MAYBECACHEABLE, NONCACHEABLE,
CACHEABLE_PARSE, CACHEABLE_BIND };
void setNonCacheable() { cacheable_ = NONCACHEABLE; }
NABoolean isNonCacheable() const { return cacheable_ == NONCACHEABLE; }
NABoolean maybeCacheable() const { return cacheable_ == MAYBECACHEABLE; }
// is this entire expression cacheable after this phase?
virtual NABoolean isCacheableExpr(CacheWA& cwa) { return FALSE; }
void markAsNormalizedForCache() { normalized4Cache_ = TRUE; }
NABoolean nodeIsNormalizedForCache() const { return normalized4Cache_; }
private:
// specify the type of the operator (join, union, and, or, ...)
OperatorType operator_;
// TRUE if bindNode() has already been called on this node.
NABoolean bound_;
// TRUE if transformNode() has already been called on this node.
NABoolean transformed_;
// TRUE if normalizeNode() has already been called on this node.
NABoolean normalized_;
// TRUE if preCodeGen() has already been called on this node.
NABoolean preCodeGenned_;
// TRUE if normalizeForCache() has already been called on this node.
NABoolean normalized4Cache_;
// TRUE if semanticQueryOptimizeNode() has already been called on this node.
NABoolean semanticQueryOptimized_;
protected:
Cacheability cacheable_; // records the cacheability of an ExprNode.
// most ExprNodes start in the MAYBECACHEABLE state.
// certain ExprNodes (eg, ControlAbstractClass, Describe, StmtNode,
// ElemDDLNode, RelLock, RelTransaction) are always NONCACHEABLE.
// (tuple) Inserts are CACHEABLE_PARSE (cacheable after parse).
// some Deletes, Updates, Scans are CACHEABLE_BIND (cacheable after bind).
}; // ExprNode
#endif /* EXPRNODE_H */