QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
19
20#include "qgsexpression.h"
24#include "qgssqliteutils.h"
25
26QgsSQLiteExpressionCompiler::QgsSQLiteExpressionCompiler( const QgsFields &fields, bool ignoreStaticNodes )
27 : QgsSqlExpressionCompiler( fields, QgsSqlExpressionCompiler::LikeIsCaseInsensitive | QgsSqlExpressionCompiler::IntegerDivisionResultsInInteger, ignoreStaticNodes )
28{
29}
30
31QgsSqlExpressionCompiler::Result QgsSQLiteExpressionCompiler::compileNode( const QgsExpressionNode *node, QString &result )
32{
33 const QgsSqlExpressionCompiler::Result staticRes = replaceNodeByStaticCachedValueIfPossible( node, result );
34 if ( staticRes != Fail )
35 return staticRes;
36
37 switch ( node->nodeType() )
38 {
40 {
41 const QgsExpressionNodeBinaryOperator *op = static_cast<const QgsExpressionNodeBinaryOperator *>( node );
42 switch ( op->op() )
43 {
46 return Fail; //not supported by SQLite
47
50 {
51 QString opL, opR;
52
53 if ( compileNode( op->opLeft(), opL ) != Complete ||
54 compileNode( op->opRight(), opR ) != Complete )
55 return Fail;
56
57 result = QStringLiteral( "lower(%1) %2 lower(%3) ESCAPE '\\'" )
58 .arg( opL )
59 .arg( op->op() == QgsExpressionNodeBinaryOperator::boILike ? QStringLiteral( "LIKE" ) : QStringLiteral( "NOT LIKE" ) )
60 .arg( opR );
61
62 return Complete;
63 }
64
65 default:
66 //fallback to default handling
67 return QgsSqlExpressionCompiler::compileNode( node, result );
68 }
69 }
70
72 {
73 const QgsExpressionNodeFunction *n = static_cast<const QgsExpressionNodeFunction *>( node );
75
76 if ( fd->name() == QLatin1String( "make_datetime" ) || fd->name() == QLatin1String( "make_date" ) || fd->name() == QLatin1String( "make_time" ) )
77 {
78 const auto constList = n->args()->list();
79 for ( const QgsExpressionNode *ln : constList )
80 {
81 if ( ln->nodeType() != QgsExpressionNode::ntLiteral )
82 return Fail;
83 }
84 }
85
86 return QgsSqlExpressionCompiler::compileNode( node, result );
87 }
88
89 default:
90 break;
91 }
92
93 return QgsSqlExpressionCompiler::compileNode( node, result );
94}
95
96QString QgsSQLiteExpressionCompiler::quotedIdentifier( const QString &identifier )
97{
98 return QgsSqliteUtils::quotedIdentifier( identifier );
99}
100
101QString QgsSQLiteExpressionCompiler::quotedValue( const QVariant &value, bool &ok )
102{
103 ok = true;
104 return QgsSqliteUtils::quotedValue( value );
105}
106
107QString QgsSQLiteExpressionCompiler::sqlFunctionFromFunctionName( const QString &fnName ) const
108{
109 static const QMap<QString, QString> FN_NAMES
110 {
111 { "abs", "abs" },
112 { "char", "char" },
113 { "coalesce", "coalesce" },
114 { "lower", "lower" },
115 { "round", "round" },
116 { "trim", "trim" },
117 { "upper", "upper" },
118 { "make_datetime", "" },
119 { "make_date", "" },
120 { "make_time", "" },
121 };
122
123 return FN_NAMES.value( fnName, QString() );
124}
125
126QStringList QgsSQLiteExpressionCompiler::sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const
127{
128 QStringList args( fnArgs );
129 if ( fnName == QLatin1String( "make_datetime" ) )
130 {
131 args = QStringList( QStringLiteral( "'%1-%2-%3T%4:%5:%6Z'" ).arg( args[0].rightJustified( 4, '0' ) )
132 .arg( args[1].rightJustified( 2, '0' ) )
133 .arg( args[2].rightJustified( 2, '0' ) )
134 .arg( args[3].rightJustified( 2, '0' ) )
135 .arg( args[4].rightJustified( 2, '0' ) )
136 .arg( args[5].rightJustified( 2, '0' ) ) );
137 }
138 else if ( fnName == QLatin1String( "make_date" ) )
139 {
140 args = QStringList( QStringLiteral( "'%1-%2-%3'" ).arg( args[0].rightJustified( 4, '0' ) )
141 .arg( args[1].rightJustified( 2, '0' ) )
142 .arg( args[2].rightJustified( 2, '0' ) ) );
143 }
144 else if ( fnName == QLatin1String( "make_time" ) )
145 {
146 args = QStringList( QStringLiteral( "'%1:%2:%3'" ).arg( args[0].rightJustified( 2, '0' ) )
147 .arg( args[1].rightJustified( 2, '0' ) )
148 .arg( args[2].rightJustified( 2, '0' ) ) );
149 }
150 return args;
151}
152
153QString QgsSQLiteExpressionCompiler::castToReal( const QString &value ) const
154{
155 return QStringLiteral( "CAST((%1) AS REAL)" ).arg( value );
156}
157
158QString QgsSQLiteExpressionCompiler::castToInt( const QString &value ) const
159{
160 return QStringLiteral( "CAST((%1) AS INTEGER)" ).arg( value );
161}
162
163QString QgsSQLiteExpressionCompiler::castToText( const QString &value ) const
164{
165 return QStringLiteral( "CAST((%1) AS TEXT)" ).arg( value );
166}
167
An 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:46
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.