Code

postgresql plugin: Added support for protocol versions less than 3.
authorSebastian Harl <sh@tokkee.org>
Sun, 17 Aug 2008 12:11:13 +0000 (14:11 +0200)
committerFlorian Forster <octo@huhu.verplant.org>
Tue, 19 Aug 2008 08:12:00 +0000 (10:12 +0200)
Support for passing parameters to a query was added in protocol version 3
which was introduced in version 7.4 of PostgreSQL (later version still support
earlier protocol versions though). If that is not available, we now fall back
to PQexec() if no parameters have been specified. Else, we skip the query and
report an error.

Signed-off-by: Sebastian Harl <sh@tokkee.org>
Signed-off-by: Florian Forster <octo@huhu.verplant.org>
src/collectd.conf.pod
src/postgresql.c

index 1e71badb02712d4bc83d7d56063e253cf195025e..5a1ced2b79aa3b6086e77ef878824268d8dcc8b8 100644 (file)
@@ -1078,6 +1078,9 @@ The username used to connect to the database.
 
 =back
 
+Please note that parameters are only supported by PostgreSQL's protocol
+version 3 and above which was introduced in version 7.4 of PostgreSQL.
+
 =item B<Column> I<type> [I<type instance>]
 
 Specify the I<type> and optional I<type instance> used to dispatch the value
index eb7587ff22b5b6d1e98d124141b045bab64764ea..fbc117b09547349bd623a4cb843abdf588014370 100644 (file)
@@ -103,6 +103,8 @@ typedef struct {
        PGconn      *conn;
        c_complain_t conn_complaint;
 
+       int proto_version;
+
        int max_params_num;
 
        /* user configuration */
@@ -209,6 +211,8 @@ static c_psql_database_t *c_psql_database_new (const char *name)
        db->conn_complaint.last     = 0;
        db->conn_complaint.interval = 0;
 
+       db->proto_version = 0;
+
        db->max_params_num = 0;
 
        db->queries     = NULL;
@@ -323,6 +327,11 @@ static int c_psql_check_connection (c_psql_database_t *db)
                                        db->database, PQerrorMessage (db->conn));
                        return -1;
                }
+
+               db->proto_version = PQprotocolVersion (db->conn);
+               if (3 > db->proto_version)
+                       log_warn ("Protocol version %d does not support parameters.",
+                                       db->proto_version);
        }
 
        c_release (LOG_INFO, &db->conn_complaint,
@@ -330,20 +339,11 @@ static int c_psql_check_connection (c_psql_database_t *db)
        return 0;
 } /* c_psql_check_connection */
 
-static int c_psql_exec_query (c_psql_database_t *db, int idx)
+static PGresult *c_psql_exec_query_params (c_psql_database_t *db,
+               c_psql_query_t *query)
 {
-       c_psql_query_t *query;
-       PGresult       *res;
-
        char *params[db->max_params_num];
-
-       int rows, cols;
-       int i;
-
-       if (idx >= db->queries_num)
-               return -1;
-
-       query = db->queries[idx];
+       int   i;
 
        assert (db->max_params_num >= query->params_num);
 
@@ -364,9 +364,40 @@ static int c_psql_exec_query (c_psql_database_t *db, int idx)
                }
        }
 
-       res = PQexecParams (db->conn, query->query, query->params_num, NULL,
+       return PQexecParams (db->conn, query->query, query->params_num, NULL,
                        (const char *const *)((0 == query->params_num) ? NULL : params),
                        NULL, NULL, /* return text data */ 0);
+} /* c_psql_exec_query_params */
+
+static PGresult *c_psql_exec_query_noparams (c_psql_database_t *db,
+               c_psql_query_t *query)
+{
+       return PQexec (db->conn, query->query);
+} /* c_psql_exec_query_noparams */
+
+static int c_psql_exec_query (c_psql_database_t *db, int idx)
+{
+       c_psql_query_t *query;
+       PGresult       *res;
+
+       int rows, cols;
+       int i;
+
+       if (idx >= db->queries_num)
+               return -1;
+
+       query = db->queries[idx];
+
+       if (3 <= db->proto_version)
+               res = c_psql_exec_query_params (db, query);
+       else if (0 == query->params_num)
+               res = c_psql_exec_query_noparams (db, query);
+       else {
+               log_err ("Connection to database \"%s\" does not support parameters "
+                               "(protocol version %d) - cannot execute query \"%s\".",
+                               db->database, db->proto_version, query->name);
+               return -1;
+       }
 
        if (PGRES_TUPLES_OK != PQresultStatus (res)) {
                log_err ("Failed to execute SQL query: %s",
@@ -522,6 +553,8 @@ static int c_psql_init (void)
                if (0 != c_psql_check_connection (db))
                        continue;
 
+               db->proto_version = PQprotocolVersion (db->conn);
+
                server_host    = PQhost (db->conn);
                server_version = PQserverVersion (db->conn);
                log_info ("Sucessfully connected to database %s (user %s) "
@@ -530,7 +563,11 @@ static int c_psql_init (void)
                                PQdb (db->conn), PQuser (db->conn),
                                C_PSQL_SOCKET3 (server_host, PQport (db->conn)),
                                C_PSQL_SERVER_VERSION3 (server_version),
-                               PQprotocolVersion (db->conn), PQbackendPID (db->conn));
+                               db->proto_version, PQbackendPID (db->conn));
+
+               if (3 > db->proto_version)
+                       log_warn ("Protocol version %d does not support parameters.",
+                                       db->proto_version);
        }
 
        plugin_register_read ("postgresql", c_psql_read);