code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/migrations/0038_oracle_data_broken.sql (about) 1 -- An earlier migration (0004_oracle_specs) changed the schema the oracle_specs so that instead of having two columns 2 -- for signers and filters, we have a single column 'data', which is a JSONB object; in order to support more diverse 3 -- sorts of data (e.g. from ethereum oracles) 4 -- 5 -- Unforunately, we neglected to preseve the existing data in those columns, so they were left with NULL values in data. 6 -- A recent API change meant that this has started to cause issues on the front end. 7 -- 8 -- Thankfully this information is actually redundantly stored inside the 'tradable_instument' field of the market table, 9 -- so we are able to recreate it; which is what this migration does. 10 -- 11 -- We found a couple of cases where there the data was missing in the market table, so for those we simply delete the 12 -- rows; they are not critical and new ones will be written when the oracle changes state. 13 -- Fish out the relevant stuff from our markets 14 -- +goose Up 15 WITH instruments AS ( 16 SELECT tradable_instrument -> 'instrument' AS instrument 17 FROM markets_current 18 ), 19 futures AS ( 20 SELECT instrument -> 'future' AS future 21 FROM instruments 22 WHERE instrument ? 'future' 23 ), 24 futures_settlement AS ( 25 SELECT future -> 'dataSourceSpecForSettlementData' AS spec 26 FROM futures 27 WHERE future ? 'dataSourceSpecForSettlementData' 28 ), 29 futures_termination AS ( 30 SELECT future -> 'dataSourceSpecForTradingTermination' AS spec 31 FROM futures 32 WHERE future ? 'dataSourceSpecForTradingTermination' 33 ), 34 perpetuals AS ( 35 SELECT instrument -> 'perpetual' AS perpetual 36 FROM instruments 37 WHERE instrument ? 'perpetual' 38 ), 39 perpetuals_settlement AS ( 40 SELECT perpetual -> 'dataSourceSpecForSettlementData' AS spec 41 FROM perpetuals 42 WHERE perpetual ? 'dataSourceSpecForSettlementData' 43 ), 44 perpetuals_schedule AS ( 45 SELECT perpetual -> 'dataSourceSpecForSettlementSchedule' AS spec 46 FROM perpetuals 47 WHERE perpetual ? 'dataSourceSpecForSettlementSchedule' 48 ), 49 all_specs AS ( 50 SELECT * 51 FROM futures_settlement 52 UNION ALL 53 SELECT * 54 FROM futures_termination 55 UNION ALL 56 SELECT * 57 FROM perpetuals_settlement 58 UNION ALL 59 SELECT * 60 FROM perpetuals_schedule 61 ), 62 nice_specs AS ( 63 SELECT DECODE(spec ->> 'id', 'hex') AS id, 64 spec -> 'data' AS DATA 65 FROM all_specs 66 ), 67 unique_specs AS ( 68 SELECT DISTINCT ON (id) * 69 FROM nice_specs 70 ), 71 changes AS ( 72 SELECT os.id, 73 os.vega_time, 74 os.data AS old_data, 75 us.data AS new_data 76 FROM oracle_specs os 77 LEFT JOIN unique_specs us ON os.id = us.id 78 WHERE os.data IS NULL 79 AND us.data IS NOT NULL 80 ORDER BY os.id, 81 os.vega_time 82 ) 83 UPDATE oracle_specs os 84 SET DATA = changes.new_data 85 FROM changes 86 WHERE os.id = changes.id 87 AND os.vega_time = changes.vega_time; 88 89 -- Finally remove any straggelers 90 DELETE FROM oracle_specs 91 WHERE DATA IS NULL; 92 93 -- And lets make sure it can't happen again 94 ALTER TABLE oracle_specs 95 ALTER COLUMN DATA 96 SET NOT NULL; 97 98 -- +goose Down 99 ALTER TABLE oracle_specs 100 ALTER COLUMN DATA 101 DROP NOT NULL;