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