Skip to content

Commit f30a15c

Browse files
committedFeb 6, 2019
Fix Postgresql connection reset not being called
PQreset was never called if the query was made using mConnectionRO from the PostgresProvider, resulting in an always failing state. Fixes #20170
1 parent 06d5b99 commit f30a15c

File tree

2 files changed

+60
-57
lines changed

2 files changed

+60
-57
lines changed
 

‎src/providers/postgres/qgspostgresconn.cpp

Lines changed: 58 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,8 +1042,34 @@ QString QgsPostgresConn::quotedValue( const QVariant &value )
10421042
}
10431043
}
10441044

1045-
PGresult *QgsPostgresConn::PQexec( const QString &query, bool logError ) const
1045+
PGresult *QgsPostgresConn::PQexec( const QString &query, bool logError, bool retry ) const
10461046
{
1047+
QMutexLocker locker( &mLock );
1048+
1049+
QgsDebugMsgLevel( QStringLiteral( "Executing SQL: %1" ).arg( query ), 3 );
1050+
1051+
PGresult *res = ::PQexec( mConn, query.toUtf8() );
1052+
1053+
// libpq may return a non null ptr with conn status not OK so we need to check for it to allow a retry below
1054+
if ( res && PQstatus() == CONNECTION_OK )
1055+
{
1056+
int errorStatus = PQresultStatus( res );
1057+
if ( errorStatus != PGRES_COMMAND_OK && errorStatus != PGRES_TUPLES_OK )
1058+
{
1059+
if ( logError )
1060+
{
1061+
QgsMessageLog::logMessage( tr( "Erroneous query: %1 returned %2 [%3]" )
1062+
.arg( query ).arg( errorStatus ).arg( PQresultErrorMessage( res ) ),
1063+
tr( "PostGIS" ) );
1064+
}
1065+
else
1066+
{
1067+
QgsDebugMsg( QStringLiteral( "Not logged erroneous query: %1 returned %2 [%3]" )
1068+
.arg( query ).arg( errorStatus ).arg( PQresultErrorMessage( res ) ) );
1069+
}
1070+
}
1071+
return res;
1072+
}
10471073
if ( PQstatus() != CONNECTION_OK )
10481074
{
10491075
if ( logError )
@@ -1057,45 +1083,48 @@ PGresult *QgsPostgresConn::PQexec( const QString &query, bool logError ) const
10571083
QgsDebugMsg( QStringLiteral( "Connection error: %1 returned %2 [%3]" )
10581084
.arg( query ).arg( PQstatus() ).arg( PQerrorMessage() ) );
10591085
}
1060-
1061-
return nullptr;
10621086
}
1063-
1064-
QgsDebugMsgLevel( QStringLiteral( "Executing SQL: %1" ).arg( query ), 3 );
1065-
PGresult *res = nullptr;
1087+
else
10661088
{
1067-
QMutexLocker locker( &mLock );
1068-
res = ::PQexec( mConn, query.toUtf8() );
1089+
if ( logError )
1090+
{
1091+
QgsMessageLog::logMessage( tr( "Query failed: %1\nError: no result buffer" ).arg( query ), tr( "PostGIS" ) );
1092+
}
1093+
else
1094+
{
1095+
QgsDebugMsg( QStringLiteral( "Not logged query failed: %1\nError: no result buffer" ).arg( query ) );
1096+
}
1097+
}
10691098

1070-
if ( res )
1099+
if ( retry )
1100+
{
1101+
QgsMessageLog::logMessage( tr( "resetting bad connection." ), tr( "PostGIS" ) );
1102+
::PQreset( mConn );
1103+
res = PQexec( query, logError, false );
1104+
if ( PQstatus() == CONNECTION_OK )
10711105
{
1072-
int errorStatus = PQresultStatus( res );
1073-
if ( errorStatus != PGRES_COMMAND_OK && errorStatus != PGRES_TUPLES_OK )
1106+
if ( res )
10741107
{
1075-
if ( logError )
1076-
{
1077-
QgsMessageLog::logMessage( tr( "Erroneous query: %1 returned %2 [%3]" )
1078-
.arg( query ).arg( errorStatus ).arg( PQresultErrorMessage( res ) ),
1079-
tr( "PostGIS" ) );
1080-
}
1081-
else
1082-
{
1083-
QgsDebugMsg( QStringLiteral( "Not logged erroneous query: %1 returned %2 [%3]" )
1084-
.arg( query ).arg( errorStatus ).arg( PQresultErrorMessage( res ) ) );
1085-
}
1108+
QgsMessageLog::logMessage( tr( "retry after reset succeeded." ), tr( "PostGIS" ) );
1109+
return res;
1110+
}
1111+
else
1112+
{
1113+
QgsMessageLog::logMessage( tr( "retry after reset failed again." ), tr( "PostGIS" ) );
1114+
return nullptr;
10861115
}
1087-
}
1088-
else if ( logError )
1089-
{
1090-
QgsMessageLog::logMessage( tr( "Query failed: %1\nError: no result buffer" ).arg( query ), tr( "PostGIS" ) );
10911116
}
10921117
else
10931118
{
1094-
QgsDebugMsg( QStringLiteral( "Not logged query failed: %1\nError: no result buffer" ).arg( query ) );
1119+
QgsMessageLog::logMessage( tr( "connection still bad after reset." ), tr( "PostGIS" ) );
10951120
}
10961121
}
1122+
else
1123+
{
1124+
QgsMessageLog::logMessage( tr( "bad connection, not retrying." ), tr( "PostGIS" ) );
1125+
}
1126+
return nullptr;
10971127

1098-
return res;
10991128
}
11001129

11011130
bool QgsPostgresConn::openCursor( const QString &cursorName, const QString &sql )
@@ -1137,7 +1166,7 @@ QString QgsPostgresConn::uniqueCursorName()
11371166
return QStringLiteral( "qgis_%1" ).arg( ++mNextCursorId );
11381167
}
11391168

1140-
bool QgsPostgresConn::PQexecNR( const QString &query, bool retry )
1169+
bool QgsPostgresConn::PQexecNR( const QString &query )
11411170
{
11421171
QMutexLocker locker( &mLock ); // to protect access to mOpenCursors
11431172

@@ -1165,32 +1194,6 @@ bool QgsPostgresConn::PQexecNR( const QString &query, bool retry )
11651194
{
11661195
PQexecNR( QStringLiteral( "ROLLBACK" ) );
11671196
}
1168-
else if ( retry )
1169-
{
1170-
QgsMessageLog::logMessage( tr( "resetting bad connection." ), tr( "PostGIS" ) );
1171-
::PQreset( mConn );
1172-
if ( PQstatus() == CONNECTION_OK )
1173-
{
1174-
if ( PQexecNR( query, false ) )
1175-
{
1176-
QgsMessageLog::logMessage( tr( "retry after reset succeeded." ), tr( "PostGIS" ) );
1177-
return true;
1178-
}
1179-
else
1180-
{
1181-
QgsMessageLog::logMessage( tr( "retry after reset failed again." ), tr( "PostGIS" ) );
1182-
return false;
1183-
}
1184-
}
1185-
else
1186-
{
1187-
QgsMessageLog::logMessage( tr( "connection still bad after reset." ), tr( "PostGIS" ) );
1188-
}
1189-
}
1190-
else
1191-
{
1192-
QgsMessageLog::logMessage( tr( "bad connection, not retrying." ), tr( "PostGIS" ) );
1193-
}
11941197

11951198
return false;
11961199
}

‎src/providers/postgres/qgspostgresconn.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ class QgsPostgresConn : public QObject
228228
int pgVersion() { return mPostgresqlVersion; }
229229

230230
//! run a query and free result buffer
231-
bool PQexecNR( const QString &query, bool retry = true );
231+
bool PQexecNR( const QString &query );
232232

233233
//! cursor handling
234234
bool openCursor( const QString &cursorName, const QString &declare );
@@ -245,7 +245,7 @@ class QgsPostgresConn : public QObject
245245
//
246246

247247
// run a query and check for errors, thread-safe
248-
PGresult *PQexec( const QString &query, bool logError = true ) const;
248+
PGresult *PQexec( const QString &query, bool logError = true, bool retry = true ) const;
249249
void PQfinish();
250250
QString PQerrorMessage() const;
251251
int PQstatus() const;

0 commit comments

Comments
 (0)
Please sign in to comment.