@@ -214,6 +214,65 @@ describe('PostgreSQL Connector Integration Tests', () => {
214214 postgresTest . createErrorHandlingTests ( ) ;
215215 postgresTest . createSSLTests ( ) ;
216216 describe ( 'PostgreSQL-specific Features' , ( ) => {
217+ it ( 'should cancel a timed-out query on the PostgreSQL server' , async ( ) => {
218+ const timedConnector = new PostgresConnector ( ) ;
219+ const observer = new PostgresConnector ( ) ;
220+ const probe = 'dbhub_query_timeout_probe' ;
221+
222+ const runningProbeCount = async ( ) : Promise < number > => {
223+ const result = await observer . executeSQL (
224+ `SELECT count(*)::int AS count
225+ FROM pg_stat_activity
226+ WHERE state = 'active'
227+ AND query LIKE '%${ probe } %'
228+ AND query NOT LIKE '%pg_stat_activity%'` ,
229+ { }
230+ ) ;
231+ return result . resultSets [ 0 ] . rows [ 0 ] . count ;
232+ } ;
233+
234+ const waitFor = async (
235+ predicate : ( ) => Promise < boolean > ,
236+ timeoutMs : number
237+ ) : Promise < boolean > => {
238+ const deadline = Date . now ( ) + timeoutMs ;
239+ while ( Date . now ( ) < deadline ) {
240+ if ( await predicate ( ) ) return true ;
241+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
242+ }
243+ return false ;
244+ } ;
245+
246+ try {
247+ await timedConnector . connect ( postgresTest . connectionString , undefined , {
248+ queryTimeoutSeconds : 1 ,
249+ } ) ;
250+ await observer . connect ( postgresTest . connectionString ) ;
251+
252+ const query = timedConnector . executeSQL (
253+ `SELECT pg_sleep(10), '${ probe } '` ,
254+ { readonly : true }
255+ ) ;
256+ const settled = query . then (
257+ ( ) => null ,
258+ ( error ) => error as NodeJS . ErrnoException
259+ ) ;
260+
261+ expect ( await waitFor ( async ( ) => ( await runningProbeCount ( ) ) === 1 , 5_000 ) ) . toBe ( true ) ;
262+
263+ const error = await settled ;
264+ expect ( error ) . toBeInstanceOf ( Error ) ;
265+ expect ( error ?. code ) . toBe ( '57014' ) ;
266+ expect ( await waitFor ( async ( ) => ( await runningProbeCount ( ) ) === 0 , 2_000 ) ) . toBe ( true ) ;
267+
268+ const after = await timedConnector . executeSQL ( 'SELECT 1 AS ok' , { readonly : true } ) ;
269+ expect ( after . resultSets [ 0 ] . rows [ 0 ] . ok ) . toBe ( 1 ) ;
270+ } finally {
271+ await timedConnector . disconnect ( ) ;
272+ await observer . disconnect ( ) ;
273+ }
274+ } , 20_000 ) ;
275+
217276 it ( 'should execute multiple statements with transaction support' , async ( ) => {
218277 const result = await postgresTest . connector . executeSQL ( `
219278 INSERT INTO users (name, email, age) VALUES ('Multi User 1', 'multi1@example.com', 30);
@@ -756,4 +815,4 @@ describe('PostgreSQL Connector Integration Tests', () => {
756815 }
757816 } ) ;
758817 } ) ;
759- } ) ;
818+ } ) ;
0 commit comments