QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgssqlexpressioncompiler.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssqlexpressioncompiler.cpp
3  ----------------------------
4  begin : November 2015
5  copyright : (C) 2015 Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgsexpressionnodeimpl.h"
18 #include "qgsexpressionfunction.h"
19 #include "qgsexpression.h"
20 
22  : mResult( None )
23  , mFields( fields )
24  , mFlags( flags )
25 {
26 }
27 
29 {
30  if ( exp->rootNode() )
31  return compileNode( exp->rootNode(), mResult );
32  else
33  return Fail;
34 }
35 
37 {
38  return mResult;
39 }
40 
42 {
43  if ( op == QgsExpressionNodeBinaryOperator::BinaryOperator::boILike ||
44  op == QgsExpressionNodeBinaryOperator::BinaryOperator::boLike ||
45  op == QgsExpressionNodeBinaryOperator::BinaryOperator::boNotILike ||
46  op == QgsExpressionNodeBinaryOperator::BinaryOperator::boNotLike ||
47  op == QgsExpressionNodeBinaryOperator::BinaryOperator::boRegexp )
48  return true;
49  else
50  return false;
51 }
52 
53 QString QgsSqlExpressionCompiler::quotedIdentifier( const QString &identifier )
54 {
55  QString quoted = identifier;
56  quoted.replace( '"', QLatin1String( "\"\"" ) );
57  quoted = quoted.prepend( '\"' ).append( '\"' );
58  return quoted;
59 }
60 
61 QString QgsSqlExpressionCompiler::quotedValue( const QVariant &value, bool &ok )
62 {
63  ok = true;
64 
65  if ( value.isNull() )
66  return QStringLiteral( "NULL" );
67 
68  switch ( value.type() )
69  {
70  case QVariant::Int:
71  case QVariant::LongLong:
72  case QVariant::Double:
73  return value.toString();
74 
75  case QVariant::Bool:
76  return value.toBool() ? QStringLiteral( "TRUE" ) : QStringLiteral( "FALSE" );
77 
78  default:
79  case QVariant::String:
80  QString v = value.toString();
81  v.replace( '\'', QLatin1String( "''" ) );
82  if ( v.contains( '\\' ) )
83  return v.replace( '\\', QLatin1String( "\\\\" ) ).prepend( "E'" ).append( '\'' );
84  else
85  return v.prepend( '\'' ).append( '\'' );
86  }
87 }
88 
90 {
91  switch ( node->nodeType() )
92  {
94  {
95  const QgsExpressionNodeUnaryOperator *n = static_cast<const QgsExpressionNodeUnaryOperator *>( node );
96  switch ( n->op() )
97  {
99  {
100  QString right;
101  if ( compileNode( n->operand(), right ) == Complete )
102  {
103  result = "( NOT " + right + ')';
104  return Complete;
105  }
106 
107  return Fail;
108  }
109 
111  {
112  if ( mFlags.testFlag( NoUnaryMinus ) )
113  return Fail;
114 
115  QString right;
116  if ( compileNode( n->operand(), right ) == Complete )
117  {
118  result = "( - (" + right + "))";
119  return Complete;
120  }
121 
122  return Fail;
123  }
124  }
125 
126  break;
127  }
128 
130  {
131  const QgsExpressionNodeBinaryOperator *n = static_cast<const QgsExpressionNodeBinaryOperator *>( node );
132 
133  QString op;
134  bool partialCompilation = false;
135  bool failOnPartialNode = false;
136  switch ( n->op() )
137  {
140  {
141  // equality between column refs results in a partial compilation, since provider is performing
142  // case-insensitive matches between strings
143  partialCompilation = true;
144  }
145 
146  op = QStringLiteral( "=" );
147  break;
148 
150  op = QStringLiteral( ">=" );
151  break;
152 
154  op = QStringLiteral( ">" );
155  break;
156 
158  op = QStringLiteral( "<=" );
159  break;
160 
162  op = QStringLiteral( "<" );
163  break;
164 
166  op = QStringLiteral( "IS" );
167  break;
168 
170  op = QStringLiteral( "IS NOT" );
171  failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
172  break;
173 
175  op = QStringLiteral( "LIKE" );
176  partialCompilation = mFlags.testFlag( LikeIsCaseInsensitive );
177  break;
178 
180  if ( mFlags.testFlag( LikeIsCaseInsensitive ) )
181  op = QStringLiteral( "LIKE" );
182  else
183  op = QStringLiteral( "ILIKE" );
184  break;
185 
187  op = QStringLiteral( "NOT LIKE" );
188  partialCompilation = mFlags.testFlag( LikeIsCaseInsensitive );
189  failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
190  break;
191 
193  failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
194  if ( mFlags.testFlag( LikeIsCaseInsensitive ) )
195  op = QStringLiteral( "NOT LIKE" );
196  else
197  op = QStringLiteral( "NOT ILIKE" );
198  break;
199 
201  if ( mFlags.testFlag( NoNullInBooleanLogic ) )
202  {
203  if ( nodeIsNullLiteral( n->opLeft() ) || nodeIsNullLiteral( n->opRight() ) )
204  return Fail;
205  }
206 
207  op = QStringLiteral( "OR" );
208  break;
209 
211  if ( mFlags.testFlag( NoNullInBooleanLogic ) )
212  {
213  if ( nodeIsNullLiteral( n->opLeft() ) || nodeIsNullLiteral( n->opRight() ) )
214  return Fail;
215  }
216 
217  op = QStringLiteral( "AND" );
218  break;
219 
221  failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
222  op = QStringLiteral( "<>" );
223  break;
224 
226  op = QStringLiteral( "*" );
227  break;
228 
230  op = QStringLiteral( "+" );
231  break;
232 
234  op = QStringLiteral( "-" );
235  break;
236 
238  op = QStringLiteral( "/" );
239  break;
240 
242  op = QStringLiteral( "%" );
243  break;
244 
246  op = QStringLiteral( "||" );
247  break;
248 
250  op = QStringLiteral( "/" );
251  break;
252 
254  op = QStringLiteral( "^" );
255  break;
256 
258  op = QStringLiteral( "~" );
259  break;
260  }
261 
262  if ( op.isNull() )
263  return Fail;
264 
265  QString left;
266  Result lr( compileNode( n->opLeft(), left ) );
267 
268  if ( opIsStringComparison( n ->op() ) )
269  left = castToText( left );
270 
271  QString right;
272  Result rr( compileNode( n->opRight(), right ) );
273 
274  if ( failOnPartialNode && ( lr == Partial || rr == Partial ) )
275  return Fail;
276 
278  {
279  right = castToReal( right );
280  if ( right.isEmpty() )
281  {
282  // not supported
283  return Fail;
284  }
285  }
286 
287  result = '(' + left + ' ' + op + ' ' + right + ')';
289  {
290  result = castToInt( result );
291  if ( result.isEmpty() )
292  {
293  // not supported
294  return Fail;
295  }
296  }
297 
298  if ( lr == Complete && rr == Complete )
299  return ( partialCompilation ? Partial : Complete );
300  else if ( ( lr == Partial && rr == Complete ) || ( lr == Complete && rr == Partial ) || ( lr == Partial && rr == Partial ) )
301  return Partial;
302  else
303  return Fail;
304  }
305 
307  {
308  const QgsExpressionNodeLiteral *n = static_cast<const QgsExpressionNodeLiteral *>( node );
309  bool ok = false;
310  if ( mFlags.testFlag( CaseInsensitiveStringMatch ) && n->value().type() == QVariant::String )
311  {
312  // provider uses case insensitive matching, so if literal was a string then we only have a Partial compilation and need to
313  // double check results using QGIS' expression engine
314  result = quotedValue( n->value(), ok );
315  return ok ? Partial : Fail;
316  }
317  else
318  {
319  result = quotedValue( n->value(), ok );
320  return ok ? Complete : Fail;
321  }
322  }
323 
325  {
326  const QgsExpressionNodeColumnRef *n = static_cast<const QgsExpressionNodeColumnRef *>( node );
327 
328  if ( mFields.indexFromName( n->name() ) == -1 )
329  // Not a provider field
330  return Fail;
331 
332  result = quotedIdentifier( n->name() );
333 
334  return Complete;
335  }
336 
338  {
339  const QgsExpressionNodeInOperator *n = static_cast<const QgsExpressionNodeInOperator *>( node );
340  QStringList list;
341 
342  Result inResult = Complete;
343  const auto constList = n->list()->list();
344  for ( const QgsExpressionNode *ln : constList )
345  {
346  QString s;
347  Result r = compileNode( ln, s );
348  if ( r == Complete || r == Partial )
349  {
350  list << s;
351  if ( r == Partial )
352  inResult = Partial;
353  }
354  else
355  return r;
356  }
357 
358  QString nd;
359  Result rn = compileNode( n->node(), nd );
360  if ( rn != Complete && rn != Partial )
361  return rn;
362 
363  result = QStringLiteral( "%1 %2IN (%3)" ).arg( nd, n->isNotIn() ? QStringLiteral( "NOT " ) : QString(), list.join( ',' ) );
364  return ( inResult == Partial || rn == Partial ) ? Partial : Complete;
365  }
366 
368  {
369  const QgsExpressionNodeFunction *n = static_cast<const QgsExpressionNodeFunction *>( node );
371 
372  // get sql function to compile node expression
373  QString nd = sqlFunctionFromFunctionName( fd->name() );
374  // if no sql function the node can't be compiled
375  if ( nd.isNull() )
376  return Fail;
377 
378  // compile arguments
379  QStringList args;
380  Result inResult = Complete;
381  const auto constList = n->args()->list();
382  for ( const QgsExpressionNode *ln : constList )
383  {
384  QString s;
385  Result r = compileNode( ln, s );
386  if ( r == Complete || r == Partial )
387  {
388  args << s;
389  if ( r == Partial )
390  inResult = Partial;
391  }
392  else
393  return r;
394  }
395 
396  // update arguments to be adapted to SQL function
397  args = sqlArgumentsFromFunctionName( fd->name(), args );
398 
399  // build result
400  result = !nd.isEmpty() ? QStringLiteral( "%1(%2)" ).arg( nd, args.join( ',' ) ) : args.join( ',' );
401  return inResult == Partial ? Partial : Complete;
402  }
403 
405  break;
406 
408  break;
409  }
410 
411  return Fail;
412 }
413 
414 QString QgsSqlExpressionCompiler::sqlFunctionFromFunctionName( const QString &fnName ) const
415 {
416  Q_UNUSED( fnName )
417  return QString();
418 }
419 
420 QStringList QgsSqlExpressionCompiler::sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const
421 {
422  Q_UNUSED( fnName )
423  return QStringList( fnArgs );
424 }
425 
426 QString QgsSqlExpressionCompiler::castToReal( const QString &value ) const
427 {
428  Q_UNUSED( value )
429  return QString();
430 }
431 
432 QString QgsSqlExpressionCompiler::castToText( const QString &value ) const
433 {
434  return value;
435 }
436 
437 QString QgsSqlExpressionCompiler::castToInt( const QString &value ) const
438 {
439  Q_UNUSED( value )
440  return QString();
441 }
442 
443 bool QgsSqlExpressionCompiler::nodeIsNullLiteral( const QgsExpressionNode *node ) const
444 {
445  if ( node->nodeType() != QgsExpressionNode::ntLiteral )
446  return false;
447 
448  const QgsExpressionNodeLiteral *nLit = static_cast<const QgsExpressionNodeLiteral *>( node );
449  return nLit->value().isNull();
450 }
QgsExpressionNodeBinaryOperator::op
QgsExpressionNodeBinaryOperator::BinaryOperator op() const
Returns the binary operator.
Definition: qgsexpressionnodeimpl.h:146
QgsSqlExpressionCompiler::LikeIsCaseInsensitive
@ LikeIsCaseInsensitive
Provider treats LIKE as case-insensitive.
Definition: qgssqlexpressioncompiler.h:59
QgsExpressionNodeBinaryOperator::boILike
@ boILike
Definition: qgsexpressionnodeimpl.h:115
QgsExpressionNodeBinaryOperator::boPlus
@ boPlus
Definition: qgsexpressionnodeimpl.h:121
QgsExpressionNodeLiteral
An expression node for literal values.
Definition: qgsexpressionnodeimpl.h:365
QgsExpressionNodeBinaryOperator
A binary expression operator, which operates on two values.
Definition: qgsexpressionnodeimpl.h:92
QgsExpressionNodeInOperator::node
QgsExpressionNode * node() const
Returns the expression node.
Definition: qgsexpressionnodeimpl.h:281
QgsExpressionNodeBinaryOperator::boRegexp
@ boRegexp
Definition: qgsexpressionnodeimpl.h:112
QgsSqlExpressionCompiler::QgsSqlExpressionCompiler
QgsSqlExpressionCompiler(const QgsFields &fields, QgsSqlExpressionCompiler::Flags flags=Flags())
Constructor for expression compiler.
Definition: qgssqlexpressioncompiler.cpp:21
QgsExpressionNodeBinaryOperator::boLE
@ boLE
<=
Definition: qgsexpressionnodeimpl.h:108
qgsexpression.h
QgsExpressionNode::ntCondition
@ ntCondition
Definition: qgsexpressionnode.h:82
QgsSqlExpressionCompiler::compileNode
virtual Result compileNode(const QgsExpressionNode *node, QString &str)
Compiles an expression node and returns the result of the compilation.
Definition: qgssqlexpressioncompiler.cpp:89
QgsExpressionNode::ntColumnRef
@ ntColumnRef
Definition: qgsexpressionnode.h:81
QgsSqlExpressionCompiler::result
virtual QString result()
Returns the compiled expression string for use by the provider.
Definition: qgssqlexpressioncompiler.cpp:36
QgsExpressionNodeBinaryOperator::boGE
@ boGE
>=
Definition: qgsexpressionnodeimpl.h:109
QgsSqlExpressionCompiler::mFields
QgsFields mFields
Definition: qgssqlexpressioncompiler.h:177
QgsExpression::rootNode
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
Definition: qgsexpression.cpp:1091
QgsExpressionNodeColumnRef
An expression node which takes it value from a feature's field.
Definition: qgsexpressionnodeimpl.h:401
QgsExpressionNodeLiteral::value
QVariant value() const
The value of the literal.
Definition: qgsexpressionnodeimpl.h:376
QgsExpressionNodeFunction::fnIndex
int fnIndex() const
Returns the index of the node's function.
Definition: qgsexpressionnodeimpl.h:331
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsSqlExpressionCompiler::castToInt
virtual QString castToInt(const QString &value) const
Casts a value to a integer result.
Definition: qgssqlexpressioncompiler.cpp:437
QgsExpressionNodeUnaryOperator
A unary node is either negative as in boolean (not) or as in numbers (minus).
Definition: qgsexpressionnodeimpl.h:28
QgsSqlExpressionCompiler::opIsStringComparison
bool opIsStringComparison(QgsExpressionNodeBinaryOperator::BinaryOperator op)
Returns true if op is one of.
Definition: qgssqlexpressioncompiler.cpp:41
QgsSqlExpressionCompiler::Partial
@ Partial
Expression was partially compiled, but provider will return extra records and results must be double-...
Definition: qgssqlexpressioncompiler.h:49
QgsSqlExpressionCompiler::Complete
@ Complete
Expression was successfully compiled and can be completely delegated to provider.
Definition: qgssqlexpressioncompiler.h:48
QgsSqlExpressionCompiler::CaseInsensitiveStringMatch
@ CaseInsensitiveStringMatch
Provider performs case-insensitive string matching for all strings.
Definition: qgssqlexpressioncompiler.h:58
QgsSqlExpressionCompiler::castToText
virtual QString castToText(const QString &value) const
Casts a value to a text result.
Definition: qgssqlexpressioncompiler.cpp:432
QgsExpressionNodeUnaryOperator::op
QgsExpressionNodeUnaryOperator::UnaryOperator op() const
Returns the unary operator.
Definition: qgsexpressionnodeimpl.h:53
QgsExpressionNodeBinaryOperator::boMod
@ boMod
Definition: qgsexpressionnodeimpl.h:126
QgsSqlExpressionCompiler::quotedValue
virtual QString quotedValue(const QVariant &value, bool &ok)
Returns a quoted attribute value, in the format expected by the provider.
Definition: qgssqlexpressioncompiler.cpp:61
QgsExpressionNodeInOperator
An expression node for value IN or NOT IN clauses.
Definition: qgsexpressionnodeimpl.h:265
QgsSqlExpressionCompiler::sqlFunctionFromFunctionName
virtual QString sqlFunctionFromFunctionName(const QString &fnName) const
Returns the SQL function for the expression function.
Definition: qgssqlexpressioncompiler.cpp:414
QgsExpressionNodeBinaryOperator::boMinus
@ boMinus
Definition: qgsexpressionnodeimpl.h:122
QgsExpressionNode::ntFunction
@ ntFunction
Definition: qgsexpressionnode.h:79
QgsExpressionNodeBinaryOperator::boPow
@ boPow
Definition: qgsexpressionnodeimpl.h:127
QgsExpressionNodeFunction::args
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
Definition: qgsexpressionnodeimpl.h:336
QgsExpressionNodeBinaryOperator::boConcat
@ boConcat
Definition: qgsexpressionnodeimpl.h:130
QgsSqlExpressionCompiler::IntegerDivisionResultsInInteger
@ IntegerDivisionResultsInInteger
Dividing int by int results in int on provider. Subclass must implement the castToReal() function to ...
Definition: qgssqlexpressioncompiler.h:62
QgsExpressionNodeBinaryOperator::boLT
@ boLT
<
Definition: qgsexpressionnodeimpl.h:110
QgsExpressionNodeBinaryOperator::boNotILike
@ boNotILike
Definition: qgsexpressionnodeimpl.h:116
qgsexpressionfunction.h
QgsExpressionNodeUnaryOperator::operand
QgsExpressionNode * operand() const
Returns the node the operator will operate upon.
Definition: qgsexpressionnodeimpl.h:58
QgsSqlExpressionCompiler::Fail
@ Fail
Provider cannot handle expression.
Definition: qgssqlexpressioncompiler.h:50
QgsExpressionNode::ntBinaryOperator
@ ntBinaryOperator
Definition: qgsexpressionnode.h:77
QgsExpressionNodeFunction
An expression node for expression functions.
Definition: qgsexpressionnodeimpl.h:317
QgsExpressionNodeBinaryOperator::boNE
@ boNE
<>
Definition: qgsexpressionnodeimpl.h:107
QgsExpressionNode::ntLiteral
@ ntLiteral
Definition: qgsexpressionnode.h:80
QgsExpression::Functions
static const QList< QgsExpressionFunction * > & Functions()
Definition: qgsexpressionfunction.cpp:6008
QgsExpressionNodeBinaryOperator::boIsNot
@ boIsNot
Definition: qgsexpressionnodeimpl.h:118
QgsExpressionNodeBinaryOperator::boLike
@ boLike
Definition: qgsexpressionnodeimpl.h:113
QgsExpressionNodeUnaryOperator::uoNot
@ uoNot
Definition: qgsexpressionnodeimpl.h:37
QgsExpressionNodeBinaryOperator::boNotLike
@ boNotLike
Definition: qgsexpressionnodeimpl.h:114
QgsExpressionNode::NodeList::list
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
Definition: qgsexpressionnode.h:144
QgsExpressionNode
Abstract base class for all nodes that can appear in an expression.
Definition: qgsexpressionnode.h:35
QgsExpressionNodeBinaryOperator::boEQ
@ boEQ
=
Definition: qgsexpressionnodeimpl.h:106
QgsExpressionNodeBinaryOperator::boIntDiv
@ boIntDiv
Definition: qgsexpressionnodeimpl.h:125
QgsExpressionNodeBinaryOperator::boIs
@ boIs
Definition: qgsexpressionnodeimpl.h:117
QgsExpressionNodeBinaryOperator::boGT
@ boGT
Definition: qgsexpressionnodeimpl.h:111
QgsExpressionNodeInOperator::isNotIn
bool isNotIn() const
Returns true if this node is a "NOT IN" operator, or false if the node is a normal "IN" operator.
Definition: qgsexpressionnodeimpl.h:286
qgsexpressionnodeimpl.h
QgsExpressionNodeColumnRef::name
QString name() const
The name of the column.
Definition: qgsexpressionnodeimpl.h:414
QgsExpressionNodeUnaryOperator::uoMinus
@ uoMinus
Definition: qgsexpressionnodeimpl.h:38
QgsExpressionFunction
A abstract base class for defining QgsExpression functions.
Definition: qgsexpressionfunction.h:41
QgsExpressionNode::ntUnaryOperator
@ ntUnaryOperator
Definition: qgsexpressionnode.h:76
QgsExpressionNodeBinaryOperator::opLeft
QgsExpressionNode * opLeft() const
Returns the node to the left of the operator.
Definition: qgsexpressionnodeimpl.h:152
qgssqlexpressioncompiler.h
QgsExpressionFunction::name
QString name() const
The name of the function.
Definition: qgsexpressionfunction.h:190
QgsSqlExpressionCompiler::mResult
QString mResult
Definition: qgssqlexpressioncompiler.h:176
QgsSqlExpressionCompiler::NoNullInBooleanLogic
@ NoNullInBooleanLogic
Provider does not support using NULL with boolean logic, e.g., "(...) OR NULL".
Definition: qgssqlexpressioncompiler.h:60
QgsExpressionNodeBinaryOperator::boDiv
@ boDiv
Definition: qgsexpressionnodeimpl.h:124
QgsSqlExpressionCompiler::castToReal
virtual QString castToReal(const QString &value) const
Casts a value to a real result.
Definition: qgssqlexpressioncompiler.cpp:426
QgsSqlExpressionCompiler::compile
virtual Result compile(const QgsExpression *exp)
Compiles an expression and returns the result of the compilation.
Definition: qgssqlexpressioncompiler.cpp:28
QgsExpressionNodeInOperator::list
QgsExpressionNode::NodeList * list() const
Returns the list of nodes to search for matching values within.
Definition: qgsexpressionnodeimpl.h:291
QgsSqlExpressionCompiler::NoUnaryMinus
@ NoUnaryMinus
Provider does not unary minus, e.g., " -( 100 * 2 ) = ...".
Definition: qgssqlexpressioncompiler.h:61
QgsExpressionNodeBinaryOperator::opRight
QgsExpressionNode * opRight() const
Returns the node to the right of the operator.
Definition: qgsexpressionnodeimpl.h:158
QgsExpressionNodeBinaryOperator::boAnd
@ boAnd
Definition: qgsexpressionnodeimpl.h:103
QgsExpressionNodeBinaryOperator::boMul
@ boMul
Definition: qgsexpressionnodeimpl.h:123
QgsExpressionNodeBinaryOperator::boOr
@ boOr
Definition: qgsexpressionnodeimpl.h:102
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:105
QgsSqlExpressionCompiler::Result
Result
Possible results from expression compilation.
Definition: qgssqlexpressioncompiler.h:46
QgsExpressionNode::ntIndexOperator
@ ntIndexOperator
Index operator.
Definition: qgsexpressionnode.h:83
QgsFields::indexFromName
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:202
QgsSqlExpressionCompiler::sqlArgumentsFromFunctionName
virtual QStringList sqlArgumentsFromFunctionName(const QString &fnName, const QStringList &fnArgs) const
Returns the Arguments for SQL function for the expression function.
Definition: qgssqlexpressioncompiler.cpp:420
QgsExpressionNode::nodeType
virtual QgsExpressionNode::NodeType nodeType() const =0
Gets the type of this node.
QgsExpressionNodeBinaryOperator::BinaryOperator
BinaryOperator
list of binary operators
Definition: qgsexpressionnodeimpl.h:100
QgsExpressionNode::ntInOperator
@ ntInOperator
Definition: qgsexpressionnode.h:78
QgsSqlExpressionCompiler::quotedIdentifier
virtual QString quotedIdentifier(const QString &identifier)
Returns a quoted column identifier, in the format expected by the provider.
Definition: qgssqlexpressioncompiler.cpp:53