File indexing completed on 2025-02-09 05:27:26
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003-2015 Jarosław Staniek <staniek@kde.org> 0003 Copyright (C) 2014 Radoslaw Wicik <radoslaw@wicik.pl> 0004 0005 Based on nexp.cpp : Parser module of Python-like language 0006 (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl) 0007 0008 This library is free software; you can redistribute it and/or 0009 modify it under the terms of the GNU Library General Public 0010 License as published by the Free Software Foundation; either 0011 version 2 of the License, or (at your option) any later version. 0012 0013 This library is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 Library General Public License for more details. 0017 0018 You should have received a copy of the GNU Library General Public License 0019 along with this library; see the file COPYING.LIB. If not, write to 0020 * Boston, MA 02110-1301, USA. 0021 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0022 */ 0023 0024 #include "KDbExpression.h" 0025 #include "KDb.h" 0026 #include "KDbDriver.h" 0027 #include "KDbQuerySchema.h" 0028 #include "KDbParser_p.h" 0029 #include "kdb_debug.h" 0030 #include "generated/sqlparser.h" 0031 0032 #include <vector> 0033 0034 //! @internal A cache 0035 class KDbExpressionClassNames 0036 { 0037 public: 0038 KDbExpressionClassNames() 0039 : names({ 0040 QLatin1String("Unknown"), 0041 QLatin1String("Unary"), 0042 QLatin1String("Arithm"), 0043 QLatin1String("Logical"), 0044 QLatin1String("Relational"), 0045 QLatin1String("SpecialBinary"), 0046 QLatin1String("Const"), 0047 QLatin1String("Variable"), 0048 QLatin1String("Function"), 0049 QLatin1String("Aggregation"), 0050 QLatin1String("FieldList"), 0051 QLatin1String("TableList"), 0052 QLatin1String("ArgumentList"), 0053 QLatin1String("QueryParameter")}) 0054 { 0055 } 0056 const std::vector<QString> names; 0057 }; 0058 0059 Q_GLOBAL_STATIC(KDbExpressionClassNames, KDb_expressionClassNames) 0060 0061 KDB_EXPORT QString expressionClassName(KDb::ExpressionClass c) 0062 { 0063 Q_ASSERT(size_t(c) < KDb_expressionClassNames->names.size()); 0064 return KDb_expressionClassNames->names[c]; 0065 } 0066 0067 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbExpression& expr) 0068 { 0069 KDb::ExpressionCallStack callStack; 0070 return expr.debug(dbg.nospace(), &callStack); 0071 } 0072 0073 //========================================= 0074 0075 KDbExpressionData::KDbExpressionData() 0076 : expressionClass(KDb::UnknownExpression) 0077 { 0078 //ExpressionDebug << "KDbExpressionData" << ref; 0079 } 0080 0081 /*Data(const Data& other) 0082 : QSharedData(other) 0083 , token(other.token) 0084 , expressionClass(other.expressionClass) 0085 , parent(other.parent) 0086 , children(other.children) 0087 { 0088 ExpressionDebug << "KDbExpressionData" << ref; 0089 }*/ 0090 0091 KDbExpressionData::~KDbExpressionData() 0092 { 0093 //ExpressionDebug << "~KDbExpressionData" << ref; 0094 } 0095 0096 KDbExpressionData* KDbExpressionData::clone() 0097 { 0098 ExpressionDebug << "KDbExpressionData::clone" << *this; 0099 return new KDbExpressionData(*this); 0100 } 0101 0102 KDbField::Type KDbExpressionData::typeInternal(KDb::ExpressionCallStack* callStack) const 0103 { 0104 Q_UNUSED(callStack); 0105 return KDbField::InvalidType; 0106 } 0107 0108 KDbField::Type KDbExpressionData::type(KDb::ExpressionCallStack* callStack) const 0109 { 0110 if (!addToCallStack(nullptr, callStack)) { 0111 return KDbField::InvalidType; 0112 } 0113 const KDbField::Type t = typeInternal(callStack); 0114 callStack->removeLast(); 0115 return t; 0116 } 0117 0118 KDbField::Type KDbExpressionData::type() const 0119 { 0120 KDb::ExpressionCallStack callStack; 0121 return type(&callStack); 0122 } 0123 0124 bool KDbExpressionData::isValid() const 0125 { 0126 return type() != KDbField::InvalidType; 0127 } 0128 0129 bool KDbExpressionData::isTextType() const 0130 { 0131 return KDbField::isTextType(type()); 0132 } 0133 0134 bool KDbExpressionData::isIntegerType() const 0135 { 0136 return KDbField::isIntegerType(type()); 0137 } 0138 0139 bool KDbExpressionData::isNumericType() const 0140 { 0141 return KDbField::isNumericType(type()); 0142 } 0143 0144 bool KDbExpressionData::isFPNumericType() const 0145 { 0146 return KDbField::isFPNumericType(type()); 0147 } 0148 0149 bool KDbExpressionData::isDateTimeType() const 0150 { 0151 return KDbField::isDateTimeType(type()); 0152 } 0153 0154 bool KDbExpressionData::validate(KDbParseInfo *parseInfo) 0155 { 0156 KDb::ExpressionCallStack callStack; 0157 return validate(parseInfo, &callStack); 0158 } 0159 0160 bool KDbExpressionData::validate(KDbParseInfo *parseInfo, KDb::ExpressionCallStack* callStack) 0161 { 0162 if (!addToCallStack(nullptr, callStack)) { 0163 return false; 0164 } 0165 bool result = validateInternal(parseInfo, callStack); 0166 callStack->removeLast(); 0167 return result; 0168 } 0169 0170 bool KDbExpressionData::validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack* callStack) 0171 { 0172 Q_UNUSED(parseInfo); 0173 Q_UNUSED(callStack); 0174 return true; 0175 } 0176 0177 KDbEscapedString KDbExpressionData::toString( 0178 const KDbDriver *driver, 0179 KDbQuerySchemaParameterValueListIterator* params, 0180 KDb::ExpressionCallStack* callStack) const 0181 { 0182 const bool owned = !callStack; 0183 if (owned) { 0184 callStack = new KDb::ExpressionCallStack(); 0185 } 0186 if (!addToCallStack(nullptr, callStack)) { 0187 if (owned) { 0188 delete callStack; 0189 } 0190 return KDbEscapedString("<CYCLE!>"); 0191 } 0192 KDbEscapedString s = toStringInternal(driver, params, callStack); 0193 callStack->removeLast(); 0194 if (owned) { 0195 delete callStack; 0196 } 0197 return s; 0198 } 0199 0200 KDbEscapedString KDbExpressionData::toStringInternal( 0201 const KDbDriver *driver, 0202 KDbQuerySchemaParameterValueListIterator* params, 0203 KDb::ExpressionCallStack* callStack) const 0204 { 0205 Q_UNUSED(driver); 0206 Q_UNUSED(params); 0207 Q_UNUSED(callStack); 0208 return KDbEscapedString("<UNKNOWN!>"); 0209 } 0210 0211 void KDbExpressionData::getQueryParameters(QList<KDbQuerySchemaParameter>* params) 0212 { 0213 Q_UNUSED(params); 0214 } 0215 0216 bool KDbExpressionData::addToCallStack(QDebug *dbg, KDb::ExpressionCallStack* callStack) const 0217 { 0218 if (callStack->contains(this)) { 0219 if (dbg) 0220 dbg->nospace() << "<CYCLE!>"; 0221 QString warning; 0222 QDebug debug(&warning); 0223 debug.nospace() << "Cycle detected in expression (depth " << callStack->length() << "):"; 0224 int level = 0; 0225 for (const KDbExpressionData *data : qAsConst(*callStack)) { 0226 debug.nospace() << endl << level + 1 << ":"; 0227 debug.space().noquote() << expressionClassName(data->expressionClass); 0228 debug.nospace() << data->token; 0229 ++level; 0230 } 0231 kdbWarning().noquote() << warning; 0232 return false; 0233 } 0234 callStack->append(this); 0235 return true; 0236 } 0237 0238 QDebug KDbExpressionData::debug(QDebug dbg, KDb::ExpressionCallStack* callStack) const 0239 { 0240 if (!addToCallStack(&dbg, callStack)) { 0241 return dbg.nospace(); 0242 } 0243 debugInternal(dbg, callStack); 0244 callStack->removeLast(); 0245 return dbg; 0246 } 0247 0248 QDebug operator<<(QDebug dbg, const KDbExpressionData& expr) 0249 { 0250 KDb::ExpressionCallStack callStack; 0251 return expr.debug(dbg.nospace(), &callStack); 0252 } 0253 0254 void KDbExpressionData::debugInternal(QDebug dbg, KDb::ExpressionCallStack* callStack) const 0255 { 0256 Q_UNUSED(callStack); 0257 dbg.nospace() << QString::fromLatin1("Exp(%1,type=%2)") 0258 .arg(token.value()).arg(KDbDriver::defaultSqlTypeName(type())); 0259 } 0260 0261 //========================================= 0262 0263 KDbExpression::KDbExpression() 0264 : d(new KDbExpressionData) 0265 { 0266 ExpressionDebug << "KDbExpression ctor ()" << *this << d->ref; 0267 } 0268 0269 KDbExpression::KDbExpression(KDbExpressionData* data, KDb::ExpressionClass aClass, KDbToken token) 0270 : d(data) 0271 { 0272 d->expressionClass = aClass; 0273 d->token = token; 0274 } 0275 0276 KDbExpression::KDbExpression(KDbExpressionData* data) 0277 : d(data) 0278 { 0279 ExpressionDebug << "KDbExpression ctor (KDbExpressionData*)" << *this; 0280 } 0281 0282 KDbExpression::KDbExpression(const ExplicitlySharedExpressionDataPointer &ptr) 0283 : d(ptr ? ptr : ExplicitlySharedExpressionDataPointer(new KDbExpressionData)) 0284 { 0285 } 0286 0287 KDbExpression::~KDbExpression() 0288 { 0289 //kdbDebug() << *this << d->ref; 0290 if (d->parent && d->ref == 1) { 0291 d->parent->children.removeOne(d); 0292 } 0293 } 0294 0295 bool KDbExpression::isNull() const 0296 { 0297 return d->expressionClass == KDb::UnknownExpression; 0298 } 0299 0300 KDbExpression KDbExpression::clone() const 0301 { 0302 return KDbExpression(d->clone()); 0303 } 0304 0305 KDbToken KDbExpression::token() const 0306 { 0307 return d->token; 0308 } 0309 0310 void KDbExpression::setToken(KDbToken token) 0311 { 0312 d->token = token; 0313 } 0314 0315 KDb::ExpressionClass KDbExpression::expressionClass() const 0316 { 0317 return d->expressionClass; 0318 } 0319 0320 void KDbExpression::setExpressionClass(KDb::ExpressionClass aClass) 0321 { 0322 d->expressionClass = aClass; 0323 } 0324 0325 bool KDbExpression::validate(KDbParseInfo *parseInfo) 0326 { 0327 return d->validate(parseInfo); 0328 } 0329 0330 KDbField::Type KDbExpression::type() const 0331 { 0332 return d->type(); 0333 } 0334 0335 bool KDbExpression::isValid() const 0336 { 0337 return d->isValid(); 0338 } 0339 0340 bool KDbExpression::isTextType() const 0341 { 0342 return d->isTextType(); 0343 } 0344 0345 bool KDbExpression::isIntegerType() const 0346 { 0347 return d->isIntegerType(); 0348 } 0349 0350 bool KDbExpression::isNumericType() const 0351 { 0352 return d->isNumericType(); 0353 } 0354 0355 bool KDbExpression::isFPNumericType() const 0356 { 0357 return d->isFPNumericType(); 0358 } 0359 0360 bool KDbExpression::isDateTimeType() const 0361 { 0362 return d->isDateTimeType(); 0363 } 0364 0365 KDbExpression KDbExpression::parent() const 0366 { 0367 return d->parent.data() ? KDbExpression(d->parent) : KDbExpression(); 0368 } 0369 0370 QList<ExplicitlySharedExpressionDataPointer> KDbExpression::children() const 0371 { 0372 return d->children; 0373 } 0374 0375 void KDbExpression::appendChild(const KDbExpression& child) 0376 { 0377 appendChild(child.d); 0378 } 0379 0380 void KDbExpression::prependChild(const KDbExpression& child) 0381 { 0382 if (!checkBeforeInsert(child.d)) 0383 return; 0384 d->children.prepend(child.d); 0385 child.d->parent = d; 0386 } 0387 0388 void KDbExpression::insertChild(int i, const KDbExpression& child) 0389 { 0390 if (!checkBeforeInsert(child.d)) 0391 return; 0392 if (i < 0 || i > d->children.count()) 0393 return; 0394 d->children.insert(i, child.d); 0395 child.d->parent = d; 0396 } 0397 0398 void KDbExpression::insertEmptyChild(int i) 0399 { 0400 if (i < 0 || i > d->children.count()) 0401 return; 0402 KDbExpression child; 0403 d->children.insert(i, child.d); 0404 child.d->parent = d; 0405 } 0406 0407 bool KDbExpression::removeChild(const KDbExpression& child) 0408 { 0409 if (isNull() || child.isNull()) 0410 return false; 0411 child.d->parent.reset(); // no longer parent 0412 return d->children.removeOne(child.d); 0413 } 0414 0415 void KDbExpression::removeChild(int i) 0416 { 0417 if (isNull()) 0418 return; 0419 if (i < 0 || i >= d->children.count()) 0420 return; 0421 //kdbDebug() << d->children.count() << d->children.at(i); 0422 d->children.removeAt(i); 0423 } 0424 0425 KDbExpression KDbExpression::takeChild(int i) 0426 { 0427 if (isNull()) 0428 return KDbExpression(); 0429 if (i < 0 || i >= d->children.count()) 0430 return KDbExpression(); 0431 ExplicitlySharedExpressionDataPointer child = d->children.takeAt(i); 0432 if (!child) 0433 return KDbExpression(); 0434 child->parent.reset(); 0435 return KDbExpression(child); 0436 } 0437 0438 int KDbExpression::indexOfChild(const KDbExpression& child, int from) const 0439 { 0440 return d->children.indexOf(child.d, from); 0441 } 0442 0443 int KDbExpression::lastIndexOfChild(const KDbExpression& child, int from) const 0444 { 0445 return d->children.lastIndexOf(child.d, from); 0446 } 0447 0448 bool KDbExpression::checkBeforeInsert(const ExplicitlySharedExpressionDataPointer& child) 0449 { 0450 if (!child) 0451 return false; 0452 if (d == child) // expression cannot be own child 0453 return false; 0454 if (child->parent == d) // cannot insert child twice 0455 return false; 0456 if (child->parent) // remove from old parent 0457 child->parent->children.removeOne(child); 0458 return true; 0459 } 0460 0461 void KDbExpression::appendChild(const ExplicitlySharedExpressionDataPointer& child) 0462 { 0463 if (!checkBeforeInsert(child)) 0464 return; 0465 d->children.append(child); 0466 child->parent = d; 0467 } 0468 0469 KDbEscapedString KDbExpression::toString(const KDbDriver *driver, 0470 KDbQuerySchemaParameterValueListIterator* params, 0471 KDb::ExpressionCallStack* callStack) const 0472 { 0473 if (isNull()) 0474 return KDbEscapedString("<UNKNOWN!>"); 0475 return d->toString(driver, params, callStack); 0476 } 0477 0478 void KDbExpression::getQueryParameters(QList<KDbQuerySchemaParameter>* params) 0479 { 0480 Q_ASSERT(params); 0481 d->getQueryParameters(params); 0482 } 0483 0484 QDebug KDbExpression::debug(QDebug dbg, KDb::ExpressionCallStack* callStack) const 0485 { 0486 if (d) 0487 d->debug(dbg, callStack); 0488 return dbg.space(); 0489 } 0490 0491 bool KDbExpression::operator==(const KDbExpression& e) const 0492 { 0493 return d == e.d; 0494 } 0495 0496 bool KDbExpression::operator!=(const KDbExpression& e) const 0497 { 0498 return !operator==(e); 0499 } 0500 0501 bool KDbExpression::isNArg() const 0502 { 0503 return d->convertConst<KDbNArgExpressionData>(); 0504 } 0505 0506 bool KDbExpression::isUnary() const 0507 { 0508 return d->convertConst<KDbUnaryExpressionData>(); 0509 } 0510 0511 bool KDbExpression::isBinary() const 0512 { 0513 return d->convertConst<KDbBinaryExpressionData>(); 0514 } 0515 0516 bool KDbExpression::isConst() const 0517 { 0518 return d->convertConst<KDbConstExpressionData>(); 0519 } 0520 0521 bool KDbExpression::isVariable() const 0522 { 0523 return d->convertConst<KDbVariableExpressionData>(); 0524 } 0525 0526 bool KDbExpression::isFunction() const 0527 { 0528 return d->convertConst<KDbFunctionExpressionData>(); 0529 } 0530 0531 bool KDbExpression::isQueryParameter() const 0532 { 0533 return d->convertConst<KDbQueryParameterExpressionData>(); 0534 } 0535 0536 #define CAST(T) \ 0537 d->convert<T ## Data>() ? T(d) : T() 0538 0539 KDbNArgExpression KDbExpression::toNArg() const 0540 { 0541 return CAST(KDbNArgExpression); 0542 } 0543 0544 KDbUnaryExpression KDbExpression::toUnary() const 0545 { 0546 return CAST(KDbUnaryExpression); 0547 } 0548 0549 KDbBinaryExpression KDbExpression::toBinary() const 0550 { 0551 return CAST(KDbBinaryExpression); 0552 } 0553 0554 KDbConstExpression KDbExpression::toConst() const 0555 { 0556 return CAST(KDbConstExpression); 0557 } 0558 0559 KDbQueryParameterExpression KDbExpression::toQueryParameter() const 0560 { 0561 return CAST(KDbQueryParameterExpression); 0562 } 0563 0564 KDbVariableExpression KDbExpression::toVariable() const 0565 { 0566 return CAST(KDbVariableExpression); 0567 } 0568 0569 KDbFunctionExpression KDbExpression::toFunction() const 0570 { 0571 return CAST(KDbFunctionExpression); 0572 } 0573 0574 void KDbExpression::setLeftOrRight(const KDbExpression& e, int index) 0575 { 0576 if (this == &e) { 0577 kdbWarning() << "Expression" << *this << "cannot be set as own child"; 0578 return; 0579 } 0580 if (d->children.indexOf(e.d) == index) { // cannot set twice 0581 return; 0582 } 0583 if (d->children[index == 0 ? 1 : 0] == e.d) { // this arg was at right, remove 0584 d->children[index] = e.d; 0585 d->children[index == 0 ? 1 : 0] = new KDbExpressionData; 0586 } 0587 else { 0588 if (e.d->parent) { // remove from old parent 0589 e.d->parent->children.removeOne(e.d); 0590 } 0591 d->children[index] = e.d; 0592 } 0593 } 0594 0595 // static 0596 KDb::ExpressionClass KDbExpression::classForToken(KDbToken token) 0597 { 0598 switch (token.value()) { 0599 case '+': 0600 case '-': 0601 case '*': 0602 case '/': 0603 case '&': 0604 case '|': 0605 case '%': 0606 case BITWISE_SHIFT_RIGHT: 0607 case BITWISE_SHIFT_LEFT: 0608 case CONCATENATION: 0609 return KDb::ArithmeticExpression; 0610 case '=': 0611 case '<': 0612 case '>': 0613 case NOT_EQUAL: 0614 case NOT_EQUAL2: 0615 case LESS_OR_EQUAL: 0616 case GREATER_OR_EQUAL: 0617 case LIKE: 0618 case NOT_LIKE: 0619 case SQL_IN: 0620 case SIMILAR_TO: 0621 case NOT_SIMILAR_TO: 0622 return KDb::RelationalExpression; 0623 case OR: 0624 case AND: 0625 case XOR: 0626 return KDb::LogicalExpression; 0627 case AS: 0628 case AS_EMPTY: 0629 return KDb::SpecialBinaryExpression; 0630 default:; 0631 } 0632 return KDb::UnknownExpression; 0633 } 0634 0635 #undef CAST