exclude constraints in pgmodeler - pgmodeler

I want to add an exclusion constraint to a table in pgmodeler.
Example table:
create table x (
lable varchar(2) not null,
timerange tstzrange not null,
primary key (lable, timerange))
);
And I want to add:
alter table x add constraint ex_x_overlap
exclude using gist(lable with =, timerange with &&);
What I tried in pgmodeler
open table properties
chose constraints
add constraint
choose a name
chose type "EXCLUDE"
add first exclude element, column "lable", but no operator available
My problem is that the operator field is mandatory, but not free text. I need to select an operator form one of the schemas. However "=" is not there (there are none in fact...).
I think I misunderstand something, any help appreciated!

Related

Adding constraint to check if the value contains specific characters- SQL Server

My Check constraint conflicts when adding values, any answer to why it is wrong will be much appreciated.
Here is the question:
Ensure that the Student’s NIC number contains 9 digits (0-9) and one
character which is “V” or “v”.
Here is the value I want to add to the table:
946785467v
Here is the constraint I used:
ALTER TABLE Student
ADD CONSTRAINT stdNIC CHECK(NIC LIKE '[0-9]{9}[V-v]');
Better to change the constraint as below.
ALTER TABLE Student ADD CONSTRAINT stdNIC CHECK(NIC LIKE '%[0-9]%[V-v]')
Example validated on db<>fiddle<>example

Postgresql exclude constraint using gist over text (varchar) data types

I need to have a constraint to assure two different rows have not the same values for two varchar columns, and there is no overlapping with the composed range with another two columns.
The table is created as:
create table test (id varchar(255) not null,
amount_from float8,
amount_to float8,
company varchar(255) not null,
currency varchar(255) not null,
primary key (id));
Also, I've created a custom type as:
CREATE TYPE floatrange AS RANGE (subtype = float8, subtype_diff = float8mi);
Now, I can create a EXCLUDE constraint to avoid overlapping with the composed ranges in base to the amounts columns (amount_from and amount_to).
alter table test_rule add constraint AMOUNTS_RANGES_OVERLAPING
EXCLUDE USING gist (floatrange(amount_from, amount_to, '[]') with &&)
But I'm not abled to include in that contraint that the company and currency columns must be equal. Something like this:
alter table test_rule add constraint AMOUNTS_RANGES_OVERLAPING
EXCLUDE USING gist (floatrange(amount_from, amount_to) with &&,
currency with =,
company with =)
This sentence provokes the following error:
SQL Error [42704]: ERROR: data type text 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.
Gist is not able to handle text types.
How can I include these columns to complete the expected constraint? Is there any function or type conversion to allow the text comparation?
Or, perhaps, is there a way to use a double EXCLUDE clause to use gist and btree to obtain what I need? Something in this way:
alter table test_rule add constraint AMOUNTS_RANGES_OVERLAPING
EXCLUDE USING btree (currency with =, company with =)
EXCLUDE USING gist (floatrange(amount_from, amount_to) with &&)

Unclear constraints in SQL's CREATE TABLE

In a Coursera course, there is a snippet of code:
I don't understand the parts:
CONSTRAINT AUTHOR_PK
(author_id) (after PRIMARY KEY)
Could you please explain?
Clarifications: for CONSTRAINT AUTHOR_PK, I don't understand why CONSTRAINT is there explicitly but it's not there for the other attributes of the table. I also don't know what AUTHOR_PK is used for.
For (author_id), I don't understand its presence. Since PRIMARY KEY is written on the same line as author_id, isn't it already implicit that author_id will be used as the primary key?
I'm very new to SQL. I consulted
https://www.w3schools.com/sql/sql_create_table.asp
https://www.w3schools.com/sql/sql_constraints.asp
but could not resolve these issues myself.
There are two types of constraints you can create in a CREATE TABLE statement. These are column constraints and table constraints.
Column constraints are included in the definition of a single column.
Table constraints are included as separate declarations, not part of a column definition.
This is the same table with the primary key declared as a table constraint:
CREATE TABLE Author
(author_id CHAR(2),
lastname VARCHAR(15) not null,
...,
CONSTRAINT PK_AUTHOR PRIMARY KEY (author_id)
)
What you have in your example is a constraint being declared as a column constraint. Normally, column constraints don't have to name which columns they're relevant to since they're part of the column's definition, and indeed in some dialects of SQL, the sample you've shown would be rejected, because it does name the columns explicitly.
PK_AUTHOR, in both your sample and mine, is being used to give a specific name to the constraint. This is helpful if you'll later need to remove the constraint. If you don't want to name the constraint, then CONSTRAINT PK_AUTHOR may be omitted from either sampe.
The CONSTRAINT keyword is necessary when you want to provide a specific name for the constraint, in this case AUTHOR_PK. If you don't do this, a name would be auto-generated, and these names are generally not very useful. All the NOT NULL constraints in this example would have auto-generated names.
In my experience, it's standard practice to name all constraints except NOT NULL ones.
I think you are right that (author_id) is unnecessary in this example, as it is implied by the fact that the constraint is declared for that column already. But the syntax allows it. (I wonder if it would allow specifying a different column in this position - I don't think so but haven't tried it.)
The syntax to specify columns is more useful when you want to declare a multiple-column key. In this case, the CONSTRAINT clause would be specified as if it were another column in the table definition:
...
country CHAR(2),
CONSTRAINT one_city_per_country UNIQUE (country,city)
);

