2019-05-31 21:29:28 +08:00
|
|
|
CREATE OR REPLACE FUNCTION @extschema@._CDB_total_relation_size(_schema_name TEXT, _table_name TEXT)
|
2015-08-13 19:23:35 +08:00
|
|
|
RETURNS bigint AS
|
|
|
|
$$
|
2015-08-17 16:17:07 +08:00
|
|
|
DECLARE relation_size bigint := 0;
|
2015-08-13 19:23:35 +08:00
|
|
|
BEGIN
|
2015-08-17 16:17:07 +08:00
|
|
|
BEGIN
|
|
|
|
SELECT pg_total_relation_size(format('"%s"."%s"', _schema_name, _table_name)) INTO relation_size;
|
|
|
|
EXCEPTION
|
|
|
|
WHEN undefined_table OR OTHERS THEN
|
2019-05-31 21:29:28 +08:00
|
|
|
RAISE NOTICE '@extschema@._CDB_total_relation_size(''%'', ''%'') caught error: % (%)', _schema_name, _table_name, SQLERRM, SQLSTATE;
|
2015-08-17 16:17:07 +08:00
|
|
|
END;
|
|
|
|
RETURN relation_size;
|
2015-08-13 19:23:35 +08:00
|
|
|
END;
|
|
|
|
$$
|
2017-10-24 20:16:56 +08:00
|
|
|
LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
|
2015-08-13 19:23:35 +08:00
|
|
|
|
2014-05-05 23:13:06 +08:00
|
|
|
-- Return the estimated size of user data. Used for quota checking.
|
2019-05-31 21:29:28 +08:00
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.CDB_UserDataSize(schema_name TEXT)
|
2014-05-05 23:13:06 +08:00
|
|
|
RETURNS bigint AS
|
|
|
|
$$
|
2014-11-18 22:24:54 +08:00
|
|
|
DECLARE
|
2015-01-29 00:54:50 +08:00
|
|
|
total_size INT8;
|
2014-11-18 22:24:54 +08:00
|
|
|
BEGIN
|
2019-10-23 02:09:15 +08:00
|
|
|
-- TODO: Make this compatible with postgis without raster (No view and no raster tables)
|
2015-01-29 00:54:50 +08:00
|
|
|
WITH raster_tables AS (
|
2019-10-23 02:09:15 +08:00
|
|
|
SELECT o_table_name, r_table_name FROM @postgisschema@.raster_overviews
|
2014-11-18 22:24:54 +08:00
|
|
|
WHERE o_table_schema = schema_name AND o_table_catalog = current_database()
|
2015-01-29 00:54:50 +08:00
|
|
|
),
|
|
|
|
user_tables AS (
|
2019-05-31 21:29:28 +08:00
|
|
|
SELECT table_name FROM @extschema@._CDB_NonAnalysisTablesInSchema(schema_name)
|
2015-01-29 00:54:50 +08:00
|
|
|
),
|
|
|
|
table_cat AS (
|
|
|
|
SELECT
|
|
|
|
table_name,
|
2016-06-13 16:39:05 +08:00
|
|
|
(
|
|
|
|
EXISTS(select * from raster_tables where o_table_name = table_name)
|
2019-05-31 21:29:28 +08:00
|
|
|
OR table_name SIMILAR TO @extschema@._CDB_OverviewTableDiscriminator() || '[\w\d]*'
|
2016-06-13 16:39:05 +08:00
|
|
|
) AS is_overview,
|
2015-01-29 00:54:50 +08:00
|
|
|
EXISTS(SELECT * FROM raster_tables WHERE r_table_name = table_name) AS is_raster
|
|
|
|
FROM user_tables
|
|
|
|
),
|
|
|
|
sizes AS (
|
2019-05-31 21:29:28 +08:00
|
|
|
SELECT COALESCE(INT8(SUM(@extschema@._CDB_total_relation_size(schema_name, table_name)))) table_size,
|
2015-01-29 00:54:50 +08:00
|
|
|
CASE
|
|
|
|
WHEN is_overview THEN 0
|
|
|
|
WHEN is_raster THEN 1
|
2015-01-29 01:10:04 +08:00
|
|
|
ELSE 0.5 -- Division by 2 is for not counting the_geom_webmercator
|
2015-01-29 00:54:50 +08:00
|
|
|
END AS multiplier FROM table_cat GROUP BY is_overview, is_raster
|
|
|
|
)
|
|
|
|
SELECT sum(table_size*multiplier)::int8 INTO total_size FROM sizes;
|
2014-11-18 22:24:54 +08:00
|
|
|
|
2015-01-29 23:46:08 +08:00
|
|
|
IF total_size IS NOT NULL THEN
|
|
|
|
RETURN total_size;
|
|
|
|
ELSE
|
|
|
|
RETURN 0;
|
|
|
|
END IF;
|
2014-11-18 22:24:54 +08:00
|
|
|
END;
|
2014-07-04 16:57:55 +08:00
|
|
|
$$
|
2017-10-24 20:16:56 +08:00
|
|
|
LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
|
2014-07-04 16:57:55 +08:00
|
|
|
|
|
|
|
|
|
|
|
-- Return the estimated size of user data. Used for quota checking.
|
|
|
|
-- Implicit schema version for backwards compatibility
|
2019-05-31 21:29:28 +08:00
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.CDB_UserDataSize()
|
2014-07-04 16:57:55 +08:00
|
|
|
RETURNS bigint AS
|
|
|
|
$$
|
2019-05-31 21:29:28 +08:00
|
|
|
SELECT @extschema@.CDB_UserDataSize('public');
|
2014-05-05 23:13:06 +08:00
|
|
|
$$
|
2017-10-24 20:16:56 +08:00
|
|
|
LANGUAGE 'sql' VOLATILE PARALLEL UNSAFE;
|
2014-05-05 23:13:06 +08:00
|
|
|
|
2014-07-04 21:55:08 +08:00
|
|
|
-- Triggers cannot have declared arguments: pbfact float8, qmax int8, schema_name text
|
2019-05-31 21:29:28 +08:00
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.CDB_CheckQuota()
|
2014-05-05 23:13:06 +08:00
|
|
|
RETURNS trigger AS
|
|
|
|
$$
|
|
|
|
DECLARE
|
|
|
|
pbfact float8;
|
|
|
|
qmax int8;
|
2014-07-04 21:55:08 +08:00
|
|
|
schema_name text;
|
2014-05-05 23:13:06 +08:00
|
|
|
dice float8;
|
|
|
|
quota float8;
|
|
|
|
BEGIN
|
2014-07-04 21:55:08 +08:00
|
|
|
IF TG_NARGS = 3 THEN
|
|
|
|
schema_name := TG_ARGV[2];
|
2019-05-31 21:29:28 +08:00
|
|
|
IF @extschema@.schema_exists(schema_name) = false THEN
|
2014-07-04 21:55:08 +08:00
|
|
|
RAISE EXCEPTION 'Invalid schema name "%"', schema_name;
|
|
|
|
END IF;
|
|
|
|
ELSE
|
|
|
|
schema_name := 'public';
|
|
|
|
END IF;
|
2014-08-11 21:26:13 +08:00
|
|
|
|
|
|
|
-- By default try to use quota function, and if not present then rely on the one specified by params
|
|
|
|
BEGIN
|
|
|
|
EXECUTE FORMAT('SELECT %I._CDB_UserQuotaInBytes();', schema_name) INTO qmax;
|
|
|
|
EXCEPTION WHEN undefined_function THEN
|
2014-07-04 21:55:08 +08:00
|
|
|
BEGIN
|
2014-08-11 21:26:13 +08:00
|
|
|
IF TG_NARGS >= 2 AND TG_ARGV[1] <> '-1' THEN
|
|
|
|
qmax := TG_ARGV[1];
|
|
|
|
ELSE
|
|
|
|
RAISE EXCEPTION 'Missing "%"._CDB_UserQuotaInBytes()', schema_name;
|
|
|
|
END IF;
|
2014-07-04 21:55:08 +08:00
|
|
|
END;
|
2014-08-11 21:26:13 +08:00
|
|
|
END;
|
|
|
|
|
2014-05-05 23:13:06 +08:00
|
|
|
pbfact := TG_ARGV[0];
|
|
|
|
|
2014-07-04 21:55:08 +08:00
|
|
|
dice := random();
|
2014-05-05 23:13:06 +08:00
|
|
|
|
|
|
|
IF dice < pbfact THEN
|
|
|
|
RAISE DEBUG 'Checking quota on table % (dice:%, needed:<%)', TG_RELID::text, dice, pbfact;
|
2014-05-08 23:14:06 +08:00
|
|
|
|
|
|
|
IF qmax = 0 THEN
|
|
|
|
RETURN NEW;
|
|
|
|
END IF;
|
|
|
|
|
2019-05-31 21:29:28 +08:00
|
|
|
SELECT @extschema@.CDB_UserDataSize(schema_name) INTO quota;
|
2014-05-05 23:13:06 +08:00
|
|
|
IF quota > qmax THEN
|
2014-07-04 21:55:08 +08:00
|
|
|
RAISE EXCEPTION 'Quota exceeded by %KB', (quota-qmax)/1024;
|
2014-05-05 23:13:06 +08:00
|
|
|
ELSE RAISE DEBUG 'User quota in bytes: % < % (max allowed)', quota, qmax;
|
|
|
|
END IF;
|
|
|
|
END IF;
|
|
|
|
|
|
|
|
RETURN NEW;
|
|
|
|
END;
|
|
|
|
$$
|
2017-10-24 20:16:56 +08:00
|
|
|
LANGUAGE 'plpgsql' VOLATILE PARALLEL UNSAFE;
|
2014-05-08 23:14:06 +08:00
|
|
|
|
2014-07-04 17:48:53 +08:00
|
|
|
|
2019-05-31 21:29:28 +08:00
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.CDB_SetUserQuotaInBytes(schema_name text, bytes int8)
|
2014-05-08 23:14:06 +08:00
|
|
|
RETURNS int8 AS
|
|
|
|
$$
|
|
|
|
DECLARE
|
|
|
|
sql text;
|
|
|
|
BEGIN
|
2019-05-31 21:29:28 +08:00
|
|
|
IF @extschema@.schema_exists(schema_name::text) = false THEN
|
2014-07-04 21:55:08 +08:00
|
|
|
RAISE EXCEPTION 'Invalid schema name "%"', schema_name::text;
|
2014-07-04 17:48:53 +08:00
|
|
|
END IF;
|
|
|
|
|
2014-07-04 21:55:08 +08:00
|
|
|
sql := 'CREATE OR REPLACE FUNCTION "' || schema_name::text || '"._CDB_UserQuotaInBytes() '
|
2014-05-08 23:14:06 +08:00
|
|
|
|| 'RETURNS int8 AS $X$ SELECT ' || bytes
|
|
|
|
|| '::int8 $X$ LANGUAGE sql IMMUTABLE';
|
|
|
|
EXECUTE sql;
|
|
|
|
|
2014-07-07 16:36:51 +08:00
|
|
|
return bytes;
|
2014-05-08 23:14:06 +08:00
|
|
|
END
|
|
|
|
$$
|
2017-10-24 20:16:56 +08:00
|
|
|
LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL UNSAFE;
|
2014-07-04 17:48:53 +08:00
|
|
|
|
|
|
|
|
2019-05-31 21:29:28 +08:00
|
|
|
CREATE OR REPLACE FUNCTION @extschema@.CDB_SetUserQuotaInBytes(bytes int8)
|
2014-07-04 17:48:53 +08:00
|
|
|
RETURNS int8 AS
|
|
|
|
$$
|
2014-07-04 21:55:08 +08:00
|
|
|
BEGIN
|
2019-05-31 21:29:28 +08:00
|
|
|
return @extschema@.CDB_SetUserQuotaInBytes('public', bytes);
|
2014-07-04 21:55:08 +08:00
|
|
|
END;
|
2014-07-04 17:48:53 +08:00
|
|
|
$$
|
2017-10-24 20:16:56 +08:00
|
|
|
LANGUAGE 'plpgsql' VOLATILE STRICT PARALLEL UNSAFE;
|