mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-24 06:53:59 +08:00
This fixes the show_indexes test support function to properly show the columns of the indexes instead of the table. The function now also shows the expressions of expression indexes.
243 lines
7.6 KiB
PL/PgSQL
243 lines
7.6 KiB
PL/PgSQL
CREATE SCHEMA IF NOT EXISTS test;
|
|
GRANT USAGE ON SCHEMA test TO PUBLIC;
|
|
|
|
-- Utility functions to show relation information in tests. These
|
|
-- functions generate output which is the same across PostgreSQL
|
|
-- versions. Their usage is preferred over psql's '\d <relation>',
|
|
-- since that output typically changes across PostgreSQL versions.
|
|
CREATE OR REPLACE FUNCTION test.show_columns(rel regclass)
|
|
RETURNS TABLE("Column" name,
|
|
"Type" text,
|
|
"Nullable" boolean) LANGUAGE SQL STABLE AS
|
|
$BODY$
|
|
SELECT a.attname,
|
|
format_type(t.oid, t.typtypmod),
|
|
a.attnotnull
|
|
FROM pg_attribute a, pg_type t
|
|
WHERE a.attrelid = rel
|
|
AND a.atttypid = t.oid
|
|
AND a.attnum >= 0
|
|
ORDER BY a.attnum;
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_columnsp(pattern text)
|
|
RETURNS TABLE("Relation" regclass,
|
|
"Kind" "char",
|
|
"Column" name,
|
|
"Column type" text,
|
|
"Nullable" boolean) LANGUAGE PLPGSQL STABLE AS
|
|
$BODY$
|
|
DECLARE
|
|
schema_name name = split_part(pattern, '.', 1);
|
|
table_name name = split_part(pattern, '.', 2);
|
|
BEGIN
|
|
IF schema_name = '' OR table_name = '' THEN
|
|
schema_name := current_schema();
|
|
table_name := pattern;
|
|
END IF;
|
|
|
|
RETURN QUERY
|
|
SELECT c.oid::regclass,
|
|
c.relkind,
|
|
a.attname,
|
|
format_type(t.oid, t.typtypmod),
|
|
a.attnotnull
|
|
FROM pg_class c, pg_attribute a, pg_type t
|
|
WHERE format('%I.%I', c.relnamespace::regnamespace::name, c.relname) LIKE format('%I.%s', schema_name, table_name)
|
|
AND a.attrelid = c.oid
|
|
AND a.atttypid = t.oid
|
|
AND a.attnum >= 0
|
|
ORDER BY c.relname, a.attnum;
|
|
END
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_indexes(rel regclass)
|
|
RETURNS TABLE("Index" regclass,
|
|
"Columns" name[],
|
|
"Expr" text,
|
|
"Unique" boolean,
|
|
"Primary" boolean,
|
|
"Exclusion" boolean,
|
|
"Tablespace" name) LANGUAGE SQL STABLE AS
|
|
$BODY$
|
|
SELECT c.oid::regclass,
|
|
array(SELECT "Column" FROM test.show_columns(i.indexrelid)),
|
|
pg_get_expr(i.indexprs, c.oid, true),
|
|
i.indisunique,
|
|
i.indisprimary,
|
|
i.indisexclusion,
|
|
(SELECT t.spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace)
|
|
FROM pg_class c, pg_index i
|
|
WHERE c.oid = i.indexrelid AND i.indrelid = rel
|
|
ORDER BY c.oid;
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_indexesp(pattern text)
|
|
RETURNS TABLE("Table" regclass,
|
|
"Index" regclass,
|
|
"Columns" name[],
|
|
"Expr" text,
|
|
"Unique" boolean,
|
|
"Primary" boolean,
|
|
"Exclusion" boolean,
|
|
"Tablespace" name) LANGUAGE PLPGSQL STABLE AS
|
|
$BODY$
|
|
DECLARE
|
|
schema_name name = split_part(pattern, '.', 1);
|
|
table_name name = split_part(pattern, '.', 2);
|
|
BEGIN
|
|
IF schema_name = '' OR table_name = '' THEN
|
|
schema_name := current_schema();
|
|
table_name := pattern;
|
|
END IF;
|
|
|
|
RETURN QUERY
|
|
SELECT c.oid::regclass,
|
|
i.indexrelid::regclass,
|
|
array(SELECT "Column" FROM test.show_columns(i.indexrelid)),
|
|
pg_get_expr(i.indexprs, c.oid, true),
|
|
i.indisunique,
|
|
i.indisprimary,
|
|
i.indisexclusion,
|
|
(SELECT t.spcname FROM pg_class cc, pg_tablespace t WHERE cc.oid = i.indexrelid AND t.oid = cc.reltablespace)
|
|
FROM pg_class c, pg_index i
|
|
WHERE format('%I.%I', c.relnamespace::regnamespace::name, c.relname) LIKE format('%I.%s', schema_name, table_name)
|
|
AND c.oid = i.indrelid
|
|
ORDER BY c.oid, i.indexrelid;
|
|
END
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_constraints(rel regclass)
|
|
RETURNS TABLE("Constraint" name,
|
|
"Type" "char",
|
|
"Columns" name[],
|
|
"Index" regclass,
|
|
"Expr" text) LANGUAGE SQL STABLE AS
|
|
$BODY$
|
|
SELECT c.conname,
|
|
c.contype,
|
|
array(SELECT attname FROM pg_attribute a, unnest(conkey) k WHERE a.attrelid = rel AND k = a.attnum),
|
|
c.conindid::regclass,
|
|
c.consrc
|
|
FROM pg_constraint c
|
|
WHERE c.conrelid = rel
|
|
ORDER BY c.conname;
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_constraintsp(pattern text)
|
|
RETURNS TABLE("Table" regclass,
|
|
"Constraint" name,
|
|
"Type" "char",
|
|
"Columns" name[],
|
|
"Index" regclass,
|
|
"Expr" text) LANGUAGE PLPGSQL STABLE AS
|
|
$BODY$
|
|
DECLARE
|
|
schema_name name = split_part(pattern, '.', 1);
|
|
table_name name = split_part(pattern, '.', 2);
|
|
BEGIN
|
|
IF schema_name = '' OR table_name = '' THEN
|
|
schema_name := current_schema();
|
|
table_name := pattern;
|
|
END IF;
|
|
|
|
RETURN QUERY
|
|
SELECT cl.oid::regclass,
|
|
c.conname,
|
|
c.contype,
|
|
array(SELECT attname FROM pg_attribute a, unnest(conkey) k WHERE a.attrelid = cl.oid AND k = a.attnum),
|
|
c.conindid::regclass,
|
|
c.consrc
|
|
FROM pg_class cl, pg_constraint c
|
|
WHERE format('%I.%I', cl.relnamespace::regnamespace::name, cl.relname) LIKE format('%I.%s', schema_name, table_name)
|
|
AND c.conrelid = cl.oid
|
|
ORDER BY cl.relname, c.conname;
|
|
END
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_triggers(rel regclass)
|
|
RETURNS TABLE("Trigger" name,
|
|
"Type" smallint,
|
|
"Function" regproc,
|
|
"Definition" text) LANGUAGE SQL STABLE AS
|
|
$BODY$
|
|
SELECT t.tgname,
|
|
t.tgtype,
|
|
t.tgfoid::regproc,
|
|
-- remove 'CREATE TRIGGER' part from definition
|
|
substring(pg_get_triggerdef(t.oid) from 15)
|
|
FROM pg_trigger t
|
|
WHERE t.tgrelid = rel
|
|
ORDER BY t.tgname;
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_triggersp(pattern text)
|
|
RETURNS TABLE("Table" regclass,
|
|
"Trigger" name,
|
|
"Type" smallint,
|
|
"Function" regproc,
|
|
"Definition" text) LANGUAGE PLPGSQL STABLE AS
|
|
$BODY$
|
|
DECLARE
|
|
schema_name name = split_part(pattern, '.', 1);
|
|
table_name name = split_part(pattern, '.', 2);
|
|
BEGIN
|
|
IF schema_name = '' OR table_name = '' THEN
|
|
schema_name := current_schema();
|
|
table_name := pattern;
|
|
END IF;
|
|
|
|
RETURN QUERY
|
|
SELECT t.tgrelid::regclass,
|
|
t.tgname,
|
|
t.tgtype,
|
|
t.tgfoid::regproc,
|
|
-- remove 'CREATE TRIGGER' part from definition
|
|
substring(pg_get_triggerdef(t.oid) from 15)
|
|
FROM pg_class cl, pg_trigger t
|
|
WHERE format('%I.%I', cl.relnamespace::regnamespace::name, cl.relname) LIKE format('%I.%s', schema_name, table_name)
|
|
AND t.tgrelid = cl.oid
|
|
ORDER BY t.tgrelid, t.tgname;
|
|
END
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_subtables(rel regclass)
|
|
RETURNS TABLE("Child" regclass,
|
|
"Tablespace" name) LANGUAGE SQL STABLE AS
|
|
$BODY$
|
|
SELECT objid::regclass, (SELECT t.spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace)
|
|
FROM pg_depend d, pg_class c
|
|
WHERE d.refobjid = rel
|
|
AND d.deptype = 'n'
|
|
AND d.classid = 'pg_class'::regclass
|
|
AND d.objid = c.oid
|
|
ORDER BY d.refobjid, d.objid;
|
|
$BODY$;
|
|
|
|
CREATE OR REPLACE FUNCTION test.show_subtablesp(pattern text)
|
|
RETURNS TABLE("Parent" regclass,
|
|
"Child" regclass,
|
|
"Tablespace" name) LANGUAGE PLPGSQL STABLE AS
|
|
$BODY$
|
|
DECLARE
|
|
schema_name name = split_part(pattern, '.', 1);
|
|
table_name name = split_part(pattern, '.', 2);
|
|
BEGIN
|
|
IF schema_name = '' OR table_name = '' THEN
|
|
schema_name := current_schema();
|
|
table_name := pattern;
|
|
END IF;
|
|
|
|
RETURN QUERY
|
|
SELECT refobjid::regclass,
|
|
objid::regclass,
|
|
(SELECT t.spcname FROM pg_class cc, pg_tablespace t WHERE cc.oid = d.objid AND t.oid = cc.reltablespace)
|
|
FROM pg_class c, pg_depend d
|
|
WHERE format('%I.%I', c.relnamespace::regnamespace::name, c.relname) LIKE format('%I.%s', schema_name, table_name)
|
|
AND d.refobjid = c.oid
|
|
AND d.deptype = 'n'
|
|
AND d.classid = 'pg_class'::regclass
|
|
ORDER BY d.refobjid, d.objid;
|
|
END
|
|
$BODY$;
|