Skip to content

Commit

Permalink
[expression] Compile make_{datetime,date,time} for sqlite
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed May 22, 2020
1 parent 73e888d commit eec8ca4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/core/qgssqlexpressioncompiler.cpp
Expand Up @@ -372,7 +372,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
// get sql function to compile node expression
QString nd = sqlFunctionFromFunctionName( fd->name() );
// if no sql function the node can't be compiled
if ( nd.isEmpty() )
if ( nd.isNull() )
return Fail;

// compile arguments
Expand All @@ -397,7 +397,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
args = sqlArgumentsFromFunctionName( fd->name(), args );

// build result
result = QStringLiteral( "%1(%2)" ).arg( nd, args.join( ',' ) );
result = !nd.isEmpty() ? QStringLiteral( "%1(%2)" ).arg( nd, args.join( ',' ) ) : QStringLiteral( "%1" ).arg( args.join( ',' ) );
return inResult == Partial ? Partial : Complete;
}

Expand Down
50 changes: 50 additions & 0 deletions src/core/qgssqliteexpressioncompiler.cpp
Expand Up @@ -17,7 +17,9 @@

#include "qgssqliteexpressioncompiler.h"
#include "qgssqlexpressioncompiler.h"
#include "qgsexpressionfunction.h"
#include "qgsexpressionnodeimpl.h"
#include "qgsexpression.h"
#include "qgssqliteutils.h"

QgsSQLiteExpressionCompiler::QgsSQLiteExpressionCompiler( const QgsFields &fields )
Expand Down Expand Up @@ -61,6 +63,24 @@ QgsSqlExpressionCompiler::Result QgsSQLiteExpressionCompiler::compileNode( const
}
}

case QgsExpressionNode::ntFunction:
{
const QgsExpressionNodeFunction *n = static_cast<const QgsExpressionNodeFunction *>( node );
QgsExpressionFunction *fd = QgsExpression::Functions()[n->fnIndex()];

if ( fd->name() == QLatin1String( "make_datetime" ) || fd->name() == QLatin1String( "make_date" ) || fd->name() == QLatin1String( "make_time" ) )
{
const auto constList = n->args()->list();
for ( const QgsExpressionNode *ln : constList )
{
if ( ln->nodeType() != QgsExpressionNode::ntLiteral )
return Fail;
}
}

return QgsSqlExpressionCompiler::compileNode( node, result );
}

default:
break;
}
Expand Down Expand Up @@ -90,11 +110,41 @@ QString QgsSQLiteExpressionCompiler::sqlFunctionFromFunctionName( const QString
{ "round", "round" },
{ "trim", "trim" },
{ "upper", "upper" },
{ "make_datetime", "" },
{ "make_date", "" },
{ "make_time", "" },
};

return FN_NAMES.value( fnName, QString() );
}

QStringList QgsSQLiteExpressionCompiler::sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const
{
QStringList args( fnArgs );
if ( fnName == QLatin1String( "make_datetime" ) )
{
args = QStringList( QStringLiteral( "'%1-%2-%3T%4:%5:%6Z'" ).arg( args[0].rightJustified( 4, '0' ) )
.arg( args[1].rightJustified( 2, '0' ) )
.arg( args[2].rightJustified( 2, '0' ) )
.arg( args[3].rightJustified( 2, '0' ) )
.arg( args[4].rightJustified( 2, '0' ) )
.arg( args[5].rightJustified( 2, '0' ) ) );
}
else if ( fnName == QLatin1String( "make_date" ) )
{
args = QStringList( QStringLiteral( "'%1-%2-%3'" ).arg( args[0].rightJustified( 4, '0' ) )
.arg( args[1].rightJustified( 2, '0' ) )
.arg( args[2].rightJustified( 2, '0' ) ) );
}
else if ( fnName == QLatin1String( "make_time" ) )
{
args = QStringList( QStringLiteral( "'%1:%2:%3'" ).arg( args[0].rightJustified( 2, '0' ) )
.arg( args[1].rightJustified( 2, '0' ) )
.arg( args[2].rightJustified( 2, '0' ) ) );
}
return args;
}

QString QgsSQLiteExpressionCompiler::castToReal( const QString &value ) const
{
return QStringLiteral( "CAST((%1) AS REAL)" ).arg( value );
Expand Down
1 change: 1 addition & 0 deletions src/core/qgssqliteexpressioncompiler.h
Expand Up @@ -50,6 +50,7 @@ class CORE_EXPORT QgsSQLiteExpressionCompiler : public QgsSqlExpressionCompiler
QString quotedIdentifier( const QString &identifier ) override;
QString quotedValue( const QVariant &value, bool &ok ) override;
QString sqlFunctionFromFunctionName( const QString &fnName ) const override;
QStringList sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const override;
QString castToReal( const QString &value ) const override;
QString castToInt( const QString &value ) const override;
QString castToText( const QString &value ) const override;
Expand Down
4 changes: 0 additions & 4 deletions tests/src/python/test_provider_gpkg.py
Expand Up @@ -154,11 +154,7 @@ def uncompiledFilters(self):
'overlaps(buffer($geometry,1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
'intersects(centroid($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))',
'intersects(point_on_surface($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))',
'"dt" <= make_datetime(2020, 5, 4, 12, 13, 14)',
'"dt" < make_date(2020, 5, 4)',
'"dt" = to_datetime(\'000www14ww13ww12www4ww5ww2020\',\'zzzwwwsswwmmwwhhwwwdwwMwwyyyy\')',
'"date" <= make_datetime(2020, 5, 4, 12, 13, 14)',
'"date" >= make_date(2020, 5, 4)',
'to_time("time") >= make_time(12, 14, 14)',
'to_time("time") = to_time(\'000www14ww13ww12www\',\'zzzwwwsswwmmwwhhwww\')',
'"date" = to_date(\'www4ww5ww2020\',\'wwwdwwMwwyyyy\')'
Expand Down
2 changes: 0 additions & 2 deletions tests/src/python/test_provider_spatialite.py
Expand Up @@ -361,8 +361,6 @@ def uncompiledFilters(self):
'"dt" <= format_date(make_datetime(2020, 5, 4, 12, 13, 14), \'yyyy-MM-dd hh:mm:ss\')',
'"dt" < format_date(make_date(2020, 5, 4), \'yyyy-MM-dd hh:mm:ss\')',
'"dt" = format_date(to_datetime(\'000www14ww13ww12www4ww5ww2020\',\'zzzwwwsswwmmwwhhwwwdwwMwwyyyy\'),\'yyyy-MM-dd hh:mm:ss\')',
'"date" <= make_datetime(2020, 5, 4, 12, 13, 14)',
'"date" >= make_date(2020, 5, 4)',
'to_time("time") >= make_time(12, 14, 14)',
'to_time("time") = to_time(\'000www14ww13ww12www\',\'zzzwwwsswwmmwwhhwww\')',
'"date" = to_date(\'www4ww5ww2020\',\'wwwdwwMwwyyyy\')'
Expand Down

0 comments on commit eec8ca4

Please sign in to comment.