@@ -1674,25 +1674,55 @@ func (rr *ResultReader) concludeCommand(commandTag CommandTag, err error) {
16741674// Batch is a collection of queries that can be sent to the PostgreSQL server in a single round-trip.
16751675type Batch struct {
16761676 buf []byte
1677+ err error
16771678}
16781679
16791680// ExecParams appends an ExecParams command to the batch. See PgConn.ExecParams for parameter descriptions.
16801681func (batch * Batch ) ExecParams (sql string , paramValues [][]byte , paramOIDs []uint32 , paramFormats []int16 , resultFormats []int16 ) {
1681- batch .buf = (& pgproto3.Parse {Query : sql , ParameterOIDs : paramOIDs }).Encode (batch .buf )
1682+ if batch .err != nil {
1683+ return
1684+ }
1685+
1686+ batch .buf , batch .err = (& pgproto3.Parse {Query : sql , ParameterOIDs : paramOIDs }).Encode (batch .buf )
1687+ if batch .err != nil {
1688+ return
1689+ }
16821690 batch .ExecPrepared ("" , paramValues , paramFormats , resultFormats )
16831691}
16841692
16851693// ExecPrepared appends an ExecPrepared e command to the batch. See PgConn.ExecPrepared for parameter descriptions.
16861694func (batch * Batch ) ExecPrepared (stmtName string , paramValues [][]byte , paramFormats []int16 , resultFormats []int16 ) {
1687- batch .buf = (& pgproto3.Bind {PreparedStatement : stmtName , ParameterFormatCodes : paramFormats , Parameters : paramValues , ResultFormatCodes : resultFormats }).Encode (batch .buf )
1688- batch .buf = (& pgproto3.Describe {ObjectType : 'P' }).Encode (batch .buf )
1689- batch .buf = (& pgproto3.Execute {}).Encode (batch .buf )
1695+ if batch .err != nil {
1696+ return
1697+ }
1698+
1699+ batch .buf , batch .err = (& pgproto3.Bind {PreparedStatement : stmtName , ParameterFormatCodes : paramFormats , Parameters : paramValues , ResultFormatCodes : resultFormats }).Encode (batch .buf )
1700+ if batch .err != nil {
1701+ return
1702+ }
1703+
1704+ batch .buf , batch .err = (& pgproto3.Describe {ObjectType : 'P' }).Encode (batch .buf )
1705+ if batch .err != nil {
1706+ return
1707+ }
1708+
1709+ batch .buf , batch .err = (& pgproto3.Execute {}).Encode (batch .buf )
1710+ if batch .err != nil {
1711+ return
1712+ }
16901713}
16911714
16921715// ExecBatch executes all the queries in batch in a single round-trip. Execution is implicitly transactional unless a
16931716// transaction is already in progress or SQL contains transaction control statements. This is a simpler way of executing
16941717// multiple queries in a single round trip than using pipeline mode.
16951718func (pgConn * PgConn ) ExecBatch (ctx context.Context , batch * Batch ) * MultiResultReader {
1719+ if batch .err != nil {
1720+ return & MultiResultReader {
1721+ closed : true ,
1722+ err : batch .err ,
1723+ }
1724+ }
1725+
16961726 if err := pgConn .lock (); err != nil {
16971727 return & MultiResultReader {
16981728 closed : true ,
@@ -1718,7 +1748,13 @@ func (pgConn *PgConn) ExecBatch(ctx context.Context, batch *Batch) *MultiResultR
17181748 pgConn .contextWatcher .Watch (ctx )
17191749 }
17201750
1721- batch .buf = (& pgproto3.Sync {}).Encode (batch .buf )
1751+ batch .buf , batch .err = (& pgproto3.Sync {}).Encode (batch .buf )
1752+ if batch .err != nil {
1753+ multiResult .closed = true
1754+ multiResult .err = batch .err
1755+ pgConn .unlock ()
1756+ return multiResult
1757+ }
17221758
17231759 pgConn .enterPotentialWriteReadDeadlock ()
17241760 defer pgConn .exitPotentialWriteReadDeadlock ()
0 commit comments