Skip to content

Commit

Permalink
Handle nested primary functions
Browse files Browse the repository at this point in the history
Fixes #598
  • Loading branch information
MarkMpn committed Dec 4, 2024
1 parent ecb4f3d commit 3ae08b5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
30 changes: 29 additions & 1 deletion MarkMpn.Sql4Cds.Engine.Tests/AdoProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2930,7 +2930,7 @@ public void ErrorOnTruncateGuid()
}

[TestMethod]
public void ErrorOnTruncateEntityReferenc()
public void ErrorOnTruncateEntityReference()
{
using (var con = new Sql4CdsConnection(_localDataSources))
using (var cmd = con.CreateCommand())
Expand All @@ -2951,5 +2951,33 @@ public void ErrorOnTruncateEntityReferenc()
}
}
}

[TestMethod]
public void NestedPrimaryFunctions()
{
using (var con = new Sql4CdsConnection(_localDataSources))
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO account (name) VALUES ('Data8')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO account (name) VALUES (null)";
cmd.ExecuteNonQuery();

cmd.CommandText = "SELECT name, MAX(IIF(name = 'Data8', COALESCE(turnover, -1), 0)) FROM account GROUP BY name";

using (var reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());
Assert.IsTrue(reader.IsDBNull(0));
Assert.AreEqual(0, reader.GetDecimal(1));

Assert.IsTrue(reader.Read());
Assert.AreEqual("Data8", reader.GetString(0));
Assert.AreEqual(-1, reader.GetDecimal(1));

Assert.IsFalse(reader.Read());
}
}
}
}
}
30 changes: 18 additions & 12 deletions MarkMpn.Sql4Cds.Engine/Visitors/ReplacePrimaryFunctionsVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ protected override ScalarExpression ReplaceExpression(ScalarExpression expressio
ThenExpression = expr
});

caseExpr.Accept(this);
return caseExpr;
}

Expand All @@ -42,13 +43,14 @@ protected override ScalarExpression ReplaceExpression(ScalarExpression expressio
{
new SearchedWhenClause
{
WhenExpression = iif.Predicate,
ThenExpression = iif.ThenExpression
WhenExpression = iif.Predicate.Clone(),
ThenExpression = iif.ThenExpression.Clone()
}
},
ElseExpression = iif.ElseExpression
ElseExpression = iif.ElseExpression.Clone()
};

caseExpr.Accept(this);
return caseExpr;
}

Expand All @@ -60,8 +62,9 @@ protected override ScalarExpression ReplaceExpression(ScalarExpression expressio
};

foreach (var param in left.Parameters)
leftFunc.Parameters.Add(param);
leftFunc.Parameters.Add(param.Clone());

leftFunc.Accept(this);
return leftFunc;
}

Expand All @@ -75,16 +78,17 @@ protected override ScalarExpression ReplaceExpression(ScalarExpression expressio
{
WhenExpression = new BooleanComparisonExpression
{
ComparisonType = BooleanComparisonType.Equals,
FirstExpression = nullif.FirstExpression.Clone(),
SecondExpression = nullif.SecondExpression
ComparisonType = BooleanComparisonType.Equals,
SecondExpression = nullif.SecondExpression.Clone()
},
ThenExpression = new NullLiteral()
}
},
ElseExpression = nullif.FirstExpression
ElseExpression = nullif.FirstExpression.Clone()
};

caseExpr.Accept(this);
return caseExpr;
}

Expand All @@ -96,8 +100,9 @@ protected override ScalarExpression ReplaceExpression(ScalarExpression expressio
};

foreach (var param in right.Parameters)
rightFunc.Parameters.Add(param);
rightFunc.Parameters.Add(param.Clone());

rightFunc.Accept(this);
return rightFunc;
}

Expand Down Expand Up @@ -126,9 +131,9 @@ protected override BooleanExpression ReplaceExpression(BooleanExpression express
{
FirstExpression = new BooleanComparisonExpression
{
FirstExpression = between.FirstExpression,
FirstExpression = between.FirstExpression.Clone(),
ComparisonType = between.TernaryExpressionType == BooleanTernaryExpressionType.Between ? BooleanComparisonType.GreaterThanOrEqualTo : BooleanComparisonType.LessThan,
SecondExpression = between.SecondExpression,
SecondExpression = between.SecondExpression.Clone(),

FirstTokenIndex = between.FirstTokenIndex,
LastTokenIndex = between.LastTokenIndex,
Expand All @@ -137,9 +142,9 @@ protected override BooleanExpression ReplaceExpression(BooleanExpression express
BinaryExpressionType = between.TernaryExpressionType == BooleanTernaryExpressionType.Between ? BooleanBinaryExpressionType.And : BooleanBinaryExpressionType.Or,
SecondExpression = new BooleanComparisonExpression
{
FirstExpression = between.FirstExpression,
FirstExpression = between.FirstExpression.Clone(),
ComparisonType = between.TernaryExpressionType == BooleanTernaryExpressionType.Between ? BooleanComparisonType.LessThanOrEqualTo : BooleanComparisonType.GreaterThan,
SecondExpression = between.ThirdExpression,
SecondExpression = between.ThirdExpression.Clone(),

FirstTokenIndex = between.FirstTokenIndex,
LastTokenIndex = between.LastTokenIndex,
Expand All @@ -156,6 +161,7 @@ protected override BooleanExpression ReplaceExpression(BooleanExpression express
ScriptTokenStream = between.ScriptTokenStream
};

converted.Accept(this);
return converted;
}

Expand Down

0 comments on commit 3ae08b5

Please sign in to comment.