Skip to content

Whole transaction aborted with Protocol=7.4-2 (MS Windows) #203

Description

@ruiaurelio

Greetings.
It seems that the expectation about 'Statement(2): Rollback the statement.' (https://odbc.postgresql.org/docs/config.html) is not fulfilled, at least in the MS Windows world.
See his demonstration with Perl script:
`use strict;
use warnings;
use DBI;

my $conn_str =
'Driver={PostgreSQL Unicode(x64)};' .
'Server=localhost;' .
'Port=5432;' .
'Database=pg_crw_local;' .
'B6=1;C0=1;C8=0;' .
'Protocol=7.4-2;'
;

my $user = '';
my $password = '';

my $dbh = DBI->connect(
"dbi:ODBC:$conn_str",
$user,
$password,
{
RaiseError => 1,
PrintError => 0,
AutoCommit => 0,
LongReadLen => 65536,
LongTruncOk => 1, # optional
}
);

print "Connected successfully.\n";

sub print_locks {
my ($dbh, $when) = @_;

print "$when:\n";
my $sql = q{ SELECT pid, locktype, mode, granted, CAST(relation AS regclass) FROM pg_locks WHERE pid = pg_backend_pid(); };
my $sth = $dbh->prepare($sql);
$sth->execute();

while (my @row = $sth->fetchrow_array) {
print join(
    ' | ',
    map { defined $_ ? $_ : '<NULL>' } @row
    ), "\n";
}
$sth->finish();

}

sub print_current_txid {
my ($dbh) = @_;

my $sql = q{ SELECT txid_current(); };
my $sth = $dbh->prepare($sql);
$sth->execute();

while (my @row = $sth->fetchrow_array) {
print "$row[0]\n";
}
$sth->finish();

}

sub lock_table_in_mode {
my ($dbh, $mode) = @_;

my $sql = "LOCK TABLE PROBLEM_PARTITION_RTD_ENV IN $mode MODE;";
eval { $dbh->do($sql); };

print "err=",    ($DBI::err    // '<none>'), "\n";
print "errstr=", ($DBI::errstr // '<none>'), "\n";

}

lock_table_in_mode( $dbh, 'EXCLUSIVE' );
print_locks( $dbh, 'before error' );
print_current_txid( $dbh );
lock_table_in_mode( $dbh, 'POTATOS' );
print_locks( $dbh, 'after error' );
print_current_txid( $dbh );

$dbh->disconnect();

print "Disconnected.\n";
`

Result:
Connected successfully.
err=
errstr=
before error:
27035 | relation | AccessShareLock | 1 | pg_locks
27035 | virtualxid | ExclusiveLock | 1 |
27035 | relation | ExclusiveLock | 1 | problem_partition_rtd_env
285981
err=1
errstr=ERROR: syntax error at or near "POTATOS";
Error while executing the query (SQL-42601)
after error:
27035 | relation | AccessShareLock | 1 | pg_locks
27035 | virtualxid | ExclusiveLock | 1 |
285982
Disconnected.

So, after the wrong SQL:

  • the table lock (on my custom table 'problem_partition_rtd_env') was lost;
  • and we have a new TX ID.

It's behaving exactly like Protocol=7.4-1.
However if I change to Protocol=7.4-0 then I get "ERROR: current transaction is aborted, commands ignored until end of transaction block" as expected.

I tested this in two PostgreSQL ODBC driver versions: 17.00.0006 and 18.00.0002, same behavior.
PostgreSQL DB version is 17.5.

Bug? Useful tips/comments?

Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions