Esempio n. 1
0
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);
	}
Esempio n. 2
0
/* 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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
/*
 * 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;
}
Esempio n. 5
0
	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;
	}
Esempio n. 6
0
	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;
	}
Esempio n. 7
0
	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;
	}
Esempio n. 8
0
/* 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;
}
Esempio n. 9
0
/* 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;
}
Esempio n. 10
0
/*
 * 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;
		}
	}
Esempio n. 11
0
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++;
	}
Esempio n. 12
0
/* 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);
	}