Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions src/EFCore.PG/Query/Expressions/Internal/ArrayAnyAllExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,20 @@ public ArrayAnyAllExpression(

/// <inheritdoc />
protected override Expression Accept(ExpressionVisitor visitor)
=> visitor is NpgsqlQuerySqlGenerator npsgqlGenerator
? npsgqlGenerator.VisitArrayAnyAll(this)
=> visitor is NpgsqlQuerySqlGenerator npgsqlGenerator
? npgsqlGenerator.VisitArrayAnyAll(this)
: base.Accept(visitor);

/// <inheritdoc />
protected override Expression VisitChildren(ExpressionVisitor visitor)
{
if (!(visitor.Visit(Operand) is Expression operand))
throw new ArgumentException($"The {nameof(operand)} of a {nameof(ArrayAnyAllExpression)} cannot be null.");

if (!(visitor.Visit(Array) is Expression collection))
throw new ArgumentException($"The {nameof(collection)} of a {nameof(ArrayAnyAllExpression)} cannot be null.");
var operand = visitor.Visit(Operand) ?? Operand;
var array = visitor.Visit(Array) ?? Array;

return
operand == Operand && collection == Array
? this
: new ArrayAnyAllExpression(ArrayComparisonType, Operator, operand, collection);
operand != Operand || array != Array
? new ArrayAnyAllExpression(ArrayComparisonType, Operator, operand, array)
: this;
}

/// <inheritdoc />
Expand All @@ -131,8 +128,7 @@ public override int GetHashCode()
(397 * Array.GetHashCode()));

/// <inheritdoc />
public override string ToString()
=> $"{Operand} {Operator} {ArrayComparisonType.ToString()} ({Array})";
public override string ToString() => $"{Operand} {Operator} {ArrayComparisonType.ToString()} ({Array})";
}

/// <summary>
Expand Down
61 changes: 40 additions & 21 deletions src/EFCore.PG/Query/Expressions/Internal/AtTimeZoneExpression.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#region License

// The PostgreSQL License
//
// Copyright (C) 2016 The Npgsql Development Team
Expand All @@ -19,6 +20,7 @@
// AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
// ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

#endregion

using System;
Expand All @@ -29,42 +31,59 @@

namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal
{
/// <summary>
/// Represents a PostgreSQL AT TIME ZONE expression.
/// </summary>
public class AtTimeZoneExpression : Expression
{
public AtTimeZoneExpression([NotNull] Expression timestampExpression, [NotNull] string timeZone)
{
Check.NotNull(timestampExpression, nameof(timestampExpression));
Check.NotNull(timeZone, nameof(timeZone));

TimestampExpression = timestampExpression;
TimeZone = timeZone;
}

public Expression TimestampExpression { get; }
public string TimeZone { get; }

/// <inheritdoc />
public override ExpressionType NodeType => ExpressionType.Extension;

/// <inheritdoc />
public override Type Type => typeof(DateTime);

protected override Expression Accept([NotNull] ExpressionVisitor visitor)
/// <summary>
/// The timestamp.
/// </summary>
[NotNull]
public Expression Timestamp { get; }

/// <summary>
/// The time zone.
/// </summary>
[NotNull]
public string TimeZone { get; }

/// <summary>
/// Constructs an <see cref="AtTimeZoneExpression"/>.
/// </summary>
/// <param name="timestamp">The timestamp.</param>
/// <param name="timeZone">The time zone.</param>
/// <exception cref="ArgumentNullException" />
public AtTimeZoneExpression([NotNull] Expression timestamp, [NotNull] string timeZone)
{
Check.NotNull(visitor, nameof(visitor));
Timestamp = Check.NotNull(timestamp, nameof(timestamp));
TimeZone = Check.NotNull(timeZone, nameof(timeZone));
}

return visitor is NpgsqlQuerySqlGenerator npgsqlGenerator
/// <inheritdoc />
protected override Expression Accept(ExpressionVisitor visitor)
=> visitor is NpgsqlQuerySqlGenerator npgsqlGenerator
? npgsqlGenerator.VisitAtTimeZone(this)
: base.Accept(visitor);
}

/// <inheritdoc />
protected override Expression VisitChildren(ExpressionVisitor visitor)
{
var newTimestampExpression = visitor.Visit(TimestampExpression);
var timestamp = visitor.Visit(Timestamp) ?? Timestamp;

return newTimestampExpression != TimestampExpression
? new AtTimeZoneExpression(newTimestampExpression, TimeZone)
: this;
return
timestamp != Timestamp
? new AtTimeZoneExpression(timestamp, TimeZone)
: this;
}

public override string ToString() => $"{TimestampExpression} AT TIME ZONE {TimeZone}";
/// <inheritdoc />
public override string ToString() => $"{Timestamp} AT TIME ZONE {TimeZone}";
}
}
74 changes: 46 additions & 28 deletions src/EFCore.PG/Query/Expressions/Internal/CustomBinaryExpression.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query.Sql.Internal;
using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities;
using NpgsqlTypes;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal
{
Expand All @@ -14,49 +12,69 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal
/// </summary>
public class CustomBinaryExpression : Expression
{
/// <inheritdoc />
public override ExpressionType NodeType => ExpressionType.Extension;

/// <inheritdoc />
public override Type Type { get; }

/// <summary>
/// The left-hand expression.
/// </summary>
[NotNull]
public Expression Left { get; }

/// <summary>
/// The right-hand expression.
/// </summary>
[NotNull]
public Expression Right { get; }

/// <summary>
/// The operator.
/// </summary>
[NotNull]
public string Operator { get; }

/// <summary>
/// Constructs a <see cref="CustomBinaryExpression"/>.
/// </summary>
/// <param name="left">The left-hand expression.</param>
/// <param name="right">The right-hand expression.</param>
/// <param name="binaryOperator">The operator symbol acting on the expression.</param>
/// <param name="type">The result type.</param>
/// <exception cref="ArgumentNullException" />
public CustomBinaryExpression(
[NotNull] Expression left,
[NotNull] Expression right,
[NotNull] string binaryOperator,
[NotNull] Type type)
{
Check.NotNull(right, nameof(right));
Check.NotNull(left, nameof(left));
Check.NotEmpty(binaryOperator, nameof(binaryOperator));
Check.NotNull(type, nameof(type));

Left = left;
Right = right;
Operator = binaryOperator;
Type = type;
Left = Check.NotNull(left, nameof(left));
Right = Check.NotNull(right, nameof(right));
Operator = Check.NotEmpty(binaryOperator, nameof(binaryOperator));
Type = Check.NotNull(type, nameof(type));
}

public Expression Left { get; }
public Expression Right { get; }
public string Operator { get; }
public override Type Type { get; }

public override ExpressionType NodeType => ExpressionType.Extension;

/// <inheritdoc />
protected override Expression Accept(ExpressionVisitor visitor)
{
Check.NotNull(visitor, nameof(visitor));

return visitor is NpgsqlQuerySqlGenerator npgsqlGenerator
=> visitor is NpgsqlQuerySqlGenerator npgsqlGenerator
? npgsqlGenerator.VisitCustomBinary(this)
: base.Accept(visitor);
}

/// <inheritdoc />
protected override Expression VisitChildren(ExpressionVisitor visitor)
{
var newLeft = visitor.Visit(Left);
var newRight = visitor.Visit(Right);
var left = visitor.Visit(Left) ?? Left;
var right = visitor.Visit(Right) ?? Right;

return newLeft != Left || newRight != Right
? new CustomBinaryExpression(newLeft, newRight, Operator, Type)
: this;
return
left != Left || right != Right
? new CustomBinaryExpression(left, right, Operator, Type)
: this;
}

/// <inheritdoc />
public override string ToString() => $"{Left} {Operator} {Right}";
}
}
76 changes: 46 additions & 30 deletions src/EFCore.PG/Query/Expressions/Internal/CustomUnaryExpression.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query.Sql.Internal;
using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities;
using NpgsqlTypes;

namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal
{
Expand All @@ -14,49 +12,67 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal
/// </summary>
public class CustomUnaryExpression : Expression
{
public CustomUnaryExpression(
[NotNull] Expression operand,
[NotNull] string @operator,
[NotNull] Type type,
bool postfix=false)
{
Check.NotNull(operand, nameof(operand));
Check.NotEmpty(@operator, nameof(@operator));
Check.NotNull(type, nameof(type));
/// <inheritdoc />
public override ExpressionType NodeType => ExpressionType.Extension;

Operand = operand;
Operator = @operator;
Type = type;
Postfix = postfix;
}
/// <inheritdoc />
public override Type Type { get; }

/// <summary>
/// The expression acted on by the operator.
/// </summary>
[NotNull]
public Expression Operand { get; }

/// <summary>
/// The operator.
/// </summary>
[NotNull]
public string Operator { get; }
public override Type Type { get; }
public bool Postfix { get; }

public override ExpressionType NodeType => ExpressionType.Extension;
/// <summary>
/// True if the operator follows the operand; otherwise, false.
/// </summary>
public bool Postfix { get; }

protected override Expression Accept(ExpressionVisitor visitor)
/// <summary>
/// Constructs a <see cref="CustomUnaryExpression"/>.
/// </summary>
/// <param name="operand">The expression acted on by the <paramref name="unaryOperator"/>.</param>
/// <param name="unaryOperator">The operator symbol acting on the expression.</param>
/// <param name="type">The result type.</param>
/// <param name="postfix">True if the <paramref name="unaryOperator"/> follows the operand; otherwise, false.</param>
/// <exception cref="ArgumentNullException" />
public CustomUnaryExpression(
[NotNull] Expression operand,
[NotNull] string unaryOperator,
[NotNull] Type type,
bool postfix = false)
{
Check.NotNull(visitor, nameof(visitor));
Operand = Check.NotNull(operand, nameof(operand));
Operator = Check.NotEmpty(unaryOperator, nameof(unaryOperator));
Type = Check.NotNull(type, nameof(type));
Postfix = postfix;
}

return visitor is NpgsqlQuerySqlGenerator npgsqlGenerator
/// <inheritdoc />
protected override Expression Accept(ExpressionVisitor visitor)
=> visitor is NpgsqlQuerySqlGenerator npgsqlGenerator
? npgsqlGenerator.VisitCustomUnary(this)
: base.Accept(visitor);
}

/// <inheritdoc />
protected override Expression VisitChildren(ExpressionVisitor visitor)
{
var newOperand = visitor.Visit(Operand);
var operand = visitor.Visit(Operand) ?? Operand;

return newOperand != Operand
? new CustomUnaryExpression(newOperand, Operator, Type)
: this;
return
operand != Operand
? new CustomUnaryExpression(operand, Operator, Type)
: this;
}

public override string ToString() => Postfix
? $"{Operator}{Operand}"
: $"{Operand}{Operator}";
/// <inheritdoc />
public override string ToString() => Postfix ? $"{Operator}{Operand}" : $"{Operand}{Operator}";
}
}
Loading