Skip to content

Commit b7776f5

Browse files
authoredFeb 20, 2019
Merge pull request #9107 from AchilleAsh/fix_20170_postgis_connection_recovery
Fix Postgresql connection reset not being called in PostgisProvider
2 parents ddbd06f + f30a15c commit b7776f5

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.