Skip to content

Apply 'trim_scale' function to results of aggregation to improve compatibility with .NET decimal #436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 26, 2025
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
1 change: 1 addition & 0 deletions ChangeLog/7.1.6-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[postgresql] For PostgreSQL 13+ apply 'trim_scale' function to results of aggregation to improve compatibility with .NET decimal
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2008-2020 Xtensive LLC.
// Copyright (C) 2008-2025 Xtensive LLC.
// This code is distributed under MIT license terms.
// See the License.txt file in the project root for more information.
// Created by: Alexey Gamzov
Expand All @@ -18,15 +18,24 @@ namespace Xtensive.Orm.Providers.PostgreSql
/// </summary>
public class DomainHandler : Providers.DomainHandler
{
/// <summary>
/// <see langword="true"/> if storage can trim insignificant zeros in numeric values
/// </summary>
protected bool HasNativeTrimOfInsignificantZerosInDecimals =>
Handlers.ProviderInfo.StorageVersion.Major >= 13;

/// <inheritdoc/>
protected override ICompiler CreateCompiler(CompilerConfiguration configuration) =>
new SqlCompiler(Handlers, configuration);

/// <inheritdoc/>
protected override IPreCompiler CreatePreCompiler(CompilerConfiguration configuration)
{
var decimalAggregateCorrector = new AggregateOverDecimalColumnCorrector(Handlers.Domain.Model);
return new CompositePreCompiler(decimalAggregateCorrector, base.CreatePreCompiler(configuration));
if (!HasNativeTrimOfInsignificantZerosInDecimals) {
var decimalAggregateCorrector = new AggregateOverDecimalColumnCorrector(Handlers.Domain.Model);
return new CompositePreCompiler(decimalAggregateCorrector, base.CreatePreCompiler(configuration));
}
return base.CreatePreCompiler(configuration);
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Copyright (C) 2014-2020 Xtensive LLC.
// Copyright (C) 2014-2025 Xtensive LLC.
// This code is distributed under MIT license terms.
// See the License.txt file in the project root for more information.
// Created by: Alena Mikshina
// Created: 2014.05.06;

using Xtensive.Core;
using Xtensive.Sql;
using Xtensive.Sql.Dml;

namespace Xtensive.Orm.Providers.PostgreSql
Expand All @@ -16,6 +17,15 @@ namespace Xtensive.Orm.Providers.PostgreSql
/// </summary>
public class PostgresqlSqlDml
{
/// <summary>
/// Creates an expression for native "trim_scale" function call. The function is supported starting from PostgreSQL 13
/// </summary>
public static SqlExpression DecimalTrimScale(SqlExpression operand)
{
ArgumentValidator.EnsureArgumentNotNull(operand, nameof(operand));
return SqlDml.FunctionCall("TRIM_SCALE", operand);
}

#region Spatial types

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2009-2021 Xtensive LLC.
// Copyright (C) 2009-2025 Xtensive LLC.
// This code is distributed under MIT license terms.
// See the License.txt file in the project root for more information.
// Created by: Denis Krjuchkov
Expand All @@ -21,6 +21,8 @@ internal class SqlCompiler : Providers.SqlCompiler
{
private const int MaxDotnetDecimalPrecision = 28;

private readonly bool canRemoveInsignificantZerosInDecimals;

protected override SqlProvider VisitFreeText(FreeTextProvider provider)
{
var rankColumnName = provider.Header.Columns[provider.Header.Columns.Count - 1].Name;
Expand Down Expand Up @@ -61,6 +63,11 @@ protected override SqlExpression ProcessAggregate(SqlProvider source, List<SqlEx
var aggregateType = aggregateColumn.AggregateType;
var originCalculateColumn = source.Origin.Header.Columns[aggregateColumn.SourceIndex];
if (AggregateRequiresDecimalAdjustments(aggregateColumn)) {
if (canRemoveInsignificantZerosInDecimals) {
return (IsCalculatedColumn(originCalculateColumn))
? PostgresqlSqlDml.DecimalTrimScale(SqlDml.Cast(result, Driver.MapValueType(aggregateColumn.Type)))
: PostgresqlSqlDml.DecimalTrimScale(result);
}
if (!IsCalculatedColumn(originCalculateColumn)) {
// this is aggregate by one column, result will be defined by the precision and scale of the column
return result;
Expand Down Expand Up @@ -138,6 +145,7 @@ AggregateType.Min or
public SqlCompiler(HandlerAccessor handlers, CompilerConfiguration configuration)
: base(handlers, configuration)
{
canRemoveInsignificantZerosInDecimals = handlers.ProviderInfo.StorageVersion.Major >= 13;
}
}
}