#==============
# Create Tables
#==============

exec-ddl
CREATE TABLE account_permission (
    ap_ca_id  INT8 NOT NULL,
    ap_acl    VARCHAR(4) NOT NULL,
    ap_tax_id VARCHAR(20) NOT NULL,
    ap_l_name VARCHAR(25) NOT NULL,
    ap_f_name VARCHAR(20) NOT NULL,
    PRIMARY KEY (ap_ca_id, ap_tax_id)
);
----

exec-ddl
CREATE TABLE customer (
    c_id      INT8 NOT NULL PRIMARY KEY,
    c_tax_id  VARCHAR(20) NOT NULL,
    c_st_id   VARCHAR(4) NOT NULL,
    c_l_name  VARCHAR(25) NOT NULL,
    c_f_name  VARCHAR(20) NOT NULL,
    c_m_name  CHAR,
    c_gndr    CHAR,
    c_tier    INT2 NOT NULL CHECK (c_tier IN (1, 2, 3)),
    c_dob     DATE NOT NULL,
    c_ad_id   INT8 NOT NULL,
    c_ctry_1  VARCHAR(3),
    c_area_1  VARCHAR(3),
    c_local_1 VARCHAR(10),
    c_ext_1   VARCHAR(5),
    c_ctry_2  VARCHAR(3),
    c_area_2  VARCHAR(3),
    c_local_2 VARCHAR(10),
    c_ext_2   VARCHAR(5),
    c_ctry_3  VARCHAR(3),
    c_area_3  VARCHAR(3),
    c_local_3 VARCHAR(10),
    c_ext_3   VARCHAR(5),
    c_email_1 VARCHAR(50),
    c_email_2 VARCHAR(50)
);
----

exec-ddl
CREATE TABLE customer_account (
    ca_id     INT8 NOT NULL PRIMARY KEY,
    ca_b_id   INT8 NOT NULL,
    ca_c_id   INT8 NOT NULL,
    ca_name   VARCHAR(50),
    ca_tax_st INT2 NOT NULL CHECK (ca_tax_st IN (0, 1, 2)),
    ca_bal    DECIMAL(12,2) NOT NULL
);
----

exec-ddl
CREATE TABLE customer_taxrate (
    cx_tx_id VARCHAR(4) NOT NULL,
    cx_c_id  INT8 NOT NULL,
    PRIMARY KEY (cx_tx_id, cx_c_id)
);
----

exec-ddl
CREATE TABLE holding (
    h_t_id   INT8 NOT NULL PRIMARY KEY,
    h_ca_id  INT8 NOT NULL,
    h_s_symb VARCHAR(15) NOT NULL,
    h_dts    TIMESTAMP NOT NULL,
    h_price  DECIMAL(8,2) NOT NULL CHECK (h_price > 0),
    h_qty    INT4 NOT NULL
);
----

exec-ddl
CREATE TABLE holding_history (
    hh_h_t_id     INT8 NOT NULL,
    hh_t_id       INT8 NOT NULL,
    hh_before_qty INT4 NOT NULL,
    hh_after_qty  INT4 NOT NULL,
    PRIMARY KEY (hh_h_t_id, hh_t_id)
);
----

exec-ddl
CREATE TABLE holding_summary (
    hs_ca_id  INT8 NOT NULL,
    hs_s_symb VARCHAR(15) NOT NULL,
    hs_qty    INT4 NOT NULL,
    PRIMARY KEY (hs_ca_id, hs_s_symb),
    FAMILY static  (hs_ca_id, hs_s_symb),
    FAMILY dynamic (hs_qty)
);
----

exec-ddl
CREATE TABLE watch_item (
    wi_wl_id  INT8 NOT NULL,
    wi_s_symb VARCHAR(15) NOT NULL,
    PRIMARY KEY (wi_wl_id, wi_s_symb)
);
----

exec-ddl
CREATE TABLE watch_list (
    wl_id   INT8 NOT NULL PRIMARY KEY,
    wl_c_id INT8 NOT NULL
);
----

