BadgerDB
|
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