source: trunk/pgmodule.c @ 981

Last change on this file since 981 was 981, checked in by cito, 4 months ago

PEP 7: Use 4-space indents and no tabs at all

  • Property svn:keywords set to Id
File size: 186.6 KB
Line 
1/*
2 * $Id: pgmodule.c 981 2019-04-22 15:40:02Z cito $
3 * PyGres, version 2.2 A Python interface for PostgreSQL database. Written by
4 * D'Arcy J.M. Cain, (darcy@druid.net).  Based heavily on code written by
5 * Pascal Andre, andre@chimay.via.ecp.fr. Copyright (c) 1995, Pascal Andre
6 * (andre@via.ecp.fr).
7 *
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation for any purpose, without fee, and without a written
10 * agreement is hereby granted, provided that the above copyright notice and
11 * this paragraph and the following two paragraphs appear in all copies or in
12 * any new file that contains a substantial portion of this file.
13 *
14 * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
15 * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
17 * AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 *
19 * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
22 * AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
23 * ENHANCEMENTS, OR MODIFICATIONS.
24 *
25 * Further modifications copyright 1997 to 2019 by D'Arcy J.M. Cain
26 * (darcy@PyGreSQL.org) subject to the same terms and conditions as above.
27 *
28 */
29
30/* Note: This should be linked against the same C runtime lib as Python */
31
32#include <Python.h>
33
34#include <libpq-fe.h>
35#include <libpq/libpq-fs.h>
36
37/* the type definitions from <server/catalog/pg_type.h> */
38#include "pgtypes.h"
39
40/* macros for single-source Python 2/3 compatibility */
41#include "py3c.h"
42
43static PyObject *Error, *Warning, *InterfaceError,
44    *DatabaseError, *InternalError, *OperationalError, *ProgrammingError,
45    *IntegrityError, *DataError, *NotSupportedError;
46
47#define _TOSTRING(x) #x
48#define TOSTRING(x) _TOSTRING(x)
49static const char *PyPgVersion = TOSTRING(PYGRESQL_VERSION);
50
51#if SIZEOF_SIZE_T != SIZEOF_INT
52#define Py_InitModule4 Py_InitModule4_64
53#endif
54
55/* default values */
56#define PG_ARRAYSIZE        1
57
58/* flags for object validity checks */
59#define CHECK_OPEN          1
60#define CHECK_CLOSE         2
61#define CHECK_CNX           4
62#define CHECK_RESULT        8
63#define CHECK_DQL           16
64
65/* query result types */
66#define RESULT_EMPTY        1
67#define RESULT_DML          2
68#define RESULT_DDL          3
69#define RESULT_DQL          4
70
71/* flags for move methods */
72#define QUERY_MOVEFIRST     1
73#define QUERY_MOVELAST      2
74#define QUERY_MOVENEXT      3
75#define QUERY_MOVEPREV      4
76
77#define MAX_BUFFER_SIZE 8192    /* maximum transaction size */
78#define MAX_ARRAY_DEPTH 16      /* maximum allowed depth of an array */
79
80/* MODULE GLOBAL VARIABLES */
81
82#ifdef DEFAULT_VARS
83static PyObject *pg_default_host;   /* default database host */
84static PyObject *pg_default_base;   /* default database name */
85static PyObject *pg_default_opt;    /* default connection options */
86static PyObject *pg_default_port;   /* default connection port */
87static PyObject *pg_default_user;   /* default username */
88static PyObject *pg_default_passwd; /* default password */
89#endif  /* DEFAULT_VARS */
90
91static PyObject *decimal = NULL, /* decimal type */
92                *dictiter = NULL, /* function for getting named results */
93                *namediter = NULL, /* function for getting named results */
94                *namednext = NULL, /* function for getting one named result */
95                *scalariter = NULL, /* function for getting scalar results */
96                *jsondecode = NULL; /* function for decoding json strings */
97static const char *date_format = NULL; /* date format that is always assumed */
98static char decimal_point = '.'; /* decimal point used in money values */
99static int bool_as_text = 0; /* whether bool shall be returned as text */
100static int array_as_text = 0; /* whether arrays shall be returned as text */
101static int bytea_escaped = 0; /* whether bytea shall be returned escaped */
102
103static int pg_encoding_utf8 = 0;
104static int pg_encoding_latin1 = 0;
105static int pg_encoding_ascii = 0;
106
107/*
108OBJECTS
109=======
110
111  Each object has a number of elements.  The naming scheme will be based on
112  the object type.  Here are the elements using example object type "foo".
113   - fooObject: A structure to hold local object information.
114   - fooXxx: Object methods such as Delete and Getattr.
115   - fooMethods: Methods declaration.
116   - fooType: Type definition for object.
117
118  This is followed by the object methods.
119
120  The objects that we need to create:
121   - pg: The module itself.
122   - conn: Connection object returned from pg.connect().
123   - notice: Notice object returned from pg.notice().
124   - large: Large object returned by pg.conn.locreate() and Pg.Conn.loimport().
125   - query: Query object returned by pg.conn.Conn.query().
126   - source: Source object returned by pg.conn.source().
127*/
128
129/* forward declarations for types */
130static PyTypeObject noticeType;
131static PyTypeObject queryType;
132static PyTypeObject sourceType;
133static PyTypeObject largeType;
134static PyTypeObject connType;
135
136/* forward static declarations */
137static void notice_receiver(void *, const PGresult *);
138
139/* --------------------------------------------------------------------- */
140/* Object declarations                                                   */
141/* --------------------------------------------------------------------- */
142typedef struct
143{
144    PyObject_HEAD
145    int         valid;              /* validity flag */
146    PGconn     *cnx;                /* Postgres connection handle */
147    const char *date_format;        /* date format derived from datestyle */
148    PyObject   *cast_hook;          /* external typecast method */
149    PyObject   *notice_receiver;    /* current notice receiver */
150}   connObject;
151#define is_connObject(v) (PyType(v) == &connType)
152
153typedef struct
154{
155    PyObject_HEAD
156    int         valid;          /* validity flag */
157    connObject *pgcnx;          /* parent connection object */
158    PGresult    *result;        /* result content */
159    int         encoding;       /* client encoding */
160    int         result_type;    /* result type (DDL/DML/DQL) */
161    long        arraysize;      /* array size for fetch method */
162    int         current_row;    /* currently selected row */
163    int         max_row;        /* number of rows in the result */
164    int         num_fields;     /* number of fields in each row */
165}   sourceObject;
166#define is_sourceObject(v) (PyType(v) == &sourceType)
167
168typedef struct
169{
170    PyObject_HEAD
171    connObject *pgcnx;          /* parent connection object */
172    PGresult    const *res;     /* an error or warning */
173}   noticeObject;
174#define is_noticeObject(v) (PyType(v) == &noticeType)
175
176typedef struct
177{
178    PyObject_HEAD
179    connObject *pgcnx;          /* parent connection object */
180    PGresult   *result;         /* result content */
181    int         encoding;       /* client encoding */
182    int         current_row;    /* currently selected row */
183    int         max_row;        /* number of rows in the result */
184    int         num_fields;     /* number of fields in each row */
185    int        *col_types;      /* PyGreSQL column types */
186}   queryObject;
187#define is_queryObject(v) (PyType(v) == &queryType)
188
189#ifdef LARGE_OBJECTS
190typedef struct
191{
192    PyObject_HEAD
193    connObject *pgcnx;          /* parent connection object */
194    Oid         lo_oid;         /* large object oid */
195    int         lo_fd;          /* large object fd */
196}   largeObject;
197#define is_largeObject(v) (PyType(v) == &largeType)
198#endif /* LARGE_OBJECTS */
199
200/* PyGreSQL internal types */
201
202/* simple types */
203#define PYGRES_INT 1
204#define PYGRES_LONG 2
205#define PYGRES_FLOAT 3
206#define PYGRES_DECIMAL 4
207#define PYGRES_MONEY 5
208#define PYGRES_BOOL 6
209/* text based types */
210#define PYGRES_TEXT 8
211#define PYGRES_BYTEA 9
212#define PYGRES_JSON 10
213#define PYGRES_OTHER 11
214/* array types */
215#define PYGRES_ARRAY 16
216
217/* --------------------------------------------------------------------- */
218/* Internal Functions                                                    */
219/* --------------------------------------------------------------------- */
220
221/* shared function for encoding and decoding strings */
222
223static PyObject *
224get_decoded_string(const char *str, Py_ssize_t size, int encoding)
225{
226    if (encoding == pg_encoding_utf8)
227        return PyUnicode_DecodeUTF8(str, size, "strict");
228    if (encoding == pg_encoding_latin1)
229        return PyUnicode_DecodeLatin1(str, size, "strict");
230    if (encoding == pg_encoding_ascii)
231        return PyUnicode_DecodeASCII(str, size, "strict");
232    /* encoding name should be properly translated to Python here */
233    return PyUnicode_Decode(str, size,
234        pg_encoding_to_char(encoding), "strict");
235}
236
237static PyObject *
238get_encoded_string(PyObject *unicode_obj, int encoding)
239{
240    if (encoding == pg_encoding_utf8)
241        return PyUnicode_AsUTF8String(unicode_obj);
242    if (encoding == pg_encoding_latin1)
243        return PyUnicode_AsLatin1String(unicode_obj);
244    if (encoding == pg_encoding_ascii)
245        return PyUnicode_AsASCIIString(unicode_obj);
246    /* encoding name should be properly translated to Python here */
247    return PyUnicode_AsEncodedString(unicode_obj,
248        pg_encoding_to_char(encoding), "strict");
249}
250
251/* helper functions */
252
253/* get PyGreSQL internal types for a PostgreSQL type */
254static int
255get_type(Oid pgtype)
256{
257    int t;
258
259    switch (pgtype)
260    {
261        /* simple types */
262
263        case INT2OID:
264        case INT4OID:
265        case CIDOID:
266        case OIDOID:
267        case XIDOID:
268            t = PYGRES_INT;
269            break;
270
271        case INT8OID:
272            t = PYGRES_LONG;
273            break;
274
275        case FLOAT4OID:
276        case FLOAT8OID:
277            t = PYGRES_FLOAT;
278            break;
279
280        case NUMERICOID:
281            t = PYGRES_DECIMAL;
282            break;
283
284        case CASHOID:
285            t = decimal_point ? PYGRES_MONEY : PYGRES_TEXT;
286            break;
287
288        case BOOLOID:
289            t = PYGRES_BOOL;
290            break;
291
292        case BYTEAOID:
293            t = bytea_escaped ? PYGRES_TEXT : PYGRES_BYTEA;
294            break;
295
296        case JSONOID:
297        case JSONBOID:
298            t = jsondecode ? PYGRES_JSON : PYGRES_TEXT;
299            break;
300
301        case BPCHAROID:
302        case CHAROID:
303        case TEXTOID:
304        case VARCHAROID:
305        case NAMEOID:
306        case REGTYPEOID:
307            t = PYGRES_TEXT;
308            break;
309
310        /* array types */
311
312        case INT2ARRAYOID:
313        case INT4ARRAYOID:
314        case CIDARRAYOID:
315        case OIDARRAYOID:
316        case XIDARRAYOID:
317            t = array_as_text ? PYGRES_TEXT : (PYGRES_INT | PYGRES_ARRAY);
318            break;
319
320        case INT8ARRAYOID:
321            t = array_as_text ? PYGRES_TEXT : (PYGRES_LONG | PYGRES_ARRAY);
322            break;
323
324        case FLOAT4ARRAYOID:
325        case FLOAT8ARRAYOID:
326            t = array_as_text ? PYGRES_TEXT : (PYGRES_FLOAT | PYGRES_ARRAY);
327            break;
328
329        case NUMERICARRAYOID:
330            t = array_as_text ? PYGRES_TEXT : (PYGRES_DECIMAL | PYGRES_ARRAY);
331            break;
332
333        case MONEYARRAYOID:
334            t = array_as_text ? PYGRES_TEXT : ((decimal_point ?
335                PYGRES_MONEY : PYGRES_TEXT) | PYGRES_ARRAY);
336            break;
337
338        case BOOLARRAYOID:
339            t = array_as_text ? PYGRES_TEXT : (PYGRES_BOOL | PYGRES_ARRAY);
340            break;
341
342        case BYTEAARRAYOID:
343            t = array_as_text ? PYGRES_TEXT : ((bytea_escaped ?
344                PYGRES_TEXT : PYGRES_BYTEA) | PYGRES_ARRAY);
345            break;
346
347        case JSONARRAYOID:
348        case JSONBARRAYOID:
349            t = array_as_text ? PYGRES_TEXT : ((jsondecode ?
350                PYGRES_JSON : PYGRES_TEXT) | PYGRES_ARRAY);
351            break;
352
353        case BPCHARARRAYOID:
354        case CHARARRAYOID:
355        case TEXTARRAYOID:
356        case VARCHARARRAYOID:
357        case NAMEARRAYOID:
358        case REGTYPEARRAYOID:
359            t = array_as_text ? PYGRES_TEXT : (PYGRES_TEXT | PYGRES_ARRAY);
360            break;
361
362        default:
363            t = PYGRES_OTHER;
364    }
365
366    return t;
367}
368
369/* get PyGreSQL column types for all result columns */
370static int *
371get_col_types(PGresult *result, int nfields)
372{
373    int *types, *t, j;
374
375    if (!(types = PyMem_Malloc(sizeof(int) * nfields)))
376        return (int *)PyErr_NoMemory();
377
378    for (j = 0, t=types; j < nfields; ++j)
379        *t++ = get_type(PQftype(result, j));
380
381    return types;
382}
383
384/* Cast a bytea encoded text based type to a Python object.
385   This assumes the text is null-terminated character string. */
386static PyObject *
387cast_bytea_text(char *s)
388{
389    PyObject   *obj;
390    char       *tmp_str;
391    size_t      str_len;
392
393    /* this function should not be called when bytea_escaped is set */
394    tmp_str = (char *)PQunescapeBytea((unsigned char*)s, &str_len);
395    obj = PyBytes_FromStringAndSize(tmp_str, str_len);
396    if (tmp_str)
397        PQfreemem(tmp_str);
398    return obj;
399}
400
401/* Cast a text based type to a Python object.
402   This needs the character string, size and encoding. */
403static PyObject *
404cast_sized_text(char *s, Py_ssize_t size, int encoding, int type)
405{
406    PyObject   *obj, *tmp_obj;
407    char       *tmp_str;
408    size_t      str_len;
409
410    switch (type) /* this must be the PyGreSQL internal type */
411    {
412        case PYGRES_BYTEA:
413            /* this type should not be passed when bytea_escaped is set */
414            /* we need to add a null byte */
415            tmp_str = (char *) PyMem_Malloc(size + 1);
416            if (!tmp_str) return PyErr_NoMemory();
417            memcpy(tmp_str, s, size);
418            s = tmp_str; *(s + size) = '\0';
419            tmp_str = (char *)PQunescapeBytea((unsigned char*)s, &str_len);
420            PyMem_Free(s);
421            if (!tmp_str) return PyErr_NoMemory();
422            obj = PyBytes_FromStringAndSize(tmp_str, str_len);
423            if (tmp_str)
424                PQfreemem(tmp_str);
425            break;
426
427        case PYGRES_JSON:
428            /* this type should only be passed when jsondecode is set */
429            obj = get_decoded_string(s, size, encoding);
430            if (obj && jsondecode) /* was able to decode */
431            {
432                tmp_obj = Py_BuildValue("(O)", obj);
433                obj = PyObject_CallObject(jsondecode, tmp_obj);
434                Py_DECREF(tmp_obj);
435            }
436            break;
437
438        default:  /* PYGRES_TEXT */
439#if IS_PY3
440            obj = get_decoded_string(s, size, encoding);
441            if (!obj) /* cannot decode */
442#endif
443            obj = PyBytes_FromStringAndSize(s, size);
444    }
445
446    return obj;
447}
448
449/* Cast an arbitrary type to a Python object using a callback function.
450   This needs the character string, size, encoding, the Postgres type
451   and the external typecast function to be called. */
452static PyObject *
453cast_other(char *s, Py_ssize_t size, int encoding, Oid pgtype,
454    PyObject *cast_hook)
455{
456    PyObject *obj;
457
458    obj = cast_sized_text(s, size, encoding, PYGRES_TEXT);
459
460    if (cast_hook)
461    {
462        PyObject *tmp_obj = obj;
463        obj = PyObject_CallFunction(cast_hook, "(OI)", obj, pgtype);
464        Py_DECREF(tmp_obj);
465    }
466    return obj;
467}
468
469/* Cast a simple type to a Python object.
470   This needs a character string representation with a given size. */
471static PyObject *
472cast_sized_simple(char *s, Py_ssize_t size, int type)
473{
474    PyObject   *obj, *tmp_obj;
475    char        buf[64], *t;
476    int         i, j, n;
477
478    switch (type) /* this must be the PyGreSQL internal type */
479    {
480        case PYGRES_INT:
481            n = sizeof(buf)/sizeof(buf[0]) - 1;
482            if ((int)size < n) n = (int)size;
483            for (i = 0, t = buf; i < n; ++i) *t++ = *s++;
484            *t = '\0';
485            obj = PyInt_FromString(buf, NULL, 10);
486            break;
487
488        case PYGRES_LONG:
489            n = sizeof(buf)/sizeof(buf[0]) - 1;
490            if ((int)size < n) n = (int)size;
491            for (i = 0, t = buf; i < n; ++i) *t++ = *s++;
492            *t = '\0';
493            obj = PyLong_FromString(buf, NULL, 10);
494            break;
495
496        case PYGRES_FLOAT:
497            tmp_obj = PyStr_FromStringAndSize(s, size);
498            obj = PyFloat_FromString(tmp_obj);
499            Py_DECREF(tmp_obj);
500            break;
501
502        case PYGRES_MONEY:
503            /* this type should only be passed when decimal_point is set */
504            n = sizeof(buf)/sizeof(buf[0]) - 1;
505            for (i = 0, j = 0; i < size && j < n; ++i, ++s)
506            {
507                if (*s >= '0' && *s <= '9')
508                    buf[j++] = *s;
509                else if (*s == decimal_point)
510                    buf[j++] = '.';
511                else if (*s == '(' || *s == '-')
512                    buf[j++] = '-';
513            }
514            if (decimal)
515            {
516                buf[j] = '\0';
517                obj = PyObject_CallFunction(decimal, "(s)", buf);
518            }
519            else
520            {
521                tmp_obj = PyStr_FromString(buf);
522                obj = PyFloat_FromString(tmp_obj);
523                Py_DECREF(tmp_obj);
524
525            }
526            break;
527
528        case PYGRES_DECIMAL:
529            tmp_obj = PyStr_FromStringAndSize(s, size);
530            obj = decimal ? PyObject_CallFunctionObjArgs(
531                decimal, tmp_obj, NULL) : PyFloat_FromString(tmp_obj);
532            Py_DECREF(tmp_obj);
533            break;
534
535        case PYGRES_BOOL:
536            /* convert to bool only if bool_as_text is not set */
537            if (bool_as_text)
538            {
539                obj = PyStr_FromString(*s == 't' ? "t" : "f");
540            }
541            else
542            {
543                obj = *s == 't' ? Py_True : Py_False;
544                Py_INCREF(obj);
545            }
546            break;
547
548        default:
549            /* other types should never be passed, use cast_sized_text */
550            obj = PyStr_FromStringAndSize(s, size);
551    }
552
553    return obj;
554}
555
556/* Cast a simple type to a Python object.
557   This needs a null-terminated character string representation. */
558static PyObject *
559cast_unsized_simple(char *s, int type)
560{
561    PyObject   *obj, *tmp_obj;
562    char        buf[64];
563    int         j, n;
564
565    switch (type) /* this must be the PyGreSQL internal type */
566    {
567        case PYGRES_INT:
568            obj = PyInt_FromString(s, NULL, 10);
569            break;
570
571        case PYGRES_LONG:
572            obj = PyLong_FromString(s, NULL, 10);
573            break;
574
575        case PYGRES_FLOAT:
576            tmp_obj = PyStr_FromString(s);
577            obj = PyFloat_FromString(tmp_obj);
578            Py_DECREF(tmp_obj);
579            break;
580
581        case PYGRES_MONEY:
582            /* this type should only be passed when decimal_point is set */
583            n = sizeof(buf)/sizeof(buf[0]) - 1;
584            for (j = 0; *s && j < n; ++s)
585            {
586                if (*s >= '0' && *s <= '9')
587                    buf[j++] = *s;
588                else if (*s == decimal_point)
589                    buf[j++] = '.';
590                else if (*s == '(' || *s == '-')
591                    buf[j++] = '-';
592            }
593            buf[j] = '\0'; s = buf;
594            /* FALLTHROUGH */ /* no break here */
595
596        case PYGRES_DECIMAL:
597            if (decimal)
598            {
599                obj = PyObject_CallFunction(decimal, "(s)", s);
600            }
601            else
602            {
603                tmp_obj = PyStr_FromString(s);
604                obj = PyFloat_FromString(tmp_obj);
605                Py_DECREF(tmp_obj);
606            }
607            break;
608
609        case PYGRES_BOOL:
610            /* convert to bool only if bool_as_text is not set */
611            if (bool_as_text)
612            {
613                obj = PyStr_FromString(*s == 't' ? "t" : "f");
614            }
615            else
616            {
617                obj = *s == 't' ? Py_True : Py_False;
618                Py_INCREF(obj);
619            }
620            break;
621
622        default:
623            /* other types should never be passed, use cast_sized_text */
624            obj = PyStr_FromString(s);
625    }
626
627    return obj;
628}
629
630/* quick case insensitive check if given sized string is null */
631#define STR_IS_NULL(s, n) (n == 4 \
632    && (s[0] == 'n' || s[0] == 'N') \
633    && (s[1] == 'u' || s[1] == 'U') \
634    && (s[2] == 'l' || s[2] == 'L') \
635    && (s[3] == 'l' || s[3] == 'L'))
636
637/* Cast string s with size and encoding to a Python list,
638   using the input and output syntax for arrays.
639   Use internal type or cast function to cast elements.
640   The parameter delim specifies the delimiter for the elements,
641   since some types do not use the default delimiter of a comma. */
642static PyObject *
643cast_array(char *s, Py_ssize_t size, int encoding,
644     int type, PyObject *cast, char delim)
645{
646    PyObject   *result, *stack[MAX_ARRAY_DEPTH];
647    char       *end = s + size, *t;
648    int         depth, ranges = 0, level = 0;
649
650    if (type)
651    {
652        type &= ~PYGRES_ARRAY; /* get the base type */
653        if (!type) type = PYGRES_TEXT;
654    }
655    if (!delim)
656        delim = ',';
657    else if (delim == '{' || delim =='}' || delim=='\\')
658    {
659        PyErr_SetString(PyExc_ValueError, "Invalid array delimiter");
660        return NULL;
661    }
662
663    /* strip blanks at the beginning */
664    while (s != end && *s == ' ') ++s;
665    if (*s == '[') /* dimension ranges */
666    {
667        int valid;
668
669        for (valid = 0; !valid;)
670        {
671            if (s == end || *s++ != '[') break;
672            while (s != end && *s == ' ') ++s;
673            if (s != end && (*s == '+' || *s == '-')) ++s;
674            if (s == end || *s < '0' || *s > '9') break;
675            while (s != end && *s >= '0' && *s <= '9') ++s;
676            if (s == end || *s++ != ':') break;
677            if (s != end && (*s == '+' || *s == '-')) ++s;
678            if (s == end || *s < '0' || *s > '9') break;
679            while (s != end && *s >= '0' && *s <= '9') ++s;
680            if (s == end || *s++ != ']') break;
681            while (s != end && *s == ' ') ++s;
682            ++ranges;
683            if (s != end && *s == '=')
684            {
685                do ++s; while (s != end && *s == ' ');
686                valid = 1;
687            }
688        }
689        if (!valid)
690        {
691            PyErr_SetString(PyExc_ValueError, "Invalid array dimensions");
692            return NULL;
693        }
694    }
695    for (t = s, depth = 0; t != end && (*t == '{' || *t == ' '); ++t)
696        if (*t == '{') ++depth;
697    if (!depth)
698    {
699        PyErr_SetString(PyExc_ValueError,
700            "Array must start with a left brace");
701        return NULL;
702    }
703    if (ranges && depth != ranges)
704    {
705        PyErr_SetString(PyExc_ValueError,
706            "Array dimensions do not match content");
707        return NULL;
708    }
709    if (depth > MAX_ARRAY_DEPTH)
710    {
711        PyErr_SetString(PyExc_ValueError, "Array is too deeply nested");
712        return NULL;
713    }
714    depth--; /* next level of parsing */
715    result = PyList_New(0);
716    if (!result) return NULL;
717    do ++s; while (s != end && *s == ' ');
718    /* everything is set up, start parsing the array */
719    while (s != end)
720    {
721        if (*s == '}')
722        {
723            PyObject *subresult;
724
725            if (!level) break; /* top level array ended */
726            do ++s; while (s != end && *s == ' ');
727            if (s == end) break; /* error */
728            if (*s == delim)
729            {
730                do ++s; while (s != end && *s == ' ');
731                if (s == end) break; /* error */
732                if (*s != '{')
733                {
734                    PyErr_SetString(PyExc_ValueError,
735                        "Subarray expected but not found");
736                    Py_DECREF(result); return NULL;
737                }
738            }
739            else if (*s != '}') break; /* error */
740            subresult = result;
741            result = stack[--level];
742            if (PyList_Append(result, subresult))
743            {
744                Py_DECREF(result); return NULL;
745            }
746        }
747        else if (level == depth) /* we expect elements at this level */
748        {
749            PyObject   *element;
750            char       *estr;
751            Py_ssize_t  esize;
752            int escaped = 0;
753
754            if (*s == '{')
755            {
756                PyErr_SetString(PyExc_ValueError,
757                    "Subarray found where not expected");
758                Py_DECREF(result); return NULL;
759            }
760            if (*s == '"') /* quoted element */
761            {
762                estr = ++s;
763                while (s != end && *s != '"')
764                {
765                    if (*s == '\\')
766                    {
767                        ++s; if (s == end) break;
768                        escaped = 1;
769                    }
770                    ++s;
771                }
772                esize = s - estr;
773                do ++s; while (s != end && *s == ' ');
774            }
775            else /* unquoted element */
776            {
777                estr = s;
778                /* can contain blanks inside */
779                while (s != end && *s != '"' &&
780                    *s != '{' && *s != '}' && *s != delim)
781                {
782                    if (*s == '\\')
783                    {
784                        ++s; if (s == end) break;
785                        escaped = 1;
786                    }
787                    ++s;
788                }
789                t = s; while (t > estr && *(t - 1) == ' ') --t;
790                if (!(esize = t - estr))
791                {
792                    s = end; break; /* error */
793                }
794                if (STR_IS_NULL(estr, esize)) /* NULL gives None */
795                    estr = NULL;
796            }
797            if (s == end) break; /* error */
798            if (estr)
799            {
800                if (escaped)
801                {
802                    char       *r;
803                    Py_ssize_t  i;
804
805                    /* create unescaped string */
806                    t = estr;
807                    estr = (char *) PyMem_Malloc(esize);
808                    if (!estr)
809                    {
810                        Py_DECREF(result); return PyErr_NoMemory();
811                    }
812                    for (i = 0, r = estr; i < esize; ++i)
813                    {
814                        if (*t == '\\') ++t, ++i;
815                        *r++ = *t++;
816                    }
817                    esize = r - estr;
818                }
819                if (type) /* internal casting of base type */
820                {
821                    if (type & PYGRES_TEXT)
822                        element = cast_sized_text(estr, esize, encoding, type);
823                    else
824                        element = cast_sized_simple(estr, esize, type);
825                }
826                else /* external casting of base type */
827                {
828#if IS_PY3
829                    element = encoding == pg_encoding_ascii ? NULL :
830                        get_decoded_string(estr, esize, encoding);
831                    if (!element) /* no decoding necessary or possible */
832#endif
833                    element = PyBytes_FromStringAndSize(estr, esize);
834                    if (element && cast)
835                    {
836                        PyObject *tmp = element;
837                        element = PyObject_CallFunctionObjArgs(
838                            cast, element, NULL);
839                        Py_DECREF(tmp);
840                    }
841                }
842                if (escaped) PyMem_Free(estr);
843                if (!element)
844                {
845                    Py_DECREF(result); return NULL;
846                }
847            }
848            else
849            {
850                Py_INCREF(Py_None); element = Py_None;
851            }
852            if (PyList_Append(result, element))
853            {
854                Py_DECREF(element); Py_DECREF(result); return NULL;
855            }
856            Py_DECREF(element);
857            if (*s == delim)
858            {
859                do ++s; while (s != end && *s == ' ');
860                if (s == end) break; /* error */
861            }
862            else if (*s != '}') break; /* error */
863        }
864        else /* we expect arrays at this level */
865        {
866            if (*s != '{')
867            {
868                PyErr_SetString(PyExc_ValueError,
869                    "Subarray must start with a left brace");
870                Py_DECREF(result); return NULL;
871            }
872            do ++s; while (s != end && *s == ' ');
873            if (s == end) break; /* error */
874            stack[level++] = result;
875            if (!(result = PyList_New(0))) return NULL;
876        }
877    }
878    if (s == end || *s != '}')
879    {
880        PyErr_SetString(PyExc_ValueError,
881            "Unexpected end of array");
882        Py_DECREF(result); return NULL;
883    }
884    do ++s; while (s != end && *s == ' ');
885    if (s != end)
886    {
887        PyErr_SetString(PyExc_ValueError,
888            "Unexpected characters after end of array");
889        Py_DECREF(result); return NULL;
890    }
891    return result;
892}
893
894/* Cast string s with size and encoding to a Python tuple.
895   using the input and output syntax for composite types.
896   Use array of internal types or cast function or sequence of cast
897   functions to cast elements. The parameter len is the record size.
898   The parameter delim can specify a delimiter for the elements,
899   although composite types always use a comma as delimiter. */
900
901static PyObject *
902cast_record(char *s, Py_ssize_t size, int encoding,
903     int *type, PyObject *cast, Py_ssize_t len, char delim)
904{
905    PyObject   *result, *ret;
906    char       *end = s + size, *t;
907    Py_ssize_t  i;
908
909    if (!delim)
910        delim = ',';
911    else if (delim == '(' || delim ==')' || delim=='\\')
912    {
913        PyErr_SetString(PyExc_ValueError, "Invalid record delimiter");
914        return NULL;
915    }
916
917    /* strip blanks at the beginning */
918    while (s != end && *s == ' ') ++s;
919    if (s == end || *s != '(')
920    {
921        PyErr_SetString(PyExc_ValueError,
922            "Record must start with a left parenthesis");
923        return NULL;
924    }
925    result = PyList_New(0);
926    if (!result) return NULL;
927    i = 0;
928    /* everything is set up, start parsing the record */
929    while (++s != end)
930    {
931        PyObject   *element;
932
933        if (*s == ')' || *s == delim)
934        {
935            Py_INCREF(Py_None); element = Py_None;
936        }
937        else
938        {
939            char       *estr;
940            Py_ssize_t  esize;
941            int quoted = 0, escaped = 0;
942
943            estr = s;
944            quoted = *s == '"';
945            if (quoted) ++s;
946            esize = 0;
947            while (s != end)
948            {
949                if (!quoted && (*s == ')' || *s == delim))
950                    break;
951                if (*s == '"')
952                {
953                    ++s; if (s == end) break;
954                    if (!(quoted && *s == '"'))
955                    {
956                        quoted = !quoted; continue;
957                    }
958                }
959                if (*s == '\\')
960                {
961                    ++s; if (s == end) break;
962                }
963                ++s, ++esize;
964            }
965            if (s == end) break; /* error */
966            if (estr + esize != s)
967            {
968                char       *r;
969
970                escaped = 1;
971                /* create unescaped string */
972                t = estr;
973                estr = (char *) PyMem_Malloc(esize);
974                if (!estr)
975                {
976                    Py_DECREF(result); return PyErr_NoMemory();
977                }
978                quoted = 0;
979                r = estr;
980                while (t != s)
981                {
982                    if (*t == '"')
983                    {
984                        ++t;
985                        if (!(quoted && *t == '"'))
986                        {
987                            quoted = !quoted; continue;
988                        }
989                    }
990                    if (*t == '\\') ++t;
991                    *r++ = *t++;
992                }
993            }
994            if (type) /* internal casting of element type */
995            {
996                int etype = type[i];
997
998                if (etype & PYGRES_ARRAY)
999                    element = cast_array(
1000                        estr, esize, encoding, etype, NULL, 0);
1001                else if (etype & PYGRES_TEXT)
1002                    element = cast_sized_text(estr, esize, encoding, etype);
1003                else
1004                    element = cast_sized_simple(estr, esize, etype);
1005            }
1006            else /* external casting of base type */
1007            {
1008#if IS_PY3
1009                element = encoding == pg_encoding_ascii ? NULL :
1010                    get_decoded_string(estr, esize, encoding);
1011                if (!element) /* no decoding necessary or possible */
1012#endif
1013                element = PyBytes_FromStringAndSize(estr, esize);
1014                if (element && cast)
1015                {
1016                    if (len)
1017                    {
1018                        PyObject *ecast = PySequence_GetItem(cast, i);
1019
1020                        if (ecast)
1021                        {
1022                            if (ecast != Py_None)
1023                            {
1024                                PyObject *tmp = element;
1025                                element = PyObject_CallFunctionObjArgs(
1026                                    ecast, element, NULL);
1027                                Py_DECREF(tmp);
1028                            }
1029                        }
1030                        else
1031                        {
1032                            Py_DECREF(element); element = NULL;
1033                        }
1034                    }
1035                    else
1036                    {
1037                        PyObject *tmp = element;
1038                        element = PyObject_CallFunctionObjArgs(
1039                            cast, element, NULL);
1040                        Py_DECREF(tmp);
1041                    }
1042                }
1043            }
1044            if (escaped) PyMem_Free(estr);
1045            if (!element)
1046            {
1047                Py_DECREF(result); return NULL;
1048            }
1049        }
1050        if (PyList_Append(result, element))
1051        {
1052            Py_DECREF(element); Py_DECREF(result); return NULL;
1053        }
1054        Py_DECREF(element);
1055        if (len) ++i;
1056        if (*s != delim) break; /* no next record */
1057        if (len && i >= len)
1058        {
1059            PyErr_SetString(PyExc_ValueError, "Too many columns");
1060            Py_DECREF(result); return NULL;
1061        }
1062    }
1063    if (s == end || *s != ')')
1064    {
1065        PyErr_SetString(PyExc_ValueError, "Unexpected end of record");
1066        Py_DECREF(result); return NULL;
1067    }
1068    do ++s; while (s != end && *s == ' ');
1069    if (s != end)
1070    {
1071        PyErr_SetString(PyExc_ValueError,
1072            "Unexpected characters after end of record");
1073        Py_DECREF(result); return NULL;
1074    }
1075    if (len && i < len)
1076    {
1077        PyErr_SetString(PyExc_ValueError, "Too few columns");
1078        Py_DECREF(result); return NULL;
1079    }
1080
1081    ret = PyList_AsTuple(result);
1082    Py_DECREF(result);
1083    return ret;
1084}
1085
1086/* Cast string s with size and encoding to a Python dictionary.
1087   using the input and output syntax for hstore values. */
1088
1089static PyObject *
1090cast_hstore(char *s, Py_ssize_t size, int encoding)
1091{
1092    PyObject   *result;
1093    char       *end = s + size;
1094
1095    result = PyDict_New();
1096
1097    /* everything is set up, start parsing the record */
1098    while (s != end)
1099    {
1100        char       *key, *val;
1101        PyObject   *key_obj, *val_obj;
1102        Py_ssize_t  key_esc = 0, val_esc = 0, size;
1103        int         quoted;
1104
1105        while (s != end && *s == ' ') ++s;
1106        if (s == end) break;
1107        quoted = *s == '"';
1108        if (quoted)
1109        {
1110            key = ++s;
1111            while (s != end)
1112            {
1113                if (*s == '"') break;
1114                if (*s == '\\')
1115                {
1116                    if (++s == end) break;
1117                    ++key_esc;
1118                }
1119                ++s;
1120            }
1121            if (s == end)
1122            {
1123                PyErr_SetString(PyExc_ValueError, "Unterminated quote");
1124                Py_DECREF(result); return NULL;
1125            }
1126        }
1127        else
1128        {
1129            key = s;
1130            while (s != end)
1131            {
1132                if (*s == '=' || *s == ' ') break;
1133                if (*s == '\\')
1134                {
1135                    if (++s == end) break;
1136                    ++key_esc;
1137                }
1138                ++s;
1139            }
1140            if (s == key)
1141            {
1142                PyErr_SetString(PyExc_ValueError, "Missing key");
1143                Py_DECREF(result); return NULL;
1144            }
1145        }
1146        size = s - key - key_esc;
1147        if (key_esc)
1148        {
1149            char *r = key, *t;
1150            key = (char *) PyMem_Malloc(size);
1151            if (!key)
1152            {
1153                Py_DECREF(result); return PyErr_NoMemory();
1154            }
1155            t = key;
1156            while (r != s)
1157            {
1158                if (*r == '\\')
1159                {
1160                    ++r; if (r == s) break;
1161                }
1162                *t++ = *r++;
1163            }
1164        }
1165        key_obj = cast_sized_text(key, size, encoding, PYGRES_TEXT);
1166        if (key_esc) PyMem_Free(key);
1167        if (!key_obj)
1168        {
1169            Py_DECREF(result); return NULL;
1170        }
1171        if (quoted) ++s;
1172        while (s != end && *s == ' ') ++s;
1173        if (s == end || *s++ != '=' || s == end || *s++ != '>')
1174        {
1175            PyErr_SetString(PyExc_ValueError, "Invalid characters after key");
1176            Py_DECREF(key_obj); Py_DECREF(result); return NULL;
1177        }
1178        while (s != end && *s == ' ') ++s;
1179        quoted = *s == '"';
1180        if (quoted)
1181        {
1182            val = ++s;
1183            while (s != end)
1184            {
1185                if (*s == '"') break;
1186                if (*s == '\\')
1187                {
1188                    if (++s == end) break;
1189                    ++val_esc;
1190                }
1191                ++s;
1192            }
1193            if (s == end)
1194            {
1195                PyErr_SetString(PyExc_ValueError, "Unterminated quote");
1196                Py_DECREF(result); return NULL;
1197            }
1198        }
1199        else
1200        {
1201            val = s;
1202            while (s != end)
1203            {
1204                if (*s == ',' || *s == ' ') break;
1205                if (*s == '\\')
1206                {
1207                    if (++s == end) break;
1208                    ++val_esc;
1209                }
1210                ++s;
1211            }
1212            if (s == val)
1213            {
1214                PyErr_SetString(PyExc_ValueError, "Missing value");
1215                Py_DECREF(key_obj); Py_DECREF(result); return NULL;
1216            }
1217            if (STR_IS_NULL(val, s - val))
1218                val = NULL;
1219        }
1220        if (val)
1221        {
1222            size = s - val - val_esc;
1223            if (val_esc)
1224            {
1225                char *r = val, *t;
1226                val = (char *) PyMem_Malloc(size);
1227                if (!val)
1228                {
1229                    Py_DECREF(key_obj); Py_DECREF(result);
1230                    return PyErr_NoMemory();
1231                }
1232                t = val;
1233                while (r != s)
1234                {
1235                    if (*r == '\\')
1236                    {
1237                        ++r; if (r == s) break;
1238                    }
1239                    *t++ = *r++;
1240                }
1241            }
1242            val_obj = cast_sized_text(val, size, encoding, PYGRES_TEXT);
1243            if (val_esc) PyMem_Free(val);
1244            if (!val_obj)
1245            {
1246                Py_DECREF(key_obj); Py_DECREF(result); return NULL;
1247            }
1248        }
1249        else
1250        {
1251            Py_INCREF(Py_None); val_obj = Py_None;
1252        }
1253        if (quoted) ++s;
1254        while (s != end && *s == ' ') ++s;
1255        if (s != end)
1256        {
1257            if (*s++ != ',')
1258            {
1259                PyErr_SetString(PyExc_ValueError,
1260                    "Invalid characters after val");
1261                Py_DECREF(key_obj); Py_DECREF(val_obj);
1262                Py_DECREF(result); return NULL;
1263            }
1264            while (s != end && *s == ' ') ++s;
1265            if (s == end)
1266            {
1267                PyErr_SetString(PyExc_ValueError, "Missing entry");
1268                Py_DECREF(key_obj); Py_DECREF(val_obj);
1269                Py_DECREF(result); return NULL;
1270            }
1271        }
1272        PyDict_SetItem(result, key_obj, val_obj);
1273        Py_DECREF(key_obj); Py_DECREF(val_obj);
1274    }
1275    return result;
1276}
1277
1278/* internal wrapper for the notice receiver callback */
1279static void
1280notice_receiver(void *arg, const PGresult *res)
1281{
1282    PyGILState_STATE gstate = PyGILState_Ensure();
1283    connObject *self = (connObject*) arg;
1284    PyObject *func = self->notice_receiver;
1285
1286    if (func)
1287    {
1288        noticeObject *notice = PyObject_NEW(noticeObject, &noticeType);
1289        PyObject *ret;
1290        if (notice)
1291        {
1292            notice->pgcnx = arg;
1293            notice->res = res;
1294        }
1295        else
1296        {
1297            Py_INCREF(Py_None);
1298            notice = (noticeObject *)(void *)Py_None;
1299        }
1300        ret = PyObject_CallFunction(func, "(O)", notice);
1301        Py_XDECREF(ret);
1302    }
1303    PyGILState_Release(gstate);
1304}
1305
1306/* gets appropriate error type from sqlstate */
1307static PyObject *
1308get_error_type(const char *sqlstate)
1309{
1310    switch (sqlstate[0]) {
1311        case '0':
1312            switch (sqlstate[1])
1313            {
1314                case 'A':
1315                    return NotSupportedError;
1316            }
1317            break;
1318        case '2':
1319            switch (sqlstate[1])
1320            {
1321                case '0':
1322                case '1':
1323                    return ProgrammingError;
1324                case '2':
1325                    return DataError;
1326                case '3':
1327                    return IntegrityError;
1328                case '4':
1329                case '5':
1330                    return InternalError;
1331                case '6':
1332                case '7':
1333                case '8':
1334                    return OperationalError;
1335                case 'B':
1336                case 'D':
1337                case 'F':
1338                    return InternalError;
1339            }
1340            break;
1341        case '3':
1342            switch (sqlstate[1])
1343            {
1344                case '4':
1345                    return OperationalError;
1346                case '8':
1347                case '9':
1348                case 'B':
1349                    return InternalError;
1350                case 'D':
1351                case 'F':
1352                    return ProgrammingError;
1353            }
1354            break;
1355        case '4':
1356            switch (sqlstate[1])
1357            {
1358                case '0':
1359                    return OperationalError;
1360                case '2':
1361                case '4':
1362                    return ProgrammingError;
1363            }
1364            break;
1365        case '5':
1366        case 'H':
1367            return OperationalError;
1368        case 'F':
1369        case 'P':
1370        case 'X':
1371            return InternalError;
1372    }
1373    return DatabaseError;
1374}
1375
1376/* sets database error message and sqlstate attribute */
1377static void
1378set_error_msg_and_state(PyObject *type,
1379    const char *msg, int encoding, const char *sqlstate)
1380{
1381    PyObject   *err_obj, *msg_obj, *sql_obj = NULL;
1382
1383#if IS_PY3
1384    if (encoding == -1) /* unknown */
1385    {
1386        msg_obj = PyUnicode_DecodeLocale(msg, NULL);
1387    }
1388    else
1389        msg_obj = get_decoded_string(msg, strlen(msg), encoding);
1390    if (!msg_obj) /* cannot decode */
1391#endif
1392    msg_obj = PyBytes_FromString(msg);
1393
1394    if (sqlstate)
1395        sql_obj = PyStr_FromStringAndSize(sqlstate, 5);
1396    else
1397    {
1398        Py_INCREF(Py_None); sql_obj = Py_None;
1399    }
1400
1401    err_obj = PyObject_CallFunctionObjArgs(type, msg_obj, NULL);
1402    if (err_obj)
1403    {
1404        Py_DECREF(msg_obj);
1405        PyObject_SetAttrString(err_obj, "sqlstate", sql_obj);
1406        Py_DECREF(sql_obj);
1407        PyErr_SetObject(type, err_obj);
1408        Py_DECREF(err_obj);
1409    }
1410    else
1411    {
1412        PyErr_SetString(type, msg);
1413    }
1414}
1415
1416/* sets given database error message */
1417static void
1418set_error_msg(PyObject *type, const char *msg)
1419{
1420    set_error_msg_and_state(type, msg, pg_encoding_ascii, NULL);
1421}
1422
1423/* sets database error from connection and/or result */
1424static void
1425set_error(PyObject *type, const char * msg, PGconn *cnx, PGresult *result)
1426{
1427    char *sqlstate = NULL; int encoding = pg_encoding_ascii;
1428
1429    if (cnx)
1430    {
1431        char *err_msg = PQerrorMessage(cnx);
1432        if (err_msg)
1433        {
1434            msg = err_msg;
1435            encoding = PQclientEncoding(cnx);
1436        }
1437    }
1438    if (result)
1439    {
1440        sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
1441        if (sqlstate) type = get_error_type(sqlstate);
1442    }
1443
1444    set_error_msg_and_state(type, msg, encoding, sqlstate);
1445}
1446
1447/* checks connection validity */
1448static int
1449check_cnx_obj(connObject *self)
1450{
1451    if (!self || !self->valid || !self->cnx)
1452    {
1453        set_error_msg(OperationalError, "Connection has been closed");
1454        return 0;
1455    }
1456    return 1;
1457}
1458
1459/* format result (mostly useful for debugging) */
1460/* Note: This is similar to the Postgres function PQprint().
1461 * PQprint() is not used because handing over a stream from Python to
1462 * Postgres can be problematic if they use different libs for streams
1463 * and because using PQprint() and tp_print is not recommended any more.
1464 */
1465static PyObject *
1466format_result(const PGresult *res)
1467{
1468    const int n = PQnfields(res);
1469
1470    if (n > 0)
1471    {
1472        char * const aligns = (char *) PyMem_Malloc(n * sizeof(char));
1473        int * const sizes = (int *) PyMem_Malloc(n * sizeof(int));
1474
1475        if (aligns && sizes)
1476        {
1477            const int m = PQntuples(res);
1478            int i, j;
1479            size_t size;
1480            char *buffer;
1481
1482            /* calculate sizes and alignments */
1483            for (j = 0; j < n; ++j)
1484            {
1485                const char * const s = PQfname(res, j);
1486                const int format = PQfformat(res, j);
1487
1488                sizes[j] = s ? (int)strlen(s) : 0;
1489                if (format)
1490                {
1491                    aligns[j] = '\0';
1492                    if (m && sizes[j] < 8)
1493                        /* "<binary>" must fit */
1494                        sizes[j] = 8;
1495                }
1496                else
1497                {
1498                    const Oid ftype = PQftype(res, j);
1499
1500                    switch (ftype)
1501                    {
1502                        case INT2OID:
1503                        case INT4OID:
1504                        case INT8OID:
1505                        case FLOAT4OID:
1506                        case FLOAT8OID:
1507                        case NUMERICOID:
1508                        case OIDOID:
1509                        case XIDOID:
1510                        case CIDOID:
1511                        case CASHOID:
1512                            aligns[j] = 'r';
1513                            break;
1514                        default:
1515                            aligns[j] = 'l';
1516                    }
1517                }
1518            }
1519            for (i = 0; i < m; ++i)
1520            {
1521                for (j = 0; j < n; ++j)
1522                {
1523                    if (aligns[j])
1524                    {
1525                        const int k = PQgetlength(res, i, j);
1526
1527                        if (sizes[j] < k)
1528                            /* value must fit */
1529                            sizes[j] = k;
1530                    }
1531                }
1532            }
1533            size = 0;
1534            /* size of one row */
1535            for (j = 0; j < n; ++j) size += sizes[j] + 1;
1536            /* times number of rows incl. heading */
1537            size *= (m + 2);
1538            /* plus size of footer */
1539            size += 40;
1540            /* is the buffer size that needs to be allocated */
1541            buffer = (char *) PyMem_Malloc(size);
1542            if (buffer)
1543            {
1544                char *p = buffer;
1545                PyObject *result;
1546
1547                /* create the header */
1548                for (j = 0; j < n; ++j)
1549                {
1550                    const char * const s = PQfname(res, j);
1551                    const int k = sizes[j];
1552                    const int h = (k - (int)strlen(s)) / 2;
1553
1554                    sprintf(p, "%*s", h, "");
1555                    sprintf(p + h, "%-*s", k - h, s);
1556                    p += k;
1557                    if (j + 1 < n)
1558                        *p++ = '|';
1559                }
1560                *p++ = '\n';
1561                for (j = 0; j < n; ++j)
1562                {
1563                    int k = sizes[j];
1564
1565                    while (k--)
1566                        *p++ = '-';
1567                    if (j + 1 < n)
1568                        *p++ = '+';
1569                }
1570                *p++ = '\n';
1571                /* create the body */
1572                for (i = 0; i < m; ++i)
1573                {
1574                    for (j = 0; j < n; ++j)
1575                    {
1576                        const char align = aligns[j];
1577                        const int k = sizes[j];
1578
1579                        if (align)
1580                        {
1581                            sprintf(p, align == 'r' ?
1582                                "%*s" : "%-*s", k,
1583                                PQgetvalue(res, i, j));
1584                        }
1585                        else
1586                        {
1587                            sprintf(p, "%-*s", k,
1588                                PQgetisnull(res, i, j) ?
1589                                "" : "<binary>");
1590                        }
1591                        p += k;
1592                        if (j + 1 < n)
1593                            *p++ = '|';
1594                    }
1595                    *p++ = '\n';
1596                }
1597                /* free memory */
1598                PyMem_Free(aligns); PyMem_Free(sizes);
1599                /* create the footer */
1600                sprintf(p, "(%d row%s)", m, m == 1 ? "" : "s");
1601                /* return the result */
1602                result = PyStr_FromString(buffer);
1603                PyMem_Free(buffer);
1604                return result;
1605            }
1606            else
1607            {
1608                PyMem_Free(aligns); PyMem_Free(sizes); return PyErr_NoMemory();
1609            }
1610        }
1611        else
1612        {
1613            PyMem_Free(aligns); PyMem_Free(sizes); return PyErr_NoMemory();
1614        }
1615    }
1616    else
1617        return PyStr_FromString("(nothing selected)");
1618}
1619
1620/* --------------------------------------------------------------------- */
1621/* large objects                                                         */
1622/* --------------------------------------------------------------------- */
1623#ifdef LARGE_OBJECTS
1624
1625/* checks large object validity */
1626static int
1627check_lo_obj(largeObject *self, int level)
1628{
1629    if (!check_cnx_obj(self->pgcnx))
1630        return 0;
1631
1632    if (!self->lo_oid)
1633    {
1634        set_error_msg(IntegrityError, "Object is not valid (null oid)");
1635        return 0;
1636    }
1637
1638    if (level & CHECK_OPEN)
1639    {
1640        if (self->lo_fd < 0)
1641        {
1642            PyErr_SetString(PyExc_IOError, "Object is not opened");
1643            return 0;
1644        }
1645    }
1646
1647    if (level & CHECK_CLOSE)
1648    {
1649        if (self->lo_fd >= 0)
1650        {
1651            PyErr_SetString(PyExc_IOError, "Object is already opened");
1652            return 0;
1653        }
1654    }
1655
1656    return 1;
1657}
1658
1659/* constructor (internal use only) */
1660static largeObject *
1661largeNew(connObject *pgcnx, Oid oid)
1662{
1663    largeObject *large_obj;
1664
1665    if (!(large_obj = PyObject_NEW(largeObject, &largeType)))
1666        return NULL;
1667
1668    Py_XINCREF(pgcnx);
1669    large_obj->pgcnx = pgcnx;
1670    large_obj->lo_fd = -1;
1671    large_obj->lo_oid = oid;
1672
1673    return large_obj;
1674}
1675
1676/* destructor */
1677static void
1678largeDealloc(largeObject *self)
1679{
1680    if (self->lo_fd >= 0 && self->pgcnx->valid)
1681        lo_close(self->pgcnx->cnx, self->lo_fd);
1682
1683    Py_XDECREF(self->pgcnx);
1684    PyObject_Del(self);
1685}
1686
1687/* opens large object */
1688static char largeOpen__doc__[] =
1689"open(mode) -- open access to large object with specified mode\n\n"
1690"The mode must be one of INV_READ, INV_WRITE (module level constants).\n";
1691
1692static PyObject *
1693largeOpen(largeObject *self, PyObject *args)
1694{
1695    int         mode,
1696                fd;
1697
1698    /* gets arguments */
1699    if (!PyArg_ParseTuple(args, "i", &mode))
1700    {
1701        PyErr_SetString(PyExc_TypeError,
1702            "The open() method takes an integer argument");
1703        return NULL;
1704    }
1705
1706    /* check validity */
1707    if (!check_lo_obj(self, CHECK_CLOSE))
1708        return NULL;
1709
1710    /* opens large object */
1711    if ((fd = lo_open(self->pgcnx->cnx, self->lo_oid, mode)) == -1)
1712    {
1713        PyErr_SetString(PyExc_IOError, "Can't open large object");
1714        return NULL;
1715    }
1716    self->lo_fd = fd;
1717
1718    /* no error : returns Py_None */
1719    Py_INCREF(Py_None);
1720    return Py_None;
1721}
1722
1723/* close large object */
1724static char largeClose__doc__[] =
1725"close() -- close access to large object data";
1726
1727static PyObject *
1728largeClose(largeObject *self, PyObject *noargs)
1729{
1730    /* checks validity */
1731    if (!check_lo_obj(self, CHECK_OPEN))
1732        return NULL;
1733
1734    /* closes large object */
1735    if (lo_close(self->pgcnx->cnx, self->lo_fd))
1736    {
1737        PyErr_SetString(PyExc_IOError, "Error while closing large object fd");
1738        return NULL;
1739    }
1740    self->lo_fd = -1;
1741
1742    /* no error : returns Py_None */
1743    Py_INCREF(Py_None);
1744    return Py_None;
1745}
1746
1747/* reads from large object */
1748static char largeRead__doc__[] =
1749"read(size) -- read from large object to sized string\n\n"
1750"Object must be opened in read mode before calling this method.\n";
1751
1752static PyObject *
1753largeRead(largeObject *self, PyObject *args)
1754{
1755    int         size;
1756    PyObject   *buffer;
1757
1758    /* gets arguments */
1759    if (!PyArg_ParseTuple(args, "i", &size))
1760    {
1761        PyErr_SetString(PyExc_TypeError,
1762            "Method read() takes an integer argument");
1763        return NULL;
1764    }
1765
1766    if (size <= 0)
1767    {
1768        PyErr_SetString(PyExc_ValueError,
1769            "Method read() takes a positive integer as argument");
1770        return NULL;
1771    }
1772
1773    /* checks validity */
1774    if (!check_lo_obj(self, CHECK_OPEN))
1775        return NULL;
1776
1777    /* allocate buffer and runs read */
1778    buffer = PyBytes_FromStringAndSize((char *) NULL, size);
1779
1780    if ((size = lo_read(self->pgcnx->cnx, self->lo_fd,
1781        PyBytes_AS_STRING((PyBytesObject *)(buffer)), size)) == -1)
1782    {
1783        PyErr_SetString(PyExc_IOError, "Error while reading");
1784        Py_XDECREF(buffer);
1785        return NULL;
1786    }
1787
1788    /* resize buffer and returns it */
1789    _PyBytes_Resize(&buffer, size);
1790    return buffer;
1791}
1792
1793/* write to large object */
1794static char largeWrite__doc__[] =
1795"write(string) -- write sized string to large object\n\n"
1796"Object must be opened in read mode before calling this method.\n";
1797
1798static PyObject *
1799largeWrite(largeObject *self, PyObject *args)
1800{
1801    char       *buffer;
1802    int         size,
1803                bufsize;
1804
1805    /* gets arguments */
1806    if (!PyArg_ParseTuple(args, "s#", &buffer, &bufsize))
1807    {
1808        PyErr_SetString(PyExc_TypeError,
1809            "Method write() expects a sized string as argument");
1810        return NULL;
1811    }
1812
1813    /* checks validity */
1814    if (!check_lo_obj(self, CHECK_OPEN))
1815        return NULL;
1816
1817    /* sends query */
1818    if ((size = lo_write(self->pgcnx->cnx, self->lo_fd, buffer,
1819                         bufsize)) != bufsize)
1820    {
1821        PyErr_SetString(PyExc_IOError, "Buffer truncated during write");
1822        return NULL;
1823    }
1824
1825    /* no error : returns Py_None */
1826    Py_INCREF(Py_None);
1827    return Py_None;
1828}
1829
1830/* go to position in large object */
1831static char largeSeek__doc__[] =
1832"seek(offset, whence) -- move to specified position\n\n"
1833"Object must be opened before calling this method. The whence option\n"
1834"can be SEEK_SET, SEEK_CUR or SEEK_END (module level constants).\n";
1835
1836static PyObject *
1837largeSeek(largeObject *self, PyObject *args)
1838{
1839    /* offset and whence are initialized to keep compiler happy */
1840    int         ret,
1841                offset = 0,
1842                whence = 0;
1843
1844    /* gets arguments */
1845    if (!PyArg_ParseTuple(args, "ii", &offset, &whence))
1846    {
1847        PyErr_SetString(PyExc_TypeError,
1848            "Method lseek() expects two integer arguments");
1849        return NULL;
1850    }
1851
1852    /* checks validity */
1853    if (!check_lo_obj(self, CHECK_OPEN))
1854        return NULL;
1855
1856    /* sends query */
1857    if ((ret = lo_lseek(self->pgcnx->cnx, self->lo_fd, offset, whence)) == -1)
1858    {
1859        PyErr_SetString(PyExc_IOError, "Error while moving cursor");
1860        return NULL;
1861    }
1862
1863    /* returns position */
1864    return PyInt_FromLong(ret);
1865}
1866
1867/* gets large object size */
1868static char largeSize__doc__[] =
1869"size() -- return large object size\n\n"
1870"The object must be opened before calling this method.\n";
1871
1872static PyObject *
1873largeSize(largeObject *self, PyObject *noargs)
1874{
1875    int         start,
1876                end;
1877
1878    /* checks validity */
1879    if (!check_lo_obj(self, CHECK_OPEN))
1880        return NULL;
1881
1882    /* gets current position */
1883    if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
1884    {
1885        PyErr_SetString(PyExc_IOError, "Error while getting current position");
1886        return NULL;
1887    }
1888
1889    /* gets end position */
1890    if ((end = lo_lseek(self->pgcnx->cnx, self->lo_fd, 0, SEEK_END)) == -1)
1891    {
1892        PyErr_SetString(PyExc_IOError, "Error while getting end position");
1893        return NULL;
1894    }
1895
1896    /* move back to start position */
1897    if ((start = lo_lseek(
1898        self->pgcnx->cnx, self->lo_fd, start, SEEK_SET)) == -1)
1899    {
1900        PyErr_SetString(PyExc_IOError,
1901            "Error while moving back to first position");
1902        return NULL;
1903    }
1904
1905    /* returns size */
1906    return PyInt_FromLong(end);
1907}
1908
1909/* gets large object cursor position */
1910static char largeTell__doc__[] =
1911"tell() -- give current position in large object\n\n"
1912"The object must be opened before calling this method.\n";
1913
1914static PyObject *
1915largeTell(largeObject *self, PyObject *noargs)
1916{
1917    int         start;
1918
1919    /* checks validity */
1920    if (!check_lo_obj(self, CHECK_OPEN))
1921        return NULL;
1922
1923    /* gets current position */
1924    if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
1925    {
1926        PyErr_SetString(PyExc_IOError, "Error while getting position");
1927        return NULL;
1928    }
1929
1930    /* returns size */
1931    return PyInt_FromLong(start);
1932}
1933
1934/* exports large object as unix file */
1935static char largeExport__doc__[] =
1936"export(filename) -- export large object data to specified file\n\n"
1937"The object must be closed when calling this method.\n";
1938
1939static PyObject *
1940largeExport(largeObject *self, PyObject *args)
1941{
1942    char *name;
1943
1944    /* checks validity */
1945    if (!check_lo_obj(self, CHECK_CLOSE))
1946        return NULL;
1947
1948    /* gets arguments */
1949    if (!PyArg_ParseTuple(args, "s", &name))
1950    {
1951        PyErr_SetString(PyExc_TypeError,
1952            "The method export() takes a filename as argument");
1953        return NULL;
1954    }
1955
1956    /* runs command */
1957    if (lo_export(self->pgcnx->cnx, self->lo_oid, name) != 1)
1958    {
1959        PyErr_SetString(PyExc_IOError, "Error while exporting large object");
1960        return NULL;
1961    }
1962
1963    Py_INCREF(Py_None);
1964    return Py_None;
1965}
1966
1967/* deletes a large object */
1968static char largeUnlink__doc__[] =
1969"unlink() -- destroy large object\n\n"
1970"The object must be closed when calling this method.\n";
1971
1972static PyObject *
1973largeUnlink(largeObject *self, PyObject *noargs)
1974{
1975    /* checks validity */
1976    if (!check_lo_obj(self, CHECK_CLOSE))
1977        return NULL;
1978
1979    /* deletes the object, invalidate it on success */
1980    if (lo_unlink(self->pgcnx->cnx, self->lo_oid) != 1)
1981    {
1982        PyErr_SetString(PyExc_IOError, "Error while unlinking large object");
1983        return NULL;
1984    }
1985    self->lo_oid = 0;
1986
1987    Py_INCREF(Py_None);
1988    return Py_None;
1989}
1990
1991/* get the list of large object attributes */
1992static PyObject *
1993largeDir(largeObject *self, PyObject *noargs)
1994{
1995    PyObject *attrs;
1996
1997    attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
1998    PyObject_CallMethod(attrs, "extend", "[sss]",
1999        "oid", "pgcnx", "error");
2000
2001    return attrs;
2002}
2003
2004/* large object methods */
2005static struct PyMethodDef largeMethods[] = {
2006    {"__dir__", (PyCFunction) largeDir,  METH_NOARGS, NULL},
2007    {"open", (PyCFunction) largeOpen, METH_VARARGS, largeOpen__doc__},
2008    {"close", (PyCFunction) largeClose, METH_NOARGS, largeClose__doc__},
2009    {"read", (PyCFunction) largeRead, METH_VARARGS, largeRead__doc__},
2010    {"write", (PyCFunction) largeWrite, METH_VARARGS, largeWrite__doc__},
2011    {"seek", (PyCFunction) largeSeek, METH_VARARGS, largeSeek__doc__},
2012    {"size", (PyCFunction) largeSize, METH_NOARGS, largeSize__doc__},
2013    {"tell", (PyCFunction) largeTell, METH_NOARGS, largeTell__doc__},
2014    {"export",(PyCFunction) largeExport, METH_VARARGS, largeExport__doc__},
2015    {"unlink",(PyCFunction) largeUnlink, METH_NOARGS, largeUnlink__doc__},
2016    {NULL, NULL}
2017};
2018
2019/* gets large object attributes */
2020static PyObject *
2021largeGetAttr(largeObject *self, PyObject *nameobj)
2022{
2023    const char *name = PyStr_AsString(nameobj);
2024
2025    /* list postgreSQL large object fields */
2026
2027    /* associated pg connection object */
2028    if (!strcmp(name, "pgcnx"))
2029    {
2030        if (check_lo_obj(self, 0))
2031        {
2032            Py_INCREF(self->pgcnx);
2033            return (PyObject *) (self->pgcnx);
2034        }
2035        PyErr_Clear();
2036        Py_INCREF(Py_None);
2037        return Py_None;
2038    }
2039
2040    /* large object oid */
2041    if (!strcmp(name, "oid"))
2042    {
2043        if (check_lo_obj(self, 0))
2044            return PyInt_FromLong(self->lo_oid);
2045        PyErr_Clear();
2046        Py_INCREF(Py_None);
2047        return Py_None;
2048    }
2049
2050    /* error (status) message */
2051    if (!strcmp(name, "error"))
2052        return PyStr_FromString(PQerrorMessage(self->pgcnx->cnx));
2053
2054    /* seeks name in methods (fallback) */
2055    return PyObject_GenericGetAttr((PyObject *) self, nameobj);
2056}
2057
2058/* return large object as string in human readable form */
2059static PyObject *
2060largeStr(largeObject *self)
2061{
2062    char        str[80];
2063    sprintf(str, self->lo_fd >= 0 ?
2064            "Opened large object, oid %ld" :
2065            "Closed large object, oid %ld", (long) self->lo_oid);
2066    return PyStr_FromString(str);
2067}
2068
2069static char large__doc__[] = "PostgreSQL large object";
2070
2071/* large object type definition */
2072static PyTypeObject largeType = {
2073    PyVarObject_HEAD_INIT(NULL, 0)
2074    "pg.LargeObject",               /* tp_name */
2075    sizeof(largeObject),            /* tp_basicsize */
2076    0,                              /* tp_itemsize */
2077
2078    /* methods */
2079    (destructor) largeDealloc,      /* tp_dealloc */
2080    0,                              /* tp_print */
2081    0,                              /* tp_getattr */
2082    0,                              /* tp_setattr */
2083    0,                              /* tp_compare */
2084    0,                              /* tp_repr */
2085    0,                              /* tp_as_number */
2086    0,                              /* tp_as_sequence */
2087    0,                              /* tp_as_mapping */
2088    0,                              /* tp_hash */
2089    0,                              /* tp_call */
2090    (reprfunc) largeStr,            /* tp_str */
2091    (getattrofunc) largeGetAttr,    /* tp_getattro */
2092    0,                              /* tp_setattro */
2093    0,                              /* tp_as_buffer */
2094    Py_TPFLAGS_DEFAULT,             /* tp_flags */
2095    large__doc__,                   /* tp_doc */
2096    0,                              /* tp_traverse */
2097    0,                              /* tp_clear */
2098    0,                              /* tp_richcompare */
2099    0,                              /* tp_weaklistoffset */
2100    0,                              /* tp_iter */
2101    0,                              /* tp_iternext */
2102    largeMethods,                   /* tp_methods */
2103};
2104#endif /* LARGE_OBJECTS */
2105
2106/* --------------------------------------------------------------------- */
2107/* connection object                                                     */
2108/* --------------------------------------------------------------------- */
2109static void
2110connDelete(connObject *self)
2111{
2112    if (self->cnx)
2113    {
2114        Py_BEGIN_ALLOW_THREADS
2115        PQfinish(self->cnx);
2116        Py_END_ALLOW_THREADS
2117    }
2118    Py_XDECREF(self->cast_hook);
2119    Py_XDECREF(self->notice_receiver);
2120    PyObject_Del(self);
2121}
2122
2123/* source creation */
2124static char connSource__doc__[] =
2125"source() -- create a new source object for this connection";
2126
2127static PyObject *
2128connSource(connObject *self, PyObject *noargs)
2129{
2130    sourceObject *source_obj;
2131
2132    /* checks validity */
2133    if (!check_cnx_obj(self))
2134        return NULL;
2135
2136    /* allocates new query object */
2137    if (!(source_obj = PyObject_NEW(sourceObject, &sourceType)))
2138        return NULL;
2139
2140    /* initializes internal parameters */
2141    Py_XINCREF(self);
2142    source_obj->pgcnx = self;
2143    source_obj->result = NULL;
2144    source_obj->valid = 1;
2145    source_obj->arraysize = PG_ARRAYSIZE;
2146
2147    return (PyObject *) source_obj;
2148}
2149
2150/* database query */
2151
2152/* base method for execution of both unprepared and prepared queries */
2153static PyObject *
2154_connQuery(connObject *self, PyObject *args, int prepared)
2155{
2156    PyObject    *query_str_obj;
2157    PyObject    *param_obj = NULL;
2158    char        *query;
2159    PGresult    *result;
2160    queryObject *query_obj;
2161    int         encoding,
2162                status,
2163                nparms = 0;
2164
2165    if (!self->cnx)
2166    {
2167        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2168        return NULL;
2169    }
2170
2171    /* get query args */
2172    if (!PyArg_ParseTuple(args, "O|O", &query_str_obj, &param_obj))
2173    {
2174        return NULL;
2175    }
2176
2177    encoding = PQclientEncoding(self->cnx);
2178
2179    if (PyBytes_Check(query_str_obj))
2180    {
2181        query = PyBytes_AsString(query_str_obj);
2182        query_str_obj = NULL;
2183    }
2184    else if (PyUnicode_Check(query_str_obj))
2185    {
2186        query_str_obj = get_encoded_string(query_str_obj, encoding);
2187        if (!query_str_obj) return NULL; /* pass the UnicodeEncodeError */
2188        query = PyBytes_AsString(query_str_obj);
2189    }
2190    else
2191    {
2192        PyErr_SetString(PyExc_TypeError,
2193            "Method query() expects a string as first argument");
2194        return NULL;
2195    }
2196
2197    /* If param_obj is passed, ensure it's a non-empty tuple. We want to treat
2198     * an empty tuple the same as no argument since we'll get that when the
2199     * caller passes no arguments to db.query(), and historic behaviour was
2200     * to call PQexec() in that case, which can execute multiple commands. */
2201    if (param_obj)
2202    {
2203        param_obj = PySequence_Fast(param_obj,
2204            "Method query() expects a sequence as second argument");
2205        if (!param_obj)
2206        {
2207            Py_XDECREF(query_str_obj);
2208            return NULL;
2209        }
2210        nparms = (int)PySequence_Fast_GET_SIZE(param_obj);
2211
2212        /* if there's a single argument and it's a list or tuple, it
2213         * contains the positional arguments. */
2214        if (nparms == 1)
2215        {
2216            PyObject *first_obj = PySequence_Fast_GET_ITEM(param_obj, 0);
2217            if (PyList_Check(first_obj) || PyTuple_Check(first_obj))
2218            {
2219                Py_DECREF(param_obj);
2220                param_obj = PySequence_Fast(first_obj, NULL);
2221                nparms = (int)PySequence_Fast_GET_SIZE(param_obj);
2222            }
2223        }
2224    }
2225
2226    /* gets result */
2227    if (nparms)
2228    {
2229        /* prepare arguments */
2230        PyObject    **str, **s;
2231        const char  **parms, **p;
2232        register int i;
2233
2234        str = (PyObject **)PyMem_Malloc(nparms * sizeof(*str));
2235        parms = (const char **)PyMem_Malloc(nparms * sizeof(*parms));
2236        if (!str || !parms)
2237        {
2238            PyMem_Free((void *)parms); PyMem_Free(str);
2239            Py_XDECREF(query_str_obj); Py_XDECREF(param_obj);
2240            return PyErr_NoMemory();
2241        }
2242
2243        /* convert optional args to a list of strings -- this allows
2244         * the caller to pass whatever they like, and prevents us
2245         * from having to map types to OIDs */
2246        for (i = 0, s=str, p=parms; i < nparms; ++i, ++p)
2247        {
2248            PyObject *obj = PySequence_Fast_GET_ITEM(param_obj, i);
2249
2250            if (obj == Py_None)
2251            {
2252                *p = NULL;
2253            }
2254            else if (PyBytes_Check(obj))
2255            {
2256                *p = PyBytes_AsString(obj);
2257            }
2258            else if (PyUnicode_Check(obj))
2259            {
2260                PyObject *str_obj = get_encoded_string(obj, encoding);
2261                if (!str_obj)
2262                {
2263                    PyMem_Free((void *)parms);
2264                    while (s != str) { s--; Py_DECREF(*s); }
2265                    PyMem_Free(str);
2266                    Py_XDECREF(query_str_obj);
2267                    Py_XDECREF(param_obj);
2268                    /* pass the UnicodeEncodeError */
2269                    return NULL;
2270                }
2271                *s++ = str_obj;
2272                *p = PyBytes_AsString(str_obj);
2273            }
2274            else
2275            {
2276                PyObject *str_obj = PyObject_Str(obj);
2277                if (!str_obj)
2278                {
2279                    PyMem_Free((void *)parms);
2280                    while (s != str) { s--; Py_DECREF(*s); }
2281                    PyMem_Free(str);
2282                    Py_XDECREF(query_str_obj);
2283                    Py_XDECREF(param_obj);
2284                    PyErr_SetString(PyExc_TypeError,
2285                        "Query parameter has no string representation");
2286                    return NULL;
2287                }
2288                *s++ = str_obj;
2289                *p = PyStr_AsString(str_obj);
2290            }
2291        }
2292
2293        Py_BEGIN_ALLOW_THREADS
2294        result = prepared ?
2295            PQexecPrepared(self->cnx, query, nparms,
2296                parms, NULL, NULL, 0) :
2297            PQexecParams(self->cnx, query, nparms,
2298                NULL, parms, NULL, NULL, 0);
2299        Py_END_ALLOW_THREADS
2300
2301        PyMem_Free((void *)parms);
2302        while (s != str) { s--; Py_DECREF(*s); }
2303        PyMem_Free(str);
2304    }
2305    else
2306    {
2307        Py_BEGIN_ALLOW_THREADS
2308        result = prepared ?
2309            PQexecPrepared(self->cnx, query, 0,
2310                NULL, NULL, NULL, 0) :
2311            PQexec(self->cnx, query);
2312        Py_END_ALLOW_THREADS
2313    }
2314
2315    /* we don't need the query and its params any more */
2316    Py_XDECREF(query_str_obj);
2317    Py_XDECREF(param_obj);
2318
2319    /* checks result validity */
2320    if (!result)
2321    {
2322        PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
2323        return NULL;
2324    }
2325
2326    /* this may have changed the datestyle, so we reset the date format
2327       in order to force fetching it newly when next time requested */
2328    self->date_format = date_format; /* this is normally NULL */
2329
2330    /* checks result status */
2331    if ((status = PQresultStatus(result)) != PGRES_TUPLES_OK)
2332    {
2333        switch (status)
2334        {
2335            case PGRES_EMPTY_QUERY:
2336                PyErr_SetString(PyExc_ValueError, "Empty query");
2337                break;
2338            case PGRES_BAD_RESPONSE:
2339            case PGRES_FATAL_ERROR:
2340            case PGRES_NONFATAL_ERROR:
2341                set_error(ProgrammingError, "Cannot execute query",
2342                    self->cnx, result);
2343                break;
2344            case PGRES_COMMAND_OK:
2345                {                       /* INSERT, UPDATE, DELETE */
2346                    Oid     oid = PQoidValue(result);
2347                    if (oid == InvalidOid)  /* not a single insert */
2348                    {
2349                        char    *ret = PQcmdTuples(result);
2350
2351                        if (ret[0])     /* return number of rows affected */
2352                        {
2353                            PyObject *obj = PyStr_FromString(ret);
2354                            PQclear(result);
2355                            return obj;
2356                        }
2357                        PQclear(result);
2358                        Py_INCREF(Py_None);
2359                        return Py_None;
2360                    }
2361                    /* for a single insert, return the oid */
2362                    PQclear(result);
2363                    return PyInt_FromLong(oid);
2364                }
2365            case PGRES_COPY_OUT:        /* no data will be received */
2366            case PGRES_COPY_IN:
2367                PQclear(result);
2368                Py_INCREF(Py_None);
2369                return Py_None;
2370            default:
2371                set_error_msg(InternalError, "Unknown result status");
2372        }
2373
2374        PQclear(result);
2375        return NULL;            /* error detected on query */
2376    }
2377
2378    if (!(query_obj = PyObject_NEW(queryObject, &queryType)))
2379        return PyErr_NoMemory();
2380
2381    /* stores result and returns object */
2382    Py_XINCREF(self);
2383    query_obj->pgcnx = self;
2384    query_obj->result = result;
2385    query_obj->encoding = encoding;
2386    query_obj->current_row = 0;
2387    query_obj->max_row = PQntuples(result);
2388    query_obj->num_fields = PQnfields(result);
2389    query_obj->col_types = get_col_types(result, query_obj->num_fields);
2390    if (!query_obj->col_types) {
2391        Py_DECREF(query_obj);
2392        Py_DECREF(self);
2393        return NULL;
2394    }
2395
2396    return (PyObject *) query_obj;
2397}
2398
2399/* database query */
2400static char connQuery__doc__[] =
2401"query(sql, [arg]) -- create a new query object for this connection\n\n"
2402"You must pass the SQL (string) request and you can optionally pass\n"
2403"a tuple with positional parameters.\n";
2404
2405static PyObject *
2406connQuery(connObject *self, PyObject *args)
2407{
2408    return _connQuery(self, args, 0);
2409}
2410
2411/* execute prepared statement */
2412static char connQueryPrepared__doc__[] =
2413"query_prepared(name, [arg]) -- execute a prepared statement\n\n"
2414"You must pass the name (string) of the prepared statement and you can\n"
2415"optionally pass a tuple with positional parameters.\n";
2416
2417static PyObject *
2418connQueryPrepared(connObject *self, PyObject *args)
2419{
2420    return _connQuery(self, args, 1);
2421}
2422
2423/* create prepared statement */
2424static char connPrepare__doc__[] =
2425"prepare(name, sql) -- create a prepared statement\n\n"
2426"You must pass the name (string) of the prepared statement and the\n"
2427"SQL (string) request for later execution.\n";
2428
2429static PyObject *
2430connPrepare(connObject *self, PyObject *args)
2431{
2432    char        *name, *query;
2433    int         name_length, query_length;
2434    PGresult    *result;
2435
2436    if (!self->cnx)
2437    {
2438        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2439        return NULL;
2440    }
2441
2442    /* reads args */
2443    if (!PyArg_ParseTuple(args, "s#s#",
2444        &name, &name_length, &query, &query_length))
2445    {
2446        PyErr_SetString(PyExc_TypeError,
2447            "Method prepare() takes two string arguments");
2448        return NULL;
2449    }
2450
2451    /* create prepared statement */
2452    Py_BEGIN_ALLOW_THREADS
2453    result = PQprepare(self->cnx, name, query, 0, NULL);
2454    Py_END_ALLOW_THREADS
2455    if (result && PQresultStatus(result) == PGRES_COMMAND_OK)
2456    {
2457        PQclear(result);
2458        Py_INCREF(Py_None);
2459        return Py_None; /* success */
2460    }
2461    set_error(ProgrammingError, "Cannot create prepared statement",
2462        self->cnx, result);
2463    if (result)
2464        PQclear(result);
2465    return NULL; /* error */
2466}
2467
2468/* describe prepared statement */
2469static char connDescribePrepared__doc__[] =
2470"describe_prepared(name) -- describe a prepared statement\n\n"
2471"You must pass the name (string) of the prepared statement.\n";
2472
2473static PyObject *
2474connDescribePrepared(connObject *self, PyObject *args)
2475{
2476    char        *name;
2477    int         name_length;
2478    PGresult    *result;
2479
2480    if (!self->cnx)
2481    {
2482        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2483        return NULL;
2484    }
2485
2486    /* reads args */
2487    if (!PyArg_ParseTuple(args, "s#",
2488        &name, &name_length))
2489    {
2490        PyErr_SetString(PyExc_TypeError,
2491            "Method prepare() takes a string argument");
2492        return NULL;
2493    }
2494
2495    /* describe prepared statement */
2496    Py_BEGIN_ALLOW_THREADS
2497    result = PQdescribePrepared(self->cnx, name);
2498    Py_END_ALLOW_THREADS
2499    if (result && PQresultStatus(result) == PGRES_COMMAND_OK)
2500    {
2501        queryObject *query_obj = PyObject_NEW(queryObject, &queryType);
2502        if (!query_obj)
2503            return PyErr_NoMemory();
2504        Py_XINCREF(self);
2505        query_obj->pgcnx = self;
2506        query_obj->result = result;
2507        query_obj->encoding = PQclientEncoding(self->cnx);
2508        query_obj->current_row = 0;
2509        query_obj->max_row = PQntuples(result);
2510        query_obj->num_fields = PQnfields(result);
2511        query_obj->col_types = get_col_types(result, query_obj->num_fields);
2512        return (PyObject *) query_obj;
2513    }
2514    set_error(ProgrammingError, "Cannot describe prepared statement",
2515        self->cnx, result);
2516    if (result)
2517        PQclear(result);
2518    return NULL; /* error */
2519}
2520
2521#ifdef DIRECT_ACCESS
2522static char connPutLine__doc__[] =
2523"putline(line) -- send a line directly to the backend";
2524
2525/* direct access function: putline */
2526static PyObject *
2527connPutLine(connObject *self, PyObject *args)
2528{
2529    char *line;
2530    int line_length;
2531
2532    if (!self->cnx)
2533    {
2534        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2535        return NULL;
2536    }
2537
2538    /* reads args */
2539    if (!PyArg_ParseTuple(args, "s#", &line, &line_length))
2540    {
2541        PyErr_SetString(PyExc_TypeError,
2542            "Method putline() takes a string argument");
2543        return NULL;
2544    }
2545
2546    /* sends line to backend */
2547    if (PQputline(self->cnx, line))
2548    {
2549        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2550        return NULL;
2551    }
2552    Py_INCREF(Py_None);
2553    return Py_None;
2554}
2555
2556/* direct access function: getline */
2557static char connGetLine__doc__[] =
2558"getline() -- get a line directly from the backend";
2559
2560static PyObject *
2561connGetLine(connObject *self, PyObject *noargs)
2562{
2563    char        line[MAX_BUFFER_SIZE];
2564    PyObject   *str = NULL;     /* GCC */
2565
2566    if (!self->cnx)
2567    {
2568        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2569        return NULL;
2570    }
2571
2572    /* gets line */
2573    switch (PQgetline(self->cnx, line, MAX_BUFFER_SIZE))
2574    {
2575        case 0:
2576            str = PyStr_FromString(line);
2577            break;
2578        case 1:
2579            PyErr_SetString(PyExc_MemoryError, "Buffer overflow");
2580            str = NULL;
2581            break;
2582        case EOF:
2583            Py_INCREF(Py_None);
2584            str = Py_None;
2585            break;
2586    }
2587
2588    return str;
2589}
2590
2591/* direct access function: end copy */
2592static char connEndCopy__doc__[] =
2593"endcopy() -- synchronize client and server";
2594
2595static PyObject *
2596connEndCopy(connObject *self, PyObject *noargs)
2597{
2598    if (!self->cnx)
2599    {
2600        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2601        return NULL;
2602    }
2603
2604    /* ends direct copy */
2605    if (PQendcopy(self->cnx))
2606    {
2607        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2608        return NULL;
2609    }
2610    Py_INCREF(Py_None);
2611    return Py_None;
2612}
2613#endif /* DIRECT_ACCESS */
2614
2615/* return query as string in human readable form */
2616static PyObject *
2617queryStr(queryObject *self)
2618{
2619    return format_result(self->result);
2620}
2621
2622/* insert table */
2623static char connInsertTable__doc__[] =
2624"inserttable(table, data) -- insert list into table\n\n"
2625"The fields in the list must be in the same order as in the table.\n";
2626
2627static PyObject *
2628connInsertTable(connObject *self, PyObject *args)
2629{
2630    PGresult    *result;
2631    char        *table,
2632                *buffer,
2633                *bufpt;
2634    int         encoding;
2635    size_t      bufsiz;
2636    PyObject    *list,
2637                *sublist,
2638                *item;
2639    PyObject    *(*getitem) (PyObject *, Py_ssize_t);
2640    PyObject    *(*getsubitem) (PyObject *, Py_ssize_t);
2641    Py_ssize_t  i,
2642                j,
2643                m,
2644                n;
2645
2646    if (!self->cnx)
2647    {
2648        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2649        return NULL;
2650    }
2651
2652    /* gets arguments */
2653    if (!PyArg_ParseTuple(args, "sO:filter", &table, &list))
2654    {
2655        PyErr_SetString(PyExc_TypeError,
2656            "Method inserttable() expects a string and a list as arguments");
2657        return NULL;
2658    }
2659
2660    /* checks list type */
2661    if (PyTuple_Check(list))
2662    {
2663        m = PyTuple_Size(list);
2664        getitem = PyTuple_GetItem;
2665    }
2666    else if (PyList_Check(list))
2667    {
2668        m = PyList_Size(list);
2669        getitem = PyList_GetItem;
2670    }
2671    else
2672    {
2673        PyErr_SetString(PyExc_TypeError,
2674            "Method inserttable() expects some kind of array"
2675            " as second argument");
2676        return NULL;
2677    }
2678
2679    /* allocate buffer */
2680    if (!(buffer = PyMem_Malloc(MAX_BUFFER_SIZE)))
2681        return PyErr_NoMemory();
2682
2683    /* starts query */
2684    sprintf(buffer, "copy %s from stdin", table);
2685
2686    Py_BEGIN_ALLOW_THREADS
2687    result = PQexec(self->cnx, buffer);
2688    Py_END_ALLOW_THREADS
2689
2690    if (!result)
2691    {
2692        PyMem_Free(buffer);
2693        PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
2694        return NULL;
2695    }
2696
2697    encoding = PQclientEncoding(self->cnx);
2698
2699    PQclear(result);
2700
2701    n = 0; /* not strictly necessary but avoids warning */
2702
2703    /* feed table */
2704    for (i = 0; i < m; ++i)
2705    {
2706        sublist = getitem(list, i);
2707        if (PyTuple_Check(sublist))
2708        {
2709            j = PyTuple_Size(sublist);
2710            getsubitem = PyTuple_GetItem;
2711        }
2712        else if (PyList_Check(sublist))
2713        {
2714            j = PyList_Size(sublist);
2715            getsubitem = PyList_GetItem;
2716        }
2717        else
2718        {
2719            PyErr_SetString(PyExc_TypeError,
2720                "Second arg must contain some kind of arrays");
2721            return NULL;
2722        }
2723        if (i)
2724        {
2725            if (j != n)
2726            {
2727                PyMem_Free(buffer);
2728                PyErr_SetString(PyExc_TypeError,
2729                    "Arrays contained in second arg must have same size");
2730                return NULL;
2731            }
2732        }
2733        else
2734        {
2735            n = j; /* never used before this assignment */
2736        }
2737
2738        /* builds insert line */
2739        bufpt = buffer;
2740        bufsiz = MAX_BUFFER_SIZE - 1;
2741
2742        for (j = 0; j < n; ++j)
2743        {
2744            if (j)
2745            {
2746                *bufpt++ = '\t'; --bufsiz;
2747            }
2748
2749            item = getsubitem(sublist, j);
2750
2751            /* convert item to string and append to buffer */
2752            if (item == Py_None)
2753            {
2754                if (bufsiz > 2)
2755                {
2756                    *bufpt++ = '\\'; *bufpt++ = 'N';
2757                    bufsiz -= 2;
2758                }
2759                else
2760                    bufsiz = 0;
2761            }
2762            else if (PyBytes_Check(item))
2763            {
2764                const char* t = PyBytes_AsString(item);
2765                while (*t && bufsiz)
2766                {
2767                    if (*t == '\\' || *t == '\t' || *t == '\n')
2768                    {
2769                        *bufpt++ = '\\'; --bufsiz;
2770                        if (!bufsiz) break;
2771                    }
2772                    *bufpt++ = *t++; --bufsiz;
2773                }
2774            }
2775            else if (PyUnicode_Check(item))
2776            {
2777                PyObject *s = get_encoded_string(item, encoding);
2778                if (!s)
2779                {
2780                    PyMem_Free(buffer);
2781                    return NULL; /* pass the UnicodeEncodeError */
2782                }
2783                else
2784                {
2785                    const char* t = PyBytes_AsString(s);
2786                    while (*t && bufsiz)
2787                    {
2788                        if (*t == '\\' || *t == '\t' || *t == '\n')
2789                        {
2790                            *bufpt++ = '\\'; --bufsiz;
2791                            if (!bufsiz) break;
2792                        }
2793                        *bufpt++ = *t++; --bufsiz;
2794                    }
2795                    Py_DECREF(s);
2796                }
2797            }
2798            else if (PyInt_Check(item) || PyLong_Check(item))
2799            {
2800                PyObject* s = PyObject_Str(item);
2801                const char* t = PyStr_AsString(s);
2802                while (*t && bufsiz)
2803                {
2804                    *bufpt++ = *t++; --bufsiz;
2805                }
2806                Py_DECREF(s);
2807            }
2808            else
2809            {
2810                PyObject* s = PyObject_Repr(item);
2811                const char* t = PyStr_AsString(s);
2812                while (*t && bufsiz)
2813                {
2814                    if (*t == '\\' || *t == '\t' || *t == '\n')
2815                    {
2816                        *bufpt++ = '\\'; --bufsiz;
2817                        if (!bufsiz) break;
2818                    }
2819                    *bufpt++ = *t++; --bufsiz;
2820                }
2821                Py_DECREF(s);
2822            }
2823
2824            if (bufsiz <= 0)
2825            {
2826                PyMem_Free(buffer); return PyErr_NoMemory();
2827            }
2828
2829        }
2830
2831        *bufpt++ = '\n'; *bufpt = '\0';
2832
2833        /* sends data */
2834        if (PQputline(self->cnx, buffer))
2835        {
2836            PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2837            PQendcopy(self->cnx);
2838            PyMem_Free(buffer);
2839            return NULL;
2840        }
2841    }
2842
2843    /* ends query */
2844    if (PQputline(self->cnx, "\\.\n"))
2845    {
2846        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2847        PQendcopy(self->cnx);
2848        PyMem_Free(buffer);
2849        return NULL;
2850    }
2851
2852    if (PQendcopy(self->cnx))
2853    {
2854        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
2855        PyMem_Free(buffer);
2856        return NULL;
2857    }
2858
2859    PyMem_Free(buffer);
2860
2861    /* no error : returns nothing */
2862    Py_INCREF(Py_None);
2863    return Py_None;
2864}
2865
2866/* get transaction state */
2867static char connTransaction__doc__[] =
2868"transaction() -- return the current transaction status";
2869
2870static PyObject *
2871connTransaction(connObject *self, PyObject *noargs)
2872{
2873    if (!self->cnx)
2874    {
2875        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2876        return NULL;
2877    }
2878
2879    return PyInt_FromLong(PQtransactionStatus(self->cnx));
2880}
2881
2882/* get parameter setting */
2883static char connParameter__doc__[] =
2884"parameter(name) -- look up a current parameter setting";
2885
2886static PyObject *
2887connParameter(connObject *self, PyObject *args)
2888{
2889    const char *name;
2890
2891    if (!self->cnx)
2892    {
2893        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2894        return NULL;
2895    }
2896
2897    /* get query args */
2898    if (!PyArg_ParseTuple(args, "s", &name))
2899    {
2900        PyErr_SetString(PyExc_TypeError,
2901            "Method parameter() takes a string as argument");
2902        return NULL;
2903    }
2904
2905    name = PQparameterStatus(self->cnx, name);
2906
2907    if (name)
2908        return PyStr_FromString(name);
2909
2910    /* unknown parameter, return None */
2911    Py_INCREF(Py_None);
2912    return Py_None;
2913}
2914
2915/* internal function converting a Postgres datestyles to date formats */
2916static const char *
2917date_style_to_format(const char *s)
2918{
2919    static const char *formats[] = {
2920        "%Y-%m-%d",     /* 0 = ISO */
2921        "%m-%d-%Y",     /* 1 = Postgres, MDY */
2922        "%d-%m-%Y",     /* 2 = Postgres, DMY */
2923        "%m/%d/%Y",     /* 3 = SQL, MDY */
2924        "%d/%m/%Y",     /* 4 = SQL, DMY */
2925        "%d.%m.%Y"};    /* 5 = German */
2926
2927    switch (s ? *s : 'I')
2928    {
2929        case 'P': /* Postgres */
2930            s = strchr(s + 1, ',');
2931            if (s) do ++s; while (*s && *s == ' ');
2932            return formats[s && *s == 'D' ? 2 : 1];
2933        case 'S': /* SQL */
2934            s = strchr(s + 1, ',');
2935            if (s) do ++s; while (*s && *s == ' ');
2936            return formats[s && *s == 'D' ? 4 : 3];
2937        case 'G': /* German */
2938            return formats[5];
2939        default: /* ISO */
2940            return formats[0]; /* ISO is the default */
2941    }
2942}
2943
2944/* internal function converting a date format to a Postgres datestyle */
2945static const char *
2946date_format_to_style(const char *s)
2947{
2948    static const char *datestyle[] = {
2949        "ISO, YMD",         /* 0 = %Y-%m-%d */
2950        "Postgres, MDY",    /* 1 = %m-%d-%Y */
2951        "Postgres, DMY",    /* 2 = %d-%m-%Y */
2952        "SQL, MDY",         /* 3 = %m/%d/%Y */
2953        "SQL, DMY",         /* 4 = %d/%m/%Y */
2954        "German, DMY"};     /* 5 = %d.%m.%Y */
2955
2956    switch (s ? s[1] : 'Y')
2957    {
2958        case 'm':
2959            switch (s[2])
2960            {
2961                case '/':
2962                    return datestyle[3]; /* SQL, MDY */
2963                default:
2964                    return datestyle[1]; /* Postgres, MDY */
2965            }
2966        case 'd':
2967            switch (s[2])
2968            {
2969                case '/':
2970                    return datestyle[4]; /* SQL, DMY */
2971                case '.':
2972                    return datestyle[5]; /* German */
2973                default:
2974                    return datestyle[2]; /* Postgres, DMY */
2975            }
2976        default:
2977            return datestyle[0]; /* ISO */
2978    }
2979}
2980
2981/* get current date format */
2982static char connDateFormat__doc__[] =
2983"date_format() -- return the current date format";
2984
2985static PyObject *
2986connDateFormat(connObject *self, PyObject *noargs)
2987{
2988    const char *fmt;
2989
2990    if (!self->cnx)
2991    {
2992        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
2993        return NULL;
2994    }
2995
2996    /* check if the date format is cached in the connection */
2997    fmt = self->date_format;
2998    if (!fmt)
2999    {
3000        fmt = date_style_to_format(PQparameterStatus(self->cnx, "DateStyle"));
3001        self->date_format = fmt; /* cache the result */
3002    }
3003
3004    return PyStr_FromString(fmt);
3005}
3006
3007#ifdef ESCAPING_FUNCS
3008
3009/* escape literal */
3010static char connEscapeLiteral__doc__[] =
3011"escape_literal(str) -- escape a literal constant for use within SQL";
3012
3013static PyObject *
3014connEscapeLiteral(connObject *self, PyObject *string)
3015{
3016    PyObject   *tmp_obj = NULL, /* auxiliary string object */
3017               *to_obj; /* string object to return */
3018    char       *from, /* our string argument as encoded string */
3019               *to; /* the result as encoded string */
3020    Py_ssize_t  from_length; /* length of string */
3021    size_t      to_length; /* length of result */
3022    int         encoding = -1; /* client encoding */
3023
3024    if (PyBytes_Check(string))
3025    {
3026        PyBytes_AsStringAndSize(string, &from, &from_length);
3027    }
3028    else if (PyUnicode_Check(string))
3029    {
3030        encoding = PQclientEncoding(self->cnx);
3031        tmp_obj = get_encoded_string(string, encoding);
3032        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3033        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
3034    }
3035    else
3036    {
3037        PyErr_SetString(PyExc_TypeError,
3038            "Method escape_literal() expects a string as argument");
3039        return NULL;
3040    }
3041
3042    to = PQescapeLiteral(self->cnx, from, (size_t)from_length);
3043    to_length = strlen(to);
3044
3045    Py_XDECREF(tmp_obj);
3046
3047    if (encoding == -1)
3048        to_obj = PyBytes_FromStringAndSize(to, to_length);
3049    else
3050        to_obj = get_decoded_string(to, to_length, encoding);
3051    if (to)
3052        PQfreemem(to);
3053    return to_obj;
3054}
3055
3056/* escape identifier */
3057static char connEscapeIdentifier__doc__[] =
3058"escape_identifier(str) -- escape an identifier for use within SQL";
3059
3060static PyObject *
3061connEscapeIdentifier(connObject *self, PyObject *string)
3062{
3063    PyObject   *tmp_obj = NULL, /* auxiliary string object */
3064               *to_obj; /* string object to return */
3065    char       *from, /* our string argument as encoded string */
3066               *to; /* the result as encoded string */
3067    Py_ssize_t  from_length; /* length of string */
3068    size_t      to_length; /* length of result */
3069    int         encoding = -1; /* client encoding */
3070
3071    if (PyBytes_Check(string))
3072    {
3073        PyBytes_AsStringAndSize(string, &from, &from_length);
3074    }
3075    else if (PyUnicode_Check(string))
3076    {
3077        encoding = PQclientEncoding(self->cnx);
3078        tmp_obj = get_encoded_string(string, encoding);
3079        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3080        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
3081    }
3082    else
3083    {
3084        PyErr_SetString(PyExc_TypeError,
3085            "Method escape_identifier() expects a string as argument");
3086        return NULL;
3087    }
3088
3089    to = PQescapeIdentifier(self->cnx, from, (size_t)from_length);
3090    to_length = strlen(to);
3091
3092    Py_XDECREF(tmp_obj);
3093
3094    if (encoding == -1)
3095        to_obj = PyBytes_FromStringAndSize(to, to_length);
3096    else
3097        to_obj = get_decoded_string(to, to_length, encoding);
3098    if (to)
3099        PQfreemem(to);
3100    return to_obj;
3101}
3102
3103#endif  /* ESCAPING_FUNCS */
3104
3105/* escape string */
3106static char connEscapeString__doc__[] =
3107"escape_string(str) -- escape a string for use within SQL";
3108
3109static PyObject *
3110connEscapeString(connObject *self, PyObject *string)
3111{
3112    PyObject   *tmp_obj = NULL, /* auxiliary string object */
3113               *to_obj; /* string object to return */
3114    char       *from, /* our string argument as encoded string */
3115               *to; /* the result as encoded string */
3116    Py_ssize_t  from_length; /* length of string */
3117    size_t      to_length; /* length of result */
3118    int         encoding = -1; /* client encoding */
3119
3120    if (PyBytes_Check(string))
3121    {
3122        PyBytes_AsStringAndSize(string, &from, &from_length);
3123    }
3124    else if (PyUnicode_Check(string))
3125    {
3126        encoding = PQclientEncoding(self->cnx);
3127        tmp_obj = get_encoded_string(string, encoding);
3128        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3129        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
3130    }
3131    else
3132    {
3133        PyErr_SetString(PyExc_TypeError,
3134            "Method escape_string() expects a string as argument");
3135        return NULL;
3136    }
3137
3138    to_length = 2*from_length + 1;
3139    if ((Py_ssize_t)to_length < from_length) /* overflow */
3140    {
3141        to_length = from_length;
3142        from_length = (from_length - 1)/2;
3143    }
3144    to = (char *)PyMem_Malloc(to_length);
3145    to_length = PQescapeStringConn(self->cnx,
3146        to, from, (size_t)from_length, NULL);
3147
3148    Py_XDECREF(tmp_obj);
3149
3150    if (encoding == -1)
3151        to_obj = PyBytes_FromStringAndSize(to, to_length);
3152    else
3153        to_obj = get_decoded_string(to, to_length, encoding);
3154    PyMem_Free(to);
3155    return to_obj;
3156}
3157
3158/* escape bytea */
3159static char connEscapeBytea__doc__[] =
3160"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
3161
3162static PyObject *
3163connEscapeBytea(connObject *self, PyObject *data)
3164{
3165    PyObject   *tmp_obj = NULL, /* auxiliary string object */
3166               *to_obj; /* string object to return */
3167    char       *from, /* our string argument as encoded string */
3168               *to; /* the result as encoded string */
3169    Py_ssize_t  from_length; /* length of string */
3170    size_t      to_length; /* length of result */
3171    int         encoding = -1; /* client encoding */
3172
3173    if (PyBytes_Check(data))
3174    {
3175        PyBytes_AsStringAndSize(data, &from, &from_length);
3176    }
3177    else if (PyUnicode_Check(data))
3178    {
3179        encoding = PQclientEncoding(self->cnx);
3180        tmp_obj = get_encoded_string(data, encoding);
3181        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3182        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
3183    }
3184    else
3185    {
3186        PyErr_SetString(PyExc_TypeError,
3187            "Method escape_bytea() expects a string as argument");
3188        return NULL;
3189    }
3190
3191    to = (char *)PQescapeByteaConn(self->cnx,
3192        (unsigned char *)from, (size_t)from_length, &to_length);
3193
3194    Py_XDECREF(tmp_obj);
3195
3196    if (encoding == -1)
3197        to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
3198    else
3199        to_obj = get_decoded_string(to, to_length - 1, encoding);
3200    if (to)
3201        PQfreemem(to);
3202    return to_obj;
3203}
3204
3205#ifdef LARGE_OBJECTS
3206/* creates large object */
3207static char connCreateLO__doc__[] =
3208"locreate(mode) -- create a new large object in the database";
3209
3210static PyObject *
3211connCreateLO(connObject *self, PyObject *args)
3212{
3213    int         mode;
3214    Oid         lo_oid;
3215
3216    /* checks validity */
3217    if (!check_cnx_obj(self))
3218        return NULL;
3219
3220    /* gets arguments */
3221    if (!PyArg_ParseTuple(args, "i", &mode))
3222    {
3223        PyErr_SetString(PyExc_TypeError,
3224            "Method locreate() takes an integer argument");
3225        return NULL;
3226    }
3227
3228    /* creates large object */
3229    lo_oid = lo_creat(self->cnx, mode);
3230    if (lo_oid == 0)
3231    {
3232        set_error_msg(OperationalError, "Can't create large object");
3233        return NULL;
3234    }
3235
3236    return (PyObject *) largeNew(self, lo_oid);
3237}
3238
3239/* init from already known oid */
3240static char connGetLO__doc__[] =
3241"getlo(oid) -- create a large object instance for the specified oid";
3242
3243static PyObject *
3244connGetLO(connObject *self, PyObject *args)
3245{
3246    int         oid;
3247    Oid         lo_oid;
3248
3249    /* checks validity */
3250    if (!check_cnx_obj(self))
3251        return NULL;
3252
3253    /* gets arguments */
3254    if (!PyArg_ParseTuple(args, "i", &oid))
3255    {
3256        PyErr_SetString(PyExc_TypeError,
3257            "Method getlo() takes an integer argument");
3258        return NULL;
3259    }
3260
3261    lo_oid = (Oid)oid;
3262    if (lo_oid == 0)
3263    {
3264        PyErr_SetString(PyExc_ValueError, "The object oid can't be null");
3265        return NULL;
3266    }
3267
3268    /* creates object */
3269    return (PyObject *) largeNew(self, lo_oid);
3270}
3271
3272/* import unix file */
3273static char connImportLO__doc__[] =
3274"loimport(name) -- create a new large object from specified file";
3275
3276static PyObject *
3277connImportLO(connObject *self, PyObject *args)
3278{
3279    char   *name;
3280    Oid     lo_oid;
3281
3282    /* checks validity */
3283    if (!check_cnx_obj(self))
3284        return NULL;
3285
3286    /* gets arguments */
3287    if (!PyArg_ParseTuple(args, "s", &name))
3288    {
3289        PyErr_SetString(PyExc_TypeError,
3290            "Method loimport() takes a string argument");
3291        return NULL;
3292    }
3293
3294    /* imports file and checks result */
3295    lo_oid = lo_import(self->cnx, name);
3296    if (lo_oid == 0)
3297    {
3298        set_error_msg(OperationalError, "Can't create large object");
3299        return NULL;
3300    }
3301
3302    return (PyObject *) largeNew(self, lo_oid);
3303}
3304#endif /* LARGE_OBJECTS */
3305
3306/* resets connection */
3307static char connReset__doc__[] =
3308"reset() -- reset connection with current parameters\n\n"
3309"All derived queries and large objects derived from this connection\n"
3310"will not be usable after this call.\n";
3311
3312static PyObject *
3313connReset(connObject *self, PyObject *noargs)
3314{
3315    if (!self->cnx)
3316    {
3317        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3318        return NULL;
3319    }
3320
3321    /* resets the connection */
3322    PQreset(self->cnx);
3323    Py_INCREF(Py_None);
3324    return Py_None;
3325}
3326
3327/* cancels current command */
3328static char connCancel__doc__[] =
3329"cancel() -- abandon processing of the current command";
3330
3331static PyObject *
3332connCancel(connObject *self, PyObject *noargs)
3333{
3334    if (!self->cnx)
3335    {
3336        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3337        return NULL;
3338    }
3339
3340    /* request that the server abandon processing of the current command */
3341    return PyInt_FromLong((long) PQrequestCancel(self->cnx));
3342}
3343
3344/* get connection socket */
3345static char connFileno__doc__[] =
3346"fileno() -- return database connection socket file handle";
3347
3348static PyObject *
3349connFileno(connObject *self, PyObject *noargs)
3350{
3351    if (!self->cnx)
3352    {
3353        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3354        return NULL;
3355    }
3356
3357#ifdef NO_PQSOCKET
3358    return PyInt_FromLong((long) self->cnx->sock);
3359#else
3360    return PyInt_FromLong((long) PQsocket(self->cnx));
3361#endif
3362}
3363
3364/* set external typecast callback function */
3365static char connSetCastHook__doc__[] =
3366"set_cast_hook(func) -- set a fallback typecast function";
3367
3368static PyObject *
3369connSetCastHook(connObject *self, PyObject *func)
3370{
3371    PyObject *ret = NULL;
3372
3373    if (func == Py_None)
3374    {
3375        Py_XDECREF(self->cast_hook);
3376        self->cast_hook = NULL;
3377        Py_INCREF(Py_None); ret = Py_None;
3378    }
3379    else if (PyCallable_Check(func))
3380    {
3381        Py_XINCREF(func); Py_XDECREF(self->cast_hook);
3382        self->cast_hook = func;
3383        Py_INCREF(Py_None); ret = Py_None;
3384    }
3385    else
3386        PyErr_SetString(PyExc_TypeError,
3387            "Method set_cast_hook() expects"
3388             " a callable or None as argument");
3389
3390    return ret;
3391}
3392
3393/* get notice receiver callback function */
3394static char connGetCastHook__doc__[] =
3395"get_cast_hook() -- get the fallback typecast function";
3396
3397static PyObject *
3398connGetCastHook(connObject *self, PyObject *noargs)
3399{
3400    PyObject *ret = self->cast_hook;;
3401
3402    if (!ret)
3403        ret = Py_None;
3404    Py_INCREF(ret);
3405
3406    return ret;
3407}
3408
3409/* set notice receiver callback function */
3410static char connSetNoticeReceiver__doc__[] =
3411"set_notice_receiver(func) -- set the current notice receiver";
3412
3413static PyObject *
3414connSetNoticeReceiver(connObject *self, PyObject *func)
3415{
3416    PyObject *ret = NULL;
3417
3418    if (func == Py_None)
3419    {
3420        Py_XDECREF(self->notice_receiver);
3421        self->notice_receiver = NULL;
3422        Py_INCREF(Py_None); ret = Py_None;
3423    }
3424    else if (PyCallable_Check(func))
3425    {
3426        Py_XINCREF(func); Py_XDECREF(self->notice_receiver);
3427        self->notice_receiver = func;
3428        PQsetNoticeReceiver(self->cnx, notice_receiver, self);
3429        Py_INCREF(Py_None); ret = Py_None;
3430    }
3431    else
3432        PyErr_SetString(PyExc_TypeError,
3433            "Method set_notice_receiver() expects"
3434             " a callable or None as argument");
3435
3436    return ret;
3437}
3438
3439/* get notice receiver callback function */
3440static char connGetNoticeReceiver__doc__[] =
3441"get_notice_receiver() -- get the current notice receiver";
3442
3443static PyObject *
3444connGetNoticeReceiver(connObject *self, PyObject *noargs)
3445{
3446    PyObject *ret = self->notice_receiver;
3447
3448    if (!ret)
3449        ret = Py_None;
3450    Py_INCREF(ret);
3451
3452    return ret;
3453}
3454
3455/* close without deleting */
3456static char connClose__doc__[] =
3457"close() -- close connection\n\n"
3458"All instances of the connection object and derived objects\n"
3459"(queries and large objects) can no longer be used after this call.\n";
3460
3461static PyObject *
3462connClose(connObject *self, PyObject *noargs)
3463{
3464    /* connection object cannot already be closed */
3465    if (!self->cnx)
3466    {
3467        set_error_msg(InternalError, "Connection already closed");
3468        return NULL;
3469    }
3470
3471    Py_BEGIN_ALLOW_THREADS
3472    PQfinish(self->cnx);
3473    Py_END_ALLOW_THREADS
3474
3475    self->cnx = NULL;
3476    Py_INCREF(Py_None);
3477    return Py_None;
3478}
3479
3480/* gets asynchronous notify */
3481static char connGetNotify__doc__[] =
3482"getnotify() -- get database notify for this connection";
3483
3484static PyObject *
3485connGetNotify(connObject *self, PyObject *noargs)
3486{
3487    PGnotify   *notify;
3488
3489    if (!self->cnx)
3490    {
3491        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3492        return NULL;
3493    }
3494
3495    /* checks for NOTIFY messages */
3496    PQconsumeInput(self->cnx);
3497
3498    if (!(notify = PQnotifies(self->cnx)))
3499    {
3500        Py_INCREF(Py_None);
3501        return Py_None;
3502    }
3503    else
3504    {
3505        PyObject   *notify_result,
3506                   *temp;
3507
3508        if (!(temp = PyStr_FromString(notify->relname)))
3509            return NULL;
3510
3511        if (!(notify_result = PyTuple_New(3)))
3512            return NULL;
3513
3514        PyTuple_SET_ITEM(notify_result, 0, temp);
3515
3516        if (!(temp = PyInt_FromLong(notify->be_pid)))
3517        {
3518            Py_DECREF(notify_result);
3519            return NULL;
3520        }
3521
3522        PyTuple_SET_ITEM(notify_result, 1, temp);
3523
3524        /* extra exists even in old versions that did not support it */
3525        if (!(temp = PyStr_FromString(notify->extra)))
3526        {
3527            Py_DECREF(notify_result);
3528            return NULL;
3529        }
3530
3531        PyTuple_SET_ITEM(notify_result, 2, temp);
3532
3533        PQfreemem(notify);
3534
3535        return notify_result;
3536    }
3537}
3538
3539/* get the list of connection attributes */
3540static PyObject *
3541connDir(connObject *self, PyObject *noargs)
3542{
3543    PyObject *attrs;
3544
3545    attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
3546    PyObject_CallMethod(attrs, "extend", "[sssssssss]",
3547        "host", "port", "db", "options", "error", "status", "user",
3548        "protocol_version", "server_version");
3549
3550    return attrs;
3551}
3552
3553/* connection object methods */
3554static struct PyMethodDef connMethods[] = {
3555    {"__dir__", (PyCFunction) connDir,  METH_NOARGS, NULL},
3556
3557    {"source", (PyCFunction) connSource, METH_NOARGS, connSource__doc__},
3558    {"query", (PyCFunction) connQuery, METH_VARARGS, connQuery__doc__},
3559    {"query_prepared", (PyCFunction) connQueryPrepared, METH_VARARGS,
3560            connQueryPrepared__doc__},
3561    {"prepare", (PyCFunction) connPrepare, METH_VARARGS, connPrepare__doc__},
3562    {"describe_prepared", (PyCFunction) connDescribePrepared, METH_VARARGS,
3563            connDescribePrepared__doc__},
3564    {"reset", (PyCFunction) connReset, METH_NOARGS, connReset__doc__},
3565    {"cancel", (PyCFunction) connCancel, METH_NOARGS, connCancel__doc__},
3566    {"close", (PyCFunction) connClose, METH_NOARGS, connClose__doc__},
3567    {"fileno", (PyCFunction) connFileno, METH_NOARGS, connFileno__doc__},
3568    {"get_cast_hook", (PyCFunction) connGetCastHook, METH_NOARGS,
3569            connGetCastHook__doc__},
3570    {"set_cast_hook", (PyCFunction) connSetCastHook, METH_O,
3571            connSetCastHook__doc__},
3572    {"get_notice_receiver", (PyCFunction) connGetNoticeReceiver, METH_NOARGS,
3573            connGetNoticeReceiver__doc__},
3574    {"set_notice_receiver", (PyCFunction) connSetNoticeReceiver, METH_O,
3575            connSetNoticeReceiver__doc__},
3576    {"getnotify", (PyCFunction) connGetNotify, METH_NOARGS,
3577            connGetNotify__doc__},
3578    {"inserttable", (PyCFunction) connInsertTable, METH_VARARGS,
3579            connInsertTable__doc__},
3580    {"transaction", (PyCFunction) connTransaction, METH_NOARGS,
3581            connTransaction__doc__},
3582    {"parameter", (PyCFunction) connParameter, METH_VARARGS,
3583            connParameter__doc__},
3584    {"date_format", (PyCFunction) connDateFormat, METH_NOARGS,
3585            connDateFormat__doc__},
3586
3587#ifdef ESCAPING_FUNCS
3588    {"escape_literal", (PyCFunction) connEscapeLiteral, METH_O,
3589            connEscapeLiteral__doc__},
3590    {"escape_identifier", (PyCFunction) connEscapeIdentifier, METH_O,
3591            connEscapeIdentifier__doc__},
3592#endif  /* ESCAPING_FUNCS */
3593    {"escape_string", (PyCFunction) connEscapeString, METH_O,
3594            connEscapeString__doc__},
3595    {"escape_bytea", (PyCFunction) connEscapeBytea, METH_O,
3596            connEscapeBytea__doc__},
3597
3598#ifdef DIRECT_ACCESS
3599    {"putline", (PyCFunction) connPutLine, METH_VARARGS, connPutLine__doc__},
3600    {"getline", (PyCFunction) connGetLine, METH_NOARGS, connGetLine__doc__},
3601    {"endcopy", (PyCFunction) connEndCopy, METH_NOARGS, connEndCopy__doc__},
3602#endif /* DIRECT_ACCESS */
3603
3604#ifdef LARGE_OBJECTS
3605    {"locreate", (PyCFunction) connCreateLO, METH_VARARGS, connCreateLO__doc__},
3606    {"getlo", (PyCFunction) connGetLO, METH_VARARGS, connGetLO__doc__},
3607    {"loimport", (PyCFunction) connImportLO, METH_VARARGS, connImportLO__doc__},
3608#endif /* LARGE_OBJECTS */
3609
3610    {NULL, NULL} /* sentinel */
3611};
3612
3613/* gets connection attributes */
3614static PyObject *
3615connGetAttr(connObject *self, PyObject *nameobj)
3616{
3617    const char *name = PyStr_AsString(nameobj);
3618
3619    /*
3620     * Although we could check individually, there are only a few
3621     * attributes that don't require a live connection and unless someone
3622     * has an urgent need, this will have to do
3623     */
3624
3625    /* first exception - close which returns a different error */
3626    if (strcmp(name, "close") && !self->cnx)
3627    {
3628        PyErr_SetString(PyExc_TypeError, "Connection is not valid");
3629        return NULL;
3630    }
3631
3632    /* list PostgreSQL connection fields */
3633
3634    /* postmaster host */
3635    if (!strcmp(name, "host"))
3636    {
3637        char *r = PQhost(self->cnx);
3638        if (!r || r[0] == '/') /* Pg >= 9.6 can return a Unix socket path */
3639            r = "localhost";
3640        return PyStr_FromString(r);
3641    }
3642
3643    /* postmaster port */
3644    if (!strcmp(name, "port"))
3645        return PyInt_FromLong(atol(PQport(self->cnx)));
3646
3647    /* selected database */
3648    if (!strcmp(name, "db"))
3649        return PyStr_FromString(PQdb(self->cnx));
3650
3651    /* selected options */
3652    if (!strcmp(name, "options"))
3653        return PyStr_FromString(PQoptions(self->cnx));
3654
3655    /* error (status) message */
3656    if (!strcmp(name, "error"))
3657        return PyStr_FromString(PQerrorMessage(self->cnx));
3658
3659    /* connection status : 1 - OK, 0 - BAD */
3660    if (!strcmp(name, "status"))
3661        return PyInt_FromLong(PQstatus(self->cnx) == CONNECTION_OK ? 1 : 0);
3662
3663    /* provided user name */
3664    if (!strcmp(name, "user"))
3665        return PyStr_FromString(PQuser(self->cnx));
3666
3667    /* protocol version */
3668    if (!strcmp(name, "protocol_version"))
3669        return PyInt_FromLong(PQprotocolVersion(self->cnx));
3670
3671    /* backend version */
3672    if (!strcmp(name, "server_version"))
3673        return PyInt_FromLong(PQserverVersion(self->cnx));
3674
3675    return PyObject_GenericGetAttr((PyObject *) self, nameobj);
3676}
3677
3678/* connection type definition */
3679static PyTypeObject connType = {
3680    PyVarObject_HEAD_INIT(NULL, 0)
3681    "pg.Connection",            /* tp_name */
3682    sizeof(connObject),         /* tp_basicsize */
3683    0,                          /* tp_itemsize */
3684    (destructor) connDelete,    /* tp_dealloc */
3685    0,                          /* tp_print */
3686    0,                          /* tp_getattr */
3687    0,                          /* tp_setattr */
3688    0,                          /* tp_reserved */
3689    0,                          /* tp_repr */
3690    0,                          /* tp_as_number */
3691    0,                          /* tp_as_sequence */
3692    0,                          /* tp_as_mapping */
3693    0,                          /* tp_hash */
3694    0,                          /* tp_call */
3695    0,                          /* tp_str */
3696    (getattrofunc) connGetAttr, /* tp_getattro */
3697    0,                          /* tp_setattro */
3698    0,                          /* tp_as_buffer */
3699    Py_TPFLAGS_DEFAULT,         /* tp_flags */
3700    0,                          /* tp_doc */
3701    0,                          /* tp_traverse */
3702    0,                          /* tp_clear */
3703    0,                          /* tp_richcompare */
3704    0,                          /* tp_weaklistoffset */
3705    0,                          /* tp_iter */
3706    0,                          /* tp_iternext */
3707    connMethods,                /* tp_methods */
3708};
3709
3710/* --------------------------------------------------------------------- */
3711/* source object                                                         */
3712/* --------------------------------------------------------------------- */
3713/* checks source object validity */
3714static int
3715check_source_obj(sourceObject *self, int level)
3716{
3717    if (!self->valid)
3718    {
3719        set_error_msg(OperationalError, "Object has been closed");
3720        return 0;
3721    }
3722
3723    if ((level & CHECK_RESULT) && !self->result)
3724    {
3725        set_error_msg(DatabaseError, "No result");
3726        return 0;
3727    }
3728
3729    if ((level & CHECK_DQL) && self->result_type != RESULT_DQL)
3730    {
3731        set_error_msg(DatabaseError, "Last query did not return tuples");
3732        return 0;
3733    }
3734
3735    if ((level & CHECK_CNX) && !check_cnx_obj(self->pgcnx))
3736        return 0;
3737
3738    return 1;
3739}
3740
3741/* destructor */
3742static void
3743sourceDealloc(sourceObject *self)
3744{
3745    if (self->result)
3746        PQclear(self->result);
3747
3748    Py_XDECREF(self->pgcnx);
3749    PyObject_Del(self);
3750}
3751
3752/* closes object */
3753static char sourceClose__doc__[] =
3754"close() -- close query object without deleting it\n\n"
3755"All instances of the query object can no longer be used after this call.\n";
3756
3757static PyObject *
3758sourceClose(sourceObject *self, PyObject *noargs)
3759{
3760    /* frees result if necessary and invalidates object */
3761    if (self->result)
3762    {
3763        PQclear(self->result);
3764        self->result_type = RESULT_EMPTY;
3765        self->result = NULL;
3766    }
3767
3768    self->valid = 0;
3769
3770    /* return None */
3771    Py_INCREF(Py_None);
3772    return Py_None;
3773}
3774
3775/* database query */
3776static char sourceExecute__doc__[] =
3777"execute(sql) -- execute a SQL statement (string)\n\n"
3778"On success, this call returns the number of affected rows, or None\n"
3779"for DQL (SELECT, ...) statements.  The fetch (fetch(), fetchone()\n"
3780"and fetchall()) methods can be used to get result rows.\n";
3781
3782static PyObject *
3783sourceExecute(sourceObject *self, PyObject *sql)
3784{
3785    PyObject   *tmp_obj = NULL; /* auxiliary string object */
3786    char       *query;
3787    int         encoding;
3788
3789    /* checks validity */
3790    if (!check_source_obj(self, CHECK_CNX))
3791        return NULL;
3792
3793    encoding = PQclientEncoding(self->pgcnx->cnx);
3794
3795    if (PyBytes_Check(sql))
3796    {
3797        query = PyBytes_AsString(sql);
3798    }
3799    else if (PyUnicode_Check(sql))
3800    {
3801        tmp_obj = get_encoded_string(sql, encoding);
3802        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
3803        query = PyBytes_AsString(tmp_obj);
3804    }
3805    else
3806    {
3807        PyErr_SetString(PyExc_TypeError,
3808            "Method execute() expects a string as argument");
3809        return NULL;
3810    }
3811
3812    /* frees previous result */
3813    if (self->result)
3814    {
3815        PQclear(self->result);
3816        self->result = NULL;
3817    }
3818    self->max_row = 0;
3819    self->current_row = 0;
3820    self->num_fields = 0;
3821    self->encoding = encoding;
3822
3823    /* gets result */
3824    Py_BEGIN_ALLOW_THREADS
3825    self->result = PQexec(self->pgcnx->cnx, query);
3826    Py_END_ALLOW_THREADS
3827
3828    /* we don't need the auxiliary string any more */
3829    Py_XDECREF(tmp_obj);
3830
3831    /* checks result validity */
3832    if (!self->result)
3833    {
3834        PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->pgcnx->cnx));
3835        return NULL;
3836    }
3837
3838    /* this may have changed the datestyle, so we reset the date format
3839       in order to force fetching it newly when next time requested */
3840    self->pgcnx->date_format = date_format; /* this is normally NULL */
3841
3842    /* checks result status */
3843    switch (PQresultStatus(self->result))
3844    {
3845        /* query succeeded */
3846        case PGRES_TUPLES_OK:   /* DQL: returns None (DB-SIG compliant) */
3847            self->result_type = RESULT_DQL;
3848            self->max_row = PQntuples(self->result);
3849            self->num_fields = PQnfields(self->result);
3850            Py_INCREF(Py_None);
3851            return Py_None;
3852        case PGRES_COMMAND_OK:  /* other requests */
3853        case PGRES_COPY_OUT:
3854        case PGRES_COPY_IN:
3855            {
3856                long    num_rows;
3857                char   *temp;
3858                temp = PQcmdTuples(self->result);
3859                if (temp[0])
3860                {
3861                    self->result_type = RESULT_DML;
3862                    num_rows = atol(temp);
3863                }
3864                else
3865                {
3866                    self->result_type = RESULT_DDL;
3867                    num_rows = -1;
3868                }
3869                return PyInt_FromLong(num_rows);
3870            }
3871
3872        /* query failed */
3873        case PGRES_EMPTY_QUERY:
3874            PyErr_SetString(PyExc_ValueError, "Empty query");
3875            break;
3876        case PGRES_BAD_RESPONSE:
3877        case PGRES_FATAL_ERROR:
3878        case PGRES_NONFATAL_ERROR:
3879            set_error(ProgrammingError, "Cannot execute command",
3880                self->pgcnx->cnx, self->result);
3881            break;
3882        default:
3883            set_error_msg(InternalError, "Internal error: "
3884                "unknown result status");
3885    }
3886
3887    /* frees result and returns error */
3888    PQclear(self->result);
3889    self->result = NULL;
3890    self->result_type = RESULT_EMPTY;
3891    return NULL;
3892}
3893
3894/* gets oid status for last query (valid for INSERTs, 0 for other) */
3895static char sourceStatusOID__doc__[] =
3896"oidstatus() -- return oid of last inserted row (if available)";
3897
3898static PyObject *
3899sourceStatusOID(sourceObject *self, PyObject *noargs)
3900{
3901    Oid         oid;
3902
3903    /* checks validity */
3904    if (!check_source_obj(self, CHECK_RESULT))
3905        return NULL;
3906
3907    /* retrieves oid status */
3908    if ((oid = PQoidValue(self->result)) == InvalidOid)
3909    {
3910        Py_INCREF(Py_None);
3911        return Py_None;
3912    }
3913
3914    return PyInt_FromLong(oid);
3915}
3916
3917/* fetches rows from last result */
3918static char sourceFetch__doc__[] =
3919"fetch(num) -- return the next num rows from the last result in a list\n\n"
3920"If num parameter is omitted arraysize attribute value is used.\n"
3921"If size equals -1, all rows are fetched.\n";
3922
3923static PyObject *
3924sourceFetch(sourceObject *self, PyObject *args)
3925{
3926    PyObject   *reslist;
3927    int         i,
3928                k;
3929    long        size;
3930#if IS_PY3
3931    int         encoding;
3932#endif
3933
3934    /* checks validity */
3935    if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL | CHECK_CNX))
3936        return NULL;
3937
3938    /* checks args */
3939    size = self->arraysize;
3940    if (!PyArg_ParseTuple(args, "|l", &size))
3941    {
3942        PyErr_SetString(PyExc_TypeError,
3943            "fetch(num), with num (integer, optional)");
3944        return NULL;
3945    }
3946
3947    /* seeks last line */
3948    /* limit size to be within the amount of data we actually have */
3949    if (size == -1 || (self->max_row - self->current_row) < size)
3950        size = self->max_row - self->current_row;
3951
3952    /* allocate list for result */
3953    if (!(reslist = PyList_New(0))) return NULL;
3954
3955#if IS_PY3
3956    encoding = self->encoding;
3957#endif
3958
3959    /* builds result */
3960    for (i = 0, k = self->current_row; i < size; ++i, ++k)
3961    {
3962        PyObject   *rowtuple;
3963        int         j;
3964
3965        if (!(rowtuple = PyTuple_New(self->num_fields)))
3966        {
3967            Py_DECREF(reslist); return NULL;
3968        }
3969
3970        for (j = 0; j < self->num_fields; ++j)
3971        {
3972            PyObject   *str;
3973
3974            if (PQgetisnull(self->result, k, j))
3975            {
3976                Py_INCREF(Py_None);
3977                str = Py_None;
3978            }
3979            else
3980            {
3981                char *s = PQgetvalue(self->result, k, j);
3982                Py_ssize_t size = PQgetlength(self->result, k, j);
3983#if IS_PY3
3984                if (PQfformat(self->result, j) == 0) /* textual format */
3985                {
3986                    str = get_decoded_string(s, size, encoding);
3987                    if (!str) /* cannot decode */
3988                        str = PyBytes_FromStringAndSize(s, size);
3989                }
3990                else
3991#endif
3992                str = PyBytes_FromStringAndSize(s, size);
3993            }
3994            PyTuple_SET_ITEM(rowtuple, j, str);
3995        }
3996
3997        if (PyList_Append(reslist, rowtuple))
3998        {
3999            Py_DECREF(rowtuple); Py_DECREF(reslist); return NULL;
4000        }
4001        Py_DECREF(rowtuple);
4002    }
4003
4004    self->current_row = k;
4005    return reslist;
4006}
4007
4008/* changes current row (internal wrapper for all "move" methods) */
4009static PyObject *
4010pgsource_move(sourceObject *self, int move)
4011{
4012    /* checks validity */
4013    if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
4014        return NULL;
4015
4016    /* changes the current row */
4017    switch (move)
4018    {
4019        case QUERY_MOVEFIRST:
4020            self->current_row = 0;
4021            break;
4022        case QUERY_MOVELAST:
4023            self->current_row = self->max_row - 1;
4024            break;
4025        case QUERY_MOVENEXT:
4026            if (self->current_row != self->max_row)
4027                ++self->current_row;
4028            break;
4029        case QUERY_MOVEPREV:
4030            if (self->current_row > 0)
4031                self->current_row--;
4032            break;
4033    }
4034
4035    Py_INCREF(Py_None);
4036    return Py_None;
4037}
4038
4039/* move to first result row */
4040static char sourceMoveFirst__doc__[] =
4041"movefirst() -- move to first result row";
4042
4043static PyObject *
4044sourceMoveFirst(sourceObject *self, PyObject *noargs)
4045{
4046    return pgsource_move(self, QUERY_MOVEFIRST);
4047}
4048
4049/* move to last result row */
4050static char sourceMoveLast__doc__[] =
4051"movelast() -- move to last valid result row";
4052
4053static PyObject *
4054sourceMoveLast(sourceObject *self, PyObject *noargs)
4055{
4056    return pgsource_move(self, QUERY_MOVELAST);
4057}
4058
4059/* move to next result row */
4060static char sourceMoveNext__doc__[] =
4061"movenext() -- move to next result row";
4062
4063static PyObject *
4064sourceMoveNext(sourceObject *self, PyObject *noargs)
4065{
4066    return pgsource_move(self, QUERY_MOVENEXT);
4067}
4068
4069/* move to previous result row */
4070static char sourceMovePrev__doc__[] =
4071"moveprev() -- move to previous result row";
4072
4073static PyObject *
4074sourceMovePrev(sourceObject *self, PyObject *noargs)
4075{
4076    return pgsource_move(self, QUERY_MOVEPREV);
4077}
4078
4079/* put copy data */
4080static char sourcePutData__doc__[] =
4081"putdata(buffer) -- send data to server during copy from stdin";
4082
4083static PyObject *
4084sourcePutData(sourceObject *self, PyObject *buffer)
4085{
4086    PyObject   *tmp_obj = NULL; /* an auxiliary object */
4087    char       *buf; /* the buffer as encoded string */
4088    Py_ssize_t  nbytes; /* length of string */
4089    char       *errormsg = NULL; /* error message */
4090    int         res; /* direct result of the operation */
4091    PyObject   *ret; /* return value */
4092
4093    /* checks validity */
4094    if (!check_source_obj(self, CHECK_CNX))
4095        return NULL;
4096
4097    /* make sure that the connection object is valid */
4098    if (!self->pgcnx->cnx)
4099        return NULL;
4100
4101    if (buffer == Py_None)
4102    {
4103        /* pass None for terminating the operation */
4104        buf = errormsg = NULL;
4105    }
4106    else if (PyBytes_Check(buffer))
4107    {
4108        /* or pass a byte string */
4109        PyBytes_AsStringAndSize(buffer, &buf, &nbytes);
4110    }
4111    else if (PyUnicode_Check(buffer))
4112    {
4113        /* or pass a unicode string */
4114        tmp_obj = get_encoded_string(
4115            buffer, PQclientEncoding(self->pgcnx->cnx));
4116        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
4117        PyBytes_AsStringAndSize(tmp_obj, &buf, &nbytes);
4118    }
4119    else if (PyErr_GivenExceptionMatches(buffer, PyExc_BaseException))
4120    {
4121        /* or pass a Python exception for sending an error message */
4122        tmp_obj = PyObject_Str(buffer);
4123        if (PyUnicode_Check(tmp_obj))
4124        {
4125            PyObject *obj = tmp_obj;
4126            tmp_obj = get_encoded_string(
4127                obj, PQclientEncoding(self->pgcnx->cnx));
4128            Py_DECREF(obj);
4129            if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
4130        }
4131        errormsg = PyBytes_AsString(tmp_obj);
4132        buf = NULL;
4133    }
4134    else
4135    {
4136        PyErr_SetString(PyExc_TypeError,
4137            "Method putdata() expects a buffer, None"
4138             " or an exception as argument");
4139        return NULL;
4140    }
4141
4142    /* checks validity */
4143    if (!check_source_obj(self, CHECK_CNX | CHECK_RESULT) ||
4144            PQresultStatus(self->result) != PGRES_COPY_IN)
4145    {
4146        PyErr_SetString(PyExc_IOError,
4147            "Connection is invalid or not in copy_in state");
4148        Py_XDECREF(tmp_obj);
4149        return NULL;
4150    }
4151
4152    if (buf)
4153    {
4154        res = nbytes ? PQputCopyData(self->pgcnx->cnx, buf, (int)nbytes) : 1;
4155    }
4156    else
4157    {
4158        res = PQputCopyEnd(self->pgcnx->cnx, errormsg);
4159    }
4160
4161    Py_XDECREF(tmp_obj);
4162
4163    if (res != 1)
4164    {
4165        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4166        return NULL;
4167    }
4168
4169    if (buf) /* buffer has been sent */
4170    {
4171        ret = Py_None;
4172        Py_INCREF(ret);
4173    }
4174    else /* copy is done */
4175    {
4176        PGresult   *result; /* final result of the operation */
4177
4178        Py_BEGIN_ALLOW_THREADS;
4179        result = PQgetResult(self->pgcnx->cnx);
4180        Py_END_ALLOW_THREADS;
4181
4182        if (PQresultStatus(result) == PGRES_COMMAND_OK)
4183        {
4184            char   *temp;
4185            long    num_rows;
4186
4187            temp = PQcmdTuples(result);
4188            num_rows = temp[0] ? atol(temp) : -1;
4189            ret = PyInt_FromLong(num_rows);
4190        }
4191        else
4192        {
4193            if (!errormsg) errormsg = PQerrorMessage(self->pgcnx->cnx);
4194            PyErr_SetString(PyExc_IOError, errormsg);
4195            ret = NULL;
4196        }
4197
4198        PQclear(self->result);
4199        self->result = NULL;
4200        self->result_type = RESULT_EMPTY;
4201    }
4202
4203    return ret; /* None or number of rows */
4204}
4205
4206/* get copy data */
4207static char sourceGetData__doc__[] =
4208"getdata(decode) -- receive data to server during copy to stdout";
4209
4210static PyObject *
4211sourceGetData(sourceObject *self, PyObject *args)
4212{
4213    int        *decode = 0; /* decode flag */
4214    char       *buffer; /* the copied buffer as encoded byte string */
4215    Py_ssize_t  nbytes; /* length of the byte string */
4216    PyObject   *ret; /* return value */
4217
4218    /* checks validity */
4219    if (!check_source_obj(self, CHECK_CNX))
4220        return NULL;
4221
4222    /* make sure that the connection object is valid */
4223    if (!self->pgcnx->cnx)
4224        return NULL;
4225
4226    if (!PyArg_ParseTuple(args, "|i", &decode))
4227        return NULL;
4228
4229    /* checks validity */
4230    if (!check_source_obj(self, CHECK_CNX | CHECK_RESULT) ||
4231            PQresultStatus(self->result) != PGRES_COPY_OUT)
4232    {
4233        PyErr_SetString(PyExc_IOError,
4234            "Connection is invalid or not in copy_out state");
4235        return NULL;
4236    }
4237
4238    nbytes = PQgetCopyData(self->pgcnx->cnx, &buffer, 0);
4239
4240    if (!nbytes || nbytes < -1) /* an error occurred */
4241    {
4242        PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4243        return NULL;
4244    }
4245
4246    if (nbytes == -1) /* copy is done */
4247    {
4248        PGresult   *result; /* final result of the operation */
4249
4250        Py_BEGIN_ALLOW_THREADS;
4251        result = PQgetResult(self->pgcnx->cnx);
4252        Py_END_ALLOW_THREADS;
4253
4254        if (PQresultStatus(result) == PGRES_COMMAND_OK)
4255        {
4256            char   *temp;
4257            long    num_rows;
4258
4259            temp = PQcmdTuples(result);
4260            num_rows = temp[0] ? atol(temp) : -1;
4261            ret = PyInt_FromLong(num_rows);
4262        }
4263        else
4264        {
4265            PyErr_SetString(PyExc_IOError, PQerrorMessage(self->pgcnx->cnx));
4266            ret = NULL;
4267        }
4268
4269        PQclear(self->result);
4270        self->result = NULL;
4271        self->result_type = RESULT_EMPTY;
4272    }
4273    else /* a row has been returned */
4274    {
4275        ret = decode ? get_decoded_string(
4276                buffer, nbytes, PQclientEncoding(self->pgcnx->cnx)) :
4277            PyBytes_FromStringAndSize(buffer, nbytes);
4278        PQfreemem(buffer);
4279    }
4280
4281    return ret; /* buffer or number of rows */
4282}
4283
4284/* finds field number from string/integer (internal use only) */
4285static int
4286sourceFieldindex(sourceObject *self, PyObject *param, const char *usage)
4287{
4288    int         num;
4289
4290    /* checks validity */
4291    if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
4292        return -1;
4293
4294    /* gets field number */
4295    if (PyStr_Check(param))
4296        num = PQfnumber(self->result, PyBytes_AsString(param));
4297    else if (PyInt_Check(param))
4298        num = (int)PyInt_AsLong(param);
4299    else
4300    {
4301        PyErr_SetString(PyExc_TypeError, usage);
4302        return -1;
4303    }
4304
4305    /* checks field validity */
4306    if (num < 0 || num >= self->num_fields)
4307    {
4308        PyErr_SetString(PyExc_ValueError, "Unknown field");
4309        return -1;
4310    }
4311
4312    return num;
4313}
4314
4315/* builds field information from position (internal use only) */
4316static PyObject *
4317pgsource_buildinfo(sourceObject *self, int num)
4318{
4319    PyObject *result;
4320
4321    /* allocates tuple */
4322    result = PyTuple_New(5);
4323    if (!result)
4324        return NULL;
4325
4326    /* affects field information */
4327    PyTuple_SET_ITEM(result, 0, PyInt_FromLong(num));
4328    PyTuple_SET_ITEM(result, 1,
4329        PyStr_FromString(PQfname(self->result, num)));
4330    PyTuple_SET_ITEM(result, 2,
4331        PyInt_FromLong(PQftype(self->result, num)));
4332    PyTuple_SET_ITEM(result, 3,
4333        PyInt_FromLong(PQfsize(self->result, num)));
4334    PyTuple_SET_ITEM(result, 4,
4335        PyInt_FromLong(PQfmod(self->result, num)));
4336
4337    return result;
4338}
4339
4340/* lists fields info */
4341static char sourceListInfo__doc__[] =
4342"listinfo() -- get information for all fields (position, name, type oid)";
4343
4344static PyObject *
4345sourceListInfo(sourceObject *self, PyObject *noargs)
4346{
4347    int         i;
4348    PyObject   *result,
4349               *info;
4350
4351    /* checks validity */
4352    if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
4353        return NULL;
4354
4355    /* builds result */
4356    if (!(result = PyTuple_New(self->num_fields)))
4357        return NULL;
4358
4359    for (i = 0; i < self->num_fields; ++i)
4360    {
4361        info = pgsource_buildinfo(self, i);
4362        if (!info)
4363        {
4364            Py_DECREF(result);
4365            return NULL;
4366        }
4367        PyTuple_SET_ITEM(result, i, info);
4368    }
4369
4370    /* returns result */
4371    return result;
4372};
4373
4374/* list fields information for last result */
4375static char sourceFieldInfo__doc__[] =
4376"fieldinfo(desc) -- get specified field info (position, name, type oid)";
4377
4378static PyObject *
4379sourceFieldInfo(sourceObject *self, PyObject *desc)
4380{
4381    int         num;
4382
4383    /* checks args and validity */
4384    if ((num = sourceFieldindex(self, desc,
4385            "Method fieldinfo() needs a string or integer as argument")) == -1)
4386        return NULL;
4387
4388    /* returns result */
4389    return pgsource_buildinfo(self, num);
4390};
4391
4392/* retrieve field value */
4393static char sourceField__doc__[] =
4394"field(desc) -- return specified field value";
4395
4396static PyObject *
4397sourceField(sourceObject *self, PyObject *desc)
4398{
4399    int         num;
4400
4401    /* checks args and validity */
4402    if ((num = sourceFieldindex(self, desc,
4403            "Method field() needs a string or integer as argument")) == -1)
4404        return NULL;
4405
4406    return PyStr_FromString(
4407        PQgetvalue(self->result, self->current_row, num));
4408}
4409
4410/* get the list of source object attributes */
4411static PyObject *
4412sourceDir(connObject *self, PyObject *noargs)
4413{
4414    PyObject *attrs;
4415
4416    attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
4417    PyObject_CallMethod(attrs, "extend", "[sssss]",
4418        "pgcnx", "arraysize", "resulttype", "ntuples", "nfields");
4419
4420    return attrs;
4421}
4422
4423/* source object methods */
4424static PyMethodDef sourceMethods[] = {
4425    {"__dir__", (PyCFunction) sourceDir,  METH_NOARGS, NULL},
4426    {"close", (PyCFunction) sourceClose, METH_NOARGS, sourceClose__doc__},
4427    {"execute", (PyCFunction) sourceExecute, METH_O, sourceExecute__doc__},
4428    {"oidstatus", (PyCFunction) sourceStatusOID, METH_NOARGS,
4429            sourceStatusOID__doc__},
4430    {"fetch", (PyCFunction) sourceFetch, METH_VARARGS,
4431            sourceFetch__doc__},
4432    {"movefirst", (PyCFunction) sourceMoveFirst, METH_NOARGS,
4433            sourceMoveFirst__doc__},
4434    {"movelast", (PyCFunction) sourceMoveLast, METH_NOARGS,
4435            sourceMoveLast__doc__},
4436    {"movenext", (PyCFunction) sourceMoveNext, METH_NOARGS,
4437            sourceMoveNext__doc__},
4438    {"moveprev", (PyCFunction) sourceMovePrev, METH_NOARGS,
4439            sourceMovePrev__doc__},
4440    {"putdata", (PyCFunction) sourcePutData, METH_O, sourcePutData__doc__},
4441    {"getdata", (PyCFunction) sourceGetData, METH_VARARGS,
4442            sourceGetData__doc__},
4443    {"field", (PyCFunction) sourceField, METH_O,
4444            sourceField__doc__},
4445    {"fieldinfo", (PyCFunction) sourceFieldInfo, METH_O,
4446            sourceFieldInfo__doc__},
4447    {"listinfo", (PyCFunction) sourceListInfo, METH_NOARGS,
4448            sourceListInfo__doc__},
4449    {NULL, NULL}
4450};
4451
4452/* gets source object attributes */
4453static PyObject *
4454sourceGetAttr(sourceObject *self, PyObject *nameobj)
4455{
4456    const char *name = PyStr_AsString(nameobj);
4457
4458    /* pg connection object */
4459    if (!strcmp(name, "pgcnx"))
4460    {
4461        if (check_source_obj(self, 0))
4462        {
4463            Py_INCREF(self->pgcnx);
4464            return (PyObject *) (self->pgcnx);
4465        }
4466        Py_INCREF(Py_None);
4467        return Py_None;
4468    }
4469
4470    /* arraysize */
4471    if (!strcmp(name, "arraysize"))
4472        return PyInt_FromLong(self->arraysize);
4473
4474    /* resulttype */
4475    if (!strcmp(name, "resulttype"))
4476        return PyInt_FromLong(self->result_type);
4477
4478    /* ntuples */
4479    if (!strcmp(name, "ntuples"))
4480        return PyInt_FromLong(self->max_row);
4481
4482    /* nfields */
4483    if (!strcmp(name, "nfields"))
4484        return PyInt_FromLong(self->num_fields);
4485
4486    /* seeks name in methods (fallback) */
4487    return PyObject_GenericGetAttr((PyObject *) self, nameobj);
4488}
4489
4490/* sets query object attributes */
4491static int
4492sourceSetAttr(sourceObject *self, char *name, PyObject *v)
4493{
4494    /* arraysize */
4495    if (!strcmp(name, "arraysize"))
4496    {
4497        if (!PyInt_Check(v))
4498        {
4499            PyErr_SetString(PyExc_TypeError, "arraysize must be integer");
4500            return -1;
4501        }
4502
4503        self->arraysize = PyInt_AsLong(v);
4504        return 0;
4505    }
4506
4507    /* unknown attribute */
4508    PyErr_SetString(PyExc_TypeError, "Not a writable attribute");
4509    return -1;
4510}
4511
4512/* return source object as string in human readable form */
4513static PyObject *
4514sourceStr(sourceObject *self)
4515{
4516    switch (self->result_type)
4517    {
4518        case RESULT_DQL:
4519            return format_result(self->result);
4520        case RESULT_DDL:
4521        case RESULT_DML:
4522            return PyStr_FromString(PQcmdStatus(self->result));
4523        case RESULT_EMPTY:
4524        default:
4525            return PyStr_FromString("(empty PostgreSQL source object)");
4526    }
4527}
4528
4529static char source__doc__[] = "PyGreSQL source object";
4530
4531/* source type definition */
4532static PyTypeObject sourceType = {
4533    PyVarObject_HEAD_INIT(NULL, 0)
4534    "pgdb.Source",                  /* tp_name */
4535    sizeof(sourceObject),           /* tp_basicsize */
4536    0,                              /* tp_itemsize */
4537    /* methods */
4538    (destructor) sourceDealloc,     /* tp_dealloc */
4539    0,                              /* tp_print */
4540    0,                              /* tp_getattr */
4541    (setattrfunc) sourceSetAttr,    /* tp_setattr */
4542    0,                              /* tp_compare */
4543    0,                              /* tp_repr */
4544    0,                              /* tp_as_number */
4545    0,                              /* tp_as_sequence */
4546    0,                              /* tp_as_mapping */
4547    0,                              /* tp_hash */
4548    0,                              /* tp_call */
4549    (reprfunc) sourceStr,           /* tp_str */
4550    (getattrofunc) sourceGetAttr,   /* tp_getattro */
4551    0,                              /* tp_setattro */
4552    0,                              /* tp_as_buffer */
4553    Py_TPFLAGS_DEFAULT,             /* tp_flags */
4554    source__doc__,                  /* tp_doc */
4555    0,                              /* tp_traverse */
4556    0,                              /* tp_clear */
4557    0,                              /* tp_richcompare */
4558    0,                              /* tp_weaklistoffset */
4559    0,                              /* tp_iter */
4560    0,                              /* tp_iternext */
4561    sourceMethods,                  /* tp_methods */
4562};
4563
4564/* connects to a database */
4565static char pgConnect__doc__[] =
4566"connect(dbname, host, port, opt) -- connect to a PostgreSQL database\n\n"
4567"The connection uses the specified parameters (optional, keywords aware).\n";
4568
4569static PyObject *
4570pgConnect(PyObject *self, PyObject *args, PyObject *dict)
4571{
4572    static const char *kwlist[] = {"dbname", "host", "port", "opt",
4573    "user", "passwd", NULL};
4574
4575    char       *pghost,
4576               *pgopt,
4577               *pgdbname,
4578               *pguser,
4579               *pgpasswd;
4580    int         pgport;
4581    char        port_buffer[20];
4582    connObject *conn_obj;
4583
4584    pghost = pgopt = pgdbname = pguser = pgpasswd = NULL;
4585    pgport = -1;
4586
4587    /*
4588     * parses standard arguments With the right compiler warnings, this
4589     * will issue a diagnostic. There is really no way around it.  If I
4590     * don't declare kwlist as const char *kwlist[] then it complains when
4591     * I try to assign all those constant strings to it.
4592     */
4593    if (!PyArg_ParseTupleAndKeywords(args, dict, "|zzizzz", (char **) kwlist,
4594        &pgdbname, &pghost, &pgport, &pgopt, &pguser, &pgpasswd))
4595        return NULL;
4596
4597#ifdef DEFAULT_VARS
4598    /* handles defaults variables (for uninitialised vars) */
4599    if ((!pghost) && (pg_default_host != Py_None))
4600        pghost = PyBytes_AsString(pg_default_host);
4601
4602    if ((pgport == -1) && (pg_default_port != Py_None))
4603        pgport = (int)PyInt_AsLong(pg_default_port);
4604
4605    if ((!pgopt) && (pg_default_opt != Py_None))
4606        pgopt = PyBytes_AsString(pg_default_opt);
4607
4608    if ((!pgdbname) && (pg_default_base != Py_None))
4609        pgdbname = PyBytes_AsString(pg_default_base);
4610
4611    if ((!pguser) && (pg_default_user != Py_None))
4612        pguser = PyBytes_AsString(pg_default_user);
4613
4614    if ((!pgpasswd) && (pg_default_passwd != Py_None))
4615        pgpasswd = PyBytes_AsString(pg_default_passwd);
4616#endif /* DEFAULT_VARS */
4617
4618    if (!(conn_obj = PyObject_NEW(connObject, &connType)))
4619    {
4620        set_error_msg(InternalError, "Can't create new connection object");
4621        return NULL;
4622    }
4623
4624    conn_obj->valid = 1;
4625    conn_obj->cnx = NULL;
4626    conn_obj->date_format = date_format;
4627    conn_obj->cast_hook = NULL;
4628    conn_obj->notice_receiver = NULL;
4629
4630    if (pgport != -1)
4631    {
4632        memset(port_buffer, 0, sizeof(port_buffer));
4633        sprintf(port_buffer, "%d", pgport);
4634    }
4635
4636    Py_BEGIN_ALLOW_THREADS
4637    conn_obj->cnx = PQsetdbLogin(pghost, pgport == -1 ? NULL : port_buffer,
4638        pgopt, NULL, pgdbname, pguser, pgpasswd);
4639    Py_END_ALLOW_THREADS
4640
4641    if (PQstatus(conn_obj->cnx) == CONNECTION_BAD)
4642    {
4643        set_error(InternalError, "Cannot connect", conn_obj->cnx, NULL);
4644        Py_XDECREF(conn_obj);
4645        return NULL;
4646    }
4647
4648    return (PyObject *) conn_obj;
4649}
4650
4651static void
4652queryDealloc(queryObject *self)
4653{
4654    Py_XDECREF(self->pgcnx);
4655    if (self->col_types)
4656        PyMem_Free(self->col_types);
4657    if (self->result)
4658        PQclear(self->result);
4659
4660    PyObject_Del(self);
4661}
4662
4663/* get number of rows */
4664static char queryNtuples__doc__[] =
4665"ntuples() -- return number of tuples returned by query";
4666
4667static PyObject *
4668queryNtuples(queryObject *self, PyObject *noargs)
4669{
4670    return PyInt_FromLong(self->max_row);
4671}
4672
4673/* list fields names from query result */
4674static char queryListfields__doc__[] =
4675"listfields() -- List field names from result";
4676
4677static PyObject *
4678queryListfields(queryObject *self, PyObject *noargs)
4679{
4680    int         i;
4681    char       *name;
4682    PyObject   *fieldstuple,
4683               *str;
4684
4685    /* builds tuple */
4686    fieldstuple = PyTuple_New(self->num_fields);
4687    if (fieldstuple) {
4688        for (i = 0; i < self->num_fields; ++i)
4689        {
4690            name = PQfname(self->result, i);
4691            str = PyStr_FromString(name);
4692            PyTuple_SET_ITEM(fieldstuple, i, str);
4693        }
4694    }
4695    return fieldstuple;
4696}
4697
4698/* get field name from last result */
4699static char queryFieldname__doc__[] =
4700"fieldname(num) -- return name of field from result from its position";
4701
4702static PyObject *
4703queryFieldname(queryObject *self, PyObject *args)
4704{
4705    int     i;
4706    char   *name;
4707
4708    /* gets args */
4709    if (!PyArg_ParseTuple(args, "i", &i))
4710    {
4711        PyErr_SetString(PyExc_TypeError,
4712            "Method fieldname() takes an integer as argument");
4713        return NULL;
4714    }
4715
4716    /* checks number validity */
4717    if (i >= self->num_fields)
4718    {
4719        PyErr_SetString(PyExc_ValueError, "Invalid field number");
4720        return NULL;
4721    }
4722
4723    /* gets fields name and builds object */
4724    name = PQfname(self->result, i);
4725    return PyStr_FromString(name);
4726}
4727
4728/* gets fields number from name in last result */
4729static char queryFieldnum__doc__[] =
4730"fieldnum(name) -- return position in query for field from its name";
4731
4732static PyObject *
4733queryFieldnum(queryObject *self, PyObject *args)
4734{
4735    int     num;
4736    char   *name;
4737
4738    /* gets args */
4739    if (!PyArg_ParseTuple(args, "s", &name))
4740    {
4741        PyErr_SetString(PyExc_TypeError,
4742            "Method fieldnum() takes a string as argument");
4743        return NULL;
4744    }
4745
4746    /* gets field number */
4747    if ((num = PQfnumber(self->result, name)) == -1)
4748    {
4749        PyErr_SetString(PyExc_ValueError, "Unknown field");
4750        return NULL;
4751    }
4752
4753    return PyInt_FromLong(num);
4754}
4755
4756/* The __iter__() method of the queryObject.
4757   This returns the default iterator yielding rows as tuples. */
4758static PyObject* queryGetIter(queryObject *self)
4759{
4760    self->current_row = 0;
4761    Py_INCREF(self);
4762    return (PyObject*)self;
4763}
4764
4765/* Return the value in the given column of the current row. */
4766static PyObject *
4767getValueInColumn(queryObject *self, int column)
4768{
4769    if (PQgetisnull(self->result, self->current_row, column))
4770    {
4771        Py_INCREF(Py_None);
4772        return Py_None;
4773    }
4774
4775    /* get the string representation of the value */
4776    /* note: this is always null-terminated text format */
4777    char   *s = PQgetvalue(self->result, self->current_row, column);
4778    /* get the PyGreSQL type of the column */
4779    int     type = self->col_types[column];
4780    /* cast the string representation into a Python object */
4781    if (type & PYGRES_ARRAY)
4782        return cast_array(s,
4783            PQgetlength(self->result, self->current_row, column),
4784            self->encoding, type, NULL, 0);
4785    if (type == PYGRES_BYTEA)
4786        return cast_bytea_text(s);
4787    if (type == PYGRES_OTHER)
4788        return cast_other(s,
4789            PQgetlength(self->result, self->current_row, column),
4790            self->encoding,
4791            PQftype(self->result, column), self->pgcnx->cast_hook);
4792    if (type & PYGRES_TEXT)
4793        return cast_sized_text(s,
4794            PQgetlength(self->result, self->current_row, column),
4795            self->encoding, type);
4796    return cast_unsized_simple(s, type);
4797}
4798
4799/* Return the current row as a tuple. */
4800static PyObject *
4801queryGetRowAsTuple(queryObject *self)
4802{
4803    PyObject   *row_tuple = NULL;
4804    int         j;
4805
4806    if (!(row_tuple = PyTuple_New(self->num_fields))) return NULL;
4807
4808    for (j = 0; j < self->num_fields; ++j)
4809    {
4810        PyObject *val = getValueInColumn(self, j);
4811        if (!val)
4812        {
4813            Py_DECREF(row_tuple); return NULL;
4814        }
4815        PyTuple_SET_ITEM(row_tuple, j, val);
4816    }
4817
4818    return row_tuple;
4819}
4820
4821/* The __next__() method of the queryObject.
4822   Returns the current current row as a tuple and moves to the next one. */
4823static PyObject *
4824queryNext(queryObject *self, PyObject *noargs)
4825{
4826    PyObject   *row_tuple = NULL;
4827
4828    if (self->current_row >= self->max_row) {
4829        PyErr_SetNone(PyExc_StopIteration);
4830        return NULL;
4831    }
4832
4833    row_tuple = queryGetRowAsTuple(self);
4834    if (row_tuple) ++self->current_row;
4835    return row_tuple;
4836}
4837
4838/* Retrieves one row from the result as a tuple. */
4839static char queryOne__doc__[] =
4840"one() -- Get one row from the result of a query\n\n"
4841"Only one row from the result is returned as a tuple of fields.\n"
4842"This method can be called multiple times to return more rows.\n"
4843"It returns None if the result does not contain one more row.\n";
4844
4845static PyObject *
4846queryOne(queryObject *self, PyObject *noargs)
4847{
4848    PyObject *row_tuple;
4849
4850    if (self->current_row >= self->max_row) {
4851        Py_INCREF(Py_None); return Py_None;
4852    }
4853
4854    row_tuple = queryGetRowAsTuple(self);
4855    if (row_tuple) ++self->current_row;
4856    return row_tuple;
4857}
4858
4859/* Retrieves the single row from the result as a tuple. */
4860static char querySingle__doc__[] =
4861"single() -- Get the result of a query as single row\n\n"
4862"The single row from the query result is returned as a tuple of fields.\n"
4863"This method returns the same single row when called multiple times.\n"
4864"It raises a ProgrammingError if the result does not have exactly one row.\n";
4865
4866static PyObject *
4867querySingle(queryObject *self, PyObject *noargs)
4868{
4869    PyObject *row_tuple;
4870
4871    if (self->max_row != 1) {
4872        set_error_msg(ProgrammingError,
4873            self->max_row ? "Multiple results found" : "No result found");
4874        return NULL;
4875    }
4876
4877    self->current_row = 0;
4878    row_tuple = queryGetRowAsTuple(self);
4879    if (row_tuple) ++self->current_row;
4880    return row_tuple;
4881}
4882
4883/* Retrieves the last query result as a list of tuples. */
4884static char queryGetresult__doc__[] =
4885"getresult() -- Get the result of a query\n\n"
4886"The result is returned as a list of rows, each one a tuple of fields\n"
4887"in the order returned by the server.\n";
4888
4889static PyObject *
4890queryGetresult(queryObject *self, PyObject *noargs)
4891{
4892    PyObject   *result_list;
4893    int         i;
4894
4895    if (!(result_list = PyList_New(self->max_row))) return NULL;
4896
4897    for (i = self->current_row = 0; i < self->max_row; ++i)
4898    {
4899        PyObject   *row_tuple = queryNext(self, noargs);
4900        if (!row_tuple)
4901        {
4902            Py_DECREF(result_list); return NULL;
4903        }
4904        PyList_SET_ITEM(result_list, i, row_tuple);
4905    }
4906
4907    return result_list;
4908}
4909
4910/* Return the current row as a dict. */
4911static PyObject *
4912queryGetRowAsDict(queryObject *self)
4913{
4914    PyObject   *row_dict = NULL;
4915    int         j;
4916
4917    if (!(row_dict = PyDict_New())) return NULL;
4918
4919    for (j = 0; j < self->num_fields; ++j)
4920    {
4921        PyObject *val = getValueInColumn(self, j);
4922        if (!val)
4923        {
4924            Py_DECREF(row_dict); return NULL;
4925        }
4926        PyDict_SetItemString(row_dict, PQfname(self->result, j), val);
4927        Py_DECREF(val);
4928    }
4929
4930    return row_dict;
4931}
4932
4933/* Return the current current row as a dict and move to the next one. */
4934static PyObject *
4935queryNextDict(queryObject *self, PyObject *noargs)
4936{
4937    PyObject   *row_dict = NULL;
4938
4939    if (self->current_row >= self->max_row) {
4940        PyErr_SetNone(PyExc_StopIteration);
4941        return NULL;
4942    }
4943
4944    row_dict = queryGetRowAsDict(self);
4945    if (row_dict) ++self->current_row;
4946    return row_dict;
4947}
4948
4949/* Retrieve one row from the result as a dictionary. */
4950static char queryOnedict__doc__[] =
4951"onedict() -- Get one row from the result of a query\n\n"
4952"Only one row from the result is returned as a dictionary with\n"
4953"the field names used as the keys.\n"
4954"This method can be called multiple times to return more rows.\n"
4955"It returns None if the result does not contain one more row.\n";
4956
4957static PyObject *
4958queryOnedict(queryObject *self, PyObject *noargs)
4959{
4960    PyObject *row_dict;
4961
4962    if (self->current_row >= self->max_row) {
4963        Py_INCREF(Py_None); return Py_None;
4964    }
4965
4966    row_dict = queryGetRowAsDict(self);
4967    if (row_dict) ++self->current_row;
4968    return row_dict;
4969}
4970
4971/* Retrieve the single row from the result as a dictionary. */
4972static char querySingledict__doc__[] =
4973"singledict() -- Get the result of a query as single row\n\n"
4974"The single row from the query result is returned as a dictionary with\n"
4975"the field names used as the keys.\n"
4976"This method returns the same single row when called multiple times.\n"
4977"It raises a ProgrammingError if the result does not have exactly one row.\n";
4978
4979static PyObject *
4980querySingledict(queryObject *self, PyObject *noargs)
4981{
4982    PyObject *row_dict;
4983
4984    if (self->max_row != 1) {
4985        set_error_msg(ProgrammingError,
4986            self->max_row ? "Multiple results found" : "No result found");
4987        return NULL;
4988    }
4989
4990    self->current_row = 0;
4991    row_dict = queryGetRowAsDict(self);
4992    if (row_dict) ++self->current_row;
4993    return row_dict;
4994}
4995
4996/* Retrieve the last query result as a list of dictionaries. */
4997static char queryDictresult__doc__[] =
4998"dictresult() -- Get the result of a query\n\n"
4999"The result is returned as a list of rows, each one a dictionary with\n"
5000"the field names used as the keys.\n";
5001
5002static PyObject *
5003queryDictresult(queryObject *self, PyObject *noargs)
5004{
5005    PyObject   *result_list;
5006    int         i;
5007
5008    if (!(result_list = PyList_New(self->max_row))) return NULL;
5009
5010    for (i = self->current_row = 0; i < self->max_row; ++i)
5011    {
5012        PyObject   *row_dict = queryNextDict(self, noargs);
5013        if (!row_dict)
5014        {
5015            Py_DECREF(result_list); return NULL;
5016        }
5017        PyList_SET_ITEM(result_list, i, row_dict);
5018    }
5019
5020    return result_list;
5021}
5022
5023/* Retrieve last result as iterator of dictionaries. */
5024static char queryDictiter__doc__[] =
5025"dictiter() -- Get the result of a query\n\n"
5026"The result is returned as an iterator of rows, each one a a dictionary\n"
5027"with the field names used as the keys.\n";
5028
5029static PyObject *
5030queryDictiter(queryObject *self, PyObject *noargs)
5031{
5032    if (!dictiter)
5033        return queryDictresult(self, noargs);
5034
5035    return PyObject_CallFunction(dictiter, "(O)", self);
5036}
5037
5038/* Retrieve one row from the result as a named tuple. */
5039static char queryOnenamed__doc__[] =
5040"onenamed() -- Get one row from the result of a query\n\n"
5041"Only one row from the result is returned as a named tuple of fields.\n"
5042"This method can be called multiple times to return more rows.\n"
5043"It returns None if the result does not contain one more row.\n";
5044
5045static PyObject *
5046queryOnenamed(queryObject *self, PyObject *noargs)
5047{
5048    if (!namednext)
5049        return queryOne(self, noargs);
5050
5051    if (self->current_row >= self->max_row) {
5052        Py_INCREF(Py_None); return Py_None;
5053    }
5054
5055    return PyObject_CallFunction(namednext, "(O)", self);
5056}
5057
5058/* Retrieve the single row from the result as a tuple. */
5059static char querySinglenamed__doc__[] =
5060"singlenamed() -- Get the result of a query as single row\n\n"
5061"The single row from the query result is returned as a named tuple of fields.\n"
5062"This method returns the same single row when called multiple times.\n"
5063"It raises a ProgrammingError if the result does not have exactly one row.\n";
5064
5065static PyObject *
5066querySinglenamed(queryObject *self, PyObject *noargs)
5067{
5068    if (!namednext)
5069        return querySingle(self, noargs);
5070
5071    if (self->max_row != 1) {
5072        set_error_msg(ProgrammingError,
5073            self->max_row ? "Multiple results found" : "No result found");
5074        return NULL;
5075    }
5076
5077    self->current_row = 0;
5078    return PyObject_CallFunction(namednext, "(O)", self);
5079}
5080
5081/* Retrieve last result as list of named tuples. */
5082static char queryNamedresult__doc__[] =
5083"namedresult() -- Get the result of a query\n\n"
5084"The result is returned as a list of rows, each one a named tuple of fields\n"
5085"in the order returned by the server.\n";
5086
5087static PyObject *
5088queryNamedresult(queryObject *self, PyObject *noargs)
5089{
5090    PyObject   *res, *res_list;
5091
5092    if (!namediter)
5093        return queryGetresult(self, noargs);
5094
5095    res = PyObject_CallFunction(namediter, "(O)", self);
5096    if (!res) return NULL;
5097    if (PyList_Check(res)) return res;
5098    res_list = PySequence_List(res);
5099    Py_DECREF(res);
5100    return res_list;
5101}
5102
5103/* Retrieve last result as iterator of named tuples. */
5104static char queryNamediter__doc__[] =
5105"namediter() -- Get the result of a query\n\n"
5106"The result is returned as an iterator of rows, each one a named tuple\n"
5107"of fields in the order returned by the server.\n";
5108
5109static PyObject *
5110queryNamediter(queryObject *self, PyObject *noargs)
5111{
5112    PyObject   *res, *res_iter;
5113
5114    if (!namediter)
5115        return queryGetIter(self);
5116
5117    res = PyObject_CallFunction(namediter, "(O)", self);
5118    if (!res) return NULL;
5119    if (!PyList_Check(res)) return res;
5120    res_iter = (Py_TYPE(res)->tp_iter)((PyObject *)self);
5121    Py_DECREF(res);
5122    return res_iter;
5123}
5124
5125/* Retrieve the last query result as a list of scalar values. */
5126static char queryScalarresult__doc__[] =
5127"scalarresult() -- Get query result as scalars\n\n"
5128"The result is returned as a list of scalar values where the values\n"
5129"are the first fields of the rows in the order returned by the server.\n";
5130
5131static PyObject *
5132queryScalarresult(queryObject *self, PyObject *noargs)
5133{
5134    PyObject   *result_list;
5135
5136    if (!self->num_fields) {
5137        set_error_msg(ProgrammingError, "No fields in result");
5138        return NULL;
5139    }
5140
5141    if (!(result_list = PyList_New(self->max_row))) return NULL;
5142
5143    for (self->current_row = 0; self->current_row < self->max_row;
5144        ++self->current_row)
5145    {
5146        PyObject   *value = getValueInColumn(self, 0);
5147        if (!value)
5148        {
5149            Py_DECREF(result_list); return NULL;
5150        }
5151        PyList_SET_ITEM(result_list, self->current_row, value);
5152    }
5153
5154    return result_list;
5155}
5156
5157/* Retrieve the last query result as iterator of scalar values. */
5158static char queryScalariter__doc__[] =
5159"scalariter() -- Get query result as scalars\n\n"
5160"The result is returned as an iterator of scalar values where the values\n"
5161"are the first fields of the rows in the order returned by the server.\n";
5162
5163static PyObject *
5164queryScalariter(queryObject *self, PyObject *noargs)
5165{
5166    if (!scalariter)
5167        return queryScalarresult(self, noargs);
5168
5169    if (!self->num_fields) {
5170        set_error_msg(ProgrammingError, "No fields in result");
5171        return NULL;
5172    }
5173
5174    return PyObject_CallFunction(scalariter, "(O)", self);
5175}
5176
5177/* Retrieve one result as scalar value. */
5178static char queryOnescalar__doc__[] =
5179"onescalar() -- Get one scalar value from the result of a query\n\n"
5180"Returns the first field of the next row from the result as a scalar value.\n"
5181"This method can be called multiple times to return more rows as scalars.\n"
5182"It returns None if the result does not contain one more row.\n";
5183
5184static PyObject *
5185queryOnescalar(queryObject *self, PyObject *noargs)
5186{
5187    PyObject *value;
5188
5189    if (!self->num_fields) {
5190        set_error_msg(ProgrammingError, "No fields in result");
5191        return NULL;
5192    }
5193
5194    if (self->current_row >= self->max_row) {
5195        Py_INCREF(Py_None); return Py_None;
5196    }
5197
5198    value = getValueInColumn(self, 0);
5199    if (value) ++self->current_row;
5200    return value;
5201}
5202
5203/* Retrieves the single row from the result as a tuple. */
5204static char querySinglescalar__doc__[] =
5205"singlescalar() -- Get scalar value from single result of a query\n\n"
5206"Returns the first field of the next row from the result as a scalar value.\n"
5207"This method returns the same single row when called multiple times.\n"
5208"It raises a ProgrammingError if the result does not have exactly one row.\n";
5209
5210static PyObject *
5211querySinglescalar(queryObject *self, PyObject *noargs)
5212{
5213    PyObject *value;
5214
5215    if (!self->num_fields) {
5216        set_error_msg(ProgrammingError, "No fields in result");
5217        return NULL;
5218    }
5219
5220    if (self->max_row != 1) {
5221        set_error_msg(ProgrammingError,
5222            self->max_row ? "Multiple results found" : "No result found");
5223        return NULL;
5224    }
5225
5226    self->current_row = 0;
5227    value = getValueInColumn(self, 0);
5228    if (value) ++self->current_row;
5229    return value;
5230}
5231
5232/* Return length of a query object. */
5233static Py_ssize_t
5234queryLen(PyObject *self)
5235{
5236    PyObject   *tmp;
5237    long        len;
5238
5239    tmp = PyLong_FromLong(((queryObject*)self)->max_row);
5240    len = PyLong_AsSsize_t(tmp);
5241    Py_DECREF(tmp);
5242    return len;
5243}
5244
5245/* Return given item from a query object. */
5246static PyObject *
5247queryGetItem(PyObject *self, Py_ssize_t i)
5248{
5249    queryObject    *q = (queryObject *)self;
5250    PyObject       *tmp;
5251    long            row;
5252
5253    tmp = PyLong_FromSize_t(i);
5254    row = PyLong_AsLong(tmp);
5255    Py_DECREF(tmp);
5256
5257    if (row < 0 || row >= q->max_row) {
5258        PyErr_SetNone(PyExc_IndexError);
5259        return NULL;
5260    }
5261
5262    q->current_row = row;
5263    return queryGetRowAsTuple(q);
5264}
5265
5266/* gets notice object attributes */
5267static PyObject *
5268noticeGetAttr(noticeObject *self, PyObject *nameobj)
5269{
5270    PGresult const *res = self->res;
5271    const char *name = PyStr_AsString(nameobj);
5272    int fieldcode;
5273
5274    if (!res)
5275    {
5276        PyErr_SetString(PyExc_TypeError, "Cannot get current notice");
5277        return NULL;
5278    }
5279
5280    /* pg connection object */
5281    if (!strcmp(name, "pgcnx"))
5282    {
5283        if (self->pgcnx && check_cnx_obj(self->pgcnx))
5284        {
5285            Py_INCREF(self->pgcnx);
5286            return (PyObject *) self->pgcnx;
5287        }
5288        else
5289        {
5290            Py_INCREF(Py_None);
5291            return Py_None;
5292        }
5293    }
5294
5295    /* full message */
5296    if (!strcmp(name, "message"))
5297        return PyStr_FromString(PQresultErrorMessage(res));
5298
5299    /* other possible fields */
5300    fieldcode = 0;
5301    if (!strcmp(name, "severity"))
5302        fieldcode = PG_DIAG_SEVERITY;
5303    else if (!strcmp(name, "primary"))
5304        fieldcode = PG_DIAG_MESSAGE_PRIMARY;
5305    else if (!strcmp(name, "detail"))
5306        fieldcode = PG_DIAG_MESSAGE_DETAIL;
5307    else if (!strcmp(name, "hint"))
5308        fieldcode = PG_DIAG_MESSAGE_HINT;
5309    if (fieldcode)
5310    {
5311        char *s = PQresultErrorField(res, fieldcode);
5312        if (s)
5313            return PyStr_FromString(s);
5314        else
5315        {
5316            Py_INCREF(Py_None); return Py_None;
5317        }
5318    }
5319
5320    return PyObject_GenericGetAttr((PyObject *) self, nameobj);
5321}
5322
5323/* return notice as string in human readable form */
5324static PyObject *
5325noticeStr(noticeObject *self)
5326{
5327    return noticeGetAttr(self, PyBytes_FromString("message"));
5328}
5329
5330/* get the list of notice attributes */
5331static PyObject *
5332noticeDir(noticeObject *self, PyObject *noargs)
5333{
5334    PyObject *attrs;
5335
5336    attrs = PyObject_Dir(PyObject_Type((PyObject *)self));
5337    PyObject_CallMethod(attrs, "extend", "[ssssss]",
5338        "pgcnx", "severity", "message", "primary", "detail", "hint");
5339
5340    return attrs;
5341}
5342
5343/* notice object methods */
5344static struct PyMethodDef noticeMethods[] = {
5345    {"__dir__", (PyCFunction) noticeDir,  METH_NOARGS, NULL},
5346    {NULL, NULL}
5347};
5348
5349/* notice type definition */
5350static PyTypeObject noticeType = {
5351    PyVarObject_HEAD_INIT(NULL, 0)
5352    "pg.Notice",                    /* tp_name */
5353    sizeof(noticeObject),           /* tp_basicsize */
5354    0,                              /* tp_itemsize */
5355    /* methods */
5356    0,                              /* tp_dealloc */
5357    0,                              /* tp_print */
5358    0,                              /* tp_getattr */
5359    0,                              /* tp_setattr */
5360    0,                              /* tp_compare */
5361    0,                              /* tp_repr */
5362    0,                              /* tp_as_number */
5363    0,                              /* tp_as_sequence */
5364    0,                              /* tp_as_mapping */
5365    0,                              /* tp_hash */
5366    0,                              /* tp_call */
5367    (reprfunc) noticeStr,           /* tp_str */
5368    (getattrofunc) noticeGetAttr,   /* tp_getattro */
5369    PyObject_GenericSetAttr,        /* tp_setattro */
5370    0,                              /* tp_as_buffer */
5371    Py_TPFLAGS_DEFAULT,             /* tp_flags */
5372    0,                              /* tp_doc */
5373    0,                              /* tp_traverse */
5374    0,                              /* tp_clear */
5375    0,                              /* tp_richcompare */
5376    0,                              /* tp_weaklistoffset */
5377    0,                              /* tp_iter */
5378    0,                              /* tp_iternext */
5379    noticeMethods,                  /* tp_methods */
5380};
5381
5382/* query object methods */
5383static struct PyMethodDef queryMethods[] = {
5384    {"getresult", (PyCFunction) queryGetresult, METH_NOARGS,
5385            queryGetresult__doc__},
5386    {"dictresult", (PyCFunction) queryDictresult, METH_NOARGS,
5387            queryDictresult__doc__},
5388    {"dictiter", (PyCFunction) queryDictiter, METH_NOARGS,
5389            queryDictiter__doc__},
5390    {"namedresult", (PyCFunction) queryNamedresult, METH_NOARGS,
5391            queryNamedresult__doc__},
5392    {"namediter", (PyCFunction) queryNamediter, METH_NOARGS,
5393            queryNamediter__doc__},
5394    {"one", (PyCFunction) queryOne, METH_NOARGS, queryOne__doc__},
5395    {"single", (PyCFunction) querySingle, METH_NOARGS, querySingle__doc__},
5396    {"onedict", (PyCFunction) queryOnedict, METH_NOARGS,
5397        queryOnedict__doc__},
5398    {"singledict", (PyCFunction) querySingledict, METH_NOARGS,
5399        querySingledict__doc__},
5400    {"onenamed", (PyCFunction) queryOnenamed, METH_NOARGS,
5401        queryOnenamed__doc__},
5402    {"singlenamed", (PyCFunction) querySinglenamed, METH_NOARGS,
5403        querySinglenamed__doc__},
5404    {"scalarresult", (PyCFunction) queryScalarresult, METH_NOARGS,
5405            queryScalarresult__doc__},
5406    {"scalariter", (PyCFunction) queryScalariter, METH_NOARGS,
5407            queryScalariter__doc__},
5408    {"onescalar", (PyCFunction) queryOnescalar, METH_NOARGS,
5409            queryOnescalar__doc__},
5410    {"singlescalar", (PyCFunction) querySinglescalar, METH_NOARGS,
5411            querySinglescalar__doc__},
5412    {"fieldname", (PyCFunction) queryFieldname, METH_VARARGS,
5413             queryFieldname__doc__},
5414    {"fieldnum", (PyCFunction) queryFieldnum, METH_VARARGS,
5415            queryFieldnum__doc__},
5416    {"listfields", (PyCFunction) queryListfields, METH_NOARGS,
5417            queryListfields__doc__},
5418    {"ntuples", (PyCFunction) queryNtuples, METH_NOARGS,
5419            queryNtuples__doc__},
5420    {NULL, NULL}
5421};
5422
5423/* query sequence protocol methods */
5424static PySequenceMethods querySequenceMethods = {
5425    (lenfunc) queryLen,             /* sq_length */
5426    0,                              /* sq_concat */
5427    0,                              /* sq_repeat */
5428    (ssizeargfunc) queryGetItem,    /* sq_item */
5429    0,                              /* sq_ass_item */
5430    0,                              /* sq_contains */
5431    0,                              /* sq_inplace_concat */
5432    0,                              /* sq_inplace_repeat */
5433};
5434
5435
5436/* query type definition */
5437static PyTypeObject queryType = {
5438    PyVarObject_HEAD_INIT(NULL, 0)
5439    "pg.Query",                 /* tp_name */
5440    sizeof(queryObject),        /* tp_basicsize */
5441    0,                          /* tp_itemsize */
5442    /* methods */
5443    (destructor) queryDealloc,  /* tp_dealloc */
5444    0,                          /* tp_print */
5445    0,                          /* tp_getattr */
5446    0,                          /* tp_setattr */
5447    0,                          /* tp_compare */
5448    0,                          /* tp_repr */
5449    0,                          /* tp_as_number */
5450    &querySequenceMethods,      /* tp_as_sequence */
5451    0,                          /* tp_as_mapping */
5452    0,                          /* tp_hash */
5453    0,                          /* tp_call */
5454    (reprfunc) queryStr,        /* tp_str */
5455    PyObject_GenericGetAttr,    /* tp_getattro */
5456    0,                          /* tp_setattro */
5457    0,                          /* tp_as_buffer */
5458    Py_TPFLAGS_DEFAULT
5459        |Py_TPFLAGS_HAVE_ITER,  /* tp_flags */
5460    0,                          /* tp_doc */
5461    0,                          /* tp_traverse */
5462    0,                          /* tp_clear */
5463    0,                          /* tp_richcompare */
5464    0,                          /* tp_weaklistoffset */
5465    (getiterfunc)queryGetIter,  /* tp_iter */
5466    (iternextfunc)queryNext,    /* tp_iternext */
5467    queryMethods,               /* tp_methods */
5468};
5469
5470/* --------------------------------------------------------------------- */
5471
5472/* MODULE FUNCTIONS */
5473
5474/* escape string */
5475static char pgEscapeString__doc__[] =
5476"escape_string(string) -- escape a string for use within SQL";
5477
5478static PyObject *
5479pgEscapeString(PyObject *self, PyObject *string)
5480{
5481    PyObject   *tmp_obj = NULL, /* auxiliary string object */
5482               *to_obj; /* string object to return */
5483    char       *from, /* our string argument as encoded string */
5484               *to; /* the result as encoded string */
5485    Py_ssize_t  from_length; /* length of string */
5486    size_t      to_length; /* length of result */
5487    int         encoding = -1; /* client encoding */
5488
5489    if (PyBytes_Check(string))
5490    {
5491        PyBytes_AsStringAndSize(string, &from, &from_length);
5492    }
5493    else if (PyUnicode_Check(string))
5494    {
5495        encoding = pg_encoding_ascii;
5496        tmp_obj = get_encoded_string(string, encoding);
5497        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5498        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5499    }
5500    else
5501    {
5502        PyErr_SetString(PyExc_TypeError,
5503            "Method escape_string() expects a string as argument");
5504        return NULL;
5505    }
5506
5507    to_length = 2*from_length + 1;
5508    if ((Py_ssize_t)to_length < from_length) /* overflow */
5509    {
5510        to_length = from_length;
5511        from_length = (from_length - 1)/2;
5512    }
5513    to = (char *)PyMem_Malloc(to_length);
5514    to_length = (int)PQescapeString(to, from, (size_t)from_length);
5515
5516    Py_XDECREF(tmp_obj);
5517
5518    if (encoding == -1)
5519        to_obj = PyBytes_FromStringAndSize(to, to_length);
5520    else
5521        to_obj = get_decoded_string(to, to_length, encoding);
5522    PyMem_Free(to);
5523    return to_obj;
5524}
5525
5526/* escape bytea */
5527static char pgEscapeBytea__doc__[] =
5528"escape_bytea(data) -- escape binary data for use within SQL as type bytea";
5529
5530static PyObject *
5531pgEscapeBytea(PyObject *self, PyObject *data)
5532{
5533    PyObject   *tmp_obj = NULL, /* auxiliary string object */
5534               *to_obj; /* string object to return */
5535    char       *from, /* our string argument as encoded string */
5536               *to; /* the result as encoded string */
5537    Py_ssize_t  from_length; /* length of string */
5538    size_t      to_length; /* length of result */
5539    int         encoding = -1; /* client encoding */
5540
5541    if (PyBytes_Check(data))
5542    {
5543        PyBytes_AsStringAndSize(data, &from, &from_length);
5544    }
5545    else if (PyUnicode_Check(data))
5546    {
5547        encoding = pg_encoding_ascii;
5548        tmp_obj = get_encoded_string(data, encoding);
5549        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5550        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5551    }
5552    else
5553    {
5554        PyErr_SetString(PyExc_TypeError,
5555            "Method escape_bytea() expects a string as argument");
5556        return NULL;
5557    }
5558
5559    to = (char *)PQescapeBytea(
5560        (unsigned char*)from, (size_t)from_length, &to_length);
5561
5562    Py_XDECREF(tmp_obj);
5563
5564    if (encoding == -1)
5565        to_obj = PyBytes_FromStringAndSize(to, to_length - 1);
5566    else
5567        to_obj = get_decoded_string(to, to_length - 1, encoding);
5568    if (to)
5569        PQfreemem(to);
5570    return to_obj;
5571}
5572
5573/* unescape bytea */
5574static char pgUnescapeBytea__doc__[] =
5575"unescape_bytea(string) -- unescape bytea data retrieved as text";
5576
5577static PyObject *
5578pgUnescapeBytea(PyObject *self, PyObject *data)
5579{
5580    PyObject   *tmp_obj = NULL, /* auxiliary string object */
5581               *to_obj; /* string object to return */
5582    char       *from, /* our string argument as encoded string */
5583               *to; /* the result as encoded string */
5584    Py_ssize_t  from_length; /* length of string */
5585    size_t      to_length; /* length of result */
5586
5587    if (PyBytes_Check(data))
5588    {
5589        PyBytes_AsStringAndSize(data, &from, &from_length);
5590    }
5591    else if (PyUnicode_Check(data))
5592    {
5593        tmp_obj = get_encoded_string(data, pg_encoding_ascii);
5594        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
5595        PyBytes_AsStringAndSize(tmp_obj, &from, &from_length);
5596    }
5597    else
5598    {
5599        PyErr_SetString(PyExc_TypeError,
5600            "Method unescape_bytea() expects a string as argument");
5601        return NULL;
5602    }
5603
5604    to = (char *)PQunescapeBytea((unsigned char*)from, &to_length);
5605
5606    Py_XDECREF(tmp_obj);
5607
5608    if (!to) return PyErr_NoMemory();
5609
5610    to_obj = PyBytes_FromStringAndSize(to, to_length);
5611    PQfreemem(to);
5612
5613    return to_obj;
5614}
5615
5616/* set fixed datestyle */
5617static char pgSetDatestyle__doc__[] =
5618"set_datestyle(style) -- set which style is assumed";
5619
5620static PyObject *
5621pgSetDatestyle(PyObject *self, PyObject *args)
5622{
5623    const char     *datestyle = NULL;
5624
5625    /* gets arguments */
5626    if (!PyArg_ParseTuple(args, "z", &datestyle))
5627    {
5628        PyErr_SetString(PyExc_TypeError,
5629            "Function set_datestyle() expects a string or None as argument");
5630        return NULL;
5631    }
5632
5633    date_format = datestyle ? date_style_to_format(datestyle) : NULL;
5634
5635    Py_INCREF(Py_None); return Py_None;
5636}
5637
5638/* get fixed datestyle */
5639static char pgGetDatestyle__doc__[] =
5640"get_datestyle() -- get which date style is assumed";
5641
5642static PyObject *
5643pgGetDatestyle(PyObject *self, PyObject *noargs)
5644{
5645    if (date_format)
5646    {
5647        return PyStr_FromString(date_format_to_style(date_format));
5648    }
5649    else
5650    {
5651        Py_INCREF(Py_None); return Py_None;
5652    }
5653}
5654
5655/* get decimal point */
5656static char pgGetDecimalPoint__doc__[] =
5657"get_decimal_point() -- get decimal point to be used for money values";
5658
5659static PyObject *
5660pgGetDecimalPoint(PyObject *self, PyObject *noargs)
5661{
5662    PyObject *ret;
5663    char s[2];
5664
5665    if (decimal_point)
5666    {
5667        s[0] = decimal_point; s[1] = '\0';
5668        ret = PyStr_FromString(s);
5669    }
5670    else
5671    {
5672        Py_INCREF(Py_None); ret = Py_None;
5673    }
5674
5675    return ret;
5676}
5677
5678/* set decimal point */
5679static char pgSetDecimalPoint__doc__[] =
5680"set_decimal_point(char) -- set decimal point to be used for money values";
5681
5682static PyObject *
5683pgSetDecimalPoint(PyObject *self, PyObject *args)
5684{
5685    PyObject *ret = NULL;
5686    char *s = NULL;
5687
5688    /* gets arguments */
5689    if (PyArg_ParseTuple(args, "z", &s))
5690    {
5691        if (!s)
5692            s = "\0";
5693        else if (*s && (*(s+1) || !strchr(".,;: '*/_`|", *s)))
5694            s = NULL;
5695    }
5696
5697    if (s)
5698    {
5699        decimal_point = *s;
5700        Py_INCREF(Py_None); ret = Py_None;
5701    }
5702    else
5703        PyErr_SetString(PyExc_TypeError,
5704            "Function set_decimal_mark() expects"
5705            " a decimal mark character as argument");
5706
5707    return ret;
5708}
5709
5710/* get decimal type */
5711static char pgGetDecimal__doc__[] =
5712"get_decimal() -- get the decimal type to be used for numeric values";
5713
5714static PyObject *
5715pgGetDecimal(PyObject *self, PyObject *noargs)
5716{
5717    PyObject *ret;
5718
5719    ret = decimal ? decimal : Py_None;
5720    Py_INCREF(ret);
5721
5722    return ret;
5723}
5724
5725/* set decimal type */
5726static char pgSetDecimal__doc__[] =
5727"set_decimal(cls) -- set a decimal type to be used for numeric values";
5728
5729static PyObject *
5730pgSetDecimal(PyObject *self, PyObject *cls)
5731{
5732    PyObject *ret = NULL;
5733
5734    if (cls == Py_None)
5735    {
5736        Py_XDECREF(decimal); decimal = NULL;
5737        Py_INCREF(Py_None); ret = Py_None;
5738    }
5739    else if (PyCallable_Check(cls))
5740    {
5741        Py_XINCREF(cls); Py_XDECREF(decimal); decimal = cls;
5742        Py_INCREF(Py_None); ret = Py_None;
5743    }
5744    else
5745        PyErr_SetString(PyExc_TypeError,
5746            "Function set_decimal() expects"
5747             " a callable or None as argument");
5748
5749    return ret;
5750}
5751
5752/* get usage of bool values */
5753static char pgGetBool__doc__[] =
5754"get_bool() -- check whether boolean values are converted to bool";
5755
5756static PyObject *
5757pgGetBool(PyObject *self, PyObject *noargs)
5758{
5759    PyObject *ret;
5760
5761    ret = bool_as_text ? Py_False : Py_True;
5762    Py_INCREF(ret);
5763
5764    return ret;
5765}
5766
5767/* set usage of bool values */
5768static char pgSetBool__doc__[] =
5769"set_bool(on) -- set whether boolean values should be converted to bool";
5770
5771static PyObject *
5772pgSetBool(PyObject *self, PyObject *args)
5773{
5774    PyObject *ret = NULL;
5775    int         i;
5776
5777    /* gets arguments */
5778    if (PyArg_ParseTuple(args, "i", &i))
5779    {
5780        bool_as_text = i ? 0 : 1;
5781        Py_INCREF(Py_None); ret = Py_None;
5782    }
5783    else
5784        PyErr_SetString(PyExc_TypeError,
5785            "Function set_bool() expects a boolean value as argument");
5786
5787    return ret;
5788}
5789
5790/* get conversion of arrays to lists */
5791static char pgGetArray__doc__[] =
5792"get_array() -- check whether arrays are converted as lists";
5793
5794static PyObject *
5795pgGetArray(PyObject *self, PyObject *noargs)
5796{
5797    PyObject *ret;
5798
5799    ret = array_as_text ? Py_False : Py_True;
5800    Py_INCREF(ret);
5801
5802    return ret;
5803}
5804
5805/* set conversion of arrays to lists */
5806static char pgSetArray__doc__[] =
5807"set_array(on) -- set whether arrays should be converted to lists";
5808
5809static PyObject *
5810pgSetArray(PyObject *self, PyObject *args)
5811{
5812    PyObject *ret = NULL;
5813    int         i;
5814
5815    /* gets arguments */
5816    if (PyArg_ParseTuple(args, "i", &i))
5817    {
5818        array_as_text = i ? 0 : 1;
5819        Py_INCREF(Py_None); ret = Py_None;
5820    }
5821    else
5822        PyErr_SetString(PyExc_TypeError,
5823            "Function set_array() expects a boolean value as argument");
5824
5825    return ret;
5826}
5827
5828/* check whether bytea values are unescaped */
5829static char pgGetByteaEscaped__doc__[] =
5830"get_bytea_escaped() -- check whether bytea will be returned escaped";
5831
5832static PyObject *
5833pgGetByteaEscaped(PyObject *self, PyObject *noargs)
5834{
5835    PyObject *ret;
5836
5837    ret = bytea_escaped ? Py_True : Py_False;
5838    Py_INCREF(ret);
5839
5840    return ret;
5841}
5842
5843/* set usage of bool values */
5844static char pgSetByteaEscaped__doc__[] =
5845"set_bytea_escaped(on) -- set whether bytea will be returned escaped";
5846
5847static PyObject *
5848pgSetByteaEscaped(PyObject *self, PyObject *args)
5849{
5850    PyObject *ret = NULL;
5851    int         i;
5852
5853    /* gets arguments */
5854    if (PyArg_ParseTuple(args, "i", &i))
5855    {
5856        bytea_escaped = i ? 1 : 0;
5857        Py_INCREF(Py_None); ret = Py_None;
5858    }
5859    else
5860        PyErr_SetString(PyExc_TypeError,
5861            "Function set_bytea_escaped() expects a boolean value as argument");
5862
5863    return ret;
5864}
5865
5866/* set query helper functions */
5867
5868static char pgSetQueryHelpers__doc__[] =
5869"set_query_helpers(*helpers) -- set internal query helper functions";
5870
5871static PyObject *
5872pgSetQueryHelpers(PyObject *self, PyObject *args)
5873{
5874    /* gets arguments */
5875    if (!PyArg_ParseTuple(args, "O!O!O!O!",
5876        &PyFunction_Type, &dictiter,
5877        &PyFunction_Type, &namediter,
5878        &PyFunction_Type, &namednext,
5879        &PyFunction_Type, &scalariter)) return NULL;
5880
5881    Py_INCREF(Py_None);
5882    return Py_None;
5883}
5884
5885/* get json decode function */
5886static char pgGetJsondecode__doc__[] =
5887"get_jsondecode() -- get the function used for decoding json results";
5888
5889static PyObject *
5890pgGetJsondecode(PyObject *self, PyObject *noargs)
5891{
5892    PyObject *ret;
5893
5894    ret = jsondecode;
5895    if (!ret)
5896        ret = Py_None;
5897    Py_INCREF(ret);
5898
5899    return ret;
5900}
5901
5902/* set json decode function */
5903static char pgSetJsondecode__doc__[] =
5904"set_jsondecode(func) -- set a function to be used for decoding json results";
5905
5906static PyObject *
5907pgSetJsondecode(PyObject *self, PyObject *func)
5908{
5909    PyObject *ret = NULL;
5910
5911    if (func == Py_None)
5912    {
5913        Py_XDECREF(jsondecode); jsondecode = NULL;
5914        Py_INCREF(Py_None); ret = Py_None;
5915    }
5916    else if (PyCallable_Check(func))
5917    {
5918        Py_XINCREF(func); Py_XDECREF(jsondecode); jsondecode = func;
5919        Py_INCREF(Py_None); ret = Py_None;
5920    }
5921    else
5922        PyErr_SetString(PyExc_TypeError,
5923            "Function jsondecode() expects"
5924             " a callable or None as argument");
5925
5926    return ret;
5927}
5928
5929#ifdef DEFAULT_VARS
5930
5931/* gets default host */
5932static char pgGetDefHost__doc__[] =
5933"get_defhost() -- return default database host";
5934
5935static PyObject *
5936pgGetDefHost(PyObject *self, PyObject *noargs)
5937{
5938    Py_XINCREF(pg_default_host);
5939    return pg_default_host;
5940}
5941
5942/* sets default host */
5943static char pgSetDefHost__doc__[] =
5944"set_defhost(string) -- set default database host and return previous value";
5945
5946static PyObject *
5947pgSetDefHost(PyObject *self, PyObject *args)
5948{
5949    char       *temp = NULL;
5950    PyObject   *old;
5951
5952    /* gets arguments */
5953    if (!PyArg_ParseTuple(args, "z", &temp))
5954    {
5955        PyErr_SetString(PyExc_TypeError,
5956            "Function set_defhost() expects a string or None as argument");
5957        return NULL;
5958    }
5959
5960    /* adjusts value */
5961    old = pg_default_host;
5962
5963    if (temp)
5964        pg_default_host = PyStr_FromString(temp);
5965    else
5966    {
5967        Py_INCREF(Py_None);
5968        pg_default_host = Py_None;
5969    }
5970
5971    return old;
5972}
5973
5974/* gets default base */
5975static char pgGetDefBase__doc__[] =
5976"get_defbase() -- return default database name";
5977
5978static PyObject *
5979pgGetDefBase(PyObject *self, PyObject *noargs)
5980{
5981    Py_XINCREF(pg_default_base);
5982    return pg_default_base;
5983}
5984
5985/* sets default base */
5986static char pgSetDefBase__doc__[] =
5987"set_defbase(string) -- set default database name and return previous value";
5988
5989static PyObject *
5990pgSetDefBase(PyObject *self, PyObject *args)
5991{
5992    char       *temp = NULL;
5993    PyObject   *old;
5994
5995    /* gets arguments */
5996    if (!PyArg_ParseTuple(args, "z", &temp))
5997    {
5998        PyErr_SetString(PyExc_TypeError,
5999            "Function set_defbase() Argument a string or None as argument");
6000        return NULL;
6001    }
6002
6003    /* adjusts value */
6004    old = pg_default_base;
6005
6006    if (temp)
6007        pg_default_base = PyStr_FromString(temp);
6008    else
6009    {
6010        Py_INCREF(Py_None);
6011        pg_default_base = Py_None;
6012    }
6013
6014    return old;
6015}
6016
6017/* gets default options */
6018static char pgGetDefOpt__doc__[] =
6019"get_defopt() -- return default database options";
6020
6021static PyObject *
6022pgGetDefOpt(PyObject *self, PyObject *noargs)
6023{
6024    Py_XINCREF(pg_default_opt);
6025    return pg_default_opt;
6026}
6027
6028/* sets default opt */
6029static char pgSetDefOpt__doc__[] =
6030"set_defopt(string) -- set default options and return previous value";
6031
6032static PyObject *
6033pgSetDefOpt(PyObject *self, PyObject *args)
6034{
6035    char       *temp = NULL;
6036    PyObject   *old;
6037
6038    /* gets arguments */
6039    if (!PyArg_ParseTuple(args, "z", &temp))
6040    {
6041        PyErr_SetString(PyExc_TypeError,
6042            "Function set_defopt() expects a string or None as argument");
6043        return NULL;
6044    }
6045
6046    /* adjusts value */
6047    old = pg_default_opt;
6048
6049    if (temp)
6050        pg_default_opt = PyStr_FromString(temp);
6051    else
6052    {
6053        Py_INCREF(Py_None);
6054        pg_default_opt = Py_None;
6055    }
6056
6057    return old;
6058}
6059
6060/* gets default username */
6061static char pgGetDefUser__doc__[] =
6062"get_defuser() -- return default database username";
6063
6064static PyObject *
6065pgGetDefUser(PyObject *self, PyObject *noargs)
6066{
6067    Py_XINCREF(pg_default_user);
6068    return pg_default_user;
6069}
6070
6071/* sets default username */
6072
6073static char pgSetDefUser__doc__[] =
6074"set_defuser(name) -- set default username and return previous value";
6075
6076static PyObject *
6077pgSetDefUser(PyObject *self, PyObject *args)
6078{
6079    char       *temp = NULL;
6080    PyObject   *old;
6081
6082    /* gets arguments */
6083    if (!PyArg_ParseTuple(args, "z", &temp))
6084    {
6085        PyErr_SetString(PyExc_TypeError,
6086            "Function set_defuser() expects a string or None as argument");
6087        return NULL;
6088    }
6089
6090    /* adjusts value */
6091    old = pg_default_user;
6092
6093    if (temp)
6094        pg_default_user = PyStr_FromString(temp);
6095    else
6096    {
6097        Py_INCREF(Py_None);
6098        pg_default_user = Py_None;
6099    }
6100
6101    return old;
6102}
6103
6104/* sets default password */
6105static char pgSetDefPassword__doc__[] =
6106"set_defpasswd(password) -- set default database password";
6107
6108static PyObject *
6109pgSetDefPassword(PyObject *self, PyObject *args)
6110{
6111    char       *temp = NULL;
6112
6113    /* gets arguments */
6114    if (!PyArg_ParseTuple(args, "z", &temp))
6115    {
6116        PyErr_SetString(PyExc_TypeError,
6117            "Function set_defpasswd() expects a string or None as argument");
6118        return NULL;
6119    }
6120
6121    if (temp)
6122        pg_default_passwd = PyStr_FromString(temp);
6123    else
6124    {
6125        Py_INCREF(Py_None);
6126        pg_default_passwd = Py_None;
6127    }
6128
6129    Py_INCREF(Py_None);
6130    return Py_None;
6131}
6132
6133/* gets default port */
6134static char pgGetDefPort__doc__[] =
6135"get_defport() -- return default database port";
6136
6137static PyObject *
6138pgGetDefPort(PyObject *self, PyObject *noargs)
6139{
6140    Py_XINCREF(pg_default_port);
6141    return pg_default_port;
6142}
6143
6144/* sets default port */
6145static char pgSetDefPort__doc__[] =
6146"set_defport(port) -- set default port and return previous value";
6147
6148static PyObject *
6149pgSetDefPort(PyObject *self, PyObject *args)
6150{
6151    long int    port = -2;
6152    PyObject   *old;
6153
6154    /* gets arguments */
6155    if ((!PyArg_ParseTuple(args, "l", &port)) || (port < -1))
6156    {
6157        PyErr_SetString(PyExc_TypeError,
6158            "Function set_deport expects"
6159             " a positive integer or -1 as argument");
6160        return NULL;
6161    }
6162
6163    /* adjusts value */
6164    old = pg_default_port;
6165
6166    if (port != -1)
6167        pg_default_port = PyInt_FromLong(port);
6168    else
6169    {
6170        Py_INCREF(Py_None);
6171        pg_default_port = Py_None;
6172    }
6173
6174    return old;
6175}
6176#endif /* DEFAULT_VARS */
6177
6178/* cast a string with a text representation of an array to a list */
6179static char pgCastArray__doc__[] =
6180"cast_array(string, cast=None, delim=',') -- cast a string as an array";
6181
6182PyObject *
6183pgCastArray(PyObject *self, PyObject *args, PyObject *dict)
6184{
6185    static const char *kwlist[] = {"string", "cast", "delim", NULL};
6186    PyObject   *string_obj, *cast_obj = NULL, *ret;
6187    char       *string, delim = ',';
6188    Py_ssize_t  size;
6189    int         encoding;
6190
6191    if (!PyArg_ParseTupleAndKeywords(args, dict, "O|Oc",
6192            (char **) kwlist, &string_obj, &cast_obj, &delim))
6193        return NULL;
6194
6195    if (PyBytes_Check(string_obj))
6196    {
6197        PyBytes_AsStringAndSize(string_obj, &string, &size);
6198        string_obj = NULL;
6199        encoding = pg_encoding_ascii;
6200    }
6201    else if (PyUnicode_Check(string_obj))
6202    {
6203        string_obj = PyUnicode_AsUTF8String(string_obj);
6204        if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
6205        PyBytes_AsStringAndSize(string_obj, &string, &size);
6206        encoding = pg_encoding_utf8;
6207    }
6208    else
6209    {
6210        PyErr_SetString(PyExc_TypeError,
6211            "Function cast_array() expects a string as first argument");
6212        return NULL;
6213    }
6214
6215    if (!cast_obj || cast_obj == Py_None)
6216    {
6217        if (cast_obj)
6218        {
6219            Py_DECREF(cast_obj); cast_obj = NULL;
6220        }
6221    }
6222    else if (!PyCallable_Check(cast_obj))
6223    {
6224        PyErr_SetString(PyExc_TypeError,
6225            "Function cast_array() expects a callable as second argument");
6226        return NULL;
6227    }
6228
6229    ret = cast_array(string, size, encoding, 0, cast_obj, delim);
6230
6231    Py_XDECREF(string_obj);
6232
6233    return ret;
6234}
6235
6236/* cast a string with a text representation of a record to a tuple */
6237static char pgCastRecord__doc__[] =
6238"cast_record(string, cast=None, delim=',') -- cast a string as a record";
6239
6240PyObject *
6241pgCastRecord(PyObject *self, PyObject *args, PyObject *dict)
6242{
6243    static const char *kwlist[] = {"string", "cast", "delim", NULL};
6244    PyObject   *string_obj, *cast_obj = NULL, *ret;
6245    char       *string, delim = ',';
6246    Py_ssize_t  size, len;
6247    int         encoding;
6248
6249    if (!PyArg_ParseTupleAndKeywords(args, dict, "O|Oc",
6250            (char **) kwlist, &string_obj, &cast_obj, &delim))
6251        return NULL;
6252
6253    if (PyBytes_Check(string_obj))
6254    {
6255        PyBytes_AsStringAndSize(string_obj, &string, &size);
6256        string_obj = NULL;
6257        encoding = pg_encoding_ascii;
6258    }
6259    else if (PyUnicode_Check(string_obj))
6260    {
6261        string_obj = PyUnicode_AsUTF8String(string_obj);
6262        if (!string_obj) return NULL; /* pass the UnicodeEncodeError */
6263        PyBytes_AsStringAndSize(string_obj, &string, &size);
6264        encoding = pg_encoding_utf8;
6265    }
6266    else
6267    {
6268        PyErr_SetString(PyExc_TypeError,
6269            "Function cast_record() expects a string as first argument");
6270        return NULL;
6271    }
6272
6273    if (!cast_obj || PyCallable_Check(cast_obj))
6274    {
6275        len = 0;
6276    }
6277    else if (cast_obj == Py_None)
6278    {
6279        Py_DECREF(cast_obj); cast_obj = NULL; len = 0;
6280    }
6281    else if (PyTuple_Check(cast_obj) || PyList_Check(cast_obj))
6282    {
6283        len = PySequence_Size(cast_obj);
6284        if (!len)
6285        {
6286            Py_DECREF(cast_obj); cast_obj = NULL;
6287        }
6288    }
6289    else
6290    {
6291        PyErr_SetString(PyExc_TypeError,
6292            "Function cast_record() expects a callable"
6293             " or tuple or list of callables as second argument");
6294        return NULL;
6295    }
6296
6297    ret = cast_record(string, size, encoding, 0, cast_obj, len, delim);
6298
6299    Py_XDECREF(string_obj);
6300
6301    return ret;
6302}
6303
6304/* cast a string with a text representation of an hstore to a dict */
6305static char pgCastHStore__doc__[] =
6306"cast_hstore(string) -- cast a string as an hstore";
6307
6308PyObject *
6309pgCastHStore(PyObject *self, PyObject *string)
6310{
6311    PyObject   *tmp_obj = NULL, *ret;
6312    char       *s;
6313    Py_ssize_t  size;
6314    int         encoding;
6315
6316    if (PyBytes_Check(string))
6317    {
6318        PyBytes_AsStringAndSize(string, &s, &size);
6319        encoding = pg_encoding_ascii;
6320    }
6321    else if (PyUnicode_Check(string))
6322    {
6323        tmp_obj = PyUnicode_AsUTF8String(string);
6324        if (!tmp_obj) return NULL; /* pass the UnicodeEncodeError */
6325        PyBytes_AsStringAndSize(tmp_obj, &s, &size);
6326        encoding = pg_encoding_utf8;
6327    }
6328    else
6329    {
6330        PyErr_SetString(PyExc_TypeError,
6331            "Function cast_hstore() expects a string as first argument");
6332        return NULL;
6333    }
6334
6335    ret = cast_hstore(s, size, encoding);
6336
6337    Py_XDECREF(tmp_obj);
6338
6339    return ret;
6340}
6341
6342/* List of functions defined in the module */
6343
6344static struct PyMethodDef pgMethods[] = {
6345    {"connect", (PyCFunction) pgConnect, METH_VARARGS|METH_KEYWORDS,
6346            pgConnect__doc__},
6347    {"escape_string", (PyCFunction) pgEscapeString, METH_O,
6348            pgEscapeString__doc__},
6349    {"escape_bytea", (PyCFunction) pgEscapeBytea, METH_O,
6350            pgEscapeBytea__doc__},
6351    {"unescape_bytea", (PyCFunction) pgUnescapeBytea, METH_O,
6352            pgUnescapeBytea__doc__},
6353    {"get_datestyle", (PyCFunction) pgGetDatestyle, METH_NOARGS,
6354            pgGetDatestyle__doc__},
6355    {"set_datestyle", (PyCFunction) pgSetDatestyle, METH_VARARGS,
6356            pgSetDatestyle__doc__},
6357    {"get_decimal_point", (PyCFunction) pgGetDecimalPoint, METH_NOARGS,
6358            pgGetDecimalPoint__doc__},
6359    {"set_decimal_point", (PyCFunction) pgSetDecimalPoint, METH_VARARGS,
6360            pgSetDecimalPoint__doc__},
6361    {"get_decimal", (PyCFunction) pgGetDecimal, METH_NOARGS,
6362            pgGetDecimal__doc__},
6363    {"set_decimal", (PyCFunction) pgSetDecimal, METH_O,
6364            pgSetDecimal__doc__},
6365    {"get_bool", (PyCFunction) pgGetBool, METH_NOARGS, pgGetBool__doc__},
6366    {"set_bool", (PyCFunction) pgSetBool, METH_VARARGS, pgSetBool__doc__},
6367    {"get_array", (PyCFunction) pgGetArray, METH_NOARGS, pgGetArray__doc__},
6368    {"set_array", (PyCFunction) pgSetArray, METH_VARARGS, pgSetArray__doc__},
6369    {"set_query_helpers", (PyCFunction) pgSetQueryHelpers, METH_VARARGS,
6370            pgSetQueryHelpers__doc__},
6371    {"get_bytea_escaped", (PyCFunction) pgGetByteaEscaped, METH_NOARGS,
6372        pgGetByteaEscaped__doc__},
6373    {"set_bytea_escaped", (PyCFunction) pgSetByteaEscaped, METH_VARARGS,
6374        pgSetByteaEscaped__doc__},
6375    {"get_jsondecode", (PyCFunction) pgGetJsondecode, METH_NOARGS,
6376            pgGetJsondecode__doc__},
6377    {"set_jsondecode", (PyCFunction) pgSetJsondecode, METH_O,
6378            pgSetJsondecode__doc__},
6379    {"cast_array", (PyCFunction) pgCastArray, METH_VARARGS|METH_KEYWORDS,
6380            pgCastArray__doc__},
6381    {"cast_record", (PyCFunction) pgCastRecord, METH_VARARGS|METH_KEYWORDS,
6382            pgCastRecord__doc__},
6383    {"cast_hstore", (PyCFunction) pgCastHStore, METH_O, pgCastHStore__doc__},
6384
6385#ifdef DEFAULT_VARS
6386    {"get_defhost", pgGetDefHost, METH_NOARGS, pgGetDefHost__doc__},
6387    {"set_defhost", pgSetDefHost, METH_VARARGS, pgSetDefHost__doc__},
6388    {"get_defbase", pgGetDefBase, METH_NOARGS, pgGetDefBase__doc__},
6389    {"set_defbase", pgSetDefBase, METH_VARARGS, pgSetDefBase__doc__},
6390    {"get_defopt", pgGetDefOpt, METH_NOARGS, pgGetDefOpt__doc__},
6391    {"set_defopt", pgSetDefOpt, METH_VARARGS, pgSetDefOpt__doc__},
6392    {"get_defport", pgGetDefPort, METH_NOARGS, pgGetDefPort__doc__},
6393    {"set_defport", pgSetDefPort, METH_VARARGS, pgSetDefPort__doc__},
6394    {"get_defuser", pgGetDefUser, METH_NOARGS, pgGetDefUser__doc__},
6395    {"set_defuser", pgSetDefUser, METH_VARARGS, pgSetDefUser__doc__},
6396    {"set_defpasswd", pgSetDefPassword, METH_VARARGS, pgSetDefPassword__doc__},
6397#endif /* DEFAULT_VARS */
6398    {NULL, NULL} /* sentinel */
6399};
6400
6401static char pg__doc__[] = "Python interface to PostgreSQL DB";
6402
6403static struct PyModuleDef moduleDef = {
6404    PyModuleDef_HEAD_INIT,
6405    "_pg",      /* m_name */
6406    pg__doc__,  /* m_doc */
6407    -1,         /* m_size */
6408    pgMethods   /* m_methods */
6409};
6410
6411/* Initialization function for the module */
6412MODULE_INIT_FUNC(_pg)
6413{
6414    PyObject   *mod, *dict, *s;
6415
6416    /* Create the module and add the functions */
6417
6418    mod = PyModule_Create(&moduleDef);
6419
6420    /* Initialize here because some Windows platforms get confused otherwise */
6421#if IS_PY3
6422    connType.tp_base = noticeType.tp_base =
6423        queryType.tp_base = sourceType.tp_base = &PyBaseObject_Type;
6424#ifdef LARGE_OBJECTS
6425    largeType.tp_base = &PyBaseObject_Type;
6426#endif
6427#else
6428    connType.ob_type = noticeType.ob_type =
6429        queryType.ob_type = sourceType.ob_type = &PyType_Type;
6430#ifdef LARGE_OBJECTS
6431    largeType.ob_type = &PyType_Type;
6432#endif
6433#endif
6434
6435    if (PyType_Ready(&connType)
6436        || PyType_Ready(&noticeType)
6437        || PyType_Ready(&queryType)
6438        || PyType_Ready(&sourceType)
6439#ifdef LARGE_OBJECTS
6440        || PyType_Ready(&largeType)
6441#endif
6442        ) return NULL;
6443
6444    dict = PyModule_GetDict(mod);
6445
6446    /* Exceptions as defined by DB-API 2.0 */
6447    Error = PyErr_NewException("pg.Error", PyExc_Exception, NULL);
6448    PyDict_SetItemString(dict, "Error", Error);
6449
6450    Warning = PyErr_NewException("pg.Warning", PyExc_Exception, NULL);
6451    PyDict_SetItemString(dict, "Warning", Warning);
6452
6453    InterfaceError = PyErr_NewException("pg.InterfaceError", Error, NULL);
6454    PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
6455
6456    DatabaseError = PyErr_NewException("pg.DatabaseError", Error, NULL);
6457    PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
6458
6459    InternalError = PyErr_NewException("pg.InternalError", DatabaseError, NULL);
6460    PyDict_SetItemString(dict, "InternalError", InternalError);
6461
6462    OperationalError =
6463        PyErr_NewException("pg.OperationalError", DatabaseError, NULL);
6464    PyDict_SetItemString(dict, "OperationalError", OperationalError);
6465
6466    ProgrammingError =
6467        PyErr_NewException("pg.ProgrammingError", DatabaseError, NULL);
6468    PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
6469
6470    IntegrityError =
6471        PyErr_NewException("pg.IntegrityError", DatabaseError, NULL);
6472    PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
6473
6474    DataError = PyErr_NewException("pg.DataError", DatabaseError, NULL);
6475    PyDict_SetItemString(dict, "DataError", DataError);
6476
6477    NotSupportedError =
6478        PyErr_NewException("pg.NotSupportedError", DatabaseError, NULL);
6479    PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
6480
6481    /* Make the version available */
6482    s = PyStr_FromString(PyPgVersion);
6483    PyDict_SetItemString(dict, "version", s);
6484    PyDict_SetItemString(dict, "__version__", s);
6485    Py_DECREF(s);
6486
6487    /* results type for queries */
6488    PyDict_SetItemString(dict, "RESULT_EMPTY", PyInt_FromLong(RESULT_EMPTY));
6489    PyDict_SetItemString(dict, "RESULT_DML", PyInt_FromLong(RESULT_DML));
6490    PyDict_SetItemString(dict, "RESULT_DDL", PyInt_FromLong(RESULT_DDL));
6491    PyDict_SetItemString(dict, "RESULT_DQL", PyInt_FromLong(RESULT_DQL));
6492
6493    /* transaction states */
6494    PyDict_SetItemString(dict,"TRANS_IDLE",PyInt_FromLong(PQTRANS_IDLE));
6495    PyDict_SetItemString(dict,"TRANS_ACTIVE",PyInt_FromLong(PQTRANS_ACTIVE));
6496    PyDict_SetItemString(dict,"TRANS_INTRANS",PyInt_FromLong(PQTRANS_INTRANS));
6497    PyDict_SetItemString(dict,"TRANS_INERROR",PyInt_FromLong(PQTRANS_INERROR));
6498    PyDict_SetItemString(dict,"TRANS_UNKNOWN",PyInt_FromLong(PQTRANS_UNKNOWN));
6499
6500#ifdef LARGE_OBJECTS
6501    /* create mode for large objects */
6502    PyDict_SetItemString(dict, "INV_READ", PyInt_FromLong(INV_READ));
6503    PyDict_SetItemString(dict, "INV_WRITE", PyInt_FromLong(INV_WRITE));
6504
6505    /* position flags for lo_lseek */
6506    PyDict_SetItemString(dict, "SEEK_SET", PyInt_FromLong(SEEK_SET));
6507    PyDict_SetItemString(dict, "SEEK_CUR", PyInt_FromLong(SEEK_CUR));
6508    PyDict_SetItemString(dict, "SEEK_END", PyInt_FromLong(SEEK_END));
6509#endif /* LARGE_OBJECTS */
6510
6511#ifdef DEFAULT_VARS
6512    /* prepares default values */
6513    Py_INCREF(Py_None);
6514    pg_default_host = Py_None;
6515    Py_INCREF(Py_None);
6516    pg_default_base = Py_None;
6517    Py_INCREF(Py_None);
6518    pg_default_opt = Py_None;
6519    Py_INCREF(Py_None);
6520    pg_default_port = Py_None;
6521    Py_INCREF(Py_None);
6522    pg_default_user = Py_None;
6523    Py_INCREF(Py_None);
6524    pg_default_passwd = Py_None;
6525#endif /* DEFAULT_VARS */
6526
6527    /* store common pg encoding ids */
6528
6529    pg_encoding_utf8 = pg_char_to_encoding("UTF8");
6530    pg_encoding_latin1 = pg_char_to_encoding("LATIN1");
6531    pg_encoding_ascii = pg_char_to_encoding("SQL_ASCII");
6532
6533    /* Check for errors */
6534    if (PyErr_Occurred())
6535        return NULL;
6536
6537    return mod;
6538}
Note: See TracBrowser for help on using the repository browser.