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 
0004    Based on nexp.cpp : Parser module of Python-like language
0005    (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl)
0006 
0007    This library is free software; you can redistribute it and/or
0008    modify it under the terms of the GNU Library General Public
0009    License as published by the Free Software Foundation; either
0010    version 2 of the License, or (at your option) any later version.
0011 
0012    This library is distributed in the hope that it will be useful,
0013    but WITHOUT ANY WARRANTY; without even the implied warranty of
0014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015    Library General Public License for more details.
0016 
0017    You should have received a copy of the GNU Library General Public License
0018    along with this library; see the file COPYING.LIB.  If not, write to
0019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  */
0022 
0023 #ifndef KDB_EXPRESSION_P_H
0024 #define KDB_EXPRESSION_P_H
0025 
0026 #include "config-kdb.h"
0027 #include "KDbToken.h"
0028 #include "KDbField.h"
0029 
0030 class KDbConstExpressionData;
0031 class KDbEscapedString;
0032 class KDbExpressionData;
0033 class KDbParseInfo;
0034 class KDbQueryParameterExpressionData;
0035 class KDbQuerySchemaParameter;
0036 class KDbQuerySchemaParameterValueListIterator;
0037 class KDbUnaryExpressionData;
0038 
0039 namespace KDb
0040 {
0041 typedef QList<const KDbExpressionData*> ExpressionCallStack;
0042 
0043 //! Classes of expressions
0044 enum ExpressionClass {
0045     UnknownExpression,
0046     UnaryExpression,
0047     ArithmeticExpression,
0048     LogicalExpression,
0049     RelationalExpression,
0050     SpecialBinaryExpression,
0051     ConstExpression,
0052     VariableExpression,
0053     FunctionExpression,
0054     AggregationExpression,
0055     FieldListExpression,
0056     TableListExpression,
0057     ArgumentListExpression,
0058     QueryParameterExpression,
0059     LastExpressionClass = QueryParameterExpression //!< This line should be at the end of the list
0060 };
0061 }
0062 
0063 typedef QExplicitlySharedDataPointer<KDbExpressionData> ExplicitlySharedExpressionDataPointer;
0064 
0065 //! Internal data class used to implement implicitly shared class KDbExpression.
0066 //! Provides thread-safe reference counting.
0067 class KDB_TESTING_EXPORT KDbExpressionData : public QSharedData
0068 {
0069 public:
0070     KDbExpressionData();
0071 
0072     /*Data(const Data& other)
0073     : QSharedData(other)
0074     , token(other.token)
0075     , expressionClass(other.expressionClass)
0076     , parent(other.parent)
0077     , children(other.children)
0078     {
0079         kdbDebug() << "KDbExpressionData" << ref;
0080     }*/
0081 
0082     virtual ~KDbExpressionData();
0083 
0084     //! @see KDbExpression::token()
0085     KDbToken token;
0086     //! @see KDbExpression::expressionClass()
0087     KDb::ExpressionClass expressionClass;
0088     ExplicitlySharedExpressionDataPointer parent;
0089     QList<ExplicitlySharedExpressionDataPointer> children;
0090     KDbField::Type type() const; //!< @return type of this expression;
0091     bool isValid() const;
0092     bool isTextType() const;
0093     bool isIntegerType() const;
0094     bool isNumericType() const;
0095     bool isFPNumericType() const;
0096     bool isDateTimeType() const;
0097     KDbEscapedString toString(const KDbDriver *driver,
0098                               KDbQuerySchemaParameterValueListIterator *params = nullptr,
0099                               KDb::ExpressionCallStack *callStack = nullptr) const;
0100     virtual void getQueryParameters(QList<KDbQuerySchemaParameter> *params);
0101     bool validate(KDbParseInfo *parseInfo);
0102     virtual KDbExpressionData* clone();
0103 
0104     template <typename T>
0105     const T* convertConst() const { return dynamic_cast<const T*>(this); }
0106 
0107     template <typename T>
0108     T* convert() { return dynamic_cast<T*>(this); }
0109 
0110     //! Sends information about this expression  to debug output @a dbg.
0111     QDebug debug(QDebug dbg, KDb::ExpressionCallStack *callStack) const;
0112 
0113     KDbField::Type type(KDb::ExpressionCallStack *callStack) const;
0114 
0115     bool validate(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack);
0116 
0117 protected:
0118     //! Sends information about this expression  to debug output @a dbg (internal).
0119     virtual void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const;
0120 
0121     virtual KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const;
0122 
0123     virtual KDbEscapedString toStringInternal(const KDbDriver *driver,
0124                                               KDbQuerySchemaParameterValueListIterator *params,
0125                                               KDb::ExpressionCallStack *callStack) const;
0126 
0127     virtual bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack);
0128 
0129     bool addToCallStack(QDebug *dbg, KDb::ExpressionCallStack *callStack) const;
0130 };
0131 
0132 //! Internal data class used to implement implicitly shared class KDbNArgExpression.
0133 //! Provides thread-safe reference counting.
0134 class KDbNArgExpressionData : public KDbExpressionData
0135 {
0136     Q_DECLARE_TR_FUNCTIONS(KDbNArgExpressionData)
0137 public:
0138     KDbNArgExpressionData();
0139     ~KDbNArgExpressionData() override;
0140 
0141     void getQueryParameters(QList<KDbQuerySchemaParameter> *params) override;
0142     KDbNArgExpressionData* clone() override;
0143     bool containsInvalidArgument() const;
0144     bool containsNullArgument() const;
0145 
0146 protected:
0147     //! Sends information about this expression  to debug output @a dbg (internal).
0148     void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override;
0149 
0150     KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override;
0151 
0152     KDbEscapedString toStringInternal(const KDbDriver *driver,
0153                                       KDbQuerySchemaParameterValueListIterator *params,
0154                                       KDb::ExpressionCallStack *callStack) const override;
0155 
0156     bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override;
0157 };
0158 
0159 //! Internal data class used to implement implicitly shared class KDbUnaryExpression.
0160 //! Provides thread-safe reference counting.
0161 class KDbUnaryExpressionData : public KDbExpressionData
0162 {
0163 public:
0164     KDbUnaryExpressionData();
0165     ~KDbUnaryExpressionData() override;
0166 
0167     void getQueryParameters(QList<KDbQuerySchemaParameter> *params) override;
0168     KDbUnaryExpressionData* clone() override;
0169     inline ExplicitlySharedExpressionDataPointer arg() const {
0170         return children.isEmpty() ? ExplicitlySharedExpressionDataPointer() : children.first();
0171     }
0172 
0173 protected:
0174     //! Sends information about this expression  to debug output @a dbg (internal).
0175     void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override;
0176 
0177     KDbEscapedString toStringInternal(const KDbDriver *driver,
0178                                       KDbQuerySchemaParameterValueListIterator *params,
0179                                       KDb::ExpressionCallStack *callStack) const override;
0180 
0181     KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override;
0182 
0183     bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override;
0184 };
0185 
0186 //! Internal data class used to implement implicitly shared class KDbBinaryExpression.
0187 //! Provides thread-safe reference counting.
0188 class KDbBinaryExpressionData : public KDbExpressionData
0189 {
0190     Q_DECLARE_TR_FUNCTIONS(KDbBinaryExpressionData)
0191 public:
0192     KDbBinaryExpressionData();
0193     ~KDbBinaryExpressionData() override;
0194 
0195     void getQueryParameters(QList<KDbQuerySchemaParameter> *params) override;
0196     KDbBinaryExpressionData *clone() override;
0197     ExplicitlySharedExpressionDataPointer left() const;
0198     ExplicitlySharedExpressionDataPointer right() const;
0199 
0200 protected:
0201     void setLeft(const KDbExpressionData& left);
0202 
0203     //! Sends information about this expression  to debug output @a dbg (internal).
0204     void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override;
0205 
0206     KDbEscapedString toStringInternal(const KDbDriver *driver,
0207                                       KDbQuerySchemaParameterValueListIterator *params,
0208                                       KDb::ExpressionCallStack *callStack) const override;
0209 
0210     KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override;
0211 
0212     bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override;
0213 };
0214 
0215 //! Internal data class used to implement implicitly shared class KDbConstExpression.
0216 //! Provides thread-safe reference counting.
0217 class KDbConstExpressionData : public KDbExpressionData
0218 {
0219 public:
0220     explicit KDbConstExpressionData(const QVariant& aValue = QVariant());
0221     ~KDbConstExpressionData() override;
0222 
0223     QVariant value;
0224     void getQueryParameters(QList<KDbQuerySchemaParameter> *params) override;
0225     KDbConstExpressionData *clone() override;
0226 
0227 protected:
0228     //! Sends information about this expression  to debug output @a dbg (internal).
0229     void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override;
0230 
0231     KDbEscapedString toStringInternal(const KDbDriver *driver,
0232                                       KDbQuerySchemaParameterValueListIterator *params,
0233                                       KDb::ExpressionCallStack *callStack) const override;
0234 
0235     KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override;
0236 
0237     bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override;
0238 };
0239 
0240 //! Internal data class used to implement implicitly shared class KDbQueryParameterExpression.
0241 //! Provides thread-safe reference counting.
0242 class KDbQueryParameterExpressionData : public KDbConstExpressionData
0243 {
0244 public:
0245     KDbQueryParameterExpressionData();
0246     KDbQueryParameterExpressionData(KDbField::Type type, const QVariant& value);
0247     ~KDbQueryParameterExpressionData() override;
0248 
0249     KDbField::Type m_type;
0250     void getQueryParameters(QList<KDbQuerySchemaParameter> *params) override;
0251     KDbQueryParameterExpressionData* clone() override;
0252 
0253 protected:
0254     //! Sends information about this expression  to debug output @a dbg (internal).
0255     void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override;
0256 
0257     KDbEscapedString toStringInternal(const KDbDriver *driver,
0258                                       KDbQuerySchemaParameterValueListIterator *params,
0259                                       KDb::ExpressionCallStack *callStack) const override;
0260 
0261     KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override;
0262 
0263     bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override;
0264 };
0265 
0266 //! Internal data class used to implement implicitly shared class KDbVariableExpression.
0267 //! Provides thread-safe reference counting.
0268 class KDbVariableExpressionData : public KDbExpressionData
0269 {
0270     Q_DECLARE_TR_FUNCTIONS(KDbVariableExpressionData)
0271 public:
0272     KDbVariableExpressionData();
0273     explicit KDbVariableExpressionData(const QString& aName);
0274     ~KDbVariableExpressionData() override;
0275 
0276     /*! Verbatim name as returned by scanner. */
0277     QString name;
0278 
0279     /*! 0 by default. After successful validate() it will point to a field,
0280      if the variable is of a form "tablename.fieldname" or "fieldname",
0281      otherwise (eg. for asterisks) still 0.
0282      Only meaningful for column expressions within a query. */
0283     KDbField *field;
0284 
0285     /*! -1 by default. After successful validate() it will contain a position of a table
0286      within query that needs to be bound to the field.
0287      This value can be either be -1 if no binding is needed.
0288      This value is used in the Parser to call
0289       KDbQuerySchema::addField(KDbField* field, int bindToTable);
0290      Only meaningful for column expressions within a query. */
0291     int tablePositionForField;
0292 
0293     /*! 0 by default. After successful validate() it will point to a table
0294      that is referenced by asterisk, i.e. "*.tablename".
0295      This is set to @c nullptr if this variable is not an asterisk of that form. */
0296     KDbTableSchema *tableForQueryAsterisk;
0297 
0298     void getQueryParameters(QList<KDbQuerySchemaParameter> *params) override;
0299     KDbVariableExpressionData* clone() override;
0300 
0301 protected:
0302     //! Sends information about this expression  to debug output @a dbg (internal).
0303     void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override;
0304 
0305     KDbEscapedString toStringInternal(const KDbDriver *driver,
0306                                       KDbQuerySchemaParameterValueListIterator *params,
0307                                       KDb::ExpressionCallStack *callStack) const override;
0308 
0309     KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override;
0310 
0311     /*! Validation. Sets field, tablePositionForField
0312      and tableForQueryAsterisk members.
0313      See addColumn() in parse.y to see how it's used on column adding. */
0314     bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override;
0315 };
0316 
0317 //! Internal data class used to implement implicitly shared class KDbFunctionExpression.
0318 //! Provides thread-safe reference counting.
0319 class KDbFunctionExpressionData : public KDbExpressionData
0320 {
0321     Q_DECLARE_TR_FUNCTIONS(KDbFunctionExpressionData)
0322 public:
0323     KDbFunctionExpressionData();
0324     explicit KDbFunctionExpressionData(const QString &aName,
0325                                        ExplicitlySharedExpressionDataPointer arguments
0326                                        = ExplicitlySharedExpressionDataPointer());
0327     ~KDbFunctionExpressionData() override;
0328 
0329     QString name;
0330     ExplicitlySharedExpressionDataPointer args;
0331 
0332     void getQueryParameters(QList<KDbQuerySchemaParameter> *params) override;
0333     KDbFunctionExpressionData* clone() override;
0334 
0335     void setArguments(ExplicitlySharedExpressionDataPointer arguments);
0336 
0337     static KDbEscapedString toString(const QString &name,
0338                                      const KDbDriver *driver,
0339                                      const KDbNArgExpressionData *args,
0340                                      KDbQuerySchemaParameterValueListIterator *params,
0341                                      KDb::ExpressionCallStack *callStack);
0342 
0343 protected:
0344     //! Sends information about this expression  to debug output @a dbg (internal).
0345     void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override;
0346 
0347     KDbEscapedString toStringInternal(const KDbDriver *driver,
0348                                       KDbQuerySchemaParameterValueListIterator *params,
0349                                       KDb::ExpressionCallStack *callStack) const override;
0350 
0351     KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override;
0352 
0353     /*! Validation. Sets field, tablePositionForField
0354      and tableForQueryAsterisk members.
0355      See addColumn() in parse.y to see how it's used on column adding. */
0356     bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override;
0357 };
0358 
0359 QDebug operator<<(QDebug dbg, const KDbExpressionData& expr);
0360 
0361 #endif