Skip to content

Commit 7708630

Browse files
authored
ensure column does not exist before adding it (#649)
* ensure column does not exist before adding it * full idempotency for mk20 sql
1 parent a144b95 commit 7708630

File tree

1 file changed

+142
-52
lines changed

1 file changed

+142
-52
lines changed

harmony/harmonydb/sql/20250505-market-mk20.sql

Lines changed: 142 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,147 @@
11
-- Add raw_size column to mk12 deals to calculate pieceCidV2
2-
ALTER TABLE market_mk12_deals
3-
ADD COLUMN raw_size BIGINT;
2+
DO $$
3+
BEGIN
4+
IF NOT EXISTS (
5+
SELECT 1 FROM information_schema.columns
6+
WHERE table_name = 'market_mk12_deals'
7+
AND column_name = 'raw_size'
8+
) THEN
9+
ALTER TABLE market_mk12_deals ADD COLUMN raw_size BIGINT;
10+
END IF;
11+
END $$;
412

513
-- Add raw_size column to mk12-ddo deals to calculate pieceCidV2
6-
ALTER TABLE market_direct_deals
7-
ADD COLUMN raw_size BIGINT;
14+
DO $$
15+
BEGIN
16+
IF NOT EXISTS (
17+
SELECT 1 FROM information_schema.columns
18+
WHERE table_name = 'market_direct_deals'
19+
AND column_name = 'raw_size'
20+
) THEN
21+
ALTER TABLE market_direct_deals ADD COLUMN raw_size BIGINT;
22+
END IF;
23+
END $$;
824

925
-- Drop the existing primary key constraint for market_piece_metadata
1026
ALTER TABLE market_piece_metadata
11-
DROP CONSTRAINT market_piece_metadata_pkey;
27+
DROP CONSTRAINT IF EXISTS market_piece_metadata_pkey;
1228

1329
-- Drop the redundant UNIQUE constraint if it exists for market_piece_metadata
1430
ALTER TABLE market_piece_metadata
1531
DROP CONSTRAINT IF EXISTS market_piece_meta_identity_key;
1632

1733
-- Add the new composite primary key for market_piece_metadata
18-
ALTER TABLE market_piece_metadata
19-
ADD PRIMARY KEY (piece_cid, piece_size);
34+
DO $$
35+
BEGIN
36+
IF NOT EXISTS (
37+
SELECT 1 FROM information_schema.table_constraints
38+
WHERE table_name = 'market_piece_metadata'
39+
AND constraint_type = 'PRIMARY KEY'
40+
) THEN
41+
ALTER TABLE market_piece_metadata ADD PRIMARY KEY (piece_cid, piece_size);
42+
END IF;
43+
END $$;
2044

2145
-- Drop the current primary key for market_piece_deal
2246
ALTER TABLE market_piece_deal
23-
DROP CONSTRAINT market_piece_deal_pkey;
47+
DROP CONSTRAINT IF EXISTS market_piece_deal_pkey;
2448

2549
-- Drop the old UNIQUE constraint for market_piece_deal
2650
ALTER TABLE market_piece_deal
2751
DROP CONSTRAINT IF EXISTS market_piece_deal_identity_key;
2852

2953
-- Add the new composite primary key for market_piece_deal
30-
ALTER TABLE market_piece_deal
31-
ADD PRIMARY KEY (id, sp_id, piece_cid, piece_length);
54+
DO $$
55+
BEGIN
56+
IF NOT EXISTS (
57+
SELECT 1 FROM information_schema.table_constraints
58+
WHERE table_name = 'market_piece_deal'
59+
AND constraint_type = 'PRIMARY KEY'
60+
) THEN
61+
ALTER TABLE market_piece_deal ADD PRIMARY KEY (id, sp_id, piece_cid, piece_length);
62+
END IF;
63+
END $$;
3264

3365
-- Add a column to relate a piece park piece to mk20 deal
34-
ALTER TABLE market_piece_deal
35-
ADD COLUMN piece_ref BIGINT;
66+
DO $$
67+
BEGIN
68+
IF NOT EXISTS (
69+
SELECT 1 FROM information_schema.columns
70+
WHERE table_name = 'market_piece_deal'
71+
AND column_name = 'piece_ref'
72+
) THEN
73+
ALTER TABLE market_piece_deal ADD COLUMN piece_ref BIGINT;
74+
END IF;
75+
END $$;
3676

3777
-- Allow piece_offset to be null for PDP deals
3878
ALTER TABLE market_piece_deal
3979
ALTER COLUMN piece_offset DROP NOT NULL;
4080

4181
-- Add column to skip scheduling piece_park. Used for upload pieces
42-
ALTER TABLE parked_pieces
43-
ADD COLUMN skip BOOLEAN NOT NULL DEFAULT FALSE;
82+
DO $$
83+
BEGIN
84+
IF NOT EXISTS (
85+
SELECT 1 FROM information_schema.columns
86+
WHERE table_name = 'parked_pieces'
87+
AND column_name = 'skip'
88+
) THEN
89+
ALTER TABLE parked_pieces ADD COLUMN skip BOOLEAN NOT NULL DEFAULT FALSE;
90+
END IF;
91+
END $$;
4492

4593
-- Add column piece_cid_v2 to IPNI table
46-
ALTER TABLE ipni
47-
ADD COLUMN piece_cid_v2 TEXT;
94+
DO $$
95+
BEGIN
96+
IF NOT EXISTS (
97+
SELECT 1 FROM information_schema.columns
98+
WHERE table_name = 'ipni'
99+
AND column_name = 'piece_cid_v2'
100+
) THEN
101+
ALTER TABLE ipni ADD COLUMN piece_cid_v2 TEXT;
102+
END IF;
103+
END $$;
48104

49105
-- Add metadata column to IPNI table which defaults to the binary of IpfsGatewayHttp
50-
ALTER TABLE ipni
51-
ADD COLUMN metadata BYTEA NOT NULL DEFAULT '\xa01200';
106+
DO $$
107+
BEGIN
108+
IF NOT EXISTS (
109+
SELECT 1 FROM information_schema.columns
110+
WHERE table_name = 'ipni'
111+
AND column_name = 'metadata'
112+
) THEN
113+
ALTER TABLE ipni ADD COLUMN metadata BYTEA NOT NULL DEFAULT '\xa01200';
114+
END IF;
115+
END $$;
52116

53117
-- Add is_pdp column to the table to allow generating 2 sets of chunks per
54118
-- piece cid. One for Payloads and another one for single CID chunks to announce a PDP piece.
55-
ALTER TABLE ipni_chunks
56-
ADD COLUMN is_pdp BOOLEAN NOT NULL DEFAULT FALSE;
119+
DO $$
120+
BEGIN
121+
IF NOT EXISTS (
122+
SELECT 1 FROM information_schema.columns
123+
WHERE table_name = 'ipni_chunks'
124+
AND column_name = 'is_pdp'
125+
) THEN
126+
ALTER TABLE ipni_chunks ADD COLUMN is_pdp BOOLEAN NOT NULL DEFAULT FALSE;
127+
END IF;
128+
END $$;
57129

58130
-- Replace the old uniqueness (piece_cid, chunk_num) with the new one
59131
ALTER TABLE ipni_chunks
60-
DROP CONSTRAINT ipni_chunks_piece_cid_chunk_num_key;
132+
DROP CONSTRAINT IF EXISTS ipni_chunks_piece_cid_chunk_num_key;
61133

62-
ALTER TABLE ipni_chunks
63-
ADD CONSTRAINT ipni_chunks_piece_cid_is_pdp_chunk_num_key
64-
UNIQUE (piece_cid, is_pdp, chunk_num);
134+
DO $$
135+
BEGIN
136+
IF NOT EXISTS (
137+
SELECT 1 FROM information_schema.table_constraints
138+
WHERE table_name = 'ipni_chunks'
139+
AND constraint_name = 'ipni_chunks_piece_cid_is_pdp_chunk_num_key'
140+
) THEN
141+
ALTER TABLE ipni_chunks ADD CONSTRAINT ipni_chunks_piece_cid_is_pdp_chunk_num_key
142+
UNIQUE (piece_cid, is_pdp, chunk_num);
143+
END IF;
144+
END $$;
65145

66146
-- The order_number column must be completely sequential
67147
ALTER SEQUENCE ipni_order_number_seq CACHE 1;
@@ -106,8 +186,16 @@ END;
106186
$$ LANGUAGE plpgsql;
107187

108188
-- Add ID column to ipni_task table
109-
ALTER TABLE ipni_task
110-
ADD COLUMN id TEXT;
189+
DO $$
190+
BEGIN
191+
IF NOT EXISTS (
192+
SELECT 1 FROM information_schema.columns
193+
WHERE table_name = 'ipni_task'
194+
AND column_name = 'id'
195+
) THEN
196+
ALTER TABLE ipni_task ADD COLUMN id TEXT;
197+
END IF;
198+
END $$;
111199

112200
-- Function to create ipni tasks
113201
CREATE OR REPLACE FUNCTION insert_ipni_task(
@@ -186,7 +274,7 @@ COMMIT;
186274

187275
-- This is main MK20 Deal table. Rows are added per deal and some
188276
-- modification is allowed later
189-
CREATE TABLE market_mk20_deal (
277+
CREATE TABLE IF NOT EXISTS market_mk20_deal (
190278
created_at TIMESTAMPTZ NOT NULL DEFAULT TIMEZONE('UTC', NOW()),
191279
id TEXT PRIMARY KEY,
192280
client TEXT NOT NULL,
@@ -203,7 +291,7 @@ COMMENT ON COLUMN market_mk20_deal.id IS 'This is ULID TEXT';
203291
COMMENT ON COLUMN market_mk20_deal.client IS 'Client must always be text as this can be a non Filecoin address like ed25519';
204292

205293
-- This is main pipeline table for PoRep processing of MK20 deals
206-
CREATE TABLE market_mk20_pipeline (
294+
CREATE TABLE IF NOT EXISTS market_mk20_pipeline (
207295
created_at TIMESTAMPTZ NOT NULL DEFAULT TIMEZONE('UTC', NOW()),
208296
id TEXT NOT NULL,
209297
sp_id BIGINT NOT NULL,
@@ -253,13 +341,13 @@ COMMENT ON COLUMN market_mk20_pipeline.deal_aggregation IS 'This is set when use
253341
-- This table is used to hold MK20 deals waiting for PoRep pipeline
254342
-- to process. This allows disconnecting the need to immediately process
255343
-- deals as received and allow upload later strategy to work
256-
CREATE TABLE market_mk20_pipeline_waiting (
344+
CREATE TABLE IF NOT EXISTS market_mk20_pipeline_waiting (
257345
id TEXT PRIMARY KEY
258346
);
259347

260348
-- This table is used to keep track of deals which need data upload.
261349
-- A separate table helps easier status check, chunked+serial upload support
262-
CREATE TABLE market_mk20_upload_waiting (
350+
CREATE TABLE IF NOT EXISTS market_mk20_upload_waiting (
263351
id TEXT PRIMARY KEY,
264352
chunked BOOLEAN DEFAULT NULL,
265353
ref_id BIGINT DEFAULT NULL,
@@ -270,7 +358,7 @@ CREATE TABLE market_mk20_upload_waiting (
270358
-- It helps with allowing multiple downloads per deal i.e. server side aggregation.
271359
-- This also allows us to reuse ongoing downloads within the same deal aggregation.
272360
-- It also allows using a common download pipeline for both PoRep and PDP.
273-
CREATE TABLE market_mk20_download_pipeline (
361+
CREATE TABLE IF NOT EXISTS market_mk20_download_pipeline (
274362
id TEXT NOT NULL,
275363
product TEXT NOT NULL, -- This allows us to run multiple refs per product for easier lifecycle management
276364
piece_cid_v2 TEXT NOT NULL,
@@ -279,7 +367,7 @@ CREATE TABLE market_mk20_download_pipeline (
279367
);
280368

281369
-- Offline URLs for PoRep deals.
282-
CREATE TABLE market_mk20_offline_urls (
370+
CREATE TABLE IF NOT EXISTS market_mk20_offline_urls (
283371
id TEXT NOT NULL,
284372
piece_cid_v2 TEXT NOT NULL,
285373
url TEXT NOT NULL,
@@ -289,7 +377,7 @@ CREATE TABLE market_mk20_offline_urls (
289377

290378
-- This table tracks the chunk upload progress for a MK20 deal. Common for both
291379
-- PoRep and PDP
292-
CREATE TABLE market_mk20_deal_chunk (
380+
CREATE TABLE IF NOT EXISTS market_mk20_deal_chunk (
293381
id TEXT not null,
294382
chunk INT not null,
295383
chunk_size BIGINT not null,
@@ -302,25 +390,25 @@ CREATE TABLE market_mk20_deal_chunk (
302390
);
303391

304392
-- MK20 product and their status table
305-
CREATE TABLE market_mk20_products (
393+
CREATE TABLE IF NOT EXISTS market_mk20_products (
306394
name TEXT PRIMARY KEY,
307395
enabled BOOLEAN DEFAULT TRUE
308396
);
309397

310398
-- MK20 supported data sources and their status table
311-
CREATE TABLE market_mk20_data_source (
399+
CREATE TABLE IF NOT EXISTS market_mk20_data_source (
312400
name TEXT PRIMARY KEY,
313401
enabled BOOLEAN DEFAULT TRUE
314402
);
315403

316404
-- Add products and data sources to table
317-
INSERT INTO market_mk20_products (name, enabled) VALUES ('ddo_v1', TRUE);
318-
INSERT INTO market_mk20_products (name, enabled) VALUES ('retrieval_v1', TRUE);
319-
INSERT INTO market_mk20_products (name, enabled) VALUES ('pdp_v1', TRUE);
320-
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('http', TRUE);
321-
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('aggregate', TRUE);
322-
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('offline', TRUE);
323-
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('put', TRUE);
405+
INSERT INTO market_mk20_products (name, enabled) VALUES ('ddo_v1', TRUE) ON CONFLICT (name) DO NOTHING;
406+
INSERT INTO market_mk20_products (name, enabled) VALUES ('retrieval_v1', TRUE) ON CONFLICT (name) DO NOTHING;
407+
INSERT INTO market_mk20_products (name, enabled) VALUES ('pdp_v1', TRUE) ON CONFLICT (name) DO NOTHING;
408+
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('http', TRUE) ON CONFLICT (name) DO NOTHING;
409+
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('aggregate', TRUE) ON CONFLICT (name) DO NOTHING;
410+
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('offline', TRUE) ON CONFLICT (name) DO NOTHING;
411+
INSERT INTO market_mk20_data_source (name, enabled) VALUES ('put', TRUE) ON CONFLICT (name) DO NOTHING;
324412

325413
-- This function sets an upload completion time. It is used to removed
326414
-- upload for deal which are not finalized in 1 hour so we don't waste space.
@@ -339,6 +427,7 @@ BEGIN
339427
END;
340428
$$ LANGUAGE plpgsql;
341429

430+
DROP TRIGGER IF EXISTS trg_ready_at_serial ON market_mk20_upload_waiting;
342431
CREATE TRIGGER trg_ready_at_serial
343432
BEFORE UPDATE OF ref_id, chunked ON market_mk20_upload_waiting
344433
FOR EACH ROW
@@ -369,6 +458,7 @@ END;
369458
$$ LANGUAGE plpgsql;
370459

371460

461+
DROP TRIGGER IF EXISTS trg_ready_at_chunks_update ON market_mk20_deal_chunk;
372462
CREATE TRIGGER trg_ready_at_chunks_update
373463
AFTER INSERT OR UPDATE OF complete ON market_mk20_deal_chunk
374464
FOR EACH ROW
@@ -447,7 +537,7 @@ END;
447537
$$ LANGUAGE plpgsql;
448538

449539
-- Main DataSet table for PDP
450-
CREATE TABLE pdp_data_set (
540+
CREATE TABLE IF NOT EXISTS pdp_data_set (
451541
id BIGINT PRIMARY KEY, -- on-chain dataset id
452542
client TEXT NOT NULL, -- client wallet which requested this dataset
453543

@@ -487,7 +577,7 @@ CREATE TABLE pdp_data_set (
487577
);
488578

489579
-- DataSet create table governs the DataSet create task
490-
CREATE TABLE pdp_data_set_create (
580+
CREATE TABLE IF NOT EXISTS pdp_data_set_create (
491581
id TEXT PRIMARY KEY, -- This is Market V2 Deal ID for lookup and response
492582
client TEXT NOT NULL,
493583

@@ -499,7 +589,7 @@ CREATE TABLE pdp_data_set_create (
499589
);
500590

501591
-- DataSet delete table governs the DataSet delete task
502-
CREATE TABLE pdp_data_set_delete (
592+
CREATE TABLE IF NOT EXISTS pdp_data_set_delete (
503593
id TEXT PRIMARY KEY, -- This is Market V2 Deal ID for lookup and response
504594
client TEXT NOT NULL,
505595

@@ -511,7 +601,7 @@ CREATE TABLE pdp_data_set_delete (
511601
);
512602

513603
-- This table governs the delete piece tasks
514-
CREATE TABLE pdp_piece_delete (
604+
CREATE TABLE IF NOT EXISTS pdp_piece_delete (
515605
id TEXT PRIMARY KEY, -- This is Market V2 Deal ID for lookup and response
516606
client TEXT NOT NULL,
517607

@@ -524,7 +614,7 @@ CREATE TABLE pdp_piece_delete (
524614
);
525615

526616
-- Main DataSet Piece table. Any and all pieces ever added by SP must be part of this table
527-
CREATE TABLE pdp_dataset_piece (
617+
CREATE TABLE IF NOT EXISTS pdp_dataset_piece (
528618
data_set_id BIGINT NOT NULL, -- pdp_data_sets.id
529619
client TEXT NOT NULL,
530620

@@ -546,7 +636,7 @@ CREATE TABLE pdp_dataset_piece (
546636
PRIMARY KEY (data_set_id, piece)
547637
);
548638

549-
CREATE TABLE pdp_pipeline (
639+
CREATE TABLE IF NOT EXISTS pdp_pipeline (
550640
created_at TIMESTAMPTZ NOT NULL DEFAULT TIMEZONE('UTC', NOW()),
551641

552642
id TEXT NOT NULL,
@@ -660,12 +750,12 @@ begin
660750
end;
661751
$$;
662752

663-
CREATE TABLE market_mk20_clients (
753+
CREATE TABLE IF NOT EXISTS market_mk20_clients (
664754
client TEXT PRIMARY KEY,
665755
allowed BOOLEAN DEFAULT TRUE
666756
);
667757

668-
CREATE TABLE pdp_proving_tasks (
758+
CREATE TABLE IF NOT EXISTS pdp_proving_tasks (
669759
data_set_id BIGINT NOT NULL, -- pdp_data_set.id
670760
task_id BIGINT NOT NULL, -- harmony_task task ID
671761

@@ -676,7 +766,7 @@ CREATE TABLE pdp_proving_tasks (
676766

677767
-- IPNI pipeline is kept separate from rest for robustness
678768
-- and reuse. This allows for removing, recreating ads using CLI.
679-
CREATE TABLE pdp_ipni_task (
769+
CREATE TABLE IF NOT EXISTS pdp_ipni_task (
680770
context_id BYTEA NOT NULL,
681771
is_rm BOOLEAN NOT NULL,
682772

@@ -769,7 +859,7 @@ END;
769859
$$ LANGUAGE plpgsql;
770860

771861

772-
CREATE TABLE piece_cleanup (
862+
CREATE TABLE IF NOT EXISTS piece_cleanup (
773863
id TEXT NOT NULL,
774864
piece_cid_v2 TEXT NOT NULL,
775865

0 commit comments

Comments
 (0)