KDb

KDbExpression.h
1/* This file is part of the KDE project
2 Copyright (C) 2003-2015 Jarosław Staniek <staniek@kde.org>
3 Copyright (C) 2014 Radoslaw Wicik <radoslaw@wicik.pl>
4
5 Design based on nexp.h : Parser module of Python-like language
6 (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl)
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef KDB_EXPRESSION_H
25#define KDB_EXPRESSION_H
26
27#include "KDbField.h"
28#include "KDbEscapedString.h"
29#include "KDbExpressionData.h"
30
31//! Maximum number of arguments in function
32//! Reasonable number, set after https://www.sqlite.org/limits.html#max_function_arg
33#define KDB_MAX_FUNCTION_ARGS 100
34
35//! @return class name of class @a c
36KDB_EXPORT QString expressionClassName(KDb::ExpressionClass c);
37
42class KDbParseInfo;
46class KDbToken;
49
50//! The KDbExpression class represents a base class for all expressions.
51class KDB_EXPORT KDbExpression
52{
53public:
54 /*! Constructs a null expression.
55 @see KDbExpression::isNull() */
57
58 virtual ~KDbExpression();
59
60 //! @return true if this expression is null.
61 //! Equivalent of expressionClass() == KDb::UnknownExpression.
62 //! @note Returns false for expressions of type KDbField::Null (SQL's NULL).
63 bool isNull() const;
64
65 //! Creates a deep (not shallow) copy of the KDbExpression.
66 KDbExpression clone() const;
67
68 /*!
69 @return the token for this expression. Tokens are characters (e.g. '+', '-')
70 or identifiers (e.g. SQL_NULL) of elements used by the KDbSQL parser.
71 By default token is 0.
72 */
73 KDbToken token() const;
74
75 /*! Sets token @a token for this expression. */
76 void setToken(KDbToken token);
77
78 /*!
79 @return class identifier of this expression.
80 Default expressionClass is KDb::UnknownExpression.
81 */
82 KDb::ExpressionClass expressionClass() const;
83
84 /*! Sets expression class @a aClass for this expression. */
85 void setExpressionClass(KDb::ExpressionClass aClass);
86
87 /*! @return type of this expression, based on effect of its evaluation.
88 Default type is KDbField::InvalidType. @see isValid() */
89 KDbField::Type type() const;
90
91 //! @return true if type of this object is not KDbField::InvalidType.
92 /*! A covenience method. @see type() */
93 bool isValid() const;
94
95 //! @return true if type of this object belong to a group of text types.
96 /*! A covenience method. @see type() */
97 bool isTextType() const;
98
99 //! \return true if type of this object belong to a group of integer types.
100 /*! A covenience method. @see type() */
101 bool isIntegerType() const;
102
103 //! @return true if type of this object belong to a group of numeric types.
104 /*! A covenience method. @see type() */
105 bool isNumericType() const;
106
107 //! @return true if type of this object belong to a group of floating-point numeric types.
108 /*! A covenience method. @see type() */
109 bool isFPNumericType() const;
110
111 //! @return true if type of this object belong to a group of time, date and date/time types.
112 /*! A covenience method. @see type() */
113 bool isDateTimeType() const;
114
115 /*! @return true if evaluation of this expression succeeded. */
116 bool validate(KDbParseInfo *parseInfo);
117
118 /*! @return string as a representation of this expression element
119 by running recursive calls.
120 @a param, if not 0, points to a list item containing value
121 of a query parameter (used in QueryParameterExpr).
122 The result may depend on the optional @a driver parameter.
123 If @a driver is 0, representation for portable KDbSQL dialect is returned. */
124 KDbEscapedString toString(const KDbDriver *driver,
126 KDb::ExpressionCallStack *callStack = nullptr) const;
127
128 /*! Collects query parameters (messages and types) recursively and saves them to @a params.
129 The leaf nodes are objects of QueryParameterExpr class.
130 @note @a params must not be 0. */
131 void getQueryParameters(QList<KDbQuerySchemaParameter>* params);
132
133 //! @return expression class for token @a token.
134 //! @todo support more tokens
135 static KDb::ExpressionClass classForToken(KDbToken token);
136
137 //! Convenience type casts.
138 KDbNArgExpression toNArg() const;
139 KDbUnaryExpression toUnary() const;
140 KDbBinaryExpression toBinary() const;
141 KDbConstExpression toConst() const;
142 KDbVariableExpression toVariable() const;
143 KDbFunctionExpression toFunction() const;
144 KDbQueryParameterExpression toQueryParameter() const;
145
146 bool isNArg() const;
147 bool isUnary() const;
148 bool isBinary() const;
149 bool isConst() const;
150 bool isVariable() const;
151 bool isFunction() const;
152 bool isQueryParameter() const;
153
154 QDebug debug(QDebug dbg, KDb::ExpressionCallStack* callStack) const;
155
156 bool operator==(const KDbExpression& e) const;
157
158 bool operator!=(const KDbExpression& e) const;
159
160 /*! @return the parent expression. */
161 KDbExpression parent() const;
162
163protected:
164 /*! @return the list of children expressions. */
166
167 void appendChild(const KDbExpression& child);
168
169 void prependChild(const KDbExpression& child);
170
171 KDbExpression takeChild(int i);
172
173 bool removeChild(const KDbExpression& child);
174
175 void removeChild(int i);
176
177 void insertChild(int i, const KDbExpression& child);
178
179 //! Used for inserting placeholders, e.g. in KDbBinaryExpression::KDbBinaryExpression()
180 void insertEmptyChild(int i);
181
182 void appendChild(const ExplicitlySharedExpressionDataPointer& child);
183
184 int indexOfChild(const KDbExpression& child, int from = 0) const;
185
186 int lastIndexOfChild(const KDbExpression& child, int from = -1) const;
187
188 bool checkBeforeInsert(const ExplicitlySharedExpressionDataPointer& child);
189
190 //! Only for KDbBinaryExpression::setLeft() and KDbBinaryExpression::setRight()
191 void setLeftOrRight(const KDbExpression& right, int index);
192
193 explicit KDbExpression(KDbExpressionData* data);
194
196
198
199 //! @internal
201
202 friend class KDbNArgExpression;
203 friend class KDbUnaryExpression;
204 friend class KDbBinaryExpression;
205 friend class KDbConstExpression;
206 friend class KDbQueryParameterExpression;
207 friend class KDbVariableExpression;
208 friend class KDbFunctionExpression;
209};
210
211//! The KDbNArgExpression class represents a base class N-argument expression.
212class KDB_EXPORT KDbNArgExpression : public KDbExpression
213{
214public:
215 /*! Constructs a null N-argument expression.
216 @see KDbExpression::isNull() */
218
219 //! Constructs an N-argument expression of class @a aClass and token @a token.
221
222 /*! Constructs a copy of other N-argument expression @a expr.
223 Resulting object is not a deep copy but rather a reference to the object @a expr. */
225
226 //! Destroys the expression.
227 ~KDbNArgExpression() override;
228
229 //! Inserts expression argument @a expr at the end of this expression.
230 void append(const KDbExpression& expr);
231
232 //! Inserts expression argument @a expr at the beginning of this expression.
233 void prepend(const KDbExpression& expr);
234
235 /*! Inserts expression argument @a expr at index position @a i in this expression.
236 If @a i is 0, the expression is prepended to the list of arguments.
237 If @a i is argCount(), the value is appended to the list of arguments.
238 @a i must be a valid index position in the list (i.e., 0 <= i < argCount()). */
239 void insert(int i, const KDbExpression& expr);
240
241 //! Replaces expression argument at index @a i with expression @a expr.
242 //! @a i must be a valid index position in the list (i.e., 0 <= i < argCount()). */
243 void replace(int i, const KDbExpression& expr);
244
245 /*! Removes the expression argument @a expr and returns true on success;
246 otherwise returns false. */
247 bool remove(const KDbExpression& expr);
248
249 /*! Removes the expression at index position @a i.
250 @a i must be a valid index position in the list (i.e., 0 <= i < argCount()). */
251 void removeAt(int i);
252
253 /*! Removes the expression at index position @a i and returns it.
254 @a i must be a valid index position in the list (i.e., 0 <= i < argCount()).
255 If you don't use the return value, removeAt() is more efficient. */
256 KDbExpression takeAt(int i);
257
258 /*! @return the index position of the first occurrence of expression argument
259 @a expr in this expression, searching forward from index position @a from.
260 @return -1 if no argument matched.
261 @see lastIndexOf() */
262 int indexOf(const KDbExpression& expr, int from = 0) const;
263
264 /*! @return the index position of the last occurrence of expression argument
265 @a expr in this expression, searching backward from index position @a from.
266 If from is -1 (the default), the search starts at the last item.
267 Returns -1 if no argument matched.
268 @see indexOf() */
269 int lastIndexOf(const KDbExpression& expr, int from = -1) const;
270
271 //! @return expression index @a i in the list of arguments.
272 //! If the index @a i is out of bounds, the function returns null expression.
273 KDbExpression arg(int i) const;
274
275 //! @return the number of expression arguments in this expression.
276 int argCount() const;
277
278 //! @return true if the expression contains no arguments; otherwise returns false.
279 bool isEmpty() const;
280
281 //! @return true if any argument is invalid (!KDbExpression::isValid()).
282 bool containsInvalidArgument() const;
283
284 //! @return true if any argument is NULL (type KDbField::Null).
285 bool containsNullArgument() const;
286
287protected:
288 explicit KDbNArgExpression(KDbExpressionData* data);
289
291
292 friend class KDbExpression;
293 friend class KDbFunctionExpression;
294 friend class KDbFunctionExpressionData;
295};
296
297//! The KDbUnaryExpression class represents unary expression (with a single argument).
298/*! operation: + - NOT (or !) ~ "IS NULL" "IS NOT NULL"
299 */
300class KDB_EXPORT KDbUnaryExpression : public KDbExpression
301{
302public:
303 /*! Constructs a null unary expression.
304 @see KDbExpression::isNull() */
306
307 //! Constructs unary expression with token @a token and argument @a arg.
308 KDbUnaryExpression(KDbToken token, const KDbExpression& arg);
309
310 /*! Constructs a copy of other unary expression @a expr.
311 Resulting object is not a deep copy but rather a reference to the object @a expr. */
313
314 ~KDbUnaryExpression() override;
315
316 //! @return expression that is argument for this unary expression
317 KDbExpression arg() const;
318
319 //! Sets expression argument @a expr for this unary expression.
320 void setArg(const KDbExpression &arg);
321
322protected:
324
326
327 friend class KDbExpression;
328};
329
330//! The KDbBinaryExpression class represents binary operation.
331/*
332 - arithmetic operations: + - / * % << >> & | ||
333 - relational operations: = (or ==) < > <= >= <> (or !=) LIKE 'NOT LIKE' IN 'SIMILAR TO'
334 'NOT SIMILAR TO'
335 - logical operations: OR (or ||) AND (or &&) XOR
336 - SpecialBinary "pseudo operators":
337 * e.g. "f1 f2" : token == 0
338 * e.g. "f1 AS f2" : token == AS
339*/
340class KDB_EXPORT KDbBinaryExpression : public KDbExpression
341{
342public:
343 /*! Constructs a null binary expression.
344 @see KDbExpression::isNull() */
346
347 /*! Constructs binary expression with left expression @a leftExpr,
348 token @a token, and right expression @a rightExpr. */
349 KDbBinaryExpression(const KDbExpression& leftExpr, KDbToken token, const KDbExpression& rightExpr);
350
351 /*! Constructs a copy of other unary expression @a expr.
352 Resulting object is not a deep copy but rather a reference to the object @a expr. */
354
355 ~KDbBinaryExpression() override;
356
357 KDbExpression left() const;
358
359 void setLeft(const KDbExpression& leftExpr);
360
361 KDbExpression right() const;
362
363 void setRight(const KDbExpression& rightExpr);
364
365protected:
367
369
370 friend class KDbExpression;
371 friend class KDbBinaryExpressionData;
372};
373
374
375//! The KDbConstExpression class represents const expression.
376/*! Types are string, integer, float constants. Also includes NULL value.
377 Token can be: IDENTIFIER, SQL_NULL, SQL_TRUE, SQL_FALSE, CHARACTER_STRING_LITERAL,
378 INTEGER_CONST, REAL_CONST, DATE_CONST, DATETIME_CONST, TIME_CONST.
379
380 @note For REAL_CONST accepted values can be of type qreal, double and QPoint.
381 In the case of QPoint, integer value (with a sign) is stored in QPoint::x
382 and the fraction part (that should be always positive) is stored in QPoint::y.
383 This gives 31 bits for the integer part (10 decimal digits) and 31 bits for the part
384 (10 decimal digits).
385*/
386class KDB_EXPORT KDbConstExpression : public KDbExpression
387{
388public:
389 /*! Constructs a null const expression.
390 @see KDbExpression::isNull() */
392
393 /*! Constructs const expression token @a token and value @a value. */
394 KDbConstExpression(KDbToken token, const QVariant& value);
395
396 /*! Constructs a copy of other const expression @a expr.
397 Resulting object is not a deep copy but rather a reference to the object @a expr. */
399
400 ~KDbConstExpression() override;
401
402 QVariant value() const;
403
404 void setValue(const QVariant& value);
405
406protected:
407 //! Internal, used by KDbQueryParameterExpression(const QString& message).
411
412 friend class KDbExpression;
413};
414
415//! The KDbQueryParameterExpression class represents query parameter expression.
416/*! Query parameter is used to getting user input of constant values.
417 It contains a message that is displayed to the user.
418*/
420{
421public:
422 /*! Constructs a null query parameter expression.
423 @see KDbExpression::isNull() */
425
426 /*! Constructs query parameter expression with message @a message. */
427 explicit KDbQueryParameterExpression(const QString& message);
428
429 /*! Constructs a copy of other query parameter expression @a expr.
430 Resulting object is not a deep copy but rather a reference to the object @a expr. */
432
434
435 /*! Sets expected type of the parameter. The default is String.
436 This method is called from parent's expression validate().
437 This depends on the type of the related expression.
438 For instance: query "SELECT * FROM cars WHERE name=[enter name]",
439 "[enter name]" has parameter of the same type as "name" field.
440 "=" binary expression's validate() will be called for the left side
441 of the expression and then the right side will have type set to String. */
442 void setType(KDbField::Type type);
443
444protected:
447
448 friend class KDbExpression;
449};
450
451//! The KDbVariableExpression class represents variables such as <i>fieldname</i> or <i>tablename</i>.<i>fieldname</i>
452class KDB_EXPORT KDbVariableExpression : public KDbExpression
453{
454public:
455 /*! Constructs a null variable expression.
456 @see KDbExpression::isNull() */
458
459 /*! Constructs variable expression with name @a name. */
460 explicit KDbVariableExpression(const QString& name);
461
462 /*! Constructs a copy of other variable expression @a expr.
463 Resulting object is not a deep copy but rather a reference to the object @a expr. */
465
466 ~KDbVariableExpression() override;
467
468 /*! Verbatim name as returned by scanner. */
469 QString name() const;
470
471 /*! 0 by default. After successful validate() it returns a field,
472 if the variable is of a form "tablename.fieldname" or "fieldname",
473 otherwise (eg. for asterisks) still 0.
474 Only meaningful for column expressions within a query. */
475 KDbField *field() const;
476
477 /*! -1 by default. After successful validate() it returns a position of a table
478 within query that needs to be bound to the field.
479 This value can be either be -1 if no binding is needed.
480 This value is used in the Parser to call
481 KDbQuerySchema::addField(KDbField* field, int bindToTable);
482 Only meaningful for column expressions within a query. */
483 int tablePositionForField() const;
484
485 /*! @c nullptr by default. After successful validate() it returns table that
486 is referenced by asterisk, i.e. "*.tablename".
487 It is @c nullptr if this variable is not an asterisk of that form. */
488 KDbTableSchema *tableForQueryAsterisk() const;
489
490protected:
493
494 friend class KDbExpression;
495};
496
497//! The KDbFunctionExpression class represents expression that use functional notation F(x, ...)
498/*! The functions list include:
499 - aggregation functions like SUM, COUNT, MAX, ...
500 - builtin functions like CURRENT_TIME()
501 - user defined functions */
502class KDB_EXPORT KDbFunctionExpression : public KDbExpression
503{
504public:
505 /*! Constructs a null function expression.
506 @see KDbExpression::isNull() */
508
509 /*! Constructs function expression with name @a name, without arguments. */
510 explicit KDbFunctionExpression(const QString& name);
511
512 /*! Constructs function expression with name @a name and arguments @a arguments. */
513 KDbFunctionExpression(const QString& name, const KDbNArgExpression &arguments);
514
515 /*! Constructs a copy of other function expression @a expr.
516 Resulting object is not a deep copy but rather a reference to the object @a expr. */
518
519 ~KDbFunctionExpression() override;
520
521 //! @return name of the function.
522 QString name() const;
523
524 //! Sets name of the function to @a name.
525 void setName(const QString &name);
526
527 //! @return list of arguments of the function.
528 KDbNArgExpression arguments();
529
530 //! Sets the list of arguments to @a arguments.
531 void setArguments(const KDbNArgExpression &arguments);
532
533 static QStringList builtInAggregates();
534
535 static bool isBuiltInAggregate(const QString& function);
536
538
539 /*! Constructs function expression with name @a name and args @a args. */
540 static KDbEscapedString toString(const QString &name, const KDbDriver *driver,
541 const KDbNArgExpression &args,
543 KDb::ExpressionCallStack* callStack);
544
545 //! @return a native (driver-specific) GREATEST() and LEAST() function calls generated
546 //! to string using CASE WHEN... keywords.
547 //! This is a workaround for cases when LEAST()/GREATEST() function ignores
548 //! NULL values and only returns NULL if all the expressions evaluate to NULL.
549 //! Instead of using F(v0,..,vN), this is used:
550 //! (CASE WHEN (v0) IS NULL OR .. OR (vN) IS NULL THEN NULL ELSE F(v0,..,vN) END)
551 //! where F == GREATEST or LEAST.
552 //! Actually it is needed by MySQL < 5.0.13 and PostgreSQL.
553 static KDbEscapedString greatestOrLeastFunctionUsingCaseToString(
554 const QString &name,
555 const KDbDriver *driver,
556 const KDbNArgExpression &args,
558 KDb::ExpressionCallStack* callStack);
559
560protected:
563
564 friend class KDbExpression;
565 friend class KDbFunctionExpressionData;
566};
567
568//! Sends information about expression @a expr to debug output @a dbg.
569KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbExpression& expr);
570
571#endif
Internal data class used to implement implicitly shared class KDbBinaryExpression.
The KDbBinaryExpression class represents binary operation.
The KDbConstExpression class represents const expression.
Database driver's abstraction.
Definition KDbDriver.h:50
Specialized string for escaping.
Internal data class used to implement implicitly shared class KDbExpression.
The KDbExpression class represents a base class for all expressions.
KDbEscapedString toString(const KDbDriver *driver, KDbQuerySchemaParameterValueListIterator *params=nullptr, KDb::ExpressionCallStack *callStack=nullptr) const
ExplicitlySharedExpressionDataPointer d
Meta-data for a field.
Definition KDbField.h:72
Internal data class used to implement implicitly shared class KDbFunctionExpression.
The KDbFunctionExpression class represents expression that use functional notation F(x,...
The KDbNArgExpression class represents a base class N-argument expression.
The KDbQueryParameterExpression class represents query parameter expression.
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
A single parameter of a query schema.
A type-safe KDbSQL token It can be used in KDb expressions.
Definition KDbToken.h:37
The KDbUnaryExpression class represents unary expression (with a single argument).
The KDbVariableExpression class represents variables such as fieldname or tablename....
ExpressionClass
Classes of expressions.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:47:36 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.