@@ -1567,8 +1567,14 @@ const CREATE_SCHEMA_SQL: &str = r"CREATE SCHEMA IF NOT EXISTS @db_name;";
1567
1567
// This runs (currently) every time a PostgresPersistence is created, so it
1568
1568
// needs to not only be idempotent but not to affect any already-resident data.
1569
1569
// IF NOT EXISTS and ON CONFLICT are helpful.
1570
+ // Despite the idempotence of IF NOT EXISTS, we still use a conditional check to
1571
+ // see if we can avoid running that statement, as it acquires an `ACCESS
1572
+ // EXCLUSIVE` lock across the database.
1570
1573
const INIT_SQL : & [ & str ] = & [
1571
1574
r#"
1575
+ DO $$
1576
+ BEGIN
1577
+ IF to_regclass('@db_name.documents') IS NULL THEN
1572
1578
CREATE TABLE IF NOT EXISTS @db_name.documents (
1573
1579
id BYTEA NOT NULL,
1574
1580
ts BIGINT NOT NULL,
@@ -1582,16 +1588,28 @@ const INIT_SQL: &[&str] = &[
1582
1588
1583
1589
PRIMARY KEY (ts, table_id, id)
1584
1590
);
1591
+ END IF;
1592
+ END $$;
1585
1593
"# ,
1586
1594
r#"
1595
+ DO $$
1596
+ BEGIN
1597
+ IF to_regclass('@db_name.documents_by_table_and_id') IS NULL THEN
1587
1598
CREATE INDEX IF NOT EXISTS documents_by_table_and_id ON @db_name.documents (
1588
1599
table_id, id, ts
1589
1600
);
1601
+ END IF;
1602
+ IF to_regclass('@db_name.documents_by_table_ts_and_id') IS NULL THEN
1590
1603
CREATE INDEX IF NOT EXISTS documents_by_table_ts_and_id ON @db_name.documents (
1591
1604
table_id, ts, id
1592
1605
);
1606
+ END IF;
1607
+ END $$;
1593
1608
"# ,
1594
1609
r#"
1610
+ DO $$
1611
+ BEGIN
1612
+ IF to_regclass('@db_name.indexes') IS NULL THEN
1595
1613
CREATE TABLE IF NOT EXISTS @db_name.indexes (
1596
1614
/* ids should be serialized as bytes but we keep it compatible with documents */
1597
1615
index_id BYTEA NOT NULL,
@@ -1618,40 +1636,62 @@ const INIT_SQL: &[&str] = &[
1618
1636
document_id BYTEA NULL,
1619
1637
PRIMARY KEY (index_id, key_prefix, key_sha256, ts)
1620
1638
);
1639
+ END IF;
1640
+ END $$;
1621
1641
"# ,
1622
1642
r#"
1623
- /* This index with `ts DESC` enables our "loose index scan" queries
1624
- * (i.e. `DISTINCT ON`) to run in both directions, complementing the
1625
- * primary key's ts ASC ordering */
1643
+ DO $$
1644
+ BEGIN
1645
+ /* This index with `ts DESC` enables our "loose index scan" queries
1646
+ * (i.e. `DISTINCT ON`) to run in both directions, complementing the
1647
+ * primary key's ts ASC ordering */
1648
+ IF to_regclass('@db_name.indexes_by_index_id_key_prefix_key_sha256_ts') IS NULL THEN
1626
1649
CREATE UNIQUE INDEX IF NOT EXISTS indexes_by_index_id_key_prefix_key_sha256_ts ON @db_name.indexes (
1627
1650
index_id,
1628
1651
key_prefix,
1629
1652
key_sha256,
1630
1653
ts DESC
1631
1654
);
1655
+ END IF;
1656
+ END $$;
1632
1657
"# ,
1633
1658
r#"
1659
+ DO $$
1660
+ BEGIN
1661
+ IF to_regclass('@db_name.leases') IS NULL THEN
1634
1662
CREATE TABLE IF NOT EXISTS @db_name.leases (
1635
1663
id BIGINT NOT NULL,
1636
1664
ts BIGINT NOT NULL,
1637
1665
1638
1666
PRIMARY KEY (id)
1639
1667
);
1668
+ END IF;
1669
+ END $$;
1640
1670
"# ,
1641
1671
r#"
1672
+ DO $$
1673
+ BEGIN
1674
+ IF to_regclass('@db_name.read_only') IS NULL THEN
1642
1675
CREATE TABLE IF NOT EXISTS @db_name.read_only (
1643
1676
id BIGINT NOT NULL,
1644
1677
1645
1678
PRIMARY KEY (id)
1646
1679
);
1680
+ END IF;
1681
+ END $$;
1647
1682
"# ,
1648
1683
r#"
1684
+ DO $$
1685
+ BEGIN
1686
+ IF to_regclass('@db_name.persistence_globals') IS NULL THEN
1649
1687
CREATE TABLE IF NOT EXISTS @db_name.persistence_globals (
1650
1688
key TEXT NOT NULL,
1651
1689
json_value BYTEA NOT NULL,
1652
1690
PRIMARY KEY (key)
1653
1691
);
1654
- "# ,
1692
+ END IF;
1693
+ END $$;
1694
+ "# ,
1655
1695
r#"
1656
1696
INSERT INTO @db_name.leases (id, ts) VALUES (1, 0) ON CONFLICT DO NOTHING;
1657
1697
"# ,
0 commit comments