QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgssqliteexpressioncompiler.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssqliteexpressioncompiler.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 
20 #include "qgsexpressionfunction.h"
21 #include "qgsexpressionnodeimpl.h"
22 #include "qgsexpression.h"
23 #include "qgssqliteutils.h"
24 
25 QgsSQLiteExpressionCompiler::QgsSQLiteExpressionCompiler( const QgsFields &fields )
26  : QgsSqlExpressionCompiler( fields, QgsSqlExpressionCompiler::LikeIsCaseInsensitive | QgsSqlExpressionCompiler::IntegerDivisionResultsInInteger )
27 {
28 }
29 
30 QgsSqlExpressionCompiler::Result QgsSQLiteExpressionCompiler::compileNode( const QgsExpressionNode *node, QString &result )
31 {
32  switch ( node->nodeType() )
33  {
35  {
36  const QgsExpressionNodeBinaryOperator *op = static_cast<const QgsExpressionNodeBinaryOperator *>( node );
37  switch ( op->op() )
38  {
41  return Fail; //not supported by SQLite
42 
45  {
46  QString opL, opR;
47 
48  if ( compileNode( op->opLeft(), opL ) != Complete ||
49  compileNode( op->opRight(), opR ) != Complete )
50  return Fail;
51 
52  result = QStringLiteral( "lower(%1) %2 lower(%3) ESCAPE '\\'" )
53  .arg( opL )
54  .arg( op->op() == QgsExpressionNodeBinaryOperator::boILike ? QStringLiteral( "LIKE" ) : QStringLiteral( "NOT LIKE" ) )
55  .arg( opR );
56 
57  return Complete;
58  }
59 
60  default:
61  //fallback to default handling
62  return QgsSqlExpressionCompiler::compileNode( node, result );
63  }
64  }
65 
67  {
68  const QgsExpressionNodeFunction *n = static_cast<const QgsExpressionNodeFunction *>( node );
70 
71  if ( fd->name() == QLatin1String( "make_datetime" ) || fd->name() == QLatin1String( "make_date" ) || fd->name() == QLatin1String( "make_time" ) )
72  {
73  const auto constList = n->args()->list();
74  for ( const QgsExpressionNode *ln : constList )
75  {
76  if ( ln->nodeType() != QgsExpressionNode::ntLiteral )
77  return Fail;
78  }
79  }
80 
81  return QgsSqlExpressionCompiler::compileNode( node, result );
82  }
83 
84  default:
85  break;
86  }
87 
88  return QgsSqlExpressionCompiler::compileNode( node, result );
89 }
90 
91 QString QgsSQLiteExpressionCompiler::quotedIdentifier( const QString &identifier )
92 {
93  return QgsSqliteUtils::quotedIdentifier( identifier );
94 }
95 
96 QString QgsSQLiteExpressionCompiler::quotedValue( const QVariant &value, bool &ok )
97 {
98  ok = true;
99  return QgsSqliteUtils::quotedValue( value );
100 }
101 
102 QString QgsSQLiteExpressionCompiler::sqlFunctionFromFunctionName( const QString &fnName ) const
103 {
104  static const QMap<QString, QString> FN_NAMES
105  {
106  { "abs", "abs" },
107  { "char", "char" },
108  { "coalesce", "coalesce" },
109  { "lower", "lower" },
110  { "round", "round" },
111  { "trim", "trim" },
112  { "upper", "upper" },
113  { "make_datetime", "" },
114  { "make_date", "" },
115  { "make_time", "" },
116  };
117 
118  return FN_NAMES.value( fnName, QString() );
119 }
120 
121 QStringList QgsSQLiteExpressionCompiler::sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const
122 {
123  QStringList args( fnArgs );
124  if ( fnName == QLatin1String( "make_datetime" ) )
125  {
126  args = QStringList( QStringLiteral( "'%1-%2-%3T%4:%5:%6Z'" ).arg( args[0].rightJustified( 4, '0' ) )
127  .arg( args[1].rightJustified( 2, '0' ) )
128  .arg( args[2].rightJustified( 2, '0' ) )
129  .arg( args[3].rightJustified( 2, '0' ) )
130  .arg( args[4].rightJustified( 2, '0' ) )
131  .arg( args[5].rightJustified( 2, '0' ) ) );
132  }
133  else if ( fnName == QLatin1String( "make_date" ) )
134  {
135  args = QStringList( QStringLiteral( "'%1-%2-%3'" ).arg( args[0].rightJustified( 4, '0' ) )
136  .arg( args[1].rightJustified( 2, '0' ) )
137  .arg( args[2].rightJustified( 2, '0' ) ) );
138  }
139  else if ( fnName == QLatin1String( "make_time" ) )
140  {
141  args = QStringList( QStringLiteral( "'%1:%2:%3'" ).arg( args[0].rightJustified( 2, '0' ) )
142  .arg( args[1].rightJustified( 2, '0' ) )
143  .arg( args[2].rightJustified( 2, '0' ) ) );
144  }
145  return args;
146 }
147 
148 QString QgsSQLiteExpressionCompiler::castToReal( const QString &value ) const
149 {
150  return QStringLiteral( "CAST((%1) AS REAL)" ).arg( value );
151 }
152 
153 QString QgsSQLiteExpressionCompiler::castToInt( const QString &value ) const
154 {
155  return QStringLiteral( "CAST((%1) AS INTEGER)" ).arg( value );
156 }
157 
158 QString QgsSQLiteExpressionCompiler::castToText( const QString &value ) const
159 {
160  return QStringLiteral( "CAST((%1) AS TEXT)" ).arg( value );
161 }
162 
QgsExpressionNodeBinaryOperator::op
QgsExpressionNodeBinaryOperator::BinaryOperator op() const
Returns the binary operator.
Definition: qgsexpressionnodeimpl.h:146
QgsExpressionNodeBinaryOperator::boILike
@ boILike
Definition: qgsexpressionnodeimpl.h:115
QgsExpressionNodeBinaryOperator
A binary expression operator, which operates on two values.
Definition: qgsexpressionnodeimpl.h:92
QgsExpressionNodeBinaryOperator::boRegexp
@ boRegexp
Definition: qgsexpressionnodeimpl.h:112
qgsexpression.h
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
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
Generic expression compiler for translation to provider specific SQL WHERE clauses.
Definition: qgssqlexpressioncompiler.h:41
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
QgsSqliteUtils::quotedValue
static QString quotedValue(const QVariant &value)
Returns a properly quoted and escaped version of value for use in SQL strings.
Definition: qgssqliteutils.cpp:266
QgsExpressionNodeBinaryOperator::boNotILike
@ boNotILike
Definition: qgsexpressionnodeimpl.h:116
qgsexpressionfunction.h
qgssqliteexpressioncompiler.h
QgsExpressionNode::ntBinaryOperator
@ ntBinaryOperator
Definition: qgsexpressionnode.h:77
QgsExpressionNodeFunction
An expression node for expression functions.
Definition: qgsexpressionnodeimpl.h:317
QgsExpressionNode::ntLiteral
@ ntLiteral
Definition: qgsexpressionnode.h:80
QgsExpression::Functions
static const QList< QgsExpressionFunction * > & Functions()
Definition: qgsexpressionfunction.cpp:6008
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
qgsexpressionnodeimpl.h
QgsExpressionFunction
A abstract base class for defining QgsExpression functions.
Definition: qgsexpressionfunction.h:41
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
qgssqliteutils.h
QgsExpressionNodeBinaryOperator::opRight
QgsExpressionNode * opRight() const
Returns the node to the right of the operator.
Definition: qgsexpressionnodeimpl.h:158
QgsSqliteUtils::quotedIdentifier
static QString quotedIdentifier(const QString &identifier)
Returns a properly quoted version of identifier.
Definition: qgssqliteutils.cpp:259
QgsSqlExpressionCompiler::Result
Result
Possible results from expression compilation.
Definition: qgssqlexpressioncompiler.h:46
QgsExpressionNode::nodeType
virtual QgsExpressionNode::NodeType nodeType() const =0
Gets the type of this node.