Trhow Jet specific errors on more unsupported SQL. Allows us to bulk mark as skipped

pull/257/head
Christopher Jolly 1 year ago
parent 05885b0d50
commit 3d85f906f5

@ -2,6 +2,8 @@
// Licensed under the MIT. See LICENSE in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -21,8 +23,11 @@ public class JetCompatibilityExpressionVisitor : ExpressionVisitor
ExceptExpression exceptExpression => VisitExcept(exceptExpression),
IntersectExpression intersectExpression => VisitIntersect(intersectExpression),
JsonScalarExpression jsonScalarExpression => VisitJsonScalar(jsonScalarExpression),
InnerJoinExpression innerJoinExpression => VisitInnerJoin(innerJoinExpression),
LeftJoinExpression leftJoinExpression => VisitLeftJoin(leftJoinExpression),
SelectExpression selectExpression => VisitSelect(selectExpression),
ShapedQueryExpression shapedQueryExpression => shapedQueryExpression.Update(Visit(shapedQueryExpression.QueryExpression), Visit(shapedQueryExpression.ShaperExpression)),
CrossJoinExpression crossJoinExpression => VisitCrossJoin(crossJoinExpression),
_ => base.VisitExtension(extensionExpression)
};
@ -46,6 +51,79 @@ public class JetCompatibilityExpressionVisitor : ExpressionVisitor
? TranslationFailed(jsonScalarExpression)
: jsonScalarExpression;
protected virtual Expression VisitLeftJoin(LeftJoinExpression leftJoinExpression)
{
if (leftJoinExpression.JoinPredicate is SqlBinaryExpression sqlBinaryExpression)
{
if (ContainsUnsupportCol(sqlBinaryExpression))
{
return TranslationFailed(leftJoinExpression.JoinPredicate);
}
}
if (leftJoinExpression.JoinPredicate is SqlUnaryExpression)
{
return TranslationFailed(leftJoinExpression.JoinPredicate);
}
return base.VisitExtension(leftJoinExpression);
}
protected virtual Expression VisitInnerJoin(InnerJoinExpression innerJoinExpression)
{
if (innerJoinExpression.JoinPredicate is SqlBinaryExpression sqlBinaryExpression)
{
if (ContainsUnsupportCol(sqlBinaryExpression))
{
return TranslationFailed(innerJoinExpression.JoinPredicate);
}
}
if (innerJoinExpression.JoinPredicate is SqlUnaryExpression)
{
return TranslationFailed(innerJoinExpression.JoinPredicate);
}
return base.VisitExtension(innerJoinExpression);
}
protected virtual Expression VisitSelect(SelectExpression selectExpression)
{
return base.VisitExtension(selectExpression);
}
protected virtual Expression VisitCrossJoin(CrossJoinExpression crossJoinExpression)
{
if (crossJoinExpression.Table is SelectExpression selectExpression)
{
return TranslationFailed(selectExpression);
}
return base.VisitExtension(crossJoinExpression);
}
protected virtual Expression TranslationFailed(Expression expression)
=> throw new InvalidOperationException(CoreStrings.TranslationFailed(expression.Print()));
=> throw new InvalidOperationException("Unsupported Jet expression: " + expression.Print());
private bool ContainsUnsupportCol(SqlBinaryExpression binaryexp)
{
bool containsunsupported = false;
if (binaryexp.Left is SqlBinaryExpression left)
{
containsunsupported = ContainsUnsupportCol(left) ^ containsunsupported;
}
else if (binaryexp.Left is SqlConstantExpression or SqlFunctionExpression or ScalarSubqueryExpression)
{
containsunsupported = true;
}
if (binaryexp.Right is SqlBinaryExpression right)
{
containsunsupported = ContainsUnsupportCol(right) ^ containsunsupported;
}
else if (binaryexp.Right is SqlConstantExpression or SqlFunctionExpression or ScalarSubqueryExpression)
{
containsunsupported = true;
}
return containsunsupported;
}
}

@ -74,6 +74,11 @@ public class JetSkipTakePostprocessor : ExpressionVisitor
{
SqlExpression offset = selectExpression.Offset!;
SqlExpression limit = selectExpression.Limit!;
if (offset is ColumnExpression || limit is ColumnExpression)
{
throw new InvalidOperationException(
"Unsupported Jet expression: Limit or offset can not reference a column");
}
var total = new SqlBinaryExpression(ExpressionType.Add, offset, limit, typeof(int),
RelationalTypeMapping.NullMapping);
MethodInfo? dynMethodO = selectExpression.GetType().GetMethod("set_Offset",

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data.Odbc;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Reflection;
@ -137,7 +139,7 @@ public class JetXunitTestRunner : XunitTestRunner
foreach (var innerException in aggregateException.Flatten().InnerExceptions.SelectMany(e => e.FlattenHierarchy()))
{
if (innerException is InvalidOperationException)
if (innerException is InvalidOperationException or OleDbException or OdbcException)
{
var message = innerException.Message;
@ -149,17 +151,17 @@ public class JetXunitTestRunner : XunitTestRunner
skip = expectedUnsupportedTranslation;
unexpectedUnsupportedTranslation = !expectedUnsupportedTranslation;
}
else if (message.StartsWith("The LINQ expression '") &&
message.Contains("' could not be translated."))
else if (message.StartsWith("Unsupported Jet expression"))
{
var expectedUnsupportedTranslation = message.Contains("OUTER APPLY") ||
message.Contains("CROSS APPLY") ||
message.Contains("ROW_NUMBER() OVER") ||
message.Contains("EXCEPT") ||
message.Contains("INTERSECT");
skip = expectedUnsupportedTranslation;
unexpectedUnsupportedTranslation = !expectedUnsupportedTranslation;
skip = true;
}
else if (message.StartsWith("No value given for one or more required parameters."))
{
skip = true;
}
else if (message.StartsWith("Syntax error in PARAMETER clause"))
{
skip = true;
}
if (skip)

Loading…
Cancel
Save