static bool plpgsql_extra_checks_check_hook(char **newvalue, void **extra, GucSource source) { char *rawstring; List *elemlist; ListCell *l; int extrachecks = 0; int *myextra; if (pg_strcasecmp(*newvalue, "all") == 0) extrachecks = PLPGSQL_XCHECK_ALL; else if (pg_strcasecmp(*newvalue, "none") == 0) extrachecks = PLPGSQL_XCHECK_NONE; else { /* Need a modifiable copy of string */ rawstring = pstrdup(*newvalue); /* Parse string into list of identifiers */ if (!SplitIdentifierString(rawstring, ',', &elemlist)) { /* syntax error in list */ GUC_check_errdetail("List syntax is invalid."); pfree(rawstring); list_free(elemlist); return false; } foreach(l, elemlist) { char *tok = (char *) lfirst(l); if (pg_strcasecmp(tok, "shadowed_variables") == 0) extrachecks |= PLPGSQL_XCHECK_SHADOWVAR; else if (pg_strcasecmp(tok, "all") == 0 || pg_strcasecmp(tok, "none") == 0) { GUC_check_errdetail("Key word \"%s\" cannot be combined with other key words.", tok); pfree(rawstring); list_free(elemlist); return false; } else { GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); pfree(rawstring); list_free(elemlist); return false; } } pfree(rawstring); list_free(elemlist); }
/* check_hook: validate new default_tablespace */ bool check_default_tablespace(char **newval, void **extra, GucSource source) { /* * If we aren't inside a transaction, we cannot do database access so * cannot verify the name. Must accept the value on faith. */ if (IsTransactionState()) { if (**newval != '\0' && !OidIsValid(get_tablespace_oid(*newval, true))) { /* * When source == PGC_S_TEST, don't throw a hard error for a * nonexistent tablespace, only a NOTICE. See comments in guc.h. */ if (source == PGC_S_TEST) { ereport(NOTICE, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("tablespace \"%s\" does not exist", *newval))); } else { GUC_check_errdetail("Tablespace \"%s\" does not exist.", *newval); return false; } } } return true; }
static bool zhprs_check_rules(char **newval, void **extra, GucSource source) { char *rawstring; char *myextra; char *ext; char *rule_path; if (strcmp(*newval, "none") == 0) return true; /* Need a modifiable copy of string */ rawstring = pstrdup(*newval); ext = strrchr(rawstring, '.'); if (ext && pg_strcasecmp(ext, ".ini") == 0) { *ext = '\0'; ext++; rule_path = zhprs_get_tsearch_config_filename(rawstring, ext); } else { GUC_check_errdetail("Unrecognized key word: \"%s\". Must end with .ini", rawstring); pfree(rawstring); return false; } myextra = strdup(rule_path); *extra = (void *) myextra; pfree(rule_path); return true; }
/* * check_hook, assign_hook and show_hook subroutines */ static bool zhprs_check_charset(char **newval, void **extra, GucSource source) { char* string = *newval; if (pg_strcasecmp(string, "gbk") != 0 && pg_strcasecmp(string, "utf8") != 0) { GUC_check_errdetail("Charset: \"%s\". Only Support \"gbk\" or \"utf8\"", string); return false; } return true; }
static bool check_enabled( bool *newval, void **extra, GucSource source) { if ( initstage < IS_PLJAVA_ENABLED ) return true; if ( *newval ) return true; GUC_check_errmsg( "too late to change \"pljava.enable\" setting"); GUC_check_errdetail( "Start-up has progressed past the point where it is checked."); GUC_check_errhint( "For another chance, exit this session and start a new one."); return false; }
static bool check_classpath( char **newval, void **extra, GucSource source) { if ( initstage < IS_JAVAVM_OPTLIST ) return true; if ( classpath == *newval ) return true; if ( classpath && *newval && 0 == strcmp(classpath, *newval) ) return true; GUC_check_errmsg( "too late to change \"pljava.classpath\" setting"); GUC_check_errdetail( "Changing the setting has no effect after " "PL/Java has started the Java virtual machine."); GUC_check_errhint( "To try a different value, exit this session and start a new one."); return false; }
static bool check_libjvm_location( char **newval, void **extra, GucSource source) { if ( initstage < IS_CAND_JVMOPENED ) return true; if ( libjvmlocation == *newval ) return true; if ( libjvmlocation && *newval && 0 == strcmp(libjvmlocation, *newval) ) return true; GUC_check_errmsg( "too late to change \"pljava.libjvm_location\" setting"); GUC_check_errdetail( "Changing the setting can have no effect after " "PL/Java has found and opened the library it points to."); GUC_check_errhint( "To try a different value, exit this session and start a new one."); return false; }
/* check_hook: validate new default_tablespace */ bool check_default_tablespace(char **newval, void **extra, GucSource source) { /* * If we aren't inside a transaction, we cannot do database access so * cannot verify the name. Must accept the value on faith. */ if (IsTransactionState()) { if (**newval != '\0' && !OidIsValid(get_tablespace_oid(*newval, true))) { GUC_check_errdetail("Tablespace \"%s\" does not exist.", *newval); return false; } } return true; }
/* check_hook: validate new default_tablespace */ bool check_default_tablespace(char **newval, void **extra, GucSource source) { /* * If we aren't inside a transaction, we cannot do database access so * cannot verify the name. Must accept the value on faith. */ if (IsTransactionState()) { if (**newval != '\0' && !OidIsValid(get_tablespace_oid(*newval, true))) { /* * When source == PGC_S_TEST, we are checking the argument of an * ALTER DATABASE SET or ALTER USER SET command. pg_dumpall dumps * all roles before tablespaces, so if we're restoring a * pg_dumpall script the tablespace might not yet exist, but will * be created later. Because of that, issue a NOTICE if source == * PGC_S_TEST, but accept the value anyway. */ if (source == PGC_S_TEST) { ereport(NOTICE, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("tablespace \"%s\" does not exist", *newval))); } else { GUC_check_errdetail("Tablespace \"%s\" does not exist.", *newval); return false; } } } return true; }
/* * check_datestyle: GUC check_hook for datestyle */ bool check_datestyle(char **newval, void **extra, GucSource source) { int newDateStyle = DateStyle; int newDateOrder = DateOrder; bool have_style = false; bool have_order = false; bool ok = true; char *rawstring; int *myextra; char *result; List *elemlist; ListCell *l; /* Need a modifiable copy of string */ rawstring = pstrdup(*newval); /* Parse string into list of identifiers */ if (!SplitIdentifierString(rawstring, ',', &elemlist)) { /* syntax error in list */ GUC_check_errdetail("List syntax is invalid."); pfree(rawstring); list_free(elemlist); return false; } foreach(l, elemlist) { char *tok = (char *) lfirst(l); /* Ugh. Somebody ought to write a table driven version -- mjl */ if (pg_strcasecmp(tok, "ISO") == 0) { if (have_style && newDateStyle != USE_ISO_DATES) ok = false; /* conflicting styles */ newDateStyle = USE_ISO_DATES; have_style = true; } else if (pg_strcasecmp(tok, "SQL") == 0) { if (have_style && newDateStyle != USE_SQL_DATES) ok = false; /* conflicting styles */ newDateStyle = USE_SQL_DATES; have_style = true; } else if (pg_strncasecmp(tok, "POSTGRES", 8) == 0) { if (have_style && newDateStyle != USE_POSTGRES_DATES) ok = false; /* conflicting styles */ newDateStyle = USE_POSTGRES_DATES; have_style = true; } else if (pg_strcasecmp(tok, "GERMAN") == 0) { if (have_style && newDateStyle != USE_GERMAN_DATES) ok = false; /* conflicting styles */ newDateStyle = USE_GERMAN_DATES; have_style = true; /* GERMAN also sets DMY, unless explicitly overridden */ if (!have_order) newDateOrder = DATEORDER_DMY; } else if (pg_strcasecmp(tok, "YMD") == 0) { if (have_order && newDateOrder != DATEORDER_YMD) ok = false; /* conflicting orders */ newDateOrder = DATEORDER_YMD; have_order = true; } else if (pg_strcasecmp(tok, "DMY") == 0 || pg_strncasecmp(tok, "EURO", 4) == 0) { if (have_order && newDateOrder != DATEORDER_DMY) ok = false; /* conflicting orders */ newDateOrder = DATEORDER_DMY; have_order = true; } else if (pg_strcasecmp(tok, "MDY") == 0 || pg_strcasecmp(tok, "US") == 0 || pg_strncasecmp(tok, "NONEURO", 7) == 0) { if (have_order && newDateOrder != DATEORDER_MDY) ok = false; /* conflicting orders */ newDateOrder = DATEORDER_MDY; have_order = true; } else if (pg_strcasecmp(tok, "DEFAULT") == 0) { /* * Easiest way to get the current DEFAULT state is to fetch the * DEFAULT string from guc.c and recursively parse it. * * We can't simply "return check_datestyle(...)" because we need * to handle constructs like "DEFAULT, ISO". */ char *subval; void *subextra = NULL; subval = strdup(GetConfigOptionResetString("datestyle")); if (!subval) { ok = false; break; } if (!check_datestyle(&subval, &subextra, source)) { free(subval); ok = false; break; } myextra = (int *) subextra; if (!have_style) newDateStyle = myextra[0]; if (!have_order) newDateOrder = myextra[1]; free(subval); free(subextra); } else { GUC_check_errdetail("Unrecognized key word: \"%s\".", tok); pfree(rawstring); list_free(elemlist); return false; } }
static bool zhprs_check_extra_dicts(char **newval, void **extra, GucSource source) { char *rawstring; List *elemlist; ListCell *l; dict_extra *myextra; int num; int i; if (strcmp(*newval, "none") == 0) return true; /* Need a modifiable copy of string */ rawstring = pstrdup(*newval); /* Parse string into list of identifiers */ if (!SplitIdentifierString(rawstring, ',', &elemlist)) { /* syntax error in list */ GUC_check_errdetail("List syntax is invalid."); pfree(rawstring); list_free(elemlist); return false; } num = list_length(elemlist); myextra = (dict_extra *) malloc(sizeof(dict_extra) + num * sizeof(dict_elem)); if (!myextra) { GUC_check_errdetail("Out of memory. Too many dictionary"); pfree(rawstring); list_free(elemlist); return false; } i = 0; foreach(l, elemlist) { char *tok = (char *) lfirst(l); char *dict_path; int load_dict_mode = zhprs_load_dict_mem_mode; char * ext = strrchr(tok, '.'); if (ext && strlen(ext) == 4) { if (pg_strcasecmp(ext, ".txt") == 0) load_dict_mode |= SCWS_XDICT_TXT; else if(pg_strcasecmp(ext, ".xdb") == 0) load_dict_mode |= SCWS_XDICT_XDB; else { GUC_check_errdetail("Unrecognized key word: \"%s\". Must end with .txt or .xdb", tok); pfree(rawstring); list_free(elemlist); free(myextra); return false; } *ext = '\0'; ext++; } else { GUC_check_errdetail("Unrecognized key word: \"%s\". Must end with .txt or .xdb", tok); pfree(rawstring); list_free(elemlist); free(myextra); return false; } dict_path = zhprs_get_tsearch_config_filename(tok, ext); memcpy(myextra->dicts[i].path, dict_path, MAXPGPATH); myextra->dicts[i].mode = load_dict_mode; i++; }
/* check_hook: validate new temp_tablespaces */ bool check_temp_tablespaces(char **newval, void **extra, GucSource source) { char *rawname; List *namelist; /* Need a modifiable copy of string */ rawname = pstrdup(*newval); /* Parse string into list of identifiers */ if (!SplitIdentifierString(rawname, ',', &namelist)) { /* syntax error in name list */ GUC_check_errdetail("List syntax is invalid."); pfree(rawname); list_free(namelist); return false; } /* * If we aren't inside a transaction, we cannot do database access so * cannot verify the individual names. Must accept the list on faith. * Fortunately, there's then also no need to pass the data to fd.c. */ if (IsTransactionState()) { temp_tablespaces_extra *myextra; Oid *tblSpcs; int numSpcs; ListCell *l; /* temporary workspace until we are done verifying the list */ tblSpcs = (Oid *) palloc(list_length(namelist) * sizeof(Oid)); numSpcs = 0; foreach(l, namelist) { char *curname = (char *) lfirst(l); Oid curoid; AclResult aclresult; /* Allow an empty string (signifying database default) */ if (curname[0] == '\0') { tblSpcs[numSpcs++] = InvalidOid; continue; } /* * In an interactive SET command, we ereport for bad info. When * source == PGC_S_TEST, don't throw a hard error for a * nonexistent tablespace, only a NOTICE. See comments in guc.h. */ curoid = get_tablespace_oid(curname, source <= PGC_S_TEST); if (curoid == InvalidOid) { if (source == PGC_S_TEST) ereport(NOTICE, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("tablespace \"%s\" does not exist", curname))); continue; } /* * Allow explicit specification of database's default tablespace * in temp_tablespaces without triggering permissions checks. */ if (curoid == MyDatabaseTableSpace) { tblSpcs[numSpcs++] = InvalidOid; continue; } /* Check permissions, similarly complaining only if interactive */ aclresult = pg_tablespace_aclcheck(curoid, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) { if (source >= PGC_S_INTERACTIVE) aclcheck_error(aclresult, ACL_KIND_TABLESPACE, curname); continue; } tblSpcs[numSpcs++] = curoid; } /* Now prepare an "extra" struct for assign_temp_tablespaces */ myextra = malloc(offsetof(temp_tablespaces_extra, tblSpcs) + numSpcs * sizeof(Oid)); if (!myextra) return false; myextra->numSpcs = numSpcs; memcpy(myextra->tblSpcs, tblSpcs, numSpcs * sizeof(Oid)); *extra = (void *) myextra; pfree(tblSpcs); }