From 3e160e27e4686620d16477a9ea9cf00141e52ce7 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 10:41:51 +0200 Subject: Adding upstream version 3.9.0. Signed-off-by: Daniel Baumann --- src/global/dict_pgsql.c | 73 ++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 38 deletions(-) (limited to 'src/global/dict_pgsql.c') diff --git a/src/global/dict_pgsql.c b/src/global/dict_pgsql.c index 5992135..c626854 100644 --- a/src/global/dict_pgsql.c +++ b/src/global/dict_pgsql.c @@ -108,18 +108,18 @@ #define TYPEUNIX (1<<0) #define TYPEINET (1<<1) -#define TYPECONNSTRING (1<<2) +#define TYPECONNSTR (1<<2) #define RETRY_CONN_MAX 100 -#define RETRY_CONN_INTV 60 /* 1 minute */ -#define IDLE_CONN_INTV 60 /* 1 minute */ +#define DEF_RETRY_INTV 60 /* 1 minute */ +#define DEF_IDLE_INTV 60 /* 1 minute */ typedef struct { PGconn *db; char *hostname; char *name; char *port; - unsigned type; /* TYPEUNIX | TYPEINET | TYPECONNSTRING */ + unsigned type; /* TYPEUNIX | TYPEINET | TYPECONNSTR */ unsigned stat; /* STATUNTRIED | STATFAIL | STATCUR */ time_t ts; /* used for attempting reconnection */ } HOST; @@ -140,6 +140,8 @@ typedef struct { char *password; char *dbname; char *encoding; + int retry_interval; + int idle_interval; char *table; ARGV *hosts; PLPGSQL *pldb; @@ -152,12 +154,11 @@ typedef struct { /* internal function declarations */ static PLPGSQL *plpgsql_init(ARGV *); -static PGSQL_RES *plpgsql_query(DICT_PGSQL *, const char *, VSTRING *, char *, - char *, char *, char *); +static PGSQL_RES *plpgsql_query(DICT_PGSQL *, const char *, VSTRING *); static void plpgsql_dealloc(PLPGSQL *); static void plpgsql_close_host(HOST *); -static void plpgsql_down_host(HOST *); -static void plpgsql_connect_single(HOST *, char *, char *, char *, char *); +static void plpgsql_down_host(HOST *, int); +static void plpgsql_connect_single(DICT_PGSQL *, HOST *); static const char *dict_pgsql_lookup(DICT *, const char *); DICT *dict_pgsql_open(const char *, int, int); static void dict_pgsql_close(DICT *); @@ -280,7 +281,7 @@ static const char *dict_pgsql_lookup(DICT *dict, const char *name) */ #ifdef SNAPSHOT if ((dict->flags & DICT_FLAG_UTF8_ACTIVE) == 0 - && !valid_utf8_string(name, strlen(name))) { + && !valid_utf8_stringz(name)) { if (msg_verbose) msg_info("%s: %s: Skipping lookup of non-UTF-8 key '%s'", myname, dict_pgsql->parser->name, name); @@ -324,11 +325,7 @@ static const char *dict_pgsql_lookup(DICT *dict, const char *name) return (0); /* do the query - set dict->error & cleanup if there's an error */ - if ((query_res = plpgsql_query(dict_pgsql, name, query, - dict_pgsql->dbname, - dict_pgsql->encoding, - dict_pgsql->username, - dict_pgsql->password)) == 0) { + if ((query_res = plpgsql_query(dict_pgsql, name, query)) == 0) { dict->error = DICT_ERR_RETRY; return 0; } @@ -404,8 +401,7 @@ static HOST *dict_pgsql_find_host(PLPGSQL *PLDB, unsigned stat, unsigned type) /* dict_pgsql_get_active - get an active connection */ -static HOST *dict_pgsql_get_active(PLPGSQL *PLDB, char *dbname, char *encoding, - char *username, char *password) +static HOST *dict_pgsql_get_active(DICT_PGSQL *dict_pgsql, PLPGSQL *PLDB) { const char *myname = "dict_pgsql_get_active"; HOST *host; @@ -414,7 +410,7 @@ static HOST *dict_pgsql_get_active(PLPGSQL *PLDB, char *dbname, char *encoding, /* try the active connections first; prefer the ones to UNIX sockets */ if ((host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPEUNIX)) != NULL || (host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPEINET)) != NULL || - (host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPECONNSTRING)) != NULL) { + (host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPECONNSTR)) != NULL) { if (msg_verbose) msg_info("%s: found active connection to host %s", myname, host->hostname); @@ -432,11 +428,11 @@ static HOST *dict_pgsql_get_active(PLPGSQL *PLDB, char *dbname, char *encoding, (host = dict_pgsql_find_host(PLDB, STATUNTRIED | STATFAIL, TYPEINET)) != NULL || (host = dict_pgsql_find_host(PLDB, STATUNTRIED | STATFAIL, - TYPECONNSTRING)) != NULL)) { + TYPECONNSTR)) != NULL)) { if (msg_verbose) msg_info("%s: attempting to connect to host %s", myname, host->hostname); - plpgsql_connect_single(host, dbname, encoding, username, password); + plpgsql_connect_single(dict_pgsql, host); if (host->stat == STATACTIVE) return host; } @@ -464,18 +460,14 @@ static void dict_pgsql_event(int unused_event, void *context) static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql, const char *name, - VSTRING *query, - char *dbname, - char *encoding, - char *username, - char *password) + VSTRING *query) { PLPGSQL *PLDB = dict_pgsql->pldb; HOST *host; PGSQL_RES *res = 0; ExecStatusType status; - while ((host = dict_pgsql_get_active(PLDB, dbname, encoding, username, password)) != NULL) { + while ((host = dict_pgsql_get_active(dict_pgsql, PLDB)) != NULL) { /* * The active host is used to escape strings in the context of the @@ -490,7 +482,7 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql, /* Check for potential dict_pgsql_quote() failure. */ if (host->stat == STATFAIL) { - plpgsql_down_host(host); + plpgsql_down_host(host, dict_pgsql->retry_interval); continue; } @@ -528,7 +520,7 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql, msg_info("dict_pgsql: successful query from host %s", host->hostname); event_request_timer(dict_pgsql_event, (void *) host, - IDLE_CONN_INTV); + dict_pgsql->idle_interval); return (res); case PGRES_FATAL_ERROR: msg_warn("pgsql query failed: fatal error from host %s: %s", @@ -559,7 +551,7 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql, */ if (res != 0) PQclear(res); - plpgsql_down_host(host); + plpgsql_down_host(host, dict_pgsql->retry_interval); } return (0); @@ -570,24 +562,25 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql, * used to reconnect to a single database when one is down or none is * connected yet. Log all errors and set the stat field of host accordingly */ -static void plpgsql_connect_single(HOST *host, char *dbname, char *encoding, char *username, char *password) +static void plpgsql_connect_single(DICT_PGSQL *dict_pgsql, HOST *host) { - if (host->type == TYPECONNSTRING) { + if (host->type == TYPECONNSTR) { host->db = PQconnectdb(host->name); } else { host->db = PQsetdbLogin(host->name, host->port, NULL, NULL, - dbname, username, password); + dict_pgsql->dbname, dict_pgsql->username, + dict_pgsql->password); } if (host->db == NULL || PQstatus(host->db) != CONNECTION_OK) { msg_warn("connect to pgsql server %s: %s", host->hostname, PQerrorMessage(host->db)); - plpgsql_down_host(host); + plpgsql_down_host(host, dict_pgsql->retry_interval); return; } - if (PQsetClientEncoding(host->db, encoding) != 0) { + if (PQsetClientEncoding(host->db, dict_pgsql->encoding) != 0) { msg_warn("dict_pgsql: cannot set the encoding to %s, skipping %s", - encoding, host->hostname); - plpgsql_down_host(host); + dict_pgsql->encoding, host->hostname); + plpgsql_down_host(host, dict_pgsql->retry_interval); return; } if (msg_verbose) @@ -611,12 +604,12 @@ static void plpgsql_close_host(HOST *host) * plpgsql_down_host - close a failed connection AND set a "stay away from * this host" timer. */ -static void plpgsql_down_host(HOST *host) +static void plpgsql_down_host(HOST *host, int retry_interval) { if (host->db) PQfinish(host->db); host->db = 0; - host->ts = time((time_t *) 0) + RETRY_CONN_INTV; + host->ts = time((time_t *) 0) + retry_interval; host->stat = STATFAIL; event_cancel_timer(dict_pgsql_event, (void *) host); } @@ -635,6 +628,10 @@ static void pgsql_parse_config(DICT_PGSQL *dict_pgsql, const char *pgsqlcf) dict_pgsql->password = cfg_get_str(p, "password", "", 0, 0); dict_pgsql->dbname = cfg_get_str(p, "dbname", "", 1, 0); dict_pgsql->encoding = cfg_get_str(p, "encoding", "UTF8", 1, 0); + dict_pgsql->retry_interval = cfg_get_int(p, "retry_interval", + DEF_RETRY_INTV, 1, 0); + dict_pgsql->idle_interval = cfg_get_int(p, "idle_interval", + DEF_IDLE_INTV, 1, 0); dict_pgsql->result_format = cfg_get_str(p, "result_format", "%s", 1, 0); /* @@ -764,7 +761,7 @@ static HOST *host_init(const char *hostname) * Modern syntax: "postgresql://connection-info". */ if (strncmp(d, "postgresql:", 11) == 0) { - host->type = TYPECONNSTRING; + host->type = TYPECONNSTR; host->name = mystrdup(d); host->port = 0; } -- cgit v1.2.3