예제 #1
0
/*
 * Judge if we have to_regclass or not.
 */
bool
pool_has_to_regclass(void)
{
/*
 * Query to know if to_regclass exists.
 */
#define HAS_TOREGCLASSQUERY "SELECT count(*) from (SELECT has_function_privilege('%s', 'pg_catalog.to_regclass(cstring)', 'execute') WHERE EXISTS(SELECT * FROM pg_catalog.pg_proc AS p WHERE p.proname = 'to_regclass')) AS s"

	bool		result;
	static POOL_RELCACHE * relcache;
	POOL_CONNECTION_POOL *backend;
	char	   *user;

	backend = pool_get_session_context(false)->backend;
	user = MASTER_CONNECTION(backend)->sp->user;

	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, HAS_TOREGCLASSQUERY,
										int_register_func, int_unregister_func,
										false);
		if (relcache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, while checking to_regclass presence")));
			return false;
		}
	}

	result = pool_search_relcache(relcache, backend, user) == 0 ? 0 : 1;
	return result;
}
예제 #2
0
/*
 * Check if the function is stable.
 */
static bool is_immutable_function(char *fname)
{
/*
 * Query to know if the function is IMMUTABLE
 */
#define IS_STABLE_FUNCTION_QUERY "SELECT count(*) FROM pg_catalog.pg_proc AS p WHERE p.proname = '%s' AND p.provolatile = 'i'"
	bool result;
	static POOL_RELCACHE *relcache;
	POOL_CONNECTION_POOL *backend;

	backend = pool_get_session_context()->backend;

	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, IS_STABLE_FUNCTION_QUERY,
										int_register_func, int_unregister_func,
										false);
		if (relcache == NULL)
		{
			pool_error("is_immutable_function: pool_create_relcache error");
			return false;
		}
		pool_debug("is_immutable_function: relcache created");
	}

	result = pool_search_relcache(relcache, backend, fname)==0?0:1;
	pool_debug("is_immutable_function: search result:%d", result);
	return result;
}
예제 #3
0
/*
 * Judge if we have pgpool_regclass or not.
 */
bool pool_has_pgpool_regclass(void)
{
/*
 * Query to know if pgpool_regclass exists.
 */
#define HASPGPOOL_REGCLASSQUERY "SELECT count(*) from (SELECT has_function_privilege('%s', 'pgpool_regclass(cstring)', 'execute') WHERE EXISTS(SELECT * FROM pg_catalog.pg_proc AS p WHERE p.proname = 'pgpool_regclass')) AS s"

	bool result;
	static POOL_RELCACHE *relcache;
	POOL_CONNECTION_POOL *backend;
	char *user;

	backend = pool_get_session_context()->backend;
	user = MASTER_CONNECTION(backend)->sp->user;

	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, HASPGPOOL_REGCLASSQUERY,
										int_register_func, int_unregister_func,
										false);
		if (relcache == NULL)
		{
			pool_error("has_pgpool_regclass: pool_create_relcache error");
			return false;
		}
	}

	result = pool_search_relcache(relcache, backend, user)==0?0:1;
	return result;
}
예제 #4
0
/*
 * Convert table_name(possibly including schema name) to oid
 */
