KDb

KDbExpression.h
1 /* This file is part of the KDE project
2  Copyright (C) 2003-2015 Jarosław Staniek <[email protected]>
3  Copyright (C) 2014 Radoslaw Wicik <[email protected]>
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
36 KDB_EXPORT QString expressionClassName(KDb::ExpressionClass c);
37 
39 class KDbConstExpression;
41 class KDbNArgExpression;
42 class KDbParseInfo;
46 class KDbToken;
47 class KDbUnaryExpression;
49 
50 //! The KDbExpression class represents a base class for all expressions.
51 class KDB_EXPORT KDbExpression
52 {
53 public:
54  /*! Constructs a null expression.
55  @see KDbExpression::isNull() */
56  KDbExpression();
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 
163 protected:
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.
212 class KDB_EXPORT KDbNArgExpression : public KDbExpression
213 {
214 public:
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 
287 protected:
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  */
300 class KDB_EXPORT KDbUnaryExpression : public KDbExpression
301 {
302 public:
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 
322 protected:
323  explicit KDbUnaryExpression(KDbExpressionData* data);
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 */
340 class KDB_EXPORT KDbBinaryExpression : public KDbExpression
341 {
342 public:
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 
365 protected:
366  explicit KDbBinaryExpression(KDbExpressionData* data);
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 */
386 class KDB_EXPORT KDbConstExpression : public KDbExpression
387 {
388 public:
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 
406 protected:
407  //! Internal, used by KDbQueryParameterExpression(const QString& message).
409  explicit KDbConstExpression(KDbExpressionData* data);
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 {
421 public:
422  /*! Constructs a null query parameter expression.
423  @see KDbExpression::isNull() */
425 
426  /*! Constructs query parameter expression with message @a 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 
433  ~KDbQueryParameterExpression() override;
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 
444 protected:
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>
452 class KDB_EXPORT KDbVariableExpression : public KDbExpression
453 {
454 public:
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 
490 protected:
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 */
502 class KDB_EXPORT KDbFunctionExpression : public KDbExpression
503 {
504 public:
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 
560 protected:
563 
564  friend class KDbExpression;
565  friend class KDbFunctionExpressionData;
566 };
567 
568 //! Sends information about expression @a expr to debug output @a dbg.
569 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbExpression& expr);
570 
571 #endif
Internal data class used to implement implicitly shared class KDbExpression.
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
A type-safe KDbSQL token It can be used in KDb expressions.
Definition: KDbToken.h:36
The KDbBinaryExpression class represents binary operation.
Internal data class used to implement implicitly shared class KDbBinaryExpression.
The KDbVariableExpression class represents variables such as fieldname or tablename....
Specialized string for escaping.
A single parameter of a query schema.
QDataStream & operator<<(QDataStream &out, const KDateTime &dateTime)
Database driver's abstraction.
Definition: KDbDriver.h:49
The KDbQueryParameterExpression class represents query parameter expression.
The KDbUnaryExpression class represents unary expression (with a single argument).
KDbEscapedString toString(const KDbDriver *driver, KDbQuerySchemaParameterValueListIterator *params=nullptr, KDb::ExpressionCallStack *callStack=nullptr) const
ExplicitlySharedExpressionDataPointer d
ExpressionClass
Classes of expressions.
The KDbNArgExpression class represents a base class N-argument expression.
Meta-data for a field.
Definition: KDbField.h:71
Internal data class used to implement implicitly shared class KDbFunctionExpression.
The KDbConstExpression class represents const expression.
The KDbExpression class represents a base class for all expressions.
Definition: KDbExpression.h:51
The KDbFunctionExpression class represents expression that use functional notation F(x,...
QString message
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jun 25 2022 06:21:33 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.