BadgerDB
/afs/cs.wisc.edu/u/n/w/nwilliam/private/workspace/Quut/src/parser/SqlParser.h
00001 //
00002 // Author: Jignesh M. Patel
00003 //         EECS Department, University of Michigan
00004 // Date:   August 2000
00005 //
00006 
00017 #ifndef SQL_PARSE_H
00018 #define SQL_PARSE_H
00019 
00020 #include <iostream>
00021 #include <cstring>
00022 #include <cassert>
00023 #include "types.h"
00024 
00025 using namespace std;
00026 using namespace badgerdb;
00027 
00028 class PxxInterp;
00029 //
00030 // Class encapsulating the Parser support routines
00031 //
00032 // TODO: Pre-allocate an array for each of the Parser Node Types and allocate
00033 //       entries from this array. The allocation of various parser nodes in sqlparser.y
00034 //       could slow down query compilation time considerably.
00035 // TODO: Purify!
00036 //
00037 class PxxParser
00038 {
00039 public:
00040    static const char* Prompt;
00041 };
00042 
00043 //
00044 // Base type for all parser classes
00045 //
00046 class PxxPnode 
00047 {
00048 public:
00049    
00050    // The different types of nodes
00051    enum NodeType 
00052    {
00053       Query,
00054          Create,
00055          CreateIndex,
00056          Delete,
00057          Drop,
00058          DropIndex,
00059          Insert,
00060          AttrName,
00061          AggrFunc,
00062          RelName,
00063          DataType,
00064          AttrType,
00065          Value,
00066          List,
00067          Predicate,
00068          PredTree,
00069          Literal
00070    };
00071    
00072    // Returns the node type
00073    virtual NodeType MyType() const = 0;
00074    
00075    // Print a description of this class instance
00076    virtual void Write (ostream& os) const 
00077    {
00078       os << "Node type: " << (unsigned) MyType();
00079    };
00080    
00081    virtual ~PxxPnode() {};
00082    // TODO: Add a method typecheck to consult the catalogs and type check the parse nodes.
00083    // virtual bool TypeCheck() const = 0; 
00084 };
00085 
00086 class PxxList; //dummy definition to satiate the compiler
00087 
00088 // Generic list node class.
00089 class ListNode
00090 {
00091    friend class PxxList;
00092 public:
00093    ListNode(PxxPnode* n) {_data = n; _next = 0;}
00094    void Write (ostream& os) const   {_data->Write(os);}
00095    ~ListNode() {if (_data) delete _data;}
00096    PxxPnode* Data() {return _data;} 
00097    ListNode* Next() 
00098    {
00099       return _next;   
00100    } 
00101    
00102 private:
00103    PxxPnode*   _data;
00104    ListNode*   _next;
00105 };
00106 //
00107 // Generic list of PxxNodes
00108 //
00109 class PxxList : public PxxPnode
00110 {
00111 public:
00112    
00113    PxxList(PxxPnode* n) 
00114    {
00115       _head = new ListNode(n);
00116       _tail = _head;
00117       _card = 1;
00118    }
00119    
00120    PxxList() {_head = 0; _tail = 0; _card = 0;} 
00121    
00122    // Definition of the pure virtual methods
00123    NodeType MyType() const {return List;}
00124    void Write (ostream& os) const;
00125    
00126    // Add a node 
00127    PxxList* Add(PxxPnode* n);
00128    
00129    // Destructor
00130    ~PxxList();
00131    
00132    unsigned Cardinality() {return _card;}
00133    
00134    // get first, used for quickly decting star shorthand in the select list
00135    ListNode* First() 
00136    {
00137       if(_head)
00138          return _head;
00139       return 0;
00140    }
00141 
00142    // iterator
00143    ListNode* Init() 
00144    {
00145       _pos = _head;
00146       if(_head)
00147          return _head;
00148       return 0;
00149    }
00150    
00151    ListNode* Next() 
00152    {
00153       if(!_pos) return 0;
00154       _pos=_pos->_next;
00155       if (_pos)
00156          return _pos;
00157       return 0;
00158    }
00159    
00160 private:
00161    ListNode*   _head;
00162    ListNode*   _tail;
00163    ListNode*   _pos;
00164    unsigned    _card;
00165 };
00166 
00167 inline PxxList* PxxList::Add(PxxPnode* n)
00168 {
00169    if (!_head)
00170    {
00171       _head = new ListNode(n);
00172       _tail = _head;
00173    }
00174    else
00175    {
00176       _tail->_next = new ListNode(n);
00177       _tail = _tail->_next;
00178    }
00179    
00180    _card++;
00181    return this;
00182 }
00183 
00184 inline void PxxList::Write (ostream& os) const
00185 {
00186    const ListNode* cur = _head;
00187    unsigned idx = 0;
00188    while (cur)
00189    {
00190       os << endl << "\t\t-" << idx++ << "- ";
00191       cur->Write(os);
00192       cur = cur->_next;
00193    }
00194 }
00195 
00196 inline PxxList::~PxxList()
00197 {
00198    ListNode* next;
00199    ListNode* cur = _head;
00200    
00201    while (cur)
00202    {
00203       // cout << "Deleting node: "; cur->Write(cout); cout << endl;
00204       next = cur->_next;
00205       delete cur;
00206       cur = next;
00207    }
00208 }
00209 
00210 // 
00211 // SQL data type parse node descriptor
00212 //
00213 class PxxDataType : public PxxPnode
00214 { 
00215    
00216 public:
00217    enum DataType {
00218          INTEGER=0,
00219          DOUBLE=1,
00220          STRING=2
00221    };
00222    PxxDataType(DataType type, int param1 = 0, int param2 = 0)
00223    {
00224       _type = type;
00225       _param1 = param1;
00226       _param2 = param2;
00227    }
00228    
00229    // Definition of the pure virtual methods
00230    NodeType MyType() const {return PxxPnode::DataType;}
00231    DataType Type() {return _type;} 
00232    void Write (ostream& os) const;
00233    
00234 protected:
00235    DataType _type;
00236    int _param1, _param2;
00237 };
00238 
00239 inline void PxxDataType::Write (ostream& os) const
00240 {
00241    os << "Type: " << (unsigned) _type ;
00242    if (_param1) os << "(" << _param1;
00243    if (_param2) os<< "." << _param2;
00244    if (_param1) os << ")";
00245    os << " ";
00246 }
00247 
00248 // 
00249 // SQL AttrType parse node; used when parsing create table commands
00250 // 
00251 class PxxAttrType : public PxxDataType
00252 {
00253 public:
00254    PxxAttrType(DataType type, int param1 = 0, int param2 = 0) 
00255       : PxxDataType(type, param1, param2), _attrName(0) {}
00256    
00257    // Definition of the pure virtual methods
00258    NodeType MyType() const {return PxxPnode::AttrType;}
00259    void Write (ostream& os) const;
00260    
00261    void SetAttrName (char* aname) {_attrName = aname;};
00262    
00263    char* AttrName() {return _attrName;}
00264    DataType Type() {return _type;}
00265    int  Param1() {return _param1;}
00266    int  Param2() {return _param2;}
00267    
00268 private:
00269    char* _attrName;  // The name of the attribute being created
00270 };
00271 
00272 inline void PxxAttrType::Write (ostream& os) const
00273 {
00274    if (_attrName) os << _attrName << ", ";
00275    PxxDataType::Write(os);
00276 }
00277 
00278 //
00279 // Parse node describing a Relation name with references
00280 // 
00281 class PxxRelName : public PxxPnode
00282 {
00283 public:
00284    PxxRelName(char* rel, char* ref = 0) : _rel(rel), _ref(ref) {};   
00285    
00286    // Definition of the pure virtual methods
00287    NodeType MyType() const {return PxxPnode::RelName;}
00288    void Write (ostream& os) const;
00289    
00290    char* RelName() const { return _rel;}
00291    char* RefName() const { return _ref;}
00292    
00293    void SetRelName(char* rel) {_rel = rel;}
00294    
00295 private:
00296    char* _rel;  // The relation name
00297    char* _ref;  // The name used to refer to this relation in the query
00298 };
00299 
00300 inline void PxxRelName::Write (ostream& os) const
00301 {
00302    os << "RelName: " << _rel;
00303    if (_ref) os << "(Ref:" << _ref << ")";
00304 }
00305 
00306 
00307 //
00308 // Parse node describing an Attribute name with references
00309 // 
00310 class PxxAttrName : public PxxPnode
00311 {
00312 public:
00313    PxxAttrName(bool star) : _attr(0), _rel(0), _star(true), _copy(false) {};
00314    PxxAttrName(char* attr, char* rel = 0, bool copy = false) : 
00315                      _attr(attr), _rel(rel), _star(false), _copy(copy) 
00316    {
00317       if (copy) 
00318       {
00319          _attr = new char[strlen(attr)+1];
00320          strcpy (_attr, attr);
00321          _rel = new char[strlen(rel)+1];
00322          strcpy (_rel, rel);
00323       }
00324    }
00325    ~PxxAttrName() 
00326    {
00327       if (_copy)
00328       {
00329          delete [] _attr;
00330          delete [] _rel;
00331       }
00332    };
00333    
00334    // Definition of the pure virtual methods
00335    NodeType MyType() const {return PxxPnode::AttrName;}
00336    void Write (ostream& os) const;
00337    
00338    char* AttrName() {return _attr;}
00339    char* RelName() {return _rel;}
00340    bool Star() {return _star;}
00341    
00342 private:
00343    char* _attr;  // The name of the attribute
00344    char* _rel;   // The name of the relation (may be empty)
00345    bool  _star;  // Denoting the "special" attribute "*"
00346    bool  _copy;  // are the attrnames and relnames copied here.
00347 };
00348 
00349 
00350 inline void PxxAttrName::Write (ostream& os) const
00351 {
00352    if (_star) os << "*";
00353    else
00354    {
00355       if (_rel) os << _rel << "."; 
00356       os << _attr;
00357    }
00358 }
00359 
00360 //
00361 // Parse node describing a Literal
00362 // 
00363 class PxxLiteral : public PxxDataType
00364 {
00365 public:
00366    PxxLiteral(void* lval, DataType type, int param1 = 0, int param2 = 0) 
00367       : PxxDataType(type, param1, param2)
00368    {
00369       _type = type;
00370       switch (type)
00371       {
00372       case STRING:
00373          {
00374             _lval.cval = (char*)lval;
00375             break;
00376          }
00377       case INTEGER: 
00378          {
00379             _lval.ival = *((int*)lval);
00380             break;
00381          }
00382          
00383       case DOUBLE:
00384          {
00385             _lval.dval = *((double*)lval);
00386             break;
00387          }
00388       default: assert (!"Invalid Data Type");
00389          
00390       }
00391    }
00392    
00393    // Definition of the pure virtual methods
00394    NodeType MyType() const {return PxxPnode::Literal;}
00395    void Write (ostream& os) const;
00396    
00397    int* Int() {return &_lval.ival;}
00398    double* Double() { return &_lval.dval;}
00399    char* Char() { return _lval.cval;}
00400 
00401    DataType LiteralType () const {return _type;}
00402    
00403 private:
00404    DataType _type;
00405 
00406    union
00407    {
00408       int    ival;   // An integer literal value
00409       double dval;   // A real literal value
00410       char*  cval;   // A character literal value
00411    } _lval;
00412    
00413 };
00414 
00415 inline void PxxLiteral::Write (ostream& os) const
00416 {
00417    // os << "Literal: ";
00418    PxxDataType::Write(os);
00419    os << ", Val: ";
00420    switch (_type)
00421    {
00422    case STRING:     os << _lval.cval; break;
00423    case INTEGER:  os << _lval.ival; break;         
00424    case DOUBLE:   os << _lval.dval; break;
00425    default: assert (!"Invalid Data Type");         
00426    }
00427 }
00428 
00429 
00430 // 
00431 // SQL Aggregate Function parse node
00432 // 
00433 class PxxAggrFunc : public PxxPnode
00434 {
00435 public:
00436    enum AggrFunc   
00437    {
00438       Avg,
00439          Count,
00440          Min,
00441          Max,
00442          Sum
00443    };
00444    
00445    PxxAggrFunc(PxxAttrName* aname, AggrFunc afunc) : _func(afunc), _attr(aname) {}
00446    
00447    // Definition of the pure virtual methods
00448    NodeType MyType() const {return PxxPnode::AggrFunc;}
00449    void Write (ostream& os) const;
00450    ~PxxAggrFunc() {if (_attr) delete _attr;}
00451    
00452 private:
00453    AggrFunc       _func;  // The aggregate function
00454    PxxAttrName*   _attr;  // The attribute being aggregated
00455 };
00456 
00457 inline void PxxAggrFunc::Write (ostream& os) const
00458 {
00459    os << "AggrFunc: " << (unsigned) _func << ", ";
00460    _attr->Write(os);
00461 }
00462 
00463 //
00464 // Parse node for create table statements
00465 //
00466 class PxxCreate : public PxxPnode
00467 {
00468 public:
00469    PxxCreate(char* rname, PxxList* alist, PxxList* plist=0)
00470    {
00471       _relName = rname;
00472       _attrList = alist;
00473       _primattrs = plist;
00474    }
00475    
00476    // Definition of the pure virtual methods
00477    NodeType MyType() const {return PxxPnode::Create;}
00478    void Write (ostream& os) const;
00479    ~PxxCreate() { if (_attrList) delete _attrList; }
00480    
00481    char* RelName() {return _relName;}
00482    PxxList* AttrList() {return _attrList;}
00483    PxxList* PrimAttrs() {return _primattrs;}
00484 private:
00485    char*    _relName;   // The relation being created
00486    PxxList* _attrList;  // A list of PxxAttrTypes 
00487    PxxList* _primattrs;  // A list of PxxAttrNames denoting the primary 
00488    // attributes in the relation. If the primary key 
00489    // is a single attrubute than this list only has 
00490    // one element (for now assume only single attribute
00491    // primary keys)
00492 };
00493 
00494 inline void PxxCreate::Write (ostream& os) const
00495 {
00496    os << "Create Table: " << _relName << "\t Attrlist "; _attrList->Write(os);
00497    if (_primattrs) 
00498    { 
00499       os << endl << "\tPrim Attrs: "; 
00500       _primattrs->Write(os);
00501    }
00502 }
00503 
00504 //
00505 // Parse node for create index statements
00506 //
00507 class PxxCreateIndex : public PxxPnode
00508 {
00509 public:
00510    
00511    enum IndexType {
00512          Hash,
00513          Btree
00514    };
00515    
00516    PxxCreateIndex(char* rname, char* aname): _type(Hash), 
00517                                              _relName (rname),
00518                                              _attrName(aname) 
00519    {} 
00520    
00521    // Definition of the pure virtual methods
00522    NodeType MyType() const {return PxxPnode::CreateIndex;}
00523    void Write (ostream& os) const 
00524    {
00525       os << "Create Index: " << _relName << ", " << _attrName;
00526    }
00527    // ~PxxCreateIndex() {}
00528 
00529    char* RelName() const { return _relName;}
00530    char* AttrName() const { return _attrName;}
00531 
00532 private:
00533    IndexType _type;  // The type of the index
00534    char* _relName;   // The relation being indexed
00535    char* _attrName;  // The attribute being indexed
00536 };
00537 
00538 //
00539 // Parse node for insert statements
00540 //
00541 class PxxInsert : public PxxPnode
00542 {
00543 public:
00544    
00545    PxxInsert(char* rname, PxxList* optAttrList, PxxList* valueList)
00546    {
00547       _relName = rname;
00548       _extFileName = 0;
00549       _optAttrList = optAttrList;
00550       _valueList = valueList;
00551    }
00552    
00553    PxxInsert(char* rname, PxxList* optAttrList, char* extFileName)
00554    {
00555       _relName = rname;
00556       _extFileName = extFileName;
00557       _optAttrList = optAttrList;
00558       _valueList = 0;
00559    }
00560    
00561    // Definition of the pure virtual methods
00562    NodeType MyType() const {return PxxPnode::Insert;}
00563    void Write (ostream& os) const;
00564    ~PxxInsert();
00565    
00566    char* RelName() {return _relName;}
00567    char* FileName() 
00568    {
00569       if(_extFileName) return _extFileName;
00570       return 0;
00571    }
00572    PxxList* ValList() { return _valueList;}
00573    PxxList* OptList() 
00574    {
00575       if(_optAttrList) return _optAttrList;
00576       return 0;
00577    }
00578    
00579 private:
00580    char* _relName;          // Insert into this relation
00581    char* _extFileName;      // Used only for bulk-inserts 
00582    PxxList* _valueList;     // A list of PxxLiteral 
00583    PxxList* _optAttrList;   // An optional list of PxxAttrName
00584 };
00585 
00586 inline PxxInsert::~PxxInsert()
00587 {
00588    if (_valueList)   delete _valueList;
00589    if (_optAttrList) delete _optAttrList;
00590 }
00591 
00592 inline void PxxInsert::Write (ostream& os) const
00593 {
00594    os << "Insert Command, Table: " << _relName;
00595    if (_optAttrList) 
00596    {
00597       os << endl;
00598       os << "\tAttrList: ";
00599       _optAttrList->Write(os);
00600    }
00601    
00602    if (_valueList) 
00603    {
00604       os << endl;
00605       os << "\tValueList: ";
00606       _valueList->Write(os);
00607    }
00608    
00609    if (_extFileName)  os << endl << "\tBulkload from: " << _extFileName;
00610 }
00611 
00612 
00613 //
00614 // Parse node for drop table command
00615 //
00616 class PxxDrop : public PxxPnode
00617 {
00618 public:
00619    PxxDrop(char* rname) : _relName (rname) {}   
00620    
00621    // Definition of the pure virtual methods
00622    NodeType MyType() const {return PxxPnode::Drop;}
00623    void Write (ostream& os) const {os << "Drop Table: " << _relName;}
00624 
00625    // Return the name of the relation being dropped
00626    char* RelName() {return _relName;}
00627    
00628 private:
00629    char* _relName;  // The relation being deleted
00630 };
00631 
00632 //
00633 // Parse node for drop Index command
00634 //
00635 class PxxDropIndex : public PxxPnode
00636 {
00637 public:
00638    PxxDropIndex(char* rname, char* aname):_relName (rname),_attrName(aname) {} 
00639    
00640    // Definition of the pure virtual methods
00641    NodeType MyType() const {return PxxPnode::DropIndex;}
00642    void Write (ostream& os) const 
00643    {
00644       os << "Drop Index: " << _relName << ", " << _attrName;
00645    }
00646    
00647    char* RelName() const { return _relName;}
00648    char* AttrName() const { return _attrName;}
00649 
00650 private:
00651    char* _relName;   // The relation being deleted
00652    char* _attrName;  // The attribute being indexed
00653 };
00654 
00655 
00656 
00657 class PxxQuery;
00658 
00659 //
00660 // A predicate expression. For now a literal or an attribute
00661 // Note: This class is not a sub-class of PxxNode
00662 //
00663 class PxxPredExpr
00664 {
00665 public:
00666    enum ExprType 
00667    {
00668       Literal,
00669          Attribute,
00670          SubQuery    // Not supported
00671    };
00672    
00673    void Set(PxxPnode* exprVal); 
00674    void Write (ostream& os) const;
00675    ~PxxPredExpr();
00676    PxxLiteral* Lit() {return _val._literal;}
00677    PxxAttrName* AttrName() {return  _val._attr;}
00678    PxxQuery* Sub() {return  _val._subQuery;}
00679    ExprType Type() {return _type;}
00680 private:
00681    ExprType _type;              // The type of the literal
00682    union
00683    {                            // An expression is either 
00684       PxxLiteral*  _literal;    //    a literal
00685       PxxAttrName* _attr;       // or an attribute 
00686       PxxQuery*    _subQuery;   // or a subquery (not yet supported)
00687    } _val;
00688 };
00689 
00690 inline void PxxPredExpr::Write (ostream& os) const 
00691 {
00692    // os << "Expr: Type: " << (unsigned) _type << ", Val: " ;
00693    switch (_type)
00694    {
00695    case Literal:   _val._literal->Write(os); break;
00696    case Attribute: _val._attr->Write(os); break;
00697    default:        assert(!"Invalid PredExpr Type");
00698    }
00699 }
00700 
00701 inline PxxPredExpr::~PxxPredExpr()
00702 {
00703    switch (_type)
00704    {
00705    case Literal:   delete _val._literal; break;
00706    case Attribute: delete _val._attr; break;
00707    default:        assert(!"Invalid PredExpr Type");
00708    }
00709 }
00710 
00711 
00712 //
00713 // Parse node for Predicates
00714 //
00715 class PxxPredicate : public PxxPnode
00716 {
00717 public:
00718    // Legal SQL Comparison operations
00719    
00720    PxxPredicate(Operator op, bool notFlag=false) : _op (op), _not(notFlag) {}   
00721    
00722    // Definition of the pure virtual methods
00723    NodeType MyType() const {return PxxPnode::Predicate;}
00724    void Write (ostream& os) const;
00725    
00726    PxxPredExpr& operator[] (unsigned idx) 
00727    {
00728       assert (idx<2); 
00729       return _expr[idx];
00730    }
00731    
00732    void Set(PxxPnode* lVal, PxxPnode* rVal);
00733    ~PxxPredicate() {}
00734    Operator Oper() {return _op;}
00735    bool Not() {return _not;}
00736    PxxPredExpr* Expr() {return _expr;}
00737    
00738 private:
00739    Operator       _op;      // Predicate operation
00740    bool        _not;     // indicate a negation of _op
00741    PxxPredExpr _expr[2]; // The l and h expression in the predicate 
00742    //  (assume binary ops only)
00743 };
00744 
00745 
00746 inline void PxxPredicate::Write (ostream& os) const 
00747 {
00748    os << "Pred: ["; _expr[0].Write(os);
00749    os << "] [OP: " << _not << " " << (unsigned) _op << "] [";
00750    _expr[1].Write(os); os << "]";
00751 }
00752 
00753 inline void PxxPredicate::Set(PxxPnode* lVal, PxxPnode* rVal)
00754 {
00755    _expr[0].Set(lVal);
00756    _expr[1].Set(rVal);
00757 }
00758 
00759 
00760 //
00761 // Parse node for Predicates
00762 //
00763 class PxxPredTree : public PxxPnode
00764 {
00765 public:
00766    enum PredConnector 
00767    {
00768       AND,
00769          OR, 
00770          NOT   // Not supported.
00771    };
00772    
00773    PxxPredTree(PredConnector con = AND) : _con(con) {}
00774    PxxPredTree* AddPredicate (PredConnector con, PxxPnode* _newPred);
00775    
00776    // Definition of the pure virtual methods
00777    NodeType MyType() const {return PxxPnode::PredTree;}
00778    void Write (ostream& os) const;
00779    ~PxxPredTree() {}
00780    
00781    PredConnector Con() {return _con;}
00782    PxxList*  Preds() {return &_plist;}
00783    
00784 private:
00785    PredConnector _con;   // The predicate connector
00786    
00787    // List of predicates. The elements in this list are either 
00788    // PxxPredicate (for a list of predicates connected by only AND or only OR)
00789    // or PxxPredTeee (for a mix of and/or predicates)
00790    PxxList   _plist;
00791    
00792    static PredConnector Negate(PredConnector con)
00793    {
00794       switch (con)
00795       {
00796       case AND: return OR;
00797       case OR: return AND;
00798       default: assert (!"Not supported");
00799       }
00800       return con;
00801    }
00802 };
00803 
00804 inline PxxPredTree* PxxPredTree::AddPredicate (PredConnector con, PxxPnode* _newPred)
00805 {
00806    if (con == _con)
00807    {
00808       // Simply add to the predicate list
00809       _plist.Add(_newPred);
00810       return this;
00811    }
00812    else if (con == Negate(_con))
00813    {
00814       PxxPredTree* newTree = new PxxPredTree(con);
00815       newTree->_plist.Add(this);
00816       newTree->_plist.Add(_newPred);
00817       return newTree;
00818    }
00819    else assert (!"Predicate not supported");
00820    
00821    return this;
00822 }
00823 
00824 inline void PxxPredTree::Write (ostream& os) const 
00825 {
00826    os << "PredTree, Connector: " << (unsigned) _con;
00827    _plist.Write (os);
00828 }
00829 
00830 
00831 //
00832 // Parse node for a Query
00833 //
00834 class PxxQuery : public PxxPnode
00835 {
00836 public:
00837    PxxQuery (PxxList* proj, PxxList* from)
00838       : _relname(0), _projList(proj), _fromList(from), _preds(0), _group(0), _having(0) {};
00839    
00840    // Add various clauses of an SQL statement
00841    void AddWhere(PxxPredTree* preds);
00842    void AddGroupBy(PxxList* grpBy);
00843    void AddHaving(PxxPredTree* preds); 
00844    void AddInsertInto(char* relname); 
00845    
00846    // Definition of the pure virtual methods
00847    NodeType MyType() const { return PxxPnode::Query;}
00848    void Write (ostream& os) const;
00849    
00850    ~PxxQuery();
00851    
00852    PxxRelName &RelName() { return _relname; }
00853    PxxList* Projs() { return _projList; }
00854    PxxList* Froms() { return _fromList; }
00855    PxxPredTree* Preds() { return _preds; }
00856    PxxList* Groups() { return _group; }
00857    PxxPredTree* Havings() { return _having; }
00858    
00859 protected:
00860    PxxRelName   _relname;  // The relation to insert into. 
00861    PxxList*     _projList; // A list of PxxAttrName and PxxAggrFunc. 
00862    // This list represents the attributes and 
00863    // aggregates specified in the select clause.
00864    PxxList*     _fromList; // A list of PxxRelName, from the from clause
00865    PxxPredTree* _preds;    // A PxxPredTree corresponding to the where clause
00866    PxxList*     _group;    // The list of PxxAttrName in the group by clause
00867    PxxPredTree* _having;   // A PxxPredTree corresponding to the having clause
00868 };
00869 
00870 inline void PxxQuery::AddWhere(PxxPredTree* preds) 
00871 {
00872    _preds = preds;
00873 }
00874 
00875 inline void PxxQuery::AddGroupBy(PxxList* grpBy) 
00876 {
00877    _group = grpBy;
00878 }
00879 
00880 inline void PxxQuery::AddHaving(PxxPredTree* preds) 
00881 {
00882    _having = preds;
00883 }
00884 
00885 inline void PxxQuery::AddInsertInto(char* relname) 
00886 {
00887    _relname.SetRelName(relname);
00888 }
00889 
00890 inline void PxxQuery::Write (ostream& os) const 
00891 {
00892    os << "Query:\tProj: "; _projList->Write(os);
00893    os << endl << "\tFrom: "; _fromList->Write(os);
00894    if (_preds)
00895    {
00896       os << endl << "\tWhere: "; 
00897       _preds->Write(os);
00898    }
00899    if (_group)
00900    {
00901       os << endl << "\tGrpBy: "; 
00902       _group->Write(os);
00903    }
00904    if (_having)
00905    {
00906       os << endl << "\tHaving: "; 
00907       _having->Write(os);
00908    }
00909    
00910    if (_relname.RelName())
00911    {
00912       os << endl << "\tInsert into: " ; 
00913       _relname.Write(os);
00914    }
00915 }
00916 
00917 inline PxxQuery::~PxxQuery()
00918 {
00919    if (_projList)    delete _projList;
00920    if (_fromList)    delete _fromList;
00921    if (_preds)       delete _preds;
00922    if (_group)       delete _group;
00923    if (_having)      delete _having;
00924 }
00925 
00926 class PxxDelete : public PxxQuery
00927 {
00928 public:
00929    PxxDelete(PxxList *from) : PxxQuery (0, from) {};
00930    NodeType MyType() const { return PxxPnode::Delete;}
00931    void Write (ostream& os) const;
00932 };
00933 
00934 inline void PxxDelete::Write (ostream& os) const 
00935 {
00936    os << "Delete:\tFrom: "; _fromList->Write(os);
00937    if (_preds)
00938    {
00939       os << endl << "\tWhere: "; 
00940       _preds->Write(os);
00941    }
00942 }
00943 
00944 
00945 
00946 inline ostream& operator<< (ostream& os, const PxxPnode& n)
00947 {
00948    n.Write(os);
00949    return os;
00950 }
00951 
00952 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends