chatai/postgrest_v12.2.8/test/spec/fixtures/schema.sql

3802 lines
100 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

SET check_function_bodies = false;
-- Hide warnings because casts on domains would show a lot of:
-- WARNING: cast will be ignored because the source data type is a domain
SET client_min_messages = error;
CREATE SCHEMA public;
CREATE SCHEMA postgrest;
CREATE SCHEMA private;
CREATE SCHEMA test;
CREATE SCHEMA تست;
CREATE SCHEMA extensions;
CREATE SCHEMA v1;
CREATE SCHEMA v2;
CREATE SCHEMA "SPECIAL ""@/\#~_-";
CREATE SCHEMA "EXTRA ""@/\#~_-";
COMMENT ON SCHEMA v1 IS 'v1 schema';
COMMENT ON SCHEMA v2 IS 'v2 schema';
COMMENT ON SCHEMA test IS
$$My API title
My API description
that spans
multiple lines$$;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
SET search_path = public, pg_catalog;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
--
-- Name: jwt_token; Type: TYPE; Schema: public; Owner: -
--
CREATE TYPE public.jwt_token AS (
token text
);
SET search_path = test, pg_catalog;
--
-- Name: enum_menagerie_type; Type: TYPE; Schema: test; Owner: -
--
CREATE TYPE enum_menagerie_type AS ENUM (
'foo',
'bar'
);
create type bit as enum ('one', 'two');
SET search_path = postgrest, pg_catalog;
--
-- Name: check_role_exists(); Type: FUNCTION; Schema: postgrest; Owner: -
--
CREATE FUNCTION check_role_exists() RETURNS trigger
LANGUAGE plpgsql
AS $$
begin
if not exists (select 1 from pg_roles as r where r.rolname = new.rolname) then
raise foreign_key_violation using message = 'Cannot create user with unknown role: ' || new.rolname;
return null;
end if;
return new;
end
$$;
--
-- Name: set_authors_only_owner(); Type: FUNCTION; Schema: postgrest; Owner: -
--
CREATE FUNCTION set_authors_only_owner() RETURNS trigger
LANGUAGE plpgsql
AS $$
begin
NEW.owner = current_setting('request.jwt.claims')::json->>'id';
RETURN NEW;
end
$$;
--
-- Name: update_owner(); Type: FUNCTION; Schema: postgrest; Owner: -
--
CREATE FUNCTION update_owner() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.owner = current_user;
RETURN NEW;
END;
$$;
SET search_path = test, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
create domain "text/plain" as text;
create domain "text/html" as text;
create domain "text/xml" as pg_catalog.xml;
create domain "application/octet-stream" as bytea;
create domain "image/png" as bytea;
create domain "application/vnd.twkb" as bytea;
create domain "application/openapi+json" as json;
create domain "application/geo+json" as jsonb;
create domain "application/vnd.geo2+json" as jsonb;
create domain "application/json" as json;
create domain "application/vnd.pgrst.object" as json;
create domain "text/tab-separated-values" as text;
create domain "text/csv" as text;
create domain "*/*" as bytea;
CREATE TABLE items (
id bigserial primary key
);
CREATE TABLE items2 (
id bigserial primary key
);
CREATE TABLE items3 (
id bigserial primary key
);
CREATE FUNCTION search(id BIGINT) RETURNS SETOF items
LANGUAGE plpgsql
STABLE
AS $$BEGIN
RETURN QUERY SELECT items.id FROM items WHERE items.id=search.id;
END$$;
CREATE FUNCTION always_true(test.items) RETURNS boolean
LANGUAGE sql IMMUTABLE
AS $$ SELECT true $$;
CREATE FUNCTION computed_overload(test.items) RETURNS boolean
LANGUAGE sql IMMUTABLE
AS $$ SELECT true $$;
CREATE FUNCTION computed_overload(test.items2) RETURNS boolean
LANGUAGE sql IMMUTABLE
AS $$ SELECT true $$;
CREATE FUNCTION is_first(test.items) RETURNS boolean
LANGUAGE sql IMMUTABLE
AS $$ SELECT $1.id = 1 $$;
CREATE FUNCTION anti_id(test.items) RETURNS bigint
LANGUAGE sql IMMUTABLE
AS $_$ SELECT $1.id * -1 $_$;
SET search_path = public, pg_catalog;
CREATE FUNCTION always_false(test.items) RETURNS boolean
LANGUAGE sql IMMUTABLE
AS $$ SELECT false $$;
create table public_consumers (
id serial not null unique,
name text not null check (name <> ''),
primary key (id)
);
create table public_orders (
id serial not null unique,
consumer integer not null references public_consumers(id),
number integer not null,
primary key (id)
);
SET search_path = تست, pg_catalog;
CREATE TABLE موارد (
هویت bigint NOT NULL
);
SET search_path = test, pg_catalog;
create view orders_view as
select * from public.public_orders;
create view consumers_view as
select * from public.public_consumers;
create view consumers_view_view as
select * from consumers_view;
create view public.consumers_extra as
select * from consumers_view;
create view consumers_extra_view as
select * from public.consumers_extra;
--
-- Name: getitemrange(bigint, bigint); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION getitemrange(min bigint, max bigint) RETURNS SETOF items
LANGUAGE sql
STABLE
AS $_$
SELECT * FROM test.items WHERE id > $1 AND id <= $2;
$_$;
--
-- Name: version(); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION noparamsproc() RETURNS text
LANGUAGE sql
IMMUTABLE
AS $$
SELECT a FROM (VALUES ('Return value of no parameters procedure.')) s(a);
$$;
--
-- Name: login(text, text); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION login(id text, pass text) RETURNS public.jwt_token
LANGUAGE sql SECURITY DEFINER
STABLE
AS $$
SELECT jwt.sign(
row_to_json(r), 'reallyreallyreallyreallyverysafe'
) as token
FROM (
SELECT rolname::text, id::text
FROM postgrest.auth
WHERE id = id AND pass = pass
) r;
$$;
CREATE FUNCTION varied_arguments(
double double precision,
"varchar" character varying,
"boolean" boolean,
date date,
money money,
enum enum_menagerie_type,
arr text[],
"integer" integer default 42,
json json default '{}',
jsonb jsonb default '{}'
) RETURNS json
LANGUAGE sql
IMMUTABLE
AS $_$
SELECT json_build_object(
'double', double,
'varchar', "varchar",
'boolean', "boolean",
'date', date,
'money', money,
'enum', enum,
'arr', arr,
'integer', "integer",
'json', json,
'jsonb', jsonb
);
$_$;
COMMENT ON FUNCTION varied_arguments(double precision, character varying, boolean, date, money, enum_menagerie_type, text[], integer, json, jsonb) IS
$_$An RPC function
Just a test for RPC function arguments$_$;
CREATE FUNCTION varied_arguments_openapi(
double double precision,
"varchar" character varying,
"boolean" boolean,
date date,
money money,
enum enum_menagerie_type,
text_arr text[],
int_arr int[],
bool_arr boolean[],
char_arr char[],
varchar_arr varchar[],
bigint_arr bigint[],
numeric_arr numeric[],
json_arr json[],
jsonb_arr jsonb[],
"integer" integer default 42,
json json default '{}',
jsonb jsonb default '{}'
) RETURNS json
LANGUAGE sql
IMMUTABLE
AS $_$
SELECT json_build_object(
'double', double,
'varchar', "varchar",
'boolean', "boolean",
'date', date,
'money', money,
'enum', enum,
'text_arr', text_arr,
'int_arr', int_arr,
'bool_arr', bool_arr,
'char_arr', char_arr,
'varchar_arr', varchar_arr,
'bigint_arr', bigint_arr,
'numeric_arr', numeric_arr,
'json_arr', json_arr,
'jsonb_arr', jsonb_arr,
'integer', "integer",
'json', json,
'jsonb', jsonb
);
$_$;
COMMENT ON FUNCTION varied_arguments_openapi(double precision, character varying, boolean, date, money, enum_menagerie_type, text[], int[], boolean[], char[], varchar[], bigint[], numeric[], json[], jsonb[], integer, json, jsonb) IS
$_$An RPC function
Just a test for RPC function arguments$_$;
CREATE FUNCTION json_argument(arg json) RETURNS text
LANGUAGE sql
IMMUTABLE
AS $_$
SELECT json_typeof(arg);
$_$;
--
-- Name: jwt_test(); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION jwt_test() RETURNS public.jwt_token
LANGUAGE sql SECURITY DEFINER
IMMUTABLE
AS $$
SELECT jwt.sign(
row_to_json(r), 'reallyreallyreallyreallyverysafe'
) as token
FROM (
SELECT 'joe'::text as iss, 'fun'::text as sub, 'everyone'::text as aud,
1300819380 as exp, 1300819380 as nbf, 1300819380 as iat,
'foo'::text as jti, 'postgrest_test'::text as role,
true as "http://postgrest.com/foo"
) r;
$$;
CREATE OR REPLACE FUNCTION switch_role() RETURNS void
LANGUAGE plpgsql
AS $$
declare
user_id text;
Begin
user_id = (current_setting('request.jwt.claims')::json->>'id')::text;
if user_id = '1'::text then
execute 'set local role postgrest_test_author';
elseif user_id = '2'::text then
execute 'set local role postgrest_test_default_role';
elseif user_id = '3'::text then
RAISE EXCEPTION 'Disabled ID --> %', user_id USING HINT = 'Please contact administrator';
/* else */
/* execute 'set local role postgrest_test_anonymous'; */
end if;
end
$$;
CREATE FUNCTION get_current_user() RETURNS text
LANGUAGE sql
STABLE
AS $$
SELECT current_user::text;
$$;
--
-- Name: reveal_big_jwt(); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION reveal_big_jwt() RETURNS TABLE (
iss text, sub text, exp bigint,
nbf bigint, iat bigint, jti text, "http://postgrest.com/foo" boolean
)
AS $$
SELECT current_setting('request.jwt.claims')::json->>'iss' as iss,
current_setting('request.jwt.claims')::json->>'sub' as sub,
(current_setting('request.jwt.claims')::json->>'exp')::bigint as exp,
(current_setting('request.jwt.claims')::json->>'nbf')::bigint as nbf,
(current_setting('request.jwt.claims')::json->>'iat')::bigint as iat,
current_setting('request.jwt.claims')::json->>'jti' as jti,
(current_setting('request.jwt.claims')::json->>'http://postgrest.com/foo')::boolean as "http://postgrest.com/foo";
$$ LANGUAGE sql SECURITY DEFINER STABLE;
CREATE FUNCTION assert() RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
ASSERT false, 'bad thing';
END;
$$;
--
-- Name: problem(); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION problem() RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
RAISE 'bad thing';
END;
$$;
--
-- Name: sayhello(text); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION sayhello(name text) RETURNS text
LANGUAGE sql
IMMUTABLE
AS $_$
SELECT 'Hello, ' || $1;
$_$;
--
-- Name: callcounter(); Type: FUNCTION; Schema: test; Owner: -
--
CREATE SEQUENCE callcounter_count START 1;
CREATE FUNCTION callcounter() RETURNS bigint
LANGUAGE sql
AS $_$
SELECT nextval('test.callcounter_count');
$_$;
CREATE FUNCTION reset_sequence(name TEXT, value INTEGER) RETURNS void
SECURITY DEFINER
LANGUAGE plpgsql AS $_$
BEGIN
EXECUTE FORMAT($exec$
ALTER SEQUENCE %s RESTART WITH %s
$exec$, name, value);
END
$_$;
--
-- Name: singlejsonparam(json); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION singlejsonparam(single_param json) RETURNS json
LANGUAGE sql
IMMUTABLE
AS $_$
SELECT single_param;
$_$;
--
-- Name: test_empty_rowset(); Type: FUNCTION; Schema: test; Owner: -
--
CREATE FUNCTION test_empty_rowset() RETURNS SETOF integer
LANGUAGE sql
IMMUTABLE
AS $$
SELECT null::int FROM (SELECT 1) a WHERE false;
$$;
SET search_path = postgrest, pg_catalog;
--
-- Name: auth; Type: TABLE; Schema: postgrest; Owner: -
--
CREATE TABLE auth (
id character varying NOT NULL,
rolname name DEFAULT 'postgrest_test_author'::name NOT NULL,
pass character(60) NOT NULL
);
SET search_path = test, pg_catalog;
--
-- Name: authors_only; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE authors_only (
owner character varying NOT NULL,
secret character varying NOT NULL
);
--
-- Name: auto_incrementing_pk; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE auto_incrementing_pk (
id integer NOT NULL,
nullable_string character varying,
non_nullable_string character varying NOT NULL,
inserted_at timestamp with time zone DEFAULT now()
);
--
-- Name: auto_incrementing_pk_id_seq; Type: SEQUENCE; Schema: test; Owner: -
--
CREATE SEQUENCE auto_incrementing_pk_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: auto_incrementing_pk_id_seq; Type: SEQUENCE OWNED BY; Schema: test; Owner: -
--
ALTER SEQUENCE auto_incrementing_pk_id_seq OWNED BY auto_incrementing_pk.id;
--
-- Name: clients; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE clients (
id integer primary key,
name text NOT NULL
);
--
-- Name: complex_items; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE complex_items (
id bigint NOT NULL,
name text,
settings json,
arr_data integer[],
"field-with_sep" integer default 1 not null
);
--
-- Name: compound_pk; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE compound_pk (
-- those columns should not be referenced to in a foreign key anywhere
-- to allow the InsertSpec.Inserting into VIEWs.returns a location header
-- to test properly
PRIMARY KEY (k1, k2),
k1 integer NOT NULL,
k2 text NOT NULL,
extra integer
);
CREATE VIEW compound_pk_view AS
SELECT * FROM compound_pk;
--
-- Name: empty_table; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE empty_table (
k character varying NOT NULL,
extra character varying NOT NULL
);
--
-- Name: private_table; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE private_table ();
--
-- Name: has_count_column; Type: VIEW; Schema: test; Owner: -
--
CREATE VIEW has_count_column AS
SELECT 1 AS count;
--
-- Name: has_fk; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE has_fk (
id bigint NOT NULL,
auto_inc_fk integer,
simple_fk character varying(255)
);
--
-- Name: has_fk_id_seq; Type: SEQUENCE; Schema: test; Owner: -
--
CREATE SEQUENCE has_fk_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: has_fk_id_seq; Type: SEQUENCE OWNED BY; Schema: test; Owner: -
--
ALTER SEQUENCE has_fk_id_seq OWNED BY has_fk.id;
--
-- Name: insertable_view_with_join; Type: VIEW; Schema: test; Owner: -
--
CREATE VIEW insertable_view_with_join AS
SELECT has_fk.id,
has_fk.auto_inc_fk,
has_fk.simple_fk,
auto_incrementing_pk.nullable_string,
auto_incrementing_pk.non_nullable_string,
auto_incrementing_pk.inserted_at
FROM (has_fk
JOIN auto_incrementing_pk USING (id));
--
-- Name: json_table; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE json_table (
data json
);
--
-- Name: materialized_view; Type: MATERIALIZED VIEW; Schema: test; Owner: -
--
CREATE MATERIALIZED VIEW materialized_view AS
SELECT version() AS version
WITH NO DATA;
--
-- Name: menagerie; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE menagerie (
"integer" integer NOT NULL,
double double precision NOT NULL,
"varchar" character varying NOT NULL,
"boolean" boolean NOT NULL,
date date NOT NULL,
money money NOT NULL,
enum enum_menagerie_type NOT NULL
);
--
-- Name: no_pk; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE no_pk (
a character varying,
b character varying
);
CREATE TABLE only_pk (
id integer primary key
);
--
-- Name: nullable_integer; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE nullable_integer (
a integer
);
--
-- Name: insertonly; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE insertonly (
v text NOT NULL
);
--
-- Name: projects; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE projects (
id integer primary key,
name text NOT NULL,
client_id integer REFERENCES clients(id)
);
alter table projects rename constraint projects_client_id_fkey to client;
--
-- Name: projects_view; Type: VIEW; Schema: test; Owner: -
--
CREATE VIEW projects_view AS
SELECT projects.id,
projects.name,
projects.client_id
FROM projects;
CREATE VIEW projects_view_alt AS
SELECT projects.id as t_id,
projects.name,
projects.client_id as t_client_id
FROM projects;
CREATE TABLE sponsors (
id integer primary key,
name varchar(20) not null
);
CREATE TABLE competitors (
id integer primary key,
sponsor_id integer references sponsors(id),
full_name varchar(40) not null
);
CREATE VIEW test_null_pk_competitors_sponsors AS
SELECT c.id, s.id as sponsor_id
FROM competitors c
LEFT JOIN sponsors s on c.sponsor_id = s.id;
CREATE RULE test_null_pk_competitors_sponsors AS
ON INSERT TO test_null_pk_competitors_sponsors DO INSTEAD
INSERT INTO competitors(id, full_name, sponsor_id)
VALUES (new.id, 'Competitor without sponsor', new.sponsor_id)
RETURNING id, sponsor_id;
--
-- Name: simple_pk; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE simple_pk (
PRIMARY KEY (k),
k character varying NOT NULL,
extra character varying NOT NULL
);
CREATE TABLE simple_pk2 (
PRIMARY KEY (k),
k character varying NOT NULL,
extra character varying NOT NULL
);
CREATE TABLE users (
id integer primary key,
name text NOT NULL
);
CREATE TABLE users_projects (
user_id integer NOT NULL REFERENCES users(id),
project_id integer NOT NULL REFERENCES projects(id),
PRIMARY KEY (project_id, user_id)
);
CREATE TABLE tasks (
id integer primary key,
name text NOT NULL,
project_id integer REFERENCES projects(id)
);
alter table tasks rename constraint tasks_project_id_fkey to project;
CREATE OR REPLACE VIEW filtered_tasks AS
SELECT id AS "myId", name, project_id AS "projectID"
FROM tasks
WHERE project_id IN (
SELECT id FROM projects WHERE id = 1
) AND
project_id IN (
SELECT project_id FROM users_projects WHERE user_id = 1
);
CREATE TABLE users_tasks (
user_id integer NOT NULL REFERENCES users(id),
task_id integer NOT NULL REFERENCES tasks(id),
primary key (task_id, user_id)
);
CREATE TABLE comments (
id integer primary key,
commenter_id integer NOT NULL,
user_id integer NOT NULL,
task_id integer NOT NULL,
content text NOT NULL
);
alter table only comments
add constraint "user" foreign key (commenter_id) references users(id),
add constraint comments_task_id_fkey foreign key (task_id, user_id) references users_tasks(task_id, user_id);
CREATE TABLE files (
project_id integer NOT NULL,
filename text NOT NULL,
content text NOT NULL,
PRIMARY KEY (project_id, filename)
);
CREATE TABLE touched_files (
user_id integer NOT NULL,
task_id integer NOT NULL,
project_id integer NOT NULL,
filename text NOT NULL,
constraint fk_users_tasks foreign key (user_id, task_id) references users_tasks (user_id, task_id) on delete cascade on update cascade,
constraint fk_upload foreign key (project_id, filename) references files (project_id,filename) on delete cascade on update cascade,
primary key(user_id, task_id, project_id, filename)
);
create table private.articles (
id integer primary key,
body text,
owner name not null
);
create table private.article_stars (
article_id integer not null,
user_id integer not null,
created_at timestamp without time zone default now() not null,
primary key (article_id, user_id)
);
alter table only private.article_stars
add constraint article foreign key (article_id) references private.articles(id),
add constraint "user" foreign key (user_id) references test.users(id);
CREATE VIEW limited_article_stars AS
SELECT article_id, user_id, created_at FROM private.article_stars;
CREATE VIEW "articleStars" AS
SELECT article_stars.article_id AS "articleId",
article_stars.user_id AS "userId",
article_stars.created_at AS "createdAt"
FROM private.article_stars;
CREATE VIEW articles AS
SELECT articles.id,
articles.body,
articles.owner
FROM private.articles;
--
-- Name: tsearch; Type: TABLE; Schema: test; Owner: -
--
CREATE TABLE tsearch (
text_search_vector tsvector
);
CREATE TABLE "Escap3e;" (
"so6meIdColumn" integer primary key
);
CREATE TABLE "ghostBusters" (
"escapeId" integer not null references "Escap3e;"("so6meIdColumn")
);
CREATE TABLE "withUnique" (
uni text UNIQUE,
extra text
);
CREATE TABLE clashing_column (
t text
);
--
-- Name: id; Type: DEFAULT; Schema: test; Owner: -
--
ALTER TABLE ONLY auto_incrementing_pk ALTER COLUMN id SET DEFAULT nextval('auto_incrementing_pk_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: test; Owner: -
--
ALTER TABLE ONLY has_fk ALTER COLUMN id SET DEFAULT nextval('has_fk_id_seq'::regclass);
SET search_path = postgrest, pg_catalog;
--
-- Name: auth_pkey; Type: CONSTRAINT; Schema: postgrest; Owner: -
--
ALTER TABLE ONLY auth
ADD CONSTRAINT auth_pkey PRIMARY KEY (id);
SET search_path = test, pg_catalog;
--
-- Name: authors_only_pkey; Type: CONSTRAINT; Schema: test; Owner: -
--
ALTER TABLE ONLY authors_only
ADD CONSTRAINT authors_only_pkey PRIMARY KEY (secret);
--
-- Name: auto_incrementing_pk_pkey; Type: CONSTRAINT; Schema: test; Owner: -
--
ALTER TABLE ONLY auto_incrementing_pk
ADD CONSTRAINT auto_incrementing_pk_pkey PRIMARY KEY (id);
--
-- Name: complex_items_pkey; Type: CONSTRAINT; Schema: test; Owner: -
--
ALTER TABLE ONLY complex_items
ADD CONSTRAINT complex_items_pkey PRIMARY KEY (id);
--
-- Name: has_fk_pkey; Type: CONSTRAINT; Schema: test; Owner: -
--
ALTER TABLE ONLY has_fk
ADD CONSTRAINT has_fk_pkey PRIMARY KEY (id);
--
-- Name: menagerie_pkey; Type: CONSTRAINT; Schema: test; Owner: -
--
ALTER TABLE ONLY menagerie
ADD CONSTRAINT menagerie_pkey PRIMARY KEY ("integer");
SET search_path = postgrest, pg_catalog;
--
-- Name: ensure_auth_role_exists; Type: TRIGGER; Schema: postgrest; Owner: -
--
CREATE CONSTRAINT TRIGGER ensure_auth_role_exists AFTER INSERT OR UPDATE ON auth NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE PROCEDURE check_role_exists();
SET search_path = private, pg_catalog;
--
-- Name: articles_owner_track; Type: TRIGGER; Schema: private; Owner: -
--
CREATE TRIGGER articles_owner_track BEFORE INSERT OR UPDATE ON articles FOR EACH ROW EXECUTE PROCEDURE postgrest.update_owner();
SET search_path = test, pg_catalog;
--
-- Name: secrets_owner_track; Type: TRIGGER; Schema: test; Owner: -
--
CREATE TRIGGER secrets_owner_track BEFORE INSERT OR UPDATE ON authors_only FOR EACH ROW EXECUTE PROCEDURE postgrest.set_authors_only_owner();
SET search_path = test, pg_catalog;
--
-- Name: has_fk_fk_fkey; Type: FK CONSTRAINT; Schema: test; Owner: -
--
ALTER TABLE ONLY has_fk
ADD CONSTRAINT has_fk_fk_fkey FOREIGN KEY (auto_inc_fk) REFERENCES auto_incrementing_pk(id);
--
-- Name: has_fk_simple_fk_fkey; Type: FK CONSTRAINT; Schema: test; Owner: -
--
ALTER TABLE ONLY has_fk
ADD CONSTRAINT has_fk_simple_fk_fkey FOREIGN KEY (simple_fk) REFERENCES simple_pk(k);
create table addresses (
id int not null unique,
address text not null
);
create table orders (
id int not null unique,
name text not null,
billing_address_id int references addresses(id),
shipping_address_id int references addresses(id)
);
alter table orders rename constraint orders_billing_address_id_fkey to billing;
alter table orders rename constraint orders_shipping_address_id_fkey to shipping;
CREATE FUNCTION getproject(id int) RETURNS SETOF projects
LANGUAGE sql
AS $_$
SELECT * FROM test.projects WHERE id = $1;
$_$;
CREATE FUNCTION get_projects_below(id int) RETURNS SETOF projects
LANGUAGE sql
AS $_$
SELECT * FROM test.projects WHERE id < $1;
$_$;
CREATE FUNCTION get_projects_above(id int) RETURNS SETOF projects
LANGUAGE sql
AS $_$
SELECT * FROM test.projects WHERE id > $1;
$_$ ROWS 1;
CREATE FUNCTION getallprojects() RETURNS SETOF projects
LANGUAGE sql
AS $_$
SELECT * FROM test.projects;
$_$ ROWS 2019;
CREATE FUNCTION setprojects(id_l int, id_h int, name text) RETURNS SETOF projects
LANGUAGE sql
AS $_$
update test.projects set name = $3 WHERE id >= $1 AND id <= $2 returning *;
$_$;
-- domains on tables are only supported from pg 11 on
DO $do$BEGIN
IF (SELECT current_setting('server_version_num')::INT >= 110000) THEN
CREATE DOMAIN projects_domain AS projects;
CREATE FUNCTION getproject_domain(id int) RETURNS SETOF projects_domain
LANGUAGE sql
STABLE
AS $_$
SELECT projects::projects_domain FROM test.projects WHERE id = $1;
$_$;
END IF;
END$do$;
create table images (
name text not null,
img bytea not null
);
create view images_base64 as (
-- encoding in base64 puts a '\n' after every 76 character due to legacy reasons, this is isn't necessary here so it's removed
select name, replace(encode(img, 'base64'), E'\n', '') as img from images
);
create function test.ret_enum(val text) returns test.enum_menagerie_type as $$
select val::test.enum_menagerie_type;
$$ language sql;
create domain one_nine as integer check (value >= 1 and value <= 9);
create function test.ret_array() returns integer[] as $$
select '{1,2,3}'::integer[];
$$ language sql;
create function test.ret_domain(val integer) returns test.one_nine as $$
select val::test.one_nine;
$$ language sql;
create function test.ret_range(low integer, up integer) returns int4range as $$
select int4range(low, up);
$$ language sql;
create function test.ret_setof_integers() returns setof integer as $$
values (1), (2), (3);
$$ language sql;
-- this function does not have named arguments and should be ignored
-- if it's not ignored, it will break the test for the function before
create function test.ret_setof_integers(int, int) returns integer AS $$
values (1);
$$ language sql;
create function test.ret_scalars() returns table(
a text, b test.enum_menagerie_type, c test.one_nine, d int4range
) as $$
select row('scalars'::text, enum_first(null::test.enum_menagerie_type),
1::test.one_nine, int4range(10, 20));
$$ language sql;
create type test.point_2d as (x integer, y integer);
create function test.ret_point_2d() returns test.point_2d as $$
select row(10, 5)::test.point_2d;
$$ language sql;
create function test.ret_point_overloaded(x int, y int) returns test.point_2d as $$
select row(x, y)::test.point_2d;
$$ language sql;
create function test.ret_point_overloaded(x json) returns json as $$
select $1;
$$ language sql;
-- domains on composite types are only supported from pg 11 on
do $do$begin
if (SELECT current_setting('server_version_num')::int >= 110000) then
create domain test.composite_domain as test.point_2d;
create function test.ret_composite_domain() returns test.composite_domain as $$
select row(10, 5)::test.composite_domain;
$$ language sql;
end if;
end$do$;
create type private.point_3d as (x integer, y integer, z integer);
create function test.ret_point_3d() returns private.point_3d as $$
select row(7, -3, 4)::private.point_3d;
$$ language sql;
create function test.ret_void() returns void as '' language sql;
create or replace function test.ret_null() returns int as $$
select null::int;
$$ language sql;
create function test.ret_image() returns "image/png" as $$
select i.img::"image/png" from test.images i where i.name = 'A.png';
$$ language sql;
create function test.single_article(id integer) returns test.articles as $$
select a.* from test.articles a where a.id = $1;
$$ language sql;
create function test.get_guc_value(name text) returns text as $$
select nullif(current_setting(name), '')::text;
$$ language sql;
-- Get the JSON type GUC values
create function test.get_guc_value(prefix text, name text) returns text as $$
select nullif(current_setting(prefix)::json->>name, '')::text;
$$ language sql;
create table w_or_wo_comma_names ( name text );
create table items_with_different_col_types (
int_data integer,
text_data text,
bool_data bool,
bin_data bytea,
char_data character varying,
date_data date,
real_data real,
time_data time
);
-- Tables used for testing complex boolean logic with and/or query params
create table entities (
id integer primary key,
name text,
arr integer[],
text_search_vector tsvector
);
create table child_entities (
id integer primary key,
name text,
parent_id integer references entities(id)
);
create view child_entities_view as table child_entities;
create table grandchild_entities (
id integer primary key,
name text,
parent_id integer references child_entities(id),
or_starting_col text,
and_starting_col text,
jsonb_col jsonb
);
-- Table used for testing range operators
create table ranges (
id integer primary key,
range numrange
);
-- OpenAPI description tests
comment on table child_entities is 'child_entities comment';
comment on column child_entities.id is 'child_entities id comment';
comment on column child_entities.name is 'child_entities name comment. Can be longer than sixty-three characters long';
comment on view child_entities_view is 'child_entities_view comment';
comment on column child_entities_view.id is 'child_entities_view id comment';
comment on column child_entities_view.name is 'child_entities_view name comment. Can be longer than sixty-three characters long';
comment on table grandchild_entities is
$$grandchild_entities summary
grandchild_entities description
that spans
multiple lines$$;
-- Used for testing that having the same return column name as the proc name
-- doesn't conflict with the required output, details in #901
create function test.test() returns table(test text, value int) as $$
values ('hello', 1);
$$ language sql;
create function test.privileged_hello(name text) returns text as $$
select 'Privileged hello to ' || $1;
$$ language sql;
create function test.get_tsearch() returns setof test.tsearch AS $$
SELECT * FROM test.tsearch;
$$ language sql;
create table test.being (
being int primary key not null
);
create table test.descendant (
descendant int primary key not null,
being int references test.being(being)
);
create table test.part (
part int primary key not null
);
create table test.being_part (
being int not null references test.being(being),
part int not null references test.part(part),
primary key(being, part)
);
create function test.single_out_param(num int, OUT num_plus_one int) AS $$
select num + 1;
$$ language sql;
create function test.single_json_out_param(a int, b text, OUT my_json json) AS $$
select json_build_object('a', a, 'b', b);
$$ language sql;
create function test.many_out_params(OUT my_json json, OUT num int, OUT str text) AS $$
select '{"a": 1, "b": "two"}'::json, 3, 'four'::text;
$$ language sql;
create function test.single_inout_param(INOUT num int) AS $$
select num + 1;
$$ language sql;
create function test.many_inout_params(INOUT num int, INOUT str text, INOUT b bool DEFAULT true) AS $$
select num, str, b;
$$ language sql;
create function test.single_column_table_return () returns table (a text) AS $$
select 'A'::text;
$$ language sql;
create function test.multi_column_table_return () returns table (a text, b text) AS $$
select 'A'::text, 'B'::text;
$$ language sql;
CREATE FUNCTION test.variadic_param(VARIADIC v TEXT[] DEFAULT '{}') RETURNS text[]
IMMUTABLE
LANGUAGE SQL AS $$
SELECT v
$$;
CREATE FUNCTION test.sayhello_variadic(name TEXT, VARIADIC v TEXT[]) RETURNS text
IMMUTABLE
LANGUAGE SQL AS $$
SELECT 'Hello, ' || name
$$;
create or replace function test.raise_pt402() returns void as $$
begin
raise sqlstate 'PT402' using message = 'Payment Required',
detail = 'Quota exceeded',
hint = 'Upgrade your plan';
end;
$$ language plpgsql;
create or replace function test.raise_bad_pt() returns void as $$
begin
raise sqlstate 'PT40A' using message = 'Wrong';
end;
$$ language plpgsql;
create or replace function test.send_body_status_403() returns json as $$
begin
perform set_config('response.status', '403', true);
return json_build_object('message', 'invalid user or password');
end;
$$ language plpgsql;
create or replace function test.send_bad_status() returns json as $$
begin
perform set_config('response.status', 'bad', true);
return null;
end;
$$ language plpgsql;
create or replace function test.get_projects_and_guc_headers() returns setof test.projects as $$
set local "response.headers" = '[{"X-Test": "key1=val1; someValue; key2=val2"}, {"X-Test-2": "key1=val1"}]';
select * from test.projects;
$$ language sql;
create or replace function test.get_int_and_guc_headers(num int) returns integer as $$
set local "response.headers" = '[{"X-Test":"key1=val1; someValue; key2=val2"},{"X-Test-2":"key1=val1"}]';
select num;
$$ language sql;
create or replace function test.bad_guc_headers_1() returns void as $$
set local "response.headers" = '{"X-Test": "invalid structure for headers"}';
$$ language sql;
create or replace function test.bad_guc_headers_2() returns void as $$
set local "response.headers" = '["invalid", "structure", "for", "headers"]';
$$ language sql;
create or replace function test.bad_guc_headers_3() returns void as $$
set local "response.headers" = '{"X-Test": "invalid", "X-Test-2": "structure", "X-Test-3": "for headers"}';
$$ language sql;
create or replace function test.set_cookie_twice() returns void as $$
set local "response.headers" = '[{"Set-Cookie": "sessionid=38afes7a8; HttpOnly; Path=/"}, {"Set-Cookie": "id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly"}]';
$$ language sql;
create or replace function test.three_defaults(a int default 1, b int default 2, c int default 3) returns int as $$
select a + b + c
$$ language sql;
create or replace function test.overloaded() returns setof int as $$
values (1), (2), (3);
$$ language sql;
create or replace function test.overloaded(json) returns table(x int, y text) as $$
select * from json_to_recordset($1) as r(x int, y text);
$$ language sql;
create or replace function test.overloaded(a int, b int) returns int as $$
select a + b
$$ language sql;
create or replace function test.overloaded(a text, b text, c text) returns text as $$
select a || b || c
$$ language sql;
create or replace function test.overloaded_default(opt_param text default 'Code w7') returns setof test.tasks as $$
select * from test.tasks where name like opt_param;
$$ language sql;
create or replace function test.overloaded_default(must_param int) returns jsonb as $$
select row_to_json(r)::jsonb from (select must_param as val) as r;
$$ language sql;
create or replace function test.overloaded_default(a int, opt_param text default 'Design IOS') returns setof test.tasks as $$
select * from test.tasks where name like opt_param and id > a;
$$ language sql;
create or replace function test.overloaded_default(a int, must_param int) returns jsonb as $$
select row_to_json(r)::jsonb from (select a, must_param as val) as r;
$$ language sql;
create or replace function test.overloaded_html_form() returns setof int as $$
values (1), (2), (3);
$$ language sql;
create or replace function test.overloaded_html_form(single_param json) returns json as $$
select single_param;
$$ language sql;
create or replace function test.overloaded_html_form(a int, b int) returns int as $$
select a + b
$$ language sql;
create or replace function test.overloaded_html_form(a text, b text, c text) returns text as $$
select a || b || c
$$ language sql;
create or replace function test.overloaded_same_args(arg integer) returns json as $$
select json_build_object(
'type', pg_typeof(arg),
'value', arg
);
$$ language sql;
create or replace function test.overloaded_same_args(arg xml) returns json as $$
select json_build_object(
'type', pg_typeof(arg),
'value', arg
);
$$ language sql;
create or replace function test.overloaded_same_args(arg text, num integer default 0) returns json as $$
select json_build_object(
'type', pg_typeof(arg),
'value', arg
);
$$ language sql;
create table test.leak(
id serial primary key,
blob bytea
);
create function test.leak(blob bytea) returns void as $$ begin end; $$ language plpgsql;
create table test.perf_articles(
id integer not null,
body text not null
);
create table test.employees(
first_name text,
last_name text,
salary money,
company text,
occupation text,
primary key(first_name, last_name)
);
create table test.tiobe_pls(
name text primary key,
rank smallint
);
create table test.single_unique(
unique_key integer unique not null,
value text
);
create table test.compound_unique(
key1 integer not null,
key2 integer not null,
value text,
unique(key1, key2)
);
create table test.family_tree (
id text not null primary key,
name text not null,
parent text
);
alter table only test.family_tree add constraint pptr foreign key (parent) references test.family_tree(id);
create table test.managers (
id integer primary key,
name text
);
create table test.organizations (
id integer primary key,
name text,
referee integer references organizations(id),
auditor integer references organizations(id),
manager_id integer references managers(id)
);
alter table only test.organizations rename constraint organizations_manager_id_fkey to manager;
create table private.authors(
id integer primary key,
name text
);
create table private.publishers(
id integer primary key,
name text
);
create table private.books(
id integer primary key,
title text,
publication_year smallint,
author_id integer references private.authors(id),
first_publisher_id integer references private.publishers(id)
);
create view test.authors as select id, name from private.authors;
create view test.publishers as select id, name from private.publishers;
create view test.books as select id, title, publication_year, author_id, first_publisher_id from private.books;
create view test.forties_books as select id, title, publication_year, author_id from private.books where publication_year >= 1940 and publication_year < 1950;
create view test.fifties_books as select id, title, publication_year, author_id from private.books where publication_year >= 1950 and publication_year < 1960;
create view test.sixties_books as select id, title, publication_year, author_id from private.books where publication_year >= 1960 and publication_year < 1970;
create table person (
id integer primary key,
name character varying not null);
create table message (
id integer primary key,
body text not null default '',
sender bigint not null references person(id),
recipient bigint not null references person(id));
create view person_detail as
select p.id, p.name, s.count as sent, r.count as received
from person p
join lateral (select message.sender, count(message.id) as count from message group by message.sender) s on s.sender = p.id
join lateral (select message.recipient, count(message.id) as count from message group by message.recipient) r on r.recipient = p.id;
create table space(
id integer primary key,
name text);
create table zone(
id integer primary key,
name text,
zone_type_id integer,
space_id integer references space(id));
-- foreign table tests
create extension file_fdw;
create server import_csv foreign data wrapper file_fdw;
create foreign table projects_dump (
id integer,
name text,
client_id integer
) server import_csv options ( filename '/tmp/projects_dump.csv', format 'csv');
comment on foreign table projects_dump is
$$A temporary projects dump
Just a test for foreign tables$$;
create table "UnitTest"(
"idUnitTest" integer primary key,
"nameUnitTest" text
);
create table json_arr(
id integer primary key,
data json
);
create table jsonb_test(
id integer primary key,
data jsonb
);
create view test.authors_books_number as
select
id,
name,
(
select
count(*)
from forties_books where author_id = authors.id
) as num_in_forties,
(
select
count(*)
from fifties_books where author_id = authors.id
) as num_in_fifties,
(
select
count(*)
from sixties_books where author_id = authors.id
) as num_in_sixties,
(
select
count(*)
from (
select id
from forties_books where author_id = authors.id
union
select id
from fifties_books where author_id = authors.id
union
select id
from sixties_books where author_id = authors.id
) _
) as num_in_all_decades
from private.authors;
create view test.authors_have_book_in_decade as
select
id,
name,
case
when (x.id in (select author_id from test.forties_books))
then true
else false
end as has_book_in_forties,
case
when (x.id in (select author_id from test.fifties_books))
then true
else false
end as has_book_in_fifties,
case
when (x.id in (select author_id from test.sixties_books))
then true
else false
end as has_book_in_sixties
from private.authors x;
create view test.authors_have_book_in_decade2 as
select
id,
name,
coalesce(
(select true from test.forties_books where author_id=x.id limit 1),
false
) as has_book_in_forties,
coalesce(
(select true from test.fifties_books where author_id=x.id limit 1),
false
) as has_book_in_fifties,
coalesce(
(select true from test.sixties_books where author_id=x.id limit 1),
false
) as has_book_in_sixties
from private.authors x;
create view test.forties_and_fifties_books as
select x.id, x.title, x.publication_year, y.name as first_publisher, x.author_id
from (
select id, title, publication_year, author_id, first_publisher_id from private.books
where publication_year >= 1940 and publication_year < 1960) x
join private.publishers y on y.id = x.first_publisher_id;
create view test.odd_years_publications as
with
odd_years_books as(
select id, title, publication_year, author_id, first_publisher_id
from private.books
where publication_year % 2 <> 0
)
select
x.id, x.title, x.publication_year,
y.name as first_publisher, x.author_id
from odd_years_books x
join private.publishers y on y.id = x.first_publisher_id;
create view test.projects_count_grouped_by as
select
client_id,
count(id) as number_of_projects
from projects
group by client_id;
create view test.authors_w_entities as
select
id,
name,
(
select json_agg(id)
from test.entities
where id not in (
select parent_id from test.child_entities
)
) as entities
from private.authors;
CREATE TABLE test."Foo"(
id int primary key,
name text
);
CREATE TABLE test.bar(
id int primary key,
name text,
"fooId" int references "Foo"(id)
);
CREATE VIEW test.foos as select id,name from "Foo";
CREATE VIEW test.bars as select id, "fooId", name from bar;
create materialized view materialized_projects as
select id, name, client_id from projects;
comment on materialized view materialized_projects is
$$A materialized view for projects
Just a test for materialized views$$;
-- Tests for updatable, insertable and deletable views
create view test.projects_auto_updatable_view_with_pk as
select id, name, client_id from test.projects;
create view test.projects_auto_updatable_view_without_pk as
select name, client_id from test.projects;
create view test.projects_view_without_triggers as
select distinct id, name, client_id from test.projects;
create or replace function test.test_for_views_with_triggers() returns trigger as $$
begin
return null;
end;
$$ language plpgsql;
create view test.projects_view_with_all_triggers_with_pk as
select distinct id, name, client_id from test.projects;
create trigger projects_view_with_all_triggers_with_pk_insert
instead of insert on test.projects_view_with_all_triggers_with_pk
for each row execute procedure test_for_views_with_triggers();
create trigger projects_view_with_all_triggers_with_pk_update
instead of update on test.projects_view_with_all_triggers_with_pk
for each row execute procedure test_for_views_with_triggers();
create trigger projects_view_with_all_triggers_with_pk_delete
instead of delete on test.projects_view_with_all_triggers_with_pk
for each row execute procedure test_for_views_with_triggers();
create view test.projects_view_with_all_triggers_without_pk as
select distinct name, client_id from test.projects;
create trigger projects_view_with_all_triggers_without_pk_insert
instead of insert on test.projects_view_with_all_triggers_without_pk
for each row execute procedure test_for_views_with_triggers();
create trigger projects_view_with_all_triggers_without_pk_update
instead of update on test.projects_view_with_all_triggers_without_pk
for each row execute procedure test_for_views_with_triggers();
create trigger projects_view_with_all_triggers_without_pk_delete
instead of delete on test.projects_view_with_all_triggers_without_pk
for each row execute procedure test_for_views_with_triggers();
create view test.projects_view_with_insert_trigger as
select distinct id, name, client_id from test.projects;
create trigger projects_view_with_insert_trigger_insert
instead of insert on test.projects_view_with_insert_trigger
for each row execute procedure test_for_views_with_triggers();
create view test.projects_view_with_update_trigger as
select distinct id, name, client_id from test.projects;
create trigger projects_view_with_update_trigger_update
instead of update on test.projects_view_with_update_trigger
for each row execute procedure test_for_views_with_triggers();
create view test.projects_view_with_delete_trigger as
select distinct id, name, client_id from test.projects;
create trigger projects_view_with_delete_trigger_delete
instead of delete on test.projects_view_with_delete_trigger
for each row execute procedure test_for_views_with_triggers();
create or replace function test."quotedFunction"("user" text, "fullName" text, "SSN" text)
returns jsonb AS $$
select format('{"user": "%s", "fullName": "%s", "SSN": "%s"}', "user", "fullName", "SSN")::jsonb;
$$ language sql;
create table private.player (
id integer not null,
first_name text not null,
last_name text not null,
birth_date date,
primary key (last_name, id, first_name, birth_date) -- just for testing a long compound pk
);
create table test.contract (
tournament text not null,
time tsrange not null,
purchase_price int not null,
id integer not null,
first_name text not null,
last_name text not null,
birth_date date,
foreign key (last_name, id, first_name, birth_date) references private.player
);
create view test.player_view as select * from private.player;
create view test.contract_view as select * from test.contract;
create type public.my_type AS enum ('something');
create function test.test_arg(my_arg public.my_type) returns text as $$
select 'foobar'::text;
$$ language sql;
create extension if not exists ltree with schema public;
create table test.ltree_sample (
path public.ltree
);
CREATE FUNCTION test.number_of_labels(test.ltree_sample) RETURNS integer AS $$
SELECT nlevel($1.path)
$$ language sql;
create extension if not exists isn with schema extensions;
create table test.isn_sample (
id extensions.isbn,
name text
);
create function test.is_valid_isbn(input text) returns boolean as $$
select is_valid(input::isbn);
$$ language sql;
create table "Server Today"(
"cHostname" text,
"Just A Server Model" text
);
create table test.pgrst_reserved_chars (
"*id*" integer,
":arr->ow::cast" text,
"(inside,parens)" text,
"a.dotted.column" text,
" col w space " text
);
CREATE TABLE test.openapi_types(
"a_character_varying" character varying,
"a_character" character(1),
"a_text" text,
"a_boolean" boolean,
"a_smallint" smallint,
"a_integer" integer,
"a_bigint" bigint,
"a_numeric" numeric,
"a_real" real,
"a_double_precision" double precision,
"a_json" json,
"a_jsonb" jsonb,
"a_text_arr" text[],
"a_int_arr" int[],
"a_bool_arr" boolean[],
"a_char_arr" char[],
"a_varchar_arr" varchar[],
"a_bigint_arr" bigint[],
"a_numeric_arr" numeric[],
"a_json_arr" json[],
"a_jsonb_arr" jsonb[]
);
CREATE TABLE test.openapi_defaults(
"text" text default 'default',
"boolean" boolean default false,
"integer" integer default 42,
"numeric" numeric default 42.2,
"date" date default '1900-01-01'::date,
"time" time default '13:00:00'::time without time zone
);
create function add_them(a integer, b integer)
returns integer as $$
select a + b;
$$ language sql;
create or replace function root() returns "application/openapi+json" as $_$
declare
openapi json = $$
{
"swagger": "2.0",
"info":{
"title":"PostgREST API",
"description":"This is a dynamic API generated by PostgREST"
}
}
$$;
begin
return openapi;
end
$_$ language plpgsql;
create or replace function welcome() returns "text/plain" as $$
select 'Welcome to PostgREST'::"text/plain";
$$ language sql;
create or replace function welcome_twice() returns setof "text/plain" as $$
select 'Welcome to PostgREST'
union all
select 'Welcome to PostgREST';
$$ language sql;
create or replace function "welcome.html"() returns "text/html" as $_$
select $$
<html>
<head>
<title>PostgREST</title>
</head>
<body>
<h1>Welcome to PostgREST</h1>
</body>
</html>
$$::"text/html";
$_$ language sql;
create view getallprojects_view as
select * from getallprojects();
create view get_projects_above_view as
select * from get_projects_above(1);
CREATE TABLE web_content (
id integer,
name text,
p_web_id integer references web_content(id),
primary key (id)
);
CREATE FUNCTION getallusers() RETURNS SETOF users AS $$
SELECT * FROM test.users;
$$ LANGUAGE sql STABLE;
create table app_users (
id integer primary key,
email text unique not null,
password text not null
);
create table private.pages (
link int not null unique
, url text
);
create table private.referrals (
site text
, link int references private.pages(link) not null
);
create view test.pages as select * from private.pages;
create view test.referrals as select * from private.referrals;
create table big_projects (
big_project_id serial primary key,
name text
);
create table sites (
site_id serial primary key
, name text
, main_project_id int null references big_projects (big_project_id)
);
alter table sites rename constraint sites_main_project_id_fkey to main_project;
create table jobs (
job_id uuid
, name text
, site_id int not null references sites (site_id)
, big_project_id int not null references big_projects (big_project_id)
, primary key(job_id, site_id, big_project_id)
);
create view main_jobs as
select * from jobs
where site_id in (select site_id from sites where main_project_id is not null);
-- junction in a private schema, just to make sure we don't leak it on resource embedding
-- if it leaks it would show on the disambiguation error tests
create view private.priv_jobs as
select * from jobs;
-- tables to show our limitation when trying to do an m2m embed
-- with a junction table that has more than two foreign keys
create table whatev_projects (
id serial primary key,
name text
);
create table whatev_sites (
id serial primary key
, name text
);
create table whatev_jobs (
job_id uuid
, name text
, site_id_1 int not null references whatev_sites (id)
, project_id_1 int not null references whatev_projects (id)
, site_id_2 int not null references whatev_sites (id)
, project_id_2 int not null references whatev_projects (id)
, primary key(job_id, site_id_1, project_id_1, site_id_2, project_id_2)
);
-- circular reference
create table agents (
id int primary key
, name text
, department_id int
);
create table departments (
id int primary key
, name text
, head_id int references agents(id)
);
ALTER TABLE agents
ADD CONSTRAINT agents_department_id_fkey foreign key (department_id) REFERENCES departments(id);
-- composite key disambiguation
create table schedules (
id int primary key
, name text
, start_at timetz
, end_at timetz
);
create table activities (
id int
, schedule_id int
, car_id text
, camera_id text
, primary key (id, schedule_id)
);
alter table activities
add constraint schedule foreign key (schedule_id)
references schedules (id);
create table unit_workdays (
unit_id int
, day date
, fst_shift_activity_id int
, fst_shift_schedule_id int
, snd_shift_activity_id int
, snd_shift_schedule_id int
, primary key (unit_id, day)
);
alter table unit_workdays
add constraint fst_shift foreign key (fst_shift_activity_id, fst_shift_schedule_id)
references activities (id, schedule_id),
add constraint snd_shift foreign key (snd_shift_activity_id, snd_shift_schedule_id)
references activities (id, schedule_id);
create view unit_workdays_fst_shift as
select unit_id, day, fst_shift_activity_id, fst_shift_schedule_id
from unit_workdays
where fst_shift_activity_id is not null
and fst_shift_schedule_id is not null;
-- for a pre-request function
create or replace function custom_headers() returns void as $$
declare
user_agent text := current_setting('request.headers', true)::json->>'user-agent';
req_path text := current_setting('request.path', true);
req_accept text := current_setting('request.headers', true)::json->>'accept';
req_method text := current_setting('request.method', true);
begin
if user_agent similar to 'MSIE (6.0|7.0)' then
perform set_config('response.headers',
'[{"Cache-Control": "no-cache, no-store, must-revalidate"}]', true);
elsif req_path similar to '/(items|projects)' and req_accept = 'text/csv' then
perform set_config('response.headers',
format('[{"Content-Disposition": "attachment; filename=%s.csv"}]', trim('/' from req_path)), true);
elsif req_path similar to '/(clients|rpc/getallprojects)' then
perform set_config('response.headers',
'[{"Content-Type": "application/custom+json"}]', true);
elsif req_path = '/items' and
req_method similar to 'POST|PATCH|PUT|DELETE' then
perform set_config('response.headers',
'[{"X-Custom-Header": "mykey=myval"}]', true);
end if;
end; $$ language plpgsql;
create table private.stuff(
id integer primary key
, name text
);
create view test.stuff as select * from private.stuff;
create or replace function location_for_stuff() returns trigger as $$
begin
insert into private.stuff values (new.id, new.name);
if new.id is not null
then
perform set_config(
'response.headers'
, format('[{"Location": "/%s?id=eq.%s&overriden=true"}]', tg_table_name, new.id)
, true
);
end if;
return new;
end
$$ language plpgsql security definer;
create trigger location_for_stuff instead of insert on test.stuff for each row execute procedure test.location_for_stuff();
create or replace function status_205_for_updated_stuff() returns trigger as $$
begin
update private.stuff set id = new.id, name = new.name;
perform set_config('response.status' , '205' , true);
return new;
end
$$ language plpgsql security definer;
create trigger status_205_for_updated_stuff instead of update on test.stuff for each row execute procedure test.status_205_for_updated_stuff();
create table loc_test (
id int primary key
, c text
);
-- tables to test multi schema access in one instance
create table v1.parents (
id int primary key
, name text
);
create table v1.children (
id int primary key
, name text
, parent_id int
, constraint parent foreign key(parent_id)
references v1.parents(id)
);
create function v1.get_parents_below(id int)
returns setof v1.parents as $$
select * from v1.parents where id < $1;
$$ language sql;
create table v2.parents (
id int primary key
, name text
);
create table v2.children (
id int primary key
, name text
, parent_id int
, constraint parent foreign key(parent_id)
references v2.parents(id)
);
create table v2.another_table (
id int primary key
, another_value text
);
create function v2.get_parents_below(id int)
returns setof v2.parents as $$
select * from v2.parents where id < $1;
$$ language sql;
create function v2.get_plain_text()
returns test."text/plain" as $$
select 'plain'::test."text/plain";
$$ language sql;
create domain v2."text/special" as text;
create function v2.get_special_text()
returns v2."text/special" as $$
select 'special'::v2."text/special";
$$ language sql;
create or replace function v2.special_trans (state v2."text/special", next v2.another_table)
returns v2."text/special" as $$
select 'special'::v2."text/special";
$$ language sql;
drop aggregate if exists v2.special_agg(v2.another_table);
create aggregate v2.special_agg (v2.another_table) (
initcond = ''
, stype = v2."text/special"
, sfunc = v2.special_trans
);
create or replace function v2.plain_trans (state test."text/plain", next v2.another_table)
returns test."text/plain" as $$
select 'plain'::test."text/plain";
$$ language sql;
drop aggregate if exists v2.plain_agg(v2.another_table);
create aggregate v2.plain_agg (v2.another_table) (
initcond = ''
, stype = test."text/plain"
, sfunc = v2.plain_trans
);
create table private.screens (
id serial primary key,
name text not null default 'new screen'
);
create table private.labels (
id serial primary key,
name text not null default 'new label'
);
create table private.label_screen (
label_id int not null references private.labels(id) on update cascade on delete cascade,
screen_id int not null references private.screens(id) on update cascade on delete cascade,
constraint label_screen_pkey primary key (label_id, screen_id)
);
create view test.labels as
select * from private.labels;
create view test.screens as
select * from private.screens;
create view test.label_screen as
select * from private.label_screen;
create table private.actors (
id int,
name text,
constraint actors_id primary key (id)
);
create table private.films (
id integer,
title text,
constraint films_id primary key (id)
);
create table private.personnages (
film_id int not null,
role_id int not null,
character text not null,
constraint personnages_film_id_role_id primary key (film_id, role_id),
constraint personnages_film_id_fkey foreign key (film_id) references private.films(id) not deferrable,
constraint personnages_role_id_fkey foreign key (role_id) references private.actors(id) not deferrable
);
create view test.actors as
select * from private.actors;
create view test.films as
select * from private.films;
create view test.personnages as
select * from private.personnages;
create table test.end_1(
id int primary key,
name text
);
create table test.end_2(
id int primary key,
name text
);
create table private.junction(
end_1_id int not null references test.end_1(id) on update cascade on delete cascade,
end_2_id int not null references test.end_2(id) on update cascade on delete cascade,
primary key (end_1_id, end_2_id)
);
create table test.schauspieler (
id int primary key,
name text
);
create table test.filme (
id int primary key,
titel text
);
create table test.rollen ();
create table private.rollen (
film_id int not null,
rolle_id int not null,
charakter text not null,
primary key (film_id, rolle_id),
foreign key (film_id) references test.filme(id),
foreign key (rolle_id) references test.schauspieler(id)
);
-- Tables used for testing embedding between partitioned tables
do $do$begin
-- partitioned tables using the PARTITION syntax are supported from pg v10
if (select current_setting('server_version_num')::int >= 100000) then
create table test.car_models(
name varchar(64) not null,
year int not null
) partition by list (year);
comment on table test.car_models is
$$A partitioned table
A test for partitioned tables$$;
create table test.car_models_2021 partition of test.car_models
for values in (2021);
create table test.car_models_default partition of test.car_models
for values in (1981,1997,2001,2013);
end if;
-- primary keys for partitioned tables are supported from pg v11
if (select current_setting('server_version_num')::int >= 110000) then
create table test.car_brands (
name varchar(64) primary key
);
alter table test.car_models add primary key (name, year);
alter table test.car_models add column car_brand_name varchar(64) references test.car_brands(name);
end if;
-- foreign keys referencing partitioned tables are supported from pg v12
if (select current_setting('server_version_num')::int >= 120000) then
create table test.car_model_sales(
date varchar(64) not null,
quantity int not null,
car_model_name varchar(64),
car_model_year int,
primary key (date, car_model_name, car_model_year),
foreign key (car_model_name, car_model_year) references test.car_models (name, year)
) partition by range (date);
create table test.car_model_sales_202101 partition of test.car_model_sales
for values from ('2021-01-01') to ('2021-01-31');
create table test.car_model_sales_default partition of test.car_model_sales
default;
create table test.car_racers (
name varchar(64) not null primary key,
car_model_name varchar(64),
car_model_year int,
foreign key (car_model_name, car_model_year) references test.car_models (name, year)
);
create table test.car_dealers (
name varchar(64) not null,
city varchar(64) not null,
primary key (name, city)
) partition by list (city);
create table test.car_dealers_springfield partition of test.car_dealers
for values in ('Springfield');
create table test.car_dealers_default partition of test.car_dealers
default;
create table test.car_models_car_dealers (
car_model_name varchar(64) not null,
car_model_year int not null,
car_dealer_name varchar(64) not null,
car_dealer_city varchar(64) not null,
quantity int not null,
foreign key (car_model_name, car_model_year) references test.car_models (name, year),
foreign key (car_dealer_name, car_dealer_city) references test.car_dealers (name, city),
primary key (car_model_name, car_model_year, car_dealer_name, car_dealer_city, quantity)
) partition by range (quantity);
create table test.car_models_car_dealers_10to20 partition of test.car_models_car_dealers
for values from (10) to (20);
create table test.car_models_car_dealers_default partition of test.car_models_car_dealers
default;
end if;
end$do$;
create or replace function test.unnamed_json_param(json) returns json as $$
select $1;
$$ language sql;
create or replace function test.unnamed_text_param(text) returns "text/plain" as $$
select $1::"text/plain";
$$ language sql;
create or replace function test.unnamed_xml_param(pg_catalog.xml) returns "text/xml" as $$
select $1::"text/xml";
$$ language sql;
create or replace function test.unnamed_bytea_param(bytea) returns "application/octet-stream" as $$
select $1::"application/octet-stream";
$$ language sql;
create or replace function test.unnamed_int_param(int) returns int as $$
select $1;
$$ language sql;
create or replace function test.overloaded_unnamed_param(json) returns json as $$
select $1;
$$ language sql;
create or replace function test.overloaded_unnamed_param(bytea) returns "application/octet-stream" as $$
select $1::"application/octet-stream";
$$ language sql;
create or replace function test.overloaded_unnamed_param(text) returns "text/plain" as $$
select $1::"text/plain";
$$ language sql;
create or replace function test.overloaded_unnamed_param() returns int as $$
select 1;
$$ language sql;
create or replace function test.overloaded_unnamed_param(x int, y int) returns int as $$
select x + y;
$$ language sql;
create or replace function test.overloaded_unnamed_json_jsonb_param(json) returns json as $$
select $1;
$$ language sql;
create or replace function test.overloaded_unnamed_json_jsonb_param(jsonb) returns jsonb as $$
select $1;
$$ language sql;
create or replace function test.overloaded_unnamed_json_jsonb_param(x int, y int) returns int as $$
select x + y;
$$ language sql;
create table products(
id int primary key
, name text
);
create table suppliers(
id int primary key
, name text
);
create table products_suppliers(
product_id int references products(id),
supplier_id int references suppliers(id),
primary key (product_id, supplier_id)
);
create table trade_unions(
id int primary key
, name text
);
create table suppliers_trade_unions(
supplier_id int references suppliers(id),
trade_union_id int references trade_unions(id),
primary key (supplier_id, trade_union_id)
);
CREATE TABLE client (
id int primary key
, name text
);
CREATE TABLE contact (
id int primary key
, name text
, clientid int references client(id)
);
CREATE TABLE clientinfo (
id serial primary key
, clientid int references client(id)
, other text
);
CREATE TABLE chores (
id int primary key
, name text
, done bool
);
CREATE TABLE deferrable_unique_constraint (
col INT UNIQUE DEFERRABLE INITIALLY IMMEDIATE
);
CREATE FUNCTION raise_constraint(deferred BOOL DEFAULT FALSE) RETURNS void
LANGUAGE plpgsql AS $$
BEGIN
IF deferred THEN
SET CONSTRAINTS ALL DEFERRED;
END IF;
INSERT INTO deferrable_unique_constraint VALUES (1), (1);
END$$;
-- This view is not used in any requests but just parsed by the pfkSourceColumns query.
-- XMLTABLE is only supported from PG 10 on
DO $do$
BEGIN
IF current_setting('server_version_num')::INT >= 100000 THEN
CREATE VIEW test.xml AS
SELECT *
FROM (SELECT ''::xml AS data) _,
XMLTABLE(
''
PASSING data
COLUMNS id int PATH '@id',
premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'
);
END IF;
END
$do$;
-- https://github.com/PostgREST/postgrest/issues/1543
CREATE TYPE complex AS (
r double precision,
i double precision
);
CREATE TABLE test.fav_numbers (
num complex,
person text
);
-- https://github.com/PostgREST/postgrest/issues/2075
create table test.arrays (
id int primary key,
numbers int[],
numbers_mult int[][]
);
-- This procedure is to confirm that procedures don't show up in the OpenAPI output right now.
-- Procedures are not supported, yet.
do $do$begin
if (select current_setting('server_version_num')::int >= 110000) then
CREATE PROCEDURE test.unsupported_proc ()
LANGUAGE SQL AS '';
end if;
end $do$;
CREATE FUNCTION public.dummy(int) RETURNS int
LANGUAGE SQL AS $$ SELECT 1 $$;
-- This aggregate is to confirm that aggregates don't show up in the OpenAPI output.
CREATE AGGREGATE test.unsupported_agg (*) (
SFUNC = public.dummy,
STYPE = int
);
create table limited_update_items(
id int primary key
, name text
);
create table limited_update_items_cpk(
id int
, name text
, primary key (id, name)
);
create table limited_update_items_no_pk(
id int
, name text
);
create view limited_update_items_view as
select * from limited_update_items;
create view limited_update_items_wnonuniq_view as
select *, 'static'::text as static from limited_update_items;
create view limited_update_items_cpk_view as
select * from limited_update_items_cpk;
create table limited_delete_items(
id int primary key
, name text
);
create table limited_delete_items_cpk(
id int
, name text
, primary key (id, name)
);
create table limited_delete_items_no_pk(
id int
, name text
);
create view limited_delete_items_view as
select * from limited_delete_items;
create view limited_delete_items_wnonuniq_view as
select *, 'static'::text as static from limited_delete_items;
create view limited_delete_items_cpk_view as
select * from limited_delete_items_cpk;
create function reset_table(tbl_name text default '', tbl_data json default '[]') returns void as $_$ begin
execute format(
$$
delete from %I where true; -- WHERE is required for pg-safeupdate tests
insert into %I
select * from json_populate_recordset(null::%I, $1);
$$::text,
tbl_name, tbl_name, tbl_name)
using tbl_data;
end; $_$ language plpgsql volatile;
-- tables for ensuring we generate real junctions for many-to-many relationships
create table plate (
plate_id int primary key
);
create table well (
well_id int primary key,
plate_id int not null,
parent_well_id int,
CONSTRAINT well_parent_well_id_fkey
FOREIGN KEY(parent_well_id)
REFERENCES well(well_id),
CONSTRAINT well_plate_id_fkey
FOREIGN KEY(plate_id)
REFERENCES plate(plate_id)
);
create table plate_plan_step (
plate_plan_step_id int primary key,
from_well_id int,
to_well_id int,
to_plate_id int,
CONSTRAINT plate_plan_step_from_well_id_fkey
FOREIGN KEY(from_well_id)
REFERENCES well(well_id),
CONSTRAINT plate_plan_step_to_plate_id_fkey
FOREIGN KEY(to_plate_id)
REFERENCES plate(plate_id),
CONSTRAINT plate_plan_step_to_well_id_fkey
FOREIGN KEY(to_well_id)
REFERENCES well(well_id)
);
CREATE FUNCTION test.return_scalar_xml() RETURNS "text/xml"
LANGUAGE sql AS $$
SELECT '<my-xml-tag/>'::"text/xml"
$$;
CREATE OR REPLACE FUNCTION "welcome.xml"() RETURNS "text/xml"
LANGUAGE sql AS $_$
select $$
<html>
<head>
<title>PostgREST</title>
</head>
<body>
<h1>Welcome to PostgREST</h1>
</body>
</html>$$::"text/xml";
$_$;
CREATE TABLE test.xmltest (
id integer primary key,
xml pg_catalog.xml NOT NULL
);
create or replace function test.xml_handler_transition (state "text/xml", next test.xmltest)
returns "text/xml" as $$
select xmlconcat2(state, next.xml)::"text/xml";
$$ language sql;
create or replace function test.xml_handler_final (data "text/xml")
returns "text/xml" as $$
select data;
$$ language sql;
drop aggregate if exists test.text_xml_agg(test.xmltest);
create aggregate test.text_xml_agg (test.xmltest) (
stype = "text/xml"
, sfunc = test.xml_handler_transition
, finalfunc = test.xml_handler_final
);
CREATE TABLE oid_test(
id int,
oid_col oid,
oid_array_col oid[]);
CREATE TABLE private.internal_job
(
id integer NOT NULL,
parent_id integer,
CONSTRAINT internal_job_pkey PRIMARY KEY (id),
CONSTRAINT parent_fk FOREIGN KEY (parent_id) REFERENCES private.internal_job (id)
);
CREATE VIEW test.job AS
SELECT j.id, j.parent_id
FROM private.internal_job j;
-- https://github.com/PostgREST/postgrest/issues/2238
CREATE TABLE series (
id bigint PRIMARY KEY,
title text NOT NULL
);
CREATE TABLE adaptation_notifications (
id bigint PRIMARY KEY,
series bigint REFERENCES series(id),
status text
);
CREATE VIEW series_popularity AS
SELECT id, random() AS popularity_score
FROM series;
-- https://github.com/PostgREST/postgrest/issues/1643
CREATE TABLE test.test (
id BIGINT NOT NULL PRIMARY KEY,
parent_id BIGINT CONSTRAINT parent_test REFERENCES test(id)
);
CREATE OR REPLACE VIEW test.view_test AS
SELECT id FROM test.test;
create extension if not exists postgis with schema extensions;
create table shops (
id int primary key
, address text
, shop_geom extensions.geometry(POINT, 4326)
);
create table shop_bles (
id int primary key
, name text
, coords extensions.geometry(POINT, 4326)
, range_area extensions.geometry(POLYGON, 4326)
, shop_id int references shops(id)
);
create function get_shop(id int) returns shops as $$
select * from shops where id = $1;
$$ language sql;
CREATE TABLE "SPECIAL ""@/\#~_-".languages(
id INT PRIMARY KEY,
name TEXT
);
CREATE TABLE "SPECIAL ""@/\#~_-".names(
id INT PRIMARY KEY,
name TEXT,
language_id INT REFERENCES "SPECIAL ""@/\#~_-".languages(id)
);
CREATE FUNCTION "SPECIAL ""@/\#~_-".computed_languages("SPECIAL ""@/\#~_-".names) RETURNS SETOF "SPECIAL ""@/\#~_-".languages ROWS 1 AS $$
SELECT * FROM "SPECIAL ""@/\#~_-".languages where id = $1.language_id;
$$ LANGUAGE sql;
CREATE FUNCTION "EXTRA ""@/\#~_-".get_val_special(val text) RETURNS text AS $$
SELECT val;
$$ LANGUAGE sql;
CREATE FUNCTION test.special_extended_schema(val text) RETURNS text AS $$
SELECT get_val_special(val);
$$ LANGUAGE sql;
CREATE TABLE do$llar$s (
a$num$ numeric
);
-- Tables and functions to test the pg-safeupdate library
CREATE TABLE test.safe_update_items(
id INT PRIMARY KEY,
name TEXT,
observation TEXT
);
CREATE TABLE test.safe_delete_items(
id INT PRIMARY KEY,
name TEXT,
observation TEXT
);
CREATE TABLE test.unsafe_update_items(
id INT PRIMARY KEY,
name TEXT,
observation TEXT
);
CREATE TABLE test.unsafe_delete_items(
id INT PRIMARY KEY,
name TEXT,
observation TEXT
);
CREATE OR REPLACE FUNCTION test.load_safeupdate() RETURNS VOID AS $$
BEGIN
LOAD 'safeupdate';
END; $$ LANGUAGE plpgsql SECURITY DEFINER;
-- This tests data representations over computed joins: even a lower case title should come back title cased.
DROP DOMAIN IF EXISTS public.titlecasetext CASCADE;
CREATE DOMAIN public.titlecasetext AS text;
CREATE OR REPLACE FUNCTION json(public.titlecasetext) RETURNS json AS $$
SELECT to_json(INITCAP($1::text));
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (public.titlecasetext AS json) WITH FUNCTION json(public.titlecasetext) AS IMPLICIT;
-- End of data representations specific stuff except for where the domain is used in the table.
CREATE TABLE designers (
id int primary key
, name public.titlecasetext
);
CREATE TABLE videogames (
id int primary key
, name text
, designer_id int references designers(id)
);
-- computed relationships
CREATE FUNCTION test.computed_designers(test.videogames) RETURNS SETOF test.designers AS $$
SELECT * FROM test.designers WHERE id = $1.designer_id;
$$ LANGUAGE sql STABLE ROWS 1;
CREATE FUNCTION test.computed_designers_noset(test.videogames) RETURNS test.designers AS $$
SELECT * FROM test.designers WHERE id = $1.designer_id;
$$ LANGUAGE sql STABLE;
CREATE FUNCTION test.computed_videogames(test.designers) RETURNS SETOF test.videogames AS $$
SELECT * FROM test.videogames WHERE designer_id = $1.id;
$$ LANGUAGE sql STABLE;
CREATE FUNCTION test.getallvideogames() RETURNS SETOF test.videogames AS $$
SELECT * FROM test.videogames;
$$ LANGUAGE sql STABLE;
CREATE FUNCTION test.getalldesigners() RETURNS SETOF test.designers AS $$
SELECT * FROM test.designers;
$$ LANGUAGE sql STABLE;
-- self join for computed relationships
CREATE FUNCTION test.child_web_content(test.web_content) RETURNS SETOF test.web_content AS $$
SELECT * FROM test.web_content WHERE $1.id = p_web_id;
$$ LANGUAGE sql STABLE;
CREATE FUNCTION test.parent_web_content(test.web_content) RETURNS SETOF test.web_content AS $$
SELECT * FROM test.web_content WHERE $1.p_web_id = id;
$$ LANGUAGE sql STABLE ROWS 1;
-- overriding computed rels that empty the results
CREATE FUNCTION test.designers(test.videogames) RETURNS SETOF test.designers AS $$
SELECT * FROM test.designers WHERE FALSE;
$$ LANGUAGE sql STABLE ROWS 1;
CREATE FUNCTION test.videogames(test.designers) RETURNS SETOF test.videogames AS $$
SELECT * FROM test.videogames WHERE FALSE;
$$ LANGUAGE sql STABLE;
CREATE TABLE test.students(
id int
, code text
, name text
, primary key(id, code)
);
CREATE TABLE test.students_info(
id int
, code text
, address text
, primary key(id, code)
, foreign key (code, id) references test.students(code, id) on delete cascade
);
CREATE TABLE test.country(
id int primary key
, name text
);
CREATE TABLE test.capital(
id int primary key
, name text
, country_id int unique
, foreign key (country_id) references test.country(id)
);
CREATE FUNCTION test.allcountries() RETURNS SETOF test.country AS $$
SELECT * FROM test.country;
$$ LANGUAGE sql STABLE;
CREATE FUNCTION test.allcapitals() RETURNS SETOF test.capital AS $$
SELECT * FROM test.capital;
$$ LANGUAGE sql STABLE;
create view students_view as
select * from students;
create view students_info_view as
select * from students_info;
create table test.second (
id int primary key,
name text
);
create table test.first (
id int primary key,
name text,
second_id_1 int references test.second unique,
second_id_2 int references test.second unique
);
create table test.second_1 (
id int primary key,
name text
);
create table test.first_1 (
id int primary key,
name text,
second_id_1 int references test.second unique,
second_id_2 int references test.second unique
);
CREATE FUNCTION test.second_1(test.first_1) RETURNS SETOF test.second_1 AS $$
SELECT * FROM test.second_1 WHERE id = $1.second_id_1;
$$ LANGUAGE sql STABLE ROWS 1;
CREATE FUNCTION test.first_1(test.second_1) RETURNS SETOF test.first_1 AS $$
SELECT * FROM test.first_1 WHERE second_id_1 = $1.id;
$$ LANGUAGE sql STABLE ROWS 1;
create table fee (
fee_id int primary key
);
create table baz (
baz_id int primary key
);
create table janedoe (
janedoe_id int primary key,
baz_id int references baz(baz_id)
);
create table johnsmith (
johnsmith_id int primary key,
fee_id int references fee(fee_id),
baz_id int references baz(baz_id)
);
create or replace function jsbaz(fee) returns setof baz as $$
select b.*
from baz b
join johnsmith js on js.baz_id = b.baz_id
where js.fee_id = $1.fee_id
$$ stable language sql;
-- issue https://github.com/PostgREST/postgrest/issues/2518
create table a (
primary key (c1, c2),
c1 int,
c2 bool
);
create table b (
c2 bool,
c1 int,
foreign key (c1, c2) references a
);
create view test.v1 as table test.a;
create view test.v2 as table test.b;
-- issue https://github.com/PostgREST/postgrest/issues/2458
create table with_pk1 (pk1 int primary key);
create table with_pk2 (pk2 int primary key);
create view with_multiple_pks as
select * from with_pk1, with_pk2;
create function with_multiple_pks_insert() returns trigger
language plpgsql as $$
begin
insert into with_pk1 values (new.pk1) on conflict do nothing;
insert into with_pk2 values (new.pk2) on conflict do nothing;
return new;
end
$$;
create trigger ins instead of insert on with_multiple_pks
for each row execute procedure with_multiple_pks_insert();
-- issue https://github.com/PostgREST/postgrest/issues/2283
create view self_recursive_view as table projects;
create or replace view self_recursive_view as table self_recursive_view;
CREATE FUNCTION test.computed_clients(test.projects) RETURNS SETOF test.clients ROWS 1 AS $$
SELECT * FROM test.clients WHERE id = $1.client_id;
$$ LANGUAGE sql STABLE;
CREATE FUNCTION test.computed_projects(test.clients) RETURNS SETOF test.projects ROWS 1 AS $$
SELECT * FROM test.projects WHERE client_id = $1.id;
$$ LANGUAGE sql STABLE;
-- issue https://github.com/PostgREST/postgrest/issues/2459
create table public.i2459_simple_t1 (
id int primary key
);
create table public.i2459_simple_t2 (
t1_id int references public.i2459_simple_t1
);
create view i2459_simple_v1 as table public.i2459_simple_t1;
create view i2459_simple_v2 as
select t1_id as t1_id1, t1_id as t1_id2 from public.i2459_simple_t2;
create table public.i2459_composite_t1 (
primary key (a,b),
a int,
b int
);
create table public.i2459_composite_t2 (
t1_a int,
t1_b int,
constraint i2459_composite_t2_t1_a_t1_b_fkey foreign key (t1_a, t1_b) references public.i2459_composite_t1
);
create view i2459_composite_v1 as table public.i2459_composite_t1;
create view i2459_composite_v2 as
select t1_a as t1_a1,
t1_b as t1_b1,
t1_a as t1_a2,
t1_b as t1_b2
from public.i2459_composite_t2;
create table public.i2459_self_t (
id int primary key,
parent int references public.i2459_self_t,
type text
);
create view i2459_self_v1 as
select parent.parent as grandparent,
child.parent,
child.id
from public.i2459_self_t as parent
join public.i2459_self_t as child
on child.parent = parent.id
where child.type = 'A';
create view i2459_self_v2 as
select parent.parent as grandparent,
child.parent,
child.id
from public.i2459_self_t as parent
join public.i2459_self_t as child
on child.parent = parent.id
where child.type = 'B';
-- issue https://github.com/PostgREST/postgrest/issues/2548
CREATE TABLE public.ta (
a1 INT PRIMARY KEY,
a2 INT,
UNIQUE (a1, a2)
);
CREATE TABLE public.tb (
b1 INT REFERENCES public.ta (a1),
b2 INT,
FOREIGN KEY (b1, b2) REFERENCES public.ta (a1, a2)
);
CREATE VIEW test.va AS SELECT a1 FROM public.ta;
CREATE VIEW test.vb AS SELECT b1 FROM public.tb;
create table test.trash(
id int primary key
);
create table test.trash_details(
id int primary key references test.trash(id),
jsonb_col jsonb
);
CREATE TABLE test.groups (
name text PRIMARY KEY
);
CREATE TABLE test.yards (
id bigint PRIMARY KEY
);
CREATE TABLE test.group_yard (
id bigint NOT NULL,
group_id text NOT NULL REFERENCES test.groups(name),
yard_id bigint NOT NULL REFERENCES test.yards(id),
PRIMARY KEY (id, group_id, yard_id)
);
CREATE FUNCTION test.get_yards() RETURNS SETOF test.yards
LANGUAGE sql
AS $$
select * from test.yards;
$$;
create table test.posters(
id int primary key,
name text
);
create table test.subscriptions(
subscriber int references test.posters(id),
subscribed int references test.posters(id),
primary key(subscriber, subscribed)
);
-- Data representations feature
DROP DOMAIN IF EXISTS public.color CASCADE;
CREATE DOMAIN public.color AS INTEGER CHECK (VALUE >= 0 AND VALUE <= 16777215);
CREATE OR REPLACE FUNCTION color(json) RETURNS public.color AS $$
SELECT color($1 #>> '{}');
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION color(text) RETURNS public.color AS $$
SELECT (('x' || lpad((CASE WHEN SUBSTRING($1::text, 1, 1) = '#' THEN SUBSTRING($1::text, 2) ELSE $1::text END), 8, '0'))::bit(32)::int)::public.color;
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION json(public.color) RETURNS json AS $$
SELECT
CASE WHEN $1 IS NULL THEN to_json(''::text)
ELSE to_json('#' || lpad(upper(to_hex($1)), 6, '0'))
END;
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (public.color AS json) WITH FUNCTION json(public.color) AS IMPLICIT;
CREATE CAST (json AS public.color) WITH FUNCTION color(json) AS IMPLICIT;
CREATE CAST (text AS public.color) WITH FUNCTION color(text) AS IMPLICIT;
DROP DOMAIN IF EXISTS public.isodate CASCADE;
CREATE DOMAIN public.isodate AS timestamp with time zone;
CREATE OR REPLACE FUNCTION isodate(json) RETURNS public.isodate AS $$
SELECT isodate($1 #>> '{}');
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION isodate(text) RETURNS public.isodate AS $$
SELECT (replace($1, 'Z', '+00:00')::timestamp with time zone)::public.isodate;
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION json(public.isodate) RETURNS json AS $$
SELECT to_json(replace(to_json($1)#>>'{}', '+00:00', 'Z'));
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (public.isodate AS json) WITH FUNCTION json(public.isodate) AS IMPLICIT;
CREATE CAST (json AS public.isodate) WITH FUNCTION isodate(json) AS IMPLICIT;
-- We intentionally don't have this in order to test query string parsing doesn't try to fall back on JSON parsing.
-- CREATE CAST (text AS public.isodate) WITH FUNCTION isodate(text) AS IMPLICIT;
-- bytea_b64 is a base64-encoded binary string
DROP DOMAIN IF EXISTS public.bytea_b64 CASCADE;
CREATE DOMAIN public.bytea_b64 AS bytea;
CREATE OR REPLACE FUNCTION bytea_b64(json) RETURNS public.bytea_b64 AS $$
SELECT bytea_b64($1 #>> '{}');
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION bytea_b64(text) RETURNS public.bytea_b64 AS $$
-- allow unpadded base64
SELECT decode($1 || repeat('=', 4 - (length($1) % 4)), 'base64')::public.bytea_b64;
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION json(public.bytea_b64) RETURNS json AS $$
SELECT to_json(translate(encode($1, 'base64'), E'\n', ''));
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (public.bytea_b64 AS json) WITH FUNCTION json(public.bytea_b64) AS IMPLICIT;
CREATE CAST (json AS public.bytea_b64) WITH FUNCTION bytea_b64(json) AS IMPLICIT;
CREATE CAST (text AS public.bytea_b64) WITH FUNCTION bytea_b64(text) AS IMPLICIT;
-- unixtz is a timestamptz represented as an integer number of seconds since the Unix epoch
DROP DOMAIN IF EXISTS public.unixtz CASCADE;
CREATE DOMAIN public.unixtz AS timestamp with time zone;
CREATE OR REPLACE FUNCTION unixtz(json) RETURNS public.unixtz AS $$
SELECT unixtz($1 #>> '{}');
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION unixtz(text) RETURNS public.unixtz AS $$
SELECT (to_timestamp($1::numeric)::public.unixtz);
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION json(public.unixtz) RETURNS json AS $$
SELECT to_json(extract(epoch from $1)::bigint);
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (public.unixtz AS json) WITH FUNCTION json(public.unixtz) AS IMPLICIT;
CREATE CAST (json AS public.unixtz) WITH FUNCTION unixtz(json) AS IMPLICIT;
CREATE CAST (text AS public.unixtz) WITH FUNCTION unixtz(text) AS IMPLICIT;
DROP DOMAIN IF EXISTS public.monetary CASCADE;
CREATE DOMAIN public.monetary AS numeric(17,2);
CREATE OR REPLACE FUNCTION monetary(json) RETURNS public.monetary AS $$
SELECT monetary($1 #>> '{}');
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION monetary(text) RETURNS public.monetary AS $$
SELECT ($1::numeric)::public.monetary;
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION json(public.monetary) RETURNS json AS $$
SELECT to_json($1::text);
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (public.monetary AS json) WITH FUNCTION json(public.monetary) AS IMPLICIT;
CREATE CAST (json AS public.monetary) WITH FUNCTION monetary(json) AS IMPLICIT;
CREATE CAST (text AS public.monetary) WITH FUNCTION monetary(text) AS IMPLICIT;
CREATE TABLE datarep_todos (
id bigint primary key,
name text,
label_color public.color default 0,
due_at public.isodate default '2018-01-01'::date,
icon_image public.bytea_b64,
created_at public.unixtz default '2017-12-14 01:02:30'::timestamptz,
budget public.monetary default 0
);
CREATE TABLE datarep_next_two_todos (
id bigint primary key,
first_item_id bigint references datarep_todos(id),
second_item_id bigint references datarep_todos(id),
name text
);
CREATE VIEW datarep_todos_computed as (
SELECT id,
name,
label_color,
due_at,
(label_color / 2)::public.color as dark_color
FROM datarep_todos
);
-- view's name is alphabetically before projects
create view test.alpha_projects as
select c.id, p.name as pro_name, c.name as cli_name
from projects p join clients c on p.client_id = c.id;
-- view's name is alphabetically after projects
create view test.zeta_projects as
select c.id, p.name as pro_name, c.name as cli_name
from projects p join clients c on p.client_id = c.id;
CREATE VIEW test.complex_items_view AS
SELECT * FROM test.complex_items;
ALTER VIEW test.complex_items_view ALTER COLUMN name SET DEFAULT 'Default';
create table test.tbl_w_json(
id int,
data json
);
DO $do$
BEGIN
IF current_setting('server_version_num')::INT >= 100000 THEN
CREATE TABLE test.channels (
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
data jsonb DEFAULT '{"foo": "bar"}',
slug text
);
END IF;
END
$do$;
CREATE FUNCTION test.is_superuser() RETURNS boolean
LANGUAGE sql
AS $$
select current_setting('is_superuser')::boolean;
$$;
DO $do$
BEGIN
IF current_setting('server_version_num')::INT >= 120000 THEN
CREATE TABLE test.foo (
a text,
b text GENERATED ALWAYS AS (
case WHEN a = 'telegram' THEN 'im'
WHEN a = 'proton' THEN 'email'
WHEN a = 'infinity' THEN 'idea'
ELSE 'bad idea'
end) stored
);
END IF;
END
$do$;
create domain devil_int as int
default 666;
create table evil_friends(
id devil_int
, name text
);
create table evil_friends_with_column_default(
id devil_int default 420
, name text
);
create table bets (
id int
, data_json json
, data_jsonb jsonb
);
create index bets_data_json on bets ((data_json ->>'contractId'));
create index bets_data_jsonb on bets ((data_jsonb ->>'contractId'));
--- https://github.com/PostgREST/postgrest/issues/2862
create table profiles (
id uuid primary key,
username text null
);
create table user_friend (
id bigint primary key,
user1 uuid references profiles (id),
user2 uuid references profiles (id)
);
create table status(
id bigint primary key
);
create table tournaments(
id bigint primary key,
status bigint references status(id)
);
-- https://github.com/PostgREST/postgrest/issues/2861
CREATE TABLE bitchar_with_length (
bit bit(5),
char char(5),
bit_arr bit(5)[],
char_arr char(5)[]
);
-- https://github.com/PostgREST/postgrest/issues/1586
create or replace function char_param_select(char_ char(4), char_arr char(4)[])
returns table(char_ char, char_arr char[]) as $$
select $1, $2;
$$ language sql;
create or replace function bit_param_select(bit_ char(4), bit_arr char(4)[])
returns table(bit_ char, bit_arr char[]) as $$
select $1, $2;
$$ language sql;
create or replace function char_param_insert(char_ char(4), char_arr char(4)[])
returns void as $$
insert into bitchar_with_length(char, char_arr) values($1, $2);
$$ language sql;
create or replace function bit_param_insert(bit_ bit(4), bit_arr bit(4)[])
returns void as $$
insert into bitchar_with_length(bit, bit_arr) values($1, $2);
$$ language sql;
create function returns_record() returns record as $$
select * from projects limit 1;
$$ language sql;
create function returns_record_params(id int, name text) returns record as $$
select * from projects p where p.id = $1 and p.name like $2;
$$ language sql;
create function returns_setof_record() returns setof record as $$
select * from projects limit 2;
$$ language sql;
create function returns_setof_record_params(id int, name text) returns setof record as $$
select * from projects p where p.id >= $1 and p.name like $2;
$$ language sql;
create function raise_sqlstate_test1() returns void
language plpgsql
as $$
begin
raise sqlstate 'PGRST' USING
message = '{"code":"123","message":"ABC","details":"DEF","hint":"XYZ"}',
detail = '{"status":332,"status_text":"My Custom Status","headers":{"X-Header":"str"}}';
end
$$;
create function raise_sqlstate_test2() returns void
language plpgsql
as $$
begin
raise sqlstate 'PGRST' USING
message = '{"code":"123","message":"ABC"}',
detail = '{"status":332,"headers":{"X-Header":"str"}}';
end
$$;
create function raise_sqlstate_test3() returns void
language plpgsql
as $$
begin
raise sqlstate 'PGRST' USING
message = '{"code":"123","message":"ABC"}',
detail = '{"status":404,"headers":{"X-Header":"str"}}';
end
$$;
create function raise_sqlstate_test4() returns void
language plpgsql
as $$
begin
raise sqlstate 'PGRST' USING
message = '{"code":"123","message":"ABC"}',
detail = '{"status":404,"status_text":"My Not Found","headers":{"X-Header":"str"}}';
end
$$;
create function raise_sqlstate_invalid_json_message() returns void
language plpgsql
as $$
begin
raise sqlstate 'PGRST' USING
message = 'INVALID',
detail = '{"status":332,"headers":{"X-Header":"str"}}';
end
$$;
create function raise_sqlstate_invalid_json_details() returns void
language plpgsql
as $$
begin
raise sqlstate 'PGRST' USING
message = '{"code":"123","message":"ABC","details":"DEF"}',
detail = 'INVALID';
end
$$;
create function raise_sqlstate_missing_details() returns void
language plpgsql
as $$
begin
raise sqlstate 'PGRST' USING
message = '{"code":"123","message":"ABC","details":"DEF"}';
end
$$;
create table table_a (
id int primary key,
name text
);
create table table_b (
table_a_id int references table_a(id),
name text
);
create or replace function test.returns_complex()
returns table(id int, val complex) as $$
select 1, row(0.1, 0.5)::complex as val
union
select 2, row(0.2, 0.6)::complex as val
union
select 3, row(0.3, 0.7)::complex as val;
$$ language sql;
create function computed_rel_overload(items) returns setof items2 as $$
select * from items2 limit 1
$$ language sql;
create function computed_rel_overload(items2) returns setof items2 as $$
select * from items2 limit 2
$$ language sql;
create function search2(id bigint) returns setof items2
language plpgsql
stable
as $$ begin
return query select items2.id from items2 where items2.id=search2.id;
end$$;
create table test.lines (
id int primary key
, name text
, geom extensions.geometry(LINESTRING, 4326)
);
create or replace function test.get_lines ()
returns setof test.lines as $$
select * from lines;
$$ language sql;
create or replace function test.get_line (id int)
returns "application/vnd.twkb" as $$
select extensions.st_astwkb(geom)::"application/vnd.twkb" from lines where id = get_line.id;
$$ language sql;
create or replace function test.get_shop_bles ()
returns setof test.shop_bles as $$
select * from shop_bles;
$$ language sql;
-- it can work without a final function too if the stype is already the media type
create or replace function test.twkb_handler_transition (state "application/vnd.twkb", next test.lines)
returns "application/vnd.twkb" as $$
select (state || extensions.st_astwkb(next.geom)) :: "application/vnd.twkb";
$$ language sql;
drop aggregate if exists test.twkb_agg(test.lines);
create aggregate test.twkb_agg (test.lines) (
initcond = ''
, stype = "application/vnd.twkb"
, sfunc = test.twkb_handler_transition
);
create or replace function test.geo2json_trans (state "application/vnd.geo2+json", next anyelement)
returns "application/vnd.geo2+json" as $$
select (state || extensions.ST_AsGeoJSON(next)::jsonb)::"application/vnd.geo2+json";
$$ language sql;
create or replace function test.geo2json_final (data "application/vnd.geo2+json")
returns "application/vnd.geo2+json" as $$
select (jsonb_build_object('type', 'FeatureCollection', 'hello', 'world'))::"application/vnd.geo2+json";
$$ language sql;
drop aggregate if exists test.geo2json_agg_any(anyelement);
create aggregate test.geo2json_agg_any(anyelement) (
initcond = '[]'
, stype = "application/vnd.geo2+json"
, sfunc = geo2json_trans
, finalfunc = geo2json_final
);
create or replace function test.geo2json_trans (state "application/vnd.geo2+json", next test.shop_bles)
returns "application/vnd.geo2+json" as $$
select '"anyelement overridden"'::"application/vnd.geo2+json";
$$ language sql;
drop aggregate if exists test.geo2json_agg(test.shop_bles);
create aggregate test.geo2json_agg(test.shop_bles) (
initcond = '[]'
, stype = "application/vnd.geo2+json"
, sfunc = geo2json_trans
);
create table ov_json ();
-- override application/json
create or replace function test.ov_json_trans (state "application/json", next ov_json)
returns "application/json" as $$
select null;
$$ language sql;
drop aggregate if exists test.ov_json_agg(ov_json);
create aggregate test.ov_json_agg(ov_json) (
initcond = '{"overridden": "true"}'
, stype = "application/json"
, sfunc = ov_json_trans
);
-- override application/geo+json
create or replace function test.lines_geojson_trans (state jsonb, next test.lines)
returns "application/geo+json" as $$
select (state || extensions.ST_AsGeoJSON(next)::jsonb)::"application/geo+json";
$$ language sql;
create or replace function test.lines_geojson_final (data jsonb)
returns "application/geo+json" as $$
select jsonb_build_object(
'type', 'FeatureCollection',
'crs', json_build_object(
'type', 'name',
'properties', json_build_object(
'name', 'EPSG:4326'
)
),
'features', data
)::"application/geo+json";
$$ language sql;
drop aggregate if exists test.lines_geojson_agg(test.lines);
create aggregate test.lines_geojson_agg (test.lines) (
initcond = '[]'
, stype = "application/geo+json"
, sfunc = lines_geojson_trans
, finalfunc = lines_geojson_final
);
-- override application/vnd.pgrst.object
create or replace function test.pgrst_obj_json_trans (state "application/vnd.pgrst.object", next anyelement)
returns "application/vnd.pgrst.object" as $$
select null;
$$ language sql;
drop aggregate if exists test.pgrst_obj_agg(anyelement);
create aggregate test.pgrst_obj_agg(anyelement) (
initcond = '{"overridden": "true"}'
, stype = "application/vnd.pgrst.object"
, sfunc = pgrst_obj_json_trans
);
-- create a "text/tab-separated-values" media type
create or replace function test.tsv_trans (state text, next test.projects)
returns "text/tab-separated-values" as $$
select (state || next.id::text || E'\t' || next.name || E'\t' || coalesce(next.client_id::text, '') || E'\n')::"text/tab-separated-values";
$$ language sql;
create or replace function test.tsv_final (data "text/tab-separated-values")
returns "text/tab-separated-values" as $$
select (E'id\tname\tclient_id\n' || data)::"text/tab-separated-values";
$$ language sql;
drop aggregate if exists test.tsv_agg(test.projects);
create aggregate test.tsv_agg (test.projects) (
initcond = ''
, stype = "text/tab-separated-values"
, sfunc = tsv_trans
, finalfunc = tsv_final
);
-- override CSV with BOM plus attachment
create or replace function test.bom_csv_trans (state text, next test.lines)
returns "text/csv" as $$
select (state || next.id::text || ',' || next.name || ',' || next.geom::text || E'\n')::"text/csv";
$$ language sql;
create or replace function test.bom_csv_final (data "text/csv")
returns "text/csv" as $$
select set_config('response.headers', '[{"Content-Disposition": "attachment; filename=\"lines.csv\""}]', true);
-- EFBBBF is the BOM in UTF8 https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
select (convert_from (decode (E'EFBBBF', 'hex'),'UTF8') || (E'id,name,geom\n' || data))::"text/csv";
$$ language sql;
drop aggregate if exists test.bom_csv_agg(test.lines);
create aggregate test.bom_csv_agg (test.lines) (
initcond = ''
, stype = "text/csv"
, sfunc = bom_csv_trans
, finalfunc = bom_csv_final
);
create table empty_string as select 1 as id, ''::text as string;
create table timestamps (
t timestamp with time zone
);
create table project_invoices (
id int primary key
, invoice_total numeric
, project_id integer references projects(id)
);
create table budget_categories (
id int primary key
, category_name text
, budget_owner text
, budget_amount numeric
);
create table budget_expenses (
id int primary key
, expense_amount numeric
, budget_category_id integer references budget_categories(id)
);
create or replace function ret_any_mt ()
returns "*/*" as $$
select 'any'::"*/*";
$$ language sql;
create or replace function ret_some_mt ()
returns "*/*" as $$
declare
req_accept text := current_setting('request.headers', true)::json->>'accept';
resp bytea;
begin
case req_accept
when 'app/chico' then
perform set_config('response.headers', json_build_array(json_build_object('Content-Type', req_accept))::text, true);
resp := 'chico';
when 'app/harpo' then
perform set_config('response.headers', json_build_array(json_build_object('Content-Type', req_accept))::text, true);
resp := 'harpo';
when '*/*' then
perform set_config('response.headers', json_build_array(json_build_object('Content-Type', 'app/groucho'))::text, true);
resp := 'groucho';
else
raise sqlstate 'PT406' using message = 'Not Acceptable';
end case;
return resp;
end; $$ language plpgsql;
create table some_numbers as select x::int as val from generate_series(1,10) x;
create or replace function some_trans (state "*/*", next some_numbers)
returns "*/*" as $$
select (state || E'\n' || next.val::text::bytea)::"*/*";
$$ language sql;
create or replace function some_final (data "*/*")
returns "*/*" as $$
declare
req_accept text := current_setting('request.headers', true)::json->>'accept';
prefix bytea;
begin
case req_accept
when 'magic/number' then
perform set_config('response.headers', json_build_array(json_build_object('Content-Type', req_accept))::text, true);
prefix := 'magic';
when 'crazy/bingo' then
perform set_config('response.headers', json_build_array(json_build_object('Content-Type', req_accept))::text, true);
prefix := 'crazy';
else
prefix := 'anything';
end case;
return (prefix || data)::"*/*";
end; $$ language plpgsql;
drop aggregate if exists some_agg (some_numbers);
create aggregate test.some_agg (some_numbers) (
initcond = ''
, stype = "*/*"
, sfunc = some_trans
, finalfunc = some_final
);
create view bad_subquery as
select * from projects where id = (select id from projects);
-- custom generic mimetype
create domain "pg/outfunc" as text;
create function test.outfunc_trans (state text, next anyelement)
returns "pg/outfunc" as $$
select (state || next::text || E'\n')::"pg/outfunc";
$$ language sql;
create aggregate test.outfunc_agg (anyelement) (
initcond = ''
, stype = "pg/outfunc"
, sfunc = outfunc_trans
);
-- used for manual testing
create or replace function test.sleep(seconds double precision default 5) returns void as $$
select pg_sleep(seconds);
$$ language sql;
-- https://github.com/PostgREST/postgrest/issues/3256
create view test.infinite_recursion as
select * from test.projects;
create or replace view test.infinite_recursion as
select * from test.infinite_recursion;
create or replace function temp_file_limit()
returns bigint as $$
select COUNT(*) FROM generate_series('-infinity'::TIMESTAMP, 'epoch'::TIMESTAMP, INTERVAL '1 DAY');
$$ language sql security definer set temp_file_limit to '1kB';
-- https://github.com/PostgREST/postgrest/issues/3255
create table test.infinite_inserts(
id int
, name text
);
create or replace function infinite_inserts()
returns trigger as $$ begin
insert into infinite_inserts values (NEW.id, NEW.name);
end $$ language plpgsql;
create trigger do_infinite_inserts
after insert
on infinite_inserts
for each row
execute procedure infinite_inserts();