Why Is "NOT NULL" not a constraint?

If I want to add a PRIMARY KEY to an existing column table :
ALTER TABLE table_name
ADD CONSTRAINT column_name_PK PRIMARY KEY (column_name);
Now, If I want to add a NOT NULL to an existing column table :
ALTER TABLE table_name
ALTER column column_name INTEGER(or other data type) NOT NULL;
Isn't NOT NULL a constraint ?
Why for a PRIMARY KEY is ADD CONSTRAINT
and for a NOT NULL is not ADD CONSTRAINT but ALTER COLUMN ?
To my eyes, NOT NULL is also a kind of constraint..
Specifying NOT NULL means 'the column must have a value'. It only means that some value must be present, but it says nothing about what those values should be. Note that in SQL terms, NULL itself is not a value but it is the absence of a value.
A CONSTRAINT on the other hand is a rule for the allowed values. You can even have a constraint on NULL columns, and then such a CONSTRAINT for the allowed values is enforced only if a non-NULL value is present.
You can just use NOT NULL inline when you declare the parameter. Like this:
CREATE TABLE People
(
ID INT NOT NULL,
Name NVARCHAR(100) NOT NULL,
Notes NVARCHAR(MAX) NULL
)
Think of it as the NULL or NOT NULL actually being part of the type declaration. A field that can hold an Integer and also can hold a NULL is a different type than one that can hold an Integer but never a NULL.
Consider
create type IntegerIsSometimesNull from integer null
create type IntegerIsNeverNull from integer not null
go
create table DifferentType ( N IntegerIsSometimesNull,
I IntegerIsNeverNull )
Here we see that NULL and NOT NULL are actually a part of the type declaration.
Consider also that these fields require a different amount of space in the database.
To my eyes, NOT NULL is also a kind of constraint..
Yes. Data Types, NULL-ness, CHECK CONSTRAINTS, and FOREIGN KEY constraints are all concerned with defining the "domain" of the column. A "domain" is the set of possible values for a column, and is a fundamental concept of the relational model.
In most RDBMS systems domains are implemented by a combination of data types and constraints.

How can I use a Postgres EXCLUDE constraint to prevent inserting two primary rows?

Postgres 9.0 supports exclusion constraints, which are kind of like a general unique constraint (http://www.postgresql.org/docs/9.0/static/sql-createtable.html#SQL-CREATETABLE-EXCLUDE).
I figured that this might be a good way to solve this problem, but I can't figure out how to use the exclusion constraints properly.
Here's the problem:
I have a table like this:
CREATE TABLE emails (
id integer NOT NULL,
email character varying(255),
"primary" boolean DEFAULT false,
user_id integer,
);
I want to ensure that only one row per unique user_id has "primary" equal to true. I tried to use an exclusion constraint like this:
ALTER TABLE emails ADD CONSTRAINT one_primary_email_per_user EXCLUDE USING gist (user_id WITH =, "primary" WITH &);
Postgres refused that with:
ERROR: data type boolean 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.
I tried again casting the boolean column to bit:
ALTER TABLE emails ADD CONSTRAINT one_primary_email_per_user EXCLUDE (user_id WITH =, (case "primary" when 't' then '1'::bit else '0'::bit end) WITH &);
That didn't work. It seems &(bit,bit) is not part of the operator class bit_ops:
ERROR: operator &(bit,bit) is not a member of operator family "bit_ops"
DETAIL: The exclusion operator must be related to the index operator class for the constraint.
Looking at http://www.leadum.com/downloads/dbscribe/samples/postgresql/web_modern/opclass/main/790197862.html, it seems like bit_ops only includes ordering comparison operators (>,<,=,>=,<=) and not bitwise operators. I'm not really sure why that's the case.
Is this kind of exclusion possible with an EXCLUDE constraint? Is there a better way to do this?
Thanks for the help!
It should be simpler to create a partial unique index for that:
create unique index on emails(email) where (primary);
(Orthogonal to this answer, but since you're asking about the error message: for the exclude constraint, you'd want to add the btree_gin or btree_gist extensions for use with btree operators.)