blob: e4efa5277bb05b5de11bd1874c99b63c676724f8 [file]
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
-- ============================================
-- 0. Specify the database name
-- (defaults to texera_db)
-- Override the name with:
-- psql -v DB_NAME=<alternative_name> ...
-- ============================================
\if :{?DB_NAME}
\else
\set DB_NAME 'texera_db'
\endif
-- ============================================
-- 1. Drop and recreate the database (psql only)
-- Remove if you already created texera_db
-- ============================================
\c postgres
DROP DATABASE IF EXISTS :"DB_NAME";
CREATE DATABASE :"DB_NAME";
-- ============================================
-- 2. Connect to the new database (psql only)
-- ============================================
\c :"DB_NAME"
CREATE SCHEMA IF NOT EXISTS texera_db;
SET search_path TO texera_db, public;
-- ============================================
-- 3. Drop all tables if they exist
-- (CASCADE handles FK dependencies)
-- ============================================
DROP TABLE IF EXISTS operator_executions CASCADE;
DROP TABLE IF EXISTS operator_port_executions CASCADE;
DROP TABLE IF EXISTS operator_port_cache CASCADE;
DROP TABLE IF EXISTS workflow_user_access CASCADE;
DROP TABLE IF EXISTS workflow_of_user CASCADE;
DROP TABLE IF EXISTS user_config CASCADE;
DROP TABLE IF EXISTS auth_provider CASCADE;
DROP TABLE IF EXISTS "user" CASCADE;
DROP TABLE IF EXISTS user_last_active_time CASCADE;
DROP TABLE IF EXISTS workflow CASCADE;
DROP TABLE IF EXISTS workflow_version CASCADE;
DROP TABLE IF EXISTS project CASCADE;
DROP TABLE IF EXISTS workflow_of_project CASCADE;
DROP TABLE IF EXISTS workflow_executions CASCADE;
DROP TABLE IF EXISTS dataset_upload_session CASCADE;
DROP TABLE IF EXISTS dataset_upload_session_part CASCADE;
DROP TABLE IF EXISTS dataset CASCADE;
DROP TABLE IF EXISTS dataset_user_access CASCADE;
DROP TABLE IF EXISTS dataset_version CASCADE;
DROP TABLE IF EXISTS model_upload_session CASCADE;
DROP TABLE IF EXISTS model_upload_session_part CASCADE;
DROP TABLE IF EXISTS model_user_access CASCADE;
DROP TABLE IF EXISTS model_version CASCADE;
DROP TABLE IF EXISTS model CASCADE;
DROP TABLE IF EXISTS dataset_contributor CASCADE;
DROP TABLE IF EXISTS public_project CASCADE;
DROP TABLE IF EXISTS project_user_access CASCADE;
DROP TABLE IF EXISTS workflow_user_likes CASCADE;
DROP TABLE IF EXISTS workflow_user_clones CASCADE;
DROP TABLE IF EXISTS workflow_view_count CASCADE;
DROP TABLE IF EXISTS user_action CASCADE;
DROP TABLE IF EXISTS dataset_user_likes CASCADE;
DROP TABLE IF EXISTS dataset_view_count CASCADE;
DROP TABLE IF EXISTS site_settings CASCADE;
DROP TABLE IF EXISTS computing_unit_user_access CASCADE;
DROP TABLE IF EXISTS notebook CASCADE;
DROP TABLE IF EXISTS workflow_notebook_mapping CASCADE;
DROP TABLE IF EXISTS virtual_environments CASCADE;
-- ============================================
-- 4. Create PostgreSQL enum types
-- to mimic MySQL ENUM fields
-- ============================================
DROP TYPE IF EXISTS user_role_enum CASCADE;
DROP TYPE IF EXISTS privilege_enum CASCADE;
DROP TYPE IF EXISTS action_enum CASCADE;
DROP TYPE IF EXISTS provider_type_enum CASCADE;
DROP TYPE IF EXISTS default_view_enum CASCADE;
CREATE TYPE user_role_enum AS ENUM ('INACTIVE', 'RESTRICTED', 'REGULAR', 'ADMIN');
CREATE TYPE action_enum AS ENUM ('like', 'unlike', 'view', 'clone');
CREATE TYPE privilege_enum AS ENUM ('NONE', 'READ', 'WRITE');
CREATE TYPE workflow_computing_unit_type_enum AS ENUM ('local', 'kubernetes');
CREATE TYPE provider_type_enum AS ENUM ('LOCAL', 'GOOGLE');
CREATE TYPE user_warehouse_flavor_enum AS ENUM ('local', 'aws');
CREATE TYPE default_view_enum AS ENUM ('CANVAS', 'FORM');
-- ============================================
-- 5. Create tables
-- ============================================
-- "user" table
CREATE TABLE IF NOT EXISTS "user"
(
uid SERIAL PRIMARY KEY,
name VARCHAR(256) NOT NULL,
email VARCHAR(256) UNIQUE,
avatar VARCHAR(512),
role user_role_enum NOT NULL DEFAULT 'INACTIVE',
comment TEXT,
account_creation_time TIMESTAMPTZ NOT NULL DEFAULT now(),
affiliation VARCHAR(128),
joining_reason VARCHAR(500),
-- placeholder accounts are auto-created for dataset contributors and carry no credentials until claimed
is_placeholder BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE TABLE IF NOT EXISTS auth_provider
(
uid INT NOT NULL,
provider_type provider_type_enum NOT NULL,
provider_id VARCHAR(256) NOT NULL,
password VARCHAR(256), -- hashed credential; only for LOCAL
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (uid, provider_type),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
CONSTRAINT uq_provider_identity UNIQUE (provider_type, provider_id),
CONSTRAINT ck_provider_credential CHECK ((provider_type = 'LOCAL') = (password IS NOT NULL))
);
-- Contributor emails are resolved with lower(email) lookups.
CREATE INDEX idx_user_email_lower ON "user" (lower(email));
-- user_config
CREATE TABLE IF NOT EXISTS user_config
(
uid INT NOT NULL,
key VARCHAR(256) NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (uid, key),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE
);
-- feedback
CREATE TABLE IF NOT EXISTS feedback
(
fid SERIAL PRIMARY KEY,
uid INT NOT NULL,
message TEXT NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE
);
-- workflow
CREATE TABLE IF NOT EXISTS workflow
(
wid SERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
description TEXT,
content TEXT NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_modified_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
is_public BOOLEAN NOT NULL DEFAULT false,
-- Which view the workflow opens in by default (CANVAS or FORM); the form's definition
-- lives in workflow.content (`formBinding`).
default_view default_view_enum NOT NULL DEFAULT 'CANVAS'
);
-- workflow_of_user
CREATE TABLE IF NOT EXISTS workflow_of_user
(
uid INT NOT NULL,
wid INT NOT NULL,
PRIMARY KEY (uid, wid),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- workflow_user_access
CREATE TABLE IF NOT EXISTS workflow_user_access
(
uid INT NOT NULL,
wid INT NOT NULL,
privilege privilege_enum NOT NULL DEFAULT 'NONE',
PRIMARY KEY (uid, wid),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- workflow_version
CREATE TABLE IF NOT EXISTS workflow_version
(
vid SERIAL PRIMARY KEY,
wid INT NOT NULL,
content TEXT NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- workflow_cover_image (optional custom card cover image, stored as a downscaled data URL)
CREATE TABLE IF NOT EXISTS workflow_cover_image
(
wid INT PRIMARY KEY,
image TEXT NOT NULL,
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- project
CREATE TABLE IF NOT EXISTS project
(
pid SERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
description VARCHAR(10000),
owner_id INT NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
color VARCHAR(6),
UNIQUE (owner_id, name),
FOREIGN KEY (owner_id) REFERENCES "user"(uid) ON DELETE CASCADE
);
-- workflow_of_project
CREATE TABLE IF NOT EXISTS workflow_of_project
(
wid INT NOT NULL,
pid INT NOT NULL,
PRIMARY KEY (wid, pid),
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE,
FOREIGN KEY (pid) REFERENCES project(pid) ON DELETE CASCADE
);
-- project_user_access
CREATE TABLE IF NOT EXISTS project_user_access
(
uid INT NOT NULL,
pid INT NOT NULL,
privilege privilege_enum NOT NULL DEFAULT 'NONE',
PRIMARY KEY (uid, pid),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
FOREIGN KEY (pid) REFERENCES project(pid) ON DELETE CASCADE
);
-- workflow_computing_unit table
CREATE TABLE IF NOT EXISTS workflow_computing_unit
(
uid INT NOT NULL,
name VARCHAR(128) NOT NULL,
cuid SERIAL PRIMARY KEY,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
terminate_time TIMESTAMP DEFAULT NULL,
type workflow_computing_unit_type_enum,
uri TEXT NOT NULL DEFAULT '',
resource TEXT DEFAULT '',
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE
);
-- Per-user warehouse registrations (#6870): one row per warehouse a user registered.
-- Base columns only; the assume-role (BYO-S3) columns come in a later change.
CREATE TABLE IF NOT EXISTS user_warehouse
(
whid SERIAL PRIMARY KEY,
uid INT NOT NULL,
name VARCHAR(128) NOT NULL,
lakekeeper_warehouse_name VARCHAR(255) NOT NULL UNIQUE,
lakekeeper_warehouse_id UUID NOT NULL,
flavor user_warehouse_flavor_enum NOT NULL,
s3_bucket VARCHAR(255),
s3_endpoint VARCHAR(255),
s3_region VARCHAR(64),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (uid, name),
FOREIGN KEY (uid) REFERENCES "user" (uid) ON DELETE CASCADE
);
-- virtual_environments table
CREATE TABLE IF NOT EXISTS virtual_environments
(
veid SERIAL PRIMARY KEY,
uid INT NOT NULL,
name VARCHAR(128) NOT NULL,
packages JSONB NOT NULL DEFAULT '{}'::jsonb,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
UNIQUE (uid, name)
);
-- workflow_executions
CREATE TABLE IF NOT EXISTS workflow_executions
(
eid SERIAL PRIMARY KEY,
vid INT NOT NULL,
uid INT NOT NULL,
cuid INT,
status SMALLINT NOT NULL DEFAULT 1,
result TEXT,
starting_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_update_time TIMESTAMP,
bookmarked BOOLEAN DEFAULT FALSE,
name VARCHAR(128) NOT NULL DEFAULT 'Untitled Execution',
environment_version VARCHAR(128) NOT NULL,
log_location TEXT,
runtime_stats_uri TEXT,
runtime_stats_size BIGINT DEFAULT 0,
whid INT,
FOREIGN KEY (vid) REFERENCES workflow_version(vid) ON DELETE CASCADE,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
FOREIGN KEY (cuid) REFERENCES workflow_computing_unit(cuid) ON DELETE CASCADE,
FOREIGN KEY (whid) REFERENCES user_warehouse(whid) ON DELETE SET NULL
);
-- public_project
CREATE TABLE IF NOT EXISTS public_project
(
pid INT PRIMARY KEY,
uid INT,
FOREIGN KEY (pid) REFERENCES project(pid) ON DELETE CASCADE
-- Note: MySQL schema doesn't define a foreign key for uid
);
-- dataset
CREATE TABLE IF NOT EXISTS dataset
(
did SERIAL PRIMARY KEY,
owner_uid INT NOT NULL,
name VARCHAR(128) NOT NULL,
repository_name VARCHAR(128),
is_public BOOLEAN NOT NULL DEFAULT TRUE,
is_downloadable BOOLEAN NOT NULL DEFAULT TRUE,
description TEXT NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
cover_image varchar(255),
FOREIGN KEY (owner_uid) REFERENCES "user"(uid) ON DELETE CASCADE,
UNIQUE (owner_uid, name)
);
-- dataset_user_access
CREATE TABLE IF NOT EXISTS dataset_user_access
(
did INT NOT NULL,
uid INT NOT NULL,
privilege privilege_enum NOT NULL DEFAULT 'NONE',
PRIMARY KEY (did, uid),
FOREIGN KEY (did) REFERENCES dataset(did) ON DELETE CASCADE,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE
);
-- dataset_version
CREATE TABLE IF NOT EXISTS dataset_version
(
dvid SERIAL PRIMARY KEY,
did INT NOT NULL,
creator_uid INT NOT NULL,
name VARCHAR(128) NOT NULL,
version_hash VARCHAR(64) NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (did) REFERENCES dataset(did) ON DELETE CASCADE
);
-- dataset_contributor
CREATE TABLE IF NOT EXISTS dataset_contributor
(
cid SERIAL PRIMARY KEY,
did INT NOT NULL,
name VARCHAR(256) NOT NULL,
creator BOOLEAN NOT NULL DEFAULT FALSE,
email VARCHAR(256),
affiliation VARCHAR(256),
comments TEXT,
uid INT,
FOREIGN KEY (did) REFERENCES dataset(did) ON DELETE CASCADE,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE SET NULL
);
-- Per-dataset contributor emails are unique (blank emails exempt).
CREATE UNIQUE INDEX idx_dataset_contributor_did_email
ON dataset_contributor (did, lower(trim(email)))
WHERE email IS NOT NULL AND trim(email) <> '';
CREATE TABLE IF NOT EXISTS dataset_upload_session
(
did INT NOT NULL,
uid INT NOT NULL,
file_path TEXT NOT NULL,
upload_id VARCHAR(256) NOT NULL UNIQUE,
physical_address TEXT,
num_parts_requested INT NOT NULL,
file_size_bytes BIGINT NOT NULL,
part_size_bytes BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (uid, did, file_path),
FOREIGN KEY (did) REFERENCES dataset(did) ON DELETE CASCADE,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
CONSTRAINT chk_dataset_upload_session_num_parts_requested_positive
CHECK (num_parts_requested >= 1),
CONSTRAINT chk_dataset_upload_session_file_size_bytes_positive
CHECK (file_size_bytes > 0),
CONSTRAINT chk_dataset_upload_session_part_size_bytes_positive
CHECK (part_size_bytes > 0),
CONSTRAINT chk_dataset_upload_session_part_size_bytes_s3_upper_bound
CHECK (part_size_bytes <= 5368709120)
);
CREATE TABLE IF NOT EXISTS dataset_upload_session_part
(
upload_id VARCHAR(256) NOT NULL,
part_number INT NOT NULL,
etag TEXT NOT NULL DEFAULT '',
PRIMARY KEY (upload_id, part_number),
CONSTRAINT chk_part_number_positive CHECK (part_number > 0),
FOREIGN KEY (upload_id)
REFERENCES dataset_upload_session(upload_id)
ON DELETE CASCADE
);
-- ML models
CREATE TABLE IF NOT EXISTS model
(
mid SERIAL PRIMARY KEY,
owner_uid INT NOT NULL,
name VARCHAR(128) NOT NULL,
repository_name VARCHAR(128),
is_public BOOLEAN NOT NULL DEFAULT TRUE,
is_downloadable BOOLEAN NOT NULL DEFAULT TRUE,
description TEXT NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
cover_image varchar(255),
framework VARCHAR(32),
format VARCHAR(32),
FOREIGN KEY (owner_uid) REFERENCES "user"(uid) ON DELETE CASCADE,
UNIQUE (owner_uid, name)
);
-- model_version
CREATE TABLE IF NOT EXISTS model_version
(
mvid SERIAL PRIMARY KEY,
mid INT NOT NULL,
creator_uid INT NOT NULL,
name VARCHAR(128) NOT NULL,
version_hash VARCHAR(64) NOT NULL,
creation_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (mid) REFERENCES model(mid) ON DELETE CASCADE,
-- FileResolver resolves a version by (mid, name) with fetchOneInto.
CONSTRAINT uq_model_version_mid_name UNIQUE (mid, name)
);
-- model_user_access
CREATE TABLE IF NOT EXISTS model_user_access
(
mid INT NOT NULL,
uid INT NOT NULL,
privilege privilege_enum NOT NULL DEFAULT 'NONE',
PRIMARY KEY (mid, uid),
FOREIGN KEY (mid) REFERENCES model(mid) ON DELETE CASCADE,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE
);
-- model_upload_session
CREATE TABLE IF NOT EXISTS model_upload_session
(
mid INT NOT NULL,
uid INT NOT NULL,
file_path TEXT NOT NULL,
upload_id VARCHAR(256) NOT NULL UNIQUE,
physical_address TEXT,
num_parts_requested INT NOT NULL,
file_size_bytes BIGINT NOT NULL,
part_size_bytes BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (uid, mid, file_path),
FOREIGN KEY (mid) REFERENCES model(mid) ON DELETE CASCADE,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
CONSTRAINT chk_model_upload_session_num_parts_requested_positive
CHECK (num_parts_requested >= 1),
CONSTRAINT chk_model_upload_session_file_size_bytes_positive
CHECK (file_size_bytes > 0),
CONSTRAINT chk_model_upload_session_part_size_bytes_positive
CHECK (part_size_bytes > 0),
CONSTRAINT chk_model_upload_session_part_size_bytes_s3_upper_bound
CHECK (part_size_bytes <= 5368709120)
);
-- model_upload_session_part
CREATE TABLE IF NOT EXISTS model_upload_session_part
(
upload_id VARCHAR(256) NOT NULL,
part_number INT NOT NULL,
etag TEXT NOT NULL DEFAULT '',
PRIMARY KEY (upload_id, part_number),
CONSTRAINT chk_model_part_number_positive CHECK (part_number > 0),
FOREIGN KEY (upload_id)
REFERENCES model_upload_session(upload_id)
ON DELETE CASCADE
);
-- operator_executions (modified to match MySQL: no separate primary key; added console_messages_uri)
CREATE TABLE IF NOT EXISTS operator_executions
(
workflow_execution_id INT NOT NULL,
operator_id VARCHAR(100) NOT NULL,
console_messages_uri TEXT,
console_messages_size BIGINT DEFAULT 0,
PRIMARY KEY (workflow_execution_id, operator_id),
FOREIGN KEY (workflow_execution_id) REFERENCES workflow_executions(eid) ON DELETE CASCADE
);
-- operator_port_executions
CREATE TABLE operator_port_executions
(
workflow_execution_id INT NOT NULL,
global_port_id VARCHAR(200) NOT NULL,
result_uri TEXT,
result_size BIGINT DEFAULT 0,
PRIMARY KEY (workflow_execution_id, global_port_id),
FOREIGN KEY (workflow_execution_id) REFERENCES workflow_executions(eid) ON DELETE CASCADE
);
-- operator_port_cache
-- Caches a materialized output port result so it can be reused across executions.
-- A row is identified by (workflow_id, global_port_id, cache_key_hash), where
-- cache_key_hash is a SHA-256 hash of the upstream sub-DAG that produces the port (its
-- operators, their parameters and exec info, schemas, and wiring). cache_key_hash is the
-- lookup key; cache_key_json is the JSON the hash was computed from, kept so a hash match
-- can be confirmed against the full content (collision safety). A different upstream
-- computation (for example an operator parameter or version change) produces a different
-- cache_key_hash and therefore a new row, so existing entries are never overwritten: each
-- row is the result of one specific computation of one port. tuple_count is the result's
-- row count, kept so the coordinator can report a reused region's output stats without a
-- second query to the Iceberg catalog.
CREATE TABLE operator_port_cache
(
workflow_id INT NOT NULL,
global_port_id VARCHAR(200) NOT NULL,
cache_key_hash CHAR(64) NOT NULL,
cache_key_json TEXT NOT NULL,
storage_uri TEXT NOT NULL,
tuple_count BIGINT,
source_execution_id BIGINT,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (workflow_id, global_port_id, cache_key_hash),
FOREIGN KEY (workflow_id) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- workflow_user_likes
CREATE TABLE IF NOT EXISTS workflow_user_likes
(
uid INT NOT NULL,
wid INT NOT NULL,
PRIMARY KEY (uid, wid),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- workflow_user_clones
CREATE TABLE IF NOT EXISTS workflow_user_clones
(
uid INT NOT NULL,
wid INT NOT NULL,
PRIMARY KEY (uid, wid),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- workflow_view_count
CREATE TABLE IF NOT EXISTS workflow_view_count
(
wid INT NOT NULL PRIMARY KEY,
view_count INT NOT NULL DEFAULT 0,
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- user_action table
CREATE TABLE IF NOT EXISTS user_action (
user_action_id BIGSERIAL PRIMARY KEY,
uid INTEGER,
ip VARCHAR(15),
action_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
resource_type VARCHAR(15) NOT NULL,
resource_id INTEGER NOT NULL,
action texera_db.action_enum NOT NULL,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE SET NULL
);
-- dataset_user_likes table
CREATE TABLE IF NOT EXISTS dataset_user_likes
(
uid INTEGER NOT NULL,
did INTEGER NOT NULL,
PRIMARY KEY (uid, did),
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE,
FOREIGN KEY (did) REFERENCES dataset(did) ON DELETE CASCADE
);
-- dataset_view_count table
CREATE TABLE IF NOT EXISTS dataset_view_count
(
did INTEGER NOT NULL,
view_count INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (did),
FOREIGN KEY (did) REFERENCES dataset(did) ON DELETE CASCADE
);
-- site_settings table
CREATE TABLE IF NOT EXISTS site_settings
(
key VARCHAR(255) PRIMARY KEY,
value TEXT NOT NULL,
updated_by VARCHAR(50),
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- user_last_active_time table
CREATE TABLE IF NOT EXISTS user_last_active_time
(
uid INT NOT NULL
PRIMARY KEY
REFERENCES "user"(uid),
last_active_time TIMESTAMPTZ
);
-- computing_unit_user_access table
CREATE TABLE IF NOT EXISTS computing_unit_user_access
(
cuid INT NOT NULL,
uid INT NOT NULL,
privilege privilege_enum NOT NULL DEFAULT 'NONE',
PRIMARY KEY (cuid, uid),
FOREIGN KEY (cuid) REFERENCES workflow_computing_unit(cuid) ON DELETE CASCADE,
FOREIGN KEY (uid) REFERENCES "user"(uid) ON DELETE CASCADE
);
-- notebook table
CREATE TABLE IF NOT EXISTS notebook
(
nid SERIAL NOT NULL PRIMARY KEY,
wid INT NOT NULL UNIQUE,
notebook JSONB NOT NULL,
UNIQUE (wid, nid),
FOREIGN KEY (wid) REFERENCES workflow(wid) ON DELETE CASCADE
);
-- workflow_notebook_mapping table
CREATE TABLE IF NOT EXISTS workflow_notebook_mapping
(
wid INT NOT NULL,
vid INT NOT NULL,
nid INT NOT NULL,
mapping JSONB NOT NULL,
PRIMARY KEY (wid, vid, nid),
FOREIGN KEY (vid) REFERENCES workflow_version(vid) ON DELETE CASCADE,
FOREIGN KEY (wid, nid) REFERENCES notebook(wid, nid) ON DELETE CASCADE
);
-- START Fulltext search index creation (DO NOT EDIT THIS LINE)
CREATE EXTENSION IF NOT EXISTS pgroonga;
DO $$
DECLARE
r RECORD;
stem_filter TEXT := '';
plugin_status TEXT;
BEGIN
-- Drop all GIN and PGroonga indexes
FOR r IN
SELECT indexname FROM pg_indexes
WHERE (indexdef ILIKE '%USING gin%' OR indexdef ILIKE '%USING pgroonga%')
AND tablename IN ('workflow', 'user', 'project', 'dataset', 'dataset_version')
LOOP
EXECUTE format('DROP INDEX IF EXISTS %I;', r.indexname);
END LOOP;
-- Check if TokenFilterStem plugin is registered
WITH plugin_registration AS (
SELECT pgroonga_command('plugin_register token_filters/stem') AS result
)
SELECT
CASE
WHEN result::jsonb @> '[true]' THEN 'Plugin registered successfully'
ELSE 'Plugin registration failed'
END INTO plugin_status
FROM plugin_registration;
-- Set the stem_filter based on plugin status
IF plugin_status = 'Plugin registered successfully' THEN
stem_filter := ', plugins=''token_filters/stem'', token_filters=''TokenFilterStem''';
RAISE NOTICE 'Using TokenMecab + TokenFilterStem';
ELSE
RAISE NOTICE 'Using TokenMecab only';
END IF;
-- Create PGroonga indexes dynamically with correct TokenFilterStem usage
FOR r IN
SELECT tablename,
CASE
WHEN tablename = 'workflow' THEN
'(COALESCE(name, '''') || '' '' || COALESCE(description, '''') || '' '' || COALESCE(content, ''''))'
WHEN tablename IN ('project', 'dataset') THEN
'(COALESCE(name, '''') || '' '' || COALESCE(description, ''''))'
ELSE
'COALESCE(name, '''')'
END AS index_column
FROM (VALUES ('workflow'), ('user'), ('project'), ('dataset'), ('dataset_version')) AS t(tablename)
LOOP
-- Create PGroonga index with proper TokenFilterStem usage
EXECUTE format(
'CREATE INDEX idx_%s_pgroonga ON %I USING pgroonga (%s) WITH (tokenizer = ''TokenMecab''%s);',
r.tablename, r.tablename, r.index_column, stem_filter
);
END LOOP;
END $$;
-- END Fulltext search index creation (DO NOT EDIT THIS LINE)