From db4ffc4900073c35dde6c7da0be3b732aa3a0a82 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Mon, 20 Jul 2026 09:32:11 -0400 Subject: [PATCH] eng-2046-merge-error --- ...60720133047_upsert_content_merge_error.sql | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 packages/database/supabase/migrations/20260720133047_upsert_content_merge_error.sql diff --git a/packages/database/supabase/migrations/20260720133047_upsert_content_merge_error.sql b/packages/database/supabase/migrations/20260720133047_upsert_content_merge_error.sql new file mode 100644 index 000000000..92b7934df --- /dev/null +++ b/packages/database/supabase/migrations/20260720133047_upsert_content_merge_error.sql @@ -0,0 +1,146 @@ +CREATE OR REPLACE FUNCTION public.upsert_content(v_space_id bigint, data jsonb, v_creator_id BIGINT, content_as_document boolean DEFAULT TRUE) +RETURNS SETOF BIGINT +SET search_path = '' +LANGUAGE plpgsql +AS $$ +DECLARE + v_platform public."Platform"; + db_document public."Document"%ROWTYPE; + document_id BIGINT; + local_content public.content_local_input; + db_content public."Content"%ROWTYPE; + content_row JSONB; + upsert_id BIGINT; +BEGIN + SELECT platform INTO STRICT v_platform FROM public."Space" WHERE id=v_space_id; + FOR content_row IN SELECT * FROM jsonb_array_elements(data) + LOOP + local_content := jsonb_populate_record(NULL::public.content_local_input, content_row); + local_content.space_id := v_space_id; + IF content_type(local_content) IS NULL THEN + local_content.content_type := CASE + WHEN variant(local_content)!='full' THEN 'text/plain' + WHEN v_platform='Roam' THEN 'text/roam+markdown' + WHEN v_platform='Obsidian' THEN 'text/obsidian+markdown' + ELSE 'text/plain' END; + END IF; + db_content := public._local_content_to_db_content(local_content); + IF account_local_id(author_inline(local_content)) IS NOT NULL THEN + SELECT public.create_account_in_space( + v_space_id, + account_local_id(author_inline(local_content)), + name(author_inline(local_content)) + ) INTO STRICT upsert_id; + db_content.author_id := upsert_id; + END IF; + IF account_local_id(creator_inline(local_content)) IS NOT NULL THEN + SELECT public.create_account_in_space( + v_space_id, + account_local_id(creator_inline(local_content)), + name(creator_inline(local_content)) + ) INTO STRICT upsert_id; + db_content.creator_id := upsert_id; + END IF; + IF content_as_document THEN + db_content.scale = 'document'; + END IF; + IF content_as_document AND document_id(db_content) IS NULL AND source_local_id(document_inline(local_content)) IS NULL THEN + local_content.document_inline.space_id := v_space_id; + local_content.document_inline.source_local_id := db_content.source_local_id; + local_content.document_inline.last_modified := db_content.last_modified; + local_content.document_inline.created := db_content.created; + local_content.document_inline.author_id := db_content.author_id; + END IF; + IF source_local_id(document_inline(local_content)) IS NOT NULL THEN + IF content_type(document_inline(local_content)) IS NULL THEN + local_content.document_inline.content_type := CASE + WHEN v_platform='Roam' THEN 'text/roam+markdown' + WHEN v_platform='Obsidian' THEN 'text/obsidian+markdown' + ELSE 'text/plain' END; + END IF; + db_document := public._local_document_to_db_document(document_inline(local_content)); + IF (db_document.author_id IS NULL AND author_inline(local_content) IS NOT NULL) THEN + db_document.author_id := upsert_account_in_space(v_space_id, author_inline(local_content)); + END IF; + INSERT INTO public."Document" ( + space_id, + source_local_id, + url, + created, + metadata, + last_modified, + author_id, + contents, + content_type + ) VALUES ( + COALESCE(db_document.space_id, v_space_id), + db_document.source_local_id, + db_document.url, + db_document.created, + COALESCE(db_document.metadata, '{}'::jsonb), + db_document.last_modified, + db_document.author_id, + db_document.contents, + db_document.content_type + ) + ON CONFLICT (space_id, source_local_id) DO UPDATE SET + url = COALESCE(db_document.url, EXCLUDED.url), + created = COALESCE(db_document.created, EXCLUDED.created), + metadata = COALESCE(db_document.metadata, EXCLUDED.metadata), + last_modified = COALESCE(db_document.last_modified, EXCLUDED.last_modified), + author_id = COALESCE(db_document.author_id, EXCLUDED.author_id), + contents = COALESCE(db_document.contents, EXCLUDED.contents), + content_type = COALESCE(db_document.content_type, EXCLUDED.content_type) + RETURNING id INTO STRICT document_id; + db_content.document_id := document_id; + END IF; + INSERT INTO public."Content" ( + document_id, + source_local_id, + variant, + author_id, + creator_id, + created, + text, + metadata, + scale, + space_id, + last_modified, + part_of_id, + content_type, + original + ) VALUES ( + db_content.document_id, + db_content.source_local_id, + COALESCE(db_content.variant, 'direct'::public."ContentVariant"), + db_content.author_id, + db_content.creator_id, + db_content.created, + db_content.text, + COALESCE(db_content.metadata, '{}'::jsonb), + db_content.scale, + db_content.space_id, + db_content.last_modified, + db_content.part_of_id, + db_content.content_type, + db_content.original + ) + ON CONFLICT (space_id, source_local_id, variant, content_type) DO UPDATE SET + document_id = COALESCE(db_content.document_id, EXCLUDED.document_id), + author_id = COALESCE(db_content.author_id, EXCLUDED.author_id), + creator_id = COALESCE(db_content.creator_id, EXCLUDED.creator_id), + created = COALESCE(db_content.created, EXCLUDED.created), + text = COALESCE(db_content.text, EXCLUDED.text), + metadata = COALESCE(db_content.metadata, EXCLUDED.metadata), + scale = COALESCE(db_content.scale, EXCLUDED.scale), + last_modified = COALESCE(db_content.last_modified, EXCLUDED.last_modified), + part_of_id = COALESCE(db_content.part_of_id, EXCLUDED.part_of_id), + original = db_content.original + RETURNING id INTO STRICT upsert_id; + IF model(embedding_inline(local_content)) IS NOT NULL THEN + PERFORM public.upsert_content_embedding(upsert_id, model(embedding_inline(local_content)), vector(embedding_inline(local_content))); + END IF; + RETURN NEXT upsert_id; + END LOOP; +END; +$$;