casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TableParse.h
Go to the documentation of this file.
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