lwpgerror("Can't find %s geometry backend", newvalue );
}
+
+#include "utils/guc.h"
+#include "utils/guc_tables.h"
+
+
+/*
+ * the bare comparison function for GUC names
+ */
+static int
+guc_name_compare(const char *namea, const char *nameb)
+{
+ /*
+ * The temptation to use strcasecmp() here must be resisted, because the
+ * array ordering has to remain stable across setlocale() calls. So, build
+ * our own with a simple ASCII-only downcasing.
+ */
+ while (*namea && *nameb)
+ {
+ char cha = *namea++;
+ char chb = *nameb++;
+
+ if (cha >= 'A' && cha <= 'Z')
+ cha += 'a' - 'A';
+ if (chb >= 'A' && chb <= 'Z')
+ chb += 'a' - 'A';
+ if (cha != chb)
+ return cha - chb;
+ }
+ if (*namea)
+ return 1; /* a is longer */
+ if (*nameb)
+ return -1; /* b is longer */
+ return 0;
+}
+
+/*
+ * comparator for qsorting and bsearching guc_variables array
+ */
+static int
+guc_var_compare(const void *a, const void *b)
+{
+ const struct config_generic *confa = *(struct config_generic * const *) a;
+ const struct config_generic *confb = *(struct config_generic * const *) b;
+
+ return guc_name_compare(confa->name, confb->name);
+}
+
+/*
+* This is copied from the top half of the find_option function
+* in postgresql's guc.c. We search the guc_variables for our option.
+* Then we make sure it's not a placeholder. Only then are we sure
+* we have a potential conflict, of the sort experienced during an
+* extension upgrade.
+*/
+static int
+guc_find_option(const char *name)
+{
+ const char **key = &name;
+ struct config_generic **res;
+
+ /*
+ * By equating const char ** with struct config_generic *, we are assuming
+ * the name field is first in config_generic.
+ */
+ res = (struct config_generic **) bsearch((void *) &key,
+ (void *) get_guc_variables(),
+ GetNumConfigOptions(),
+ sizeof(struct config_generic *),
+ guc_var_compare);
+
+ /* Found nothing? Good */
+ if ( ! res ) return 0;
+
+ /* Hm, you found something, but maybe it's just a placeholder? */
+ /* We'll consider a placehold a "not found" */
+ if ( (*res)->flags & GUC_CUSTOM_PLACEHOLDER )
+ return 0;
+
+ return 1;
+}
+
+
void lwgeom_init_backend()
{
/* #2382 Before trying to create a user GUC, make sure */
/* already be loaded in memory and the GUC already defined. We */
/* can skip GUC definition in this case, so we just return. */
static const char *guc_name = "postgis.backend";
- const char *guc_installed = GetConfigOption(guc_name, TRUE, FALSE);
-
+ // const char *guc_installed = GetConfigOption(guc_name, TRUE, FALSE);
+
/* Uh oh, this GUC name already exists. Ordinarily we could just go on */
/* our way, but the way the postgis.backend works is by using the "assign" */
/* callback to change which backend is in use by flipping a global variable */
/* over. This saves the overhead of looking up the engine every time, at */
/* the expense of the extra complexity. */
- if ( guc_installed )
+ if ( guc_find_option(guc_name) )
{
/* In this narrow case the previously installed GUC is tied to the callback in */
/* the previously loaded library. Probably this is happening during an */
/* upgrade, so the old library is where the callback ties to. */
- elog(WARNING, "'%s' is currently set to '%s' and cannot be changed until you reconnect", guc_name, guc_installed);
+ elog(WARNING, "'%s' is already set and cannot be changed until you reconnect", guc_name);
return;
}
);
}
+#if 0
+
+backend/utils/misc/guc.h
+int GetNumConfigOptions(void) returns num_guc_variables
+
+backend/utils/misc/guc_tables.h
+struct config_generic ** get_guc_variables(void)
+
+
+
+
+#endif
+
PG_FUNCTION_INFO_V1(intersects);
Datum intersects(PG_FUNCTION_ARGS)
{