From 044c9a62f408b242c8222c1300aa9fe2fb5104ce Mon Sep 17 00:00:00 2001 From: tilghman Date: Tue, 6 Oct 2009 19:34:48 +0000 Subject: Recorded merge of revisions 222309 via svnmerge from https://origsvn.digium.com/svn/asterisk/trunk ........ r222309 | tilghman | 2009-10-06 14:31:39 -0500 (Tue, 06 Oct 2009) | 10 lines Change schema query to involve the use of an optional schema parameter. This change is done in such a way as to allow the driver to continue to function with older databases which don't have these features. (closes issue #16000) Reported by: jamicque Patches: 20091002__issue16000.diff.txt uploaded by tilghman (license 14) 20091002__issue16000__1.6.1.diff.txt uploaded by tilghman (license 14) Tested by: jamicque ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.1@222310 f38db490-d61c-443f-a65b-d21fe96a405b --- cdr/cdr_pgsql.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 9 deletions(-) (limited to 'cdr') diff --git a/cdr/cdr_pgsql.c b/cdr/cdr_pgsql.c index decccfb58..0214b3233 100644 --- a/cdr/cdr_pgsql.c +++ b/cdr/cdr_pgsql.c @@ -474,22 +474,58 @@ static int config_module(int reload) conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword); if (PQstatus(conn) != CONNECTION_BAD) { - char sqlcmd[512]; + char sqlcmd[768]; char *fname, *ftype, *flen, *fnotnull, *fdef; - char *tableptr; - int i, rows; + int i, rows, version; ast_debug(1, "Successfully connected to PostgreSQL database.\n"); connected = 1; + version = PQserverVersion(conn); + + if (version >= 70300) { + char *schemaname, *tablename; + if (strchr(table, '.')) { + schemaname = ast_strdupa(table); + tablename = strchr(schemaname, '.'); + *tablename++ = '\0'; + } else { + schemaname = ""; + tablename = table; + } + + /* Escape special characters in schemaname */ + if (strchr(schemaname, '\\') || strchr(schemaname, '\'')) { + char *tmp = schemaname, *ptr; + + ptr = schemaname = alloca(strlen(tmp) * 2 + 1); + for (; *tmp; tmp++) { + if (strchr("\\'", *tmp)) { + *ptr++ = *tmp; + } + *ptr++ = *tmp; + } + *ptr = '\0'; + } + /* Escape special characters in tablename */ + if (strchr(tablename, '\\') || strchr(tablename, '\'')) { + char *tmp = tablename, *ptr; + + ptr = tablename = alloca(strlen(tmp) * 2 + 1); + for (; *tmp; tmp++) { + if (strchr("\\'", *tmp)) { + *ptr++ = *tmp; + } + *ptr++ = *tmp; + } + *ptr = '\0'; + } - /* Remove any schema name from the table */ - if ((tableptr = strrchr(table, '.'))) { - tableptr++; + snprintf(sqlcmd, sizeof(sqlcmd), "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM (((pg_catalog.pg_class c INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND c.relname = '%s' AND n.nspname = %s%s%s) INNER JOIN pg_catalog.pg_attribute a ON (NOT a.attisdropped) AND a.attnum > 0 AND a.attrelid = c.oid) INNER JOIN pg_catalog.pg_type t ON t.oid = a.atttypid) LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum ORDER BY n.nspname, c.relname, attnum", + tablename, + ast_strlen_zero(schemaname) ? "" : "'", ast_strlen_zero(schemaname) ? "current_schema()" : schemaname, ast_strlen_zero(schemaname) ? "" : "'"); } else { - tableptr = table; + snprintf(sqlcmd, sizeof(sqlcmd), "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", table); } - /* Query the columns */ - snprintf(sqlcmd, sizeof(sqlcmd), "select a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc from pg_class c, pg_type t, pg_attribute a left outer join pg_attrdef d on a.atthasdef and d.adrelid = a.attrelid and d.adnum = a.attnum where c.oid = a.attrelid and a.atttypid = t.oid and (a.attnum > 0) and c.relname = '%s' order by c.relname, attnum", tableptr); result = PQexec(conn, sqlcmd); if (PQresultStatus(result) != PGRES_TUPLES_OK) { pgerror = PQresultErrorMessage(result); @@ -506,6 +542,10 @@ static int config_module(int reload) flen = PQgetvalue(result, i, 2); fnotnull = PQgetvalue(result, i, 3); fdef = PQgetvalue(result, i, 4); + if (atoi(flen) == -1) { + /* For varchar columns, the maximum length is encoded in a different field */ + flen = PQgetvalue(result, i, 5); + } ast_verb(4, "Found column '%s' of type '%s'\n", fname, ftype); cur = ast_calloc(1, sizeof(*cur) + strlen(fname) + strlen(ftype) + 2); if (cur) { -- cgit v1.2.3