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$ 00027 00028 #ifndef TABLES_TAQLNODEHANDLER_H 00029 #define TABLES_TAQLNODEHANDLER_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/tables/TaQL/TaQLNodeVisitor.h> 00034 #include <casacore/tables/TaQL/TaQLNodeDer.h> 00035 #include <casacore/tables/TaQL/TableParse.h> 00036 #include <casacore/tables/TaQL/ExprNode.h> 00037 #include <casacore/tables/TaQL/ExprNodeSet.h> 00038 #include <casacore/casa/Containers/Record.h> 00039 #include <casacore/casa/Containers/ValueHolder.h> 00040 #include <vector> 00041 00042 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00043 00044 //# Forward Declarations 00045 class TaQLNodeHRValue; 00046 00047 00048 // <summary> 00049 // Class to handle the nodes in the raw TaQL parse tree. 00050 // </summary> 00051 00052 // <use visibility=local> 00053 00054 // <reviewed reviewer="" date="" tests="tTableGram"> 00055 // </reviewed> 00056 00057 // <prerequisite> 00058 //# Classes you should understand before using this one. 00059 // <li> <linkto class=TaQLNode>TaQLNode</linkto> 00060 // <li> Note 199 describing 00061 // <a href="../notes/199.html"> 00062 // TaQL</a> 00063 // </prerequisite> 00064 00065 // <synopsis> 00066 // TaQLNodeHandler is a specialization of class 00067 // <linkto class=TaQLNodeVisitor>TaQLNodeVisitor</linkto>. 00068 // It processes the raw TaQL parse tree generated by TableGram. 00069 // The processing is done in a recursive way. It starts at the top 00070 // (which is a SELECT, UPDATE, etc. expression) and the processing 00071 // results of a query are stored in a TableParseSelect object. 00072 // These objects are kept in a stack for possible nested queries. 00073 // After a query is fully processed, it is executed. Usually the result 00074 // is a table; only a CALC command gives a TableExprNode as result. 00075 // </synopsis> 00076 00077 // <motivation> 00078 // Separating the raw query parsing from the query processing has 00079 // several advantages compared to the old situation where parsing 00080 // and processing were combined. 00081 // <ul> 00082 // <li> The full command is parsed before any processing is done. 00083 // So in case of a parse error, no possibly expensive processing 00084 // has been done yet. 00085 // <li> In the future query optimization can be done in an easier way. 00086 // <li> Nested parsing is not possible. In case a Table is opened 00087 // with a virtual TaQL column, the parsing of that TaQL string 00088 // does not interfere with parsing the TaQL command. 00089 // <li> It is possible to use expressions in the column list. 00090 // That could not be done before, because the column list was 00091 // parsed/processed before the table list. 00092 // </ul> 00093 // </motivation> 00094 00095 class TaQLNodeHandler : public TaQLNodeVisitor 00096 { 00097 public: 00098 virtual ~TaQLNodeHandler(); 00099 00100 // Handle and process the raw parse tree. 00101 // The result contains a Table or TableExprNode object. 00102 TaQLNodeResult handleTree (const TaQLNode& tree, 00103 const std::vector<const Table*>&); 00104 00105 // Define the functions to visit each node type. 00106 // <group> 00107 virtual TaQLNodeResult visitConstNode (const TaQLConstNodeRep& node); 00108 virtual TaQLNodeResult visitRegexNode (const TaQLRegexNodeRep& node); 00109 virtual TaQLNodeResult visitUnaryNode (const TaQLUnaryNodeRep& node); 00110 virtual TaQLNodeResult visitBinaryNode (const TaQLBinaryNodeRep& node); 00111 virtual TaQLNodeResult visitMultiNode (const TaQLMultiNodeRep& node); 00112 virtual TaQLNodeResult visitFuncNode (const TaQLFuncNodeRep& node); 00113 virtual TaQLNodeResult visitRangeNode (const TaQLRangeNodeRep& node); 00114 virtual TaQLNodeResult visitIndexNode (const TaQLIndexNodeRep& node); 00115 virtual TaQLNodeResult visitKeyColNode (const TaQLKeyColNodeRep& node); 00116 virtual TaQLNodeResult visitTableNode (const TaQLTableNodeRep& node); 00117 virtual TaQLNodeResult visitColNode (const TaQLColNodeRep& node); 00118 virtual TaQLNodeResult visitColumnsNode (const TaQLColumnsNodeRep& node); 00119 virtual TaQLNodeResult visitJoinNode (const TaQLJoinNodeRep& node); 00120 virtual TaQLNodeResult visitGroupNode (const TaQLGroupNodeRep& node); 00121 virtual TaQLNodeResult visitSortKeyNode (const TaQLSortKeyNodeRep& node); 00122 virtual TaQLNodeResult visitSortNode (const TaQLSortNodeRep& node); 00123 virtual TaQLNodeResult visitLimitOffNode (const TaQLLimitOffNodeRep& node); 00124 virtual TaQLNodeResult visitGivingNode (const TaQLGivingNodeRep& node); 00125 virtual TaQLNodeResult visitUpdExprNode (const TaQLUpdExprNodeRep& node); 00126 virtual TaQLNodeResult visitSelectNode (const TaQLSelectNodeRep& node); 00127 virtual TaQLNodeResult visitUpdateNode (const TaQLUpdateNodeRep& node); 00128 virtual TaQLNodeResult visitInsertNode (const TaQLInsertNodeRep& node); 00129 virtual TaQLNodeResult visitDeleteNode (const TaQLDeleteNodeRep& node); 00130 virtual TaQLNodeResult visitCountNode (const TaQLCountNodeRep& node); 00131 virtual TaQLNodeResult visitCalcNode (const TaQLCalcNodeRep& node); 00132 virtual TaQLNodeResult visitCreTabNode (const TaQLCreTabNodeRep& node); 00133 virtual TaQLNodeResult visitColSpecNode (const TaQLColSpecNodeRep& node); 00134 virtual TaQLNodeResult visitRecFldNode (const TaQLRecFldNodeRep& node); 00135 virtual TaQLNodeResult visitUnitNode (const TaQLUnitNodeRep& node); 00136 virtual TaQLNodeResult visitAltTabNode (const TaQLAltTabNodeRep& node); 00137 virtual TaQLNodeResult visitAddColNode (const TaQLAddColNodeRep& node); 00138 virtual TaQLNodeResult visitSetKeyNode (const TaQLSetKeyNodeRep& node); 00139 virtual TaQLNodeResult visitRenDropNode (const TaQLRenDropNodeRep& node); 00140 virtual TaQLNodeResult visitAddRowNode (const TaQLAddRowNodeRep& node); 00141 virtual TaQLNodeResult visitConcTabNode (const TaQLConcTabNodeRep& node); 00142 virtual TaQLNodeResult visitShowNode (const TaQLShowNodeRep& node); 00143 // </group> 00144 00145 // Get the actual result object from the result. 00146 static const TaQLNodeHRValue& getHR (const TaQLNodeResult&); 00147 00148 private: 00149 // Push a new TableParseSelect on the stack. 00150 TableParseSelect* pushStack (TableParseSelect::CommandType); 00151 00152 // Get the top of the TableParseSelect stack. 00153 TableParseSelect* topStack() const; 00154 00155 // Pop the top from the TableParseSelect stack. 00156 void popStack(); 00157 00158 // Clear the select stack. 00159 void clearStack(); 00160 00161 // Handle the select command. 00162 // Optionally the command is not executed (needed for the EXISTS operator). 00163 TaQLNodeResult handleSelect (const TaQLSelectNodeRep& node, Bool doExec); 00164 00165 // Handle a MultiNode containing table info. 00166 void handleTables (const TaQLMultiNode&); 00167 00168 // Make a ConcatTable from a nested set of tables. 00169 Table makeConcatTable (const TaQLMultiNodeRep& node); 00170 00171 // Handle the WHERE clause. 00172 void handleWhere (const TaQLNode&); 00173 00174 // Handle the HAVING clause. 00175 void handleHaving (const TaQLNode&); 00176 00177 // Handle the UPDATE SET clause. 00178 void handleUpdate (const TaQLMultiNode&); 00179 00180 // Handle the INSERT columns. 00181 void handleInsCol (const TaQLMultiNode&); 00182 00183 // Handle the INSERT values. 00184 void handleInsVal (const TaQLNode&); 00185 00186 // Handle a column specification in a create table. 00187 void handleColSpecs (const TaQLMultiNode&); 00188 00189 // Handle a Multi RecFld representing a Record. 00190 Record handleMultiRecFld (const TaQLNode& node); 00191 00192 00193 //# Use vector instead of stack because it has random access 00194 //# (which is used in TableParse.cc). 00195 std::vector<TableParseSelect*> itsStack; 00196 //# The temporary tables referred to by $i in the TaQL string. 00197 std::vector<const Table*> itsTempTables; 00198 }; 00199 00200 00201 // <summary> 00202 // Class containing the result value of the handling of a TaQLNode. 00203 // </summary> 00204 00205 // <use visibility=local> 00206 00207 // <reviewed reviewer="" date="" tests="tTableGram"> 00208 // </reviewed> 00209 00210 // <prerequisite> 00211 //# Classes you should understand before using this one. 00212 // <li> <linkto class=TaQLNode>TaQLNodeResult</linkto> 00213 // <li> <linkto class=TaQLNode>TaQLNodeHandler</linkto> 00214 // <li> Note 199 describing 00215 // <a href="../notes/199.html"> 00216 // TaQL</a> 00217 // </prerequisite> 00218 00219 // <synopsis> 00220 // TaQLNodeHRValue is a specialization of class 00221 // <linkto class=TaQLNodeResultRep>TaQLNodeResultRep</linkto>. 00222 // It contains the values resulting from handling a particular node. 00223 // The object is effectively a collection of all possible values that 00224 // need to be returned. Which values are filled in, depends on which node 00225 // has been processed. 00226 // <note> The getHR function in TaQLNodeHandler is very useful to 00227 // extract/cast the TaQLNodeHRValue object from the general 00228 // TaQLNodeResult object. 00229 // </note> 00230 // </synopsis> 00231 00232 class TaQLNodeHRValue: public TaQLNodeResultRep 00233 { 00234 public: 00235 TaQLNodeHRValue() 00236 : itsInt(-1), itsElem(0), itsSet(0), itsNames(0) {} 00237 TaQLNodeHRValue (const TableExprNode& expr) 00238 : itsInt(-1), itsExpr(expr), itsElem(0), itsSet(0), itsNames(0) {} 00239 virtual ~TaQLNodeHRValue(); 00240 00241 // Get the values. 00242 // <group> 00243 Int getInt() const 00244 { return itsInt; } 00245 const String& getString() const 00246 { return itsString; } 00247 const String& getAlias() const 00248 { return itsAlias; } 00249 const String& getNameMask() const 00250 { return itsNameMask; } 00251 const String& getDtype() const 00252 { return itsDtype; } 00253 const Record& getRecord() const 00254 { return itsRecord; } 00255 const ValueHolder& getValueHolder() const 00256 { return itsVH; } 00257 const Table& getTable() const 00258 { return itsTable; } 00259 const TableExprNode& getExpr() const 00260 { return itsExpr; } 00261 const TableExprNodeSetElem* getElem() const 00262 { return itsElem; } 00263 const TableExprNodeSet& getExprSet() const 00264 { return *itsSet; } 00265 const Vector<String>* getNames() const 00266 { return itsNames; } 00267 // </group> 00268 00269 // Set the values. 00270 // If a pointer is given, it takes over the pointer. 00271 // <group> 00272 void setInt (Int ival) 00273 { itsInt = ival; } 00274 void setString (const String& str) 00275 { itsString = str; } 00276 void setAlias (const String& alias) 00277 { itsAlias = alias; } 00278 void setNameMask (const String& nameMask) 00279 { itsNameMask = nameMask; } 00280 void setDtype (const String& dtype) 00281 { itsDtype = dtype; } 00282 void setRecord (const Record& record) 00283 { itsRecord = record; } 00284 void setValueHolder (const ValueHolder& vh) 00285 { itsVH = vh; } 00286 void setTable (const Table& table) 00287 { itsTable = table; } 00288 void setExpr (const TableExprNode& expr) 00289 { itsExpr = expr; } 00290 void setElem (TableExprNodeSetElem* elem) 00291 { itsElem = elem; } 00292 void setExprSet (TableExprNodeSet* set) 00293 { itsSet = set; } 00294 void setNames (Vector<String>* names) 00295 { itsNames = names; } 00296 // </group> 00297 00298 private: 00299 Int itsInt; 00300 String itsString; 00301 String itsAlias; 00302 String itsNameMask; 00303 String itsDtype; 00304 Record itsRecord; 00305 ValueHolder itsVH; 00306 Table itsTable; 00307 TableExprNode itsExpr; 00308 TableExprNodeSetElem* itsElem; 00309 TableExprNodeSet* itsSet; 00310 Vector<String>* itsNames; 00311 }; 00312 00313 00314 //# This function can only be implemented after TaQLNodeHRBase is declared. 00315 inline const TaQLNodeHRValue& TaQLNodeHandler::getHR (const TaQLNodeResult& res) 00316 { 00317 return *(TaQLNodeHRValue*)(res.getRep()); 00318 } 00319 00320 00321 00322 } //# NAMESPACE CASACORE - END 00323 00324 #endif