|
| 1 | +async def dochange(db, rs): |
| 2 | + await db.execute('DROP MATERIALIZED VIEW challenge_state;') |
| 3 | + |
| 4 | + await db.execute( |
| 5 | + ''' |
| 6 | + CREATE TABLE challenge_state ( |
| 7 | + chal_id integer NOT NULL, |
| 8 | + state integer, |
| 9 | + runtime bigint DEFAULT 0, |
| 10 | + memory bigint DEFAULT 0, |
| 11 | + rate integer DEFAULT 0 |
| 12 | + ); |
| 13 | + ''') |
| 14 | + await db.execute( |
| 15 | + ''' |
| 16 | + ALTER TABLE ONLY public.challenge_state |
| 17 | + ADD CONSTRAINT challenge_state_forkey_chal_id FOREIGN KEY (chal_id) REFERENCES public.challenge(chal_id) ON DELETE CASCADE; |
| 18 | + ''') |
| 19 | + |
| 20 | + await db.execute("ALTER TABLE challenge_state ADD CONSTRAINT challenge_state_unique_chal_id UNIQUE(chal_id);") |
| 21 | + |
| 22 | + |
| 23 | + await db.execute( |
| 24 | + ''' |
| 25 | + CREATE TABLE last_update_time ( |
| 26 | + view_name TEXT PRIMARY KEY, |
| 27 | + last_update TIMESTAMP WITH TIME ZONE |
| 28 | + ); |
| 29 | + ''' |
| 30 | + ) |
| 31 | + |
| 32 | + await db.execute("INSERT INTO last_update_time (view_name, last_update) VALUES ('challenge_state', NOW());") |
| 33 | + |
| 34 | + await db.execute("ALTER TABLE test ADD COLUMN last_modified TIMESTAMP WITH TIME ZONE DEFAULT NOW();") |
| 35 | + |
| 36 | + await db.execute("CREATE INDEX idx_test_last_modified ON test (last_modified);") |
| 37 | + await db.execute("CREATE UNIQUE INDEX ON test_valid_rate (pro_id, test_idx);") |
| 38 | + |
| 39 | + await db.execute( |
| 40 | + ''' |
| 41 | + CREATE OR REPLACE FUNCTION update_test_last_modified() |
| 42 | + RETURNS TRIGGER AS $$ |
| 43 | + BEGIN |
| 44 | + NEW.last_modified = NOW(); |
| 45 | + RETURN NEW; |
| 46 | + END; |
| 47 | + $$ LANGUAGE plpgsql; |
| 48 | + ''') |
| 49 | + |
| 50 | + await db.execute( |
| 51 | + ''' |
| 52 | + CREATE TRIGGER test_last_modified_trigger |
| 53 | + BEFORE UPDATE ON test |
| 54 | + FOR EACH ROW EXECUTE FUNCTION update_test_last_modified(); |
| 55 | + ''') |
| 56 | + |
| 57 | + await db.execute( |
| 58 | + ''' |
| 59 | + CREATE OR REPLACE FUNCTION refresh_challenge_state_incremental() |
| 60 | + RETURNS VOID AS $$ |
| 61 | + DECLARE |
| 62 | + last_update_time TIMESTAMP WITH TIME ZONE; |
| 63 | + BEGIN |
| 64 | + SELECT last_update INTO last_update_time |
| 65 | + FROM last_update_time |
| 66 | + WHERE view_name = 'challenge_state'; |
| 67 | +
|
| 68 | + WITH challenge_summary AS ( |
| 69 | + SELECT |
| 70 | + t.chal_id, |
| 71 | + MAX(t.state) AS max_state, |
| 72 | + SUM(t.runtime) AS total_runtime, |
| 73 | + SUM(t.memory) AS total_memory, |
| 74 | + SUM(CASE WHEN t.state = 1 THEN tvr.rate ELSE 0 END) AS total_rate |
| 75 | + FROM test t |
| 76 | + LEFT JOIN test_valid_rate tvr ON t.pro_id = tvr.pro_id AND t.test_idx = tvr.test_idx |
| 77 | + WHERE t.last_modified > last_update_time |
| 78 | + GROUP BY t.chal_id |
| 79 | + ), |
| 80 | + upsert_result AS ( |
| 81 | + INSERT INTO challenge_state (chal_id, state, runtime, memory, rate) |
| 82 | + SELECT |
| 83 | + chal_id, |
| 84 | + max_state, |
| 85 | + total_runtime, |
| 86 | + total_memory, |
| 87 | + total_rate |
| 88 | + FROM challenge_summary |
| 89 | + ON CONFLICT (chal_id) DO UPDATE |
| 90 | + SET |
| 91 | + state = EXCLUDED.state, |
| 92 | + runtime = EXCLUDED.runtime, |
| 93 | + memory = EXCLUDED.memory, |
| 94 | + rate = EXCLUDED.rate |
| 95 | + WHERE |
| 96 | + challenge_state.state != EXCLUDED.state OR |
| 97 | + challenge_state.runtime != EXCLUDED.runtime OR |
| 98 | + challenge_state.memory != EXCLUDED.memory OR |
| 99 | + challenge_state.rate != EXCLUDED.rate |
| 100 | + ) |
| 101 | +
|
| 102 | + UPDATE last_update_time |
| 103 | + SET last_update = NOW() |
| 104 | + WHERE view_name = 'challenge_state'; |
| 105 | + END; |
| 106 | + $$ LANGUAGE plpgsql; |
| 107 | + ''') |
| 108 | + await db.execute('SELECT refresh_challenge_state_incremental();') |
0 commit comments