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
1 change: 1 addition & 0 deletions ChangeLog/7.2.0-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[postgresql] Server-side statement timeout handled as TimeoutException
6 changes: 6 additions & 0 deletions Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/Driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ private SqlExceptionType ProcessServerSideException(PostgresException serverSide
return SqlExceptionType.Deadlock;
case "40001": // serialization_failure
return SqlExceptionType.SerializationFailure;
case "57014": {
// operation timeout due to statement_timeout setting of postgres (global or per session)
if (serverSideException.Message.Contains("statement timeout", StringComparison.OrdinalIgnoreCase))
return SqlExceptionType.OperationTimeout;
return SqlExceptionType.Unknown;
}
}

return SqlExceptionType.Unknown;
Expand Down
8 changes: 4 additions & 4 deletions Orm/Xtensive.Orm.Tests.Sql/ExceptionTypesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private class EvilThreadArgument
private const string UniqueTableName = "TheUnique";
private const string CheckedTableName = "TheChecked";

private Schema schema;
protected Schema schema;

protected override void TestFixtureSetUp()
{
Expand Down Expand Up @@ -282,12 +282,12 @@ protected virtual void AssertExceptionType(SqlExceptionType expected, SqlExcepti
Assert.AreEqual(expected, actual);
}

private void AssertExceptionType(ISqlCompileUnit statement, SqlExceptionType expectedExceptionType)
protected void AssertExceptionType(ISqlCompileUnit statement, SqlExceptionType expectedExceptionType)
{
AssertExceptionType(Connection, statement, expectedExceptionType);
}

private void AssertExceptionType(SqlConnection connection, ISqlCompileUnit statement, SqlExceptionType expectedExceptionType)
protected void AssertExceptionType(SqlConnection connection, ISqlCompileUnit statement, SqlExceptionType expectedExceptionType)
{
var commandText = Driver.Compile(statement).GetCommandText();
AssertExceptionType(connection, commandText, expectedExceptionType);
Expand All @@ -305,7 +305,7 @@ private void AssertExceptionType(SqlConnection connection, string commandText, S
Assert.Fail("Exception was not thrown");
}

private TableColumn CreatePrimaryKey(Table table)
protected TableColumn CreatePrimaryKey(Table table)
{
var column = table.CreateColumn(IdColumnName, Driver.TypeMappings[typeof (int)].MapType());
_ = table.CreatePrimaryKey("pk_" + table.Name, column);
Expand Down
52 changes: 49 additions & 3 deletions Orm/Xtensive.Orm.Tests.Sql/PostgreSql/ExceptionTypesTest.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,65 @@
// Copyright (C) 2010 Xtensive LLC.
// All rights reserved.
// For conditions of distribution and use, see license.
// Copyright (C) 2010-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
// Created: 2010.02.08

using System.Data;
using NUnit.Framework;
using Xtensive.Sql;

namespace Xtensive.Orm.Tests.Sql.PostgreSql
{
[TestFixture]
public class ExceptionTypesTest : Sql.ExceptionTypesTest
{
private const string PgTimeoutTableName = "PgTheTimeout";
private const string IdColumnName = "id";

protected override void CheckRequirements()
{
Require.ProviderIs(StorageProvider.PostgreSql);
}

protected override void TestFixtureSetUp()
{
base.TestFixtureSetUp();
Connection.BeginTransaction();
EnsureTableNotExists(schema, PgTimeoutTableName);
Connection.Commit();
}

[Test]
public void PostgreSqlServerSideTimeout()
{
Connection.BeginTransaction();
var table = schema.CreateTable(PgTimeoutTableName);
_ = CreatePrimaryKey(table);
_ = ExecuteNonQuery(SqlDdl.Create(table));
Connection.Commit();

var tableRef = SqlDml.TableRef(table);
var insert = SqlDml.Insert(tableRef);
insert.AddValueRow((tableRef[IdColumnName], 1));

using (var connectionOne = Driver.CreateConnection()) {
connectionOne.Open();
connectionOne.BeginTransaction();
using (var command = connectionOne.CreateCommand()) {
command.CommandText = "SET statement_timeout = 15";
_ = command.ExecuteNonQuery();
}

using (var connectionTwo = Driver.CreateConnection()) {
connectionTwo.Open();
connectionTwo.BeginTransaction(IsolationLevel.ReadCommitted);

using (var command = connectionTwo.CreateCommand(insert)) {
_ = command.ExecuteNonQuery();
}
AssertExceptionType(connectionOne, insert, SqlExceptionType.OperationTimeout);
}
}
}
}
}