From 1c16009985b330619dd1a8cceb2d0c69c132a4f0 Mon Sep 17 00:00:00 2001 From: Federico Di Gregorio Date: Fri, 19 Jan 2007 14:08:06 +0000 Subject: [PATCH] Added support for NULL in arrays (closes: #154) --- ChangeLog | 7 ++++++- psycopg/adapter_list.c | 10 +++++++--- psycopg/typecast_array.c | 19 +++++++++++++++---- sandbox/array.py | 13 ++++++++----- setup.cfg | 2 +- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8b7f884..d1d684f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,11 @@ 2007-01-19 Federico Di Gregorio - * Release 2.0.6 beta 1. + * psycopg/adapt_list.c: added support for None. And this closes + the other half. + + * psycopg/typecast_array.c: added support for detecting the NULL + special string and converting it as a real NULL if not enclosed in + quotes. This closes half of #154. 2007-01-16 Federico Di Gregorio diff --git a/psycopg/adapter_list.c b/psycopg/adapter_list.c index c65aac83..37a3b933 100644 --- a/psycopg/adapter_list.c +++ b/psycopg/adapter_list.c @@ -51,9 +51,13 @@ list_quote(listObject *self) tmp = PyTuple_New(len); for (i=0; iwrapped, i), - (connectionObject*)self->connection); + PyObject *quoted; + PyObject *wrapped = PyList_GET_ITEM(self->wrapped, i); + if (wrapped == Py_None) + quoted = PyString_FromString("NULL"); + else + quoted = microprotocol_getquoted(wrapped, + (connectionObject*)self->connection); if (quoted == NULL) goto error; /* here we don't loose a refcnt: SET_ITEM does not change the diff --git a/psycopg/typecast_array.c b/psycopg/typecast_array.c index 7dcb3a3d..8d6cf09a 100644 --- a/psycopg/typecast_array.c +++ b/psycopg/typecast_array.c @@ -54,7 +54,7 @@ typecast_array_cleanup(char **str, int *len) static int typecast_array_tokenize(char *str, int strlength, - int *pos, char** token, int *length) + int *pos, char** token, int *length, int *quotes) { /* FORTRAN glory */ int i, j, q, b, l, res; @@ -117,10 +117,12 @@ typecast_array_tokenize(char *str, int strlength, tokenize: /* remove initial quoting character and calculate raw length */ + *quotes = 0; l = i - *pos; if (str[*pos] == '"') { *pos += 1; l -= 2; + *quotes = 1; } if (res == ASCAN_QUOTED) { @@ -155,7 +157,7 @@ static int typecast_array_scan(char *str, int strlength, PyObject *curs, PyObject *base, PyObject *array) { - int state, length = 0, pos = 0; + int state, quotes, length = 0, pos = 0; char *token; PyObject *stack[MAX_DIMENSIONS]; @@ -163,11 +165,20 @@ typecast_array_scan(char *str, int strlength, while (1) { token = NULL; - state = typecast_array_tokenize(str, strlength, &pos, &token, &length); + state = typecast_array_tokenize(str, strlength, + &pos, &token, &length, "es); Dprintf("typecast_array_scan: state = %d, length = %d, token = '%s'", state, length, token); if (state == ASCAN_TOKEN || state == ASCAN_QUOTED) { - PyObject *obj = typecast_cast(base, token, length, curs); + PyObject *obj; + if (!quotes && length == 4 + && (token[0] == 'n' || token[0] == 'N') + && (token[1] == 'u' || token[1] == 'U') + && (token[2] == 'l' || token[2] == 'L') + && (token[3] == 'l' || token[3] == 'L')) + obj = typecast_cast(base, NULL, 0, curs); + else + obj = typecast_cast(base, token, length, curs); /* before anything else we free the memory */ if (state == ASCAN_QUOTED) PyMem_Free(token); diff --git a/sandbox/array.py b/sandbox/array.py index 183c89b1..2327a273 100644 --- a/sandbox/array.py +++ b/sandbox/array.py @@ -1,6 +1,6 @@ import psycopg2 -conn = psycopg2.connect("dbname=test") +conn = psycopg2.connect("port=5433 dbname=test") curs = conn.cursor() #curs.execute("SELECT ARRAY[1,2,3] AS foo") @@ -20,9 +20,12 @@ curs = conn.cursor() #print curs.description #print curs.fetchone()[0] -curs.execute("SELECT 1 AS foo, ARRAY[1,2] AS bar") -print curs.fetchone() - -curs.execute("SELECT * FROM test()") +#curs.execute("SELECT 1 AS foo, ARRAY[1,2] AS bar") +#print curs.fetchone() + +#curs.execute("SELECT * FROM test()") +#print curs.fetchone() + +curs.execute("SELECT %s", ([1,2,None],)) print curs.fetchone() diff --git a/setup.cfg b/setup.cfg index ce6b7fa8..f7d6d03e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [build_ext] -define=PSYCOPG_EXTENSIONS,PSYCOPG_DISPLAY_SIZE,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3 +define=PSYCOPG_DEBUG,PSYCOPG_EXTENSIONS,PSYCOPG_DISPLAY_SIZE,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3 # PSYCOPG_EXTENSIONS enables extensions to PEP-249 (you really want this) # PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower) # HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.4