int pool_table_name_to_oid(char *table_name)
{
/*
 * Query to convert table name to oid
 */
#define TABLE_TO_OID_QUERY "SELECT pgpool_regclass('%s')"
#define TABLE_TO_OID_QUERY2 "SELECT oid FROM pg_class WHERE relname = '%s'"

	int oid = 0;
	static POOL_RELCACHE *relcache;
	POOL_CONNECTION_POOL *backend;
	char *query;

	if (table_name == NULL)
	{
		return oid;
	}

	backend = pool_get_session_context()->backend;

	if (pool_has_pgpool_regclass())
	{
		query = TABLE_TO_OID_QUERY;
	}
	else
	{
		query = TABLE_TO_OID_QUERY2;
	}

	/*
	 * If relcache does not exist, create it.
	 */
	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, query,
										int_register_func, int_unregister_func,
										true);
		if (relcache == NULL)
		{
			pool_error("table_name_to_oid: pool_create_relcache error");
			return oid;
		}

		/* Se do not cache if pgpool_regclass() returns 0, which indicates
		 * there's no such a table. In this case we do not want to cache the
		 * state because the table might be created later in this session.
		 */
		relcache->no_cache_if_zero = true;	
	}

	/*
	 * Search relcache.
	 */
	oid = (int)(intptr_t)pool_search_relcache(relcache, backend, table_name);
	return oid;
}
예제 #5
0
static TSRel*
relcache_lookup(TSRewriteContext *ctx)
{
#define ATTRDEFQUERY "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \
	" AND (a.atttypid = 'timestamp'::regtype::oid OR" \
	" a.atttypid = 'timestamp with time zone'::regtype::oid OR" \
	" a.atttypid = 'date'::regtype::oid OR" \
	" a.atttypid = 'time'::regtype::oid OR" \
	" a.atttypid = 'time with time zone'::regtype::oid)" \
    " , false)" \
	" FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
	" LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
	" WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s'" \
	" ORDER BY a.attnum"

#define ATTRDEFQUERY2 "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%')" \
	" AND (a.atttypid = 'timestamp'::regtype::oid OR" \
	" a.atttypid = 'timestamp with time zone'::regtype::oid OR" \
	" a.atttypid = 'date'::regtype::oid OR" \
	" a.atttypid = 'time'::regtype::oid OR" \
	" a.atttypid = 'time with time zone'::regtype::oid)" \
    " , false)" \
	" FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
	" LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
	" WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s')" \
	" ORDER BY a.attnum"

	char *query;

	if (pool_has_pgpool_regclass())
	{
		query = ATTRDEFQUERY2;
	}
	else
	{
		query = ATTRDEFQUERY;
	}

	if (!ts_relcache)
	{
		ts_relcache = pool_create_relcache(pool_config->relcache_size, query, ts_register_func, ts_unregister_func, false);

		if (ts_relcache == NULL)
		{
			pool_error("relcache_lookup: pool_create_relcache error");
			return NULL;
		}
	}

	return (TSRel *) pool_search_relcache(ts_relcache, ctx->backend, ctx->relname);
}
예제 #6
0
/*
 * Judge the table used in a query is a view or not.
 */
bool is_view(char *table_name)
{
/*
 * Query to know if the target table is a view.
 */
#define ISVIEWQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relkind = 'v'"

#define ISVIEWQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('%s') AND c.relkind = 'v'"

	static POOL_RELCACHE *relcache;
	POOL_CONNECTION_POOL *backend;
	bool result;
	char *query;

	if (table_name == NULL)
	{
			return false;
	}

	backend = pool_get_session_context()->backend;

	/* pgpool_regclass has been installed */
	if (pool_has_pgpool_regclass())
	{
		query = ISVIEWQUERY2;
	}
	else
	{
		query = ISVIEWQUERY;
	}

	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, query,
										int_register_func, int_unregister_func,
										false);
		if (relcache == NULL)
		{
			pool_error("is_view: pool_create_relcache error");
			return false;
		}

	}

	/*
	 * Search relcache.
	 */
	result = pool_search_relcache(relcache, backend, table_name)==0?false:true;
	return result;
}
예제 #7
0
/*
 * Check if the function is stable.
 */
static bool
is_immutable_function(char *fname)
{
/*
 * Query to know if the function is IMMUTABLE
 */
#define IS_STABLE_FUNCTION_QUERY "SELECT count(*) FROM pg_catalog.pg_proc AS p WHERE p.proname = '%s' AND p.provolatile = 'i'"
	bool		result;
	static POOL_RELCACHE * relcache;
	POOL_CONNECTION_POOL *backend;

	backend = pool_get_session_context(false)->backend;

	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, IS_STABLE_FUNCTION_QUERY,
										int_register_func, int_unregister_func,
										false);
		if (relcache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, while checking if the function is immutable")));
			return false;
		}
		ereport(DEBUG1,
				(errmsg("checking if the function is IMMUTABLE"),
				 errdetail("relcache created")));
	}

	result = (pool_search_relcache(relcache, backend, fname) == 0) ? 0 : 1;

	ereport(DEBUG1,
			(errmsg("checking if the function is IMMUTABLE"),
			 errdetail("search result = %d", result)));
	return result;
}
예제 #8
0
/*
 * Judge the table used in a query is a view or not.
 */
