blob: 5e3c1a182e5c49014ca5e496d4cf77d8a6e0a69b [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.
*/
\c texera_db
SET search_path TO texera_db;
BEGIN;
-- The file resolver now requires an explicit resource-type prefix on dataset
-- logical paths (/datasets/ownerEmail/datasetName/versionName/...) so other
-- resource types (e.g. models) can be told apart by the prefix. Existing
-- workflows store unprefixed dataset paths inside workflow.content and
-- workflow_version.content, in two operator properties:
-- * fileName (scan-source operators): /owner/name/version/file
-- * datasetVersionPath (file-lister operator): /owner/name/version
-- This migration prepends the "datasets" segment to both.
--
-- A value is treated as a dataset path only when its first two segments match an
-- existing (user.email, dataset.name) pair -- that pair is unique.
-- Local file paths and URLs match no dataset and are left untouched.
-- Already-prefixed values are skipped (idempotent). jsonb_set
-- uses create_missing = false so absent properties are never added.
DO $$
DECLARE
wf_count INT := 0;
wv_count INT := 0;
BEGIN
WITH affected AS (
SELECT w.wid
FROM workflow w,
jsonb_array_elements(
CASE
WHEN jsonb_typeof(w.content::jsonb -> 'operators') = 'array'
THEN w.content::jsonb -> 'operators'
ELSE '[]'::jsonb
END
) AS op,
LATERAL (
SELECT op #>> '{operatorProperties,fileName}' AS fn,
op #>> '{operatorProperties,datasetVersionPath}' AS dvp
) f
WHERE jsonb_typeof(w.content::jsonb -> 'operators') = 'array'
AND (
(f.fn IS NOT NULL AND left(f.fn, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.fn, '/'), '/', 1)
AND d.name = split_part(ltrim(f.fn, '/'), '/', 2)))
OR
(f.dvp IS NOT NULL AND left(f.dvp, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.dvp, '/'), '/', 1)
AND d.name = split_part(ltrim(f.dvp, '/'), '/', 2)))
)
GROUP BY w.wid
),
updated AS (
UPDATE workflow w
SET content = jsonb_set(w.content::jsonb, '{operators}', (
SELECT jsonb_agg(
jsonb_set(
jsonb_set(
op,
'{operatorProperties,fileName}',
CASE
WHEN f.fn IS NOT NULL AND left(f.fn, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.fn, '/'), '/', 1)
AND d.name = split_part(ltrim(f.fn, '/'), '/', 2))
THEN to_jsonb('/datasets/' || ltrim(f.fn, '/'))
ELSE COALESCE(op #> '{operatorProperties,fileName}', 'null'::jsonb)
END,
false
),
'{operatorProperties,datasetVersionPath}',
CASE
WHEN f.dvp IS NOT NULL AND left(f.dvp, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.dvp, '/'), '/', 1)
AND d.name = split_part(ltrim(f.dvp, '/'), '/', 2))
THEN to_jsonb('/datasets/' || ltrim(f.dvp, '/'))
ELSE COALESCE(op #> '{operatorProperties,datasetVersionPath}', 'null'::jsonb)
END,
false
)
ORDER BY ord
)
FROM jsonb_array_elements(
CASE
WHEN jsonb_typeof(w.content::jsonb -> 'operators') = 'array'
THEN w.content::jsonb -> 'operators'
ELSE '[]'::jsonb
END
) WITH ORDINALITY AS t(op, ord),
LATERAL (
SELECT op #>> '{operatorProperties,fileName}' AS fn,
op #>> '{operatorProperties,datasetVersionPath}' AS dvp
) f
))::text
FROM affected a
WHERE w.wid = a.wid
RETURNING 1
)
SELECT count(*) INTO wf_count FROM updated;
WITH affected AS (
SELECT wv.vid
FROM workflow_version wv,
jsonb_array_elements(
CASE
WHEN jsonb_typeof(wv.content::jsonb -> 'operators') = 'array'
THEN wv.content::jsonb -> 'operators'
ELSE '[]'::jsonb
END
) AS op,
LATERAL (
SELECT op #>> '{operatorProperties,fileName}' AS fn,
op #>> '{operatorProperties,datasetVersionPath}' AS dvp
) f
WHERE jsonb_typeof(wv.content::jsonb -> 'operators') = 'array'
AND (
(f.fn IS NOT NULL AND left(f.fn, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.fn, '/'), '/', 1)
AND d.name = split_part(ltrim(f.fn, '/'), '/', 2)))
OR
(f.dvp IS NOT NULL AND left(f.dvp, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.dvp, '/'), '/', 1)
AND d.name = split_part(ltrim(f.dvp, '/'), '/', 2)))
)
GROUP BY wv.vid
),
updated AS (
UPDATE workflow_version wv
SET content = jsonb_set(wv.content::jsonb, '{operators}', (
SELECT jsonb_agg(
jsonb_set(
jsonb_set(
op,
'{operatorProperties,fileName}',
CASE
WHEN f.fn IS NOT NULL AND left(f.fn, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.fn, '/'), '/', 1)
AND d.name = split_part(ltrim(f.fn, '/'), '/', 2))
THEN to_jsonb('/datasets/' || ltrim(f.fn, '/'))
ELSE COALESCE(op #> '{operatorProperties,fileName}', 'null'::jsonb)
END,
false
),
'{operatorProperties,datasetVersionPath}',
CASE
WHEN f.dvp IS NOT NULL AND left(f.dvp, 10) <> '/datasets/'
AND EXISTS (SELECT 1 FROM dataset d JOIN "user" u ON d.owner_uid = u.uid
WHERE u.email = split_part(ltrim(f.dvp, '/'), '/', 1)
AND d.name = split_part(ltrim(f.dvp, '/'), '/', 2))
THEN to_jsonb('/datasets/' || ltrim(f.dvp, '/'))
ELSE COALESCE(op #> '{operatorProperties,datasetVersionPath}', 'null'::jsonb)
END,
false
)
ORDER BY ord
)
FROM jsonb_array_elements(
CASE
WHEN jsonb_typeof(wv.content::jsonb -> 'operators') = 'array'
THEN wv.content::jsonb -> 'operators'
ELSE '[]'::jsonb
END
) WITH ORDINALITY AS t(op, ord),
LATERAL (
SELECT op #>> '{operatorProperties,fileName}' AS fn,
op #>> '{operatorProperties,datasetVersionPath}' AS dvp
) f
))::text
FROM affected a
WHERE wv.vid = a.vid
RETURNING 1
)
SELECT count(*) INTO wv_count FROM updated;
RAISE NOTICE 'Prefixed legacy dataset paths with "datasets/" in % workflow and % workflow_version row(s).', wf_count, wv_count;
END $$;
COMMIT;