Eu tenho uma tabela que armazena informações de assinatura do usuário, agora quero adicionar uma restrição para fazer com que o usuário não assine o produto várias vezes no mesmo período de tempo. O que estou tentando fazer assim:
CREATE INDEX user_sub_exclusion_index ON user_sub USING GIST (
user_id,
tsrange(sub_start_time, sub_end_time)
);
e criar restrição:
ALTER TABLE user_sub ADD CONSTRAINT user_sub_exclusion_constraint EXCLUDE USING GIST (
user_id WITH =,
tsrange(sub_start_time, sub_end_time) WITH &&
);
parece que o tsrange precisa do tipo de dados timestamp. Eu tentei a função de intervalo, mas não funcionou. o que devo fazer para que o gist index funcione e não altere o tipo de dado? Esta é a tabela DDL:
CREATE TABLE public.user_sub (
id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
app_id varchar NOT NULL,
product_id int4 NOT NULL,
iap_product_id varchar NOT NULL,
created_time int8 NOT NULL,
updated_time int8 NOT NULL,
user_id int8 NOT NULL,
sub_start_time int8 NOT NULL DEFAULT 0,
sub_end_time int8 NOT NULL DEFAULT 0,
enabled int2 NOT NULL DEFAULT 1,
order_id varchar NOT NULL,
CONSTRAINT user_sub_new_pk PRIMARY KEY (id),
CONSTRAINT user_sub_new_un UNIQUE (order_id)
);
Eu tentei alterar o campo para timestamptz e ajustar o sql assim:
CREATE INDEX user_sub_exclusion_index ON user_sub USING GIST (
user_id,
tstzrange(sub_start, sub_end)
);
mostrar erro:
SQL Error [42704]: ERROR: data type bigint has no default operator class for access method "gist"
Hint: You must specify an operator class for the index or define a default operator class for the data type.
o que devo fazer para adicionar a restrição?
Por padrão, o PostgreSQL não inclui classes de operadores GiST para tipos básicos como
bigint
. Você precisa criar uma extensão padrão que forneça as classes de operador necessárias:Então você pode criar sua restrição.
Observe que adicionar uma restrição de exclusão cria automaticamente um índice GiST.