bool
is_view(char *table_name)
{
/*
 * Query to know if the target table is a view (including a materialized view).
 */
#define ISVIEWQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND (c.relkind = 'v' OR c.relkind = 'm')"

#define ISVIEWQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('%s') AND (c.relkind = 'v' OR c.relkind = 'm')"

#define ISVIEWQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pg_catalog.to_regclass('%s') AND (c.relkind = 'v' OR c.relkind = 'm')"

	static POOL_RELCACHE * relcache;
	POOL_CONNECTION_POOL *backend;
	bool		result;
	char	   *query;

	if (table_name == NULL)
	{
		return false;
	}

	if (!pool_has_to_regclass() && !pool_has_pgpool_regclass())
		table_name = remove_quotes_and_schema_from_relname(table_name);

	backend = pool_get_session_context(false)->backend;

	/* PostgreSQL 9.4 or later has to_regclass() */
	if (pool_has_to_regclass())
	{
		query = ISVIEWQUERY3;
	}
	/* pgpool_regclass has been installed */
	else if (pool_has_pgpool_regclass())
	{
		query = ISVIEWQUERY2;
	}
	else
	{
		query = ISVIEWQUERY;
	}

	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, query,
										int_register_func, int_unregister_func,
										false);
		if (relcache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, while checking for view")));
			return false;
		}

	}

	/*
	 * Search relcache.
	 */
	result = pool_search_relcache(relcache, backend, table_name) == 0 ? false : true;
	return result;
}
예제 #9
0
/*
 * Judge the table used in a query represented by node is a unlogged
 * table or not.
 */
