Skip to content

Commit b821624

Browse files
author
James William Pye
committed
Add functools.compose and some associated optimizations.
1 parent bbd01d4 commit b821624

11 files changed

Lines changed: 414 additions & 247 deletions

File tree

postgresql/driver/pq3.py

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,8 @@ def close(self):
343343
self.closed = True
344344

345345
def _pq_parameters(self):
346-
return pg_typio.row_pack(
347-
self.parameters,
348-
self.statement._input_io,
349-
self.database.typio.encode
346+
return pg_typio.process_tuple(
347+
self.statement._input_io, self.parameters,
350348
)
351349

352350
def _init(self):
@@ -645,13 +643,11 @@ def _buffer_more(self, quantity, direction):
645643

646644
def _expansion(self):
647645
return [
648-
pg_typio.Row(
649-
pg_typio.row_unpack(
650-
y,
651-
self._output_io,
652-
self.database.typio.decode
646+
pg_types.Row(
647+
pg_typio.process_tuple(
648+
self._output_io, y,
653649
),
654-
attmap = self._output_attmap
650+
attribute_map = self._output_attmap
655651
)
656652
for y in self._xact.messages_received()
657653
if y.type == pq.element.Tuple.type
@@ -846,6 +842,9 @@ def _fini(self):
846842
else pq.element.BinaryFormat
847843
for x in self._output_io
848844
]
845+
self._output_io = tuple([
846+
x or self.database.typio.decode for x in self._output_io
847+
])
849848
super()._fini()
850849
# Done with the first transaction.
851850
self._xact = None
@@ -1048,7 +1047,9 @@ def column_types(self):
10481047
if self.closed:
10491048
self.prepare()
10501049
if self._output is not None:
1051-
return [self.database.typio.type_from_oid(x[3]) for x in self._output]
1050+
return [
1051+
self.database.typio.type_from_oid(x[3]) for x in self._output
1052+
]
10521053

10531054
@property
10541055
def pg_parameter_types(self):
@@ -1168,7 +1169,9 @@ def _fini(self):
11681169
self._output_formats = None
11691170
else:
11701171
self._output = tupdesc
1171-
self._output_attmap = dict(self.database.typio.attribute_map(tupdesc))
1172+
self._output_attmap = dict(
1173+
self.database.typio.attribute_map(tupdesc)
1174+
)
11721175
# tuple output
11731176
self._output_io = \
11741177
self.database.typio.resolve_descriptor(tupdesc, 1)
@@ -1178,18 +1181,23 @@ def _fini(self):
11781181
else pq.element.BinaryFormat
11791182
for x in self._output_io
11801183
]
1184+
self._output_io = tuple([
1185+
x or self.database.typio.decode for x in self._output_io
1186+
])
11811187

11821188
self._input = argtypes
1183-
self._input_io = [
1184-
(self.database.typio.resolve(x) or (None,None))[0]
1185-
for x in argtypes
1186-
]
1187-
self._input_formats = [
1188-
pq.element.StringFormat
1189-
if x is None
1190-
else pq.element.BinaryFormat
1191-
for x in self._input_io
1192-
]
1189+
packs = []
1190+
formats = []
1191+
for x in argtypes:
1192+
pack = (self.database.typio.resolve(x) or (None,None))[0]
1193+
packs.append(pack or self.database.typio.encode)
1194+
formats.append(
1195+
pq.element.StringFormat
1196+
if x is None
1197+
else pq.element.BinaryFormat
1198+
)
1199+
self._input_io = tuple(packs)
1200+
self._input_formats = formats
11931201
self.closed = False
11941202
self._pq_xact = None
11951203

@@ -1211,10 +1219,8 @@ def first(self, *parameters):
12111219
c = self.database
12121220

12131221
if self._input_io:
1214-
params = pg_typio.row_pack(
1215-
parameters,
1216-
self._input_io,
1217-
c.typio.encode
1222+
params = pg_typio.process_tuple(
1223+
self._input_io, parameters,
12181224
)
12191225
else:
12201226
params = ()
@@ -1245,9 +1251,9 @@ def first(self, *parameters):
12451251
return None
12461252

12471253
if len(self._output_io) > 1:
1248-
return pg_typio.Row(
1249-
pg_typio.row_unpack(xt, self._output_io, c.typio.decode),
1250-
attmap = self._output_attmap
1254+
return pg_types.Row(
1255+
pg_typio.process_tuple(self._output_io, xt),
1256+
attribute_map = self._output_attmap
12511257
)
12521258
else:
12531259
if xt[0] is None:
@@ -1337,10 +1343,7 @@ def _load_bulk_tuples(self, tupleseq, tps = None):
13371343
c = 0
13381344
xm = []
13391345
for t in tupleseqiter:
1340-
params = pg_typio.row_pack(
1341-
t, self._input_io,
1342-
self.database.typio.encode
1343-
)
1346+
params = pg_typio.process_tuple(self._input_io, tuple(t))
13441347
xm.extend((
13451348
pq.element.Bind(
13461349
b'',
@@ -1444,7 +1447,7 @@ def __init__(self, ident, database, description = ()):
14441447
).first(int(ident))
14451448
else:
14461449
proctup = database.prepare(
1447-
ProcedureLookup + ' WHERE pg_proc.oid = $1::regprocedure',
1450+
ProcedureLookup + ' WHERE pg_proc.oid = $1::text::regprocedure',
14481451
title = 'func_lookup_by_name'
14491452
).first(ident)
14501453
if proctup is None:

postgresql/protocol/buffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ p_new(PyTypeObject *subtype, PyObject *args, PyObject *kw)
9494
struct p_buffer *pb;
9595
PyObject *rob;
9696

97-
if (PyArg_ParseTupleAndKeywords(args, kw, "", kwlist) < 0)
97+
if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
9898
return(NULL);
9999

100100
rob = subtype->tp_alloc(subtype, 0);
@@ -406,7 +406,7 @@ p_read(PyObject *self, PyObject *args)
406406
struct p_buffer *pb;
407407
PyObject *rob = NULL;
408408

409-
if (PyArg_ParseTuple(args, "|i", &msg_count) < 0)
409+
if (!PyArg_ParseTuple(args, "|i", &msg_count))
410410
return(NULL);
411411

412412
pb = (struct p_buffer *) self;

postgresql/protocol/optimized.c

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ parse_tuple_message(PyObject *self, PyObject *args)
3535
if (!PyObject_IsSubclass(typ, (PyObject *) &PyTuple_Type))
3636
{
3737
const char *typname = "<not-a-type>";
38-
if (PyObject_IsInstance((PyObject *) typ->ob_type, (PyObject *) &PyType_Type))
38+
if (PyObject_IsInstance(
39+
(PyObject *) typ->ob_type,
40+
(PyObject *) &PyType_Type
41+
))
3942
{
4043
typname = ((PyTypeObject *) typ)->tp_name;
4144
}
@@ -105,7 +108,7 @@ parse_tuple_message(PyObject *self, PyObject *args)
105108
if (ob == NULL)
106109
{
107110
/*
108-
* Probably a OOM error.
111+
* Probably an OOM error.
109112
*/
110113
goto cleanup;
111114
}
@@ -133,9 +136,84 @@ parse_tuple_message(PyObject *self, PyObject *args)
133136
return(NULL);
134137
}
135138

139+
static PyObject *
140+
process_tuple(PyObject *self, PyObject *args)
141+
{
142+
PyObject *tup, *procs, *rob;
143+
Py_ssize_t len, i;
144+
145+
if (!PyArg_ParseTuple(args, "OO", &procs, &tup))
146+
return(NULL);
147+
148+
if (!PyObject_IsInstance(procs, (PyObject *) &PyTuple_Type))
149+
{
150+
PyErr_SetString(
151+
PyExc_TypeError,
152+
"process_tuple requires a tuple as its first argument"
153+
);
154+
return(NULL);
155+
}
156+
157+
if (!PyObject_IsInstance(tup, (PyObject *) &PyTuple_Type))
158+
{
159+
PyErr_SetString(
160+
PyExc_TypeError,
161+
"process_tuple requires a tuple as its second argument"
162+
);
163+
return(NULL);
164+
}
165+
166+
len = PyTuple_GET_SIZE(tup);
167+
168+
if (len != PyTuple_GET_SIZE(procs))
169+
{
170+
PyErr_Format(
171+
PyExc_ValueError,
172+
"inconsistent items, %d processors and %d objects",
173+
len,
174+
PyTuple_GET_SIZE(procs)
175+
);
176+
return(NULL);
177+
}
178+
rob = PyTuple_New(len);
179+
180+
for (i = 0; i < len; ++i)
181+
{
182+
PyObject *p, *o, *ot, *r;
183+
o = PyTuple_GET_ITEM(tup, i);
184+
if (o == Py_None)
185+
{
186+
Py_INCREF(Py_None);
187+
PyTuple_SET_ITEM(rob, i, Py_None);
188+
continue;
189+
}
190+
p = PyTuple_GET_ITEM(procs, i);
191+
ot = PyTuple_New(1);
192+
PyTuple_SET_ITEM(ot, 0, o);
193+
Py_INCREF(o);
194+
r = PyObject_CallObject(p, ot);
195+
Py_DECREF(ot);
196+
if (r == NULL)
197+
{
198+
Py_DECREF(rob);
199+
rob = NULL;
200+
break;
201+
}
202+
PyTuple_SET_ITEM(rob, i, r);
203+
}
204+
205+
return(rob);
206+
}
207+
136208
static PyMethodDef optimized_methods[] = {
137209
{"parse_tuple_message", (PyCFunction) parse_tuple_message, METH_VARARGS,
138210
PyDoc_STR("parse the given tuple data into a tuple of raw data"),},
211+
{"process_tuple", (PyCFunction) process_tuple, METH_VARARGS,
212+
PyDoc_STR(
213+
"process the items in the second argument "
214+
"with the corresponding items in the first argument."
215+
),
216+
},
139217
{NULL}
140218
};
141219

0 commit comments

Comments
 (0)