Canonical TSAPI series DB schema v1.0.0
Single source of truth for the timeseries PostgreSQL schema shared by the Python (TSAPI_SERIESDB_PG_PY) and C++ (TSAPI_POSTGRES_CPP) libraries. SQL seeded byte-for-byte from TSAPI_SERIESDB_PG_PY/tsapi_pgdb/sql on 2026-09-02. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
eed06559c0
17 changed files with 2080 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Local connection settings (never commit credentials)
|
||||
db_config.json
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
104
README.md
Normal file
104
README.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# TSAPI_SERIESDB_SCHEMA — canonical timeseries DB schema
|
||||
|
||||
**Single source of truth** for the PostgreSQL schema used by the TSAPI
|
||||
timeseries database. Both client libraries target the schema defined here:
|
||||
|
||||
- **Python** — `TSAPI_SERIESDB_PG_PY`
|
||||
- **C++** — `TSAPI_POSTGRES_CPP`
|
||||
|
||||
Neither project should keep its own copy of the DDL. When the schema changes,
|
||||
it changes **here**, and both projects re-provision / re-test against it.
|
||||
|
||||
Current schema version: **1.0.0** (see [`VERSION`](VERSION); recorded at runtime
|
||||
in the `meta.schema_version` table).
|
||||
|
||||
---
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
TSAPI_SERIESDB_SCHEMA/
|
||||
├── VERSION # canonical schema version string
|
||||
├── run_setup.py # provisioner — runs the numbered files in order
|
||||
├── db_config.json.example # copy to db_config.json and edit (gitignored)
|
||||
├── README.md
|
||||
└── sql/
|
||||
├── 00_extensions.sql # pg_trgm
|
||||
├── 01_schemas.sql # meta / series / log schemas
|
||||
├── 02_sequences.sql # id sequences
|
||||
├── 03_tables.sql # meta.* and log.* tables
|
||||
├── 04_indexes.sql # indexes + registry constraints
|
||||
├── 05_procedures.sql # meta.* / log.* stored procedures
|
||||
├── 06_triggers.sql # prevent_series_drops event trigger
|
||||
├── 07_reference_data.sql # timezones + currencies reference data
|
||||
├── 08_script_log.sql # auxiliary (not part of a fresh install)
|
||||
└── migrate/ # one-off migration scripts (run manually)
|
||||
```
|
||||
|
||||
`run_setup.py` executes `00`–`07` in order. `08_script_log.sql` and
|
||||
`sql/migrate/*.sql` are auxiliary and are **not** run by a fresh install.
|
||||
|
||||
---
|
||||
|
||||
## Provisioning a database
|
||||
|
||||
```bash
|
||||
# 1. configure
|
||||
cp db_config.json.example db_config.json # then edit host/user/password
|
||||
# (or pass connection flags on the command line instead)
|
||||
|
||||
# 2. create the schema
|
||||
python run_setup.py # uses db_config.json / defaults
|
||||
python run_setup.py --host 192.168.1.7 --user claude --password claudepwd
|
||||
python run_setup.py --drop-existing # drop meta+series+log first
|
||||
python run_setup.py --clean-slate # drop ALL user objects first
|
||||
```
|
||||
|
||||
Requires `psycopg2` and a PostgreSQL user with CREATE privileges on the target
|
||||
database.
|
||||
|
||||
---
|
||||
|
||||
## What gets created
|
||||
|
||||
- **Schemas:** `meta` (registry + reference data), `series` (timeseries data
|
||||
tables live here), `log` (event/audit trail).
|
||||
- **Registry:** `meta.series` — one row per series table, PK `table_id`,
|
||||
`UNIQUE (db_schema, table_name)`.
|
||||
- **Reference tables:** `meta.currencies`, `meta.timezones`, `meta.exchanges`,
|
||||
`meta.instruments`, `meta.sessions`, `meta.holidays`, `meta.security_types`,
|
||||
`meta.schema_version`.
|
||||
- **Procedures:** `meta.drop_series` / `_if_exists` / `drop_all_series`,
|
||||
`meta.update_series_last_timestamp`, `meta.refresh_series_timestamps`,
|
||||
`meta.read_series_batch[_cursor|_ohlc]`, `log.notify_event_log`,
|
||||
`log.flush_pending_to_event_log`.
|
||||
- **Event trigger:** `prevent_series_drops` — blocks direct `DROP TABLE` on a
|
||||
registered series (drops must go through `meta.drop_series*`).
|
||||
|
||||
Series data tables have **no `UNIQUE` constraint on `timestamp`** — the index is
|
||||
BRIN. Concurrent writers must serialise per-series with the advisory-lock
|
||||
protocol (`pg_advisory_lock(hashtext('tsapi_pgdb.write:{schema}.{table}'))`); see
|
||||
the C++ project's `planning/2026-09-02_cpp_locking_interop_plan.md`.
|
||||
|
||||
---
|
||||
|
||||
## Versioning contract
|
||||
|
||||
Bump [`VERSION`](VERSION) whenever `sql/` changes in a way clients must know
|
||||
about, and have each client read `meta.schema_version` on connect and warn/fail
|
||||
on mismatch. This turns silent schema drift into a loud error.
|
||||
|
||||
---
|
||||
|
||||
## Provenance
|
||||
|
||||
The `sql/` files were seeded (byte-for-byte, 2026-09-02) from the then-current
|
||||
authoritative copy in `TSAPI_SERIESDB_PG_PY/tsapi_pgdb/sql/`. From this point on,
|
||||
**this** directory is authoritative and the Python project should consume it
|
||||
rather than keep its own copy — see the migration note in the C++ project's
|
||||
`planning/` folder.
|
||||
|
||||
> **Known drift caught during setup:** on 2026-09-02 the remote instance
|
||||
> `192.168.1.7` had `meta.sessions.exchange_id` as nullable, while the canonical
|
||||
> DDL (`03_tables.sql`) defines it `NOT NULL`. Re-provision drifted databases
|
||||
> from these files.
|
||||
1
VERSION
Normal file
1
VERSION
Normal file
|
|
@ -0,0 +1 @@
|
|||
1.0.0
|
||||
7
db_config.json.example
Normal file
7
db_config.json.example
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"database": "timeseries_db__dev",
|
||||
"user": "tsapi",
|
||||
"password": "tsapipwd"
|
||||
}
|
||||
211
run_setup.py
Normal file
211
run_setup.py
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
"""
|
||||
Provision the TSAPI series database schema from the canonical SQL files.
|
||||
|
||||
This is the SINGLE SOURCE OF TRUTH provisioner for the TSAPI timeseries
|
||||
PostgreSQL schema. Both the Python library (TSAPI_SERIESDB_PG_PY) and the C++
|
||||
library (TSAPI_POSTGRES_CPP) target the schema it creates. Do not fork the SQL
|
||||
into either project -- edit it here.
|
||||
|
||||
It executes the numbered DDL files in ./sql/ in order:
|
||||
00_extensions, 01_schemas, 02_sequences, 03_tables, 04_indexes,
|
||||
05_procedures, 06_triggers, 07_reference_data
|
||||
|
||||
Connection settings come from (highest precedence first):
|
||||
1. command-line flags (--host --port --dbname --user --password)
|
||||
2. db_config.json next to this script
|
||||
3. built-in defaults (localhost:5432 / timeseries_db__dev / tsapi)
|
||||
|
||||
Usage:
|
||||
python run_setup.py # use db_config.json / defaults
|
||||
python run_setup.py --host 192.168.1.7 --user claude --password claudepwd
|
||||
python run_setup.py --drop-existing # drop meta+series schemas first
|
||||
python run_setup.py --clean-slate # drop ALL user objects first
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
import psycopg2
|
||||
|
||||
SQL_DIR = Path(__file__).parent / "sql"
|
||||
CONFIG_FILE = Path(__file__).parent / "db_config.json"
|
||||
|
||||
# Executed in order. 08_script_log.sql and sql/migrate/*.sql are auxiliary and
|
||||
# are intentionally NOT part of a fresh install.
|
||||
SQL_FILES = [
|
||||
"00_extensions.sql",
|
||||
"01_schemas.sql",
|
||||
"02_sequences.sql",
|
||||
"03_tables.sql",
|
||||
"04_indexes.sql",
|
||||
"05_procedures.sql",
|
||||
"06_triggers.sql",
|
||||
"07_reference_data.sql",
|
||||
]
|
||||
|
||||
DEFAULTS = {
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"database": "timeseries_db__dev",
|
||||
"user": "tsapi",
|
||||
"password": "tsapipwd",
|
||||
}
|
||||
|
||||
|
||||
def load_config(args) -> Dict:
|
||||
config = dict(DEFAULTS)
|
||||
if CONFIG_FILE.exists():
|
||||
try:
|
||||
config.update(json.loads(CONFIG_FILE.read_text()))
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"[FAIL] Invalid JSON in {CONFIG_FILE}: {e}")
|
||||
sys.exit(1)
|
||||
# CLI overrides
|
||||
for key, val in (
|
||||
("host", args.host), ("port", args.port), ("database", args.dbname),
|
||||
("user", args.user), ("password", args.password),
|
||||
):
|
||||
if val is not None:
|
||||
config[key] = val
|
||||
return config
|
||||
|
||||
|
||||
def execute_sql_file(conn, sql_file: Path):
|
||||
try:
|
||||
sql = sql_file.read_text(encoding="utf-8")
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(sql)
|
||||
conn.commit()
|
||||
return True, f"[OK] Executed {sql_file.name}"
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
return False, f"[FAIL] {sql_file.name}: {e}"
|
||||
|
||||
|
||||
def verify_setup(conn) -> None:
|
||||
print("\n" + "=" * 70)
|
||||
print("Verifying setup")
|
||||
print("=" * 70)
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT schema_name FROM information_schema.schemata "
|
||||
"WHERE schema_name IN ('meta','series','log') ORDER BY 1"
|
||||
)
|
||||
print("[OK] Schemas:", ", ".join(r[0] for r in cur.fetchall()))
|
||||
|
||||
cur.execute("SELECT count(*) FROM information_schema.tables WHERE table_schema='meta'")
|
||||
print("[OK] meta tables:", cur.fetchone()[0])
|
||||
|
||||
cur.execute("SELECT count(*) FROM information_schema.routines WHERE routine_schema IN ('meta','log')")
|
||||
print("[OK] procedures:", cur.fetchone()[0])
|
||||
|
||||
cur.execute("SELECT count(*) FROM pg_event_trigger WHERE evtname='prevent_series_drops'")
|
||||
print("[OK] event triggers:", cur.fetchone()[0])
|
||||
|
||||
cur.execute("SELECT count(*) FROM meta.timezones")
|
||||
tz = cur.fetchone()[0]
|
||||
cur.execute("SELECT count(*) FROM meta.currencies")
|
||||
cu = cur.fetchone()[0]
|
||||
print(f"[OK] reference data: {tz} timezones, {cu} currencies")
|
||||
|
||||
cur.execute("SELECT version, description FROM meta.schema_version ORDER BY installed_at DESC LIMIT 1")
|
||||
row = cur.fetchone()
|
||||
if row:
|
||||
print(f"[OK] schema_version: {row[0]} ({row[1]})")
|
||||
|
||||
|
||||
def clean_slate(conn) -> None:
|
||||
print("Performing clean slate...")
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT schema_name FROM information_schema.schemata "
|
||||
"WHERE schema_name NOT IN ('pg_catalog','information_schema','pg_toast','public') "
|
||||
"AND schema_name NOT LIKE 'pg_temp_%' AND schema_name NOT LIKE 'pg_toast_temp_%'"
|
||||
)
|
||||
for (schema,) in cur.fetchall():
|
||||
print(f" drop schema {schema}")
|
||||
cur.execute(f"DROP SCHEMA IF EXISTS {schema} CASCADE")
|
||||
cur.execute("SELECT evtname FROM pg_event_trigger")
|
||||
for (trig,) in cur.fetchall():
|
||||
cur.execute(f"DROP EVENT TRIGGER IF EXISTS {trig}")
|
||||
cur.execute("CREATE SCHEMA IF NOT EXISTS public")
|
||||
conn.commit()
|
||||
print("[OK] clean slate done\n")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
p = argparse.ArgumentParser(description="Provision the TSAPI series DB schema")
|
||||
p.add_argument("--host")
|
||||
p.add_argument("--port", type=int)
|
||||
p.add_argument("--dbname")
|
||||
p.add_argument("--user")
|
||||
p.add_argument("--password")
|
||||
p.add_argument("--drop-existing", action="store_true",
|
||||
help="Drop meta and series schemas before creating (destructive)")
|
||||
p.add_argument("--clean-slate", action="store_true",
|
||||
help="Drop ALL user objects before creating (very destructive)")
|
||||
p.add_argument("--yes", action="store_true", help="Skip confirmation prompts")
|
||||
args = p.parse_args()
|
||||
|
||||
cfg = load_config(args)
|
||||
|
||||
print("=" * 70)
|
||||
print("TSAPI series DB schema setup")
|
||||
print("=" * 70)
|
||||
print(f"Target : {cfg['host']}:{cfg['port']}/{cfg['database']} (user {cfg['user']})")
|
||||
print(f"SQL dir: {SQL_DIR}")
|
||||
|
||||
if (args.clean_slate or args.drop_existing) and not args.yes:
|
||||
what = "ALL user objects" if args.clean_slate else "meta and series schemas"
|
||||
if input(f"This will DROP {what}. Continue? (yes/no): ").lower() != "yes":
|
||||
print("Aborted.")
|
||||
return 1
|
||||
|
||||
try:
|
||||
conn = psycopg2.connect(
|
||||
host=cfg["host"], port=cfg["port"], dbname=cfg["database"],
|
||||
user=cfg["user"], password=cfg["password"],
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[FAIL] connect: {e}")
|
||||
return 1
|
||||
|
||||
try:
|
||||
if args.clean_slate:
|
||||
clean_slate(conn)
|
||||
elif args.drop_existing:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("DROP SCHEMA IF EXISTS meta CASCADE")
|
||||
cur.execute("DROP SCHEMA IF EXISTS series CASCADE")
|
||||
cur.execute("DROP SCHEMA IF EXISTS log CASCADE")
|
||||
cur.execute("DROP EVENT TRIGGER IF EXISTS prevent_series_drops")
|
||||
conn.commit()
|
||||
print("[OK] existing schemas dropped\n")
|
||||
|
||||
failed = []
|
||||
for name in SQL_FILES:
|
||||
f = SQL_DIR / name
|
||||
if not f.exists():
|
||||
print(f"[FAIL] missing {name}")
|
||||
failed.append(name)
|
||||
continue
|
||||
ok, msg = execute_sql_file(conn, f)
|
||||
print(msg)
|
||||
if not ok:
|
||||
failed.append(name)
|
||||
|
||||
if failed:
|
||||
print(f"\n[FAIL] {len(failed)} file(s) failed: {', '.join(failed)}")
|
||||
return 1
|
||||
verify_setup(conn)
|
||||
print("\n[SUCCESS] schema setup complete")
|
||||
return 0
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
4
sql/00_extensions.sql
Normal file
4
sql/00_extensions.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
-- PostgreSQL extensions
|
||||
-- Generated: 2025-10-15T12:24:56.026074
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm SCHEMA public;
|
||||
6
sql/01_schemas.sql
Normal file
6
sql/01_schemas.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
-- Database schemas
|
||||
-- Generated: 2025-10-15T12:24:56.026074
|
||||
|
||||
CREATE SCHEMA IF NOT EXISTS meta;
|
||||
CREATE SCHEMA IF NOT EXISTS series;
|
||||
CREATE SCHEMA IF NOT EXISTS log;
|
||||
16
sql/02_sequences.sql
Normal file
16
sql/02_sequences.sql
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- Sequences
|
||||
-- Generated: 2025-10-15T12:24:56.037289
|
||||
|
||||
CREATE SEQUENCE meta._table_meta__table_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO CYCLE
|
||||
;
|
||||
|
||||
CREATE SEQUENCE log.event_log_id_seq
|
||||
AS bigint
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO CYCLE
|
||||
;
|
||||
145
sql/03_tables.sql
Normal file
145
sql/03_tables.sql
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
-- Meta schema tables
|
||||
-- Generated: 2025-10-15T12:24:56.295509
|
||||
|
||||
CREATE UNLOGGED TABLE log.pending_changes (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
"timestamp" TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
||||
series_name TEXT NOT NULL,
|
||||
db_schema TEXT NOT NULL,
|
||||
op_type TEXT NOT NULL,
|
||||
db_user TEXT DEFAULT CURRENT_USER,
|
||||
details JSONB
|
||||
);
|
||||
|
||||
CREATE TABLE log.event_log (
|
||||
id BIGINT NOT NULL DEFAULT nextval('log.event_log_id_seq'),
|
||||
"timestamp" TIMESTAMPTZ,
|
||||
series_name TEXT NOT NULL,
|
||||
db_schema TEXT NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
details JSONB,
|
||||
source TEXT,
|
||||
db_user TEXT,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE meta.currencies (
|
||||
code character varying(3) NOT NULL,
|
||||
name character varying(100) NOT NULL,
|
||||
symbol character varying(10),
|
||||
decimal_places integer DEFAULT 2,
|
||||
notes text
|
||||
);
|
||||
|
||||
CREATE TABLE meta.exchanges (
|
||||
id character varying(12) NOT NULL,
|
||||
name character varying(50),
|
||||
timezone character varying(35),
|
||||
currency character varying(3),
|
||||
default_sec_type character varying(18),
|
||||
default_session character varying(40),
|
||||
default_holiday_calendar character varying(40),
|
||||
default_tick_size double precision,
|
||||
default_tick_value double precision,
|
||||
default_extended_hours boolean DEFAULT false,
|
||||
country character varying(3)
|
||||
);
|
||||
|
||||
CREATE TABLE meta.holidays (
|
||||
calendar_name character varying(50) NOT NULL,
|
||||
date date NOT NULL,
|
||||
description character varying(255),
|
||||
early_close boolean NOT NULL DEFAULT false,
|
||||
PRIMARY KEY (calendar_name, date)
|
||||
);
|
||||
|
||||
CREATE TABLE meta.instruments (
|
||||
symbol character varying(12) NOT NULL,
|
||||
exchange character varying(12) NOT NULL,
|
||||
name character varying(50) NOT NULL,
|
||||
type character varying(10),
|
||||
tick_size double precision,
|
||||
tick_value double precision,
|
||||
expiry character varying(20),
|
||||
strike double precision,
|
||||
currency character varying(3),
|
||||
session character varying(40),
|
||||
holiday_calendar character varying(50),
|
||||
sec_id character varying(50),
|
||||
sec_id_type character varying(20),
|
||||
description character varying(255),
|
||||
country character varying(3),
|
||||
extended_hours boolean,
|
||||
sector character varying(50),
|
||||
industry character varying(100),
|
||||
category character varying(50),
|
||||
subcategory character varying(50),
|
||||
asset_class character varying(30),
|
||||
geography character varying(30),
|
||||
underlying character varying(30)
|
||||
);
|
||||
|
||||
CREATE TABLE meta.security_types (
|
||||
code character varying(10) NOT NULL,
|
||||
name character varying(50) NOT NULL,
|
||||
description text,
|
||||
notes text
|
||||
);
|
||||
|
||||
CREATE TABLE meta.schema_version (
|
||||
version character varying(20) NOT NULL,
|
||||
installed_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
description text
|
||||
);
|
||||
|
||||
CREATE TABLE meta.series (
|
||||
table_id integer DEFAULT nextval('meta._table_meta__table_id_seq'::regclass) NOT NULL,
|
||||
db_schema character varying(70) NOT NULL,
|
||||
table_name character varying(70) NOT NULL,
|
||||
type character varying(30),
|
||||
description character varying(255),
|
||||
column_schema text DEFAULT ''::text,
|
||||
symbol character varying(30),
|
||||
root_symbol character varying(30),
|
||||
exchange character varying(30),
|
||||
frequency character varying(30),
|
||||
session text,
|
||||
sec_type character varying(30),
|
||||
sec_id character varying(30),
|
||||
sec_id_type character varying(30),
|
||||
create_timestamp timestamp without time zone DEFAULT CURRENT_TIMESTAMP,
|
||||
num_records bigint,
|
||||
first_timestamp timestamp without time zone,
|
||||
last_timestamp timestamp without time zone,
|
||||
bar_type character varying(30),
|
||||
feed character varying(30),
|
||||
currency character varying(30),
|
||||
expiry character varying(30),
|
||||
roll_type character varying(30),
|
||||
feed_type character varying(30),
|
||||
user_attr text,
|
||||
user_attr_2 text,
|
||||
script text,
|
||||
notes text,
|
||||
timezone character varying(50),
|
||||
category character varying(30),
|
||||
subcategory character varying(30),
|
||||
json JSONB,
|
||||
needs_reindex boolean NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE TABLE meta.sessions (
|
||||
name character varying(50) NOT NULL,
|
||||
definition text NOT NULL,
|
||||
"json" text,
|
||||
exchange_id character varying(12) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE meta.timezones (
|
||||
iana_name character varying(50) NOT NULL,
|
||||
display_name character varying(100) NOT NULL,
|
||||
description text,
|
||||
region character varying(50),
|
||||
utc_offset_hours real,
|
||||
notes text
|
||||
);
|
||||
46
sql/04_indexes.sql
Normal file
46
sql/04_indexes.sql
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
-- Indexes and constraints
|
||||
-- Generated: 2025-10-15T12:24:56.570321
|
||||
|
||||
-- Primary key constraints for metadata tables
|
||||
ALTER TABLE meta.instruments ADD CONSTRAINT instruments_pkey PRIMARY KEY (symbol, exchange);
|
||||
ALTER TABLE meta.exchanges ADD CONSTRAINT exchanges_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE meta.sessions ADD CONSTRAINT sessions_pkey PRIMARY KEY (name);
|
||||
|
||||
-- Identity constraints for the series registry and reference tables.
|
||||
--
|
||||
-- These are small registries, not timeseries data: a btree key here costs
|
||||
-- almost nothing. This is unrelated to the deliberate decision NOT to put a
|
||||
-- unique constraint on series timestamps, where BRIN is used precisely
|
||||
-- because a btree would be prohibitive at millions of rows per series.
|
||||
--
|
||||
-- Without these, duplicate registry rows were possible and the add_* methods
|
||||
-- advertised "already exists" errors that no constraint could raise.
|
||||
ALTER TABLE meta.series ADD CONSTRAINT series_pkey PRIMARY KEY (table_id);
|
||||
ALTER TABLE meta.series ADD CONSTRAINT series_schema_table_key UNIQUE (db_schema, table_name);
|
||||
ALTER TABLE meta.currencies ADD CONSTRAINT currencies_pkey PRIMARY KEY (code);
|
||||
ALTER TABLE meta.security_types ADD CONSTRAINT security_types_pkey PRIMARY KEY (code);
|
||||
ALTER TABLE meta.timezones ADD CONSTRAINT timezones_pkey PRIMARY KEY (iana_name);
|
||||
|
||||
CREATE INDEX idx_event_log_series_timestamp ON log.event_log USING btree (series_name, "timestamp" DESC);
|
||||
|
||||
CREATE INDEX idx_event_log_timestamp ON log.event_log USING btree ("timestamp" DESC);
|
||||
|
||||
CREATE INDEX idx_event_log_event_type ON log.event_log USING btree (event_type);
|
||||
|
||||
CREATE INDEX idx_series_create_timestamp_desc ON meta.series USING btree (create_timestamp DESC NULLS LAST);
|
||||
|
||||
CREATE INDEX idx_series_db_schema ON meta.series USING btree (db_schema) WHERE ((db_schema IS NOT NULL) AND ((db_schema)::text <> ''::text));
|
||||
|
||||
CREATE INDEX idx_series_exchange_pattern ON meta.series USING btree (lower((exchange)::text) text_pattern_ops) WHERE ((exchange IS NOT NULL) AND ((exchange)::text <> ''::text));
|
||||
|
||||
CREATE INDEX idx_series_frequency_pattern ON meta.series USING btree (lower((frequency)::text) text_pattern_ops) WHERE ((frequency IS NOT NULL) AND ((frequency)::text <> ''::text));
|
||||
|
||||
CREATE INDEX idx_series_symbol_exchange ON meta.series USING btree (lower((symbol)::text), lower((exchange)::text)) WHERE ((symbol IS NOT NULL) AND ((symbol)::text <> ''::text) AND (exchange IS NOT NULL) AND ((exchange)::text <> ''::text));
|
||||
|
||||
CREATE INDEX idx_series_symbol_pattern ON meta.series USING btree (lower((symbol)::text) text_pattern_ops) WHERE ((symbol IS NOT NULL) AND ((symbol)::text <> ''::text));
|
||||
|
||||
CREATE INDEX idx_series_symbol_trgm ON meta.series USING gin (symbol public.gin_trgm_ops) WHERE ((symbol IS NOT NULL) AND ((symbol)::text <> ''::text));
|
||||
|
||||
CREATE INDEX idx_series_table_name_trgm ON meta.series USING gin (table_name public.gin_trgm_ops) WHERE ((table_name IS NOT NULL) AND ((table_name)::text <> ''::text));
|
||||
|
||||
CREATE INDEX idx_series_type_pattern ON meta.series USING btree (lower((type)::text) text_pattern_ops) WHERE ((type IS NOT NULL) AND ((type)::text <> ''::text));
|
||||
426
sql/05_procedures.sql
Normal file
426
sql/05_procedures.sql
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
-- Stored procedures and functions
|
||||
-- Generated: 2025-10-15T12:24:56.582392
|
||||
|
||||
-- Log schema functions
|
||||
|
||||
-- Function: log.notify_event_log
|
||||
-- Writes a breadcrumb to the staging table (UNLOGGED, fast).
|
||||
-- Self-drains every 20,000th insert to prevent unbounded growth.
|
||||
CREATE OR REPLACE FUNCTION log.notify_event_log(
|
||||
p_series_name TEXT,
|
||||
p_db_schema TEXT,
|
||||
p_op_type TEXT,
|
||||
p_details JSONB DEFAULT NULL
|
||||
) RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO log.pending_changes (series_name, db_schema, op_type, details)
|
||||
VALUES (p_series_name, p_db_schema, p_op_type, p_details);
|
||||
|
||||
-- Self-drain every 20,000th insert
|
||||
IF (currval('log.pending_changes_id_seq') % 20000 = 0) THEN
|
||||
PERFORM log.flush_pending_to_event_log();
|
||||
END IF;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RAISE WARNING 'notify_event_log failed: %', SQLERRM;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: log.flush_pending_to_event_log
|
||||
-- Drains the staging table into the permanent event_log.
|
||||
-- Safe for concurrent use: snapshots max(id) before processing.
|
||||
-- After moving events, verifies that meta.series timestamps match actual
|
||||
-- data for any series that had data-modifying events. If a mismatch is
|
||||
-- found, writes a TIMESTAMP_MISMATCH event to log.event_log for visibility.
|
||||
-- (Timestamps are kept accurate by the application on every data operation,
|
||||
-- so this step is a safety net, not a correction mechanism.)
|
||||
CREATE OR REPLACE FUNCTION log.flush_pending_to_event_log()
|
||||
RETURNS INT
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
batch_id BIGINT;
|
||||
v_count INT;
|
||||
_rec RECORD;
|
||||
_actual_first TIMESTAMP;
|
||||
_actual_last TIMESTAMP;
|
||||
_meta_first TIMESTAMP;
|
||||
_meta_last TIMESTAMP;
|
||||
BEGIN
|
||||
-- Serialise flushes. Snapshotting MAX(id) does not make this safe on its
|
||||
-- own: two callers can both read the same batch_id, both copy those rows
|
||||
-- to log.event_log, and only then delete them -- duplicating permanent
|
||||
-- audit events. The lock is transaction-scoped, so it is released when
|
||||
-- this function's transaction ends, however it ends.
|
||||
PERFORM pg_advisory_xact_lock(hashtext('tsapi_pgdb.flush_event_log'));
|
||||
|
||||
SELECT COALESCE(MAX(id), 0) INTO batch_id FROM log.pending_changes;
|
||||
IF batch_id = 0 THEN RETURN 0; END IF;
|
||||
|
||||
-- 1. Move rows from staging to permanent event_log
|
||||
INSERT INTO log.event_log ("timestamp", series_name, db_schema, event_type, details, source, db_user)
|
||||
SELECT "timestamp", series_name, db_schema, op_type, details, 'app', db_user
|
||||
FROM log.pending_changes
|
||||
WHERE id <= batch_id
|
||||
ORDER BY id;
|
||||
|
||||
GET DIAGNOSTICS v_count = ROW_COUNT;
|
||||
|
||||
-- 2. Verify meta.series timestamps for series with data-modifying events
|
||||
FOR _rec IN
|
||||
SELECT DISTINCT series_name, db_schema
|
||||
FROM log.pending_changes
|
||||
WHERE id <= batch_id
|
||||
AND op_type IN (
|
||||
'CSV_IMPORT', 'JSON_APPEND', 'DATAFRAME_IMPORT',
|
||||
'DELETE_FROM', 'DELETE_AFTER', 'DELETE_RANGE', 'DELETE_UNTIL',
|
||||
'DELETE_WEEKENDS', 'DELETE_TIME_RANGE', 'SERIES_TRUNCATED'
|
||||
)
|
||||
LOOP
|
||||
BEGIN
|
||||
EXECUTE format(
|
||||
'SELECT MIN(timestamp), MAX(timestamp) FROM %I.%I',
|
||||
_rec.db_schema, _rec.series_name
|
||||
) INTO _actual_first, _actual_last;
|
||||
|
||||
SELECT first_timestamp, last_timestamp INTO _meta_first, _meta_last
|
||||
FROM meta.series
|
||||
WHERE table_name = _rec.series_name AND db_schema = _rec.db_schema;
|
||||
|
||||
IF _meta_first IS DISTINCT FROM _actual_first
|
||||
OR _meta_last IS DISTINCT FROM _actual_last THEN
|
||||
INSERT INTO log.event_log
|
||||
("timestamp", series_name, db_schema, event_type, details, source, db_user)
|
||||
VALUES (
|
||||
CURRENT_TIMESTAMP,
|
||||
_rec.series_name,
|
||||
_rec.db_schema,
|
||||
'TIMESTAMP_MISMATCH',
|
||||
jsonb_build_object(
|
||||
'meta_first', _meta_first,
|
||||
'meta_last', _meta_last,
|
||||
'actual_first', _actual_first,
|
||||
'actual_last', _actual_last
|
||||
),
|
||||
'flush_verify',
|
||||
CURRENT_USER
|
||||
);
|
||||
END IF;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
NULL; -- table may have been dropped in same batch
|
||||
END;
|
||||
END LOOP;
|
||||
|
||||
-- 3. Clear staging
|
||||
DELETE FROM log.pending_changes WHERE id <= batch_id;
|
||||
|
||||
RETURN v_count;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Meta schema functions
|
||||
|
||||
-- Function: meta.update_series_last_timestamp
|
||||
-- Lightweight timestamp update for append operations.
|
||||
-- Uses GREATEST to conditionally update last_timestamp (no table scan).
|
||||
-- Sets first_timestamp on first insert via COALESCE.
|
||||
-- p_first_timestamp is optional: when NULL, uses p_last_timestamp for first_timestamp.
|
||||
-- For single inserts, only p_last_timestamp is needed.
|
||||
-- For batch inserts, pass min timestamp as p_first_timestamp.
|
||||
-- Both Python and C++ clients call this after appending data.
|
||||
CREATE OR REPLACE FUNCTION meta.update_series_last_timestamp(
|
||||
p_table_name TEXT,
|
||||
p_db_schema TEXT DEFAULT 'series',
|
||||
p_last_timestamp TIMESTAMP DEFAULT NULL,
|
||||
p_first_timestamp TIMESTAMP DEFAULT NULL
|
||||
) RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
UPDATE meta.series
|
||||
SET first_timestamp = COALESCE(first_timestamp, p_first_timestamp, p_last_timestamp),
|
||||
last_timestamp = GREATEST(last_timestamp, p_last_timestamp)
|
||||
WHERE table_name = p_table_name AND db_schema = p_db_schema;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.refresh_series_timestamps
|
||||
-- Full timestamp refresh using MIN/MAX scan.
|
||||
-- Used after deletes, truncates, or any operation that may change first_timestamp.
|
||||
-- BRIN indexes make MIN/MAX fast even on large tables.
|
||||
-- Both Python and C++ clients call this after data deletion.
|
||||
CREATE OR REPLACE FUNCTION meta.refresh_series_timestamps(
|
||||
p_table_name TEXT,
|
||||
p_db_schema TEXT DEFAULT 'series'
|
||||
) RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
_first_ts TIMESTAMP;
|
||||
_last_ts TIMESTAMP;
|
||||
BEGIN
|
||||
EXECUTE format(
|
||||
'SELECT MIN(timestamp), MAX(timestamp) FROM %I.%I',
|
||||
p_db_schema, p_table_name
|
||||
) INTO _first_ts, _last_ts;
|
||||
|
||||
UPDATE meta.series
|
||||
SET first_timestamp = _first_ts, last_timestamp = _last_ts
|
||||
WHERE table_name = p_table_name AND db_schema = p_db_schema;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.drop_all_series
|
||||
CREATE OR REPLACE FUNCTION meta.drop_all_series()
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
_rec record;
|
||||
BEGIN
|
||||
-- Set the context to allow drops
|
||||
PERFORM set_config('application.dropping_series', 'true', true);
|
||||
|
||||
-- Loop through all series in series table
|
||||
FOR _rec IN SELECT "table_name", "db_schema" FROM meta.series
|
||||
LOOP
|
||||
-- Drop each table
|
||||
EXECUTE format('DROP TABLE IF EXISTS %I.%I', _rec."db_schema", _rec."table_name");
|
||||
END LOOP;
|
||||
|
||||
-- Clear the series table
|
||||
DELETE FROM meta.series;
|
||||
|
||||
-- Reset the context
|
||||
PERFORM set_config('application.dropping_series', 'false', true);
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.drop_series
|
||||
CREATE OR REPLACE FUNCTION meta.drop_series(_table_name text, _schema_name text DEFAULT 'series'::text, _raise_if_missing boolean DEFAULT true)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
-- Check if the series exists in series table
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM meta.series
|
||||
WHERE "table_name" = _table_name
|
||||
AND "db_schema" = _schema_name
|
||||
) THEN
|
||||
IF _raise_if_missing THEN
|
||||
RAISE EXCEPTION 'Series %.% does not exist', _schema_name, _table_name;
|
||||
END IF;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- Set the context to allow drops
|
||||
PERFORM set_config('application.dropping_series', 'true', true);
|
||||
|
||||
-- Drop the table
|
||||
EXECUTE format('DROP TABLE IF EXISTS %I.%I', _schema_name, _table_name);
|
||||
|
||||
-- Remove from series table
|
||||
DELETE FROM meta.series
|
||||
WHERE "table_name" = _table_name
|
||||
AND "db_schema" = _schema_name;
|
||||
|
||||
-- Reset the context
|
||||
PERFORM set_config('application.dropping_series', 'false', true);
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.drop_series_if_exists
|
||||
CREATE OR REPLACE FUNCTION meta.drop_series_if_exists(_table_name text, _schema_name text DEFAULT 'series'::text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
-- Check if the series exists in series table
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM meta.series
|
||||
WHERE "table_name" = _table_name
|
||||
AND "db_schema" = _schema_name
|
||||
) THEN
|
||||
-- Signal the prevent_direct_drop event trigger that this DROP is
|
||||
-- coming from a sanctioned procedure. Without it the trigger rejects
|
||||
-- the statement below, because the table is registered in meta.series.
|
||||
-- Local to the transaction, so it cannot leak to later statements.
|
||||
PERFORM set_config('application.dropping_series', 'true', true);
|
||||
|
||||
-- Drop the table
|
||||
EXECUTE format('DROP TABLE IF EXISTS %I.%I', _schema_name, _table_name);
|
||||
|
||||
-- Remove from series table
|
||||
DELETE FROM meta.series
|
||||
WHERE "table_name" = _table_name
|
||||
AND "db_schema" = _schema_name;
|
||||
|
||||
PERFORM set_config('application.dropping_series', 'false', true);
|
||||
END IF;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.prevent_direct_drop
|
||||
CREATE OR REPLACE FUNCTION meta.prevent_direct_drop()
|
||||
RETURNS event_trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
obj record;
|
||||
BEGIN
|
||||
-- Get the current context
|
||||
IF current_setting('application.dropping_series', true) = 'true' THEN
|
||||
-- Allow the drop if it's coming from our procedures
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
|
||||
WHERE object_type = 'table'
|
||||
LOOP
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM meta.series
|
||||
WHERE table_name = obj.object_name
|
||||
AND db_schema = obj.schema_name
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Table %.% is registered in series and can only be dropped using TimeseriesDB.drop_series()',
|
||||
obj.schema_name, obj.object_name;
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.read_series_batch
|
||||
CREATE OR REPLACE FUNCTION meta.read_series_batch(p_schema_name text, p_table_name text, p_start_ts timestamp without time zone DEFAULT NULL::timestamp without time zone, p_batch_size integer DEFAULT 10000)
|
||||
RETURNS TABLE(result_json jsonb)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
v_query TEXT;
|
||||
v_qualified_name TEXT;
|
||||
BEGIN
|
||||
-- Build qualified table name (with proper quoting)
|
||||
v_qualified_name := format('%I.%I', p_schema_name, p_table_name);
|
||||
|
||||
-- Build query with proper WHERE clause
|
||||
IF p_start_ts IS NULL THEN
|
||||
-- Read from beginning
|
||||
v_query := format('
|
||||
SELECT to_jsonb(t.*) AS result_json
|
||||
FROM (
|
||||
SELECT *
|
||||
FROM %s
|
||||
ORDER BY timestamp
|
||||
LIMIT %s
|
||||
) t
|
||||
', v_qualified_name, p_batch_size);
|
||||
ELSE
|
||||
-- Read from specified timestamp (inclusive)
|
||||
v_query := format('
|
||||
SELECT to_jsonb(t.*) AS result_json
|
||||
FROM (
|
||||
SELECT *
|
||||
FROM %s
|
||||
WHERE timestamp >= %L
|
||||
ORDER BY timestamp
|
||||
LIMIT %s
|
||||
) t
|
||||
', v_qualified_name, p_start_ts, p_batch_size);
|
||||
END IF;
|
||||
|
||||
-- Execute and return
|
||||
RETURN QUERY EXECUTE v_query;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.read_series_batch_cursor
|
||||
CREATE OR REPLACE FUNCTION meta.read_series_batch_cursor(p_schema_name text, p_table_name text, p_start_ts timestamp without time zone DEFAULT NULL::timestamp without time zone, p_batch_size integer DEFAULT 10000, p_cursor_name text DEFAULT 'series_cursor'::text)
|
||||
RETURNS refcursor
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
v_query TEXT;
|
||||
v_qualified_name TEXT;
|
||||
v_cursor refcursor;
|
||||
BEGIN
|
||||
-- Build qualified table name (with proper quoting)
|
||||
v_qualified_name := format('%I.%I', p_schema_name, p_table_name);
|
||||
|
||||
-- Open cursor with name
|
||||
v_cursor := p_cursor_name;
|
||||
|
||||
-- Build query with proper WHERE clause
|
||||
IF p_start_ts IS NULL THEN
|
||||
-- Read from beginning
|
||||
v_query := format('
|
||||
SELECT *
|
||||
FROM %s
|
||||
ORDER BY timestamp
|
||||
LIMIT %s
|
||||
', v_qualified_name, p_batch_size);
|
||||
ELSE
|
||||
-- Read from specified timestamp (inclusive)
|
||||
v_query := format('
|
||||
SELECT *
|
||||
FROM %s
|
||||
WHERE timestamp >= %L
|
||||
ORDER BY timestamp
|
||||
LIMIT %s
|
||||
', v_qualified_name, p_start_ts, p_batch_size);
|
||||
END IF;
|
||||
|
||||
-- Open cursor
|
||||
OPEN v_cursor FOR EXECUTE v_query;
|
||||
|
||||
RETURN v_cursor;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
-- Function: meta.read_series_batch_ohlc
|
||||
CREATE OR REPLACE FUNCTION meta.read_series_batch_ohlc(p_schema_name text, p_table_name text, p_start_ts timestamp without time zone DEFAULT NULL::timestamp without time zone, p_batch_size integer DEFAULT 10000)
|
||||
RETURNS TABLE(ts timestamp without time zone, open double precision, high double precision, low double precision, close double precision, volume bigint)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
v_query TEXT;
|
||||
v_qualified_name TEXT;
|
||||
BEGIN
|
||||
-- Build qualified table name (with proper quoting)
|
||||
v_qualified_name := format('%I.%I', p_schema_name, p_table_name);
|
||||
|
||||
-- Build query with proper WHERE clause
|
||||
IF p_start_ts IS NULL THEN
|
||||
-- Read from beginning
|
||||
v_query := format('
|
||||
SELECT timestamp AS ts, open, high, low, close, volume
|
||||
FROM %s
|
||||
ORDER BY timestamp
|
||||
LIMIT %s
|
||||
', v_qualified_name, p_batch_size);
|
||||
ELSE
|
||||
-- Read from specified timestamp (inclusive)
|
||||
v_query := format('
|
||||
SELECT timestamp AS ts, open, high, low, close, volume
|
||||
FROM %s
|
||||
WHERE timestamp >= %L
|
||||
ORDER BY timestamp
|
||||
LIMIT %s
|
||||
', v_qualified_name, p_start_ts, p_batch_size);
|
||||
END IF;
|
||||
|
||||
-- Execute and return
|
||||
RETURN QUERY EXECUTE v_query;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
37
sql/06_triggers.sql
Normal file
37
sql/06_triggers.sql
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
-- Triggers and event triggers
|
||||
-- Generated: 2025-10-15T12:24:56.582392
|
||||
|
||||
-- Event triggers
|
||||
-- Event trigger: prevent_series_drops
|
||||
CREATE OR REPLACE FUNCTION meta.prevent_direct_drop()
|
||||
RETURNS event_trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
obj record;
|
||||
BEGIN
|
||||
-- Get the current context
|
||||
IF current_setting('application.dropping_series', true) = 'true' THEN
|
||||
-- Allow the drop if it's coming from our procedures
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
|
||||
WHERE object_type = 'table'
|
||||
LOOP
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM meta.series
|
||||
WHERE table_name = obj.object_name
|
||||
AND db_schema = obj.schema_name
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Table %.% is registered in series and can only be dropped using TimeseriesDB.drop_series()',
|
||||
obj.schema_name, obj.object_name;
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
$function$;
|
||||
|
||||
|
||||
CREATE EVENT TRIGGER prevent_series_drops
|
||||
ON sql_drop
|
||||
EXECUTE FUNCTION meta.prevent_direct_drop();
|
||||
769
sql/07_reference_data.sql
Normal file
769
sql/07_reference_data.sql
Normal file
|
|
@ -0,0 +1,769 @@
|
|||
-- Reference data (timezones and currencies)
|
||||
-- Generated: 2025-10-15T12:24:56.582392
|
||||
|
||||
-- Timezones
|
||||
INSERT INTO meta.timezones (iana_name, display_name, description, region, utc_offset_hours, notes)
|
||||
VALUES
|
||||
('Africa/Abidjan', 'Africa/Abidjan', 'IANA timezone: Africa/Abidjan', 'Africa', 0.0, NULL),
|
||||
('Africa/Accra', 'Africa/Accra', 'IANA timezone: Africa/Accra', 'Africa', 0.0, NULL),
|
||||
('Africa/Addis_Ababa', 'Africa/Addis Ababa', 'IANA timezone: Africa/Addis_Ababa', 'Africa', 3.0, NULL),
|
||||
('Africa/Algiers', 'Africa/Algiers', 'IANA timezone: Africa/Algiers', 'Africa', 1.0, NULL),
|
||||
('Africa/Asmara', 'Africa/Asmara', 'IANA timezone: Africa/Asmara', 'Africa', 3.0, NULL),
|
||||
('Africa/Asmera', 'Africa/Asmera', 'IANA timezone: Africa/Asmera', 'Africa', 3.0, NULL),
|
||||
('Africa/Bamako', 'Africa/Bamako', 'IANA timezone: Africa/Bamako', 'Africa', 0.0, NULL),
|
||||
('Africa/Bangui', 'Africa/Bangui', 'IANA timezone: Africa/Bangui', 'Africa', 1.0, NULL),
|
||||
('Africa/Banjul', 'Africa/Banjul', 'IANA timezone: Africa/Banjul', 'Africa', 0.0, NULL),
|
||||
('Africa/Bissau', 'Africa/Bissau', 'IANA timezone: Africa/Bissau', 'Africa', 0.0, NULL),
|
||||
('Africa/Blantyre', 'Africa/Blantyre', 'IANA timezone: Africa/Blantyre', 'Africa', 2.0, NULL),
|
||||
('Africa/Brazzaville', 'Africa/Brazzaville', 'IANA timezone: Africa/Brazzaville', 'Africa', 1.0, NULL),
|
||||
('Africa/Bujumbura', 'Africa/Bujumbura', 'IANA timezone: Africa/Bujumbura', 'Africa', 2.0, NULL),
|
||||
('Africa/Cairo', 'Africa/Cairo', 'IANA timezone: Africa/Cairo', 'Africa', 3.0, NULL),
|
||||
('Africa/Casablanca', 'Africa/Casablanca', 'IANA timezone: Africa/Casablanca', 'Africa', 1.0, NULL),
|
||||
('Africa/Ceuta', 'Africa/Ceuta', 'IANA timezone: Africa/Ceuta', 'Africa', 2.0, NULL),
|
||||
('Africa/Conakry', 'Africa/Conakry', 'IANA timezone: Africa/Conakry', 'Africa', 0.0, NULL),
|
||||
('Africa/Dakar', 'Africa/Dakar', 'IANA timezone: Africa/Dakar', 'Africa', 0.0, NULL),
|
||||
('Africa/Dar_es_Salaam', 'Africa/Dar es Salaam', 'IANA timezone: Africa/Dar_es_Salaam', 'Africa', 3.0, NULL),
|
||||
('Africa/Djibouti', 'Africa/Djibouti', 'IANA timezone: Africa/Djibouti', 'Africa', 3.0, NULL),
|
||||
('Africa/Douala', 'Africa/Douala', 'IANA timezone: Africa/Douala', 'Africa', 1.0, NULL),
|
||||
('Africa/El_Aaiun', 'Africa/El Aaiun', 'IANA timezone: Africa/El_Aaiun', 'Africa', 1.0, NULL),
|
||||
('Africa/Freetown', 'Africa/Freetown', 'IANA timezone: Africa/Freetown', 'Africa', 0.0, NULL),
|
||||
('Africa/Gaborone', 'Africa/Gaborone', 'IANA timezone: Africa/Gaborone', 'Africa', 2.0, NULL),
|
||||
('Africa/Harare', 'Africa/Harare', 'IANA timezone: Africa/Harare', 'Africa', 2.0, NULL),
|
||||
('Africa/Johannesburg', 'Africa/Johannesburg', 'IANA timezone: Africa/Johannesburg', 'Africa', 2.0, NULL),
|
||||
('Africa/Juba', 'Africa/Juba', 'IANA timezone: Africa/Juba', 'Africa', 2.0, NULL),
|
||||
('Africa/Kampala', 'Africa/Kampala', 'IANA timezone: Africa/Kampala', 'Africa', 3.0, NULL),
|
||||
('Africa/Khartoum', 'Africa/Khartoum', 'IANA timezone: Africa/Khartoum', 'Africa', 2.0, NULL),
|
||||
('Africa/Kigali', 'Africa/Kigali', 'IANA timezone: Africa/Kigali', 'Africa', 2.0, NULL),
|
||||
('Africa/Kinshasa', 'Africa/Kinshasa', 'IANA timezone: Africa/Kinshasa', 'Africa', 1.0, NULL),
|
||||
('Africa/Lagos', 'Africa/Lagos', 'IANA timezone: Africa/Lagos', 'Africa', 1.0, NULL),
|
||||
('Africa/Libreville', 'Africa/Libreville', 'IANA timezone: Africa/Libreville', 'Africa', 1.0, NULL),
|
||||
('Africa/Lome', 'Africa/Lome', 'IANA timezone: Africa/Lome', 'Africa', 0.0, NULL),
|
||||
('Africa/Luanda', 'Africa/Luanda', 'IANA timezone: Africa/Luanda', 'Africa', 1.0, NULL),
|
||||
('Africa/Lubumbashi', 'Africa/Lubumbashi', 'IANA timezone: Africa/Lubumbashi', 'Africa', 2.0, NULL),
|
||||
('Africa/Lusaka', 'Africa/Lusaka', 'IANA timezone: Africa/Lusaka', 'Africa', 2.0, NULL),
|
||||
('Africa/Malabo', 'Africa/Malabo', 'IANA timezone: Africa/Malabo', 'Africa', 1.0, NULL),
|
||||
('Africa/Maputo', 'Africa/Maputo', 'IANA timezone: Africa/Maputo', 'Africa', 2.0, NULL),
|
||||
('Africa/Maseru', 'Africa/Maseru', 'IANA timezone: Africa/Maseru', 'Africa', 2.0, NULL),
|
||||
('Africa/Mbabane', 'Africa/Mbabane', 'IANA timezone: Africa/Mbabane', 'Africa', 2.0, NULL),
|
||||
('Africa/Mogadishu', 'Africa/Mogadishu', 'IANA timezone: Africa/Mogadishu', 'Africa', 3.0, NULL),
|
||||
('Africa/Monrovia', 'Africa/Monrovia', 'IANA timezone: Africa/Monrovia', 'Africa', 0.0, NULL),
|
||||
('Africa/Nairobi', 'Africa/Nairobi', 'IANA timezone: Africa/Nairobi', 'Africa', 3.0, NULL),
|
||||
('Africa/Ndjamena', 'Africa/Ndjamena', 'IANA timezone: Africa/Ndjamena', 'Africa', 1.0, NULL),
|
||||
('Africa/Niamey', 'Africa/Niamey', 'IANA timezone: Africa/Niamey', 'Africa', 1.0, NULL),
|
||||
('Africa/Nouakchott', 'Africa/Nouakchott', 'IANA timezone: Africa/Nouakchott', 'Africa', 0.0, NULL),
|
||||
('Africa/Ouagadougou', 'Africa/Ouagadougou', 'IANA timezone: Africa/Ouagadougou', 'Africa', 0.0, NULL),
|
||||
('Africa/Porto-Novo', 'Africa/Porto-Novo', 'IANA timezone: Africa/Porto-Novo', 'Africa', 1.0, NULL),
|
||||
('Africa/Sao_Tome', 'Africa/Sao Tome', 'IANA timezone: Africa/Sao_Tome', 'Africa', 0.0, NULL),
|
||||
('Africa/Timbuktu', 'Africa/Timbuktu', 'IANA timezone: Africa/Timbuktu', 'Africa', 0.0, NULL),
|
||||
('Africa/Tripoli', 'Africa/Tripoli', 'IANA timezone: Africa/Tripoli', 'Africa', 2.0, NULL),
|
||||
('Africa/Tunis', 'Africa/Tunis', 'IANA timezone: Africa/Tunis', 'Africa', 1.0, NULL),
|
||||
('Africa/Windhoek', 'Africa/Windhoek', 'IANA timezone: Africa/Windhoek', 'Africa', 2.0, NULL),
|
||||
('America/Adak', 'America/Adak', 'IANA timezone: America/Adak', 'America', -9.0, NULL),
|
||||
('America/Anchorage', 'America/Anchorage', 'IANA timezone: America/Anchorage', 'America', -8.0, NULL),
|
||||
('America/Anguilla', 'America/Anguilla', 'IANA timezone: America/Anguilla', 'America', -4.0, NULL),
|
||||
('America/Antigua', 'America/Antigua', 'IANA timezone: America/Antigua', 'America', -4.0, NULL),
|
||||
('America/Araguaina', 'America/Araguaina', 'IANA timezone: America/Araguaina', 'America', -3.0, NULL),
|
||||
('America/Argentina/Buenos_Aires', 'America/Argentina/Buenos Aires', 'IANA timezone: America/Argentina/Buenos_Aires', 'America', -3.0, NULL),
|
||||
('America/Argentina/Catamarca', 'America/Argentina/Catamarca', 'IANA timezone: America/Argentina/Catamarca', 'America', -3.0, NULL),
|
||||
('America/Argentina/ComodRivadavia', 'America/Argentina/ComodRivadavia', 'IANA timezone: America/Argentina/ComodRivadavia', 'America', -3.0, NULL),
|
||||
('America/Argentina/Cordoba', 'America/Argentina/Cordoba', 'IANA timezone: America/Argentina/Cordoba', 'America', -3.0, NULL),
|
||||
('America/Argentina/Jujuy', 'America/Argentina/Jujuy', 'IANA timezone: America/Argentina/Jujuy', 'America', -3.0, NULL),
|
||||
('America/Argentina/La_Rioja', 'America/Argentina/La Rioja', 'IANA timezone: America/Argentina/La_Rioja', 'America', -3.0, NULL),
|
||||
('America/Argentina/Mendoza', 'America/Argentina/Mendoza', 'IANA timezone: America/Argentina/Mendoza', 'America', -3.0, NULL),
|
||||
('America/Argentina/Rio_Gallegos', 'America/Argentina/Rio Gallegos', 'IANA timezone: America/Argentina/Rio_Gallegos', 'America', -3.0, NULL),
|
||||
('America/Argentina/Salta', 'America/Argentina/Salta', 'IANA timezone: America/Argentina/Salta', 'America', -3.0, NULL),
|
||||
('America/Argentina/San_Juan', 'America/Argentina/San Juan', 'IANA timezone: America/Argentina/San_Juan', 'America', -3.0, NULL),
|
||||
('America/Argentina/San_Luis', 'America/Argentina/San Luis', 'IANA timezone: America/Argentina/San_Luis', 'America', -3.0, NULL),
|
||||
('America/Argentina/Tucuman', 'America/Argentina/Tucuman', 'IANA timezone: America/Argentina/Tucuman', 'America', -3.0, NULL),
|
||||
('America/Argentina/Ushuaia', 'America/Argentina/Ushuaia', 'IANA timezone: America/Argentina/Ushuaia', 'America', -3.0, NULL),
|
||||
('America/Aruba', 'America/Aruba', 'IANA timezone: America/Aruba', 'America', -4.0, NULL),
|
||||
('America/Asuncion', 'America/Asuncion', 'IANA timezone: America/Asuncion', 'America', -3.0, NULL),
|
||||
('America/Atikokan', 'America/Atikokan', 'IANA timezone: America/Atikokan', 'America', -5.0, NULL),
|
||||
('America/Atka', 'America/Atka', 'IANA timezone: America/Atka', 'America', -9.0, NULL),
|
||||
('America/Bahia', 'America/Bahia', 'IANA timezone: America/Bahia', 'America', -3.0, NULL),
|
||||
('America/Bahia_Banderas', 'America/Bahia Banderas', 'IANA timezone: America/Bahia_Banderas', 'America', -6.0, NULL),
|
||||
('America/Barbados', 'America/Barbados', 'IANA timezone: America/Barbados', 'America', -4.0, NULL),
|
||||
('America/Belem', 'America/Belem', 'IANA timezone: America/Belem', 'America', -3.0, NULL),
|
||||
('America/Belize', 'America/Belize', 'IANA timezone: America/Belize', 'America', -6.0, NULL),
|
||||
('America/Blanc-Sablon', 'America/Blanc-Sablon', 'IANA timezone: America/Blanc-Sablon', 'America', -4.0, NULL),
|
||||
('America/Boa_Vista', 'America/Boa Vista', 'IANA timezone: America/Boa_Vista', 'America', -4.0, NULL),
|
||||
('America/Bogota', 'America/Bogota', 'IANA timezone: America/Bogota', 'America', -5.0, NULL),
|
||||
('America/Boise', 'America/Boise', 'IANA timezone: America/Boise', 'America', -6.0, NULL),
|
||||
('America/Buenos_Aires', 'America/Buenos Aires', 'IANA timezone: America/Buenos_Aires', 'America', -3.0, NULL),
|
||||
('America/Cambridge_Bay', 'America/Cambridge Bay', 'IANA timezone: America/Cambridge_Bay', 'America', -6.0, NULL),
|
||||
('America/Campo_Grande', 'America/Campo Grande', 'IANA timezone: America/Campo_Grande', 'America', -4.0, NULL),
|
||||
('America/Cancun', 'America/Cancun', 'IANA timezone: America/Cancun', 'America', -5.0, NULL),
|
||||
('America/Caracas', 'America/Caracas', 'IANA timezone: America/Caracas', 'America', -4.0, NULL),
|
||||
('America/Catamarca', 'America/Catamarca', 'IANA timezone: America/Catamarca', 'America', -3.0, NULL),
|
||||
('America/Cayenne', 'America/Cayenne', 'IANA timezone: America/Cayenne', 'America', -3.0, NULL),
|
||||
('America/Cayman', 'America/Cayman', 'IANA timezone: America/Cayman', 'America', -5.0, NULL),
|
||||
('America/Chicago', 'America/Chicago', 'IANA timezone: America/Chicago', 'America', -5.0, NULL),
|
||||
('America/Chihuahua', 'America/Chihuahua', 'IANA timezone: America/Chihuahua', 'America', -6.0, NULL),
|
||||
('America/Ciudad_Juarez', 'America/Ciudad Juarez', 'IANA timezone: America/Ciudad_Juarez', 'America', -6.0, NULL),
|
||||
('America/Coral_Harbour', 'America/Coral Harbour', 'IANA timezone: America/Coral_Harbour', 'America', -5.0, NULL),
|
||||
('America/Cordoba', 'America/Cordoba', 'IANA timezone: America/Cordoba', 'America', -3.0, NULL),
|
||||
('America/Costa_Rica', 'America/Costa Rica', 'IANA timezone: America/Costa_Rica', 'America', -6.0, NULL),
|
||||
('America/Coyhaique', 'America/Coyhaique', 'IANA timezone: America/Coyhaique', 'America', -3.0, NULL),
|
||||
('America/Creston', 'America/Creston', 'IANA timezone: America/Creston', 'America', -7.0, NULL),
|
||||
('America/Cuiaba', 'America/Cuiaba', 'IANA timezone: America/Cuiaba', 'America', -4.0, NULL),
|
||||
('America/Curacao', 'America/Curacao', 'IANA timezone: America/Curacao', 'America', -4.0, NULL),
|
||||
('America/Danmarkshavn', 'America/Danmarkshavn', 'IANA timezone: America/Danmarkshavn', 'America', 0.0, NULL),
|
||||
('America/Dawson', 'America/Dawson', 'IANA timezone: America/Dawson', 'America', -7.0, NULL),
|
||||
('America/Dawson_Creek', 'America/Dawson Creek', 'IANA timezone: America/Dawson_Creek', 'America', -7.0, NULL),
|
||||
('America/Denver', 'America/Denver', 'IANA timezone: America/Denver', 'America', -6.0, NULL),
|
||||
('America/Detroit', 'America/Detroit', 'IANA timezone: America/Detroit', 'America', -4.0, NULL),
|
||||
('America/Dominica', 'America/Dominica', 'IANA timezone: America/Dominica', 'America', -4.0, NULL),
|
||||
('America/Edmonton', 'America/Edmonton', 'IANA timezone: America/Edmonton', 'America', -6.0, NULL),
|
||||
('America/Eirunepe', 'America/Eirunepe', 'IANA timezone: America/Eirunepe', 'America', -5.0, NULL),
|
||||
('America/El_Salvador', 'America/El Salvador', 'IANA timezone: America/El_Salvador', 'America', -6.0, NULL),
|
||||
('America/Ensenada', 'America/Ensenada', 'IANA timezone: America/Ensenada', 'America', -7.0, NULL),
|
||||
('America/Fortaleza', 'America/Fortaleza', 'IANA timezone: America/Fortaleza', 'America', -3.0, NULL),
|
||||
('America/Fort_Nelson', 'America/Fort Nelson', 'IANA timezone: America/Fort_Nelson', 'America', -7.0, NULL),
|
||||
('America/Fort_Wayne', 'America/Fort Wayne', 'IANA timezone: America/Fort_Wayne', 'America', -4.0, NULL),
|
||||
('America/Glace_Bay', 'America/Glace Bay', 'IANA timezone: America/Glace_Bay', 'America', -3.0, NULL),
|
||||
('America/Godthab', 'America/Godthab', 'IANA timezone: America/Godthab', 'America', -1.0, NULL),
|
||||
('America/Goose_Bay', 'America/Goose Bay', 'IANA timezone: America/Goose_Bay', 'America', -3.0, NULL),
|
||||
('America/Grand_Turk', 'America/Grand Turk', 'IANA timezone: America/Grand_Turk', 'America', -4.0, NULL),
|
||||
('America/Grenada', 'America/Grenada', 'IANA timezone: America/Grenada', 'America', -4.0, NULL),
|
||||
('America/Guadeloupe', 'America/Guadeloupe', 'IANA timezone: America/Guadeloupe', 'America', -4.0, NULL),
|
||||
('America/Guatemala', 'America/Guatemala', 'IANA timezone: America/Guatemala', 'America', -6.0, NULL),
|
||||
('America/Guayaquil', 'America/Guayaquil', 'IANA timezone: America/Guayaquil', 'America', -5.0, NULL),
|
||||
('America/Guyana', 'America/Guyana', 'IANA timezone: America/Guyana', 'America', -4.0, NULL),
|
||||
('America/Halifax', 'America/Halifax', 'IANA timezone: America/Halifax', 'America', -3.0, NULL),
|
||||
('America/Havana', 'America/Havana', 'IANA timezone: America/Havana', 'America', -4.0, NULL),
|
||||
('America/Hermosillo', 'America/Hermosillo', 'IANA timezone: America/Hermosillo', 'America', -7.0, NULL),
|
||||
('America/Indiana/Indianapolis', 'America/Indiana/Indianapolis', 'IANA timezone: America/Indiana/Indianapolis', 'America', -4.0, NULL),
|
||||
('America/Indiana/Knox', 'America/Indiana/Knox', 'IANA timezone: America/Indiana/Knox', 'America', -5.0, NULL),
|
||||
('America/Indiana/Marengo', 'America/Indiana/Marengo', 'IANA timezone: America/Indiana/Marengo', 'America', -4.0, NULL),
|
||||
('America/Indiana/Petersburg', 'America/Indiana/Petersburg', 'IANA timezone: America/Indiana/Petersburg', 'America', -4.0, NULL),
|
||||
('America/Indianapolis', 'America/Indianapolis', 'IANA timezone: America/Indianapolis', 'America', -4.0, NULL),
|
||||
('America/Indiana/Tell_City', 'America/Indiana/Tell City', 'IANA timezone: America/Indiana/Tell_City', 'America', -5.0, NULL),
|
||||
('America/Indiana/Vevay', 'America/Indiana/Vevay', 'IANA timezone: America/Indiana/Vevay', 'America', -4.0, NULL),
|
||||
('America/Indiana/Vincennes', 'America/Indiana/Vincennes', 'IANA timezone: America/Indiana/Vincennes', 'America', -4.0, NULL),
|
||||
('America/Indiana/Winamac', 'America/Indiana/Winamac', 'IANA timezone: America/Indiana/Winamac', 'America', -4.0, NULL),
|
||||
('America/Inuvik', 'America/Inuvik', 'IANA timezone: America/Inuvik', 'America', -6.0, NULL),
|
||||
('America/Iqaluit', 'America/Iqaluit', 'IANA timezone: America/Iqaluit', 'America', -4.0, NULL),
|
||||
('America/Jamaica', 'America/Jamaica', 'IANA timezone: America/Jamaica', 'America', -5.0, NULL),
|
||||
('America/Jujuy', 'America/Jujuy', 'IANA timezone: America/Jujuy', 'America', -3.0, NULL),
|
||||
('America/Juneau', 'America/Juneau', 'IANA timezone: America/Juneau', 'America', -8.0, NULL),
|
||||
('America/Kentucky/Louisville', 'America/Kentucky/Louisville', 'IANA timezone: America/Kentucky/Louisville', 'America', -4.0, NULL),
|
||||
('America/Kentucky/Monticello', 'America/Kentucky/Monticello', 'IANA timezone: America/Kentucky/Monticello', 'America', -4.0, NULL),
|
||||
('America/Knox_IN', 'America/Knox IN', 'IANA timezone: America/Knox_IN', 'America', -5.0, NULL),
|
||||
('America/Kralendijk', 'America/Kralendijk', 'IANA timezone: America/Kralendijk', 'America', -4.0, NULL),
|
||||
('America/La_Paz', 'America/La Paz', 'IANA timezone: America/La_Paz', 'America', -4.0, NULL),
|
||||
('America/Lima', 'America/Lima', 'IANA timezone: America/Lima', 'America', -5.0, NULL),
|
||||
('America/Los_Angeles', 'America/Los Angeles', 'IANA timezone: America/Los_Angeles', 'America', -7.0, NULL),
|
||||
('America/Louisville', 'America/Louisville', 'IANA timezone: America/Louisville', 'America', -4.0, NULL),
|
||||
('America/Lower_Princes', 'America/Lower Princes', 'IANA timezone: America/Lower_Princes', 'America', -4.0, NULL),
|
||||
('America/Maceio', 'America/Maceio', 'IANA timezone: America/Maceio', 'America', -3.0, NULL),
|
||||
('America/Managua', 'America/Managua', 'IANA timezone: America/Managua', 'America', -6.0, NULL),
|
||||
('America/Manaus', 'America/Manaus', 'IANA timezone: America/Manaus', 'America', -4.0, NULL),
|
||||
('America/Marigot', 'America/Marigot', 'IANA timezone: America/Marigot', 'America', -4.0, NULL),
|
||||
('America/Martinique', 'America/Martinique', 'IANA timezone: America/Martinique', 'America', -4.0, NULL),
|
||||
('America/Matamoros', 'America/Matamoros', 'IANA timezone: America/Matamoros', 'America', -5.0, NULL),
|
||||
('America/Mazatlan', 'America/Mazatlan', 'IANA timezone: America/Mazatlan', 'America', -7.0, NULL),
|
||||
('America/Mendoza', 'America/Mendoza', 'IANA timezone: America/Mendoza', 'America', -3.0, NULL),
|
||||
('America/Menominee', 'America/Menominee', 'IANA timezone: America/Menominee', 'America', -5.0, NULL),
|
||||
('America/Merida', 'America/Merida', 'IANA timezone: America/Merida', 'America', -6.0, NULL),
|
||||
('America/Metlakatla', 'America/Metlakatla', 'IANA timezone: America/Metlakatla', 'America', -8.0, NULL),
|
||||
('America/Mexico_City', 'America/Mexico City', 'IANA timezone: America/Mexico_City', 'America', -6.0, NULL),
|
||||
('America/Miquelon', 'America/Miquelon', 'IANA timezone: America/Miquelon', 'America', -2.0, NULL),
|
||||
('America/Moncton', 'America/Moncton', 'IANA timezone: America/Moncton', 'America', -3.0, NULL),
|
||||
('America/Monterrey', 'America/Monterrey', 'IANA timezone: America/Monterrey', 'America', -6.0, NULL),
|
||||
('America/Montevideo', 'America/Montevideo', 'IANA timezone: America/Montevideo', 'America', -3.0, NULL),
|
||||
('America/Montreal', 'America/Montreal', 'IANA timezone: America/Montreal', 'America', -4.0, NULL),
|
||||
('America/Montserrat', 'America/Montserrat', 'IANA timezone: America/Montserrat', 'America', -4.0, NULL),
|
||||
('America/Nassau', 'America/Nassau', 'IANA timezone: America/Nassau', 'America', -4.0, NULL),
|
||||
('America/New_York', 'America/New York', 'IANA timezone: America/New_York', 'America', -4.0, NULL),
|
||||
('America/Nipigon', 'America/Nipigon', 'IANA timezone: America/Nipigon', 'America', -4.0, NULL),
|
||||
('America/Nome', 'America/Nome', 'IANA timezone: America/Nome', 'America', -8.0, NULL),
|
||||
('America/Noronha', 'America/Noronha', 'IANA timezone: America/Noronha', 'America', -2.0, NULL),
|
||||
('America/North_Dakota/Beulah', 'America/North Dakota/Beulah', 'IANA timezone: America/North_Dakota/Beulah', 'America', -5.0, NULL),
|
||||
('America/North_Dakota/Center', 'America/North Dakota/Center', 'IANA timezone: America/North_Dakota/Center', 'America', -5.0, NULL),
|
||||
('America/North_Dakota/New_Salem', 'America/North Dakota/New Salem', 'IANA timezone: America/North_Dakota/New_Salem', 'America', -5.0, NULL),
|
||||
('America/Nuuk', 'America/Nuuk', 'IANA timezone: America/Nuuk', 'America', -1.0, NULL),
|
||||
('America/Ojinaga', 'America/Ojinaga', 'IANA timezone: America/Ojinaga', 'America', -5.0, NULL),
|
||||
('America/Panama', 'America/Panama', 'IANA timezone: America/Panama', 'America', -5.0, NULL),
|
||||
('America/Pangnirtung', 'America/Pangnirtung', 'IANA timezone: America/Pangnirtung', 'America', -4.0, NULL),
|
||||
('America/Paramaribo', 'America/Paramaribo', 'IANA timezone: America/Paramaribo', 'America', -3.0, NULL),
|
||||
('America/Phoenix', 'America/Phoenix', 'IANA timezone: America/Phoenix', 'America', -7.0, NULL),
|
||||
('America/Port-au-Prince', 'America/Port-au-Prince', 'IANA timezone: America/Port-au-Prince', 'America', -4.0, NULL),
|
||||
('America/Porto_Acre', 'America/Porto Acre', 'IANA timezone: America/Porto_Acre', 'America', -5.0, NULL),
|
||||
('America/Port_of_Spain', 'America/Port of Spain', 'IANA timezone: America/Port_of_Spain', 'America', -4.0, NULL),
|
||||
('America/Porto_Velho', 'America/Porto Velho', 'IANA timezone: America/Porto_Velho', 'America', -4.0, NULL),
|
||||
('America/Puerto_Rico', 'America/Puerto Rico', 'IANA timezone: America/Puerto_Rico', 'America', -4.0, NULL),
|
||||
('America/Punta_Arenas', 'America/Punta Arenas', 'IANA timezone: America/Punta_Arenas', 'America', -3.0, NULL),
|
||||
('America/Rainy_River', 'America/Rainy River', 'IANA timezone: America/Rainy_River', 'America', -5.0, NULL),
|
||||
('America/Rankin_Inlet', 'America/Rankin Inlet', 'IANA timezone: America/Rankin_Inlet', 'America', -5.0, NULL),
|
||||
('America/Recife', 'America/Recife', 'IANA timezone: America/Recife', 'America', -3.0, NULL),
|
||||
('America/Regina', 'America/Regina', 'IANA timezone: America/Regina', 'America', -6.0, NULL),
|
||||
('America/Resolute', 'America/Resolute', 'IANA timezone: America/Resolute', 'America', -5.0, NULL),
|
||||
('America/Rio_Branco', 'America/Rio Branco', 'IANA timezone: America/Rio_Branco', 'America', -5.0, NULL),
|
||||
('America/Rosario', 'America/Rosario', 'IANA timezone: America/Rosario', 'America', -3.0, NULL),
|
||||
('America/Santa_Isabel', 'America/Santa Isabel', 'IANA timezone: America/Santa_Isabel', 'America', -7.0, NULL),
|
||||
('America/Santarem', 'America/Santarem', 'IANA timezone: America/Santarem', 'America', -3.0, NULL),
|
||||
('America/Santiago', 'America/Santiago', 'IANA timezone: America/Santiago', 'America', -3.0, NULL),
|
||||
('America/Santo_Domingo', 'America/Santo Domingo', 'IANA timezone: America/Santo_Domingo', 'America', -4.0, NULL),
|
||||
('America/Sao_Paulo', 'America/Sao Paulo', 'IANA timezone: America/Sao_Paulo', 'America', -3.0, NULL),
|
||||
('America/Scoresbysund', 'America/Scoresbysund', 'IANA timezone: America/Scoresbysund', 'America', -1.0, NULL),
|
||||
('America/Shiprock', 'America/Shiprock', 'IANA timezone: America/Shiprock', 'America', -6.0, NULL),
|
||||
('America/Sitka', 'America/Sitka', 'IANA timezone: America/Sitka', 'America', -8.0, NULL),
|
||||
('America/St_Barthelemy', 'America/St Barthelemy', 'IANA timezone: America/St_Barthelemy', 'America', -4.0, NULL),
|
||||
('America/St_Johns', 'America/St Johns', 'IANA timezone: America/St_Johns', 'America', -2.5, NULL),
|
||||
('America/St_Kitts', 'America/St Kitts', 'IANA timezone: America/St_Kitts', 'America', -4.0, NULL),
|
||||
('America/St_Lucia', 'America/St Lucia', 'IANA timezone: America/St_Lucia', 'America', -4.0, NULL),
|
||||
('America/St_Thomas', 'America/St Thomas', 'IANA timezone: America/St_Thomas', 'America', -4.0, NULL),
|
||||
('America/St_Vincent', 'America/St Vincent', 'IANA timezone: America/St_Vincent', 'America', -4.0, NULL),
|
||||
('America/Swift_Current', 'America/Swift Current', 'IANA timezone: America/Swift_Current', 'America', -6.0, NULL),
|
||||
('America/Tegucigalpa', 'America/Tegucigalpa', 'IANA timezone: America/Tegucigalpa', 'America', -6.0, NULL),
|
||||
('America/Thule', 'America/Thule', 'IANA timezone: America/Thule', 'America', -3.0, NULL),
|
||||
('America/Thunder_Bay', 'America/Thunder Bay', 'IANA timezone: America/Thunder_Bay', 'America', -4.0, NULL),
|
||||
('America/Tijuana', 'America/Tijuana', 'IANA timezone: America/Tijuana', 'America', -7.0, NULL),
|
||||
('America/Toronto', 'America/Toronto', 'IANA timezone: America/Toronto', 'America', -4.0, NULL),
|
||||
('America/Tortola', 'America/Tortola', 'IANA timezone: America/Tortola', 'America', -4.0, NULL),
|
||||
('America/Vancouver', 'America/Vancouver', 'IANA timezone: America/Vancouver', 'America', -7.0, NULL),
|
||||
('America/Virgin', 'America/Virgin', 'IANA timezone: America/Virgin', 'America', -4.0, NULL),
|
||||
('America/Whitehorse', 'America/Whitehorse', 'IANA timezone: America/Whitehorse', 'America', -7.0, NULL),
|
||||
('America/Winnipeg', 'America/Winnipeg', 'IANA timezone: America/Winnipeg', 'America', -5.0, NULL),
|
||||
('America/Yakutat', 'America/Yakutat', 'IANA timezone: America/Yakutat', 'America', -8.0, NULL),
|
||||
('America/Yellowknife', 'America/Yellowknife', 'IANA timezone: America/Yellowknife', 'America', -6.0, NULL),
|
||||
('Antarctica/Casey', 'Antarctica/Casey', 'IANA timezone: Antarctica/Casey', 'Antarctica', 8.0, NULL),
|
||||
('Antarctica/Davis', 'Antarctica/Davis', 'IANA timezone: Antarctica/Davis', 'Antarctica', 7.0, NULL),
|
||||
('Antarctica/DumontDUrville', 'Antarctica/DumontDUrville', 'IANA timezone: Antarctica/DumontDUrville', 'Antarctica', 10.0, NULL),
|
||||
('Antarctica/Macquarie', 'Antarctica/Macquarie', 'IANA timezone: Antarctica/Macquarie', 'Antarctica', 11.0, NULL),
|
||||
('Antarctica/Mawson', 'Antarctica/Mawson', 'IANA timezone: Antarctica/Mawson', 'Antarctica', 5.0, NULL),
|
||||
('Antarctica/McMurdo', 'Antarctica/McMurdo', 'IANA timezone: Antarctica/McMurdo', 'Antarctica', 13.0, NULL),
|
||||
('Antarctica/Palmer', 'Antarctica/Palmer', 'IANA timezone: Antarctica/Palmer', 'Antarctica', -3.0, NULL),
|
||||
('Antarctica/Rothera', 'Antarctica/Rothera', 'IANA timezone: Antarctica/Rothera', 'Antarctica', -3.0, NULL),
|
||||
('Antarctica/South_Pole', 'Antarctica/South Pole', 'IANA timezone: Antarctica/South_Pole', 'Antarctica', 13.0, NULL),
|
||||
('Antarctica/Syowa', 'Antarctica/Syowa', 'IANA timezone: Antarctica/Syowa', 'Antarctica', 3.0, NULL),
|
||||
('Antarctica/Troll', 'Antarctica/Troll', 'IANA timezone: Antarctica/Troll', 'Antarctica', 2.0, NULL),
|
||||
('Antarctica/Vostok', 'Antarctica/Vostok', 'IANA timezone: Antarctica/Vostok', 'Antarctica', 5.0, NULL),
|
||||
('Arctic/Longyearbyen', 'Arctic/Longyearbyen', 'IANA timezone: Arctic/Longyearbyen', 'Arctic', 2.0, NULL),
|
||||
('Asia/Aden', 'Asia/Aden', 'IANA timezone: Asia/Aden', 'Asia', 3.0, NULL),
|
||||
('Asia/Almaty', 'Asia/Almaty', 'IANA timezone: Asia/Almaty', 'Asia', 5.0, NULL),
|
||||
('Asia/Amman', 'Asia/Amman', 'IANA timezone: Asia/Amman', 'Asia', 3.0, NULL),
|
||||
('Asia/Anadyr', 'Asia/Anadyr', 'IANA timezone: Asia/Anadyr', 'Asia', 12.0, NULL),
|
||||
('Asia/Aqtau', 'Asia/Aqtau', 'IANA timezone: Asia/Aqtau', 'Asia', 5.0, NULL),
|
||||
('Asia/Aqtobe', 'Asia/Aqtobe', 'IANA timezone: Asia/Aqtobe', 'Asia', 5.0, NULL),
|
||||
('Asia/Ashgabat', 'Asia/Ashgabat', 'IANA timezone: Asia/Ashgabat', 'Asia', 5.0, NULL),
|
||||
('Asia/Ashkhabad', 'Asia/Ashkhabad', 'IANA timezone: Asia/Ashkhabad', 'Asia', 5.0, NULL),
|
||||
('Asia/Atyrau', 'Asia/Atyrau', 'IANA timezone: Asia/Atyrau', 'Asia', 5.0, NULL),
|
||||
('Asia/Baghdad', 'Asia/Baghdad', 'IANA timezone: Asia/Baghdad', 'Asia', 3.0, NULL),
|
||||
('Asia/Bahrain', 'Asia/Bahrain', 'IANA timezone: Asia/Bahrain', 'Asia', 3.0, NULL),
|
||||
('Asia/Baku', 'Asia/Baku', 'IANA timezone: Asia/Baku', 'Asia', 4.0, NULL),
|
||||
('Asia/Bangkok', 'Asia/Bangkok', 'IANA timezone: Asia/Bangkok', 'Asia', 7.0, NULL),
|
||||
('Asia/Barnaul', 'Asia/Barnaul', 'IANA timezone: Asia/Barnaul', 'Asia', 7.0, NULL),
|
||||
('Asia/Beirut', 'Asia/Beirut', 'IANA timezone: Asia/Beirut', 'Asia', 3.0, NULL),
|
||||
('Asia/Bishkek', 'Asia/Bishkek', 'IANA timezone: Asia/Bishkek', 'Asia', 6.0, NULL),
|
||||
('Asia/Brunei', 'Asia/Brunei', 'IANA timezone: Asia/Brunei', 'Asia', 8.0, NULL),
|
||||
('Asia/Calcutta', 'Asia/Calcutta', 'IANA timezone: Asia/Calcutta', 'Asia', 5.5, NULL),
|
||||
('Asia/Chita', 'Asia/Chita', 'IANA timezone: Asia/Chita', 'Asia', 9.0, NULL),
|
||||
('Asia/Choibalsan', 'Asia/Choibalsan', 'IANA timezone: Asia/Choibalsan', 'Asia', 8.0, NULL),
|
||||
('Asia/Chongqing', 'Asia/Chongqing', 'IANA timezone: Asia/Chongqing', 'Asia', 8.0, NULL),
|
||||
('Asia/Chungking', 'Asia/Chungking', 'IANA timezone: Asia/Chungking', 'Asia', 8.0, NULL),
|
||||
('Asia/Colombo', 'Asia/Colombo', 'IANA timezone: Asia/Colombo', 'Asia', 5.5, NULL),
|
||||
('Asia/Dacca', 'Asia/Dacca', 'IANA timezone: Asia/Dacca', 'Asia', 6.0, NULL),
|
||||
('Asia/Damascus', 'Asia/Damascus', 'IANA timezone: Asia/Damascus', 'Asia', 3.0, NULL),
|
||||
('Asia/Dhaka', 'Asia/Dhaka', 'IANA timezone: Asia/Dhaka', 'Asia', 6.0, NULL),
|
||||
('Asia/Dili', 'Asia/Dili', 'IANA timezone: Asia/Dili', 'Asia', 9.0, NULL),
|
||||
('Asia/Dubai', 'Asia/Dubai', 'IANA timezone: Asia/Dubai', 'Asia', 4.0, NULL),
|
||||
('Asia/Dushanbe', 'Asia/Dushanbe', 'IANA timezone: Asia/Dushanbe', 'Asia', 5.0, NULL),
|
||||
('Asia/Famagusta', 'Asia/Famagusta', 'IANA timezone: Asia/Famagusta', 'Asia', 3.0, NULL),
|
||||
('Asia/Gaza', 'Asia/Gaza', 'IANA timezone: Asia/Gaza', 'Asia', 3.0, NULL),
|
||||
('Asia/Harbin', 'Asia/Harbin', 'IANA timezone: Asia/Harbin', 'Asia', 8.0, NULL),
|
||||
('Asia/Hebron', 'Asia/Hebron', 'IANA timezone: Asia/Hebron', 'Asia', 3.0, NULL),
|
||||
('Asia/Ho_Chi_Minh', 'Asia/Ho Chi Minh', 'IANA timezone: Asia/Ho_Chi_Minh', 'Asia', 7.0, NULL),
|
||||
('Asia/Hong_Kong', 'Asia/Hong Kong', 'IANA timezone: Asia/Hong_Kong', 'Asia', 8.0, NULL),
|
||||
('Asia/Hovd', 'Asia/Hovd', 'IANA timezone: Asia/Hovd', 'Asia', 7.0, NULL),
|
||||
('Asia/Irkutsk', 'Asia/Irkutsk', 'IANA timezone: Asia/Irkutsk', 'Asia', 8.0, NULL),
|
||||
('Asia/Istanbul', 'Asia/Istanbul', 'IANA timezone: Asia/Istanbul', 'Asia', 3.0, NULL),
|
||||
('Asia/Jakarta', 'Asia/Jakarta', 'IANA timezone: Asia/Jakarta', 'Asia', 7.0, NULL),
|
||||
('Asia/Jayapura', 'Asia/Jayapura', 'IANA timezone: Asia/Jayapura', 'Asia', 9.0, NULL),
|
||||
('Asia/Jerusalem', 'Asia/Jerusalem', 'IANA timezone: Asia/Jerusalem', 'Asia', 3.0, NULL),
|
||||
('Asia/Kabul', 'Asia/Kabul', 'IANA timezone: Asia/Kabul', 'Asia', 4.5, NULL),
|
||||
('Asia/Kamchatka', 'Asia/Kamchatka', 'IANA timezone: Asia/Kamchatka', 'Asia', 12.0, NULL),
|
||||
('Asia/Karachi', 'Asia/Karachi', 'IANA timezone: Asia/Karachi', 'Asia', 5.0, NULL),
|
||||
('Asia/Kashgar', 'Asia/Kashgar', 'IANA timezone: Asia/Kashgar', 'Asia', 6.0, NULL),
|
||||
('Asia/Kathmandu', 'Asia/Kathmandu', 'IANA timezone: Asia/Kathmandu', 'Asia', 5.75, NULL),
|
||||
('Asia/Katmandu', 'Asia/Katmandu', 'IANA timezone: Asia/Katmandu', 'Asia', 5.75, NULL),
|
||||
('Asia/Khandyga', 'Asia/Khandyga', 'IANA timezone: Asia/Khandyga', 'Asia', 9.0, NULL),
|
||||
('Asia/Kolkata', 'Asia/Kolkata', 'IANA timezone: Asia/Kolkata', 'Asia', 5.5, NULL),
|
||||
('Asia/Krasnoyarsk', 'Asia/Krasnoyarsk', 'IANA timezone: Asia/Krasnoyarsk', 'Asia', 7.0, NULL),
|
||||
('Asia/Kuala_Lumpur', 'Asia/Kuala Lumpur', 'IANA timezone: Asia/Kuala_Lumpur', 'Asia', 8.0, NULL),
|
||||
('Asia/Kuching', 'Asia/Kuching', 'IANA timezone: Asia/Kuching', 'Asia', 8.0, NULL),
|
||||
('Asia/Kuwait', 'Asia/Kuwait', 'IANA timezone: Asia/Kuwait', 'Asia', 3.0, NULL),
|
||||
('Asia/Macao', 'Asia/Macao', 'IANA timezone: Asia/Macao', 'Asia', 8.0, NULL),
|
||||
('Asia/Macau', 'Asia/Macau', 'IANA timezone: Asia/Macau', 'Asia', 8.0, NULL),
|
||||
('Asia/Magadan', 'Asia/Magadan', 'IANA timezone: Asia/Magadan', 'Asia', 11.0, NULL),
|
||||
('Asia/Makassar', 'Asia/Makassar', 'IANA timezone: Asia/Makassar', 'Asia', 8.0, NULL),
|
||||
('Asia/Manila', 'Asia/Manila', 'IANA timezone: Asia/Manila', 'Asia', 8.0, NULL),
|
||||
('Asia/Muscat', 'Asia/Muscat', 'IANA timezone: Asia/Muscat', 'Asia', 4.0, NULL),
|
||||
('Asia/Nicosia', 'Asia/Nicosia', 'IANA timezone: Asia/Nicosia', 'Asia', 3.0, NULL),
|
||||
('Asia/Novokuznetsk', 'Asia/Novokuznetsk', 'IANA timezone: Asia/Novokuznetsk', 'Asia', 7.0, NULL),
|
||||
('Asia/Novosibirsk', 'Asia/Novosibirsk', 'IANA timezone: Asia/Novosibirsk', 'Asia', 7.0, NULL),
|
||||
('Asia/Omsk', 'Asia/Omsk', 'IANA timezone: Asia/Omsk', 'Asia', 6.0, NULL),
|
||||
('Asia/Oral', 'Asia/Oral', 'IANA timezone: Asia/Oral', 'Asia', 5.0, NULL),
|
||||
('Asia/Phnom_Penh', 'Asia/Phnom Penh', 'IANA timezone: Asia/Phnom_Penh', 'Asia', 7.0, NULL),
|
||||
('Asia/Pontianak', 'Asia/Pontianak', 'IANA timezone: Asia/Pontianak', 'Asia', 7.0, NULL),
|
||||
('Asia/Pyongyang', 'Asia/Pyongyang', 'IANA timezone: Asia/Pyongyang', 'Asia', 9.0, NULL),
|
||||
('Asia/Qatar', 'Asia/Qatar', 'IANA timezone: Asia/Qatar', 'Asia', 3.0, NULL),
|
||||
('Asia/Qostanay', 'Asia/Qostanay', 'IANA timezone: Asia/Qostanay', 'Asia', 5.0, NULL),
|
||||
('Asia/Qyzylorda', 'Asia/Qyzylorda', 'IANA timezone: Asia/Qyzylorda', 'Asia', 5.0, NULL),
|
||||
('Asia/Rangoon', 'Asia/Rangoon', 'IANA timezone: Asia/Rangoon', 'Asia', 6.5, NULL),
|
||||
('Asia/Riyadh', 'Asia/Riyadh', 'IANA timezone: Asia/Riyadh', 'Asia', 3.0, NULL),
|
||||
('Asia/Saigon', 'Asia/Saigon', 'IANA timezone: Asia/Saigon', 'Asia', 7.0, NULL),
|
||||
('Asia/Sakhalin', 'Asia/Sakhalin', 'IANA timezone: Asia/Sakhalin', 'Asia', 11.0, NULL),
|
||||
('Asia/Samarkand', 'Asia/Samarkand', 'IANA timezone: Asia/Samarkand', 'Asia', 5.0, NULL),
|
||||
('Asia/Seoul', 'Asia/Seoul', 'IANA timezone: Asia/Seoul', 'Asia', 9.0, NULL),
|
||||
('Asia/Shanghai', 'Asia/Shanghai', 'IANA timezone: Asia/Shanghai', 'Asia', 8.0, NULL),
|
||||
('Asia/Singapore', 'Asia/Singapore', 'IANA timezone: Asia/Singapore', 'Asia', 8.0, NULL),
|
||||
('Asia/Srednekolymsk', 'Asia/Srednekolymsk', 'IANA timezone: Asia/Srednekolymsk', 'Asia', 11.0, NULL),
|
||||
('Asia/Taipei', 'Asia/Taipei', 'IANA timezone: Asia/Taipei', 'Asia', 8.0, NULL),
|
||||
('Asia/Tashkent', 'Asia/Tashkent', 'IANA timezone: Asia/Tashkent', 'Asia', 5.0, NULL),
|
||||
('Asia/Tbilisi', 'Asia/Tbilisi', 'IANA timezone: Asia/Tbilisi', 'Asia', 4.0, NULL),
|
||||
('Asia/Tehran', 'Asia/Tehran', 'IANA timezone: Asia/Tehran', 'Asia', 3.5, NULL),
|
||||
('Asia/Tel_Aviv', 'Asia/Tel Aviv', 'IANA timezone: Asia/Tel_Aviv', 'Asia', 3.0, NULL),
|
||||
('Asia/Thimbu', 'Asia/Thimbu', 'IANA timezone: Asia/Thimbu', 'Asia', 6.0, NULL),
|
||||
('Asia/Thimphu', 'Asia/Thimphu', 'IANA timezone: Asia/Thimphu', 'Asia', 6.0, NULL),
|
||||
('Asia/Tokyo', 'Asia/Tokyo', 'IANA timezone: Asia/Tokyo', 'Asia', 9.0, NULL),
|
||||
('Asia/Tomsk', 'Asia/Tomsk', 'IANA timezone: Asia/Tomsk', 'Asia', 7.0, NULL),
|
||||
('Asia/Ujung_Pandang', 'Asia/Ujung Pandang', 'IANA timezone: Asia/Ujung_Pandang', 'Asia', 8.0, NULL),
|
||||
('Asia/Ulaanbaatar', 'Asia/Ulaanbaatar', 'IANA timezone: Asia/Ulaanbaatar', 'Asia', 8.0, NULL),
|
||||
('Asia/Ulan_Bator', 'Asia/Ulan Bator', 'IANA timezone: Asia/Ulan_Bator', 'Asia', 8.0, NULL),
|
||||
('Asia/Urumqi', 'Asia/Urumqi', 'IANA timezone: Asia/Urumqi', 'Asia', 6.0, NULL),
|
||||
('Asia/Ust-Nera', 'Asia/Ust-Nera', 'IANA timezone: Asia/Ust-Nera', 'Asia', 10.0, NULL),
|
||||
('Asia/Vientiane', 'Asia/Vientiane', 'IANA timezone: Asia/Vientiane', 'Asia', 7.0, NULL),
|
||||
('Asia/Vladivostok', 'Asia/Vladivostok', 'IANA timezone: Asia/Vladivostok', 'Asia', 10.0, NULL),
|
||||
('Asia/Yakutsk', 'Asia/Yakutsk', 'IANA timezone: Asia/Yakutsk', 'Asia', 9.0, NULL),
|
||||
('Asia/Yangon', 'Asia/Yangon', 'IANA timezone: Asia/Yangon', 'Asia', 6.5, NULL),
|
||||
('Asia/Yekaterinburg', 'Asia/Yekaterinburg', 'IANA timezone: Asia/Yekaterinburg', 'Asia', 5.0, NULL),
|
||||
('Asia/Yerevan', 'Asia/Yerevan', 'IANA timezone: Asia/Yerevan', 'Asia', 4.0, NULL),
|
||||
('Atlantic/Azores', 'Atlantic/Azores', 'IANA timezone: Atlantic/Azores', 'Atlantic', 0.0, NULL),
|
||||
('Atlantic/Bermuda', 'Atlantic/Bermuda', 'IANA timezone: Atlantic/Bermuda', 'Atlantic', -3.0, NULL),
|
||||
('Atlantic/Canary', 'Atlantic/Canary', 'IANA timezone: Atlantic/Canary', 'Atlantic', 1.0, NULL),
|
||||
('Atlantic/Cape_Verde', 'Atlantic/Cape Verde', 'IANA timezone: Atlantic/Cape_Verde', 'Atlantic', -1.0, NULL),
|
||||
('Atlantic/Faeroe', 'Atlantic/Faeroe', 'IANA timezone: Atlantic/Faeroe', 'Atlantic', 1.0, NULL),
|
||||
('Atlantic/Faroe', 'Atlantic/Faroe', 'IANA timezone: Atlantic/Faroe', 'Atlantic', 1.0, NULL),
|
||||
('Atlantic/Jan_Mayen', 'Atlantic/Jan Mayen', 'IANA timezone: Atlantic/Jan_Mayen', 'Atlantic', 2.0, NULL),
|
||||
('Atlantic/Madeira', 'Atlantic/Madeira', 'IANA timezone: Atlantic/Madeira', 'Atlantic', 1.0, NULL),
|
||||
('Atlantic/Reykjavik', 'Atlantic/Reykjavik', 'IANA timezone: Atlantic/Reykjavik', 'Atlantic', 0.0, NULL),
|
||||
('Atlantic/South_Georgia', 'Atlantic/South Georgia', 'IANA timezone: Atlantic/South_Georgia', 'Atlantic', -2.0, NULL),
|
||||
('Atlantic/Stanley', 'Atlantic/Stanley', 'IANA timezone: Atlantic/Stanley', 'Atlantic', -3.0, NULL),
|
||||
('Atlantic/St_Helena', 'Atlantic/St Helena', 'IANA timezone: Atlantic/St_Helena', 'Atlantic', 0.0, NULL),
|
||||
('Australia/ACT', 'Australia/ACT', 'IANA timezone: Australia/ACT', 'Australia', 11.0, NULL),
|
||||
('Australia/Adelaide', 'Australia/Adelaide', 'IANA timezone: Australia/Adelaide', 'Australia', 10.5, NULL),
|
||||
('Australia/Brisbane', 'Australia/Brisbane', 'IANA timezone: Australia/Brisbane', 'Australia', 10.0, NULL),
|
||||
('Australia/Broken_Hill', 'Australia/Broken Hill', 'IANA timezone: Australia/Broken_Hill', 'Australia', 10.5, NULL),
|
||||
('Australia/Canberra', 'Australia/Canberra', 'IANA timezone: Australia/Canberra', 'Australia', 11.0, NULL),
|
||||
('Australia/Currie', 'Australia/Currie', 'IANA timezone: Australia/Currie', 'Australia', 11.0, NULL),
|
||||
('Australia/Darwin', 'Australia/Darwin', 'IANA timezone: Australia/Darwin', 'Australia', 9.5, NULL),
|
||||
('Australia/Eucla', 'Australia/Eucla', 'IANA timezone: Australia/Eucla', 'Australia', 8.75, NULL),
|
||||
('Australia/Hobart', 'Australia/Hobart', 'IANA timezone: Australia/Hobart', 'Australia', 11.0, NULL),
|
||||
('Australia/LHI', 'Australia/LHI', 'IANA timezone: Australia/LHI', 'Australia', 11.0, NULL),
|
||||
('Australia/Lindeman', 'Australia/Lindeman', 'IANA timezone: Australia/Lindeman', 'Australia', 10.0, NULL),
|
||||
('Australia/Lord_Howe', 'Australia/Lord Howe', 'IANA timezone: Australia/Lord_Howe', 'Australia', 11.0, NULL),
|
||||
('Australia/Melbourne', 'Australia/Melbourne', 'IANA timezone: Australia/Melbourne', 'Australia', 11.0, NULL),
|
||||
('Australia/North', 'Australia/North', 'IANA timezone: Australia/North', 'Australia', 9.5, NULL),
|
||||
('Australia/NSW', 'Australia/NSW', 'IANA timezone: Australia/NSW', 'Australia', 11.0, NULL),
|
||||
('Australia/Perth', 'Australia/Perth', 'IANA timezone: Australia/Perth', 'Australia', 8.0, NULL),
|
||||
('Australia/Queensland', 'Australia/Queensland', 'IANA timezone: Australia/Queensland', 'Australia', 10.0, NULL),
|
||||
('Australia/South', 'Australia/South', 'IANA timezone: Australia/South', 'Australia', 10.5, NULL),
|
||||
('Australia/Sydney', 'Australia/Sydney', 'IANA timezone: Australia/Sydney', 'Australia', 11.0, NULL),
|
||||
('Australia/Tasmania', 'Australia/Tasmania', 'IANA timezone: Australia/Tasmania', 'Australia', 11.0, NULL),
|
||||
('Australia/Victoria', 'Australia/Victoria', 'IANA timezone: Australia/Victoria', 'Australia', 11.0, NULL),
|
||||
('Australia/West', 'Australia/West', 'IANA timezone: Australia/West', 'Australia', 8.0, NULL),
|
||||
('Australia/Yancowinna', 'Australia/Yancowinna', 'IANA timezone: Australia/Yancowinna', 'Australia', 10.5, NULL),
|
||||
('Brazil/Acre', 'Brazil/Acre', 'IANA timezone: Brazil/Acre', 'Brazil', -5.0, NULL),
|
||||
('Brazil/DeNoronha', 'Brazil/DeNoronha', 'IANA timezone: Brazil/DeNoronha', 'Brazil', -2.0, NULL),
|
||||
('Brazil/East', 'Brazil/East', 'IANA timezone: Brazil/East', 'Brazil', -3.0, NULL),
|
||||
('Brazil/West', 'Brazil/West', 'IANA timezone: Brazil/West', 'Brazil', -4.0, NULL),
|
||||
('Canada/Atlantic', 'Canada/Atlantic', 'IANA timezone: Canada/Atlantic', 'Canada', -3.0, NULL),
|
||||
('Canada/Central', 'Canada/Central', 'IANA timezone: Canada/Central', 'Canada', -5.0, NULL),
|
||||
('Canada/Eastern', 'Canada/Eastern', 'IANA timezone: Canada/Eastern', 'Canada', -4.0, NULL),
|
||||
('Canada/Mountain', 'Canada/Mountain', 'IANA timezone: Canada/Mountain', 'Canada', -6.0, NULL),
|
||||
('Canada/Newfoundland', 'Canada/Newfoundland', 'IANA timezone: Canada/Newfoundland', 'Canada', -2.5, NULL),
|
||||
('Canada/Pacific', 'Canada/Pacific', 'IANA timezone: Canada/Pacific', 'Canada', -7.0, NULL),
|
||||
('Canada/Saskatchewan', 'Canada/Saskatchewan', 'IANA timezone: Canada/Saskatchewan', 'Canada', -6.0, NULL),
|
||||
('Canada/Yukon', 'Canada/Yukon', 'IANA timezone: Canada/Yukon', 'Canada', -7.0, NULL),
|
||||
('CET', 'CET', 'IANA timezone: CET', 'Other', 2.0, NULL),
|
||||
('Chile/Continental', 'Chile/Continental', 'IANA timezone: Chile/Continental', 'Chile', -3.0, NULL),
|
||||
('Chile/EasterIsland', 'Chile/EasterIsland', 'IANA timezone: Chile/EasterIsland', 'Chile', -5.0, NULL),
|
||||
('CST6CDT', 'CST6CDT', 'IANA timezone: CST6CDT', 'Other', -5.0, NULL),
|
||||
('Cuba', 'Cuba', 'IANA timezone: Cuba', 'Other', -4.0, NULL),
|
||||
('EET', 'EET', 'IANA timezone: EET', 'Other', 3.0, NULL),
|
||||
('Egypt', 'Egypt', 'IANA timezone: Egypt', 'Other', 3.0, NULL),
|
||||
('Eire', 'Eire', 'IANA timezone: Eire', 'Other', 1.0, NULL),
|
||||
('EST', 'EST', 'IANA timezone: EST', 'Other', -5.0, NULL),
|
||||
('EST5EDT', 'EST5EDT', 'IANA timezone: EST5EDT', 'Other', -4.0, NULL),
|
||||
('Europe/Amsterdam', 'Europe/Amsterdam', 'IANA timezone: Europe/Amsterdam', 'Europe', 2.0, NULL),
|
||||
('Europe/Andorra', 'Europe/Andorra', 'IANA timezone: Europe/Andorra', 'Europe', 2.0, NULL),
|
||||
('Europe/Astrakhan', 'Europe/Astrakhan', 'IANA timezone: Europe/Astrakhan', 'Europe', 4.0, NULL),
|
||||
('Europe/Athens', 'Europe/Athens', 'IANA timezone: Europe/Athens', 'Europe', 3.0, NULL),
|
||||
('Europe/Belfast', 'Europe/Belfast', 'IANA timezone: Europe/Belfast', 'Europe', 1.0, NULL),
|
||||
('Europe/Belgrade', 'Europe/Belgrade', 'IANA timezone: Europe/Belgrade', 'Europe', 2.0, NULL),
|
||||
('Europe/Berlin', 'Europe/Berlin', 'IANA timezone: Europe/Berlin', 'Europe', 2.0, NULL),
|
||||
('Europe/Bratislava', 'Europe/Bratislava', 'IANA timezone: Europe/Bratislava', 'Europe', 2.0, NULL),
|
||||
('Europe/Brussels', 'Europe/Brussels', 'IANA timezone: Europe/Brussels', 'Europe', 2.0, NULL),
|
||||
('Europe/Bucharest', 'Europe/Bucharest', 'IANA timezone: Europe/Bucharest', 'Europe', 3.0, NULL),
|
||||
('Europe/Budapest', 'Europe/Budapest', 'IANA timezone: Europe/Budapest', 'Europe', 2.0, NULL),
|
||||
('Europe/Busingen', 'Europe/Busingen', 'IANA timezone: Europe/Busingen', 'Europe', 2.0, NULL),
|
||||
('Europe/Chisinau', 'Europe/Chisinau', 'IANA timezone: Europe/Chisinau', 'Europe', 3.0, NULL),
|
||||
('Europe/Copenhagen', 'Europe/Copenhagen', 'IANA timezone: Europe/Copenhagen', 'Europe', 2.0, NULL),
|
||||
('Europe/Dublin', 'Europe/Dublin', 'IANA timezone: Europe/Dublin', 'Europe', 1.0, NULL),
|
||||
('Europe/Gibraltar', 'Europe/Gibraltar', 'IANA timezone: Europe/Gibraltar', 'Europe', 2.0, NULL),
|
||||
('Europe/Guernsey', 'Europe/Guernsey', 'IANA timezone: Europe/Guernsey', 'Europe', 1.0, NULL),
|
||||
('Europe/Helsinki', 'Europe/Helsinki', 'IANA timezone: Europe/Helsinki', 'Europe', 3.0, NULL),
|
||||
('Europe/Isle_of_Man', 'Europe/Isle of Man', 'IANA timezone: Europe/Isle_of_Man', 'Europe', 1.0, NULL),
|
||||
('Europe/Istanbul', 'Europe/Istanbul', 'IANA timezone: Europe/Istanbul', 'Europe', 3.0, NULL),
|
||||
('Europe/Jersey', 'Europe/Jersey', 'IANA timezone: Europe/Jersey', 'Europe', 1.0, NULL),
|
||||
('Europe/Kaliningrad', 'Europe/Kaliningrad', 'IANA timezone: Europe/Kaliningrad', 'Europe', 2.0, NULL),
|
||||
('Europe/Kiev', 'Europe/Kiev', 'IANA timezone: Europe/Kiev', 'Europe', 3.0, NULL),
|
||||
('Europe/Kirov', 'Europe/Kirov', 'IANA timezone: Europe/Kirov', 'Europe', 3.0, NULL),
|
||||
('Europe/Kyiv', 'Europe/Kyiv', 'IANA timezone: Europe/Kyiv', 'Europe', 3.0, NULL),
|
||||
('Europe/Lisbon', 'Europe/Lisbon', 'IANA timezone: Europe/Lisbon', 'Europe', 1.0, NULL),
|
||||
('Europe/Ljubljana', 'Europe/Ljubljana', 'IANA timezone: Europe/Ljubljana', 'Europe', 2.0, NULL),
|
||||
('Europe/London', 'Europe/London', 'IANA timezone: Europe/London', 'Europe', 1.0, NULL),
|
||||
('Europe/Luxembourg', 'Europe/Luxembourg', 'IANA timezone: Europe/Luxembourg', 'Europe', 2.0, NULL),
|
||||
('Europe/Madrid', 'Europe/Madrid', 'IANA timezone: Europe/Madrid', 'Europe', 2.0, NULL),
|
||||
('Europe/Malta', 'Europe/Malta', 'IANA timezone: Europe/Malta', 'Europe', 2.0, NULL),
|
||||
('Europe/Mariehamn', 'Europe/Mariehamn', 'IANA timezone: Europe/Mariehamn', 'Europe', 3.0, NULL),
|
||||
('Europe/Minsk', 'Europe/Minsk', 'IANA timezone: Europe/Minsk', 'Europe', 3.0, NULL),
|
||||
('Europe/Monaco', 'Europe/Monaco', 'IANA timezone: Europe/Monaco', 'Europe', 2.0, NULL),
|
||||
('Europe/Moscow', 'Europe/Moscow', 'IANA timezone: Europe/Moscow', 'Europe', 3.0, NULL),
|
||||
('Europe/Nicosia', 'Europe/Nicosia', 'IANA timezone: Europe/Nicosia', 'Europe', 3.0, NULL),
|
||||
('Europe/Oslo', 'Europe/Oslo', 'IANA timezone: Europe/Oslo', 'Europe', 2.0, NULL),
|
||||
('Europe/Paris', 'Europe/Paris', 'IANA timezone: Europe/Paris', 'Europe', 2.0, NULL),
|
||||
('Europe/Podgorica', 'Europe/Podgorica', 'IANA timezone: Europe/Podgorica', 'Europe', 2.0, NULL),
|
||||
('Europe/Prague', 'Europe/Prague', 'IANA timezone: Europe/Prague', 'Europe', 2.0, NULL),
|
||||
('Europe/Riga', 'Europe/Riga', 'IANA timezone: Europe/Riga', 'Europe', 3.0, NULL),
|
||||
('Europe/Rome', 'Europe/Rome', 'IANA timezone: Europe/Rome', 'Europe', 2.0, NULL),
|
||||
('Europe/Samara', 'Europe/Samara', 'IANA timezone: Europe/Samara', 'Europe', 4.0, NULL),
|
||||
('Europe/San_Marino', 'Europe/San Marino', 'IANA timezone: Europe/San_Marino', 'Europe', 2.0, NULL),
|
||||
('Europe/Sarajevo', 'Europe/Sarajevo', 'IANA timezone: Europe/Sarajevo', 'Europe', 2.0, NULL),
|
||||
('Europe/Saratov', 'Europe/Saratov', 'IANA timezone: Europe/Saratov', 'Europe', 4.0, NULL),
|
||||
('Europe/Simferopol', 'Europe/Simferopol', 'IANA timezone: Europe/Simferopol', 'Europe', 3.0, NULL),
|
||||
('Europe/Skopje', 'Europe/Skopje', 'IANA timezone: Europe/Skopje', 'Europe', 2.0, NULL),
|
||||
('Europe/Sofia', 'Europe/Sofia', 'IANA timezone: Europe/Sofia', 'Europe', 3.0, NULL),
|
||||
('Europe/Stockholm', 'Europe/Stockholm', 'IANA timezone: Europe/Stockholm', 'Europe', 2.0, NULL),
|
||||
('Europe/Tallinn', 'Europe/Tallinn', 'IANA timezone: Europe/Tallinn', 'Europe', 3.0, NULL),
|
||||
('Europe/Tirane', 'Europe/Tirane', 'IANA timezone: Europe/Tirane', 'Europe', 2.0, NULL),
|
||||
('Europe/Tiraspol', 'Europe/Tiraspol', 'IANA timezone: Europe/Tiraspol', 'Europe', 3.0, NULL),
|
||||
('Europe/Ulyanovsk', 'Europe/Ulyanovsk', 'IANA timezone: Europe/Ulyanovsk', 'Europe', 4.0, NULL),
|
||||
('Europe/Uzhgorod', 'Europe/Uzhgorod', 'IANA timezone: Europe/Uzhgorod', 'Europe', 3.0, NULL),
|
||||
('Europe/Vaduz', 'Europe/Vaduz', 'IANA timezone: Europe/Vaduz', 'Europe', 2.0, NULL),
|
||||
('Europe/Vatican', 'Europe/Vatican', 'IANA timezone: Europe/Vatican', 'Europe', 2.0, NULL),
|
||||
('Europe/Vienna', 'Europe/Vienna', 'IANA timezone: Europe/Vienna', 'Europe', 2.0, NULL),
|
||||
('Europe/Vilnius', 'Europe/Vilnius', 'IANA timezone: Europe/Vilnius', 'Europe', 3.0, NULL),
|
||||
('Europe/Volgograd', 'Europe/Volgograd', 'IANA timezone: Europe/Volgograd', 'Europe', 3.0, NULL),
|
||||
('Europe/Warsaw', 'Europe/Warsaw', 'IANA timezone: Europe/Warsaw', 'Europe', 2.0, NULL),
|
||||
('Europe/Zagreb', 'Europe/Zagreb', 'IANA timezone: Europe/Zagreb', 'Europe', 2.0, NULL),
|
||||
('Europe/Zaporozhye', 'Europe/Zaporozhye', 'IANA timezone: Europe/Zaporozhye', 'Europe', 3.0, NULL),
|
||||
('Europe/Zurich', 'Europe/Zurich', 'IANA timezone: Europe/Zurich', 'Europe', 2.0, NULL),
|
||||
('Factory', 'Factory', 'IANA timezone: Factory', 'Other', 0.0, NULL),
|
||||
('GB', 'GB', 'IANA timezone: GB', 'Other', 1.0, NULL),
|
||||
('GB-Eire', 'GB-Eire', 'IANA timezone: GB-Eire', 'Other', 1.0, NULL),
|
||||
('GMT', 'GMT', 'IANA timezone: GMT', 'Other', 0.0, NULL),
|
||||
('GMT+0', 'GMT+0', 'IANA timezone: GMT+0', 'Other', 0.0, NULL),
|
||||
('GMT-0', 'GMT-0', 'IANA timezone: GMT-0', 'Other', 0.0, NULL),
|
||||
('GMT0', 'GMT0', 'IANA timezone: GMT0', 'Other', 0.0, NULL),
|
||||
('Greenwich', 'Greenwich', 'IANA timezone: Greenwich', 'Other', 0.0, NULL),
|
||||
('Hongkong', 'Hongkong', 'IANA timezone: Hongkong', 'Other', 8.0, NULL),
|
||||
('HST', 'HST', 'IANA timezone: HST', 'Other', -10.0, NULL),
|
||||
('Iceland', 'Iceland', 'IANA timezone: Iceland', 'Other', 0.0, NULL),
|
||||
('Indian/Antananarivo', 'Indian/Antananarivo', 'IANA timezone: Indian/Antananarivo', 'Indian', 3.0, NULL),
|
||||
('Indian/Chagos', 'Indian/Chagos', 'IANA timezone: Indian/Chagos', 'Indian', 6.0, NULL),
|
||||
('Indian/Christmas', 'Indian/Christmas', 'IANA timezone: Indian/Christmas', 'Indian', 7.0, NULL),
|
||||
('Indian/Cocos', 'Indian/Cocos', 'IANA timezone: Indian/Cocos', 'Indian', 6.5, NULL),
|
||||
('Indian/Comoro', 'Indian/Comoro', 'IANA timezone: Indian/Comoro', 'Indian', 3.0, NULL),
|
||||
('Indian/Kerguelen', 'Indian/Kerguelen', 'IANA timezone: Indian/Kerguelen', 'Indian', 5.0, NULL),
|
||||
('Indian/Mahe', 'Indian/Mahe', 'IANA timezone: Indian/Mahe', 'Indian', 4.0, NULL),
|
||||
('Indian/Maldives', 'Indian/Maldives', 'IANA timezone: Indian/Maldives', 'Indian', 5.0, NULL),
|
||||
('Indian/Mauritius', 'Indian/Mauritius', 'IANA timezone: Indian/Mauritius', 'Indian', 4.0, NULL),
|
||||
('Indian/Mayotte', 'Indian/Mayotte', 'IANA timezone: Indian/Mayotte', 'Indian', 3.0, NULL),
|
||||
('Indian/Reunion', 'Indian/Reunion', 'IANA timezone: Indian/Reunion', 'Indian', 4.0, NULL),
|
||||
('Iran', 'Iran', 'IANA timezone: Iran', 'Other', 3.5, NULL),
|
||||
('Israel', 'Israel', 'IANA timezone: Israel', 'Other', 3.0, NULL),
|
||||
('Jamaica', 'Jamaica', 'IANA timezone: Jamaica', 'Other', -5.0, NULL),
|
||||
('Japan', 'Japan', 'IANA timezone: Japan', 'Other', 9.0, NULL),
|
||||
('Kwajalein', 'Kwajalein', 'IANA timezone: Kwajalein', 'Other', 12.0, NULL),
|
||||
('Libya', 'Libya', 'IANA timezone: Libya', 'Other', 2.0, NULL),
|
||||
('MET', 'MET', 'IANA timezone: MET', 'Other', 2.0, NULL),
|
||||
('Mexico/BajaNorte', 'Mexico/BajaNorte', 'IANA timezone: Mexico/BajaNorte', 'Mexico', -7.0, NULL),
|
||||
('Mexico/BajaSur', 'Mexico/BajaSur', 'IANA timezone: Mexico/BajaSur', 'Mexico', -7.0, NULL),
|
||||
('Mexico/General', 'Mexico/General', 'IANA timezone: Mexico/General', 'Mexico', -6.0, NULL),
|
||||
('MST', 'MST', 'IANA timezone: MST', 'Other', -7.0, NULL),
|
||||
('MST7MDT', 'MST7MDT', 'IANA timezone: MST7MDT', 'Other', -6.0, NULL),
|
||||
('Navajo', 'Navajo', 'IANA timezone: Navajo', 'Other', -6.0, NULL),
|
||||
('NZ', 'NZ', 'IANA timezone: NZ', 'Other', 13.0, NULL),
|
||||
('NZ-CHAT', 'NZ-CHAT', 'IANA timezone: NZ-CHAT', 'Other', 13.75, NULL),
|
||||
('Pacific/Apia', 'Pacific/Apia', 'IANA timezone: Pacific/Apia', 'Pacific', 13.0, NULL),
|
||||
('Pacific/Auckland', 'Pacific/Auckland', 'IANA timezone: Pacific/Auckland', 'Pacific', 13.0, NULL),
|
||||
('Pacific/Bougainville', 'Pacific/Bougainville', 'IANA timezone: Pacific/Bougainville', 'Pacific', 11.0, NULL),
|
||||
('Pacific/Chatham', 'Pacific/Chatham', 'IANA timezone: Pacific/Chatham', 'Pacific', 13.75, NULL),
|
||||
('Pacific/Chuuk', 'Pacific/Chuuk', 'IANA timezone: Pacific/Chuuk', 'Pacific', 10.0, NULL),
|
||||
('Pacific/Easter', 'Pacific/Easter', 'IANA timezone: Pacific/Easter', 'Pacific', -5.0, NULL),
|
||||
('Pacific/Efate', 'Pacific/Efate', 'IANA timezone: Pacific/Efate', 'Pacific', 11.0, NULL),
|
||||
('Pacific/Enderbury', 'Pacific/Enderbury', 'IANA timezone: Pacific/Enderbury', 'Pacific', 13.0, NULL),
|
||||
('Pacific/Fakaofo', 'Pacific/Fakaofo', 'IANA timezone: Pacific/Fakaofo', 'Pacific', 13.0, NULL),
|
||||
('Pacific/Fiji', 'Pacific/Fiji', 'IANA timezone: Pacific/Fiji', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Funafuti', 'Pacific/Funafuti', 'IANA timezone: Pacific/Funafuti', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Galapagos', 'Pacific/Galapagos', 'IANA timezone: Pacific/Galapagos', 'Pacific', -6.0, NULL),
|
||||
('Pacific/Gambier', 'Pacific/Gambier', 'IANA timezone: Pacific/Gambier', 'Pacific', -9.0, NULL),
|
||||
('Pacific/Guadalcanal', 'Pacific/Guadalcanal', 'IANA timezone: Pacific/Guadalcanal', 'Pacific', 11.0, NULL),
|
||||
('Pacific/Guam', 'Pacific/Guam', 'IANA timezone: Pacific/Guam', 'Pacific', 10.0, NULL),
|
||||
('Pacific/Honolulu', 'Pacific/Honolulu', 'IANA timezone: Pacific/Honolulu', 'Pacific', -10.0, NULL),
|
||||
('Pacific/Johnston', 'Pacific/Johnston', 'IANA timezone: Pacific/Johnston', 'Pacific', -10.0, NULL),
|
||||
('Pacific/Kanton', 'Pacific/Kanton', 'IANA timezone: Pacific/Kanton', 'Pacific', 13.0, NULL),
|
||||
('Pacific/Kiritimati', 'Pacific/Kiritimati', 'IANA timezone: Pacific/Kiritimati', 'Pacific', 14.0, NULL),
|
||||
('Pacific/Kosrae', 'Pacific/Kosrae', 'IANA timezone: Pacific/Kosrae', 'Pacific', 11.0, NULL),
|
||||
('Pacific/Kwajalein', 'Pacific/Kwajalein', 'IANA timezone: Pacific/Kwajalein', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Majuro', 'Pacific/Majuro', 'IANA timezone: Pacific/Majuro', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Marquesas', 'Pacific/Marquesas', 'IANA timezone: Pacific/Marquesas', 'Pacific', -9.5, NULL),
|
||||
('Pacific/Midway', 'Pacific/Midway', 'IANA timezone: Pacific/Midway', 'Pacific', -11.0, NULL),
|
||||
('Pacific/Nauru', 'Pacific/Nauru', 'IANA timezone: Pacific/Nauru', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Niue', 'Pacific/Niue', 'IANA timezone: Pacific/Niue', 'Pacific', -11.0, NULL),
|
||||
('Pacific/Norfolk', 'Pacific/Norfolk', 'IANA timezone: Pacific/Norfolk', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Noumea', 'Pacific/Noumea', 'IANA timezone: Pacific/Noumea', 'Pacific', 11.0, NULL),
|
||||
('Pacific/Pago_Pago', 'Pacific/Pago Pago', 'IANA timezone: Pacific/Pago_Pago', 'Pacific', -11.0, NULL),
|
||||
('Pacific/Palau', 'Pacific/Palau', 'IANA timezone: Pacific/Palau', 'Pacific', 9.0, NULL),
|
||||
('Pacific/Pitcairn', 'Pacific/Pitcairn', 'IANA timezone: Pacific/Pitcairn', 'Pacific', -8.0, NULL),
|
||||
('Pacific/Pohnpei', 'Pacific/Pohnpei', 'IANA timezone: Pacific/Pohnpei', 'Pacific', 11.0, NULL),
|
||||
('Pacific/Ponape', 'Pacific/Ponape', 'IANA timezone: Pacific/Ponape', 'Pacific', 11.0, NULL),
|
||||
('Pacific/Port_Moresby', 'Pacific/Port Moresby', 'IANA timezone: Pacific/Port_Moresby', 'Pacific', 10.0, NULL),
|
||||
('Pacific/Rarotonga', 'Pacific/Rarotonga', 'IANA timezone: Pacific/Rarotonga', 'Pacific', -10.0, NULL),
|
||||
('Pacific/Saipan', 'Pacific/Saipan', 'IANA timezone: Pacific/Saipan', 'Pacific', 10.0, NULL),
|
||||
('Pacific/Samoa', 'Pacific/Samoa', 'IANA timezone: Pacific/Samoa', 'Pacific', -11.0, NULL),
|
||||
('Pacific/Tahiti', 'Pacific/Tahiti', 'IANA timezone: Pacific/Tahiti', 'Pacific', -10.0, NULL),
|
||||
('Pacific/Tarawa', 'Pacific/Tarawa', 'IANA timezone: Pacific/Tarawa', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Tongatapu', 'Pacific/Tongatapu', 'IANA timezone: Pacific/Tongatapu', 'Pacific', 13.0, NULL),
|
||||
('Pacific/Truk', 'Pacific/Truk', 'IANA timezone: Pacific/Truk', 'Pacific', 10.0, NULL),
|
||||
('Pacific/Wake', 'Pacific/Wake', 'IANA timezone: Pacific/Wake', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Wallis', 'Pacific/Wallis', 'IANA timezone: Pacific/Wallis', 'Pacific', 12.0, NULL),
|
||||
('Pacific/Yap', 'Pacific/Yap', 'IANA timezone: Pacific/Yap', 'Pacific', 10.0, NULL),
|
||||
('Poland', 'Poland', 'IANA timezone: Poland', 'Other', 2.0, NULL),
|
||||
('Portugal', 'Portugal', 'IANA timezone: Portugal', 'Other', 1.0, NULL),
|
||||
('PRC', 'PRC', 'IANA timezone: PRC', 'Other', 8.0, NULL),
|
||||
('PST8PDT', 'PST8PDT', 'IANA timezone: PST8PDT', 'Other', -7.0, NULL),
|
||||
('ROC', 'ROC', 'IANA timezone: ROC', 'Other', 8.0, NULL),
|
||||
('ROK', 'ROK', 'IANA timezone: ROK', 'Other', 9.0, NULL),
|
||||
('Singapore', 'Singapore', 'IANA timezone: Singapore', 'Other', 8.0, NULL),
|
||||
('Turkey', 'Turkey', 'IANA timezone: Turkey', 'Other', 3.0, NULL),
|
||||
('UCT', 'UCT', 'IANA timezone: UCT', 'Other', 0.0, NULL),
|
||||
('Universal', 'Universal', 'IANA timezone: Universal', 'Other', 0.0, NULL),
|
||||
('US/Alaska', 'US/Alaska', 'IANA timezone: US/Alaska', 'US', -8.0, NULL),
|
||||
('US/Aleutian', 'US/Aleutian', 'IANA timezone: US/Aleutian', 'US', -9.0, NULL),
|
||||
('US/Arizona', 'US/Arizona', 'IANA timezone: US/Arizona', 'US', -7.0, NULL),
|
||||
('US/Central', 'US/Central', 'IANA timezone: US/Central', 'US', -5.0, NULL),
|
||||
('US/Eastern', 'US/Eastern', 'IANA timezone: US/Eastern', 'US', -4.0, NULL),
|
||||
('US/East-Indiana', 'US/East-Indiana', 'IANA timezone: US/East-Indiana', 'US', -4.0, NULL),
|
||||
('US/Hawaii', 'US/Hawaii', 'IANA timezone: US/Hawaii', 'US', -10.0, NULL),
|
||||
('US/Indiana-Starke', 'US/Indiana-Starke', 'IANA timezone: US/Indiana-Starke', 'US', -5.0, NULL),
|
||||
('US/Michigan', 'US/Michigan', 'IANA timezone: US/Michigan', 'US', -4.0, NULL),
|
||||
('US/Mountain', 'US/Mountain', 'IANA timezone: US/Mountain', 'US', -6.0, NULL),
|
||||
('US/Pacific', 'US/Pacific', 'IANA timezone: US/Pacific', 'US', -7.0, NULL),
|
||||
('US/Samoa', 'US/Samoa', 'IANA timezone: US/Samoa', 'US', -11.0, NULL),
|
||||
('UTC', 'UTC', 'IANA timezone: UTC', 'Other', 0.0, NULL),
|
||||
('WET', 'WET', 'IANA timezone: WET', 'Other', 1.0, NULL),
|
||||
('W-SU', 'W-SU', 'IANA timezone: W-SU', 'Other', 3.0, NULL),
|
||||
('Zulu', 'Zulu', 'IANA timezone: Zulu', 'Other', 0.0, NULL);
|
||||
|
||||
-- Currencies
|
||||
INSERT INTO meta.currencies (code, name, symbol, decimal_places, notes)
|
||||
VALUES
|
||||
('AED', 'UAE Dirham', 'د.إ', 2, NULL),
|
||||
('AFN', 'Afghani', 'AFN', 2, NULL),
|
||||
('ALL', 'Lek', 'ALL', 2, NULL),
|
||||
('AMD', 'Armenian Dram', 'AMD', 2, NULL),
|
||||
('AOA', 'Kwanza', 'AOA', 2, NULL),
|
||||
('ARS', 'Argentine Peso', '$', 2, NULL),
|
||||
('AUD', 'Australian Dollar', 'A$', 2, NULL),
|
||||
('AWG', 'Aruban Florin', 'AWG', 2, NULL),
|
||||
('AZN', 'Azerbaijan Manat', 'AZN', 2, NULL),
|
||||
('BAM', 'Convertible Mark', 'BAM', 2, NULL),
|
||||
('BBD', 'Barbados Dollar', 'BBD', 2, NULL),
|
||||
('BDT', 'Taka', 'BDT', 2, NULL),
|
||||
('BGN', 'Bulgarian Lev', 'BGN', 2, NULL),
|
||||
('BHD', 'Bahraini Dinar', 'BHD', 3, NULL),
|
||||
('BIF', 'Burundi Franc', 'BIF', 0, NULL),
|
||||
('BMD', 'Bermudian Dollar', 'BMD', 2, NULL),
|
||||
('BND', 'Brunei Dollar', 'BND', 2, NULL),
|
||||
('BOB', 'Boliviano', 'BOB', 2, NULL),
|
||||
('BOV', 'Mvdol', 'BOV', 2, NULL),
|
||||
('BRL', 'Brazilian Real', 'R$', 2, NULL),
|
||||
('BSD', 'Bahamian Dollar', 'BSD', 2, NULL),
|
||||
('BTN', 'Ngultrum', 'BTN', 2, NULL),
|
||||
('BWP', 'Pula', 'BWP', 2, NULL),
|
||||
('BYN', 'Belarusian Ruble', 'BYN', 2, NULL),
|
||||
('BZD', 'Belize Dollar', 'BZD', 2, NULL),
|
||||
('CAD', 'Canadian Dollar', 'C$', 2, NULL),
|
||||
('CDF', 'Congolese Franc', 'CDF', 2, NULL),
|
||||
('CHE', 'WIR Euro', 'CHE', 2, NULL),
|
||||
('CHF', 'Swiss Franc', 'CHF', 2, NULL),
|
||||
('CHW', 'WIR Franc', 'CHW', 2, NULL),
|
||||
('CLF', 'Unidad de Fomento', 'CLF', 4, NULL),
|
||||
('CLP', 'Chilean Peso', '$', 0, NULL),
|
||||
('CNY', 'Yuan Renminbi', '¥', 2, NULL),
|
||||
('COP', 'Colombian Peso', 'COP', 2, NULL),
|
||||
('COU', 'Unidad de Valor Real', 'COU', 2, NULL),
|
||||
('CRC', 'Costa Rican Colon', 'CRC', 2, NULL),
|
||||
('CUP', 'Cuban Peso', 'CUP', 2, NULL),
|
||||
('CVE', 'Cabo Verde Escudo', 'CVE', 2, NULL),
|
||||
('CZK', 'Czech Koruna', 'Kč', 2, NULL),
|
||||
('DJF', 'Djibouti Franc', 'DJF', 0, NULL),
|
||||
('DKK', 'Danish Krone', 'kr', 2, NULL),
|
||||
('DOP', 'Dominican Peso', 'DOP', 2, NULL),
|
||||
('DZD', 'Algerian Dinar', 'DZD', 2, NULL),
|
||||
('EGP', 'Egyptian Pound', 'EGP', 2, NULL),
|
||||
('ERN', 'Nakfa', 'ERN', 2, NULL),
|
||||
('ETB', 'Ethiopian Birr', 'ETB', 2, NULL),
|
||||
('EUR', 'Euro', '€', 2, NULL),
|
||||
('FJD', 'Fiji Dollar', 'FJD', 2, NULL),
|
||||
('FKP', 'Falkland Islands Pound', 'FKP', 2, NULL),
|
||||
('GBP', 'Pound Sterling', '£', 2, NULL),
|
||||
('GEL', 'Lari', 'GEL', 2, NULL),
|
||||
('GHS', 'Ghana Cedi', 'GHS', 2, NULL),
|
||||
('GIP', 'Gibraltar Pound', 'GIP', 2, NULL),
|
||||
('GMD', 'Dalasi', 'GMD', 2, NULL),
|
||||
('GNF', 'Guinean Franc', 'GNF', 0, NULL),
|
||||
('GTQ', 'Quetzal', 'GTQ', 2, NULL),
|
||||
('GYD', 'Guyana Dollar', 'GYD', 2, NULL),
|
||||
('HKD', 'Hong Kong Dollar', 'HK$', 2, NULL),
|
||||
('HNL', 'Lempira', 'HNL', 2, NULL),
|
||||
('HTG', 'Gourde', 'HTG', 2, NULL),
|
||||
('HUF', 'Forint', 'Ft', 2, NULL),
|
||||
('IDR', 'Rupiah', 'Rp', 2, NULL),
|
||||
('ILS', 'New Israeli Sheqel', '₪', 2, NULL),
|
||||
('INR', 'Indian Rupee', '₹', 2, NULL),
|
||||
('IQD', 'Iraqi Dinar', 'IQD', 3, NULL),
|
||||
('IRR', 'Iranian Rial', 'IRR', 2, NULL),
|
||||
('ISK', 'Iceland Krona', 'ISK', 0, NULL),
|
||||
('JMD', 'Jamaican Dollar', 'JMD', 2, NULL),
|
||||
('JOD', 'Jordanian Dinar', 'JOD', 3, NULL),
|
||||
('JPY', 'Yen', '¥', 0, NULL),
|
||||
('KES', 'Kenyan Shilling', 'KES', 2, NULL),
|
||||
('KGS', 'Som', 'KGS', 2, NULL),
|
||||
('KHR', 'Riel', 'KHR', 2, NULL),
|
||||
('KMF', 'Comorian Franc', 'KMF', 0, NULL),
|
||||
('KPW', 'North Korean Won', 'KPW', 2, NULL),
|
||||
('KRW', 'Won', '₩', 0, NULL),
|
||||
('KWD', 'Kuwaiti Dinar', 'KWD', 3, NULL),
|
||||
('KYD', 'Cayman Islands Dollar', 'KYD', 2, NULL),
|
||||
('KZT', 'Tenge', 'KZT', 2, NULL),
|
||||
('LAK', 'Lao Kip', 'LAK', 2, NULL),
|
||||
('LBP', 'Lebanese Pound', 'LBP', 2, NULL),
|
||||
('LKR', 'Sri Lanka Rupee', 'LKR', 2, NULL),
|
||||
('LRD', 'Liberian Dollar', 'LRD', 2, NULL),
|
||||
('LSL', 'Loti', 'LSL', 2, NULL),
|
||||
('LYD', 'Libyan Dinar', 'LYD', 3, NULL),
|
||||
('MAD', 'Moroccan Dirham', 'MAD', 2, NULL),
|
||||
('MDL', 'Moldovan Leu', 'MDL', 2, NULL),
|
||||
('MGA', 'Malagasy Ariary', 'MGA', 2, NULL),
|
||||
('MKD', 'Denar', 'MKD', 2, NULL),
|
||||
('MMK', 'Kyat', 'MMK', 2, NULL),
|
||||
('MNT', 'Tugrik', 'MNT', 2, NULL),
|
||||
('MOP', 'Pataca', 'MOP', 2, NULL),
|
||||
('MRU', 'Ouguiya', 'MRU', 2, NULL),
|
||||
('MUR', 'Mauritius Rupee', 'MUR', 2, NULL),
|
||||
('MVR', 'Rufiyaa', 'MVR', 2, NULL),
|
||||
('MWK', 'Malawi Kwacha', 'MWK', 2, NULL),
|
||||
('MXN', 'Mexican Peso', 'Mex$', 2, NULL),
|
||||
('MXV', 'Mexican Unidad de Inversion (UDI)', 'MXV', 2, NULL),
|
||||
('MYR', 'Malaysian Ringgit', 'RM', 2, NULL),
|
||||
('MZN', 'Mozambique Metical', 'MZN', 2, NULL),
|
||||
('NAD', 'Namibia Dollar', 'NAD', 2, NULL),
|
||||
('NGN', 'Naira', 'NGN', 2, NULL),
|
||||
('NIO', 'Cordoba Oro', 'NIO', 2, NULL),
|
||||
('NOK', 'Norwegian Krone', 'kr', 2, NULL),
|
||||
('NPR', 'Nepalese Rupee', 'NPR', 2, NULL),
|
||||
('NZD', 'New Zealand Dollar', 'NZ$', 2, NULL),
|
||||
('OMR', 'Rial Omani', 'OMR', 3, NULL),
|
||||
('PAB', 'Balboa', 'PAB', 2, NULL),
|
||||
('PEN', 'Sol', 'PEN', 2, NULL),
|
||||
('PGK', 'Kina', 'PGK', 2, NULL),
|
||||
('PHP', 'Philippine Peso', '₱', 2, NULL),
|
||||
('PKR', 'Pakistan Rupee', 'PKR', 2, NULL),
|
||||
('PLN', 'Zloty', 'zł', 2, NULL),
|
||||
('PYG', 'Guarani', 'PYG', 0, NULL),
|
||||
('QAR', 'Qatari Rial', 'QAR', 2, NULL),
|
||||
('RON', 'Romanian Leu', 'RON', 2, NULL),
|
||||
('RSD', 'Serbian Dinar', 'RSD', 2, NULL),
|
||||
('RUB', 'Russian Ruble', '₽', 2, NULL),
|
||||
('RWF', 'Rwanda Franc', 'RWF', 0, NULL),
|
||||
('SAR', 'Saudi Riyal', '﷼', 2, NULL),
|
||||
('SBD', 'Solomon Islands Dollar', 'SBD', 2, NULL),
|
||||
('SCR', 'Seychelles Rupee', 'SCR', 2, NULL),
|
||||
('SDG', 'Sudanese Pound', 'SDG', 2, NULL),
|
||||
('SEK', 'Swedish Krona', 'kr', 2, NULL),
|
||||
('SGD', 'Singapore Dollar', 'S$', 2, NULL),
|
||||
('SHP', 'Saint Helena Pound', 'SHP', 2, NULL),
|
||||
('SLE', 'Leone', 'SLE', 2, NULL),
|
||||
('SOS', 'Somali Shilling', 'SOS', 2, NULL),
|
||||
('SRD', 'Surinam Dollar', 'SRD', 2, NULL),
|
||||
('SSP', 'South Sudanese Pound', 'SSP', 2, NULL),
|
||||
('STN', 'Dobra', 'STN', 2, NULL),
|
||||
('SVC', 'El Salvador Colon', 'SVC', 2, NULL),
|
||||
('SYP', 'Syrian Pound', 'SYP', 2, NULL),
|
||||
('SZL', 'Lilangeni', 'SZL', 2, NULL),
|
||||
('THB', 'Baht', '฿', 2, NULL),
|
||||
('TJS', 'Somoni', 'TJS', 2, NULL),
|
||||
('TMT', 'Turkmenistan New Manat', 'TMT', 2, NULL),
|
||||
('TND', 'Tunisian Dinar', 'TND', 3, NULL),
|
||||
('TOP', 'Pa’anga', 'TOP', 2, NULL),
|
||||
('TRY', 'Turkish Lira', '₺', 2, NULL),
|
||||
('TTD', 'Trinidad and Tobago Dollar', 'TTD', 2, NULL),
|
||||
('TWD', 'New Taiwan Dollar', 'NT$', 2, NULL),
|
||||
('TZS', 'Tanzanian Shilling', 'TZS', 2, NULL),
|
||||
('UAH', 'Hryvnia', 'UAH', 2, NULL),
|
||||
('UGX', 'Uganda Shilling', 'UGX', 0, NULL),
|
||||
('USD', 'US Dollar', '$', 2, NULL),
|
||||
('USN', 'US Dollar (Next day)', 'USN', 2, NULL),
|
||||
('UYI', 'Uruguay Peso en Unidades Indexadas (UI)', 'UYI', 0, NULL),
|
||||
('UYU', 'Peso Uruguayo', 'UYU', 2, NULL),
|
||||
('UYW', 'Unidad Previsional', 'UYW', 4, NULL),
|
||||
('UZS', 'Uzbekistan Sum', 'UZS', 2, NULL),
|
||||
('VED', 'Bolívar Soberano', 'VED', 2, NULL),
|
||||
('VES', 'Bolívar Soberano', 'VES', 2, NULL),
|
||||
('VND', 'Dong', '₫', 0, NULL),
|
||||
('VUV', 'Vatu', 'VUV', 0, NULL),
|
||||
('WST', 'Tala', 'WST', 2, NULL),
|
||||
('XAD', 'Arab Accounting Dinar', 'XAD', 2, NULL),
|
||||
('XAF', 'CFA Franc BEAC', 'XAF', 0, NULL),
|
||||
('XAG', 'Silver', 'XAG', 2, NULL),
|
||||
('XAU', 'Gold', 'XAU', 2, NULL),
|
||||
('XBA', 'Bond Markets Unit European Composite Unit (EURCO)', 'XBA', 2, NULL),
|
||||
('XBB', 'Bond Markets Unit European Monetary Unit (E.M.U.-6)', 'XBB', 2, NULL),
|
||||
('XBC', 'Bond Markets Unit European Unit of Account 9 (E.U.A.-9)', 'XBC', 2, NULL),
|
||||
('XBD', 'Bond Markets Unit European Unit of Account 17 (E.U.A.-17)', 'XBD', 2, NULL),
|
||||
('XCD', 'East Caribbean Dollar', 'XCD', 2, NULL),
|
||||
('XCG', 'Caribbean Guilder', 'XCG', 2, NULL),
|
||||
('XDR', 'SDR (Special Drawing Right)', 'XDR', 2, NULL),
|
||||
('XOF', 'CFA Franc BCEAO', 'XOF', 0, NULL),
|
||||
('XPD', 'Palladium', 'XPD', 2, NULL),
|
||||
('XPF', 'CFP Franc', 'XPF', 0, NULL),
|
||||
('XPT', 'Platinum', 'XPT', 2, NULL),
|
||||
('XSU', 'Sucre', 'XSU', 2, NULL),
|
||||
('XTS', 'Codes specifically reserved for testing purposes', 'XTS', 2, NULL),
|
||||
('XUA', 'ADB Unit of Account', 'XUA', 2, NULL),
|
||||
('XXX', 'The codes assigned for transactions where no currency is involved', 'XXX', 2, NULL),
|
||||
('YER', 'Yemeni Rial', 'YER', 2, NULL),
|
||||
('ZAR', 'Rand', 'R', 2, NULL),
|
||||
('ZMW', 'Zambian Kwacha', 'ZMW', 2, NULL),
|
||||
('ZWG', 'Zimbabwe Gold', 'ZWG', 2, NULL);
|
||||
|
||||
-- Security Types (Interactive Brokers conventions)
|
||||
INSERT INTO meta.security_types (code, name, description, notes)
|
||||
VALUES
|
||||
('ADR', 'American Depositary Receipt', 'Negotiable certificate representing shares in a foreign company', NULL),
|
||||
('BOND', 'Bond', 'Government and corporate bonds', NULL),
|
||||
('CASH', 'Forex', 'Foreign exchange currency pairs', NULL),
|
||||
('CFD', 'CFD', 'Contracts for difference', NULL),
|
||||
('CRYPTO', 'Cryptocurrency', 'Digital currencies and tokens', NULL),
|
||||
('ETF', 'Exchange Traded Fund', 'Exchange-traded fund that tracks an index, commodity, or basket of assets', NULL),
|
||||
('FOP', 'Futures Option', 'Options on futures contracts', NULL),
|
||||
('FUND', 'Mutual Fund', 'Open and closed-end mutual funds', NULL),
|
||||
('FUT', 'Future', 'Exchange-traded futures contracts', NULL),
|
||||
('IOPT', 'Structured Product', 'Dutch warrants and structured products', NULL),
|
||||
('OPT', 'Option', 'Equity and index options', NULL),
|
||||
('STK', 'Stock', 'Common and preferred equities', NULL),
|
||||
('WAR', 'Warrant', 'Equity warrants', NULL);
|
||||
44
sql/08_script_log.sql
Normal file
44
sql/08_script_log.sql
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
-- ============================================================================
|
||||
-- Script Logging Table
|
||||
-- ============================================================================
|
||||
-- Persistent log for import scripts and library operations.
|
||||
-- Provides queryable event log without cluttering CLI output.
|
||||
--
|
||||
-- Usage:
|
||||
-- session = db.log_session("import_ohlc.py")
|
||||
-- session.info("Starting import for AAPL")
|
||||
-- session.warning("Missing data for 2024-01-15")
|
||||
-- session.error("Failed to parse file", details={"file": "bad.csv"})
|
||||
-- ============================================================================
|
||||
|
||||
-- Create script_log table in log schema
|
||||
CREATE TABLE IF NOT EXISTS log.script_log (
|
||||
id SERIAL PRIMARY KEY,
|
||||
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
level VARCHAR(10) NOT NULL DEFAULT 'INFO' CHECK (level IN ('DEBUG', 'INFO', 'WARNING', 'ERROR')),
|
||||
message TEXT NOT NULL,
|
||||
script_name VARCHAR(100),
|
||||
series_name VARCHAR(255),
|
||||
session_id UUID,
|
||||
details JSONB
|
||||
);
|
||||
|
||||
-- Indexes for common query patterns
|
||||
CREATE INDEX IF NOT EXISTS idx_script_log_timestamp ON log.script_log(timestamp DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_script_log_session ON log.script_log(session_id) WHERE session_id IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_script_log_series ON log.script_log(series_name) WHERE series_name IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_script_log_level ON log.script_log(level);
|
||||
|
||||
-- View for recent logs (last 1000)
|
||||
CREATE OR REPLACE VIEW log.script_log_recent AS
|
||||
SELECT * FROM log.script_log
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT 1000;
|
||||
|
||||
-- Table and column comments
|
||||
COMMENT ON TABLE log.script_log IS 'Persistent log for import scripts and library operations';
|
||||
COMMENT ON COLUMN log.script_log.level IS 'Log level: DEBUG, INFO, WARNING, ERROR';
|
||||
COMMENT ON COLUMN log.script_log.session_id IS 'Groups logs from a single script run (UUID)';
|
||||
COMMENT ON COLUMN log.script_log.script_name IS 'Name of the script or operation (e.g., import_ohlc.py)';
|
||||
COMMENT ON COLUMN log.script_log.series_name IS 'Optional: link to specific series';
|
||||
COMMENT ON COLUMN log.script_log.details IS 'Optional structured data stored as JSONB';
|
||||
48
sql/migrate/migrate_drop_series_if_exists.sql
Normal file
48
sql/migrate/migrate_drop_series_if_exists.sql
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
-- Migration: repair meta.drop_series_if_exists()
|
||||
--
|
||||
-- The function dropped a registered series without setting
|
||||
-- application.dropping_series, so the prevent_direct_drop event trigger
|
||||
-- rejected its own DROP:
|
||||
--
|
||||
-- Table series.X is registered in series and can only be dropped
|
||||
-- using TimeseriesDB.drop_series()
|
||||
--
|
||||
-- Unlike meta.drop_series() and meta.drop_all_series(), which set the flag
|
||||
-- correctly, this one never did -- so it always failed on exactly the case it
|
||||
-- exists to handle. The Python API does not call it, which is why the defect
|
||||
-- went unnoticed.
|
||||
--
|
||||
-- New databases pick this up from 05_procedures.sql. Run this against any
|
||||
-- database initialised before the fix.
|
||||
--
|
||||
-- Safe to run more than once (CREATE OR REPLACE).
|
||||
|
||||
CREATE OR REPLACE FUNCTION meta.drop_series_if_exists(_table_name text, _schema_name text DEFAULT 'series'::text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
-- Check if the series exists in series table
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM meta.series
|
||||
WHERE "table_name" = _table_name
|
||||
AND "db_schema" = _schema_name
|
||||
) THEN
|
||||
-- Signal the prevent_direct_drop event trigger that this DROP is
|
||||
-- coming from a sanctioned procedure. Without it the trigger rejects
|
||||
-- the statement below, because the table is registered in meta.series.
|
||||
-- Local to the transaction, so it cannot leak to later statements.
|
||||
PERFORM set_config('application.dropping_series', 'true', true);
|
||||
|
||||
-- Drop the table
|
||||
EXECUTE format('DROP TABLE IF EXISTS %I.%I', _schema_name, _table_name);
|
||||
|
||||
-- Remove from series table
|
||||
DELETE FROM meta.series
|
||||
WHERE "table_name" = _table_name
|
||||
AND "db_schema" = _schema_name;
|
||||
|
||||
PERFORM set_config('application.dropping_series', 'false', true);
|
||||
END IF;
|
||||
END;
|
||||
$function$;
|
||||
99
sql/migrate/migrate_instrument_metadata.sql
Normal file
99
sql/migrate/migrate_instrument_metadata.sql
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
-- Migration: Add Instrument Metadata Columns
|
||||
-- Date: 2026-02-11
|
||||
-- Description: Adds classification and trading specification columns to meta.exchanges and meta.instruments
|
||||
|
||||
-- ============================================================================
|
||||
-- 1. Add columns to meta.exchanges
|
||||
-- ============================================================================
|
||||
|
||||
-- Trading specifications
|
||||
ALTER TABLE meta.exchanges ADD COLUMN IF NOT EXISTS default_tick_size DOUBLE PRECISION;
|
||||
ALTER TABLE meta.exchanges ADD COLUMN IF NOT EXISTS default_tick_value DOUBLE PRECISION;
|
||||
ALTER TABLE meta.exchanges ADD COLUMN IF NOT EXISTS default_extended_hours BOOLEAN DEFAULT false;
|
||||
|
||||
-- Geographic info
|
||||
ALTER TABLE meta.exchanges ADD COLUMN IF NOT EXISTS country VARCHAR(3);
|
||||
|
||||
COMMENT ON COLUMN meta.exchanges.default_tick_size IS 'Default minimum price increment (e.g., 0.01 for stocks)';
|
||||
COMMENT ON COLUMN meta.exchanges.default_tick_value IS 'Default value per tick in currency (0.01 for stocks = 1 cent per share)';
|
||||
COMMENT ON COLUMN meta.exchanges.default_extended_hours IS 'Default for whether instruments support pre/post market trading';
|
||||
COMMENT ON COLUMN meta.exchanges.country IS 'ISO 3166-1 alpha-3 country code (USA, GBR, JPN)';
|
||||
|
||||
-- ============================================================================
|
||||
-- 2. Add columns to meta.instruments
|
||||
-- ============================================================================
|
||||
|
||||
-- Basic info
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS description VARCHAR(255);
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS country VARCHAR(3);
|
||||
|
||||
-- Trading specifications
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS extended_hours BOOLEAN;
|
||||
|
||||
-- Company/Fund classification
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS sector VARCHAR(50);
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS industry VARCHAR(100);
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS category VARCHAR(50);
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS subcategory VARCHAR(50);
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS asset_class VARCHAR(30);
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS geography VARCHAR(30);
|
||||
|
||||
-- ETF-specific
|
||||
ALTER TABLE meta.instruments ADD COLUMN IF NOT EXISTS underlying VARCHAR(30);
|
||||
|
||||
COMMENT ON COLUMN meta.instruments.description IS 'Full name/description of the instrument';
|
||||
COMMENT ON COLUMN meta.instruments.country IS 'ISO 3166-1 alpha-3 country code (overrides exchange default)';
|
||||
COMMENT ON COLUMN meta.instruments.extended_hours IS 'Override exchange default for pre/post market trading';
|
||||
COMMENT ON COLUMN meta.instruments.sector IS 'GICS sector (e.g., Technology, Financials)';
|
||||
COMMENT ON COLUMN meta.instruments.industry IS 'GICS industry (e.g., Software-Application)';
|
||||
COMMENT ON COLUMN meta.instruments.category IS 'Custom categorization (e.g., Sector ETF, Broad Market)';
|
||||
COMMENT ON COLUMN meta.instruments.subcategory IS 'Custom sub-categorization (e.g., S&P 500, Technology)';
|
||||
COMMENT ON COLUMN meta.instruments.asset_class IS 'Asset class (Equity, Fixed Income, Commodity, Currency)';
|
||||
COMMENT ON COLUMN meta.instruments.geography IS 'Geographic focus (US, International, Emerging)';
|
||||
COMMENT ON COLUMN meta.instruments.underlying IS 'Underlying symbol for ETFs/derivatives (e.g., SPX, NDX)';
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. Update existing exchange data
|
||||
-- ============================================================================
|
||||
|
||||
-- Update NYSE if it exists
|
||||
UPDATE meta.exchanges
|
||||
SET
|
||||
default_tick_size = 0.01,
|
||||
default_tick_value = 0.01,
|
||||
default_extended_hours = true,
|
||||
country = 'USA'
|
||||
WHERE id = 'NYSE';
|
||||
|
||||
-- Update CME if it exists
|
||||
UPDATE meta.exchanges
|
||||
SET
|
||||
country = 'USA',
|
||||
default_extended_hours = true
|
||||
WHERE id = 'CME';
|
||||
|
||||
-- Add NASDAQ if it doesn't exist
|
||||
INSERT INTO meta.exchanges (
|
||||
id, name, timezone, currency, default_sec_type,
|
||||
default_tick_size, default_tick_value, default_extended_hours, country
|
||||
)
|
||||
SELECT 'NASDAQ', 'NASDAQ Stock Market', 'America/New_York', 'USD', 'STK',
|
||||
0.01, 0.01, true, 'USA'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM meta.exchanges WHERE id = 'NASDAQ');
|
||||
|
||||
-- ============================================================================
|
||||
-- Migration Complete
|
||||
-- ============================================================================
|
||||
|
||||
-- Verify the changes
|
||||
SELECT 'meta.exchanges columns:' as info;
|
||||
SELECT column_name, data_type, character_maximum_length
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'meta' AND table_name = 'exchanges'
|
||||
ORDER BY ordinal_position;
|
||||
|
||||
SELECT 'meta.instruments columns:' as info;
|
||||
SELECT column_name, data_type, character_maximum_length
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'meta' AND table_name = 'instruments'
|
||||
ORDER BY ordinal_position;
|
||||
111
sql/migrate/migrate_metadata_identity.sql
Normal file
111
sql/migrate/migrate_metadata_identity.sql
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
-- Migration: add identity constraints to the series registry and reference tables
|
||||
--
|
||||
-- meta.series had no primary key and no unique constraint, so two rows could
|
||||
-- describe the same series -- and copy_series() actively created that, by
|
||||
-- copying the source's table_id and db_schema. meta.currencies,
|
||||
-- meta.security_types and meta.timezones had no key on their natural
|
||||
-- identifier either, while add_currency()/add_security_type()/add_timezone()
|
||||
-- all catch IntegrityError and promise an "already exists" error that no
|
||||
-- constraint could raise.
|
||||
--
|
||||
-- These are small registries, not timeseries data. A btree key here costs
|
||||
-- almost nothing, and this is unrelated to the deliberate decision NOT to
|
||||
-- constrain series timestamps, where BRIN is used precisely because a btree
|
||||
-- would be prohibitive at millions of rows per series.
|
||||
--
|
||||
-- New databases get these from 04_indexes.sql. Run this against any database
|
||||
-- initialised before the fix.
|
||||
--
|
||||
-- Safe to run more than once: each constraint is added only if absent.
|
||||
--
|
||||
-- IMPORTANT: this ABORTS if duplicate rows already exist, printing what
|
||||
-- collides. It does not guess which row to keep -- that is a data decision.
|
||||
-- Resolve the duplicates, then run it again.
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
dup_count integer;
|
||||
dup_list text;
|
||||
BEGIN
|
||||
----------------------------------------------------------------------
|
||||
-- Pre-flight: refuse to run if any natural key already collides.
|
||||
----------------------------------------------------------------------
|
||||
SELECT count(*), string_agg(format('%s.%s', db_schema, table_name), ', ')
|
||||
INTO dup_count, dup_list
|
||||
FROM (SELECT db_schema, table_name FROM meta.series
|
||||
GROUP BY db_schema, table_name HAVING count(*) > 1) d;
|
||||
IF dup_count > 0 THEN
|
||||
RAISE EXCEPTION
|
||||
'meta.series has % duplicated (db_schema, table_name): %. '
|
||||
'Remove the extra rows, then re-run this migration.',
|
||||
dup_count, dup_list;
|
||||
END IF;
|
||||
|
||||
SELECT count(*), string_agg(table_id::text, ', ')
|
||||
INTO dup_count, dup_list
|
||||
FROM (SELECT table_id FROM meta.series
|
||||
GROUP BY table_id HAVING count(*) > 1) d;
|
||||
IF dup_count > 0 THEN
|
||||
RAISE EXCEPTION
|
||||
'meta.series has % duplicated table_id: %. Most likely created by '
|
||||
'copy_series() before it was fixed. Reassign with '
|
||||
'UPDATE meta.series SET table_id = nextval(''meta._table_meta__table_id_seq'') '
|
||||
'WHERE ... , then re-run this migration.',
|
||||
dup_count, dup_list;
|
||||
END IF;
|
||||
|
||||
SELECT count(*), string_agg(code, ', ')
|
||||
INTO dup_count, dup_list
|
||||
FROM (SELECT code FROM meta.currencies GROUP BY code HAVING count(*) > 1) d;
|
||||
IF dup_count > 0 THEN
|
||||
RAISE EXCEPTION 'meta.currencies has % duplicated code: %', dup_count, dup_list;
|
||||
END IF;
|
||||
|
||||
SELECT count(*), string_agg(code, ', ')
|
||||
INTO dup_count, dup_list
|
||||
FROM (SELECT code FROM meta.security_types GROUP BY code HAVING count(*) > 1) d;
|
||||
IF dup_count > 0 THEN
|
||||
RAISE EXCEPTION 'meta.security_types has % duplicated code: %', dup_count, dup_list;
|
||||
END IF;
|
||||
|
||||
SELECT count(*), string_agg(iana_name, ', ')
|
||||
INTO dup_count, dup_list
|
||||
FROM (SELECT iana_name FROM meta.timezones GROUP BY iana_name HAVING count(*) > 1) d;
|
||||
IF dup_count > 0 THEN
|
||||
RAISE EXCEPTION 'meta.timezones has % duplicated iana_name: %', dup_count, dup_list;
|
||||
END IF;
|
||||
|
||||
----------------------------------------------------------------------
|
||||
-- Add the constraints, skipping any that already exist.
|
||||
----------------------------------------------------------------------
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'series_pkey'
|
||||
AND conrelid = 'meta.series'::regclass) THEN
|
||||
ALTER TABLE meta.series ADD CONSTRAINT series_pkey PRIMARY KEY (table_id);
|
||||
RAISE NOTICE 'added meta.series primary key on (table_id)';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'series_schema_table_key'
|
||||
AND conrelid = 'meta.series'::regclass) THEN
|
||||
ALTER TABLE meta.series ADD CONSTRAINT series_schema_table_key
|
||||
UNIQUE (db_schema, table_name);
|
||||
RAISE NOTICE 'added meta.series unique constraint on (db_schema, table_name)';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'currencies_pkey'
|
||||
AND conrelid = 'meta.currencies'::regclass) THEN
|
||||
ALTER TABLE meta.currencies ADD CONSTRAINT currencies_pkey PRIMARY KEY (code);
|
||||
RAISE NOTICE 'added meta.currencies primary key on (code)';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'security_types_pkey'
|
||||
AND conrelid = 'meta.security_types'::regclass) THEN
|
||||
ALTER TABLE meta.security_types ADD CONSTRAINT security_types_pkey PRIMARY KEY (code);
|
||||
RAISE NOTICE 'added meta.security_types primary key on (code)';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'timezones_pkey'
|
||||
AND conrelid = 'meta.timezones'::regclass) THEN
|
||||
ALTER TABLE meta.timezones ADD CONSTRAINT timezones_pkey PRIMARY KEY (iana_name);
|
||||
RAISE NOTICE 'added meta.timezones primary key on (iana_name)';
|
||||
END IF;
|
||||
END $$;
|
||||
Loading…
Add table
Add a link
Reference in a new issue