[Python-modules-commits] [asyncpg] 01/04: Import asyncpg_0.7.0.orig.tar.gz

Piotr Ożarowski piotr at moszumanska.debian.org
Wed Dec 21 11:34:22 UTC 2016


This is an automated email from the git hooks/post-receive script.

piotr pushed a commit to branch master
in repository asyncpg.

commit 49e86aafb0751371624f9aea94d029f6483128a0
Author: Piotr Ożarowski <piotr at debian.org>
Date:   Tue Nov 29 12:30:50 2016 +0100

    Import asyncpg_0.7.0.orig.tar.gz
---
 Makefile                            |    2 +-
 PKG-INFO                            |    3 +-
 asyncpg.egg-info/PKG-INFO           |    3 +-
 asyncpg/cluster.py                  |    7 +-
 asyncpg/connection.py               |   21 +
 asyncpg/introspection.py            |    2 +
 asyncpg/protocol/codecs/array.pyx   |   51 +-
 asyncpg/protocol/codecs/base.pyx    |   15 +-
 asyncpg/protocol/codecs/network.pyx |   12 +-
 asyncpg/protocol/coreproto.pxd      |   20 +-
 asyncpg/protocol/coreproto.pyx      |  102 +-
 asyncpg/protocol/prepared_stmt.pyx  |   10 +-
 asyncpg/protocol/protocol.c         | 9907 ++++++++++++++++++++++-------------
 asyncpg/protocol/protocol.pyx       |   41 +-
 asyncpg/protocol/record/recordobj.c |    6 +-
 setup.cfg                           |    2 +-
 setup.py                            |   14 +-
 tests/test_codecs.py                |  102 +-
 tests/test_execute.py               |   35 +
 tests/test_prepare.py               |    5 +
 tests/test_record.py                |   37 +-
 21 files changed, 6595 insertions(+), 3802 deletions(-)

diff --git a/Makefile b/Makefile
index 8e8d826..f5402ab 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ debug:
 	$(PYTHON) setup.py build_ext --inplace --debug \
 		--cython-always \
 		--cython-annotate \
-		--cython-directives linetrace=True \
+		--cython-directives="linetrace=True" \
 		--define ASYNCPG_DEBUG,CYTHON_TRACE,CYTHON_TRACE_NOGIL
 
 
diff --git a/PKG-INFO b/PKG-INFO
index e7dcf27..542463f 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: asyncpg
-Version: 0.6.3
+Version: 0.7.0
 Summary: An asyncio PosgtreSQL driver
 Home-page: UNKNOWN
 Author: MagicStack Inc
@@ -15,5 +15,6 @@ Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Operating System :: POSIX
 Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Operating System :: Microsoft :: Windows
 Classifier: Development Status :: 4 - Beta
 Provides: asyncpg
diff --git a/asyncpg.egg-info/PKG-INFO b/asyncpg.egg-info/PKG-INFO
index e7dcf27..542463f 100644
--- a/asyncpg.egg-info/PKG-INFO
+++ b/asyncpg.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: asyncpg
-Version: 0.6.3
+Version: 0.7.0
 Summary: An asyncio PosgtreSQL driver
 Home-page: UNKNOWN
 Author: MagicStack Inc
@@ -15,5 +15,6 @@ Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Operating System :: POSIX
 Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Operating System :: Microsoft :: Windows
 Classifier: Development Status :: 4 - Beta
 Provides: asyncpg
diff --git a/asyncpg/cluster.py b/asyncpg/cluster.py
index 93ac64e..1e6faad 100644
--- a/asyncpg/cluster.py
+++ b/asyncpg/cluster.py
@@ -109,7 +109,7 @@ class Cluster:
         elif process.returncode == 3:
             return 'stopped'
         elif process.returncode == 0:
-            r = re.match(r'.*PID:\s+(\d+).*', stdout.decode())
+            r = re.match(r'.*PID\s?:\s+(\d+).*', stdout.decode())
             if not r:
                 raise ClusterError(
                     'could not parse pg_ctl status output: {}'.format(
@@ -134,8 +134,9 @@ class Cluster:
                     self._data_dir))
 
         if settings:
-            extra_args = ['-o'] + ['--{}={}'.format(k, v)
-                                   for k, v in settings.items()]
+            settings_args = ['--{}={}'.format(k, v)
+                             for k, v in settings.items()]
+            extra_args = ['-o'] + [' '.join(settings_args)]
         else:
             extra_args = []
 
diff --git a/asyncpg/connection.py b/asyncpg/connection.py
index 8910b43..604c4a0 100644
--- a/asyncpg/connection.py
+++ b/asyncpg/connection.py
@@ -148,6 +148,27 @@ class Connection:
                                                          True, timeout)
         return status.decode()
 
+    async def executemany(self, command: str, args, timeout: float=None):
+        """Execute an SQL *command* for each sequence of arguments in *args*.
+
+        Example:
+
+        .. code-block:: pycon
+
+            >>> await con.executemany('''
+            ...     INSERT INTO mytab (a) VALUES ($1, $2, $3);
+            ... ''', [(1, 2, 3), (4, 5, 6)])
+
+        :param command: Command to execute.
+        :args: An iterable containing sequences of arguments.
+        :param float timeout: Optional timeout value in seconds.
+        :return None: This method discards the results of the operations.
+
+        .. versionadded:: 0.7.0
+        """
+        stmt = await self._get_statement(command, timeout)
+        return await self._protocol.bind_execute_many(stmt, args, '', timeout)
+
     async def _get_statement(self, query, timeout):
         cache = self._stmt_cache_max_size > 0
 
diff --git a/asyncpg/introspection.py b/asyncpg/introspection.py
index b67142b..07448ee 100644
--- a/asyncpg/introspection.py
+++ b/asyncpg/introspection.py
@@ -20,6 +20,8 @@ AS (
             pg_attribute ia
             INNER JOIN pg_class c
                 ON (ia.attrelid = c.oid)
+        WHERE
+            ia.attnum > 0 AND NOT ia.attisdropped
         GROUP BY
             c.reltype
     ),
