casa
$Rev:20696$
|
00001 //# TableParse.h: Classes to hold results from table grammar parser 00002 //# Copyright (C) 1994,1995,1997,1998,1999,2000,2001,2003 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: TableParse.h 21168 2012-01-04 08:11:03Z gervandiepen $ 00027 00028 #ifndef TABLES_TABLEPARSE_H 00029 #define TABLES_TABLEPARSE_H 00030 00031 //# Includes 00032 #include <casa/aips.h> 00033 #include <tables/Tables/Table.h> 00034 #include <tables/Tables/TableDesc.h> 00035 #include <tables/Tables/ExprNode.h> 00036 #include <tables/Tables/TaQLResult.h> 00037 #include <casa/BasicSL/String.h> 00038 #include <casa/Utilities/Sort.h> 00039 #include <casa/Containers/Block.h> 00040 #include <vector> 00041 00042 namespace casa { //# NAMESPACE CASA - BEGIN 00043 00044 //# Forward Declarations 00045 class TableExprNodeSet; 00046 class TableExprNodeIndex; 00047 class TableColumn; 00048 class AipsIO; 00049 template<class T> class Vector; 00050 00051 00052 // <summary> 00053 // Class to hold values from table grammar parser 00054 // </summary> 00055 00056 // <use visibility=local> 00057 00058 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tTableGram"> 00059 // </reviewed> 00060 00061 // <prerequisite> 00062 //# Classes you should understand before using this one. 00063 // </prerequisite> 00064 00065 // <etymology> 00066 // TableParse is the class used to parse a table command. 00067 // </etymology> 00068 00069 // <synopsis> 00070 // TableParse is used by the parser of table select statements. 00071 // The parser is written in Bison and Flex in files TableGram.y and .l. 00072 // The statements in there use the routines in this file to act 00073 // upon a reduced rule. 00074 // Since multiple tables can be given (with a shorthand), the table 00075 // names are stored in a container. The variable names can be qualified 00076 // by the table name and will be looked up in the appropriate table. 00077 // 00078 // A select command is similar to SQL and can look like: 00079 // SELECT columns FROM tab1 sh1, tab2 sh2, tab3 WHERE 00080 // sh1.field == 3*sh1.field2 ... ORDERBY columns GIVING table 00081 // This is described in more detail in TableGram.l. 00082 // 00083 // The class TableParse only contains information about a table 00084 // used in the table command. 00085 // 00086 // Global functions are used to operate on the information. 00087 // The main function is the global function tableCommand. 00088 // It executes the given TaQL command and returns the resulting table. 00089 // This is, in fact, the only function to be used by a user. 00090 // </synopsis> 00091 00092 // <motivation> 00093 // It is necessary to be able to give a table select command in ASCII. 00094 // This can be used in a CLI or in the table browser to get a subset 00095 // of a table or to sort a table. 00096 // </motivation> 00097 00098 //# <todo asof="$DATE:$"> 00099 //# A List of bugs, limitations, extensions or planned refinements. 00100 //# </todo> 00101 00102 00103 class TableParse 00104 { 00105 00106 public: 00107 // Default constructor for container class. 00108 TableParse(); 00109 00110 // Copy constructor (copy semantics). 00111 TableParse (const TableParse&); 00112 00113 // Assignment (copy semantics). 00114 TableParse& operator= (const TableParse&); 00115 00116 // Associate the table and the shorthand. 00117 TableParse (const Table& table, const String& shorthand); 00118 00119 // Test if shorthand matches. 00120 Bool test (const String& shortHand) const; 00121 00122 // Get the shorthand. 00123 const String& shorthand() const; 00124 00125 // Get table object. 00126 const Table& table() const; 00127 00128 private: 00129 String shorthand_p; 00130 Table table_p; 00131 }; 00132 00133 00134 00135 // <synopsis> 00136 // Parse and execute the given command. 00137 // It will open (and close) all tables needed. 00138 // It returns the resulting table. 00139 // The command type (select or update) and the selected or updated 00140 // column names can be returned. 00141 // Zero or more temporary tables can be used in the command 00142 // using the $nnn syntax. 00143 // </synopsis> 00144 // <group name=tableCommand> 00145 TaQLResult tableCommand (const String& command); 00146 00147 TaQLResult tableCommand (const String& command, 00148 const Table& tempTable); 00149 TaQLResult tableCommand (const String& command, 00150 const std::vector<const Table*>& tempTables); 00151 TaQLResult tableCommand (const String& command, 00152 Vector<String>& columnNames); 00153 TaQLResult tableCommand (const String& command, 00154 Vector<String>& columnNames, 00155 String& commandType); 00156 TaQLResult tableCommand (const String& command, 00157 const std::vector<const Table*>& tempTables, 00158 Vector<String>& columnNames); 00159 TaQLResult tableCommand (const String& command, 00160 const std::vector<const Table*>& tempTables, 00161 Vector<String>& columnNames, 00162 String& commandType); 00163 // </group> 00164 00165 00166 00167 00168 // <summary> 00169 // Helper class for sort keys in TableParse 00170 // </summary> 00171 00172 // <use visibility=local> 00173 00174 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00175 // </reviewed> 00176 00177 // <prerequisite> 00178 //# Classes you should understand before using this one. 00179 // <li> TableParse 00180 // </prerequisite> 00181 00182 // <etymology> 00183 // TableParseSort holds a sort expression and order. 00184 // </etymology> 00185 00186 // <synopsis> 00187 // A table command is parsed. 00188 // An object of this class is used to hold the sort expression 00189 // and sort order. 00190 // </synopsis> 00191 00192 00193 class TableParseSort 00194 { 00195 public: 00196 // Construct from a given expression. 00197 // The order is not given. 00198 TableParseSort(); 00199 00200 // Construct from a given expression. 00201 // The order is not given. 00202 explicit TableParseSort (const TableExprNode&); 00203 00204 // Construct from a given expression and for the given order. 00205 TableParseSort (const TableExprNode&, Sort::Order); 00206 00207 ~TableParseSort(); 00208 00209 // Get the expression node. 00210 const TableExprNode& node() const; 00211 00212 // Get the sort order. 00213 Sort::Order order() const; 00214 00215 // Is the order given? 00216 Bool orderGiven() const; 00217 00218 private: 00219 TableExprNode node_p; 00220 Sort::Order order_p; 00221 Bool given_p; 00222 }; 00223 00224 00225 00226 00227 // <summary> 00228 // Helper class for updates in TableParse 00229 // </summary> 00230 00231 // <use visibility=local> 00232 00233 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00234 // </reviewed> 00235 00236 // <prerequisite> 00237 //# Classes you should understand before using this one. 00238 // <li> TableParse 00239 // </prerequisite> 00240 00241 // <etymology> 00242 // TableParseUpdate holds a column name, optional indices, and an 00243 // update expression. 00244 // </etymology> 00245 00246 // <synopsis> 00247 // A table command is parsed. 00248 // An object of this class is used to hold the column name, optional indices, 00249 // and value expression for the UPDATE command. 00250 // </synopsis> 00251 00252 00253 class TableParseUpdate 00254 { 00255 public: 00256 TableParseUpdate() 00257 : indexPtr_p(0) {} 00258 00259 // Construct from a column name and expression. 00260 TableParseUpdate (const String& columnName, const TableExprNode&); 00261 00262 // Construct from a column name, subscripts, and expression. 00263 TableParseUpdate (const String& columnName, 00264 const TableExprNodeSet& indices, 00265 const TableExprNode&, 00266 const TaQLStyle&); 00267 00268 ~TableParseUpdate(); 00269 00270 // Set the column name. 00271 void setColumnName (const String& name); 00272 00273 // Get the column name. 00274 const String& columnName() const; 00275 00276 // Get the pointer to the indices. 00277 TableExprNodeIndex* indexPtr() const; 00278 00279 // Get the index expression node. 00280 const TableExprNode& indexNode() const; 00281 00282 // Get the expression node. 00283 // <group> 00284 const TableExprNode& node() const; 00285 TableExprNode& node(); 00286 // </group> 00287 00288 // Adapt the possible unit of the expression to the possible unit 00289 // of the column. 00290 void adaptUnit (const Unit& columnUnit); 00291 00292 private: 00293 String columnName_p; 00294 TableExprNodeIndex* indexPtr_p; //# copy of pointer in indexNode_p 00295 TableExprNode indexNode_p; 00296 TableExprNode node_p; 00297 }; 00298 00299 00300 00301 00302 // <summary> 00303 // Select-class for flex/bison scanner/parser for TableParse 00304 // </summary> 00305 00306 // <use visibility=local> 00307 00308 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00309 // </reviewed> 00310 00311 // <prerequisite> 00312 //# Classes you should understand before using this one. 00313 // <li> TableParse 00314 // <li> TableGram.l and .y (flex and bison grammar) 00315 // </prerequisite> 00316 00317 // <synopsis> 00318 // This class is needed for the the actions in the flex scanner 00319 // and bison parser. 00320 // This stores the information by constructing TableParse objects 00321 // as needed and storing them in a vector. 00322 // </synopsis> 00323 00324 // <motivation> 00325 // It is necessary to be able to give a table select command in ASCII. 00326 // This can be used in a CLI or in the table browser to get a subset 00327 // of a table or to sort a table. 00328 // </motivation> 00329 00330 //# <todo asof="$DATE:$"> 00331 //# A List of bugs, limitations, extensions or planned refinements. 00332 //# </todo> 00333 00334 00335 class TableParseSelect 00336 { 00337 public: 00338 enum CommandType { 00339 PSELECT, 00340 PUPDATE, 00341 PINSERT, 00342 PDELETE, 00343 PCOUNT, 00344 PCALC, 00345 PCRETAB 00346 }; 00347 00348 // Construct. 00349 TableParseSelect (CommandType type); 00350 00351 // Destructor. 00352 ~TableParseSelect(); 00353 00354 // Return the command type. 00355 CommandType commandType() const 00356 { return commandType_p; } 00357 00358 // Return the expression node. 00359 TableExprNode getNode() const 00360 { return node_p; } 00361 00362 // Execute the select command (select/sort/projection/giving). 00363 // The setInGiving flag tells if a set in the GIVING part is allowed. 00364 // The mustSelect flag tells if a SELECT command must do something. 00365 // Usually that is required, but not for a SELECT in an INSERT command. 00366 // Optionally the maximum nr of rows to be selected can be given. 00367 // It will be used as the default value for the LIMIT clause. 00368 // 0 = no maximum. 00369 void execute (Bool showTimings, Bool setInGiving, 00370 Bool mustSelect, uInt maxRow); 00371 00372 // Execute a query in a from clause resulting in a Table. 00373 Table doFromQuery (Bool showTimings); 00374 00375 // Execute a subquery and create an appropriate node for the result. 00376 TableExprNode doSubQuery (Bool showTimings); 00377 00378 // Test if a subquery has sufficient elements. 00379 // It uses default LIMIT=1, but that can be overidden in the subquery. 00380 // The flag tells if NOT EXISTS or EXISTS was given. 00381 TableExprNode doExists (Bool noexists, Bool showTimings); 00382 00383 // Show the expression tree. 00384 void show (ostream& os) const; 00385 00386 // Keep the selection expression. 00387 void handleSelect (const TableExprNode&); 00388 00389 // Keep the expression of a calculate command. 00390 void handleCalcComm (const TableExprNode&); 00391 00392 // Keep the create table command. 00393 void handleCreTab (const String& tableName, const Record& dmInfo); 00394 00395 // Keep the column specification in a create table command. 00396 void handleColSpec (const String& columnName, const String& dataType, 00397 const Record& spec, Bool isCOrder=False); 00398 00399 // Add an update object. 00400 void addUpdate (TableParseUpdate* upd); 00401 00402 // Keep the update expressions. 00403 void handleUpdate(); 00404 00405 // Make ready for the insert expression. 00406 // The first one uses values (added via addUpdate), 00407 // the second one a subquery. 00408 // <group> 00409 void handleInsert(); 00410 void handleInsert (TableParseSelect* sel); 00411 // </group> 00412 00413 // Make ready for a COUNT command. 00414 // It checks if all column expressions are scalar. 00415 void handleCount(); 00416 00417 // Keep the sort expressions. 00418 void handleSort (const std::vector<TableParseSort>& sortList, 00419 Bool noDuplicates, Sort::Order defaultSortOrder); 00420 00421 // Evaluate and keep the limit value. 00422 void handleLimit (const TableExprNode& expr); 00423 00424 // Evaluate and keep the offset value. 00425 void handleOffset (const TableExprNode& expr); 00426 00427 // Add a table nr, name, or object to the container. 00428 void addTable (Int tabnr, const String& name, 00429 const Table& table, 00430 const String& shorthand, 00431 const vector<const Table*> tempTables, 00432 const vector<TableParseSelect*>& stack); 00433 00434 // Replace the first table (used by CALC command). 00435 void replaceTable (const Table& table); 00436 00437 // Find the keyword or column name and create a TableExprNode from it. 00438 TableExprNode handleKeyCol (const String& name); 00439 00440 // Handle a slice operator. 00441 static TableExprNode handleSlice (const TableExprNode& array, 00442 const TableExprNodeSet& indices, 00443 const TaQLStyle&); 00444 00445 // Handle a function. 00446 TableExprNode handleFunc (const String& name, 00447 const TableExprNodeSet& arguments, 00448 const TaQLStyle&); 00449 00450 // Make a function object node for the given function name and arguments. 00451 // The ignoreFuncs vector contains invalid function codes. 00452 static TableExprNode makeFuncNode (const String& name, 00453 const TableExprNodeSet& arguments, 00454 const Vector<int>& ignoreFuncs, 00455 const Table& table, 00456 const TaQLStyle&); 00457 00458 // Add a column to the list of column names. 00459 void handleColumn (Int type, const String& name, const TableExprNode& expr, 00460 const String& newName, const String& newDtype); 00461 00462 // Finish the addition of columns to the list of column names. 00463 void handleColumnFinish (Bool distinct); 00464 00465 // Handle the name and type given in a GIVING clause. 00466 void handleGiving (const String& name, Int type); 00467 00468 // Handle the set given in a GIVING clause. 00469 void handleGiving (const TableExprNodeSet&); 00470 00471 // Get the projected column names. 00472 const Block<String>& getColumnNames() const; 00473 00474 // Get the resulting table. 00475 const Table& getTable() const; 00476 00477 00478 private: 00479 // Find the function code belonging to a function name. 00480 // Functions to be ignored can be given (as function type values). 00481 // If the function name is unknown, NRFUNC is returned. 00482 static TableExprFuncNode::FunctionType findFunc 00483 (const String& name, 00484 uInt narguments, 00485 const Vector<Int>& ignoreFuncs); 00486 00487 // Do the update step. 00488 // Rows 0,1,2,.. in UpdTable are updated from the expression result 00489 // for the rows in the given rownrs vector. 00490 void doUpdate (Bool showTimings, const Table& origTable, 00491 Table& updTable, const Vector<uInt>& rownrs); 00492 00493 // Do the insert step and return a selection containing the new rows. 00494 Table doInsert (Bool showTimings, Table& table); 00495 00496 // Do the delete step. 00497 void doDelete (Bool showTimings, Table& table); 00498 00499 // Do the count step returning a memory table containing the unique 00500 // column values and the counts of the column values. 00501 Table doCount (Bool showTimings, const Table&); 00502 00503 // Do the projection step returning a table containing the projection. 00504 Table doProject (Bool showTimings, const Table&); 00505 00506 // Do the projection containing column expressions. 00507 // Projection is done for the selected rownrs. 00508 Table doProjectExpr(); 00509 00510 // Do the sort step. 00511 void doSort (Bool showTimings, const Table& origTable); 00512 00513 // Do the limit/offset step. 00514 void doLimOff (Bool showTimings); 00515 Table doLimOff (Bool showTimings, const Table& table); 00516 00517 // Do the 'select distinct' step. 00518 Table doDistinct (Bool showTimings, const Table& table); 00519 00520 // Finish the table (rename, copy, and/or flush). 00521 Table doFinish (Bool showTimings, Table& table); 00522 00523 // Update the values in the columns (helpers of doUpdate). 00524 // <group> 00525 template<typename TCOL, typename TNODE> 00526 void updateValue2 (uInt row, const TableExprId& rowid, Bool isScalarCol, 00527 const TableExprNode& node, TableColumn& col, 00528 const Slicer* slicerPtr, 00529 IPosition& blc, IPosition& trc, IPosition& inc); 00530 template<typename T> 00531 void updateValue1 (uInt row, const TableExprId& rowid, Bool isScalarCol, 00532 const TableExprNode& node, TableColumn& col, 00533 const Slicer* slicerPtr, 00534 IPosition& blc, IPosition& trc, IPosition& inc); 00535 // </group> 00536 00537 // Make a data type from the string. 00538 // It checks if it is compatible with the given (expression) data type. 00539 DataType makeDataType (DataType dtype, const String& dtstr, 00540 const String& colName); 00541 00542 // Get the order for this key. Use the default order_p if not 00543 // explicitly given with the key. 00544 Sort::Order getOrder (const TableParseSort& key) const; 00545 00546 // Make an array from the contents of a column in a subquery. 00547 TableExprNode getColSet(); 00548 00549 // Make a set from the results of the subquery. 00550 TableExprNode makeSubSet (const Table& origTable) const; 00551 00552 // Evaluate an int scalar expression. 00553 Int64 evalIntScaExpr (const TableExprNode& expr) const; 00554 00555 // Split a name into its parts (shorthand, column and field names). 00556 // True is returned when the name contained a keyword part. 00557 // In that case fieldNames contains the keyword name and the possible 00558 // subfields. The possible shorthand and the column name are 00559 // filled in if it is a column keyword. 00560 // If the name represents a column, fieldNames contains the subfields 00561 // of the column (for the case where the column contains records). 00562 // If the name is invalid, an exception is thrown if checkError=True. 00563 // Otherwise the name is treated as a normal name without keyword. 00564 Bool splitName (String& shorthand, String& columnName, 00565 Vector<String>& fieldNames, const String& name, 00566 Bool checkError) const; 00567 00568 // Find a table for the given shorthand. 00569 // If no shorthand is given, the first table is returned (if there). 00570 // If not found, a null Table object is returned. 00571 Table findTable (const String& shorthand) const; 00572 00573 // Handle the selection of a wildcarded column name. 00574 void handleWildColumn (Int stringType, const String& name); 00575 00576 // Add the description of a column to the table description. 00577 // ndim < 0 means a scalar column. 00578 void addColumnDesc (TableDesc& td, DataType dtype, 00579 const String& colName, Int options, 00580 Int ndim, const IPosition& shape, 00581 const String& dmType, const String& dmGroup, 00582 const String& comment, 00583 const String& unitName); 00584 00585 // Find the names of all stored columns in a table. 00586 Block<String> getStoredColumns (const Table& tab) const; 00587 00588 // Try to find the keyword representing a table in one of the tables 00589 // in any select block (from inner to outer). 00590 // If not found, an exception is thrown. 00591 static Table tableKey (const String& fullName, 00592 const String& shorthand, const String& columnName, 00593 const Vector<String>& fieldNames, 00594 const vector<TableParseSelect*>& stack); 00595 00596 // Try to find the keyword representing a table in the given table. 00597 // If the columnName is empty, the keyword is a table keyword. 00598 // If not found, a null Table object is returned. 00599 static Table findTableKey (const Table& table, const String& columnName, 00600 const Vector<String>& keyNames); 00601 00602 00603 //# Command type. 00604 CommandType commandType_p; 00605 //# Table description for a series of column descriptions. 00606 TableDesc tableDesc_p; 00607 //# Vector of TableParse objects. 00608 //# This is needed for the functions above, otherwise they have no 00609 //# way to communicate. 00610 vector<TableParse> fromTables_p; 00611 //# Block of selected column names (new name in case of select). 00612 Block<String> columnNames_p; 00613 //# Block of selected column expressions. 00614 Block<TableExprNode> columnExpr_p; 00615 //# The old name for a selected column. 00616 Block<String> columnOldNames_p; 00617 //# The new data type for a column. 00618 Block<String> columnDtypes_p; 00619 //# Number of expressions used in selected columns. 00620 uInt nrSelExprUsed_p; 00621 //# Distinct values in output? 00622 Bool distinct_p; 00623 //# Name and type of the resulting table (from GIVING part). 00624 String resultName_p; 00625 Int resultType_p; 00626 //# Resulting set (from GIVING part). 00627 TableExprNodeSet* resultSet_p; 00628 //# The WHERE expression tree. 00629 TableExprNode node_p; 00630 //# The possible limit (= max nr of selected rows) (0 means no limit). 00631 Int64 limit_p; 00632 //# The possible offset (= nr of selected rows to skip). 00633 Int64 offset_p; 00634 //# The update or insert expression list. 00635 std::vector<TableParseUpdate*> update_p; 00636 //# The table selection to be inserted. 00637 TableParseSelect* insSel_p; 00638 //# The sort list. 00639 std::vector<TableParseSort> sort_p; 00640 //# The noDuplicates sort switch. 00641 Bool noDupl_p; 00642 //# The default sort order. 00643 Sort::Order order_p; 00644 //# The resulting table. 00645 Table table_p; 00646 //# The resulting row numbers. 00647 Vector<uInt> rownrs_p; 00648 }; 00649 00650 00651 00652 //# Implement the inline functions. 00653 inline Bool TableParse::test (const String& str) const 00654 { return (shorthand_p == str ? True : False); } 00655 00656 inline const String& TableParse::shorthand() const 00657 { return shorthand_p; } 00658 00659 inline const Table& TableParse::table() const 00660 { return table_p; } 00661 00662 00663 inline void TableParseUpdate::setColumnName (const String& name) 00664 { columnName_p = name; } 00665 inline const String& TableParseUpdate::columnName() const 00666 { return columnName_p; } 00667 inline TableExprNodeIndex* TableParseUpdate::indexPtr() const 00668 { return indexPtr_p; } 00669 inline const TableExprNode& TableParseUpdate::indexNode() const 00670 { return indexNode_p; } 00671 inline const TableExprNode& TableParseUpdate::node() const 00672 { return node_p; } 00673 inline TableExprNode& TableParseUpdate::node() 00674 { return node_p; } 00675 inline void TableParseUpdate::adaptUnit (const Unit& columnUnit) 00676 { node_p.adaptUnit (columnUnit); } 00677 00678 inline const TableExprNode& TableParseSort::node() const 00679 { return node_p; } 00680 inline Bool TableParseSort::orderGiven() const 00681 { return given_p; } 00682 inline Sort::Order TableParseSort::order() const 00683 { return order_p; } 00684 00685 00686 inline const Block<String>& TableParseSelect::getColumnNames() const 00687 { return columnNames_p; } 00688 00689 inline const Table& TableParseSelect::getTable() const 00690 { return table_p; } 00691 00692 inline void TableParseSelect::addUpdate (TableParseUpdate* upd) 00693 { update_p.push_back (upd); } 00694 00695 inline Sort::Order TableParseSelect::getOrder (const TableParseSort& key) const 00696 { return (key.orderGiven() ? key.order() : order_p); } 00697 00698 00699 } //# NAMESPACE CASA - END 00700 00701 #endif