exec-ddl
CREATE TABLE broker (
    b_id         INT8 NOT NULL PRIMARY KEY,
    b_st_id      VARCHAR(4) NOT NULL,
    b_name       VARCHAR(49) NOT NULL,
    b_num_trades INT8 NOT NULL,
    b_comm_total DECIMAL(12,2) NOT NULL,
    FAMILY static  (b_id, b_st_id, b_name),
    FAMILY dynamic (b_comm_total, b_num_trades)
);
----

exec-ddl
CREATE TABLE cash_transaction (
    ct_t_id INT8 NOT NULL PRIMARY KEY,
    ct_dts  TIMESTAMP NOT NULL,
    ct_amt  DECIMAL(10,2) NOT NULL,
    ct_name VARCHAR(100)
);
----

exec-ddl
CREATE TABLE charge (
    ch_tt_id  VARCHAR(3) NOT NULL,
    ch_c_tier INT2 NOT NULL CHECK (ch_c_tier IN (1, 2, 3)),
    ch_chrg   DECIMAL(10,2) NOT NULL CHECK (ch_chrg >= 0),
    PRIMARY KEY (ch_tt_id, ch_c_tier)
);
----

exec-ddl
CREATE TABLE commission_rate (
    cr_c_tier   INT2 NOT NULL CHECK (cr_c_tier IN (1, 2, 3)),
    cr_tt_id    VARCHAR(3) NOT NULL,
    cr_ex_id    VARCHAR(6) NOT NULL,
    cr_from_qty INT4 NOT NULL CHECK (cr_from_qty >= 0),
    cr_to_qty   INT4 NOT NULL CHECK (cr_to_qty > cr_from_qty),
    cr_rate     DECIMAL(5,2) NOT NULL CHECK (cr_rate >= 0),
    PRIMARY KEY (cr_c_tier, cr_tt_id, cr_ex_id, cr_from_qty)
);
----

exec-ddl
CREATE TABLE settlement (
    se_t_id          INT8 NOT NULL PRIMARY KEY,
    se_cash_type     VARCHAR(40) NOT NULL,
    se_cash_due_date DATE NOT NULL,
    se_amt           DECIMAL(10,2) NOT NULL
);
----

exec-ddl
CREATE TABLE trade (
    t_id          INT8 NOT NULL PRIMARY KEY,
    t_dts         TIMESTAMP NOT NULL,
    t_st_id       VARCHAR(4) NOT NULL,
    t_tt_id       VARCHAR(3) NOT NULL,
    t_is_cash     BOOL NOT NULL,
    t_s_symb      VARCHAR(15) NOT NULL,
    t_qty         INT4 NOT NULL CHECK (t_qty > 0),
    t_bid_price   DECIMAL(8,2) NOT NULL CHECK (t_bid_price > 0),
    t_ca_id       INT8 NOT NULL,
    t_exec_name   VARCHAR(49) NOT NULL,
    t_trade_price DECIMAL(8,2),
    t_chrg        DECIMAL(10,2) NOT NULL CHECK (t_chrg >= 0),
    t_comm        DECIMAL(10,2) NOT NULL CHECK (t_comm >= 0),
    t_tax         DECIMAL(10,2) NOT NULL CHECK (t_tax  >= 0),
    t_lifo        BOOL NOT NULL,
    FAMILY static   (t_id),
    FAMILY dynamic1 (t_comm, t_dts, t_st_id, t_trade_price, t_exec_name, t_tt_id, t_is_cash, t_s_symb, t_qty, t_bid_price, t_ca_id, t_chrg, t_lifo),
    FAMILY dynamic2 (t_tax)
);
----

exec-ddl
CREATE TABLE trade_history (
    th_t_id  INT8 NOT NULL,
    th_dts   TIMESTAMP NOT NULL,
    th_st_id VARCHAR(4) NOT NULL,
    PRIMARY KEY (th_t_id, th_st_id)
);
----

exec-ddl
CREATE TABLE trade_request (
    tr_t_id      INT8 NOT NULL PRIMARY KEY,
    tr_tt_id     VARCHAR(3) NOT NULL,
    tr_s_symb    VARCHAR(15) NOT NULL,
    tr_qty       INT4 NOT NULL CHECK (tr_qty > 0),
    tr_bid_price DECIMAL(8,2) NOT NULL CHECK (tr_bid_price > 0),
    tr_b_id      INT8 NOT NULL
);
----

exec-ddl
CREATE TABLE trade_type (
    tt_id      VARCHAR(3) NOT NULL PRIMARY KEY,
    tt_name    VARCHAR(12) NOT NULL,
    tt_is_sell BOOL NOT NULL,
    tt_is_mrkt BOOL NOT NULL
);
----

exec-ddl
CREATE TABLE company (
    co_id        INT8 NOT NULL PRIMARY KEY,
    co_st_id     VARCHAR(4) NOT NULL,
    co_name      VARCHAR(60) NOT NULL,
    co_in_id     VARCHAR(2) NOT NULL,
    co_sp_rate   VARCHAR(4) NOT NULL,
    co_ceo       VARCHAR(46) NOT NULL,
    co_ad_id     INT8 NOT NULL,
    co_desc      VARCHAR(150) NOT NULL,
    co_open_date DATE NOT NULL
);
----

exec-ddl
CREATE TABLE company_competitor (
    cp_co_id      INT8 NOT NULL,
    cp_comp_co_id INT8 NOT NULL,
    cp_in_id      VARCHAR(2) NOT NULL,
    PRIMARY KEY (cp_co_id, cp_comp_co_id, cp_in_id)
);
----

exec-ddl
CREATE TABLE daily_market (
    dm_date   DATE NOT NULL,
    dm_s_symb VARCHAR(15) NOT NULL,
    dm_close  DECIMAL(8,2) NOT NULL,
    dm_high   DECIMAL(8,2) NOT NULL,
    dm_low    DECIMAL(8,2) NOT NULL,
    dm_vol    INT8 NOT NULL,
    PRIMARY KEY (dm_date, dm_s_symb)
);
----

exec-ddl
CREATE TABLE exchange (
    ex_id       VARCHAR(6) NOT NULL PRIMARY KEY,
    ex_name     VARCHAR(100) NOT NULL,
    ex_num_symb INT4 NOT NULL,
    ex_open     INT2 NOT NULL,
    ex_close    INT2 NOT NULL,
    ex_desc     VARCHAR(150),
    ex_ad_id    INT8 NOT NULL
);
----

exec-ddl
CREATE TABLE financial (
    fi_co_id          INT8 NOT NULL,
    fi_year           INT2 NOT NULL,
    fi_qtr            INT2 NOT NULL CHECK (fi_qtr IN (1, 2, 3, 4)),
    fi_qtr_start_date DATE NOT NULL,
    fi_revenue        DECIMAL(15,2) NOT NULL,
    fi_net_earn       DECIMAL(15,2) NOT NULL,
    fi_basic_eps      DECIMAL(10,2) NOT NULL,
    fi_dilut_eps      DECIMAL(10,2) NOT NULL,
    fi_margin         DECIMAL(10,2) NOT NULL,
    fi_inventory      DECIMAL(15,2) NOT NULL,
    fi_assets         DECIMAL(15,2) NOT NULL,
    fi_liability      DECIMAL(15,2) NOT NULL,
    fi_out_basic      INT8 NOT NULL,
    fi_out_dilut      INT8 NOT NULL,
    PRIMARY KEY (fi_co_id, fi_year, fi_qtr)
);
----

exec-ddl
CREATE TABLE industry (
    in_id    VARCHAR(2) NOT NULL PRIMARY KEY,
    in_name  VARCHAR(50) NOT NULL,
    in_sc_id VARCHAR(2) NOT NULL
);
----

exec-ddl
CREATE TABLE last_trade (
    lt_s_symb     VARCHAR(15) NOT NULL PRIMARY KEY,
    lt_dts        TIMESTAMP NOT NULL,
    lt_price      DECIMAL(8,2) NOT NULL,
    lt_open_price DECIMAL(8,2) NOT NULL,
    lt_vol        INT8 NOT NULL
);
----

exec-ddl
CREATE TABLE news_item (
    ni_id       INT8 NOT NULL PRIMARY KEY,
    ni_headline VARCHAR(80) NOT NULL,
    ni_summary  VARCHAR(255) NOT NULL,
    ni_item     BYTEA NOT NULL,
    ni_dts      TIMESTAMP NOT NULL,
    ni_source   VARCHAR(30) NOT NULL,
    ni_author   VARCHAR(30),
    FAMILY static (ni_id, ni_headline, ni_summary, ni_dts, ni_source, ni_author),
    FAMILY blob   (ni_item)
);
----

exec-ddl
CREATE TABLE news_xref (
    nx_ni_id INT8 NOT NULL,
    nx_co_id INT8 NOT NULL,
    PRIMARY KEY (nx_ni_id, nx_co_id)
);
----

exec-ddl
CREATE TABLE sector (
    sc_id   VARCHAR(2) NOT NULL PRIMARY KEY,
    sc_name VARCHAR(30) NOT NULL
);
----

exec-ddl
CREATE TABLE security (
    s_symb           VARCHAR(15) NOT NULL PRIMARY KEY,
    s_issue          VARCHAR(6) NOT NULL,
    s_st_id          VARCHAR(4) NOT NULL,
    s_name           VARCHAR(70) NOT NULL,
    s_ex_id          VARCHAR(6) NOT NULL,
    s_co_id          INT8 NOT NULL,
    s_num_out        INT8 NOT NULL,
    s_start_date     DATE NOT NULL,
    s_exch_date      DATE NOT NULL,
    s_pe             DECIMAL(10,2) NOT NULL,
    s_52wk_high      DECIMAL(8,2) NOT NULL,
    s_52wk_high_date DATE NOT NULL,
    s_52wk_low       DECIMAL(8,2) NOT NULL,
    s_52wk_low_date  DATE NOT NULL,
    s_dividend       DECIMAL(10,2) NOT NULL,
    s_yield          DECIMAL(5,2) NOT NULL
);
----

exec-ddl
CREATE TABLE address (
    ad_id      INT8 NOT NULL PRIMARY KEY,
    ad_line1   VARCHAR(80),
    ad_line2   VARCHAR(80),
    ad_zc_code VARCHAR(12) NOT NULL,
    ad_ctry    VARCHAR(80)
);
----

exec-ddl
CREATE TABLE status_type (
    st_id   VARCHAR(4) NOT NULL PRIMARY KEY,
    st_name VARCHAR(10) NOT NULL
);
----

exec-ddl
CREATE TABLE taxrate (
    tx_id   VARCHAR(4) NOT NULL PRIMARY KEY,
    tx_name VARCHAR(50) NOT NULL,
    tx_rate DECIMAL(6,5) NOT NULL CHECK (tx_rate >= 0)
);
----

exec-ddl
CREATE TABLE zip_code (
    zc_code VARCHAR(12) NOT NULL PRIMARY KEY,
    zc_town VARCHAR(80) NOT NULL,
    zc_div  VARCHAR(80) NOT NULL
);
----

#============
# Add Indexes
#============

exec-ddl
CREATE INDEX ON broker (b_name);
----

exec-ddl
CREATE UNIQUE INDEX ON sector (sc_name);
----

exec-ddl
CREATE INDEX ON industry (in_sc_id);
----

exec-ddl
CREATE INDEX ON trade_request (tr_b_id, tr_s_symb) STORING (tr_qty, tr_bid_price);
----

exec-ddl
CREATE UNIQUE INDEX ON customer (c_tax_id);
----

exec-ddl
CREATE INDEX ON customer_account (ca_c_id);
----

exec-ddl
CREATE INDEX ON trade_request (tr_s_symb) STORING (tr_tt_id, tr_qty, tr_bid_price) WHERE tr_tt_id IN ('TSL', 'TLS', 'TLB');
----

