Changeset 981 for trunk


Ignore:
Timestamp:
Apr 22, 2019, 11:40:02 AM (3 months ago)
Author:
cito
Message:

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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/pgmodule.c

    r980 r981  
    4242
    4343static PyObject *Error, *Warning, *InterfaceError,
    44         *DatabaseError, *InternalError, *OperationalError, *ProgrammingError,
    45         *IntegrityError, *DataError, *NotSupportedError;
     44    *DatabaseError, *InternalError, *OperationalError, *ProgrammingError,
     45    *IntegrityError, *DataError, *NotSupportedError;
    4646
    4747#define _TOSTRING(x) #x
     
    5454
    5555/* default values */
    56 #define PG_ARRAYSIZE            1
     56#define PG_ARRAYSIZE        1
    5757
    5858/* 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
     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
    6464
    6565/* query result types */
    66 #define RESULT_EMPTY            1
    67 #define RESULT_DML                      2
    68 #define RESULT_DDL                      3
    69 #define RESULT_DQL                      4
     66#define RESULT_EMPTY        1
     67#define RESULT_DML          2
     68#define RESULT_DDL          3
     69#define RESULT_DQL          4
    7070
    7171/* 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 */
     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 */
    7979
    8080/* MODULE GLOBAL VARIABLES */
    8181
    8282#ifdef DEFAULT_VARS
    83 static PyObject *pg_default_host;       /* default database host */
    84 static PyObject *pg_default_base;       /* default database name */
    85 static PyObject *pg_default_opt;        /* default connection options */
    86 static PyObject *pg_default_port;       /* default connection port */
    87 static PyObject *pg_default_user;       /* default username */
    88 static PyObject *pg_default_passwd;     /* default password */
    89 #endif  /* 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 */
    9090
    9191static 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 */
     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 */
    9797static const char *date_format = NULL; /* date format that is always assumed */
    9898static char decimal_point = '.'; /* decimal point used in money values */
     
    138138
    139139/* --------------------------------------------------------------------- */
    140 /* Object declarations                                                                                                  */
     140/* Object declarations                                                  */
    141141/* --------------------------------------------------------------------- */
    142142typedef struct
    143143{
    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;
     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;
    151151#define is_connObject(v) (PyType(v) == &connType)
    152152
    153153typedef struct
    154154{
    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;
     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;
    166166#define is_sourceObject(v) (PyType(v) == &sourceType)
    167167
    168168typedef struct
    169169{
    170         PyObject_HEAD
    171         connObject *pgcnx;                      /* parent connection object */
    172         PGresult        const *res;             /* an error or warning */
    173 }       noticeObject;
     170    PyObject_HEAD
     171    connObject *pgcnx;          /* parent connection object */
     172    PGresult    const *res;     /* an error or warning */
     173}   noticeObject;
    174174#define is_noticeObject(v) (PyType(v) == &noticeType)
    175175
    176176typedef struct
    177177{
    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;
     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;
    187187#define is_queryObject(v) (PyType(v) == &queryType)
    188188
     
    190190typedef struct
    191191{
    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;
     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;
    197197#define is_largeObject(v) (PyType(v) == &largeType)
    198198#endif /* LARGE_OBJECTS */
     
    216216
    217217/* --------------------------------------------------------------------- */
    218 /* Internal Functions                                                                                                    */
     218/* Internal Functions                                                    */
    219219/* --------------------------------------------------------------------- */
    220220
     
    224224get_decoded_string(const char *str, Py_ssize_t size, int encoding)
    225225{
    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");
     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");
    235235}
    236236
     
    238238get_encoded_string(PyObject *unicode_obj, int encoding)
    239239{
    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");
     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");
    249249}
    250250
     
    255255get_type(Oid pgtype)
    256256{
    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;
     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;
    367367}
    368368
     
    371371get_col_types(PGresult *result, int nfields)
    372372{
    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;
     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;
    382382}
    383383
     
    387387cast_bytea_text(char *s)
    388388{
    389         PyObject   *obj;
    390         char       *tmp_str;
    391         size_t          str_len;
     389    PyObject   *obj;
     390    char       *tmp_str;
     391    size_t      str_len;
    392392
    393393    /* 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;
     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;
    399399}
    400400
     
    404404cast_sized_text(char *s, Py_ssize_t size, int encoding, int type)
    405405{
    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 */
     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 */
    439439#if IS_PY3
    440                         obj = get_decoded_string(s, size, encoding);
    441                         if (!obj) /* cannot decode */
     440            obj = get_decoded_string(s, size, encoding);
     441            if (!obj) /* cannot decode */
    442442#endif
    443                         obj = PyBytes_FromStringAndSize(s, size);
    444         }
    445 
    446         return obj;
     443            obj = PyBytes_FromStringAndSize(s, size);
     444    }
     445
     446    return obj;
    447447}
    448448
     
    452452static PyObject *
    453453cast_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;
     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;
    467467}
    468468
     
    472472cast_sized_simple(char *s, Py_ssize_t size, int type)
    473473{
    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;
     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;
    554554}
    555555
     
    559559cast_unsized_simple(char *s, int type)
    560560{
    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;
     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;
    628628}
    629629
    630630/* quick case insensitive check if given sized string is null */
    631631#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'))
     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'))
    636636
    637637/* Cast string s with size and encoding to a Python list,
     
    642642static PyObject *
    643643cast_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                                 {
     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                {
    828828#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 */
     829                    element = encoding == pg_encoding_ascii ? NULL :
     830                        get_decoded_string(estr, esize, encoding);
     831                    if (!element) /* no decoding necessary or possible */
    832832#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;
     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;
    892892}
    893893
     
    901901static PyObject *
    902902cast_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                         {
     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            {
    10081008#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 */
     1009                element = encoding == pg_encoding_ascii ? NULL :
     1010                    get_decoded_string(estr, esize, encoding);
     1011                if (!element) /* no decoding necessary or possible */
    10121012#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;
     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;
    10841084}
    10851085
     
    10901090cast_hstore(char *s, Py_ssize_t size, int encoding)
    10911091{
    1092         PyObject   *result;
    1093         char       *end = s + size;
     1092    PyObject   *result;
     1093    char       *end = s + size;
    10941094
    10951095    result = PyDict_New();
    10961096
    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;
     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;
    12761276}
    12771277
     
    12801280notice_receiver(void *arg, const PGresult *res)
    12811281{
    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);
     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);
    13041304}
    13051305
     
    13081308get_error_type(const char *sqlstate)
    13091309{
    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;
     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;
    13741374}
    13751375
     
    13771377static void
    13781378set_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;
     1379    const char *msg, int encoding, const char *sqlstate)
     1380{
     1381    PyObject   *err_obj, *msg_obj, *sql_obj = NULL;
    13821382
    13831383#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 */
     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 */
    13911391#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         }
     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    }
    14141414}
    14151415
     
    14181418set_error_msg(PyObject *type, const char *msg)
    14191419{
    1420         set_error_msg_and_state(type, msg, pg_encoding_ascii, NULL);
     1420    set_error_msg_and_state(type, msg, pg_encoding_ascii, NULL);
    14211421}
    14221422
     
    14251425set_error(PyObject *type, const char * msg, PGconn *cnx, PGresult *result)
    14261426{
    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);
     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);
    14451445}
    14461446
     
    14491449check_cnx_obj(connObject *self)
    14501450{
    1451         if (!self || !self->valid || !self->cnx)
    1452         {
    1453                 set_error_msg(OperationalError, "Connection has been closed");
    1454                 return 0;
    1455         }
    1456         return 1;
     1451    if (!self || !self->valid || !self->cnx)
     1452    {
     1453        set_error_msg(OperationalError, "Connection has been closed");
     1454        return 0;
     1455    }
     1456    return 1;
    14571457}
    14581458
     
    14661466format_result(const PGresult *res)
    14671467{
    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)");
     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)");
    16181618}
    16191619
    16201620/* --------------------------------------------------------------------- */
    1621 /* large objects                                                                                                                */
     1621/* large objects                                                        */
    16221622/* --------------------------------------------------------------------- */
    16231623#ifdef LARGE_OBJECTS
     
    16271627check_lo_obj(largeObject *self, int level)
    16281628{
    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;
     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;
    16571657}
    16581658
     
    16611661largeNew(connObject *pgcnx, Oid oid)
    16621662{
    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;
     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;
    16741674}
    16751675
     
    16781678largeDealloc(largeObject *self)
    16791679{
    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);
     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);
    16851685}
    16861686
     
    16931693largeOpen(largeObject *self, PyObject *args)
    16941694{
    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;
     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;
    17211721}
    17221722
     
    17281728largeClose(largeObject *self, PyObject *noargs)
    17291729{
    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;
     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;
    17451745}
    17461746
     
    17531753largeRead(largeObject *self, PyObject *args)
    17541754{
    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;
     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;
    17911791}
    17921792
     
    17991799largeWrite(largeObject *self, PyObject *args)
    18001800{
    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;
     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;
    18281828}
    18291829
     
    18371837largeSeek(largeObject *self, PyObject *args)
    18381838{
    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);
     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);
    18651865}
    18661866
     
    18731873largeSize(largeObject *self, PyObject *noargs)
    18741874{
    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);
     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);
    19071907}
    19081908
     
    19151915largeTell(largeObject *self, PyObject *noargs)
    19161916{
    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);
     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);
    19321932}
    19331933
     
    19401940largeExport(largeObject *self, PyObject *args)
    19411941{
    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;
     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;
    19651965}
    19661966
     
    19731973largeUnlink(largeObject *self, PyObject *noargs)
    19741974{
    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;
     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;
    19891989}
    19901990
     
    19931993largeDir(largeObject *self, PyObject *noargs)
    19941994{
    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;
     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;
    20022002}
    20032003
    20042004/* large object methods */
    20052005static 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}
     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}
    20172017};
    20182018
     
    20212021largeGetAttr(largeObject *self, PyObject *nameobj)
    20222022{
    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);
     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);
    20562056}
    20572057
     
    20602060largeStr(largeObject *self)
    20612061{
    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);
     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);
    20672067}
    20682068
     
    20712071/* large object type definition */
    20722072static 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 */
     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 */
    21032103};
    21042104#endif /* LARGE_OBJECTS */
    21052105
    21062106/* --------------------------------------------------------------------- */
    2107 /* connection object                                                                                                    */
     2107/* connection object                                                    */
    21082108/* --------------------------------------------------------------------- */
    21092109static void
    21102110connDelete(connObject *self)
    21112111{
    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);
     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);
    21212121}
    21222122
     
    21282128connSource(connObject *self, PyObject *noargs)
    21292129{
    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;
     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;
    21482148}
    21492149
     
    21542154_connQuery(connObject *self, PyObject *args, int prepared)
    21552155{
    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;
     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;
    23972397}
    23982398
     
    24062406connQuery(connObject *self, PyObject *args)
    24072407{
    2408         return _connQuery(self, args, 0);
     2408    return _connQuery(self, args, 0);
    24092409}
    24102410
     
    24182418connQueryPrepared(connObject *self, PyObject *args)
    24192419{
    2420         return _connQuery(self, args, 1);
     2420    return _connQuery(self, args, 1);
    24212421}
    24222422
     
    24302430connPrepare(connObject *self, PyObject *args)
    24312431{
    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 */
     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 */
    24662466}
    24672467
     
    24742474connDescribePrepared(connObject *self, PyObject *args)
    24752475{
    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 */
     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 */
    25192519}
    25202520
     
    25272527connPutLine(connObject *self, PyObject *args)
    25282528{
    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;
     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;
    25542554}
    25552555
     
    25612561connGetLine(connObject *self, PyObject *noargs)
    25622562{
    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;
     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;
    25892589}
    25902590
     
    25962596connEndCopy(connObject *self, PyObject *noargs)
    25972597{
    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;
     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;
    26122612}
    26132613#endif /* DIRECT_ACCESS */
     
    26172617queryStr(queryObject *self)
    26182618{
    2619         return format_result(self->result);
     2619    return format_result(self->result);
    26202620}
    26212621
     
    26282628connInsertTable(connObject *self, PyObject *args)
    26292629{
    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;
     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;
    28642864}
    28652865
     
    28712871connTransaction(connObject *self, PyObject *noargs)
    28722872{
    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));
     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));
    28802880}
    28812881
     
    28872887connParameter(connObject *self, PyObject *args)
    28882888{
    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;
     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;
    29132913}
    29142914
     
    29172917date_style_to_format(const char *s)
    29182918{
    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         }
     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    }
    29422942}
    29432943
     
    29462946date_format_to_style(const char *s)
    29472947{
    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         }
     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    }
    29792979}
    29802980
     
    29862986connDateFormat(connObject *self, PyObject *noargs)
    29872987{
    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);
     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);
    30053005}
    30063006
     
    30143014connEscapeLiteral(connObject *self, PyObject *string)
    30153015{
    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;
     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;
    30543054}
    30553055
     
    30613061connEscapeIdentifier(connObject *self, PyObject *string)
    30623062{
    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 = PQescapeI