bool
is_unlogged_table(char *table_name)
{
/*
 * Query to know if pg_class has relpersistence column or not.
 * PostgreSQL 9.1 or later has this.
 */
#define HASRELPERSISTENCEQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c, pg_catalog.pg_attribute AS a WHERE c.relname = 'pg_class' AND a.attrelid = c.oid AND a.attname = 'relpersistence'"

/*
 * Query to know if the target table is a unlogged one.  This query
 * is valid in PostgreSQL 9.1 or later.
 */
#define ISUNLOGGEDQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relpersistence = 'u'"

#define ISUNLOGGEDQUERY2 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pgpool_regclass('%s') AND c.relpersistence = 'u'"

#define ISUNLOGGEDQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pg_catalog.to_regclass('%s') AND c.relpersistence = 'u'"

	int			hasrelpersistence;
	static POOL_RELCACHE * hasrelpersistence_cache;
	static POOL_RELCACHE * relcache;
	POOL_CONNECTION_POOL *backend;

	if (table_name == NULL)
	{
		return false;
	}

	if (!pool_has_to_regclass() && !pool_has_pgpool_regclass())
		table_name = remove_quotes_and_schema_from_relname(table_name);

	backend = pool_get_session_context(false)->backend;

	/*
	 * Check backend version
	 */
	if (!hasrelpersistence_cache)
	{
		hasrelpersistence_cache = pool_create_relcache(pool_config->relcache_size, HASRELPERSISTENCEQUERY,
													   int_register_func, int_unregister_func,
													   false);
		if (hasrelpersistence_cache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, while checking for unlogged table")));
			return false;
		}
	}

	hasrelpersistence = pool_search_relcache(hasrelpersistence_cache, backend, "pg_class") == 0 ? 0 : 1;
	if (hasrelpersistence)
	{
		bool		result;
		char	   *query;

		/* PostgreSQL 9.4 or later has to_regclass() */
		if (pool_has_to_regclass())
		{
			query = ISUNLOGGEDQUERY3;
		}
		/* pgpool_regclass has been installed */
		else if (pool_has_pgpool_regclass())
		{
			query = ISUNLOGGEDQUERY2;
		}
		else
		{
			query = ISUNLOGGEDQUERY;
		}

		/*
		 * If relcache does not exist, create it.
		 */
		if (!relcache)
		{
			relcache = pool_create_relcache(pool_config->relcache_size, query,
											int_register_func, int_unregister_func,
											false);
			if (relcache == NULL)
			{
				ereport(WARNING,
						(errmsg("unable to create relcache, while checking for unlogged table")));
				return false;
			}
		}

		/*
		 * Search relcache.
		 */
		result = pool_search_relcache(relcache, backend, table_name) == 0 ? false : true;
		return result;
	}
	else
	{
		return false;
	}
}
예제 #10
0
static bool
is_temp_table(char *table_name)
{
/*
 * Query to know if pg_class has relistemp column or not.
 * PostgreSQL 8.4 and 9.0 have this.
 */
#define HASRELITEMPPQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c, pg_attribute AS a WHERE c.relname = 'pg_class' AND a.attrelid = c.oid AND a.attname = 'relistemp'"

/*
 * Query to know if the target table is a temporary one.  This query
 * is valid in PostgreSQL 7.3 to 8.3 and 9.1 or later.  We do not use
 * regclass (or its variant) here, because temporary tables never have
 * schema qualified name.
 */
#define ISTEMPQUERY83 "SELECT count(*) FROM pg_catalog.pg_class AS c, pg_namespace AS n WHERE c.relname = '%s' AND c.relnamespace = n.oid AND n.nspname ~ '^pg_temp_'"

/*
 * Query to know if the target table is a temporary one.  This query
 * is valid in PostgreSQL 8.4 and 9.0. We do not use regclass (or its
 * variant) here, because temporary tables never have schema qualified
 * name.
 */
#define ISTEMPQUERY84 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relistemp"

	int			hasrelistemp;
	bool		result;
	static POOL_RELCACHE * hasrelistemp_cache;
	char	   *query;
	POOL_CONNECTION_POOL *backend;

	if (table_name == NULL)
	{
		return false;
	}

	backend = pool_get_session_context(false)->backend;

	/*
	 * Check backend version
	 */
	if (!hasrelistemp_cache)
	{
		hasrelistemp_cache = pool_create_relcache(pool_config->relcache_size, HASRELITEMPPQUERY,
												  int_register_func, int_unregister_func,
												  false);
		if (hasrelistemp_cache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, while checking for temporary table")));
			return false;
		}
	}

	hasrelistemp = pool_search_relcache(hasrelistemp_cache, backend, "pg_class") == 0 ? 0 : 1;
	if (hasrelistemp)
		query = ISTEMPQUERY84;
	else
		query = ISTEMPQUERY83;

	/*
	 * If relcache does not exist, create it.
	 */
	if (!is_temp_table_relcache)
	{
		is_temp_table_relcache = pool_create_relcache(pool_config->relcache_size, query,
													  int_register_func, int_unregister_func,
													  true);
		if (is_temp_table_relcache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, while checking for temporary table")));
			return false;
		}
	}

	/*
	 * Search relcache.
	 */
	result = pool_search_relcache(is_temp_table_relcache, backend, table_name) == 0 ? false : true;
	return result;
}
예제 #11
0
/*
 * Judge the table used in a query represented by node is a system
 * catalog or not.
 */
