1 /***************************************************************************
2                                qgssqlstatement.h
3                              ---------------------
4     begin                : April 2016
5     copyright            : (C) 2011 by Martin Dobias
6     copyright            : (C) 2016 by Even Rouault
7     email                : even.rouault at spatialys.com
8  ***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 
17 #ifndef QGSSQLSTATEMENT_H
18 #define QGSSQLSTATEMENT_H
19 
20 #include <QCoreApplication>
21 #include "qgis_sip.h"
22 #include <QMetaType>
23 #include <QStringList>
24 #include <QVariant>
25 #include <QList>
26 #include <QSet>
27 
28 #include "qgis_core.h"
29 
30 /**
31  * \ingroup core
32  * \brief Class for parsing SQL statements.
33  * \since QGIS 2.16
34  */
35 class CORE_EXPORT QgsSQLStatement
36 {
37     Q_DECLARE_TR_FUNCTIONS( QgsSQLStatement )
38   public:
39 
40     /**
41      * Creates a new statement based on the provided string.
42      */
43     QgsSQLStatement( const QString &statement );
44 
45     /**
46      * Create a copy of this statement.
47      */
48     QgsSQLStatement( const QgsSQLStatement &other );
49 
50     /**
51      * Create a copy of this statement.
52      */
53     QgsSQLStatement &operator=( const QgsSQLStatement &other );
54     virtual ~QgsSQLStatement();
55 
56     //! Returns TRUE if an error occurred when parsing the input statement
57     bool hasParserError() const;
58     //! Returns parser error
59     QString parserErrorString() const;
60 
61     /**
62      * Performs basic validity checks. Basically checking that columns referencing
63      * a table, references a specified table. Returns TRUE if the validation is
64      * successful
65     */
66     bool doBasicValidationChecks( QString &errorMsgOut SIP_OUT ) const;
67 
68     class Node;
69 
70     /**
71      * Returns the root node of the statement.
72      * The root node is NULLPTR if parsing has failed.
73      */
74     const QgsSQLStatement::Node *rootNode() const;
75 
76     /**
77      * Returns the original, unmodified statement string.
78      * If there was none supplied because it was constructed by sole
79      * API calls, dump() will be used to create one instead.
80      */
81     QString statement() const;
82 
83     /**
84      * Returns the statement string, constructed from the internal
85      * abstract syntax tree. This does not contain any nice whitespace
86      * formatting or comments. In general it is preferable to use
87      * statement() instead.
88      */
89     QString dump() const;
90 
91     /**
92      * Returns a quoted column reference (in double quotes)
93      * \see quotedString(), quotedIdentifierIfNeeded()
94      */
95     static QString quotedIdentifier( QString name );
96 
97     /**
98      * Returns a quoted column reference (in double quotes) if needed, or
99      * otherwise the original string.
100      * \see quotedString(), quotedIdentifier()
101      */
102     static QString quotedIdentifierIfNeeded( const QString &name );
103 
104     /**
105      * Remove double quotes from an identifier.
106      * \see quotedIdentifier()
107      */
108     static QString stripQuotedIdentifier( QString text );
109 
110     /**
111      * Remove double quotes from an Microsoft style identifier.
112      * \see quotedIdentifier()
113      */
114     static QString stripMsQuotedIdentifier( QString text );
115 
116     /**
117      * Returns a quoted version of a string (in single quotes)
118      * \see quotedIdentifier(), quotedIdentifierIfNeeded()
119      */
120     static QString quotedString( QString text );
121 
122     /**
123      * \brief list of unary operators
124      * \note if any change is made here, the definition of QgsSQLStatement::UnaryOperatorText[] must be adapted.
125      */
126     enum UnaryOperator
127     {
128       uoNot,
129       uoMinus,
130     };
131 
132     /**
133      * \brief list of binary operators
134      * \note if any change is made here, the definition of QgsSQLStatement::BinaryOperatorText[] must be adapted.
135      */
136     enum BinaryOperator
137     {
138       // logical
139       boOr,
140       boAnd,
141 
142       // comparison
143       boEQ,  // =
144       boNE,  // <>
145       boLE,  // <=
146       boGE,  // >=
147       boLT,  // <
148       boGT,  // >
149       boLike,
150       boNotLike,
151       boILike,
152       boNotILike,
153       boIs,
154       boIsNot,
155 
156       // math
157       boPlus,
158       boMinus,
159       boMul,
160       boDiv,
161       boIntDiv,
162       boMod,
163       boPow,
164 
165       // strings
166       boConcat,
167     };
168 
169     /**
170      * \brief list of join types
171      * \note if any change is made here, the definition of QgsSQLStatement::JoinTypeText[] must be adapted.
172      */
173     enum JoinType
174     {
175       jtDefault,
176       jtLeft,
177       jtLeftOuter,
178       jtRight,
179       jtRightOuter,
180       jtCross,
181       jtInner,
182       jtFull
183     };
184 
185     //! \note not available in Python bindings
186     static const char *BINARY_OPERATOR_TEXT[] SIP_SKIP;
187 
188     //! \note not available in Python bindings
189     static const char *UNARY_OPERATOR_TEXT[] SIP_SKIP;
190 
191     //! \note not available in Python bindings
192     static const char *JOIN_TYPE_TEXT[] SIP_SKIP;
193 
194     //////
195 
196     class Visitor; // visitor interface is defined below
197 
198     //! Node type
199     enum NodeType
200     {
201       ntUnaryOperator,
202       ntBinaryOperator,
203       ntInOperator,
204       ntBetweenOperator,
205       ntFunction,
206       ntLiteral,
207       ntColumnRef,
208       ntSelectedColumn,
209       ntSelect,
210       ntTableDef,
211       ntJoin,
212       ntColumnSorted,
213       ntCast
214     };
215 
216     /**
217      * \ingroup core
218      * \brief Abstract node class
219     */
220     class CORE_EXPORT Node
221     {
222 
223 #ifdef SIP_RUN
224         SIP_CONVERT_TO_SUBCLASS_CODE
225         switch ( sipCpp->nodeType() )
226         {
227           case QgsSQLStatement::ntUnaryOperator:   sipType = sipType_QgsSQLStatement_NodeUnaryOperator; break;
228           case QgsSQLStatement::ntBinaryOperator:  sipType = sipType_QgsSQLStatement_NodeBinaryOperator; break;
229           case QgsSQLStatement::ntInOperator:      sipType = sipType_QgsSQLStatement_NodeInOperator; break;
230           case QgsSQLStatement::ntBetweenOperator: sipType = sipType_QgsSQLStatement_NodeBetweenOperator; break;
231           case QgsSQLStatement::ntFunction:        sipType = sipType_QgsSQLStatement_NodeFunction; break;
232           case QgsSQLStatement::ntLiteral:         sipType = sipType_QgsSQLStatement_NodeLiteral; break;
233           case QgsSQLStatement::ntColumnRef:       sipType = sipType_QgsSQLStatement_NodeColumnRef; break;
234           case QgsSQLStatement::ntSelectedColumn:  sipType = sipType_QgsSQLStatement_NodeSelectedColumn; break;
235           case QgsSQLStatement::ntSelect:          sipType = sipType_QgsSQLStatement_NodeSelect; break;
236           case QgsSQLStatement::ntTableDef:        sipType = sipType_QgsSQLStatement_NodeTableDef; break;
237           case QgsSQLStatement::ntJoin:            sipType = sipType_QgsSQLStatement_NodeJoin; break;
238           case QgsSQLStatement::ntColumnSorted:    sipType = sipType_QgsSQLStatement_NodeColumnSorted; break;
239           case QgsSQLStatement::ntCast:            sipType = sipType_QgsSQLStatement_NodeCast; break;
240           default:                               sipType = 0; break;
241         }
242         SIP_END
243 #endif
244 
245       public:
246         virtual ~Node() = default;
247 
248         /**
249          * Abstract virtual that returns the type of this node.
250          *
251          * \returns The type of this node
252          */
253         virtual QgsSQLStatement::NodeType nodeType() const = 0;
254 
255         /**
256          * Abstract virtual dump method
257          *
258          * \returns A statement which represents this node as string
259          */
260         virtual QString dump() const = 0;
261 
262         /**
263          * Generate a clone of this node.
264          * Make sure that the clone does not contain any information which is
265          * generated in prepare and context related.
266          * Ownership is transferred to the caller.
267          *
268          * \returns a deep copy of this node.
269          */
270         virtual QgsSQLStatement::Node *clone() const = 0 SIP_FACTORY;
271 
272         /**
273          * Support the visitor pattern.
274          *
275          * For any implementation this should look like
276          *
277          * C++:
278          *
279          *     v.visit( *this );
280          *
281          * Python:
282          *
283          *     v.visit( self)
284          *
285          * \param v A visitor that visits this node.
286          */
287         virtual void accept( QgsSQLStatement::Visitor &v ) const = 0;
288     };
289 
290     /**
291      * A list of nodes.
292      * \ingroup core
293      */
294     class CORE_EXPORT NodeList
295     {
296       public:
297         //! Constructor
298         NodeList() = default;
~NodeList()299         virtual ~NodeList() { qDeleteAll( mList ); }
300 
301         //! Takes ownership of the provided node
append(QgsSQLStatement::Node * node SIP_TRANSFER)302         void append( QgsSQLStatement::Node *node SIP_TRANSFER ) { mList.append( node ); }
303 
304         //! Returns list
list()305         QList<QgsSQLStatement::Node *> list() { return mList; }
306 
307         /**
308          * Returns the number of nodes in the list.
309          */
count()310         int count() const { return mList.count(); }
311 
312         //! Accept visitor
313         void accept( QgsSQLStatement::Visitor &v ) const;
314 
315         //! Creates a deep copy of this list. Ownership is transferred to the caller
316         QgsSQLStatement::NodeList *clone() const SIP_FACTORY;
317 
318         //! Dump list
319         virtual QString dump() const;
320 
321       protected:
322         QList<Node *> mList;
323     };
324 
325     /**
326      * \ingroup core
327      * \brief Unary logicial/arithmetical operator ( NOT, - )
328     */
329     class CORE_EXPORT NodeUnaryOperator : public QgsSQLStatement::Node
330     {
331       public:
332         //! Constructor
NodeUnaryOperator(QgsSQLStatement::UnaryOperator op,QgsSQLStatement::Node * operand SIP_TRANSFER)333         NodeUnaryOperator( QgsSQLStatement::UnaryOperator op, QgsSQLStatement::Node *operand SIP_TRANSFER ) : mOp( op ), mOperand( operand ) {}
~NodeUnaryOperator()334         ~NodeUnaryOperator() override { delete mOperand; }
335 
336         //! Operator
op()337         QgsSQLStatement::UnaryOperator op() const { return mOp; }
338 
339         //! Operand
operand()340         QgsSQLStatement::Node *operand() const { return mOperand; }
341 
nodeType()342         QgsSQLStatement::NodeType nodeType() const override { return ntUnaryOperator; }
343         QString dump() const override;
344 
accept(QgsSQLStatement::Visitor & v)345         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
346         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
347 
348       protected:
349         UnaryOperator mOp;
350         Node *mOperand = nullptr;
351     };
352 
353     /**
354      * \ingroup core
355      * \brief Binary logical/arithmetical operator (AND, OR, =, +, ...)
356     */
357     class CORE_EXPORT NodeBinaryOperator : public QgsSQLStatement::Node
358     {
359       public:
360         //! Constructor
NodeBinaryOperator(QgsSQLStatement::BinaryOperator op,QgsSQLStatement::Node * opLeft SIP_TRANSFER,QgsSQLStatement::Node * opRight SIP_TRANSFER)361         NodeBinaryOperator( QgsSQLStatement::BinaryOperator op, QgsSQLStatement::Node *opLeft SIP_TRANSFER, QgsSQLStatement::Node *opRight SIP_TRANSFER )
362           : mOp( op )
363           , mOpLeft( opLeft )
364           , mOpRight( opRight )
365         {}
~NodeBinaryOperator()366         ~NodeBinaryOperator() override { delete mOpLeft; delete mOpRight; }
367 
368         //! Operator
op()369         QgsSQLStatement::BinaryOperator op() const { return mOp; }
370 
371         //! Left operand
opLeft()372         QgsSQLStatement::Node *opLeft() const { return mOpLeft; }
373 
374         //! Right operand
opRight()375         QgsSQLStatement::Node *opRight() const { return mOpRight; }
376 
nodeType()377         QgsSQLStatement::NodeType nodeType() const override { return ntBinaryOperator; }
378         QString dump() const override;
379 
accept(QgsSQLStatement::Visitor & v)380         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
381         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
382 
383         //! Precedence
384         int precedence() const;
385 
386         //! Is left associative ?
387         bool leftAssociative() const;
388 
389       protected:
390 
391         BinaryOperator mOp;
392         Node *mOpLeft = nullptr;
393         Node *mOpRight = nullptr;
394     };
395 
396     /**
397      * \ingroup core
398      * \brief 'x IN (y, z)' operator
399     */
400     class CORE_EXPORT NodeInOperator : public QgsSQLStatement::Node
401     {
402       public:
403         //! Constructor
mNode(node)404         NodeInOperator( QgsSQLStatement::Node *node SIP_TRANSFER, QgsSQLStatement::NodeList *list SIP_TRANSFER, bool notin = false ) : mNode( node ), mList( list ), mNotIn( notin ) {}
~NodeInOperator()405         ~NodeInOperator() override { delete mNode; delete mList; }
406 
407         //! Variable at the left of IN
node()408         QgsSQLStatement::Node *node() const { return mNode; }
409 
410         //! Whether this is a NOT IN operator
isNotIn()411         bool isNotIn() const { return mNotIn; }
412 
413         //! Values list
list()414         QgsSQLStatement::NodeList *list() const { return mList; }
415 
nodeType()416         QgsSQLStatement::NodeType nodeType() const override { return ntInOperator; }
417         QString dump() const override;
418 
accept(QgsSQLStatement::Visitor & v)419         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
420         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
421 
422       protected:
423         Node *mNode = nullptr;
424         NodeList *mList = nullptr;
425         bool mNotIn;
426     };
427 
428     /**
429      * \ingroup core
430      * \brief 'X BETWEEN y and z' operator
431     */
432     class CORE_EXPORT NodeBetweenOperator : public QgsSQLStatement::Node
433     {
434       public:
435         //! Constructor
436         NodeBetweenOperator( QgsSQLStatement::Node *node SIP_TRANSFER, QgsSQLStatement::Node *minVal SIP_TRANSFER, QgsSQLStatement::Node *maxVal SIP_TRANSFER, bool notBetween = false )
mNode(node)437           : mNode( node ), mMinVal( minVal ), mMaxVal( maxVal ), mNotBetween( notBetween ) {}
~NodeBetweenOperator()438         ~NodeBetweenOperator() override { delete mNode; delete mMinVal; delete mMaxVal; }
439 
440         //! Variable at the left of BETWEEN
node()441         QgsSQLStatement::Node *node() const { return mNode; }
442 
443         //! Whether this is a NOT BETWEEN operator
isNotBetween()444         bool isNotBetween() const { return mNotBetween; }
445 
446         //! Minimum bound
minVal()447         QgsSQLStatement::Node *minVal() const { return mMinVal; }
448 
449         //! Maximum bound
maxVal()450         QgsSQLStatement::Node *maxVal() const { return mMaxVal; }
451 
nodeType()452         QgsSQLStatement::NodeType nodeType() const override { return ntBetweenOperator; }
453         QString dump() const override;
454 
accept(QgsSQLStatement::Visitor & v)455         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
456         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
457 
458       protected:
459         Node *mNode = nullptr;
460         Node *mMinVal = nullptr;
461         Node *mMaxVal = nullptr;
462         bool mNotBetween;
463     };
464 
465     /**
466      * \ingroup core
467      * \brief Function with a name and arguments node
468     */
469     class CORE_EXPORT NodeFunction : public QgsSQLStatement::Node
470     {
471       public:
472         //! Constructor
NodeFunction(const QString & name,QgsSQLStatement::NodeList * args SIP_TRANSFER)473         NodeFunction( const QString &name, QgsSQLStatement::NodeList *args  SIP_TRANSFER ) : mName( name ), mArgs( args ) {}
~NodeFunction()474         ~NodeFunction() override { delete mArgs; }
475 
476         //! Returns function name
name()477         QString name() const { return mName; }
478 
479         //! Returns arguments
args()480         QgsSQLStatement::NodeList *args() const { return mArgs; }
481 
nodeType()482         QgsSQLStatement::NodeType nodeType() const override { return ntFunction; }
483         QString dump() const override;
484 
accept(QgsSQLStatement::Visitor & v)485         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
486         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
487 
488       protected:
489         QString mName;
490         NodeList *mArgs = nullptr;
491 
492     };
493 
494     /**
495      * \ingroup core
496      * \brief Literal value (integer, integer64, double, string)
497     */
498     class CORE_EXPORT NodeLiteral : public QgsSQLStatement::Node
499     {
500       public:
501         //! Constructor
NodeLiteral(const QVariant & value)502         NodeLiteral( const QVariant &value ) : mValue( value ) {}
503 
504         //! The value of the literal.
value()505         inline QVariant value() const { return mValue; }
506 
nodeType()507         QgsSQLStatement::NodeType nodeType() const override { return ntLiteral; }
508         QString dump() const override;
509 
accept(QgsSQLStatement::Visitor & v)510         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
511         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
512 
513       protected:
514         QVariant mValue;
515     };
516 
517     /**
518      * \ingroup core
519      * \brief Reference to a column
520     */
521     class CORE_EXPORT NodeColumnRef : public QgsSQLStatement::Node
522     {
523       public:
524         //! Constructor with column name only
NodeColumnRef(const QString & name,bool star)525         NodeColumnRef( const QString &name, bool star ) : mName( name ), mDistinct( false ), mStar( star ) {}
526         //! Constructor with table and column name
NodeColumnRef(const QString & tableName,const QString & name,bool star)527         NodeColumnRef( const QString &tableName, const QString &name, bool star ) : mTableName( tableName ), mName( name ), mDistinct( false ), mStar( star ) {}
528 
529         //! Sets whether this is prefixed by DISTINCT
530         void setDistinct( bool distinct = true ) { mDistinct = distinct; }
531 
532         //! The name of the table. May be empty.
tableName()533         QString tableName() const { return mTableName; }
534 
535         //! The name of the column.
name()536         QString name() const { return mName; }
537 
538         //! Whether this is the * column
star()539         bool star() const { return mStar; }
540 
541         //! Whether this is prefixed by DISTINCT
distinct()542         bool distinct() const { return mDistinct; }
543 
nodeType()544         QgsSQLStatement::NodeType nodeType() const override { return ntColumnRef; }
545         QString dump() const override;
546 
accept(QgsSQLStatement::Visitor & v)547         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
548         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
549         //! Clone with same type return
550         QgsSQLStatement::NodeColumnRef *cloneThis() const SIP_FACTORY;
551 
552       protected:
553         QString mTableName;
554         QString mName;
555         bool mDistinct;
556         bool mStar;
557     };
558 
559     /**
560      * \ingroup core
561      * \brief Selected column
562     */
563     class CORE_EXPORT NodeSelectedColumn : public QgsSQLStatement::Node
564     {
565       public:
566         //! Constructor
NodeSelectedColumn(QgsSQLStatement::Node * node SIP_TRANSFER)567         NodeSelectedColumn( QgsSQLStatement::Node *node SIP_TRANSFER ) : mColumnNode( node ) {}
~NodeSelectedColumn()568         ~NodeSelectedColumn() override { delete mColumnNode; }
569 
570         //! Sets alias name
setAlias(const QString & alias)571         void setAlias( const QString &alias ) { mAlias = alias; }
572 
573         //! Column that is referred to
column()574         QgsSQLStatement::Node *column() const { return mColumnNode; }
575 
576         //! Alias name
alias()577         QString alias() const { return mAlias; }
578 
nodeType()579         QgsSQLStatement::NodeType nodeType() const override { return ntSelectedColumn; }
580         QString dump() const override;
581 
accept(QgsSQLStatement::Visitor & v)582         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
583         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
584         //! Clone with same type return
585         QgsSQLStatement::NodeSelectedColumn *cloneThis() const SIP_FACTORY;
586 
587       protected:
588         Node *mColumnNode = nullptr;
589         QString mAlias;
590     };
591 
592     /**
593      * \ingroup core
594      * \brief CAST operator
595     */
596     class CORE_EXPORT NodeCast : public QgsSQLStatement::Node
597     {
598       public:
599         //! Constructor
NodeCast(QgsSQLStatement::Node * node SIP_TRANSFER,const QString & type)600         NodeCast( QgsSQLStatement::Node *node SIP_TRANSFER, const QString &type ) : mNode( node ), mType( type ) {}
~NodeCast()601         ~NodeCast() override { delete mNode; }
602 
603         //! Node that is referred to
node()604         QgsSQLStatement::Node *node() const { return mNode; }
605 
606         //! Type
type()607         QString type() const { return mType; }
608 
nodeType()609         QgsSQLStatement::NodeType nodeType() const override { return ntCast; }
610         QString dump() const override;
611 
accept(QgsSQLStatement::Visitor & v)612         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
613         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
614 
615       protected:
616         Node *mNode = nullptr;
617         QString mType;
618     };
619 
620     /**
621      * \ingroup core
622      * \brief Table definition
623     */
624     class CORE_EXPORT NodeTableDef : public QgsSQLStatement::Node
625     {
626       public:
627         //! Constructor with table name
NodeTableDef(const QString & name)628         NodeTableDef( const QString &name ) : mName( name ) {}
629         //! Constructor with table name and alias
NodeTableDef(const QString & name,const QString & alias)630         NodeTableDef( const QString &name, const QString &alias ) : mName( name ), mAlias( alias ) {}
631 
632         //! Table name
name()633         QString name() const { return mName; }
634 
635         //! Table alias
alias()636         QString alias() const { return mAlias; }
637 
nodeType()638         QgsSQLStatement::NodeType nodeType() const override { return ntTableDef; }
639         QString dump() const override;
640 
accept(QgsSQLStatement::Visitor & v)641         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
642         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
643         //! Clone with same type return
644         QgsSQLStatement::NodeTableDef *cloneThis() const SIP_FACTORY;
645 
646       protected:
647         QString mName;
648         QString mAlias;
649     };
650 
651     /**
652      * \ingroup core
653      * \brief Join definition
654     */
655     class CORE_EXPORT NodeJoin : public QgsSQLStatement::Node
656     {
657       public:
658         //! Constructor with table definition, ON expression
NodeJoin(QgsSQLStatement::NodeTableDef * tabledef SIP_TRANSFER,QgsSQLStatement::Node * onExpr SIP_TRANSFER,QgsSQLStatement::JoinType type)659         NodeJoin( QgsSQLStatement::NodeTableDef *tabledef SIP_TRANSFER, QgsSQLStatement::Node *onExpr SIP_TRANSFER, QgsSQLStatement::JoinType type ) : mTableDef( tabledef ), mOnExpr( onExpr ), mType( type ) {}
660         //! Constructor with table definition and USING columns
NodeJoin(QgsSQLStatement::NodeTableDef * tabledef SIP_TRANSFER,const QList<QString> & usingColumns,QgsSQLStatement::JoinType type)661         NodeJoin( QgsSQLStatement::NodeTableDef *tabledef SIP_TRANSFER, const QList<QString> &usingColumns, QgsSQLStatement::JoinType type ) : mTableDef( tabledef ), mUsingColumns( usingColumns ), mType( type ) {}
~NodeJoin()662         ~NodeJoin() override { delete mTableDef; delete mOnExpr; }
663 
664         //! Table definition
tableDef()665         QgsSQLStatement::NodeTableDef *tableDef() const { return mTableDef; }
666 
667         //! On expression. Will be NULLPTR if usingColumns() is not empty
onExpr()668         QgsSQLStatement::Node *onExpr() const { return mOnExpr; }
669 
670         //! Columns referenced by USING
usingColumns()671         QList<QString> usingColumns() const { return mUsingColumns; }
672 
673         //! Join type
type()674         QgsSQLStatement::JoinType type() const { return mType; }
675 
nodeType()676         QgsSQLStatement::NodeType nodeType() const override { return ntJoin; }
677         QString dump() const override;
678 
accept(QgsSQLStatement::Visitor & v)679         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
680         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
681         //! Clone with same type return
682         QgsSQLStatement::NodeJoin *cloneThis() const SIP_FACTORY;
683 
684       protected:
685         NodeTableDef *mTableDef = nullptr;
686         Node *mOnExpr = nullptr;
687         QList<QString> mUsingColumns;
688         JoinType mType;
689     };
690 
691     /**
692      * \ingroup core
693      * \brief Column in a ORDER BY
694     */
695     class CORE_EXPORT NodeColumnSorted : public QgsSQLStatement::Node
696     {
697       public:
698         //! Constructor
NodeColumnSorted(QgsSQLStatement::NodeColumnRef * column SIP_TRANSFER,bool asc)699         NodeColumnSorted( QgsSQLStatement::NodeColumnRef *column SIP_TRANSFER, bool asc ) : mColumn( column ), mAsc( asc ) {}
~NodeColumnSorted()700         ~NodeColumnSorted() override { delete mColumn; }
701 
702         //! The name of the column.
column()703         QgsSQLStatement::NodeColumnRef *column() const { return mColumn; }
704 
705         //! Whether the column is sorted in ascending order
ascending()706         bool ascending() const { return mAsc; }
707 
nodeType()708         QgsSQLStatement::NodeType nodeType() const override { return ntColumnSorted; }
709         QString dump() const override;
710 
accept(QgsSQLStatement::Visitor & v)711         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
712         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
713         //! Clone with same type return
714         QgsSQLStatement::NodeColumnSorted *cloneThis() const SIP_FACTORY;
715 
716       protected:
717         NodeColumnRef *mColumn = nullptr;
718         bool mAsc;
719     };
720 
721     /**
722      * \ingroup core
723      * \brief SELECT node
724     */
725     class CORE_EXPORT NodeSelect : public QgsSQLStatement::Node
726     {
727       public:
728         //! Constructor
NodeSelect(const QList<QgsSQLStatement::NodeTableDef * > & tableList SIP_TRANSFER,const QList<QgsSQLStatement::NodeSelectedColumn * > & columns SIP_TRANSFER,bool distinct)729         NodeSelect( const QList<QgsSQLStatement::NodeTableDef *> &tableList SIP_TRANSFER, const QList<QgsSQLStatement::NodeSelectedColumn *> &columns SIP_TRANSFER, bool distinct ) : mTableList( tableList ), mColumns( columns ), mDistinct( distinct ) {}
730         ~NodeSelect() override;
731 
732         //! Sets joins
setJoins(const QList<QgsSQLStatement::NodeJoin * > & joins SIP_TRANSFER)733         void setJoins( const QList<QgsSQLStatement::NodeJoin *> &joins SIP_TRANSFER ) { qDeleteAll( mJoins ); mJoins = joins; }
734         //! Append a join
appendJoin(QgsSQLStatement::NodeJoin * join SIP_TRANSFER)735         void appendJoin( QgsSQLStatement::NodeJoin *join SIP_TRANSFER ) { mJoins.append( join ); }
736         //! Sets where clause
setWhere(QgsSQLStatement::Node * where SIP_TRANSFER)737         void setWhere( QgsSQLStatement::Node *where SIP_TRANSFER ) { delete mWhere; mWhere = where; }
738         //! Sets order by columns
setOrderBy(const QList<QgsSQLStatement::NodeColumnSorted * > & orderBy SIP_TRANSFER)739         void setOrderBy( const QList<QgsSQLStatement::NodeColumnSorted *> &orderBy SIP_TRANSFER ) { qDeleteAll( mOrderBy ); mOrderBy = orderBy; }
740 
741         //! Returns the list of tables
tables()742         QList<QgsSQLStatement::NodeTableDef *> tables() const { return mTableList; }
743         //! Returns the list of columns
columns()744         QList<QgsSQLStatement::NodeSelectedColumn *> columns() const { return mColumns; }
745         //! Returns if the SELECT is DISTINCT
distinct()746         bool distinct() const { return mDistinct; }
747         //! Returns the list of joins
joins()748         QList<QgsSQLStatement::NodeJoin *> joins() const { return mJoins; }
749         //! Returns the where clause
where()750         QgsSQLStatement::Node *where() const { return mWhere; }
751         //! Returns the list of order by columns
orderBy()752         QList<QgsSQLStatement::NodeColumnSorted *> orderBy() const { return mOrderBy; }
753 
nodeType()754         QgsSQLStatement::NodeType nodeType() const override { return ntSelect; }
755         QString dump() const override;
756 
accept(QgsSQLStatement::Visitor & v)757         void accept( QgsSQLStatement::Visitor &v ) const override { v.visit( *this ); }
758         QgsSQLStatement::Node *clone() const override SIP_FACTORY;
759 
760       protected:
761         QList<NodeTableDef *> mTableList;
762         QList<NodeSelectedColumn *> mColumns;
763         bool mDistinct;
764         QList<NodeJoin *> mJoins;
765         Node *mWhere = nullptr;
766         QList<NodeColumnSorted *> mOrderBy;
767     };
768 
769     //////
770 
771     /**
772      * \ingroup core
773      * \brief Support for visitor pattern - algorithms dealing with the statement
774      * may be implemented without modifying the Node classes
775     */
776     class CORE_EXPORT Visitor
777     {
778       public:
779         virtual ~Visitor() = default;
780         //! Visit NodeUnaryOperator
781         virtual void visit( const QgsSQLStatement::NodeUnaryOperator &n ) = 0;
782         //! Visit NodeBinaryOperator
783         virtual void visit( const QgsSQLStatement::NodeBinaryOperator &n ) = 0;
784         //! Visit NodeInOperator
785         virtual void visit( const QgsSQLStatement::NodeInOperator &n ) = 0;
786         //! Visit NodeBetweenOperator
787         virtual void visit( const QgsSQLStatement::NodeBetweenOperator &n ) = 0;
788         //! Visit NodeFunction
789         virtual void visit( const QgsSQLStatement::NodeFunction &n ) = 0;
790         //! Visit NodeLiteral
791         virtual void visit( const QgsSQLStatement::NodeLiteral &n ) = 0;
792         //! Visit NodeColumnRef
793         virtual void visit( const QgsSQLStatement::NodeColumnRef &n ) = 0;
794         //! Visit NodeSelectedColumn
795         virtual void visit( const QgsSQLStatement::NodeSelectedColumn &n ) = 0;
796         //! Visit NodeTableDef
797         virtual void visit( const QgsSQLStatement::NodeTableDef &n ) = 0;
798         //! Visit NodeSelect
799         virtual void visit( const QgsSQLStatement::NodeSelect &n ) = 0;
800         //! Visit NodeJoin
801         virtual void visit( const QgsSQLStatement::NodeJoin &n ) = 0;
802         //! Visit NodeColumnSorted
803         virtual void visit( const QgsSQLStatement::NodeColumnSorted &n ) = 0;
804         //! Visit NodeCast
805         virtual void visit( const QgsSQLStatement::NodeCast &n ) = 0;
806     };
807 
808     /**
809      * \ingroup core
810      * \brief A visitor that recursively explores all children
811     */
812     class CORE_EXPORT RecursiveVisitor: public QgsSQLStatement::Visitor
813     {
814       public:
815         //! Constructor
816         RecursiveVisitor() = default;
817 
visit(const QgsSQLStatement::NodeUnaryOperator & n)818         void visit( const QgsSQLStatement::NodeUnaryOperator &n ) override { n.operand()->accept( *this ); }
visit(const QgsSQLStatement::NodeBinaryOperator & n)819         void visit( const QgsSQLStatement::NodeBinaryOperator &n ) override { n.opLeft()->accept( *this ); n.opRight()->accept( *this ); }
visit(const QgsSQLStatement::NodeInOperator & n)820         void visit( const QgsSQLStatement::NodeInOperator &n ) override { n.node()->accept( *this ); n.list()->accept( *this ); }
visit(const QgsSQLStatement::NodeBetweenOperator & n)821         void visit( const QgsSQLStatement::NodeBetweenOperator &n ) override { n.node()->accept( *this ); n.minVal()->accept( *this ); n.maxVal()->accept( *this ); }
visit(const QgsSQLStatement::NodeFunction & n)822         void visit( const QgsSQLStatement::NodeFunction &n ) override { n.args()->accept( *this ); }
visit(const QgsSQLStatement::NodeLiteral &)823         void visit( const QgsSQLStatement::NodeLiteral & ) override {}
visit(const QgsSQLStatement::NodeColumnRef &)824         void visit( const QgsSQLStatement::NodeColumnRef & ) override { }
visit(const QgsSQLStatement::NodeSelectedColumn & n)825         void visit( const QgsSQLStatement::NodeSelectedColumn &n ) override { n.column()->accept( *this ); }
visit(const QgsSQLStatement::NodeTableDef &)826         void visit( const QgsSQLStatement::NodeTableDef & ) override {}
827         void visit( const QgsSQLStatement::NodeSelect &n ) override;
828         void visit( const QgsSQLStatement::NodeJoin &n ) override;
visit(const QgsSQLStatement::NodeColumnSorted & n)829         void visit( const QgsSQLStatement::NodeColumnSorted &n ) override { n.column()->accept( *this ); }
visit(const QgsSQLStatement::NodeCast & n)830         void visit( const QgsSQLStatement::NodeCast &n ) override { n.node()->accept( *this ); }
831     };
832 
833     //! Entry function for the visitor pattern
834     void acceptVisitor( QgsSQLStatement::Visitor &v ) const;
835 
836   protected:
837     QgsSQLStatement::Node *mRootNode = nullptr;
838     bool mAllowFragments = false;
839     QString mStatement;
840     QString mParserErrorString;
841 
842     /**
843      * Constructor for QgsSQLStatement, with the specified \a statement.
844      *
845      * If \a allowFragments is TRUE then the parser will allow SQL fragments,
846      * such as a expression or filter where clause alone.
847      *
848      * \since QGIS 3.16
849      */
850     QgsSQLStatement( const QString &statement, bool allowFragments );
851 };
852 
Q_DECLARE_METATYPE(QgsSQLStatement::Node *)853 Q_DECLARE_METATYPE( QgsSQLStatement::Node * )
854 
855 /**
856  * \ingroup core
857  * \brief Class for parsing fragments of SQL statements, such as an expression or where clause.
858  * \since QGIS 3.16
859 */
860 class CORE_EXPORT QgsSQLStatementFragment : public QgsSQLStatement
861 {
862   public:
863 
864     /**
865      * Constructor for QgsSQLStatementFragment of the specified \a fragment.
866      */
867     QgsSQLStatementFragment( const QString &fragment );
868 
869 };
870 
871 
872 #endif // QGSSQLSTATEMENT_H
873