mirror of https://github.com/citusdata/citus.git
alloc non-global conn. params in provided context
Having DATA-segment string literals made blindly freeing the keywords/ values difficult, so I've switched to allocating all in the provided context; because of this (and with the knowledge of the end point of the global parameters), we can safely pfree non-global parameters when we come across an invalid connection parameter entry.pull/2632/head
parent
67ecbe821a
commit
00d836e5a3
|
@ -80,6 +80,7 @@ ResetConnParams()
|
||||||
|
|
||||||
for (paramIdx = 0; paramIdx < ConnParams.size; paramIdx++)
|
for (paramIdx = 0; paramIdx < ConnParams.size; paramIdx++)
|
||||||
{
|
{
|
||||||
|
/* FIXME: People still have references to these! */
|
||||||
free((void *) ConnParams.keywords[paramIdx]);
|
free((void *) ConnParams.keywords[paramIdx]);
|
||||||
free((void *) ConnParams.values[paramIdx]);
|
free((void *) ConnParams.values[paramIdx]);
|
||||||
|
|
||||||
|
@ -94,15 +95,14 @@ ResetConnParams()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AddConnParam adds a parameter setting to the global libpq settings according
|
* AddConnParam adds a parameter setting to the global libpq settings according
|
||||||
* to the provided keyword and value. Under assert-enabled builds, array bounds
|
* to the provided keyword and value.
|
||||||
* checking is performed.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AddConnParam(const char *keyword, const char *value)
|
AddConnParam(const char *keyword, const char *value)
|
||||||
{
|
{
|
||||||
if (ConnParams.size + 1 >= ConnParams.maxSize)
|
if (ConnParams.size + 1 >= ConnParams.maxSize)
|
||||||
{
|
{
|
||||||
/* we expect developers to see that error messages */
|
/* hopefully this error is only seen by developers */
|
||||||
ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
|
ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
|
||||||
errmsg("ConnParams arrays bound check failed")));
|
errmsg("ConnParams arrays bound check failed")));
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ CheckConninfo(const char *conninfo, const char **whitelist,
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
||||||
MemoryContext context)
|
Index *nonGlobalParamStart, MemoryContext context)
|
||||||
{
|
{
|
||||||
/* make space for the port as a string: sign, 10 digits, NUL */
|
/* make space for the port as a string: sign, 10 digits, NUL */
|
||||||
char *nodePortString = MemoryContextAlloc(context, 12 * sizeof(char *));
|
char *nodePortString = MemoryContextAlloc(context, 12 * sizeof(char *));
|
||||||
|
@ -241,16 +241,24 @@ GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
||||||
* The global parameters have already been assigned from a GUC, so begin by
|
* The global parameters have already been assigned from a GUC, so begin by
|
||||||
* calculating the key-specific parameters (basically just the fields of
|
* calculating the key-specific parameters (basically just the fields of
|
||||||
* the key and the active database encoding).
|
* the key and the active database encoding).
|
||||||
|
*
|
||||||
|
* We allocate everything in the provided context so as to facilitate using
|
||||||
|
* pfree on all runtime parameters when connections using these entries are
|
||||||
|
* invalidated during config reloads.
|
||||||
*/
|
*/
|
||||||
const char *runtimeKeywords[] = {
|
const char *runtimeKeywords[] = {
|
||||||
"host", "port", "dbname", "user", "client_encoding"
|
MemoryContextStrdup(context, "host"),
|
||||||
|
MemoryContextStrdup(context, "port"),
|
||||||
|
MemoryContextStrdup(context, "dbname"),
|
||||||
|
MemoryContextStrdup(context, "user"),
|
||||||
|
MemoryContextStrdup(context, "client_encoding")
|
||||||
};
|
};
|
||||||
const char *runtimeValues[] = {
|
const char *runtimeValues[] = {
|
||||||
MemoryContextStrdup(context, key->hostname),
|
MemoryContextStrdup(context, key->hostname),
|
||||||
nodePortString,
|
nodePortString,
|
||||||
MemoryContextStrdup(context, key->database),
|
MemoryContextStrdup(context, key->database),
|
||||||
MemoryContextStrdup(context, key->user),
|
MemoryContextStrdup(context, key->user),
|
||||||
GetDatabaseEncodingName()
|
MemoryContextStrdup(context, GetDatabaseEncodingName())
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -265,12 +273,12 @@ GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
||||||
/* auth keywords will begin after global and runtime ones are appended */
|
/* auth keywords will begin after global and runtime ones are appended */
|
||||||
Index authParamsIdx = ConnParams.size + lengthof(runtimeKeywords);
|
Index authParamsIdx = ConnParams.size + lengthof(runtimeKeywords);
|
||||||
|
|
||||||
int paramIndex = 0;
|
Index paramIndex = 0;
|
||||||
int runtimeParamIndex = 0;
|
Index runtimeParamIndex = 0;
|
||||||
|
|
||||||
if (ConnParams.size + lengthof(runtimeKeywords) >= ConnParams.maxSize)
|
if (ConnParams.size + lengthof(runtimeKeywords) >= ConnParams.maxSize)
|
||||||
{
|
{
|
||||||
/* unexpected, intended as developers rather than users */
|
/* hopefully this error is only seen by developers */
|
||||||
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("too many connParams entries")));
|
errmsg("too many connParams entries")));
|
||||||
}
|
}
|
||||||
|
@ -302,6 +310,7 @@ GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
||||||
|
|
||||||
*keywords = connKeywords;
|
*keywords = connKeywords;
|
||||||
*values = connValues;
|
*values = connValues;
|
||||||
|
*nonGlobalParamStart = ConnParams.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -312,7 +321,7 @@ GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
||||||
const char *
|
const char *
|
||||||
GetConnParam(const char *keyword)
|
GetConnParam(const char *keyword)
|
||||||
{
|
{
|
||||||
int i = 0;
|
Index i = 0;
|
||||||
|
|
||||||
for (i = 0; i < ConnParams.size; i++)
|
for (i = 0; i < ConnParams.size; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -694,8 +694,30 @@ StartConnectionEstablishment(ConnectionHashKey *key)
|
||||||
entry = hash_search(ConnParamsHash, key, HASH_ENTER, &found);
|
entry = hash_search(ConnParamsHash, key, HASH_ENTER, &found);
|
||||||
if (!found || !entry->isValid)
|
if (!found || !entry->isValid)
|
||||||
{
|
{
|
||||||
/* if they're not found, compute them from GUC, runtime, etc. */
|
if (found && !entry->isValid)
|
||||||
GetConnParams(key, &entry->keywords, &entry->values, ConnectionContext);
|
{
|
||||||
|
char **keyword = &entry->keywords[entry->nonGlobalParamStart];
|
||||||
|
char **value = &entry->values[entry->nonGlobalParamStart];
|
||||||
|
|
||||||
|
while (*keyword != NULL)
|
||||||
|
{
|
||||||
|
pfree(*keyword);
|
||||||
|
keyword++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*value != NULL)
|
||||||
|
{
|
||||||
|
pfree(*value);
|
||||||
|
value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(entry->keywords);
|
||||||
|
pfree(entry->values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if not found or not valid, compute them from GUC, runtime, etc. */
|
||||||
|
GetConnParams(key, &entry->keywords, &entry->values, &entry->nonGlobalParamStart,
|
||||||
|
ConnectionContext);
|
||||||
|
|
||||||
entry->isValid = true;
|
entry->isValid = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,7 @@ typedef struct ConnParamsHashEntry
|
||||||
{
|
{
|
||||||
ConnectionHashKey key;
|
ConnectionHashKey key;
|
||||||
bool isValid;
|
bool isValid;
|
||||||
|
Index nonGlobalParamStart;
|
||||||
char **keywords;
|
char **keywords;
|
||||||
char **values;
|
char **values;
|
||||||
} ConnParamsHashEntry;
|
} ConnParamsHashEntry;
|
||||||
|
@ -144,7 +145,7 @@ extern void InitConnParams(void);
|
||||||
extern void ResetConnParams(void);
|
extern void ResetConnParams(void);
|
||||||
extern void AddConnParam(const char *keyword, const char *value);
|
extern void AddConnParam(const char *keyword, const char *value);
|
||||||
extern void GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
extern void GetConnParams(ConnectionHashKey *key, char ***keywords, char ***values,
|
||||||
MemoryContext context);
|
Index *nonGlobalParamStart, MemoryContext context);
|
||||||
extern const char * GetConnParam(const char *keyword);
|
extern const char * GetConnParam(const char *keyword);
|
||||||
extern bool CheckConninfo(const char *conninfo, const char **whitelist,
|
extern bool CheckConninfo(const char *conninfo, const char **whitelist,
|
||||||
Size whitelistLength, char **errmsg);
|
Size whitelistLength, char **errmsg);
|
||||||
|
|
Loading…
Reference in New Issue