Skip to content

Commit 7b9633e

Browse files
author
James William Pye
committed
Direct SingleXact cursors to use the "default cursor id".
This avoids some unnecessary garbage collection as SingleXact cursors only exist as long as they are running. Use the default cursor, b'', and avoid the extra weakref.ref().
1 parent 4f7ed32 commit 7b9633e

1 file changed

Lines changed: 28 additions & 15 deletions

File tree

postgresql/driver/pq3.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# http://python.projects.postgresql.org
44
##
55
"""
6-
PG-API interface for PostgreSQL that support the PQ version 3.0 protocol.
6+
PG-API interface for PostgreSQL using PQ version 3.0.
77
"""
88
import sys
99
import os
@@ -407,18 +407,19 @@ def count(self):
407407
return self._complete_message.extract_count()
408408

409409
class Chunks(Output, pg_api.Chunks):
410-
chunksize = 256
410+
pass
411+
412+
class FetchAll(Chunks):
413+
_e_factors = ('statement', 'parameters',)
411414
def _e_metas(self):
412-
yield ('chunksize', self.chunksize)
413415
yield ('type', type(self).__name__)
414416

415-
def __init__(self, statement, parameters, cursor_id):
417+
def __init__(self, statement, parameters):
416418
self.statement = statement
417419
self.parameters = parameters
418420
self.database = statement.database
419-
Output.__init__(self, cursor_id or ID(self))
421+
Output.__init__(self, '')
420422

421-
class SingleXact(Chunks):
422423
def _init(self):
423424
expect = self._expect
424425
self._xact = self._ins(
@@ -478,21 +479,32 @@ def __next__(self):
478479
del x.completed[0]
479480
return r
480481

481-
class SingleXactCopy(SingleXact):
482+
class SingleXactCopy(FetchAll):
482483
_expect = element.CopyToBegin.type
483-
_process_chunk = SingleXact._process_copy_chunk
484+
_process_chunk = FetchAll._process_copy_chunk
484485

485-
class SingleXactFetch(SingleXact):
486+
class SingleXactFetch(FetchAll):
486487
_expect = element.Tuple.type
487-
_process_chunk_ = SingleXact._process_tuple_chunk_Row
488+
_process_chunk_ = FetchAll._process_tuple_chunk_Row
488489
def _process_chunk(self, x):
489490
return self._process_chunk_((
490491
y for y in x if y.type is element.Tuple.type
491492
))
492493

493494
class MultiXactStream(Chunks):
495+
chunksize = 256
494496
# only tuple streams
495-
_process_chunk = Chunks._process_tuple_chunk_Row
497+
_process_chunk = Output._process_tuple_chunk_Row
498+
499+
def _e_metas(self):
500+
yield ('chunksize', self.chunksize)
501+
yield ('type', type(self).__name__)
502+
503+
def __init__(self, statement, parameters, cursor_id):
504+
self.statement = statement
505+
self.parameters = parameters
506+
self.database = statement.database
507+
Output.__init__(self, cursor_id or ID(self))
496508

497509
@abstractmethod
498510
def _bind(self):
@@ -940,9 +952,9 @@ def __call__(self, *parameters):
940952
# get em' all!
941953
if self._output is None:
942954
# might be a copy.
943-
c = SingleXactCopy(self, parameters, None)
955+
c = SingleXactCopy(self, parameters)
944956
else:
945-
c = SingleXactFetch(self, parameters, None)
957+
c = SingleXactFetch(self, parameters)
946958

947959
# iff output is None, it's not a tuple returning query.
948960
# however, if it's a copy, detect that fact by SingleXactCopy's
@@ -978,12 +990,13 @@ def chunks(self, *parameters):
978990
len(self._input), len(parameters)
979991
))
980992
if self._output is None:
981-
return SingleXactCopy(self, parameters, None)
993+
return SingleXactCopy(self, parameters)
982994
if self.database.pq.state == b'I':
983995
if self.string is not None:
984996
return MultiXactOutsideBlock(self, parameters, None)
985997
else:
986-
return SingleXactFetch(self, parameters, None)
998+
# statement source unknown, so it can't be DECLARE'd.
999+
return SingleXactFetch(self, parameters)
9871000
else:
9881001
return MultiXactInsideBlock(self, parameters, None)
9891002

0 commit comments

Comments
 (0)