#include <Assertion.h>
Public Member Functions | |
bool | appendChild (Operator *child) |
Add another child to a conjunction-style operator. | |
bool | appendChild (Operator *child) |
Add another child to a conjunction-style operator. | |
const std::vector< Operator * > & | getChildren () const |
Throw exception if Operator is a comparison operator. | |
const std::vector< Operator * > & | getChildren () const |
Throw exception if Operator is a comparison operator. | |
const std::string * | getCompareArgs () const |
Throw exception if Operator is not a comparison operator. | |
const std::string * | getCompareArgs () const |
Throw exception if Operator is not a comparison operator. | |
const FIELDTYPE * | getCompareArgTypes () const |
Get types of comparison args. | |
const FIELDTYPE * | getCompareArgTypes () const |
Throw exception if Operator is not a comparison operator. | |
bool | getOld () const |
True if operator or sub-operator refers to existing row. | |
bool | getOld () const |
True if operator or sub-operator refers to existing row. | |
OPTYPE | getOpType () const |
OPTYPE | getOpType () const |
const std::string & | getTableName () const |
Throw exception if Operaotr is not EXISTS. | |
const std::string & | getTableName () const |
Throw exception if Operator is not EXISTS. | |
bool | getToBe () const |
True if operator or sub-operator refers to future row. | |
bool | getToBe () const |
True if operator or sub-operator refers to future row. | |
bool | isCompareOp () const |
bool | isCompareOp () const |
Operator (Operator *op, Row *toBe) | |
Copy an operator, substituting from toBe row as appropriate. | |
Operator (OPTYPE type, const std::vector< Operator * > &children, bool keepChildren=false) | |
Constructor for OR, AND, NOT. | |
Operator (OPTYPE type, const std::string &tableName, Operator *child=0) | |
Constructor for EXISTS. | |
Operator (OPTYPE type, const std::string &leftArg, const std::string &rightArg, FIELDTYPE leftType, FIELDTYPE rightType) | |
Operator () | |
Operator (Operator *op, Row *toBe) | |
Copy an operator, substituting from toBe row as appropriate. | |
Operator (OPTYPE type, const std::vector< Operator * > &children, bool keepChildren=false) | |
Constructor for OR, AND, NOT. | |
Operator (OPTYPE type, const std::string &tableName, Operator *child=0) | |
Constructor for EXISTS. | |
Operator (OPTYPE type, const std::string &leftArg, const std::string &rightArg, FIELDTYPE leftType, FIELDTYPE rightType) | |
Operator () | |
bool | validCompareOp (Table *table) const |
bool | validCompareOp (Table *table) const |
bool | verify (Row &old, Row &toBe, Table *t) const |
Evaluate operator on argument Rows. | |
bool | verify (Row &old, Row &toBe, Table *t) const |
Evaluate operator on argument Rows. | |
~Operator () | |
~Operator () | |
Private Member Functions | |
bool | compareFloat (const std::string *vals, OPTYPE type) const |
Handling specific to floating point data. | |
bool | compareFloat (const std::string *vals, OPTYPE type) const |
Handling specific to floating point data. | |
bool | compareInt (const std::string *vals, OPTYPE type) const |
Handling specific to integer data. | |
bool | compareInt (const std::string *vals, OPTYPE type) const |
Handling specific to integer data. | |
bool | compareString (const std::string *vals, OPTYPE type) const |
Handling specific to string data. | |
bool | compareString (const std::string *vals, OPTYPE type) const |
Handling specific to string data. | |
bool | compareTs (const std::string *vals, OPTYPE type) const |
Handling specific to timestamp data. | |
bool | compareTs (const std::string *vals, OPTYPE type) const |
Handling specific to timestamp data. | |
bool | verifyCompare (Row &old, Row &toBe, Table *t) const |
Handling specific to 2-arg compare operators. | |
bool | verifyCompare (Row &old, Row &toBe, Table *t) const |
Handling specific to 2-arg compare operators. | |
Private Attributes | |
std::string | m_compareArgs [2] |
FIELDTYPE | m_compareType [2] |
bool | m_keepChildren |
bool | m_old |
std::vector< Operator * > | m_operands |
Following is used only for non-compare operators. | |
std::vector< Operator * > | m_operands |
Following is used only for non-compare operators. | |
OPTYPE | m_opType |
std::string | m_tableName |
Following used only for EXISTS. | |
bool | m_toBe |
|
00073 : m_opType(OPTYPEundefined) {};
|
|
00012 { 00013 if (!m_keepChildren) { 00014 while (m_operands.size() ) { 00015 Operator* op = m_operands.back(); 00016 m_operands.pop_back(); 00017 delete op; 00018 } 00019 } 00020 }
|
|
Constructor for comparison. If the operator is OPTTYPEisNull or OPTYPEisEmpty rightArg and rightLiteral are ignored. 00043 : m_opType(type), m_keepChildren(false), m_toBe(false), m_old(false) { 00044 00045 m_tableName.clear(); 00046 m_operands.clear(); 00047 if (!isCompareOp()) { 00048 m_opType = OPTYPEundefined; 00049 return; 00050 } 00051 00052 m_compareArgs[0] = leftArg; 00053 m_compareArgs[1] = rightArg; 00054 m_compareType[0] = leftLiteral; 00055 m_compareType[1] = rightLiteral; 00056 if ((type == OPTYPEisNull) || (type ==OPTYPEisEmpty)) { 00057 m_compareType[1] = FIELDTYPElit; 00058 m_compareArgs[1] = ""; 00059 } 00060 m_toBe = ((leftLiteral == FIELDTYPEtoBe) || 00061 (rightLiteral == FIELDTYPEtoBe)); 00062 m_old = ((leftLiteral == FIELDTYPEold) || 00063 (rightLiteral == FIELDTYPEold)); 00064 }
|
|
Constructor for EXISTS.
00068 : m_opType(type), 00069 m_tableName(tableName), 00070 m_keepChildren(false) 00071 { 00072 if (type != OPTYPEexists) { 00073 m_opType = OPTYPEundefined; 00074 return; 00075 } 00076 m_operands.clear(); 00077 m_operands.push_back(child); 00078 }
|
|
Constructor for OR, AND, NOT.
00083 : 00084 m_opType(type), m_keepChildren(keepChildren) { 00085 00086 m_toBe = false; 00087 m_old = false; 00088 if ((type == OPTYPEor) || (type == OPTYPEand) || (type = OPTYPEnot)) { 00089 m_tableName.clear(); 00090 unsigned int nChild = children.size(); 00091 if (!nChild) { 00092 m_opType = OPTYPEundefined; 00093 return; 00094 } 00095 for (unsigned int iChild = 0; iChild < nChild; iChild++) { 00096 m_toBe |= (children[iChild]->m_toBe); 00097 m_old |= (children[iChild]->m_old); 00098 m_operands.push_back(children[iChild]); 00099 } 00100 } 00101 else m_opType = OPTYPEundefined; 00102 }
|
|
Copy an operator, substituting from toBe row as appropriate.
00107 : m_opType(op->m_opType), m_tableName(op->m_tableName), 00108 m_keepChildren(false), m_toBe(false), m_old(op->m_old) { 00109 m_operands.clear(); 00110 00111 switch (m_opType) { 00112 // OPTYPEor, and, not and exists all have child operators 00113 case OPTYPEor: 00114 case OPTYPEand: 00115 case OPTYPEnot: 00116 case OPTYPEexists: 00117 { 00118 unsigned nChild = op->m_operands.size(); 00119 for (unsigned iChild = 0; iChild < nChild; iChild++) { 00120 Operator* child = new Operator((op->m_operands)[iChild], toBe); 00121 appendChild(child); 00122 } 00123 break; 00124 } 00125 case OPTYPEequal: 00126 case OPTYPEnotEqual: 00127 case OPTYPElessThan: 00128 case OPTYPEgreaterThan: 00129 case OPTYPElessOrEqual: 00130 case OPTYPEgreaterOrEqual: 00131 case OPTYPEisEmpty: 00132 case OPTYPEisNull: { 00133 for (unsigned i = 0; i < 2; i++) { 00134 if ((op->m_compareType[i] == FIELDTYPEtoBe) || 00135 (op->m_compareType[i] == FIELDTYPEtoBeDef) ) { 00136 // have to supply value from row 00137 FieldVal* f = toBe->find(op->m_compareArgs[i]); 00138 if (!f) { 00139 throw RdbException 00140 ("Assertion::Operator constructor can't resolve field"); 00141 } 00142 m_compareArgs[i] = f->m_val; 00143 m_compareType[i] = FIELDTYPElit; 00144 } 00145 else { // just copy what's there 00146 m_compareArgs[i] = op->m_compareArgs[i]; 00147 m_compareType[i] =op->m_compareType[i]; 00148 } 00149 } 00150 break; 00151 } 00152 default: 00153 throw RdbException("Assertion::Operator constructor - Unknown OP type"); 00154 } 00155 }
|
|
00073 : m_opType(OPTYPEundefined) {};
|
|
|
|
Constructor for comparison. If the operator is OPTTYPEisNull or OPTYPEisEmpty rightArg and rightLiteral are ignored. |
|
Constructor for EXISTS.
|
|
Constructor for OR, AND, NOT.
|
|
Copy an operator, substituting from toBe row as appropriate.
|
|
Add another child to a conjunction-style operator.
|
|
Add another child to a conjunction-style operator.
00158 { 00159 m_toBe |= child->m_toBe; 00160 m_old |= child->m_old; 00161 if ((m_opType == OPTYPEor) || (m_opType == OPTYPEand) ) { 00162 m_operands.push_back(child); 00163 return true; 00164 } 00165 else if ((m_opType == OPTYPEnot) && (m_operands.size() == 0) ) { 00166 m_operands.push_back(child); 00167 return true; 00168 } 00169 throw RdbException("Assertion::Operator::appendChild: wrong parent operator type"); 00170 return false; 00171 }
|
|
Handling specific to floating point data.
|
|
Handling specific to floating point data.
00412 { 00413 using facilities::Util; 00414 double left, right; 00415 try { 00416 left = Util::stringToDouble(*vals); 00417 right = Util::stringToDouble(*(vals + 1)); 00418 } 00419 catch (facilities::WrongType ex) { 00420 throw 00421 RdbException("Assertion::Operator::compareFloat illegal input"); 00422 } 00423 switch (type) { 00424 case OPTYPEequal: 00425 return left == right; 00426 case OPTYPEnotEqual: 00427 return left != right; 00428 case OPTYPElessThan: 00429 return left < right; 00430 case OPTYPEgreaterThan: 00431 return left > right; 00432 case OPTYPElessOrEqual: 00433 return left <= right; 00434 case OPTYPEgreaterOrEqual: 00435 return right >= right; 00436 default: 00437 throw RdbException("Assertion::Operator::compareFloat bad OPTYPE"); 00438 } 00439 return false; 00440 }
|
|
Handling specific to integer data.
|
|
Handling specific to integer data.
00396 { 00397 using facilities::Util; 00398 00399 try { 00400 int i= Util::stringToInt(*vals); 00401 i = Util::stringToInt(*(vals + 1)); 00402 } 00403 catch (facilities::WrongType ex) { 00404 throw 00405 RdbException("Assertion::Operator::compareInt illegal input"); 00406 } 00407 return compareFloat(vals, type); 00408 }
|
|
Handling specific to string data.
|
|
Handling specific to string data. Handling specific to string data. Only supported operators for strings are == and != 00445 { 00446 switch (type) { 00447 case OPTYPEequal: 00448 return ( (*vals).compare(*(vals+1)) == 0 ); 00449 case OPTYPEnotEqual: 00450 return ( (*vals).compare(*(vals+1)) != 0 ); 00451 default: 00452 throw 00453 RdbException("Assertion::Operator::compareString Unsupported OPTYPE"); 00454 } 00455 return false; 00456 }
|
|
Handling specific to timestamp data.
|
|
Handling specific to timestamp data.
00362 { 00363 using facilities::Timestamp; 00364 Timestamp left, right; 00365 try { 00366 left = Timestamp(*vals); 00367 right = Timestamp(*(vals + 1)); 00368 } 00369 catch(facilities::BadTimeInput ex) { 00370 throw 00371 RdbException("Assertion::Operator::CompareTs illegal input"); 00372 } 00373 00374 switch (type) { 00375 case OPTYPEequal: 00376 return left == right; 00377 case OPTYPEnotEqual: 00378 return left != right; 00379 case OPTYPElessThan: 00380 return left < right; 00381 case OPTYPEgreaterThan: 00382 return left > right; 00383 case OPTYPElessOrEqual: 00384 return left <= right; 00385 case OPTYPEgreaterOrEqual: 00386 return right >= right; 00387 default: 00388 throw RdbException("Assertion::Operator::compareTs bad OPTYPE"); 00389 } 00390 return false; 00391 00392 00393 }
|
|
Throw exception if Operator is a comparison operator.
|
|
Throw exception if Operator is a comparison operator.
00338 { 00339 if (isCompareOp()) 00340 throw RdbException("Assertion::Operator::getChildren: wrong type"); 00341 return m_operands; 00342 }
|
|
Throw exception if Operator is not a comparison operator.
|
|
Throw exception if Operator is not a comparison operator.
00193 { 00194 if (!isCompareOp()) 00195 throw RdbException("Assertion::Operator::getCompareArgs: wrong type"); 00196 return &m_compareArgs[0]; 00197 }
|
|
Get types of comparison args.
|
|
Throw exception if Operator is not a comparison operator.
00201 { 00202 if (!isCompareOp()) 00203 throw RdbException("Assertion::Operator::getLiteralness: wrong type"); 00204 return &m_compareType[0]; 00205 }
|
|
True if operator or sub-operator refers to existing row.
00121 {return m_old;}
|
|
True if operator or sub-operator refers to existing row.
00121 {return m_old;}
|
|
00115 {return m_opType;}
|
|
00115 {return m_opType;}
|
|
Throw exception if Operaotr is not EXISTS.
|
|
Throw exception if Operator is not EXISTS.
00208 { 00209 if (m_opType != OPTYPEexists) 00210 throw RdbException("Assertion::Operator::getTableName: wrong type"); 00211 return m_tableName; 00212 }
|
|
True if operator or sub-operator refers to future row.
00118 {return m_toBe;}
|
|
True if operator or sub-operator refers to future row.
00118 {return m_toBe;}
|
|
True if operator is isNull, isEmpty or any of the usual arithmetic comparisons 00101 {return (m_opType >= OPTYPEisNull);}
|
|
True if operator is isNull, isEmpty or any of the usual arithmetic comparisons 00101 {return (m_opType >= OPTYPEisNull);}
|
|
Check whether columns or column and literal to be compared have compatible types |
|
Check whether columns or column and literal to be compared have compatible types 00174 { 00175 if (m_compareType[0] != FIELDTYPElit) { 00176 Column* col0 = myTable->getColumnByName(m_compareArgs[0]); 00177 if (m_compareType[1] != FIELDTYPElit) { 00178 Column* col1 = myTable->getColumnByName(m_compareArgs[1]); 00179 return col1->isCompatible(col0); 00180 } 00181 else { // one column, one literal 00182 return col0->okValue(m_compareArgs[1], false); 00183 } 00184 } 00185 else { // 1st arg is a literal; second arg must be column 00186 Column* col1 = myTable->getColumnByName(m_compareArgs[1]); 00187 return col1->okValue(m_compareArgs[0], false); 00188 } 00189 }
|
|
Evaluate operator on argument Rows.
|
|
Evaluate operator on argument Rows.
00215 { 00216 switch(m_opType) { 00217 case OPTYPEor: { 00218 unsigned nChild = m_operands.size(); 00219 for (unsigned i = 0; i < nChild; i++) { 00220 if (m_operands[i]->verify(old, toBe, t)) return true; 00221 } 00222 return false; 00223 } 00224 00225 case OPTYPEand: { 00226 unsigned nChild = m_operands.size(); 00227 for (unsigned i = 0; i < nChild; i++) { 00228 if (!(m_operands[i]->verify(old, toBe, t))) return false; 00229 } 00230 return true; 00231 } 00232 case OPTYPEnot: 00233 return (!(m_operands[0]->verify(old, toBe, t))); 00234 00235 00236 case OPTYPEisNull: 00237 case OPTYPEisEmpty: 00238 // These two are almost the same 00239 { 00240 Row* r = 0; 00241 if ( (m_compareType[0] == FIELDTYPEtoBe) || 00242 (m_compareType[0] == FIELDTYPEtoBeDef) ) r = &toBe; 00243 else r = &old; 00244 00245 FieldVal* f = r->find(m_compareArgs[0]); 00246 if (f) { 00247 if (m_opType == OPTYPEisNull) return f->m_null; 00248 return ((f->m_val).size() == 0); 00249 } 00250 else { // improper input. Field should have been found 00251 throw RdbException("Assertion::Operator::verify missing isNull field"); 00252 } 00253 } 00254 // handle all 2-argument compare operators together 00255 case OPTYPEequal: 00256 case OPTYPEnotEqual: 00257 case OPTYPElessThan: 00258 case OPTYPEgreaterThan: 00259 case OPTYPElessOrEqual: 00260 case OPTYPEgreaterOrEqual: 00261 return verifyCompare(old, toBe, t); 00262 00263 default: 00264 return false; 00265 } 00266 return false; 00267 }
|
|
Handling specific to 2-arg compare operators.
|
|
Handling specific to 2-arg compare operators.
00270 { 00271 // Assume we already know the comparison is sensible; that is, that 00272 // the two args are of compatible types. This check should be 00273 // done when the operator is constructed (by XercesBuilder) 00274 std::string values[2]; 00275 std::string colname; 00276 colname.clear(); // used to determine type (string, int,..) of compare 00277 00278 for (unsigned i = 0; i < 2; i++) { 00279 switch (m_compareType[i]) { 00280 case FIELDTYPElit: 00281 case FIELDTYPElitDef: 00282 values[i] = m_compareArgs[i]; 00283 break; 00284 case FIELDTYPEold: 00285 case FIELDTYPEoldDef: { 00286 FieldVal* f = old.find(m_compareArgs[i]); 00287 if (!f) { 00288 std::string msg = 00289 std::string("Assertion::Operator::verifyCompare missing field ") 00290 + m_compareArgs[i]; 00291 throw 00292 RdbException(msg); 00293 } 00294 values[i] = f->m_val; 00295 colname = f->m_colname; 00296 break; 00297 } 00298 case FIELDTYPEtoBe: 00299 case FIELDTYPEtoBeDef: { 00300 FieldVal* f = toBe.find(m_compareArgs[i]); 00301 if (!f) { 00302 throw 00303 RdbException("Assertion::Operator::verifyCompare missing field"); 00304 } 00305 values[i] = f->m_val; 00306 colname = f->m_colname; 00307 break; 00308 } 00309 default: 00310 throw 00311 RdbException("Assertion::Operator::verifyCompare bad arg type"); 00312 } 00313 } 00314 if (colname.size() > 0) {// determine type to convert to 00315 Column* c = t->getColumnByName(colname); 00316 Datatype* d = c->getDatatype(); 00317 00318 switch (d->getType()) { 00319 case Datatype::TYPEtimestamp: 00320 case Datatype::TYPEdatetime: 00321 return compareTs(&values[0], m_opType); 00322 case Datatype::TYPEint: 00323 case Datatype::TYPEmediumint: 00324 case Datatype::TYPEsmallint: 00325 return compareInt(&values[0], m_opType); 00326 case Datatype::TYPEreal: 00327 case Datatype::TYPEdouble: 00328 return compareFloat(&values[0], m_opType); 00329 default: // do nothing 00330 ; 00331 } 00332 } 00333 // Otherwise they're strings. 00334 return compareString(&values[0], m_opType); 00335 }
|
|
Following two lines apply only to compare operators (includes isNull, isEmpty) In order to format properly in an SQL query, need to keep track of whether compare arg is literal, column name referring to current row under consideration, or column name referring to proposed row (in case this is part of an assertion about relation of existing rows to proposed row) |
|
|
|
|
|
Following is true if this operator or suboperator has an arg. column name referring to a row already in the table |
|
Following is used only for non-compare operators.
|
|
Following is used only for non-compare operators.
|
|
|
|
Following used only for EXISTS.
|
|
Following is true if this operator or suboperator has an arg. column name referring to a "toBe" row |