exec-ddl
CREATE INDEX ON watch_list (wl_c_id);
----

exec-ddl
CREATE UNIQUE INDEX ON industry (in_name);
----

exec-ddl
CREATE INDEX ON company (co_in_id);
----

exec-ddl
CREATE UNIQUE INDEX ON daily_market (dm_s_symb, dm_date) STORING (dm_close, dm_high, dm_low, dm_vol);
----

exec-ddl
CREATE INDEX ON news_xref (nx_co_id);
----

exec-ddl
CREATE UNIQUE INDEX ON holding_history (hh_t_id, hh_h_t_id);
----

exec-ddl
CREATE UNIQUE INDEX ON company (co_name);
----

exec-ddl
CREATE UNIQUE INDEX ON security (s_co_id, s_issue) STORING (s_ex_id, s_name);
----

exec-ddl
CREATE INDEX ON customer_taxrate (cx_c_id);
----

exec-ddl
CREATE UNIQUE INDEX ON holding_summary (hs_s_symb, hs_ca_id) STORING (hs_qty);
----

exec-ddl
CREATE INDEX ON holding (h_ca_id, h_s_symb, h_dts) STORING (h_qty, h_price);
----

exec-ddl
CREATE INDEX ON trade (t_ca_id, t_dts DESC) STORING (t_st_id, t_tt_id, t_is_cash, t_s_symb, t_qty, t_bid_price, t_exec_name, t_trade_price, t_chrg);
----

exec-ddl
CREATE INDEX ON trade (t_s_symb, t_dts ASC) STORING (t_ca_id, t_exec_name, t_is_cash, t_trade_price, t_qty, t_tt_id);
----

#=================
# Add Foreign Keys
#=================

exec-ddl
ALTER TABLE account_permission ADD FOREIGN KEY (ap_ca_id) REFERENCES customer_account;
----

exec-ddl
ALTER TABLE customer ADD FOREIGN KEY (c_st_id) REFERENCES status_type;
----

exec-ddl
ALTER TABLE customer ADD FOREIGN KEY (c_ad_id) REFERENCES address;
----

exec-ddl
ALTER TABLE customer_account ADD FOREIGN KEY (ca_b_id) REFERENCES broker;
----

exec-ddl
ALTER TABLE customer_account ADD FOREIGN KEY (ca_c_id) REFERENCES customer;
----

exec-ddl
ALTER TABLE customer_taxrate ADD FOREIGN KEY (cx_tx_id) REFERENCES taxrate;
----

exec-ddl
ALTER TABLE customer_taxrate ADD FOREIGN KEY (cx_c_id) REFERENCES customer;
----

exec-ddl
ALTER TABLE holding ADD FOREIGN KEY (h_t_id) REFERENCES trade;
----

exec-ddl
ALTER TABLE holding ADD FOREIGN KEY (h_ca_id, h_s_symb) REFERENCES holding_summary;
----

exec-ddl
ALTER TABLE holding_history ADD FOREIGN KEY (hh_h_t_id) REFERENCES trade;
----

exec-ddl
ALTER TABLE holding_history ADD FOREIGN KEY (hh_t_id) REFERENCES trade;
----

exec-ddl
ALTER TABLE holding_summary ADD FOREIGN KEY (hs_ca_id) REFERENCES customer_account;
----

exec-ddl
ALTER TABLE holding_summary ADD FOREIGN KEY (hs_s_symb) REFERENCES security;
----

exec-ddl
ALTER TABLE watch_item ADD FOREIGN KEY (wi_wl_id) REFERENCES watch_list;
----

exec-ddl
ALTER TABLE watch_item ADD FOREIGN KEY (wi_s_symb) REFERENCES security;
----

exec-ddl
ALTER TABLE watch_list ADD FOREIGN KEY (wl_c_id) REFERENCES customer;
----

exec-ddl
ALTER TABLE broker ADD FOREIGN KEY (b_st_id) REFERENCES status_type;
----