diff --git a/asyncpg/protocol/codecs/array.pyx b/asyncpg/protocol/codecs/array.pyx
index 4a2eae0..92706c4 100644
--- a/asyncpg/protocol/codecs/array.pyx
+++ b/asyncpg/protocol/codecs/array.pyx
@@ -31,6 +31,11 @@ cdef inline _is_container(object obj):
     return not _is_trivial_container(obj) and isinstance(obj, ContainerABC)
 
 
+cdef inline _is_sub_array(object obj):
+    return not _is_trivial_container(obj) and isinstance(obj, ContainerABC) \
+            and not cpython.PyTuple_Check(obj)
+
+
 cdef _get_array_shape(object obj, int32_t *dims, int32_t *ndims):
     cdef:
         int32_t mylen = len(obj)
@@ -45,7 +50,7 @@ cdef _get_array_shape(object obj, int32_t *dims, int32_t *ndims):
     dims[ndims[0] - 1] = mylen
 
     for elem in obj:
-        if _is_container(elem):
+        if _is_sub_array(elem):
             if elemlen == -2:
                 elemlen = len(elem)
                 ndims[0] += 1
@@ -133,7 +138,7 @@ cdef inline array_decode(ConnectionSettings settings, FastReadBuffer buf,
         int32_t ndims = hton.unpack_int32(buf.read(4))
         int32_t flags = hton.unpack_int32(buf.read(4))
         uint32_t elem_oid = hton.unpack_int32(buf.read(4))
-        tuple result
+        list result
         uint32_t i
         int32_t elem_len
         int64_t elem_count = 1
@@ -142,7 +147,7 @@ cdef inline array_decode(ConnectionSettings settings, FastReadBuffer buf,
         Codec elem_codec
 
     if ndims == 0:
-        result = ()
+        result = cpython.PyList_New(0)
         return result
 
     if ndims > ARRAY_MAXDIM:
@@ -169,7 +174,7 @@ cdef inline array_decode(ConnectionSettings settings, FastReadBuffer buf,
 
     if ndims == 1:
         # Fast path for flat arrays
-        result = cpython.PyTuple_New(elem_count)
+        result = cpython.PyList_New(elem_count)
 
         for i in range(elem_count):
             elem_len = hton.unpack_int32(buf.read(4))
@@ -180,7 +185,7 @@ cdef inline array_decode(ConnectionSettings settings, FastReadBuffer buf,
                 elem = decoder(settings, elem_buf, decoder_arg)
 
             cpython.Py_INCREF(elem)
-            cpython.PyTuple_SET_ITEM(result, i, elem)
+            cpython.PyList_SET_ITEM(result, i, elem)
 
     else:
         result = _nested_array_decode(settings, buf,
@@ -200,20 +205,20 @@ cdef inline _nested_array_decode(ConnectionSettings settings,
     cdef:
         int32_t elem_len
         int32_t d1, d2, d3, d4, d5, d6
-        tuple result
+        list result
         object elem
-        tuple stride1, stride2, stride3, stride4, stride5
+        list stride1, stride2, stride3, stride4, stride5
 
     # Nested array.  The approach here is dumb, but fast: rely
     # on the dimension limit and shape data using nested loops.
     # Alas, Cython doesn't have preprocessor macros.
     #
-    result = cpython.PyTuple_New(dims[0])
+    result = cpython.PyList_New(dims[0])
 
     for d1 in range(dims[0]):
-        stride1 = cpython.PyTuple_New(dims[1])
+        stride1 = cpython.PyList_New(dims[1])
         cpython.Py_INCREF(stride1)
-        cpython.PyTuple_SET_ITEM(result, d1, stride1)
+        cpython.PyList_SET_ITEM(result, d1, stride1)
 
         for d2 in range(dims[1]):
             if ndims == 2:
@@ -226,12 +231,12 @@ cdef inline _nested_array_decode(ConnectionSettings settings,
                                    decoder_arg)
 
                 cpython.Py_INCREF(elem)
-                cpython.PyTuple_SET_ITEM(stride1, d2, elem)
+                cpython.PyList_SET_ITEM(stride1, d2, elem)
 
             else:
-                stride2 = cpython.PyTuple_New(dims[2])
+                stride2 = cpython.PyList_New(dims[2])
                 cpython.Py_INCREF(stride2)
-                cpython.PyTuple_SET_ITEM(stride1, d2, stride2)
+                cpython.PyList_SET_ITEM(stride1, d2, stride2)
 
                 for d3 in range(dims[2]):
                     if ndims == 3:
@@ -244,12 +249,12 @@ cdef inline _nested_array_decode(ConnectionSettings settings,
                                            decoder_arg)
 
                         cpython.Py_INCREF(elem)
-                        cpython.PyTuple_SET_ITEM(stride2, d3, elem)
+                        cpython.PyList_SET_ITEM(stride2, d3, elem)
 
                     else:
-                        stride3 = cpython.PyTuple_New(dims[3])
+                        stride3 = cpython.PyList_New(dims[3])
                         cpython.Py_INCREF(stride3)
-                        cpython.PyTuple_SET_ITEM(stride2, d3, stride3)
+                        cpython.PyList_SET_ITEM(stride2, d3, stride3)
 
                         for d4 in range(dims[3]):
                             if ndims == 4:
@@ -262,12 +267,12 @@ cdef inline _nested_array_decode(ConnectionSettings settings,
                                                    decoder_arg)
 
                                 cpython.Py_INCREF(elem)
-                                cpython.PyTuple_SET_ITEM(stride3, d4, elem)
+                                cpython.PyList_SET_ITEM(stride3, d4, elem)
 
                             else:
-                                stride4 = cpython.PyTuple_New(dims[4])
+                                stride4 = cpython.PyList_New(dims[4])
                                 cpython.Py_INCREF(stride4)
-                                cpython.PyTuple_SET_ITEM(stride3, d4, stride4)
+                                cpython.PyList_SET_ITEM(stride3, d4, stride4)
 
                                 for d5 in range(dims[4]):
                                     if ndims == 5:
@@ -280,12 +285,12 @@ cdef inline _nested_array_decode(ConnectionSettings settings,
                                                            decoder_arg)
 
                                         cpython.Py_INCREF(elem)
-                                        cpython.PyTuple_SET_ITEM(stride4, d5, elem)
+                                        cpython.PyList_SET_ITEM(stride4, d5, elem)
 
                                     else:
-                                        stride5 = cpython.PyTuple_New(dims[5])
+                                        stride5 = cpython.PyList_New(dims[5])
                                         cpython.Py_INCREF(stride5)
-                                        cpython.PyTuple_SET_ITEM(stride4, d5, stride5)
+                                        cpython.PyList_SET_ITEM(stride4, d5, stride5)
 
                                         for d6 in range(dims[5]):
                                             elem_len = hton.unpack_int32(buf.read(4))
@@ -297,7 +302,7 @@ cdef inline _nested_array_decode(ConnectionSettings settings,
                                                                decoder_arg)
 
                                             cpython.Py_INCREF(elem)
-                                            cpython.PyTuple_SET_ITEM(stride5, d6, elem)
+                                            cpython.PyList_SET_ITEM(stride5, d6, elem)
 
     return result
 
diff --git a/asyncpg/protocol/codecs/base.pyx b/asyncpg/protocol/codecs/base.pyx
index 248bf26..54b422d 100644
--- a/asyncpg/protocol/codecs/base.pyx
+++ b/asyncpg/protocol/codecs/base.pyx
@@ -153,8 +153,14 @@ cdef class Codec:
 
             if received_elem_typ != elem_typ:
                 raise RuntimeError(
-                    'unexpected attribute data type: {}, expected {}'
-                        .format(received_elem_typ, elem_typ))
+                    'unexpected data type of composite type attribute {}: '
+                    '{!r}, expected {!r}'
+                        .format(
+                            i,
+                            TYPEMAP.get(received_elem_typ, received_elem_typ),
+                            TYPEMAP.get(elem_typ, elem_typ)
+                        )
+                )
 
             elem_len = hton.unpack_int32(buf.read(4))
             if elem_len == -1:
@@ -313,7 +319,10 @@ cdef class DataCodecConfig:
             schema = ti['ns']
             array_element_oid = ti['elemtype']
             range_subtype_oid = ti['range_subtype']
-            comp_type_attrs = ti['attrtypoids']
+            if ti['attrtypoids']:
+                comp_type_attrs = tuple(ti['attrtypoids'])
+            else:
+                comp_type_attrs = None
             base_type = ti['basetype']
 
             if array_element_oid:
diff --git a/asyncpg/protocol/codecs/network.pyx b/asyncpg/protocol/codecs/network.pyx
index 7c36986..690df46 100644
--- a/asyncpg/protocol/codecs/network.pyx
+++ b/asyncpg/protocol/codecs/network.pyx
@@ -62,7 +62,7 @@ cdef net_decode(ConnectionSettings settings, FastReadBuffer buf):
 
     addr = cpython.PyBytes_FromStringAndSize(buf.read(addrlen), addrlen)
 
-    if is_cidr:
+    if is_cidr or bits > 0:
         return _ipnet(addr).supernet(new_prefix=cpython.PyLong_FromLong(bits))
     else:
         return _ipaddr(addr)
@@ -81,8 +81,14 @@ cdef inet_encode(ConnectionSettings settings, WriteBuffer buf, obj):
     cdef:
         object ipaddr
 
-    ipaddr = _ipaddr(obj)
-    _net_encode(buf, ipaddr.version, 0, 0, ipaddr.packed)
+    try:
+        ipaddr = _ipaddr(obj)
+    except ValueError:
+        # PostgreSQL accepts *both* CIDR and host values
+        # for the host datatype.
+        cidr_encode(settings, buf, obj)
+    else:
+        _net_encode(buf, ipaddr.version, 0, 0, ipaddr.packed)
 
 
 cdef init_network_codecs():
diff --git a/asyncpg/protocol/coreproto.pxd b/asyncpg/protocol/coreproto.pxd
index 8496e01..b6845a2 100644
--- a/asyncpg/protocol/coreproto.pxd
+++ b/asyncpg/protocol/coreproto.pxd
@@ -21,10 +21,11 @@ cdef enum ProtocolState:
     PROTOCOL_AUTH = 10
     PROTOCOL_PREPARE = 11
     PROTOCOL_BIND_EXECUTE = 12
-    PROTOCOL_CLOSE_STMT_PORTAL = 13
-    PROTOCOL_SIMPLE_QUERY = 14
-    PROTOCOL_EXECUTE = 15
-    PROTOCOL_BIND = 16
+    PROTOCOL_BIND_EXECUTE_MANY = 13
+    PROTOCOL_CLOSE_STMT_PORTAL = 14
+    PROTOCOL_SIMPLE_QUERY = 15
+    PROTOCOL_EXECUTE = 16
+    PROTOCOL_BIND = 17
 
 
 cdef enum AuthenticationMessage:
@@ -67,6 +68,12 @@ cdef class CoreProtocol:
     cdef:
         ReadBuffer buffer
         bint _skip_discard
+        bint _discard_data
+
+        # executemany support data
+        object _execute_iter
+        str _execute_portal_name
+        str _execute_stmt_name
 
         ConnectionStatus con_status
         ProtocolState state
@@ -95,6 +102,7 @@ cdef class CoreProtocol:
     cdef _process__auth(self, char mtype)
     cdef _process__prepare(self, char mtype)
     cdef _process__bind_execute(self, char mtype)
+    cdef _process__bind_execute_many(self, char mtype)
     cdef _process__close_stmt_portal(self, char mtype)
     cdef _process__simple_query(self, char mtype)
     cdef _process__bind(self, char mtype)
@@ -129,8 +137,12 @@ cdef class CoreProtocol:
 
     cdef _connect(self)
     cdef _prepare(self, str stmt_name, str query)
+    cdef _send_bind_message(self, str portal_name, str stmt_name,
+                            WriteBuffer bind_data, int32_t limit)
     cdef _bind_execute(self, str portal_name, str stmt_name,
                        WriteBuffer bind_data, int32_t limit)
+    cdef _bind_execute_many(self, str portal_name, str stmt_name,
+                            object bind_data)
     cdef _bind(self, str portal_name, str stmt_name,
                WriteBuffer bind_data)
     cdef _execute(self, str portal_name, int32_t limit)
diff --git a/asyncpg/protocol/coreproto.pyx b/asyncpg/protocol/coreproto.pyx
index ccdc2c5..4ea36b2 100644
--- a/asyncpg/protocol/coreproto.pyx
+++ b/asyncpg/protocol/coreproto.pyx
@@ -24,6 +24,11 @@ cdef class CoreProtocol:
 
         self._skip_discard = False
 
+        # executemany support data
+        self._execute_iter = None
+        self._execute_portal_name = None
+        self._execute_stmt_name = None
+
         self._reset_result()
 
     cdef _write(self, buf):
@@ -60,6 +65,9 @@ cdef class CoreProtocol:
                 elif state == PROTOCOL_BIND_EXECUTE:
                     self._process__bind_execute(mtype)
 
+                elif state == PROTOCOL_BIND_EXECUTE_MANY:
+                    self._process__bind_execute_many(mtype)
+
                 elif state == PROTOCOL_EXECUTE:
                     self._process__bind_execute(mtype)
 
@@ -194,6 +202,49 @@ cdef class CoreProtocol:
             # EmptyQueryResponse
             self.buffer.consume_message()
 
+    cdef _process__bind_execute_many(self, char mtype):
+        cdef WriteBuffer buf
+
+        if mtype == b'D':
+            # DataRow
+            self._parse_data_msgs()
+
+        elif mtype == b's':
+            # PortalSuspended
+            self.buffer.consume_message()
+
+        elif mtype == b'C':
+            # CommandComplete
+            self._parse_msg_command_complete()
+
+        elif mtype == b'E':
+            # ErrorResponse
+            self._parse_msg_error_response(True)
+
+        elif mtype == b'2':
+            # BindComplete
+            self.buffer.consume_message()
+
+        elif mtype == b'Z':
+            # ReadyForQuery
+            self._parse_msg_ready_for_query()
+            if self.result_type == RESULT_FAILED:
+                self._push_result()
+            else:
+                try:
+                    buf = <WriteBuffer>next(self._execute_iter)
+                except StopIteration:
+                    self._push_result()
+                else:
+                    # Next iteration over the executemany() arg sequence
+                    self._send_bind_message(
+                        self._execute_portal_name, self._execute_stmt_name,
+                        buf, 0)
+
+        elif mtype == b'I':
+            # EmptyQueryResponse
+            self.buffer.consume_message()
+
     cdef _process__bind(self, char mtype):
         if mtype == b'E':
             # ErrorResponse
@@ -275,6 +326,14 @@ cdef class CoreProtocol:
                 raise RuntimeError(
                     '_parse_data_msgs: first message is not "D"')
 
+        if self._discard_data:
+            while True:
+                buf.consume_message()
+                if not buf.has_message() or buf.get_message_type() != b'D':
+                    self._skip_discard = True
+                    return
+
+        if ASYNCPG_DEBUG:
             if type(self.result) is not list:
                 raise RuntimeError(
                     '_parse_data_msgs: result is not a list, but {!r}'.
@@ -424,6 +483,7 @@ cdef class CoreProtocol:
         self.result_row_desc = None
         self.result_status_msg = None
         self.result_execute_completed = False
+        self._discard_data = False
 
     cdef _set_state(self, ProtocolState new_state):
         if new_state == PROTOCOL_IDLE:
@@ -537,16 +597,11 @@ cdef class CoreProtocol:
 
         self.transport.write(memoryview(packet))
 
-    cdef _bind_execute(self, str portal_name, str stmt_name,
-                       WriteBuffer bind_data, int32_t limit):
+    cdef _send_bind_message(self, str portal_name, str stmt_name,
+                            WriteBuffer bind_data, int32_t limit):
 
         cdef WriteBuffer buf
 
-        self._ensure_connected()
-        self._set_state(PROTOCOL_BIND_EXECUTE)
-
-        self.result = []
-
         buf = self._build_bind_message(portal_name, stmt_name, bind_data)
         self._write(buf)
 
@@ -558,6 +613,39 @@ cdef class CoreProtocol:
 
         self._write_sync_message()
 
+    cdef _bind_execute(self, str portal_name, str stmt_name,
+                       WriteBuffer bind_data, int32_t limit):
+
+        cdef WriteBuffer buf
+
+        self._ensure_connected()
+        self._set_state(PROTOCOL_BIND_EXECUTE)
+
+        self.result = []
+
+        self._send_bind_message(portal_name, stmt_name, bind_data, limit)
+
+    cdef _bind_execute_many(self, str portal_name, str stmt_name,
+                            object bind_data):
+
+        cdef WriteBuffer buf
+
+        self._ensure_connected()
+        self._set_state(PROTOCOL_BIND_EXECUTE_MANY)
+
+        self.result = None
+        self._discard_data = True
+        self._execute_iter = bind_data
+        self._execute_portal_name = portal_name
+        self._execute_stmt_name = stmt_name
+
+        try:
+            buf = <WriteBuffer>next(bind_data)
+        except StopIteration:
+            self._push_result()
+        else:
+            self._send_bind_message(portal_name, stmt_name, buf, 0)
+
     cdef _execute(self, str portal_name, int32_t limit):
         cdef WriteBuffer buf
 
diff --git a/asyncpg/protocol/prepared_stmt.pyx b/asyncpg/protocol/prepared_stmt.pyx
index cc68a2c..2b35064 100644
--- a/asyncpg/protocol/prepared_stmt.pyx
+++ b/asyncpg/protocol/prepared_stmt.pyx
@@ -141,7 +141,11 @@ cdef class PreparedStatementState:
             Codec codec
             list codecs
 
-        if self.cols_num == 0 or self.cols_desc is not None:
+        if self.cols_desc is not None:
+            return
+
+        if self.cols_num == 0:
+            self.cols_desc = record.ApgRecordDesc_New({}, ())
             return
 
         cols_mapping = collections.OrderedDict()
@@ -219,7 +223,9 @@ cdef class PreparedStatementState:
                     fnum, self.cols_num))
 
         if rows_codecs is None or len(rows_codecs) < fnum:
-            raise RuntimeError('invalid rows_codecs')
+            if fnum > 0:
+                # It's OK to have no rows_codecs for empty records
+                raise RuntimeError('invalid rows_codecs')
 
         dec_row = record.ApgRecord_New(self.cols_desc, fnum)
         for i in range(fnum):
diff --git a/asyncpg/protocol/protocol.c b/asyncpg/protocol/protocol.c
index 1d6a47c..a6e7155 100644
--- a/asyncpg/protocol/protocol.c
+++ b/asyncpg/protocol/protocol.c
@@ -553,11 +553,13 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol_PreparedStatementState;
 struct __pyx_obj_7asyncpg_8protocol_8protocol_BaseProtocol;
 struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct__prepare;
 struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_1_bind_execute;
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind;
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_3_execute;
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_4_query;
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_5_close_statement;
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_6_close;
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind_execute_many;
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_3_genexpr;
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_4_bind;
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_5_execute;
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_6_query;
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_7_close_statement;
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_8_close;
 union __pyx_t_7asyncpg_8protocol_4hton__floatconv;
 union __pyx_t_7asyncpg_8protocol_4hton__doubleconv;
 
@@ -640,13 +642,14 @@ enum __pyx_t_7asyncpg_8protocol_8protocol_ProtocolState {
   __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_AUTH = 10,
   __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_PREPARE = 11,
   __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_BIND_EXECUTE = 12,
-  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_CLOSE_STMT_PORTAL = 13,
-  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_SIMPLE_QUERY = 14,
-  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_EXECUTE = 15,
-  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_BIND = 16
+  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_BIND_EXECUTE_MANY = 13,
+  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_CLOSE_STMT_PORTAL = 14,
+  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_SIMPLE_QUERY = 15,
+  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_EXECUTE = 16,
+  __pyx_e_7asyncpg_8protocol_8protocol_PROTOCOL_BIND = 17
 };
 
-/* "asyncpg/protocol/coreproto.pxd":30
+/* "asyncpg/protocol/coreproto.pxd":31
  * 
  * 
  * cdef enum AuthenticationMessage:             # <<<<<<<<<<<<<<
@@ -664,7 +667,7 @@ enum __pyx_t_7asyncpg_8protocol_8protocol_AuthenticationMessage {
   __pyx_e_7asyncpg_8protocol_8protocol_AUTH_REQUIRED_SSPI = 9
 };
 
-/* "asyncpg/protocol/coreproto.pxd":50
+/* "asyncpg/protocol/coreproto.pxd":51
  * 
  * 
  * cdef enum ResultType:             # <<<<<<<<<<<<<<
@@ -676,7 +679,7 @@ enum __pyx_t_7asyncpg_8protocol_8protocol_ResultType {
   __pyx_e_7asyncpg_8protocol_8protocol_RESULT_FAILED = 2
 };
 
-/* "asyncpg/protocol/coreproto.pxd":55
+/* "asyncpg/protocol/coreproto.pxd":56
  * 
  * 
  * cdef enum TransactionStatus:             # <<<<<<<<<<<<<<
@@ -727,7 +730,7 @@ typedef PyObject *(*__pyx_t_7asyncpg_8protocol_8protocol_codec_encode_func)(stru
  */
 typedef PyObject *(*__pyx_t_7asyncpg_8protocol_8protocol_codec_decode_func)(struct __pyx_obj_7asyncpg_8protocol_8protocol_Codec *, struct __pyx_obj_7asyncpg_8protocol_8protocol_ConnectionSettings *, struct __pyx_obj_7asyncpg_8protocol_8protocol_FastReadBuffer *);
 
-/* "asyncpg/protocol/coreproto.pxd":63
+/* "asyncpg/protocol/coreproto.pxd":64
  * 
  * 
  * ctypedef object (*decode_row_method)(object, const char*, int32_t)             # <<<<<<<<<<<<<<
@@ -906,7 +909,7 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol_ConnectionSettings {
 };
 
 
-/* "asyncpg/protocol/coreproto.pxd":66
+/* "asyncpg/protocol/coreproto.pxd":67
  * 
  * 
  * cdef class CoreProtocol:             # <<<<<<<<<<<<<<
@@ -918,6 +921,10 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol {
   struct __pyx_vtabstruct_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_vtab;
   struct __pyx_obj_7asyncpg_8protocol_8protocol_ReadBuffer *buffer;
   int _skip_discard;
+  int _discard_data;
+  PyObject *_execute_iter;
+  PyObject *_execute_portal_name;
+  PyObject *_execute_stmt_name;
   enum __pyx_t_7asyncpg_8protocol_8protocol_ConnectionStatus con_status;
   enum __pyx_t_7asyncpg_8protocol_8protocol_ProtocolState state;
   enum __pyx_t_7asyncpg_8protocol_8protocol_TransactionStatus xact_status;
@@ -1031,11 +1038,49 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_1_bind_execute
 /* "asyncpg/protocol/protocol.pyx":165
  *         return await self._new_waiter(timeout)
  * 
+ *     async def bind_execute_many(self, PreparedStatementState state, args,             # <<<<<<<<<<<<<<
+ *                                 str portal_name, timeout):
+ * 
+ */
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind_execute_many {
+  PyObject_HEAD
+  PyObject *__pyx_v_arg_bufs;
+  PyObject *__pyx_v_args;
+  PyObject *__pyx_v_data_gen;
+  PyObject *__pyx_v_genexpr;
+  PyObject *__pyx_v_portal_name;
+  struct __pyx_obj_7asyncpg_8protocol_8protocol_BaseProtocol *__pyx_v_self;
+  struct __pyx_obj_7asyncpg_8protocol_8protocol_PreparedStatementState *__pyx_v_state;
+  PyObject *__pyx_v_timeout;
+  PyObject *__pyx_v_waiter;
+};
+
+
+/* "asyncpg/protocol/protocol.pyx":179
+ *         # this generator expression to keep the memory pressure under
+ *         # control.
+ *         data_gen = (state._encode_bind_msg(b) for b in args)             # <<<<<<<<<<<<<<
+ *         arg_bufs = iter(data_gen)
+ * 
+ */
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_3_genexpr {
+  PyObject_HEAD
+  struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind_execute_many *__pyx_outer_scope;
+  PyObject *__pyx_v_b;
+  PyObject *__pyx_t_0;
+  Py_ssize_t __pyx_t_1;
+  PyObject *(*__pyx_t_2)(PyObject *);
+};
+
+
+/* "asyncpg/protocol/protocol.pyx":196
+ *         return await waiter
+ * 
  *     async def bind(self, PreparedStatementState state, args,             # <<<<<<<<<<<<<<
  *                    str portal_name, timeout):
  * 
  */
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind {
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_4_bind {
   PyObject_HEAD
   PyObject *__pyx_v_args;
   PyObject *__pyx_v_portal_name;
@@ -1045,14 +1090,14 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind {
 };
 
 
-/* "asyncpg/protocol/protocol.pyx":186
+/* "asyncpg/protocol/protocol.pyx":217
  *         return await self._new_waiter(timeout)
  * 
  *     async def execute(self, PreparedStatementState state,             # <<<<<<<<<<<<<<
  *                       str portal_name, int limit, return_extra,
  *                       timeout):
  */
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_3_execute {
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_5_execute {
   PyObject_HEAD
   int __pyx_v_limit;
   PyObject *__pyx_v_portal_name;
@@ -1063,14 +1108,14 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_3_execute {
 };
 
 
-/* "asyncpg/protocol/protocol.pyx":209
+/* "asyncpg/protocol/protocol.pyx":240
  *         return await self._new_waiter(timeout)
  * 
  *     async def query(self, query, timeout):             # <<<<<<<<<<<<<<
  *         if self.cancel_waiter is not None:
  *             await self.cancel_waiter
  */
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_4_query {
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_6_query {
   PyObject_HEAD
   PyObject *__pyx_v_query;
   struct __pyx_obj_7asyncpg_8protocol_8protocol_BaseProtocol *__pyx_v_self;
@@ -1078,14 +1123,14 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_4_query {
 };
 
 
-/* "asyncpg/protocol/protocol.pyx":224
+/* "asyncpg/protocol/protocol.pyx":255
  *         return await self._new_waiter(timeout)
  * 
  *     async def close_statement(self, PreparedStatementState state, timeout):             # <<<<<<<<<<<<<<
  *         if self.cancel_waiter is not None:
  *             await self.cancel_waiter
  */
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_5_close_statement {
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_7_close_statement {
   PyObject_HEAD
   struct __pyx_obj_7asyncpg_8protocol_8protocol_BaseProtocol *__pyx_v_self;
   struct __pyx_obj_7asyncpg_8protocol_8protocol_PreparedStatementState *__pyx_v_state;
@@ -1093,14 +1138,14 @@ struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_5_close_stateme
 };
 
 
-/* "asyncpg/protocol/protocol.pyx":256
+/* "asyncpg/protocol/protocol.pyx":287
  *         self.transport.abort()
  * 
  *     async def close(self):             # <<<<<<<<<<<<<<
  *         if self.cancel_waiter is not None:
  *             await self.cancel_waiter
  */
-struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_6_close {
+struct __pyx_obj_7asyncpg_8protocol_8protocol___pyx_scope_struct_8_close {
   PyObject_HEAD
   struct __pyx_obj_7asyncpg_8protocol_8protocol_BaseProtocol *__pyx_v_self;
 };
@@ -1302,7 +1347,7 @@ static struct __pyx_obj_7asyncpg_8protocol_8protocol_Codec *__pyx_f_7asyncpg_8pr
 static struct __pyx_obj_7asyncpg_8protocol_8protocol_Codec *__pyx_f_7asyncpg_8protocol_8protocol_5Codec_new_python_codec(uint32_t, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, enum __pyx_t_7asyncpg_8protocol_8protocol_CodecFormat);
 
 
-/* "asyncpg/protocol/codecs/base.pyx":292
+/* "asyncpg/protocol/codecs/base.pyx":298
  * 
  * 
  * cdef class DataCodecConfig:             # <<<<<<<<<<<<<<
@@ -1356,6 +1401,7 @@ struct __pyx_vtabstruct_7asyncpg_8protocol_8protocol_CoreProtocol {
   PyObject *(*_process__auth)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, char);
   PyObject *(*_process__prepare)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, char);
   PyObject *(*_process__bind_execute)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, char);
+  PyObject *(*_process__bind_execute_many)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, char);
   PyObject *(*_process__close_stmt_portal)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, char);
   PyObject *(*_process__simple_query)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, char);
   PyObject *(*_process__bind)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, char);
@@ -1379,7 +1425,9 @@ struct __pyx_vtabstruct_7asyncpg_8protocol_8protocol_CoreProtocol {
   struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *(*_build_bind_message)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, PyObject *, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *);
   PyObject *(*_connect)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *);
   PyObject *(*_prepare)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, PyObject *);
+  PyObject *(*_send_bind_message)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, PyObject *, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *, int32_t);
   PyObject *(*_bind_execute)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, PyObject *, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *, int32_t);
+  PyObject *(*_bind_execute_many)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, PyObject *, PyObject *);
   PyObject *(*_bind)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, PyObject *, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *);
   PyObject *(*_execute)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, int32_t);
   PyObject *(*_close)(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *, PyObject *, int);
@@ -1786,6 +1834,10 @@ static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr
 #define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v)
 #endif
 
+/* IterNext.proto */
+#define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL)
+static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject *, PyObject *);
+
 /* decode_c_bytes.proto */
 static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
          const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
@@ -1894,6 +1946,9 @@ static CYTHON_INLINE PyObject* __Pyx__Coroutine_Yield_From(__pyx_CoroutineObject
     if (value == Py_None) PyErr_SetNone(PyExc_StopIteration); else __Pyx__ReturnWithStopIteration(value)
 static void __Pyx__ReturnWithStopIteration(PyObject* value);
 
+/* None.proto */
+static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
+
 /* SetVTable.proto */
 static int __Pyx_SetVtable(PyObject *dict, void *vtable);
 
@@ -2000,6 +2055,15 @@ static CYTHON_INLINE int16_t __Pyx_PyInt_As_int16_t(PyObject *);
 /* CIntFromPy.proto */
 static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
 
+/* Generator.proto */
+#define __Pyx_Generator_USED
+static PyTypeObject *__pyx_GeneratorType = 0;
+#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
+#define __Pyx_Generator_New(body, closure, name, qualname, module_name)\
+    __Pyx__Coroutine_New(__pyx_GeneratorType, body, closure, name, qualname, module_name)
+static PyObject *__Pyx_Generator_Next(PyObject *self);
+static int __pyx_Generator_init(void);
+
 /* CheckBinaryVersion.proto */
 static int __Pyx_check_binary_version(void);
 
@@ -2103,6 +2167,7 @@ static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__read_serve
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__process__auth(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, char __pyx_v_mtype); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__process__prepare(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, char __pyx_v_mtype); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__process__bind_execute(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, char __pyx_v_mtype); /* proto*/
+static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__process__bind_execute_many(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, char __pyx_v_mtype); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__process__bind(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, char __pyx_v_mtype); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__process__close_stmt_portal(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, char __pyx_v_mtype); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__process__simple_query(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, char __pyx_v_mtype); /* proto*/
@@ -2123,7 +2188,9 @@ static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__ensure_con
 static struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__build_bind_message(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_portal_name, PyObject *__pyx_v_stmt_name, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *__pyx_v_bind_data); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__connect(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__prepare(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_stmt_name, PyObject *__pyx_v_query); /* proto*/
+static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__send_bind_message(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_portal_name, PyObject *__pyx_v_stmt_name, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *__pyx_v_bind_data, int32_t __pyx_v_limit); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__bind_execute(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_portal_name, PyObject *__pyx_v_stmt_name, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *__pyx_v_bind_data, int32_t __pyx_v_limit); /* proto*/
+static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__bind_execute_many(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_portal_name, PyObject *__pyx_v_stmt_name, PyObject *__pyx_v_bind_data); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__execute(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_portal_name, int32_t __pyx_v_limit); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__bind(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_portal_name, PyObject *__pyx_v_stmt_name, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *__pyx_v_bind_data); /* proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_12CoreProtocol__close(struct __pyx_obj_7asyncpg_8protocol_8protocol_CoreProtocol *__pyx_v_self, PyObject *__pyx_v_name, int __pyx_v_is_portal); /* proto*/
@@ -2280,11 +2347,13 @@ static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol_PreparedStatementS
 static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol_BaseProtocol = 0;
 static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct__prepare = 0;
 static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_1_bind_execute = 0;
-static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind = 0;
-static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_3_execute = 0;
-static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_4_query = 0;
-static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_5_close_statement = 0;
-static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_6_close = 0;
+static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_2_bind_execute_many = 0;
+static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_3_genexpr = 0;
+static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_4_bind = 0;
+static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_5_execute = 0;
+static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_6_query = 0;
+static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_7_close_statement = 0;
+static PyTypeObject *__pyx_ptype_7asyncpg_8protocol_8protocol___pyx_scope_struct_8_close = 0;
 static PyObject *__pyx_v_7asyncpg_8protocol_8protocol_ARRAY_TYPES = 0;
 static PyObject *__pyx_v_7asyncpg_8protocol_8protocol_ENCODINGS_MAP = 0;
 static void *__pyx_v_7asyncpg_8protocol_8protocol_codec_map[(0x1000 + 1)];
@@ -2393,6 +2462,7 @@ static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_void_decode(struct __pyx_o
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol_init_pseudo_codecs(void); /*proto*/
 static CYTHON_INLINE int __pyx_f_7asyncpg_8protocol_8protocol__is_trivial_container(PyObject *); /*proto*/
 static CYTHON_INLINE PyObject *__pyx_f_7asyncpg_8protocol_8protocol__is_container(PyObject *); /*proto*/
+static CYTHON_INLINE PyObject *__pyx_f_7asyncpg_8protocol_8protocol__is_sub_array(PyObject *); /*proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol__get_array_shape(PyObject *, int32_t *, int32_t *); /*proto*/
 static PyObject *__pyx_f_7asyncpg_8protocol_8protocol__write_array_data(struct __pyx_obj_7asyncpg_8protocol_8protocol_ConnectionSettings *, PyObject *, int32_t, int32_t, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *, __pyx_t_7asyncpg_8protocol_8protocol_encode_func_ex, void const *); /*proto*/
 static CYTHON_INLINE PyObject *__pyx_f_7asyncpg_8protocol_8protocol_array_encode(struct __pyx_obj_7asyncpg_8protocol_8protocol_ConnectionSettings *, struct __pyx_obj_7asyncpg_8protocol_8protocol_WriteBuffer *, PyObject *, uint32_t, __pyx_t_7asyncpg_8protocol_8protocol_encode_func_ex, void const *); /*proto*/
@@ -2440,6 +2510,7 @@ static PyObject *__pyx_builtin_NotImplementedError;
 static PyObject *__pyx_builtin_ValueError;
 static PyObject *__pyx_builtin_TypeError;
 static PyObject *__pyx_builtin_memoryview;
+static PyObject *__pyx_builtin_StopIteration;
 static const char __pyx_k_c[] = "c";
 static const char __pyx_k_d[] = "d";
 static const char __pyx_k_i[] = "i";
@@ -2631,6 +2702,7 @@ static const char __pyx_k_decimal[] = "decimal";
 static const char __pyx_k_decoder[] = "decoder";
 static const char __pyx_k_encoder[] = "encoder";
 static const char __pyx_k_execute[] = "execute";
+static const char __pyx_k_genexpr[] = "genexpr";
 static const char __pyx_k_getattr[] = "__getattr__";
 static const char __pyx_k_hashlib[] = "hashlib";
 static const char __pyx_k_inspect[] = "inspect";
@@ -2785,6 +2857,7 @@ static const char __pyx_k_pg_node_tree[] = "pg_node_tree";
 static const char __pyx_k_regnamespace[] = "regnamespace";
 static const char __pyx_k_regprocedure[] = "regprocedure";
 static const char __pyx_k_return_extra[] = "return_extra";
+static const char __pyx_k_StopIteration[] = "StopIteration";
 static const char __pyx_k_asyncio_tasks[] = "asyncio.tasks";
 static const char __pyx_k_asyncpg_types[] = "asyncpg.types";
 static const char __pyx_k_connected_fut[] = "connected_fut";
@@ -2818,6 +2891,7 @@ static const char __pyx_k_language_handler[] = "language_handler";
 static const char __pyx_k_BaseProtocol_bind[] = "BaseProtocol.bind";
 static const char __pyx_k_add_done_callback[] = "add_done_callback";
 static const char __pyx_k_already_connected[] = "already connected";
+static const char __pyx_k_bind_execute_many[] = "bind_execute_many";
 static const char __pyx_k_date_from_ordinal[] = "date_from_ordinal";
 static const char __pyx_k_infinity_datetime[] = "infinity_datetime";
 static const char __pyx_k_pg_contrib_hstore[] = "pg_contrib.hstore";
@@ -2861,6 +2935,7 @@ static const char __pyx_k_BaseProtocol_close_statement[] = "BaseProtocol.close_s
 static const char __pyx_k_decode_row_statement_is_None[] = "_decode_row: statement is None";
 static const char __pyx_k_no_codec_for_domain_base_type[] = "no codec for domain base type {}";
 static const char __pyx_k_not_enough_data_to_read_bytes[] = "not enough data to read {} bytes";
+static const char __pyx_k_BaseProtocol_bind_execute_many[] = "BaseProtocol.bind_execute_many";
 static const char __pyx_k_a_boolean_is_required_got_type[] = "a boolean is required (got type {})";
 static const char __pyx_k_cannot_override_codec_for_type[] = "cannot override codec for type {}";
 static const char __pyx_k_home_elvis_dev_sprymix_asyncpg[] = "/home/elvis/dev/sprymix/asyncpg/asyncpg/protocol/protocol.pyx";
@@ -2885,6 +2960,7 @@ static const char __pyx_k_protocol_is_in_an_unknown_state[] = "protocol is in an
 static const char __pyx_k_the_buffer_is_in_read_only_mode[] = "the buffer is in read-only mode";
 static const char __pyx_k_type_record_missing_field_types[] = "type record missing field types for composite {}";
 static const char __pyx_k_Deallocating_buffer_with_attache[] = "Deallocating buffer with attached memoryviews";
+static const char __pyx_k_bind_execute_many_locals_genexpr[] = "bind_execute_many.<locals>.genexpr";
 static const char __pyx_k_cannot_perform_operation_another[] = "cannot perform operation: another operation is cancelling";
 static const char __pyx_k_cannot_perform_operation_connect[] = "cannot perform operation: connection is closed";
 static const char __pyx_k_cannot_register_core_codec_for_O[] = "cannot register core codec for OID {}: it is greater than MAXSUPPORTEDOID ({})";
@@ -2910,7 +2986,7 @@ static const char __pyx_k_number_of_array_dimensions_excee[] = "number of array
 static const char __pyx_k_number_of_columns_in_result_is_d[] = "number of columns in result ({}) is different from what was described ({})";
 static const char __pyx_k_read_cstr_only_works_when_the_me[] = "read_cstr only works when the message guaranteed to be in the buffer";
 static const char __pyx_k_type_record_missing_base_type_fo[] = "type record missing base type for domain {}";
-static const char __pyx_k_unexpected_attribute_data_type_e[] = "unexpected attribute data type: {}, expected {}";
+static const char __pyx_k_unexpected_data_type_of_composit[] = "unexpected data type of composite type attribute {}: {!r}, expected {!r}";
 static const char __pyx_k_unexpected_trailing_bytes_in_buf[] = "unexpected trailing {} bytes in buffer";
 static const char __pyx_k_unhandled_standard_data_type_r_O[] = "unhandled standard data type {!r} (OID {})";
 static const char __pyx_k_unknown_error_in_protocol_implem[] = "unknown error in protocol implementation";
@@ -2927,6 +3003,7 @@ static PyObject *__pyx_n_s_Attribute;
 static PyObject *__pyx_n_s_AttributeError;
 static PyObject *__pyx_n_s_BaseProtocol_bind;
 static PyObject *__pyx_n_s_BaseProtocol_bind_execute;
+static PyObject *__pyx_n_s_BaseProtocol_bind_execute_many;
 static PyObject *__pyx_n_s_BaseProtocol_close;
 static PyObject *__pyx_n_s_BaseProtocol_close_statement;
 static PyObject *__pyx_n_s_BaseProtocol_execute;
@@ -2963,6 +3040,7 @@ static PyObject *__pyx_n_s_PostgresMessage;
 static PyObject *__pyx_n_s_Protocol;
 static PyObject *__pyx_n_s_Range;
 static PyObject *__pyx_n_s_RuntimeError;
... 25793 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/asyncpg.git



More information about the Python-modules-commits mailing list