@@ -24,6 +24,11 @@ cdef class CoreProtocol:
2424
2525 self ._skip_discard = False
2626
27+ # executemany support data
28+ self ._execute_iter = None
29+ self ._execute_portal_name = None
30+ self ._execute_stmt_name = None
31+
2732 self ._reset_result()
2833
2934 cdef _write(self , buf):
@@ -60,6 +65,9 @@ cdef class CoreProtocol:
6065 elif state == PROTOCOL_BIND_EXECUTE:
6166 self ._process__bind_execute(mtype)
6267
68+ elif state == PROTOCOL_BIND_EXECUTE_MANY:
69+ self ._process__bind_execute_many(mtype)
70+
6371 elif state == PROTOCOL_EXECUTE:
6472 self ._process__bind_execute(mtype)
6573
@@ -194,6 +202,49 @@ cdef class CoreProtocol:
194202 # EmptyQueryResponse
195203 self .buffer.consume_message()
196204
205+ cdef _process__bind_execute_many(self , char mtype):
206+ cdef WriteBuffer buf
207+
208+ if mtype == b' D' :
209+ # DataRow
210+ self ._parse_data_msgs()
211+
212+ elif mtype == b' s' :
213+ # PortalSuspended
214+ self .buffer.consume_message()
215+
216+ elif mtype == b' C' :
217+ # CommandComplete
218+ self ._parse_msg_command_complete()
219+
220+ elif mtype == b' E' :
221+ # ErrorResponse
222+ self ._parse_msg_error_response(True )
223+
224+ elif mtype == b' 2' :
225+ # BindComplete
226+ self .buffer.consume_message()
227+
228+ elif mtype == b' Z' :
229+ # ReadyForQuery
230+ self ._parse_msg_ready_for_query()
231+ if self .result_type == RESULT_FAILED:
232+ self ._push_result()
233+ else :
234+ try :
235+ buf = < WriteBuffer> next(self ._execute_iter)
236+ except StopIteration :
237+ self ._push_result()
238+ else :
239+ # Next iteration over the executemany() arg sequence
240+ self ._send_bind_message(
241+ self ._execute_portal_name, self ._execute_stmt_name,
242+ buf, 0 )
243+
244+ elif mtype == b' I' :
245+ # EmptyQueryResponse
246+ self .buffer.consume_message()
247+
197248 cdef _process__bind(self , char mtype):
198249 if mtype == b' E' :
199250 # ErrorResponse
@@ -275,6 +326,14 @@ cdef class CoreProtocol:
275326 raise RuntimeError (
276327 ' _parse_data_msgs: first message is not "D"' )
277328
329+ if self ._discard_data:
330+ while True :
331+ buf.consume_message()
332+ if not buf.has_message() or buf.get_message_type() != b' D' :
333+ self ._skip_discard = True
334+ return
335+
336+ if ASYNCPG_DEBUG:
278337 if type (self .result) is not list :
279338 raise RuntimeError (
280339 ' _parse_data_msgs: result is not a list, but {!r}' .
@@ -424,6 +483,7 @@ cdef class CoreProtocol:
424483 self .result_row_desc = None
425484 self .result_status_msg = None
426485 self .result_execute_completed = False
486+ self ._discard_data = False
427487
428488 cdef _set_state(self , ProtocolState new_state):
429489 if new_state == PROTOCOL_IDLE:
@@ -537,16 +597,11 @@ cdef class CoreProtocol:
537597
538598 self .transport.write(memoryview(packet))
539599
540- cdef _bind_execute (self , str portal_name, str stmt_name,
541- WriteBuffer bind_data, int32_t limit):
600+ cdef _send_bind_message (self , str portal_name, str stmt_name,
601+ WriteBuffer bind_data, int32_t limit):
542602
543603 cdef WriteBuffer buf
544604
545- self ._ensure_connected()
546- self ._set_state(PROTOCOL_BIND_EXECUTE)
547-
548- self .result = []
549-
550605 buf = self ._build_bind_message(portal_name, stmt_name, bind_data)
551606 self ._write(buf)
552607
@@ -558,6 +613,39 @@ cdef class CoreProtocol:
558613
559614 self ._write_sync_message()
560615
616+ cdef _bind_execute(self , str portal_name, str stmt_name,
617+ WriteBuffer bind_data, int32_t limit):
618+
619+ cdef WriteBuffer buf
620+
621+ self ._ensure_connected()
622+ self ._set_state(PROTOCOL_BIND_EXECUTE)
623+
624+ self .result = []
625+
626+ self ._send_bind_message(portal_name, stmt_name, bind_data, limit)
627+
628+ cdef _bind_execute_many(self , str portal_name, str stmt_name,
629+ object bind_data):
630+
631+ cdef WriteBuffer buf
632+
633+ self ._ensure_connected()
634+ self ._set_state(PROTOCOL_BIND_EXECUTE_MANY)
635+
636+ self .result = None
637+ self ._discard_data = True
638+ self ._execute_iter = bind_data
639+ self ._execute_portal_name = portal_name
640+ self ._execute_stmt_name = stmt_name
641+
642+ try :
643+ buf = < WriteBuffer> next(bind_data)
644+ except StopIteration :
645+ self ._push_result()
646+ else :
647+ self ._send_bind_message(portal_name, stmt_name, buf, 0 )
648+
561649 cdef _execute(self , str portal_name, int32_t limit):
562650 cdef WriteBuffer buf
563651
0 commit comments