@@ -608,6 +608,7 @@ typedef struct
608
608
609
609
int use_file ; /* index in sql_script for this client */
610
610
int command ; /* command number in script */
611
+ int num_syncs ; /* number of ongoing sync commands */
611
612
612
613
/* client variables */
613
614
Variables variables ;
@@ -697,6 +698,7 @@ typedef enum MetaCommand
697
698
META_ELSE , /* \else */
698
699
META_ENDIF , /* \endif */
699
700
META_STARTPIPELINE , /* \startpipeline */
701
+ META_SYNCPIPELINE , /* \syncpipeline */
700
702
META_ENDPIPELINE , /* \endpipeline */
701
703
} MetaCommand ;
702
704
@@ -2902,6 +2904,8 @@ getMetaCommand(const char *cmd)
2902
2904
mc = META_ASET ;
2903
2905
else if (pg_strcasecmp (cmd , "startpipeline" ) == 0 )
2904
2906
mc = META_STARTPIPELINE ;
2907
+ else if (pg_strcasecmp (cmd , "syncpipeline" ) == 0 )
2908
+ mc = META_SYNCPIPELINE ;
2905
2909
else if (pg_strcasecmp (cmd , "endpipeline" ) == 0 )
2906
2910
mc = META_ENDPIPELINE ;
2907
2911
else
@@ -3317,8 +3321,10 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
3317
3321
break ;
3318
3322
3319
3323
case PGRES_PIPELINE_SYNC :
3320
- pg_log_debug ("client %d pipeline ending" , st -> id );
3321
- if (PQexitPipelineMode (st -> con ) != 1 )
3324
+ pg_log_debug ("client %d pipeline ending, ongoing syncs: %d" ,
3325
+ st -> id , st -> num_syncs );
3326
+ st -> num_syncs -- ;
3327
+ if (st -> num_syncs == 0 && PQexitPipelineMode (st -> con ) != 1 )
3322
3328
pg_log_error ("client %d failed to exit pipeline mode: %s" , st -> id ,
3323
3329
PQerrorMessage (st -> con ));
3324
3330
break ;
@@ -4449,6 +4455,20 @@ executeMetaCommand(CState *st, pg_time_usec_t *now)
4449
4455
return CSTATE_ABORTED ;
4450
4456
}
4451
4457
}
4458
+ else if (command -> meta == META_SYNCPIPELINE )
4459
+ {
4460
+ if (PQpipelineStatus (st -> con ) != PQ_PIPELINE_ON )
4461
+ {
4462
+ commandFailed (st , "syncpipeline" , "not in pipeline mode" );
4463
+ return CSTATE_ABORTED ;
4464
+ }
4465
+ if (PQsendPipelineSync (st -> con ) == 0 )
4466
+ {
4467
+ commandFailed (st , "syncpipeline" , "failed to send a pipeline sync" );
4468
+ return CSTATE_ABORTED ;
4469
+ }
4470
+ st -> num_syncs ++ ;
4471
+ }
4452
4472
else if (command -> meta == META_ENDPIPELINE )
4453
4473
{
4454
4474
if (PQpipelineStatus (st -> con ) != PQ_PIPELINE_ON )
@@ -4461,6 +4481,7 @@ executeMetaCommand(CState *st, pg_time_usec_t *now)
4461
4481
commandFailed (st , "endpipeline" , "failed to send a pipeline sync" );
4462
4482
return CSTATE_ABORTED ;
4463
4483
}
4484
+ st -> num_syncs ++ ;
4464
4485
/* Now wait for the PGRES_PIPELINE_SYNC and exit pipeline mode there */
4465
4486
/* collect pending results before getting out of pipeline mode */
4466
4487
return CSTATE_WAIT_RESULT ;
@@ -5794,7 +5815,8 @@ process_backslash_command(PsqlScanState sstate, const char *source)
5794
5815
}
5795
5816
else if (my_command -> meta == META_ELSE || my_command -> meta == META_ENDIF ||
5796
5817
my_command -> meta == META_STARTPIPELINE ||
5797
- my_command -> meta == META_ENDPIPELINE )
5818
+ my_command -> meta == META_ENDPIPELINE ||
5819
+ my_command -> meta == META_SYNCPIPELINE )
5798
5820
{
5799
5821
if (my_command -> argc != 1 )
5800
5822
syntax_error (source , lineno , my_command -> first_line , my_command -> argv [0 ],
0 commit comments