DEV Community

Uday Yadav
Uday Yadav

Posted on β€’ Edited on

1 1

SQL : User Defined Datatypes

This guide is for PostgreSQL : https://www.postgresql.org/

Getting Started with PostgreSQL :
https://dev117uday.gitbook.io/databases/sql/getting-started

Loading Sample Data Guide :
https://dev117uday.gitbook.io/databases/sql/getting-started/load-data

CREATE DOMAIN

  • Create user defined data type with a range, optional, DEFAULT, NOT NULL and CHECK Constraint.
  • They are unique within schema scope.
  • Helps standardise your database types in one place.
  • Composite Type : Only single value return
CREATE DOMAIN name datatype constraint

-- ex 1
-- 'addr' with domain VARCHAR(100)
CREATE DOMAIN addr VARCHAR(100) NOT NULL;

CREATE TABLE locations (
    address addr
);

            Table "public.locations"
 Column  | Type | Collation | Nullable | Default 
---------+------+-----------+----------+---------
 address | addr |           |          | 


-- Dropping Constraints
-- if domain isnt used anywhere
drop domain addr;    

-- this will drop the column in the table it is present in
-- use this with caution
drop domain addr CASCADE;

-- List all domains inside a schema
select typname from pg_catalog.pg_type 
 join pg_catalog.pg_namespace 
 on pg_namespace.oid = pg_type.typnamespace
 where typtype = 'd' and nspname = 'public';

      typname      
------------------
 positive_numeric
 valid_color
 addr
Enter fullscreen mode Exit fullscreen mode

Number Based Components

-- Example 2
-- 'positive_numeric' : value > 0

CREATE DOMAIN positive_numeric 
    INT NOT NULL CHECK (VALUE > 0);

CREATE TABLE sample (
    number positive_numeric
);

INSERT INTO sample (NUMBER) VALUES (10);

-- error
INSERT INTO sample (NUMBER) VALUES (-10);

-- ERROR:  value for domain positive_numeric 
--    violates check constraint "positive_numeric_check"

SELECT * FROM sample;

 number 
--------
     10
Enter fullscreen mode Exit fullscreen mode

Text Based Domain

-- Example 3
-- check email domain

CREATE DOMAIN 
     proper_email VARCHAR(150) 
CHECK 
    ( VALUE ~* '^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+[.][A-Za-z]+$' );


CREATE TABLE email_check (
    client_email proper_email
);

insert into email_check (client_email) 
    values ('a@b.com') ;

-- error 
insert into email_check (client_email) 
    values ('a@#.com') ;
Enter fullscreen mode Exit fullscreen mode

Enum Based Domain

-- enum based domain
CREATE DOMAIN valid_color VARCHAR(10)
CHECK (VALUE IN ('red','green','blue'));

CREATE TABLE color (
    color valid_color
);

INSERT INTO color (color) 
    VALUES ('red'),('blue'),('green');

-- error
INSERT INTO color (color) 
    VALUES ('yellow');
Enter fullscreen mode Exit fullscreen mode

Composite Data Types

Syntax : (composite_column).city

Example 1

-- address type

CREATE TYPE address AS (
    city VARCHAR(50),
    country VARCHAR(100)
);

CREATE TABLE person (
    id SERIAL PRIMARY KEY,
    address address
);

INSERT INTO person ( address ) 
    VALUES (ROW('London','UK')), (ROW('New York','USA'));

select * from person;

 id |     address      
----+------------------
  1 | (London,UK)
  2 | ("New York",USA)

select (address).country from person;

 country 
---------
 UK
 USA
Enter fullscreen mode Exit fullscreen mode

Example 2


CREATE TYPE currency AS ENUM(
    'USD','EUR','GBP','CHF'
);

SELECT 'USD'::currency

 currency 
----------
 USD

SELECT 'INR'::currency

-- ERROR:  invalid input value for enum currency: "INR"
-- LINE 1: SELECT 'INR'::currency

ALTER TYPE currency ADD VALUE 'CHF' AFTER 'EUR';

CREATE TABLE stocks (
    id SERIAL PRIMARY KEY,
    symbol currency
);

insert into stocks ( symbol ) VALUES ('CHF');

select * from stocks
 id | symbol 
----+--------
  1 | CHF

-- DROP TYPE currency;
Enter fullscreen mode Exit fullscreen mode

Alter

Alter TYPE

ALTER TYPE addr RENAME TO user_address

ALTER TYPE user_address OWNER TO uday

ALTER TYPE user_address SET SCHEMA test_scm

ALTER TYPE test_scm.user_address 
    ADD ATTRIBUTE street_address VARCHAR(150)    

CREATE TYPE mycolors AS ENUM ('green','red','blue')

ALTER TYPE mycolors RENAME VALUE 'red' TO 'orange'

SELECT enum_range(NULL::mycolors);

ALTER TYPE mycolors ADD VALUE 'red' BEFORE 'green'
Enter fullscreen mode Exit fullscreen mode

ALTER ENUM

CREATE TYPE status_enum AS enum 
('queued','waiting','running','done');

CREATE TABLE jobs (
    id SERIAL PRIMARY KEY,
    job_status status_enum
);

INSERT INTO jobs ( job_status ) VALUES 
    ('queued'),('waiting'),('running'),('done');

SELECT * FROM jobs;

 id | job_status 
----+------------
  1 | queued
  2 | waiting
  3 | running
  4 | done

-- UPDATING waiting to running

UPDATE jobs SET job_status = 'running' 
    WHERE job_status = 'waiting';

 id | job_status 
----+------------
  1 | queued
  3 | running
  4 | done
  2 | running

Enter fullscreen mode Exit fullscreen mode

Updating/Replacing ENUM domain

ALTER TYPE status_enum RENAME TO status_enum_old;

CREATE TYPE status_enum as enum 
    ('queued','running','done');

ALTER TABLE jobs ALTER COLUMN job_status 
    TYPE status_enum USING job_status::text::status_enum;

DROP TYPE status_enum_old;
Enter fullscreen mode Exit fullscreen mode

Default value ENUM

CREATE TYPE  status AS ENUM 
    ('PENDING','APPROVED','DECLINE')

CREATE TABLE cron_jobs (
    id SERIAL,
    status status DEFAULT 'PENDING'
);

INSERT INTO cron_jobs ( status ) VALUES ('APPROVED');
Enter fullscreen mode Exit fullscreen mode

CREATE DOMAIN IF NOT EXISTS

DO
$$
BEGIN
    IF NOT EXISTS ( 
            SELECT 
                * 
            FROM pg_type tp 
            INNER JOIN 
                pg_namespace nsp ON nsp.oid = typ.typnamespace
                WHERE nsp.nspname = current_schema() 
                AND typ.typname = 'a' 
            ) 
        THEN
            CREATE TYPE ai AS ( 
                a TEXT, i INT 
            );
    END IF;
END;
$$
LANGUAGE plpgsql;
Enter fullscreen mode Exit fullscreen mode

API Trace View

How I Cut 22.3 Seconds Off an API Call with Sentry πŸ‘€

Struggling with slow API calls? Dan Mindru walks through how he used Sentry's new Trace View feature to shave off 22.3 seconds from an API call.

Get a practical walkthrough of how to identify bottlenecks, split tasks into multiple parallel tasks, identify slow AI model calls, and more.

Read more β†’

Top comments (0)

Sentry image

See why 4M developers consider Sentry, β€œnot bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay