diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt new file mode 100644 index 93da50d..5566943 *** a/src/interfaces/libpq/exports.txt --- b/src/interfaces/libpq/exports.txt *************** lo_lseek64 162 *** 165,167 **** --- 165,169 ---- lo_tell64 163 lo_truncate64 164 PQconninfo 165 + PQconninfoParseParams 166 + PQconninfodefaultsMerge 167 diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c new file mode 100644 index eea9c6b..5546c38 *** a/src/interfaces/libpq/fe-connect.c --- b/src/interfaces/libpq/fe-connect.c *************** PQconninfoParse(const char *conninfo, ch *** 4002,4007 **** --- 4002,4085 ---- } /* + * PQconninfoParseParams + * + * Parse a string like PQconnectdbParams() would do and return the + * resulting connection options array. NULL is returned on failure. + * The result contains only options specified directly in the array, + * not any possible default values. + * + * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd + * string on failure (use PQfreemem to free it). In out-of-memory conditions + * both *errmsg and the result could be NULL. + * + * NOTE: the returned array is dynamically allocated and should + * be freed when no longer needed via PQconninfoFree(). + */ + PQconninfoOption *PQconninfoParseParams(const char *const * keywords, + const char *const * values, int expand_dbname, + char **errmsg) + { + PQExpBufferData errorBuf; + PQconninfoOption *connOptions; + + if (errmsg) + *errmsg = NULL; /* default */ + initPQExpBuffer(&errorBuf); + if (PQExpBufferDataBroken(errorBuf)) + return NULL; /* out of memory already :-( */ + connOptions = conninfo_array_parse(keywords, values, + &errorBuf, + false, expand_dbname); + + if (connOptions == NULL && errmsg) + *errmsg = errorBuf.data; + else + termPQExpBuffer(&errorBuf); + return connOptions; + } + + /* + * PQconninfodefaultsMerge + * + * Add the default values for any unspecified options to the connection + * options array. + * + * Defaults are obtained from a service file, environment variables, etc. + * + * Returns 1 if successful, otherwise 0; connOptions is freed and errmsg is + * filled in upon failure. Note that failure to locate a default value is + * not an error condition here --- we just leave the option's value as NULL. + * + * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd + * string on failure (use PQfreemem to free it). In out-of-memory conditions + * both *errmsg and the result could be NULL. + */ + int + PQconninfodefaultsMerge(PQconninfoOption *connOptions, char **errmsg) + { + PQExpBufferData errorBuf; + + if (errmsg) + *errmsg = NULL; + initPQExpBuffer(&errorBuf); + if (PQExpBufferDataBroken(errorBuf)) + { + PQconninfoFree(connOptions); + return 0; + } + if (!conninfo_add_defaults(connOptions, &errorBuf)) + { + if (errmsg) + *errmsg = errorBuf.data; + PQconninfoFree(connOptions); + return 0; + } + termPQExpBuffer(&errorBuf); + return 1; + } + + /* * Build a working copy of the constant PQconninfoOptions array. */ static PQconninfoOption * diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h new file mode 100644 index e0f4bc7..9fa3c1c *** a/src/interfaces/libpq/libpq-fe.h --- b/src/interfaces/libpq/libpq-fe.h *************** extern PQconninfoOption *PQconndefaults( *** 267,276 **** /* parse connection options in same way as PQconnectdb */ extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); /* return the connection options used by a live connection */ extern PQconninfoOption *PQconninfo(PGconn *conn); ! /* free the data structure returned by PQconndefaults() or PQconninfoParse() */ extern void PQconninfoFree(PQconninfoOption *connOptions); /* --- 267,284 ---- /* parse connection options in same way as PQconnectdb */ extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); + /* parse connection options in same way as PQconnectdbParams */ + extern PQconninfoOption *PQconninfoParseParams(const char *const * keywords, + const char *const * values, int expand_dbname, + char **errmsg); + + /* Merge default connection options into an existing PQconninfoOption struct */ + extern int PQconninfodefaultsMerge(PQconninfoOption *connOptions, char **errmsg); + /* return the connection options used by a live connection */ extern PQconninfoOption *PQconninfo(PGconn *conn); ! /* free the data structure returned by PQconndefaults(), PQconninfoParse(), or PQconninfoParseParams() */ extern void PQconninfoFree(PQconninfoOption *connOptions); /*