File indexing completed on 2024-04-21 15:29:54

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