Skip to content
Permalink
Browse files

Compile make_datetime on oracle

  • Loading branch information
nyalldawson authored and nirvn committed May 22, 2020
1 parent b17da05 commit fb8cd81b79a03e90929a0f04cbd58c1939dd808d
@@ -24,65 +24,90 @@ QgsOracleExpressionCompiler::QgsOracleExpressionCompiler( QgsOracleFeatureSource

QgsSqlExpressionCompiler::Result QgsOracleExpressionCompiler::compileNode( const QgsExpressionNode *node, QString &result )
{
if ( node->nodeType() == QgsExpressionNode::ntBinaryOperator )
switch ( node->nodeType() )
{
const QgsExpressionNodeBinaryOperator *bin( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );

switch ( bin->op() )
case QgsExpressionNode::ntBinaryOperator:
{
case QgsExpressionNodeBinaryOperator::boConcat:
// oracle's handling of || WRT null is not standards compliant
return Fail;

case QgsExpressionNodeBinaryOperator::boPow:
case QgsExpressionNodeBinaryOperator::boRegexp:
case QgsExpressionNodeBinaryOperator::boILike:
case QgsExpressionNodeBinaryOperator::boNotILike:
case QgsExpressionNodeBinaryOperator::boMod:
case QgsExpressionNodeBinaryOperator::boIntDiv:
{
QString op1, op2;
const QgsExpressionNodeBinaryOperator *bin( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );

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

switch ( bin->op() )
case QgsExpressionNodeBinaryOperator::boPow:
case QgsExpressionNodeBinaryOperator::boRegexp:
case QgsExpressionNodeBinaryOperator::boILike:
case QgsExpressionNodeBinaryOperator::boNotILike:
case QgsExpressionNodeBinaryOperator::boMod:
case QgsExpressionNodeBinaryOperator::boIntDiv:
{
case QgsExpressionNodeBinaryOperator::boPow:
result = QStringLiteral( "power(%1,%2)" ).arg( op1, op2 );
return Complete;
QString op1, op2;

if ( compileNode( bin->opLeft(), op1 ) != Complete ||
compileNode( bin->opRight(), op2 ) != Complete )
return Fail;

switch ( bin->op() )
{
case QgsExpressionNodeBinaryOperator::boPow:
result = QStringLiteral( "power(%1,%2)" ).arg( op1, op2 );
return Complete;

case QgsExpressionNodeBinaryOperator::boRegexp:
result = QStringLiteral( "regexp_like(%1,%2)" ).arg( op1, op2 );
return Complete;
case QgsExpressionNodeBinaryOperator::boRegexp:
result = QStringLiteral( "regexp_like(%1,%2)" ).arg( op1, op2 );
return Complete;

case QgsExpressionNodeBinaryOperator::boILike:
result = QStringLiteral( "lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
return Complete;
case QgsExpressionNodeBinaryOperator::boILike:
result = QStringLiteral( "lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
return Complete;

case QgsExpressionNodeBinaryOperator::boNotILike:
result = QStringLiteral( "NOT lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
return Complete;
case QgsExpressionNodeBinaryOperator::boNotILike:
result = QStringLiteral( "NOT lower(%1) LIKE lower(%2) ESCAPE '\\'" ).arg( op1, op2 );
return Complete;

case QgsExpressionNodeBinaryOperator::boIntDiv:
result = QStringLiteral( "FLOOR(%1 / %2)" ).arg( op1, op2 );
return Complete;
case QgsExpressionNodeBinaryOperator::boIntDiv:
result = QStringLiteral( "FLOOR(%1 / %2)" ).arg( op1, op2 );
return Complete;


case QgsExpressionNodeBinaryOperator::boMod :
result = QStringLiteral( "MOD(%1,%2)" ).arg( op1, op2 );
return Complete;
case QgsExpressionNodeBinaryOperator::boMod :
result = QStringLiteral( "MOD(%1,%2)" ).arg( op1, op2 );
return Complete;

default:
break;
default:
break;
}
break; // no warnings
}
break; // no warnings

default:
break;
}
break;
}

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

if ( fd->name() == QLatin1String( "make_datetime" ) )
{
const auto constList = n->args()->list();
for ( const QgsExpressionNode *ln : constList )
{
if ( ln->nodeType() != QgsExpressionNode::ntLiteral )
return Fail;
}
}
return QgsSqlExpressionCompiler::compileNode( node, result );
break;
}

default:
break;
}

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

QString QgsOracleExpressionCompiler::sqlFunctionFromFunctionName( const QString &fnName ) const
{
return FUNCTION_NAMES_SQL_FUNCTIONS_MAP.value( fnName, QString() );
}

QStringList QgsOracleExpressionCompiler::sqlArgumentsFromFunctionName( const QString &fnName, const QStringList &fnArgs ) const
{
QStringList args( fnArgs );
if ( fnName == QLatin1String( "make_datetime" ) )
{
args = QStringList( QStringLiteral( "TIMESTAMP '%1-%2-%3 %4:%5:%6'" ).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' ) ) );
}
return args;
}
@@ -31,6 +31,7 @@ class QgsOracleExpressionCompiler : 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;
};

#endif // QGSORACLEEXPRESSIONCOMPILER_H
@@ -167,10 +167,8 @@ 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)',
'"date" = to_date(\'www4ww5ww2020\',\'wwwdwwMwwyyyy\')',
'to_time("time") >= make_time(12, 14, 14)',

0 comments on commit fb8cd81

Please sign in to comment.
You can’t perform that action at this time.