casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TaQLNodeHandler.h
Go to the documentation of this file.
00001 //# TaQLNodeHandler.h: Classes to handle the nodes in the raw TaQL parse tree
00002 //# Copyright (C) 2005
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: TaQLNodeHandler.h 20739 2009-09-29 01:15:15Z Malte.Marquarding $
00027 
00028 #ifndef TABLES_TAQLNODEHANDLER_H
00029 #define TABLES_TAQLNODEHANDLER_H
00030 
00031 //# Includes
00032 #include <tables/Tables/TaQLNodeVisitor.h>
00033 #include <tables/Tables/TaQLNodeDer.h>
00034 #include <tables/Tables/TableParse.h>
00035 #include <tables/Tables/ExprNode.h>
00036 #include <tables/Tables/ExprNodeSet.h>
00037 #include <casa/Containers/Record.h>
00038 #include <vector>
00039 
00040 namespace casa { //# NAMESPACE CASA - BEGIN
00041 
00042 //# Forward Declarations
00043 class TaQLNodeHRValue;
00044 
00045 
00046 // <summary>
00047 // Class to handle the nodes in the raw TaQL parse tree.
00048 // </summary>
00049 
00050 // <use visibility=local>
00051 
00052 // <reviewed reviewer="" date="" tests="tTableGram">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //# Classes you should understand before using this one.
00057 //   <li> <linkto class=TaQLNode>TaQLNode</linkto>
00058 //   <li> Note 199 describing
00059 //        <a href="../notes/199.html">
00060 //        TaQL</a>
00061 // </prerequisite>
00062 
00063 // <synopsis> 
00064 // TaQLNodeHandler is a specialization of class
00065 // <linkto class=TaQLNodeVisitor>TaQLNodeVisitor</linkto>.
00066 // It processes the raw TaQL parse tree generated by TableGram.
00067 // The processing is done in a recursive way. It starts at the top
00068 // (which is a SELECT, UPDATE, etc. expression) and the processing
00069 // results of a query are stored in a TableParseSelect object.
00070 // These objects are kept in a stack for possible nested queries.
00071 // After a query is fully processed, it is executed. Usually the result
00072 // is a table; only a CALC command gives a TableExprNode as result.
00073 // </synopsis> 
00074 
00075 // <motivation>
00076 // Separating the raw query parsing from the query processing has
00077 // several advantages compared to the old situation where parsing
00078 // and processing were combined.
00079 // <ul>
00080 //  <li> The full command is parsed before any processing is done.
00081 //       So in case of a parse error, no possibly expensive processing
00082 //       has been done yet.
00083 //  <li> In the future query optimization can be done in an easier way.
00084 //  <li> Nested parsing is not possible. In case a Table is opened
00085 //       with a virtual TaQL column, the parsing of that TaQL string
00086 //       does not interfere with parsing the TaQL command.
00087 //  <li> It is possible to use expressions in the column list.
00088 //       That could not be done before, because the column list was
00089 //       parsed/processed before the table list.
00090 // </ul>
00091 // </motivation>
00092 
00093 class TaQLNodeHandler : public TaQLNodeVisitor
00094 {
00095 public:
00096   virtual ~TaQLNodeHandler();
00097 
00098   // Handle and process the raw parse tree.
00099   // The result contains a Table or TableExprNode object.
00100   TaQLNodeResult handleTree (const TaQLNode& tree,
00101                              const std::vector<const Table*>&);
00102 
00103   // Define the functions to visit each node type.
00104   // <group>
00105   virtual TaQLNodeResult visitConstNode    (const TaQLConstNodeRep& node);
00106   virtual TaQLNodeResult visitRegexNode    (const TaQLRegexNodeRep& node);
00107   virtual TaQLNodeResult visitUnaryNode    (const TaQLUnaryNodeRep& node);
00108   virtual TaQLNodeResult visitBinaryNode   (const TaQLBinaryNodeRep& node);
00109   virtual TaQLNodeResult visitMultiNode    (const TaQLMultiNodeRep& node);
00110   virtual TaQLNodeResult visitFuncNode     (const TaQLFuncNodeRep& node);
00111   virtual TaQLNodeResult visitRangeNode    (const TaQLRangeNodeRep& node);
00112   virtual TaQLNodeResult visitIndexNode    (const TaQLIndexNodeRep& node);
00113   virtual TaQLNodeResult visitKeyColNode   (const TaQLKeyColNodeRep& node);
00114   virtual TaQLNodeResult visitTableNode    (const TaQLTableNodeRep& node);
00115   virtual TaQLNodeResult visitColNode      (const TaQLColNodeRep& node);
00116   virtual TaQLNodeResult visitColumnsNode  (const TaQLColumnsNodeRep& node);
00117   virtual TaQLNodeResult visitJoinNode     (const TaQLJoinNodeRep& node);
00118   virtual TaQLNodeResult visitSortKeyNode  (const TaQLSortKeyNodeRep& node);
00119   virtual TaQLNodeResult visitSortNode     (const TaQLSortNodeRep& node);
00120   virtual TaQLNodeResult visitLimitOffNode (const TaQLLimitOffNodeRep& node);
00121   virtual TaQLNodeResult visitGivingNode   (const TaQLGivingNodeRep& node);
00122   virtual TaQLNodeResult visitUpdExprNode  (const TaQLUpdExprNodeRep& node);
00123   virtual TaQLNodeResult visitSelectNode   (const TaQLSelectNodeRep& node);
00124   virtual TaQLNodeResult visitUpdateNode   (const TaQLUpdateNodeRep& node);
00125   virtual TaQLNodeResult visitInsertNode   (const TaQLInsertNodeRep& node);
00126   virtual TaQLNodeResult visitDeleteNode   (const TaQLDeleteNodeRep& node);
00127   virtual TaQLNodeResult visitCountNode    (const TaQLCountNodeRep& node);
00128   virtual TaQLNodeResult visitCalcNode     (const TaQLCalcNodeRep& node);
00129   virtual TaQLNodeResult visitCreTabNode   (const TaQLCreTabNodeRep& node);
00130   virtual TaQLNodeResult visitColSpecNode  (const TaQLColSpecNodeRep& node);
00131   virtual TaQLNodeResult visitRecFldNode   (const TaQLRecFldNodeRep& node);
00132   virtual TaQLNodeResult visitUnitNode     (const TaQLUnitNodeRep& node);
00133   // </group>
00134 
00135   // Get the actual result object from the result.
00136   static const TaQLNodeHRValue& getHR (const TaQLNodeResult&);
00137 
00138 private:
00139   // Push a new TableParseSelect on the stack.
00140   TableParseSelect* pushStack (TableParseSelect::CommandType);
00141 
00142   // Get the top of the TableParseSelect stack.
00143   TableParseSelect* topStack() const;
00144 
00145   // Pop the top from the TableParseSelect stack.
00146   void popStack();
00147 
00148   // Clear the select stack.
00149   void clearStack();
00150 
00151   // Handle the select command.
00152   // Optionally the command is not executed (needed for the EXISTS operator).
00153   TaQLNodeResult handleSelect (const TaQLSelectNodeRep& node, Bool doExec);
00154 
00155   // Handle a MultiNode containing table info.
00156   void handleTables (const TaQLMultiNode&);
00157 
00158   // Handle the WHERE clause.
00159   void handleWhere (const TaQLNode&);
00160 
00161   // Handle the UPDATE SET clause.
00162   void handleUpdate (const TaQLMultiNode&);
00163 
00164   // Handle the INSERT columns.
00165   void handleInsCol (const TaQLMultiNode&);
00166 
00167   // Handle the INSERT values.
00168   void handleInsVal (const TaQLNode&);
00169 
00170   // Handle a column specification in a create table.
00171   void handleColSpec (const TaQLMultiNode&);
00172 
00173   // Handle a record specification.
00174   Record handleRecord (const TaQLMultiNodeRep*);
00175 
00176   // Handle a record field and add it to the Record.
00177   void handleRecFld (const TaQLNode&, Record&);
00178 
00179   // Handle a record field with multiple values and add it to the Record.
00180   // The field can be a record or a vector of values.
00181   void handleMultiRecFld (const String& fldName,
00182                           const TaQLMultiNodeRep* node,
00183                           Record& rec);
00184 
00185   // Determine 'highest' constant data type and check if they match.
00186   int checkConstDtype (int dt1, int dt2);
00187 
00188 
00189   //# Use vector instead of stack because it has random access
00190   //# (which is used in TableParse.cc).
00191   std::vector<TableParseSelect*> itsStack;
00192   //# The temporary tables referred to by $i in the TaQL string.
00193   std::vector<const Table*> itsTempTables;
00194 };
00195 
00196 
00197 // <summary>
00198 // Class containing the result value of the handling of a TaQLNode.
00199 // </summary>
00200 
00201 // <use visibility=local>
00202 
00203 // <reviewed reviewer="" date="" tests="tTableGram">
00204 // </reviewed>
00205 
00206 // <prerequisite>
00207 //# Classes you should understand before using this one.
00208 //   <li> <linkto class=TaQLNode>TaQLNodeResult</linkto>
00209 //   <li> <linkto class=TaQLNode>TaQLNodeHandler</linkto>
00210 //   <li> Note 199 describing
00211 //        <a href="../notes/199.html">
00212 //        TaQL</a>
00213 // </prerequisite>
00214 
00215 // <synopsis> 
00216 // TaQLNodeHRValue is a specialization of class
00217 // <linkto class=TaQLNodeResultRep>TaQLNodeResultRep</linkto>.
00218 // It contains the values resulting from handling a particular node.
00219 // The object is effectively a collection of all possible values that
00220 // need to be returned. Which values are filled in, depends on which node
00221 // has been processed.
00222 // <note> The getHR function in TaQLNodeHandler is very useful to
00223 // extract/cast the TaQLNodeHRValue object from the general
00224 // TaQLNodeResult object.
00225 // </note>
00226 // </synopsis> 
00227 
00228 class TaQLNodeHRValue: public TaQLNodeResultRep
00229 {
00230 public:
00231   TaQLNodeHRValue()
00232     : itsInt(-1), itsElem(0), itsSet(0), itsNames(0) {}
00233   TaQLNodeHRValue (const TableExprNode& expr)
00234     : itsInt(-1), itsExpr(expr), itsElem(0), itsSet(0), itsNames(0) {}
00235   virtual ~TaQLNodeHRValue();
00236 
00237   // Get the values.
00238   // <group>
00239   Int getInt() const
00240     { return itsInt; }
00241   const String& getString() const
00242     { return itsString; }
00243   const String& getAlias() const
00244     { return itsAlias; }
00245   const String& getDtype() const
00246     { return itsDtype; }
00247   const Record& getRecord() const
00248     { return itsRecord; }
00249   const Table& getTable() const
00250     { return itsTable; }
00251   const TableExprNode& getExpr() const
00252     { return itsExpr; }
00253   const TableExprNodeSetElem* getElem() const
00254     { return itsElem; }
00255   const TableExprNodeSet& getExprSet() const
00256     { return *itsSet; }
00257   const Vector<String>* getNames() const
00258     { return itsNames; }
00259   // </group>
00260 
00261   // Set the values.
00262   // If a pointer is given, it takes over the pointer.
00263   // <group>
00264   void setInt (Int ival)
00265     { itsInt = ival; }
00266   void setString (const String& str)
00267     { itsString = str; }
00268   void setAlias (const String& alias)
00269     { itsAlias = alias; }
00270   void setDtype (const String& dtype)
00271     { itsDtype = dtype; }
00272   void setRecord (const Record& record)
00273     { itsRecord = record; }
00274   void setTable (const Table& table)
00275     { itsTable = table; }
00276   void setExpr (const TableExprNode& expr)
00277     { itsExpr = expr; }
00278   void setElem (TableExprNodeSetElem* elem)
00279     { itsElem = elem; }
00280   void setExprSet (TableExprNodeSet* set)
00281     { itsSet = set; }
00282   void setNames (Vector<String>* names)
00283     { itsNames = names; }
00284   // </group>
00285 
00286 private:
00287   Int    itsInt;
00288   String itsString;
00289   String itsAlias;
00290   String itsDtype;
00291   Record itsRecord;
00292   Table  itsTable;
00293   TableExprNode         itsExpr;
00294   TableExprNodeSetElem* itsElem;
00295   TableExprNodeSet*     itsSet;
00296   Vector<String>*       itsNames;
00297 };
00298 
00299 
00300 //# This function can only be implemented after TaQLNodeHRBase is declared.
00301 inline const TaQLNodeHRValue& TaQLNodeHandler::getHR (const TaQLNodeResult& res)
00302 {
00303   return *(TaQLNodeHRValue*)(res.getRep());
00304 }
00305 
00306   
00307 
00308 } //# NAMESPACE CASA - END
00309 
00310 #endif