exec-ddl
ALTER TABLE cash_transaction ADD FOREIGN KEY (ct_t_id) REFERENCES trade;
----

exec-ddl
ALTER TABLE charge ADD FOREIGN KEY (ch_tt_id) REFERENCES trade_type;
----

exec-ddl
ALTER TABLE commission_rate ADD FOREIGN KEY (cr_tt_id) REFERENCES trade_type;
----

exec-ddl
ALTER TABLE commission_rate ADD FOREIGN KEY (cr_ex_id) REFERENCES exchange;
----

exec-ddl
ALTER TABLE settlement ADD FOREIGN KEY (se_t_id) REFERENCES trade;
----

exec-ddl
ALTER TABLE trade ADD FOREIGN KEY (t_st_id) REFERENCES status_type;
----

exec-ddl
ALTER TABLE trade ADD FOREIGN KEY (t_tt_id) REFERENCES trade_type;
----

exec-ddl
ALTER TABLE trade ADD FOREIGN KEY (t_s_symb) REFERENCES security;
----

exec-ddl
ALTER TABLE trade ADD FOREIGN KEY (t_ca_id) REFERENCES customer_account;
----

exec-ddl
ALTER TABLE trade_history ADD FOREIGN KEY (th_t_id) REFERENCES trade;
----

exec-ddl
ALTER TABLE trade_history ADD FOREIGN KEY (th_st_id) REFERENCES status_type;
----

exec-ddl
ALTER TABLE trade_request ADD FOREIGN KEY (tr_t_id) REFERENCES trade;
----

exec-ddl
ALTER TABLE trade_request ADD FOREIGN KEY (tr_tt_id) REFERENCES trade_type;
----

exec-ddl
ALTER TABLE trade_request ADD FOREIGN KEY (tr_s_symb) REFERENCES security;
----

exec-ddl
ALTER TABLE trade_request ADD FOREIGN KEY (tr_b_id) REFERENCES broker;
----

exec-ddl
ALTER TABLE company ADD FOREIGN KEY (co_st_id) REFERENCES status_type;
----

exec-ddl
ALTER TABLE company ADD FOREIGN KEY (co_in_id) REFERENCES industry;
----

exec-ddl
ALTER TABLE company ADD FOREIGN KEY (co_ad_id) REFERENCES address;
----

exec-ddl
ALTER TABLE company_competitor ADD FOREIGN KEY (cp_co_id) REFERENCES company;
----

exec-ddl
ALTER TABLE company_competitor ADD FOREIGN KEY (cp_comp_co_id) REFERENCES company;
----

exec-ddl
ALTER TABLE company_competitor ADD FOREIGN KEY (cp_in_id) REFERENCES industry;
----

exec-ddl
ALTER TABLE daily_market ADD FOREIGN KEY (dm_s_symb) REFERENCES security;
----

exec-ddl
ALTER TABLE exchange ADD FOREIGN KEY (ex_ad_id) REFERENCES address;
----

exec-ddl
ALTER TABLE financial ADD FOREIGN KEY (fi_co_id) REFERENCES company;
----

exec-ddl
ALTER TABLE industry ADD FOREIGN KEY (in_sc_id) REFERENCES sector;
----

exec-ddl
ALTER TABLE last_trade ADD FOREIGN KEY (lt_s_symb) REFERENCES security;
----

exec-ddl
ALTER TABLE news_xref ADD FOREIGN KEY (nx_ni_id) REFERENCES news_item;
----

exec-ddl
ALTER TABLE news_xref ADD FOREIGN KEY (nx_co_id) REFERENCES company;
----

exec-ddl
ALTER TABLE security ADD FOREIGN KEY (s_st_id) REFERENCES status_type;
----

exec-ddl
ALTER TABLE security ADD FOREIGN KEY (s_ex_id) REFERENCES exchange;
----

exec-ddl
ALTER TABLE security ADD FOREIGN KEY (s_co_id) REFERENCES company;
----

exec-ddl
ALTER TABLE address ADD FOREIGN KEY (ad_zc_code) REFERENCES zip_code;
----
