@@ -47,29 +47,74 @@ namespace Npgsql
4747 public sealed partial class NpgsqlCommand : DbCommand , ICloneable
4848 {
4949 /// <summary>
50- /// Slightly optimised version of ExecuteNonQuery() for internal use in cases where the number
50+ /// Internal query shortcut for use in cases where the number
5151 /// of affected rows is of no interest.
52- /// This function must not be called with a query that returns result rows, after calling Prepare(), or.
53- /// with a query that requires parameter substitution of any kind.
5452 /// </summary>
55- internal void ExecuteBlind ( )
53+ internal static void ExecuteBlind ( NpgsqlConnector connector , byte [ ] command , int timeout = 20 )
5654 {
5755 NpgsqlQuery query ;
5856
59- // Bypass cpmmand parsing overhead and send commandText verbatim.
60- query = NpgsqlQuery . Create ( m_Connector . BackendProtocolVersion , commandText ) ;
57+ connector . SetBackendCommandTimeout ( timeout ) ;
58+
59+ // Bypass cpmmand parsing overhead and send command verbatim.
60+ query = NpgsqlQuery . Create ( connector . BackendProtocolVersion , command ) ;
61+
62+ // Block the notification thread before writing anything to the wire.
63+ using ( var blocker = connector . BlockNotificationThread ( ) )
64+ {
65+ // Write the Query message to the wire.
66+ connector . Query ( query ) ;
67+
68+ // Flush, and wait for and discard all responses.
69+ connector . ProcessAndDiscardBackendResponses ( ) ;
70+ }
71+ }
72+
73+ /// <summary>
74+ /// Internal query shortcut for use in cases where the number
75+ /// of affected rows is of no interest.
76+ /// </summary>
77+ internal static void ExecuteBlind ( NpgsqlConnector connector , string command , int timeout = 20 )
78+ {
79+ NpgsqlQuery query ;
80+
81+ connector . SetBackendCommandTimeout ( timeout ) ;
82+
83+ // Bypass cpmmand parsing overhead and send command verbatim.
84+ query = NpgsqlQuery . Create ( connector . BackendProtocolVersion , command ) ;
6185
6286 // Block the notification thread before writing anything to the wire.
63- using ( var blocker = m_Connector . BlockNotificationThread ( ) )
87+ using ( var blocker = connector . BlockNotificationThread ( ) )
6488 {
6589 // Write the Query message to the wire.
66- m_Connector . Query ( query ) ;
90+ connector . Query ( query ) ;
6791
6892 // Flush, and wait for and discard all responses.
69- m_Connector . ProcessAndDiscardBackendResponses ( ) ;
93+ connector . ProcessAndDiscardBackendResponses ( ) ;
7094 }
7195 }
7296
97+ /// <summary>
98+ /// Special adaptation of ExecuteBlind() that sets statement_timeout.
99+ /// This exists to prevent Connector.SetBackendCommandTimeout() from calling Command.ExecuteBlind(),
100+ /// which will cause an endless recursive loop.
101+ /// </summary>
102+ /// <param name="connector"></param>
103+ /// <param name="timeout">Timeout in seconds.</param>
104+ internal static void ExecuteSetStatementTimeoutBlind ( NpgsqlConnector connector , int timeout )
105+ {
106+ NpgsqlQuery query ;
107+
108+ // Bypass cpmmand parsing overhead and send command verbatim.
109+ query = NpgsqlQuery . Create ( connector . BackendProtocolVersion , string . Format ( "SET statement_timeout = {0}" , timeout * 1000 ) ) ;
110+
111+ // Write the Query message to the wire.
112+ connector . Query ( query ) ;
113+
114+ // Flush, and wait for and discard all responses.
115+ connector . ProcessAndDiscardBackendResponses ( ) ;
116+ }
117+
73118 /// <summary>
74119 /// Executes a SQL statement against the connection and returns the number of rows affected.
75120 /// </summary>
@@ -394,13 +439,8 @@ private void PrepareInternal()
394439 planName = Connector . NextPlanName ( ) ;
395440 preparedCommandText = GetCommandText ( true , false ) ;
396441
397- // BackendEncoding.UTF8Encoding.GetString() is temporary. A new optimization for
398- // ExecuteBlind() will negate the need.
399- using ( NpgsqlCommand command = new NpgsqlCommand ( BackendEncoding . UTF8Encoding . GetString ( preparedCommandText ) , m_Connector ) )
400- {
401- command . ExecuteBlind ( ) ;
402- prepared = PrepareStatus . V2Prepared ;
403- }
442+ ExecuteBlind ( m_Connector , preparedCommandText ) ;
443+ prepared = PrepareStatus . V2Prepared ;
404444
405445 // Tell to mediator what command is being sent.
406446 m_Connector . Mediator . SetSqlSent ( preparedCommandText , NpgsqlMediator . SQLSentType . Prepare ) ;
0 commit comments