static bool
is_system_catalog(char *table_name)
{
/*
 * Query to know if pg_namespace exists. PostgreSQL 7.2 or before doesn't have.
 */
#define HASPGNAMESPACEQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s'"

/*
 * Query to know if the target table belongs pg_catalog schema.
 */
#define ISBELONGTOPGCATALOGQUERY "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = '%s' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"

#define ISBELONGTOPGCATALOGQUERY2 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = pgpool_regclass('\"%s\"') AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"

#define ISBELONGTOPGCATALOGQUERY3 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = pg_catalog.to_regclass('\"%s\"') AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"

	int			hasreliscatalog;
	bool		result;
	static POOL_RELCACHE * hasreliscatalog_cache;
	static POOL_RELCACHE * relcache;
	POOL_CONNECTION_POOL *backend;

	if (table_name == NULL)
	{
		return false;
	}

	if (!pool_has_to_regclass() && !pool_has_pgpool_regclass())
		table_name = remove_quotes_and_schema_from_relname(table_name);

	backend = pool_get_session_context(false)->backend;

	/*
	 * Check if pg_namespace exists
	 */
	if (!hasreliscatalog_cache)
	{
		char	   *query;

		query = HASPGNAMESPACEQUERY;

		hasreliscatalog_cache = pool_create_relcache(pool_config->relcache_size, query,
													 int_register_func, int_unregister_func,
													 false);
		if (hasreliscatalog_cache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, while checking for system catalog")));
			return false;
		}
	}

	hasreliscatalog = pool_search_relcache(hasreliscatalog_cache, backend, "pg_namespace") == 0 ? 0 : 1;

	if (hasreliscatalog)
	{
		/*
		 * If relcache does not exist, create it.
		 */
		if (!relcache)
		{
			char	   *query;

			/* PostgreSQL 9.4 or later has to_regclass() */
			if (pool_has_to_regclass())
			{
				query = ISBELONGTOPGCATALOGQUERY3;
			}
			/* pgpool_regclass has been installed */
			else if (pool_has_pgpool_regclass())
			{
				query = ISBELONGTOPGCATALOGQUERY2;
			}
			else
			{
				query = ISBELONGTOPGCATALOGQUERY;
			}

			relcache = pool_create_relcache(pool_config->relcache_size, query,
											int_register_func, int_unregister_func,
											false);
			if (relcache == NULL)
			{
				ereport(WARNING,
						(errmsg("unable to create relcache, while checking for system catalog")));
				return false;
			}
		}

		/*
		 * Search relcache.
		 */
		result = pool_search_relcache(relcache, backend, table_name) == 0 ? false : true;
		return result;
	}

	/*
	 * Pre 7.3. Just check whether the table starts with "pg_".
	 */
	return (strcasecmp(table_name, "pg_") == 0);
}
예제 #12
0
/*
 * Convert table_name(possibly including schema name) to oid
 */
int
pool_table_name_to_oid(char *table_name)
{
/*
 * Query to convert table name to oid
 */
#define TABLE_TO_OID_QUERY "SELECT pgpool_regclass('%s')"
#define TABLE_TO_OID_QUERY2 "SELECT oid FROM pg_class WHERE relname = '%s'"
#define TABLE_TO_OID_QUERY3 "SELECT COALESCE(pg_catalog.to_regclass('%s')::oid, 0)"

	int			oid = 0;
	static POOL_RELCACHE * relcache;
	POOL_CONNECTION_POOL *backend;
	char	   *query;

	if (table_name == NULL)
	{
		return oid;
	}

	if (!pool_has_to_regclass() && !pool_has_pgpool_regclass())
		table_name = remove_quotes_and_schema_from_relname(table_name);

	backend = pool_get_session_context(false)->backend;

	if (pool_has_to_regclass())
	{
		query = TABLE_TO_OID_QUERY3;
	}
	else if (pool_has_pgpool_regclass())
	{
		query = TABLE_TO_OID_QUERY;
	}
	else
	{
		query = TABLE_TO_OID_QUERY2;
	}

	/*
	 * If relcache does not exist, create it.
	 */
	if (!relcache)
	{
		relcache = pool_create_relcache(pool_config->relcache_size, query,
										int_register_func, int_unregister_func,
										true);
		if (relcache == NULL)
		{
			ereport(WARNING,
					(errmsg("unable to create relcache, getting OID from table name")));
			return oid;
		}

		/*
		 * Se do not cache if pgpool_regclass() returns 0, which indicates
		 * there's no such a table. In this case we do not want to cache the
		 * state because the table might be created later in this session.
		 */
		relcache->no_cache_if_zero = true;
	}

	/*
	 * Search relcache.
	 */
	oid = (int) (intptr_t) pool_search_relcache(relcache, backend, table_name);
	return oid;
}