Skip to content

Commit fb8cd81

Browse files
nyalldawsonnirvn
authored andcommittedMay 22, 2020
Compile make_datetime on oracle
1 parent b17da05 commit fb8cd81

File tree

3 files changed

+84
-44
lines changed

3 files changed

+84
-44
lines changed
 

‎src/providers/oracle/qgsoracleexpressioncompiler.cpp

Lines changed: 83 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,65 +24,90 @@ QgsOracleExpressionCompiler::QgsOracleExpressionCompiler( QgsOracleFeatureSource
2424

2525
QgsSqlExpressionCompiler::Result QgsOracleExpressionCompiler::compileNode( const QgsExpressionNode *node, QString &result )
2626
{
27-
if ( node->nodeType() == QgsExpressionNode::ntBinaryOperator )
27+
switch ( node->nodeType() )
2828
{
29-
const QgsExpressionNodeBinaryOperator *bin( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );
30-
31-
switch ( bin->op() )
29+
case QgsExpressionNode::ntBinaryOperator:
3230
{
33-
case QgsExpressionNodeBinaryOperator::boConcat:
34-
// oracle's handling of || WRT null is not standards compliant
35-
return Fail;
36-
37-
case QgsExpressionNodeBinaryOperator::boPow:
38-
case QgsExpressionNodeBinaryOperator::boRegexp:
39-
case QgsExpressionNodeBinaryOperator::boILike:
40-
case QgsExpressionNodeBinaryOperator::boNotILike:
41-
case QgsExpressionNodeBinaryOperator::boMod:
42-
case QgsExpressionNodeBinaryOperator::boIntDiv:
43-
{
44-
QString op1, op2;
31+
const QgsExpressionNodeBinaryOperator *bin( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );
4532

46-
if ( compileNode( bin->opLeft(), op1 ) != Complete ||
47-
compileNode( bin->opRight(), op2 ) != Complete )
33+
switch ( bin->op() )
34+
{
35+
case QgsExpressionNodeBinaryOperator::boConcat:
36+
// oracle's handling of || WRT null is not standards compliant
4837
return Fail;
4938

50-
switch ( bin->op() )
39+
case QgsExpressionNodeBinaryOperator::boPow:
40+
case QgsExpressionNodeBinaryOperator::boRegexp:
41+
case QgsExpressionNodeBinaryOperator::boILike:
42+
case QgsExpressionNodeBinaryOperator::boNotILike:
43+
case QgsExpressionNodeBinaryOperator::boMod:
44+
case QgsExpressionNodeBinaryOperator::boIntDiv:
5145
{
52-
case QgsExpressionNodeBinaryOperator::boPow:
53-
result = QStringLiteral( "power(%1,%2)" ).arg( op1, op2 );
54-
return Complete;
46+
QString op1, op2;
47+
48+
if ( compileNode( bin->opLeft(), op1 ) != Complete ||
49+
compileNode( bin->opRight(), op2 ) != Complete )
50+
return Fail;
51+
52+
switch ( bin->op() )
53+
{
54+
case QgsExpressionNodeBinaryOperator::boPow:
55+
result = QStringLiteral( "power(%1,%2)" ).arg( op1, op2 );
56+
return Complete;
5557

56-
case QgsExpressionNodeBinaryOperator::boRegexp:
57-
result = QStringLiteral( "regexp_like(%1,%2)" ).arg( op1, op2 );
58-
return Complete;
58+
case QgsExpressionNodeBinaryOperator::boRegexp:
59+
result = QStringLiteral( "regexp_like(%1,%2)" ).arg( op1, op2 );
60+
return Complete;
5961

60-
case QgsExpressionNodeBinaryOperator::boILike:
61-
result = QStringLiteral( "lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
62-
return Complete;
62+
case QgsExpressionNodeBinaryOperator::boILike:
63+
result = QStringLiteral( "lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
64+
return Complete;
6365

64-
case QgsExpressionNodeBinaryOperator::boNotILike:
65-
result = QStringLiteral( "NOT lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
66-
return Complete;
66+
case QgsExpressionNodeBinaryOperator::boNotILike:
67+
result = QStringLiteral( "NOT lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
68+
return Complete;
6769

68-
case QgsExpressionNodeBinaryOperator::boIntDiv:
69-
result = QStringLiteral( "FLOOR(%1 / %2)" ).arg( op1, op2 );
70-
return Complete;
70+
case QgsExpressionNodeBinaryOperator::boIntDiv:
71+
result = QStringLiteral( "FLOOR(%1 / %2)" ).arg( op1, op2 );
72+
return Complete;
7173

7274

73-
case QgsExpressionNodeBinaryOperator::boMod :
74-
result = QStringLiteral( "MOD(%1,%2)" ).arg( op1, op2 );
75-
return Complete;
75+
case QgsExpressionNodeBinaryOperator::boMod :
76+
result = QStringLiteral( "MOD(%1,%2)" ).arg( op1, op2 );
77+
return Complete;
7678

77-
default:
78-
break;
79+
default:
80+
break;
81+
}
82+
break; // no warnings
7983
}
80-
break; // no warnings
84+
85+
default:
86+
break;
8187
}
88+
break;
89+
}
8290

83-
default:
84-
break;
91+
case QgsExpressionNode::ntFunction:
92+
{
93+
const QgsExpressionNodeFunction *n = static_cast<const QgsExpressionNodeFunction *>( node );
94+
QgsExpressionFunction *fd = QgsExpression::Functions()[n->fnIndex()];
95+
96+
if ( fd->name() == QLatin1String( "make_datetime" ) )
97+
{
98+
const auto constList = n->args()->list();
99+
for ( const QgsExpressionNode *ln : constList )
100+
{
101+
if ( ln->nodeType() != QgsExpressionNode::ntLiteral )
102+
return Fail;
103+
}
104+
}
105+
return QgsSqlExpressionCompiler::compileNode( node, result );
106+
break;
85107
}
108+
109+
default:
110+
break;
86111
}
87112

88113
//fallback to default handling
@@ -127,9 +152,25 @@ static const QMap<QString, QString> FUNCTION_NAMES_SQL_FUNCTIONS_MAP
127152
{ "ceil", "ceil" },
128153
{ "lower", "lower" },
129154
{ "upper", "upper" },
155+
{ "make_datetime", "" },
130156
};
131157

132158
QString QgsOracleExpressionCompiler::sqlFunctionFromFunctionName( const QString &fnName ) const
133159
{
134160
return FUNCTION_NAMES_SQL_FUNCTIONS_MAP.value( fnName, QString() );
135161
}
162+
163+
QStringList QgsOracleExpressionCompiler::sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const
164+
{
165+
QStringList args( fnArgs );
166+
if ( fnName == QLatin1String( "make_datetime" ) )
167+
{
168+
args = QStringList( QStringLiteral( "TIMESTAMP '%1-%2-%3 %4:%5:%6'" ).arg( args[0].rightJustified( 4, '0' ) )
169+
.arg( args[1].rightJustified( 2, '0' ) )
170+
.arg( args[2].rightJustified( 2, '0' ) )
171+
.arg( args[3].rightJustified( 2, '0' ) )
172+
.arg( args[4].rightJustified( 2, '0' ) )
173+
.arg( args[5].rightJustified( 2, '0' ) ) );
174+
}
175+
return args;
176+
}

‎src/providers/oracle/qgsoracleexpressioncompiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class QgsOracleExpressionCompiler : public QgsSqlExpressionCompiler
3131
QString quotedIdentifier( const QString &identifier ) override;
3232
QString quotedValue( const QVariant &value, bool &ok ) override;
3333
QString sqlFunctionFromFunctionName( const QString &fnName ) const override;
34+
QStringList sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const override;
3435
};
3536

3637
#endif // QGSORACLEEXPRESSIONCOMPILER_H

‎tests/src/python/test_provider_oracle.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,8 @@ def uncompiledFilters(self):
167167
'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))\'))',
168168
'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))\'))',
169169
'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))\'))',
170-
'"dt" <= make_datetime(2020, 5, 4, 12, 13, 14)',
171170
'"dt" < make_date(2020, 5, 4)',
172171
'"dt" = to_datetime(\'000www14ww13ww12www4ww5ww2020\',\'zzzwwwsswwmmwwhhwwwdwwMwwyyyy\')',
173-
'"date" <= make_datetime(2020, 5, 4, 12, 13, 14)',
174172
'"date" >= make_date(2020, 5, 4)',
175173
'"date" = to_date(\'www4ww5ww2020\',\'wwwdwwMwwyyyy\')',
176174
'to_time("time") >= make_time(12, 14, 14)',

0 commit comments

Comments
 (0)
Please sign in to comment.