diff --git a/backend/.sqlx/query-02bdda30f56376073333e45fdf67a874a0cc1a26ca295b0e9b4a6f26e2e83db7.json b/backend/.sqlx/query-02bdda30f56376073333e45fdf67a874a0cc1a26ca295b0e9b4a6f26e2e83db7.json new file mode 100644 index 0000000000..affd6e8caa --- /dev/null +++ b/backend/.sqlx/query-02bdda30f56376073333e45fdf67a874a0cc1a26ca295b0e9b4a6f26e2e83db7.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_diff_full_scan SET source_workspace_id = $1 WHERE source_workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + }, + "nullable": [] + }, + "hash": "02bdda30f56376073333e45fdf67a874a0cc1a26ca295b0e9b4a6f26e2e83db7" +} diff --git a/backend/.sqlx/query-0c5558686b4e5a9bacc73c7b6709ad4e3e6e69582605eeb84a93c29d629b94be.json b/backend/.sqlx/query-0c5558686b4e5a9bacc73c7b6709ad4e3e6e69582605eeb84a93c29d629b94be.json new file mode 100644 index 0000000000..0974be4709 --- /dev/null +++ b/backend/.sqlx/query-0c5558686b4e5a9bacc73c7b6709ad4e3e6e69582605eeb84a93c29d629b94be.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_settings SET error_handler_fallback_to_instance_alerts = false WHERE workspace_id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [] + }, + "hash": "0c5558686b4e5a9bacc73c7b6709ad4e3e6e69582605eeb84a93c29d629b94be" +} diff --git a/backend/.sqlx/query-0d7bd92d4a8bc6261978dcf416fd583b1879d4eaade35a1e2e3a02b76a8a3c04.json b/backend/.sqlx/query-0d7bd92d4a8bc6261978dcf416fd583b1879d4eaade35a1e2e3a02b76a8a3c04.json new file mode 100644 index 0000000000..24231ed318 --- /dev/null +++ b/backend/.sqlx/query-0d7bd92d4a8bc6261978dcf416fd583b1879d4eaade35a1e2e3a02b76a8a3c04.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT parent_workspace_id = $2 FROM workspace WHERE id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "0d7bd92d4a8bc6261978dcf416fd583b1879d4eaade35a1e2e3a02b76a8a3c04" +} diff --git a/backend/.sqlx/query-104873cf0863b063ebd8e4e8f54ec32e3aea2c5bd09fe972a385c1954b4657a8.json b/backend/.sqlx/query-104873cf0863b063ebd8e4e8f54ec32e3aea2c5bd09fe972a385c1954b4657a8.json new file mode 100644 index 0000000000..0368bad7c6 --- /dev/null +++ b/backend/.sqlx/query-104873cf0863b063ebd8e4e8f54ec32e3aea2c5bd09fe972a385c1954b4657a8.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO workspace_diff_full_scan (source_workspace_id, fork_workspace_id)\n VALUES ($1, $2)\n ON CONFLICT (source_workspace_id, fork_workspace_id) DO UPDATE SET scanned_at = now()\n RETURNING scanned_at", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "scanned_at", + "type_info": "Timestamptz" + } + ], + "parameters": { + "Left": [ + "Varchar", + "Varchar" + ] + }, + "nullable": [ + false + ] + }, + "hash": "104873cf0863b063ebd8e4e8f54ec32e3aea2c5bd09fe972a385c1954b4657a8" +} diff --git a/backend/.sqlx/query-18a813c420dac379962cc0fc5777f7be4baa9ac83fd01ac054761976e82d9794.json b/backend/.sqlx/query-18a813c420dac379962cc0fc5777f7be4baa9ac83fd01ac054761976e82d9794.json new file mode 100644 index 0000000000..a48532d1b2 --- /dev/null +++ b/backend/.sqlx/query-18a813c420dac379962cc0fc5777f7be4baa9ac83fd01ac054761976e82d9794.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO datatable_migrations (workspace_id, datatable, timestamp, name, code_up)\n VALUES\n ('test-workspace', 'dt', 20260101000001, 'renamed_here', 'ALTER TABLE t ADD COLUMN a int'),\n ('other-workspace', 'dt', 20260101000001, 'named_there', 'ALTER TABLE t ADD COLUMN a int')", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "18a813c420dac379962cc0fc5777f7be4baa9ac83fd01ac054761976e82d9794" +} diff --git a/backend/.sqlx/query-2213dc4b594d27b3788c48b19e13c600224681e11c016eea5cee3086a7bea8d0.json b/backend/.sqlx/query-2213dc4b594d27b3788c48b19e13c600224681e11c016eea5cee3086a7bea8d0.json new file mode 100644 index 0000000000..14f17d871e --- /dev/null +++ b/backend/.sqlx/query-2213dc4b594d27b3788c48b19e13c600224681e11c016eea5cee3086a7bea8d0.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE workspace_settings\n SET\n ai_config = source_ws.ai_config,\n large_file_storage = source_ws.large_file_storage,\n ducklake = source_ws.ducklake,\n datatable = source_ws.datatable,\n git_app_installations = source_ws.git_app_installations\n FROM workspace_settings source_ws\n WHERE source_ws.workspace_id = $1\n AND workspace_settings.workspace_id = $2\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "2213dc4b594d27b3788c48b19e13c600224681e11c016eea5cee3086a7bea8d0" +} diff --git a/backend/.sqlx/query-2dc5a74c4e614b43148925cdbac234f6a2f295a9c46897f5e9aab8f7298ff0d7.json b/backend/.sqlx/query-2dc5a74c4e614b43148925cdbac234f6a2f295a9c46897f5e9aab8f7298ff0d7.json deleted file mode 100644 index 8714711595..0000000000 --- a/backend/.sqlx/query-2dc5a74c4e614b43148925cdbac234f6a2f295a9c46897f5e9aab8f7298ff0d7.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO workspace_settings SELECT $1, slack_team_id, slack_name, slack_command_script, slack_email, customer_id, plan, webhook, deploy_to, ai_config, large_file_storage, git_sync, default_app, default_scripts, deploy_ui, mute_critical_alerts, color, operator_settings, teams_command_script, teams_team_id, teams_team_name, git_app_installations, ducklake, slack_oauth_client_id, slack_oauth_client_secret, datatable, teams_team_guid, auto_invite, error_handler, success_handler, public_app_execution_limit_per_minute, error_handler_fallback_to_instance_alerts FROM workspace_settings WHERE workspace_id = $2", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Text" - ] - }, - "nullable": [] - }, - "hash": "2dc5a74c4e614b43148925cdbac234f6a2f295a9c46897f5e9aab8f7298ff0d7" -} diff --git a/backend/.sqlx/query-2ef832a6d8e9feb83de6706b0ffe8e849e56f8db795df2ad4d907cdb3c9fce60.json b/backend/.sqlx/query-2ef832a6d8e9feb83de6706b0ffe8e849e56f8db795df2ad4d907cdb3c9fce60.json new file mode 100644 index 0000000000..183c620240 --- /dev/null +++ b/backend/.sqlx/query-2ef832a6d8e9feb83de6706b0ffe8e849e56f8db795df2ad4d907cdb3c9fce60.json @@ -0,0 +1,24 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT DISTINCT flow_step_id as \"flow_step_id!\" FROM v2_job\n WHERE parent_job = $1 AND workspace_id = $2 AND flow_step_id IS NOT NULL\n AND ($3::text[] IS NULL OR tag = ANY($3))\n ORDER BY flow_step_id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "flow_step_id!", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "TextArray" + ] + }, + "nullable": [ + true + ] + }, + "hash": "2ef832a6d8e9feb83de6706b0ffe8e849e56f8db795df2ad4d907cdb3c9fce60" +} diff --git a/backend/.sqlx/query-2f2d26375589ac3df48f476e8200791351c334a13a2ba180ca1f120454c63111.json b/backend/.sqlx/query-2f2d26375589ac3df48f476e8200791351c334a13a2ba180ca1f120454c63111.json new file mode 100644 index 0000000000..2521789b89 --- /dev/null +++ b/backend/.sqlx/query-2f2d26375589ac3df48f476e8200791351c334a13a2ba180ca1f120454c63111.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT path FROM resource WHERE workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "2f2d26375589ac3df48f476e8200791351c334a13a2ba180ca1f120454c63111" +} diff --git a/backend/.sqlx/query-385f671934471f725c964b45314c737d3000f148512ae0e8f63a28bef5d7e998.json b/backend/.sqlx/query-385f671934471f725c964b45314c737d3000f148512ae0e8f63a28bef5d7e998.json new file mode 100644 index 0000000000..e4a3278223 --- /dev/null +++ b/backend/.sqlx/query-385f671934471f725c964b45314c737d3000f148512ae0e8f63a28bef5d7e998.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO usr (workspace_id, email, username, is_admin, role)\n VALUES ('other-workspace', 'test@windmill.dev', 'test-user', true, 'Admin')", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "385f671934471f725c964b45314c737d3000f148512ae0e8f63a28bef5d7e998" +} diff --git a/backend/.sqlx/query-3e869b95799300dff973a3c858f823a2872e33a360ff5a02169e4e80ce3d3b7b.json b/backend/.sqlx/query-3e869b95799300dff973a3c858f823a2872e33a360ff5a02169e4e80ce3d3b7b.json new file mode 100644 index 0000000000..ce3b4fcdf8 --- /dev/null +++ b/backend/.sqlx/query-3e869b95799300dff973a3c858f823a2872e33a360ff5a02169e4e80ce3d3b7b.json @@ -0,0 +1,59 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT email, username, is_admin, is_operator, groups, folders, end_user_email FROM job_perms WHERE job_id = $1 AND workspace_id = $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "email", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "username", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "is_admin", + "type_info": "Bool" + }, + { + "ordinal": 3, + "name": "is_operator", + "type_info": "Bool" + }, + { + "ordinal": 4, + "name": "groups", + "type_info": "TextArray" + }, + { + "ordinal": 5, + "name": "folders", + "type_info": "JsonbArray" + }, + { + "ordinal": 6, + "name": "end_user_email", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text" + ] + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + true + ] + }, + "hash": "3e869b95799300dff973a3c858f823a2872e33a360ff5a02169e4e80ce3d3b7b" +} diff --git a/backend/.sqlx/query-40c76629ba533ad9c523cb9dae2ee8a2a78a250884acff600f3cf0eb9bbaf058.json b/backend/.sqlx/query-40c76629ba533ad9c523cb9dae2ee8a2a78a250884acff600f3cf0eb9bbaf058.json new file mode 100644 index 0000000000..1b6b602ea0 --- /dev/null +++ b/backend/.sqlx/query-40c76629ba533ad9c523cb9dae2ee8a2a78a250884acff600f3cf0eb9bbaf058.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "DELETE FROM workspace_diff_full_scan WHERE source_workspace_id = $1 OR fork_workspace_id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [] + }, + "hash": "40c76629ba533ad9c523cb9dae2ee8a2a78a250884acff600f3cf0eb9bbaf058" +} diff --git a/backend/.sqlx/query-48c2eeca50aedc1895256f615aecc8b68627c8ed9a6da969674734854ef2742a.json b/backend/.sqlx/query-48c2eeca50aedc1895256f615aecc8b68627c8ed9a6da969674734854ef2742a.json new file mode 100644 index 0000000000..93b908a567 --- /dev/null +++ b/backend/.sqlx/query-48c2eeca50aedc1895256f615aecc8b68627c8ed9a6da969674734854ef2742a.json @@ -0,0 +1,37 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT j.id,\n COALESCE(c.status::text,\n CASE WHEN q.running AND q.suspend > 0 THEN 'suspended'\n WHEN q.running THEN 'running'\n ELSE 'queued' END) as \"status!\",\n COALESCE((\n SELECT m->'value'->>'type'\n FROM v2_job parent_j\n LEFT JOIN flow_version fv ON fv.id = parent_j.runnable_id\n AND parent_j.kind::text = 'flow'\n LEFT JOIN flow f ON f.path = parent_j.runnable_path\n AND f.workspace_id = parent_j.workspace_id\n LEFT JOIN flow_node fn ON fn.id = parent_j.runnable_id\n CROSS JOIN LATERAL jsonb_array_elements(\n COALESCE(parent_j.raw_flow, fv.value, f.value, fn.flow)->'modules'\n ) m\n WHERE parent_j.id = $1\n AND m->>'id' = $3\n LIMIT 1\n ), '')::text as \"parent_module_type!\"\n FROM v2_job j\n LEFT JOIN v2_job_completed c ON c.id = j.id\n LEFT JOIN v2_job_queue q ON q.id = j.id\n LEFT JOIN (\n SELECT fj.jid, fj.ord\n FROM (SELECT COALESCE(\n (SELECT flow_status FROM v2_job_completed WHERE id = $1),\n (SELECT flow_status FROM v2_job_status WHERE id = $1)\n ) AS fs) pf\n CROSS JOIN LATERAL (\n SELECT m FROM jsonb_array_elements(pf.fs->'modules') m\n WHERE m->>'id' = $3\n LIMIT 1\n ) md\n CROSS JOIN LATERAL jsonb_array_elements_text(md.m->'flow_jobs')\n WITH ORDINALITY fj(jid, ord)\n ) pos ON pos.jid = j.id::text\n WHERE j.parent_job = $1 AND j.workspace_id = $2 AND j.flow_step_id = $3\n AND ($4::text[] IS NULL OR j.tag = ANY($4))\n ORDER BY pos.ord NULLS LAST, j.id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "status!", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "parent_module_type!", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Text", + "TextArray" + ] + }, + "nullable": [ + false, + null, + null + ] + }, + "hash": "48c2eeca50aedc1895256f615aecc8b68627c8ed9a6da969674734854ef2742a" +} diff --git a/backend/.sqlx/query-4a0b3f5e2daa723f16fc005afc2c5cb901a9d13e874e35ba399ac3a1d31aa470.json b/backend/.sqlx/query-4a0b3f5e2daa723f16fc005afc2c5cb901a9d13e874e35ba399ac3a1d31aa470.json new file mode 100644 index 0000000000..8fd0e0c13a --- /dev/null +++ b/backend/.sqlx/query-4a0b3f5e2daa723f16fc005afc2c5cb901a9d13e874e35ba399ac3a1d31aa470.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO script (workspace_id, path, hash, content, summary, description, language, created_by, created_at, archived, schema_validation, ws_error_handler_muted, deleted)\n VALUES\n ('test-workspace', 'f/shared/same', 1, 'def main(): pass', 'Same', '', 'python3', 'test@windmill.dev', NOW(), false, false, false, false),\n ('test-workspace', 'f/shared/differs', 2, 'def main(): return 1', 'Differs', '', 'python3', 'test@windmill.dev', NOW(), false, false, false, false),\n ('test-workspace', 'f/shared/only_here', 3, 'def main(): return 2', 'Only here', '', 'python3', 'test@windmill.dev', NOW(), false, false, false, false),\n ('other-workspace', 'f/shared/same', 4, 'def main(): pass', 'Same', '', 'python3', 'test@windmill.dev', NOW(), false, false, false, false),\n ('other-workspace', 'f/shared/differs', 5, 'def main(): return 99', 'Differs', '', 'python3', 'test@windmill.dev', NOW(), false, false, false, false)", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "4a0b3f5e2daa723f16fc005afc2c5cb901a9d13e874e35ba399ac3a1d31aa470" +} diff --git a/backend/.sqlx/query-5d1e758bb2f907ceb85fbd8b9991fafabb0ab8a2155062a20f1a229567d1bddf.json b/backend/.sqlx/query-5d1e758bb2f907ceb85fbd8b9991fafabb0ab8a2155062a20f1a229567d1bddf.json new file mode 100644 index 0000000000..abfe83c55e --- /dev/null +++ b/backend/.sqlx/query-5d1e758bb2f907ceb85fbd8b9991fafabb0ab8a2155062a20f1a229567d1bddf.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT pg_advisory_xact_lock(hashtext('workspace_diff_pair:' || $1 || '/' || $2))", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "pg_advisory_xact_lock", + "type_info": "Void" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "5d1e758bb2f907ceb85fbd8b9991fafabb0ab8a2155062a20f1a229567d1bddf" +} diff --git a/backend/.sqlx/query-5e27017f770c9315205e310902441c01f6b65c123c7b877902a1129fda0b6fe5.json b/backend/.sqlx/query-5e27017f770c9315205e310902441c01f6b65c123c7b877902a1129fda0b6fe5.json new file mode 100644 index 0000000000..f6a4873075 --- /dev/null +++ b/backend/.sqlx/query-5e27017f770c9315205e310902441c01f6b65c123c7b877902a1129fda0b6fe5.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(SELECT 1 FROM workspace WHERE id = $1 AND deleted = false)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "5e27017f770c9315205e310902441c01f6b65c123c7b877902a1129fda0b6fe5" +} diff --git a/backend/.sqlx/query-63bf7697facb7a989a7cddac67ae48716ad4269aeaabbd9d3d938d22c268f374.json b/backend/.sqlx/query-63bf7697facb7a989a7cddac67ae48716ad4269aeaabbd9d3d938d22c268f374.json new file mode 100644 index 0000000000..c74438a6b7 --- /dev/null +++ b/backend/.sqlx/query-63bf7697facb7a989a7cddac67ae48716ad4269aeaabbd9d3d938d22c268f374.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO app (workspace_id, path, summary, policy, versions)\n VALUES ($1, 'f/shared/converted', 'Converted', '{}'::jsonb, ARRAY[]::bigint[])\n RETURNING id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Varchar" + ] + }, + "nullable": [ + false + ] + }, + "hash": "63bf7697facb7a989a7cddac67ae48716ad4269aeaabbd9d3d938d22c268f374" +} diff --git a/backend/.sqlx/query-6658faa1fcf54885ee6313d39cf3ee4a13c4b30daefc0c67b63d263d77f0e9b7.json b/backend/.sqlx/query-6658faa1fcf54885ee6313d39cf3ee4a13c4b30daefc0c67b63d263d77f0e9b7.json new file mode 100644 index 0000000000..9cd3c104de --- /dev/null +++ b/backend/.sqlx/query-6658faa1fcf54885ee6313d39cf3ee4a13c4b30daefc0c67b63d263d77f0e9b7.json @@ -0,0 +1,24 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO app_version (app_id, value, created_by, created_at, raw_app)\n VALUES ($1, $2, 'test@windmill.dev', NOW(), $3) RETURNING id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8", + "Json", + "Bool" + ] + }, + "nullable": [ + false + ] + }, + "hash": "6658faa1fcf54885ee6313d39cf3ee4a13c4b30daefc0c67b63d263d77f0e9b7" +} diff --git a/backend/.sqlx/query-673f2a8dccad6bfc4439adaf20013054aac4d94d60827e36cb81a484d2daadd7.json b/backend/.sqlx/query-673f2a8dccad6bfc4439adaf20013054aac4d94d60827e36cb81a484d2daadd7.json new file mode 100644 index 0000000000..51d51b5185 --- /dev/null +++ b/backend/.sqlx/query-673f2a8dccad6bfc4439adaf20013054aac4d94d60827e36cb81a484d2daadd7.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT EXISTS(\n SELECT 1\n FROM workspace_settings ws\n CROSS JOIN LATERAL jsonb_each(\n CASE WHEN jsonb_typeof(ws.ducklake->'ducklakes') = 'object'\n THEN ws.ducklake->'ducklakes'\n ELSE '{}'::jsonb END\n ) AS dl(key, value)\n WHERE value->'catalog'->>'resource_type' = 'instance'\n AND value->'catalog'->>'resource_path' = $1\n ) AS \"e!\"\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "e!", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "673f2a8dccad6bfc4439adaf20013054aac4d94d60827e36cb81a484d2daadd7" +} diff --git a/backend/.sqlx/query-6981553b904f9ae38d6eaeae05716ac71390028dfe8c54798b1701b01591fff7.json b/backend/.sqlx/query-6981553b904f9ae38d6eaeae05716ac71390028dfe8c54798b1701b01591fff7.json new file mode 100644 index 0000000000..1a965a6dc3 --- /dev/null +++ b/backend/.sqlx/query-6981553b904f9ae38d6eaeae05716ac71390028dfe8c54798b1701b01591fff7.json @@ -0,0 +1,66 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT j.kind::text as kind,\n c.status::text as completed_status,\n c.duration_ms as \"duration_ms?\",\n COALESCE(c.started_at, q.started_at) as started_at,\n LEFT(c.result::text, $3) as result_prefix,\n length(c.result::text) as result_length,\n q.running as \"q_running?\",\n q.suspend as \"q_suspend?\"\n FROM v2_job j\n LEFT JOIN v2_job_completed c ON c.id = j.id\n LEFT JOIN v2_job_queue q ON q.id = j.id\n WHERE j.id = $1 AND j.workspace_id = $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "kind", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "completed_status", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "duration_ms?", + "type_info": "Int8" + }, + { + "ordinal": 3, + "name": "started_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 4, + "name": "result_prefix", + "type_info": "Text" + }, + { + "ordinal": 5, + "name": "result_length", + "type_info": "Int4" + }, + { + "ordinal": 6, + "name": "q_running?", + "type_info": "Bool" + }, + { + "ordinal": 7, + "name": "q_suspend?", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "Int4" + ] + }, + "nullable": [ + null, + null, + false, + null, + null, + null, + false, + false + ] + }, + "hash": "6981553b904f9ae38d6eaeae05716ac71390028dfe8c54798b1701b01591fff7" +} diff --git a/backend/.sqlx/query-6ade445fab717d2dadbebfb5747db8b49c98709cfc99a6ee25c29a230bf9ec46.json b/backend/.sqlx/query-6ade445fab717d2dadbebfb5747db8b49c98709cfc99a6ee25c29a230bf9ec46.json new file mode 100644 index 0000000000..0f39dca9d2 --- /dev/null +++ b/backend/.sqlx/query-6ade445fab717d2dadbebfb5747db8b49c98709cfc99a6ee25c29a230bf9ec46.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT ahead FROM workspace_diff\n WHERE source_workspace_id = 'test-workspace'\n AND fork_workspace_id = 'wm-fork-no-deploy-to'\n AND kind = 'script'\n AND path = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "ahead", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "6ade445fab717d2dadbebfb5747db8b49c98709cfc99a6ee25c29a230bf9ec46" +} diff --git a/backend/.sqlx/query-6ddf798848b75affad1333b76c95b300c08ef40ef59a1cc159840cac51cc4789.json b/backend/.sqlx/query-6ddf798848b75affad1333b76c95b300c08ef40ef59a1cc159840cac51cc4789.json new file mode 100644 index 0000000000..b61f755814 --- /dev/null +++ b/backend/.sqlx/query-6ddf798848b75affad1333b76c95b300c08ef40ef59a1cc159840cac51cc4789.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE workspace_settings\n SET git_sync = jsonb_set(\n git_sync,\n '{repositories}',\n (SELECT jsonb_agg(\n CASE WHEN elem->>'git_repo_resource_path' = $2\n AND jsonb_typeof(elem->'auto_pull') = 'object'\n THEN jsonb_set(elem, '{auto_pull}',\n ((elem->'auto_pull') - 'webhook_id' - 'webhook_secret' - 'webhook_url' - 'webhook_error') || $3)\n ELSE elem END)\n FROM jsonb_array_elements(git_sync->'repositories') AS elem)\n )\n WHERE workspace_id = $1\n AND jsonb_typeof(git_sync->'repositories') = 'array'\n AND EXISTS (\n SELECT 1 FROM jsonb_array_elements(git_sync->'repositories') AS e\n WHERE e->>'git_repo_resource_path' = $2\n AND jsonb_typeof(e->'auto_pull') = 'object'\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Jsonb" + ] + }, + "nullable": [] + }, + "hash": "6ddf798848b75affad1333b76c95b300c08ef40ef59a1cc159840cac51cc4789" +} diff --git a/backend/.sqlx/query-754d417acf38a659897488b9f0583a77398a3932ed1c5e29fa8284b76e383084.json b/backend/.sqlx/query-754d417acf38a659897488b9f0583a77398a3932ed1c5e29fa8284b76e383084.json new file mode 100644 index 0000000000..75456b0956 --- /dev/null +++ b/backend/.sqlx/query-754d417acf38a659897488b9f0583a77398a3932ed1c5e29fa8284b76e383084.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT 1 FROM datatable_ephemeral_role WHERE role_name = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "754d417acf38a659897488b9f0583a77398a3932ed1c5e29fa8284b76e383084" +} diff --git a/backend/.sqlx/query-767d4e0097a79b864d413b28153c1bcfd03be03bbb9ebd141513e57869f445d3.json b/backend/.sqlx/query-767d4e0097a79b864d413b28153c1bcfd03be03bbb9ebd141513e57869f445d3.json new file mode 100644 index 0000000000..d14be4a749 --- /dev/null +++ b/backend/.sqlx/query-767d4e0097a79b864d413b28153c1bcfd03be03bbb9ebd141513e57869f445d3.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE datatable_migrations SET name = 'renamed_again'\n WHERE workspace_id = 'test-workspace' AND datatable = 'dt'", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "767d4e0097a79b864d413b28153c1bcfd03be03bbb9ebd141513e57869f445d3" +} diff --git a/backend/.sqlx/query-7776414a7f0d2f0677b8c81e6b2ef1a20b025696c9b9ab807f8957cde9a21a05.json b/backend/.sqlx/query-7776414a7f0d2f0677b8c81e6b2ef1a20b025696c9b9ab807f8957cde9a21a05.json new file mode 100644 index 0000000000..4baf5c389a --- /dev/null +++ b/backend/.sqlx/query-7776414a7f0d2f0677b8c81e6b2ef1a20b025696c9b9ab807f8957cde9a21a05.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "DELETE FROM workspace_diff WHERE source_workspace_id = $1 AND fork_workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "7776414a7f0d2f0677b8c81e6b2ef1a20b025696c9b9ab807f8957cde9a21a05" +} diff --git a/backend/.sqlx/query-780cc55995eb5d5f88955381cdd71f46addafdabfe7dde0953d5c58a18a9274a.json b/backend/.sqlx/query-780cc55995eb5d5f88955381cdd71f46addafdabfe7dde0953d5c58a18a9274a.json new file mode 100644 index 0000000000..5d0542d65b --- /dev/null +++ b/backend/.sqlx/query-780cc55995eb5d5f88955381cdd71f46addafdabfe7dde0953d5c58a18a9274a.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "DELETE FROM workspace_diff WHERE (source_workspace_id = $1 AND fork_workspace_id = $2)\n OR (source_workspace_id = $2 AND fork_workspace_id = $1)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "780cc55995eb5d5f88955381cdd71f46addafdabfe7dde0953d5c58a18a9274a" +} diff --git a/backend/.sqlx/query-7c45f8d05a10ccf538c1b63aa1337e6d0491a2e8d04fe87eddb5a573de00d125.json b/backend/.sqlx/query-7c45f8d05a10ccf538c1b63aa1337e6d0491a2e8d04fe87eddb5a573de00d125.json deleted file mode 100644 index f2bc7955da..0000000000 --- a/backend/.sqlx/query-7c45f8d05a10ccf538c1b63aa1337e6d0491a2e8d04fe87eddb5a573de00d125.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO workspace_settings SELECT $1, slack_team_id, slack_name, slack_command_script, slack_email, customer_id, plan, webhook, deploy_to, ai_config, large_file_storage, git_sync, default_app, default_scripts, deploy_ui, mute_critical_alerts, color, operator_settings, teams_command_script, teams_team_id, teams_team_name, git_app_installations, ducklake, slack_oauth_client_id, slack_oauth_client_secret, datatable, teams_team_guid, auto_invite, error_handler, success_handler FROM workspace_settings WHERE workspace_id = $2", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Text" - ] - }, - "nullable": [] - }, - "hash": "7c45f8d05a10ccf538c1b63aa1337e6d0491a2e8d04fe87eddb5a573de00d125" -} diff --git a/backend/.sqlx/query-8058042d5564a934534517e9c0446c5fcc0c3654746c5e65994123ffb4d05f78.json b/backend/.sqlx/query-8058042d5564a934534517e9c0446c5fcc0c3654746c5e65994123ffb4d05f78.json new file mode 100644 index 0000000000..5453ec6899 --- /dev/null +++ b/backend/.sqlx/query-8058042d5564a934534517e9c0446c5fcc0c3654746c5e65994123ffb4d05f78.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO workspace_settings (workspace_id, slack_team_id, slack_name, slack_command_script, slack_email, customer_id, plan, webhook, ai_config, large_file_storage, git_sync, default_app, default_scripts, deploy_ui, mute_critical_alerts, color, operator_settings, teams_command_script, teams_team_id, teams_team_name, git_app_installations, ducklake, slack_oauth_client_id, slack_oauth_client_secret, datatable, teams_team_guid, auto_invite, error_handler, success_handler, public_app_execution_limit_per_minute, error_handler_fallback_to_instance_alerts) SELECT $1, slack_team_id, slack_name, slack_command_script, slack_email, customer_id, plan, webhook, ai_config, large_file_storage, git_sync, default_app, default_scripts, deploy_ui, mute_critical_alerts, color, operator_settings, teams_command_script, teams_team_id, teams_team_name, git_app_installations, ducklake, slack_oauth_client_id, slack_oauth_client_secret, datatable, teams_team_guid, auto_invite, error_handler, success_handler, public_app_execution_limit_per_minute, error_handler_fallback_to_instance_alerts FROM workspace_settings WHERE workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + }, + "nullable": [] + }, + "hash": "8058042d5564a934534517e9c0446c5fcc0c3654746c5e65994123ffb4d05f78" +} diff --git a/backend/.sqlx/query-81f4c030c77b423ff112012ad542e91975745846cade8b1a0b26882e4a3f3cc9.json b/backend/.sqlx/query-81f4c030c77b423ff112012ad542e91975745846cade8b1a0b26882e4a3f3cc9.json new file mode 100644 index 0000000000..d443af1ce7 --- /dev/null +++ b/backend/.sqlx/query-81f4c030c77b423ff112012ad542e91975745846cade8b1a0b26882e4a3f3cc9.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE app SET versions = ARRAY[$2::bigint] WHERE id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "81f4c030c77b423ff112012ad542e91975745846cade8b1a0b26882e4a3f3cc9" +} diff --git a/backend/.sqlx/query-a479cd371fb5d1f52e7c727730cf48ab229e63b8dfe377975d48dcd223251e7c.json b/backend/.sqlx/query-88a6a86285fcfaa778e9716d5072f555dff175feb704c3d825d6100defe91bce.json similarity index 83% rename from backend/.sqlx/query-a479cd371fb5d1f52e7c727730cf48ab229e63b8dfe377975d48dcd223251e7c.json rename to backend/.sqlx/query-88a6a86285fcfaa778e9716d5072f555dff175feb704c3d825d6100defe91bce.json index 6f75beab08..9097eb8584 100644 --- a/backend/.sqlx/query-a479cd371fb5d1f52e7c727730cf48ab229e63b8dfe377975d48dcd223251e7c.json +++ b/backend/.sqlx/query-88a6a86285fcfaa778e9716d5072f555dff175feb704c3d825d6100defe91bce.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT\n workspace_id,\n slack_team_id,\n teams_team_id,\n teams_team_name,\n teams_team_guid,\n slack_name,\n slack_command_script,\n teams_command_script,\n slack_email,\n slack_oauth_client_id,\n slack_oauth_client_secret,\n customer_id,\n plan,\n webhook,\n deploy_to,\n ai_config,\n large_file_storage,\n datatable,\n ducklake,\n git_sync,\n deploy_ui,\n default_app,\n default_scripts,\n mute_critical_alerts,\n color,\n operator_settings,\n git_app_installations,\n auto_invite,\n error_handler,\n success_handler,\n public_app_execution_limit_per_minute\n FROM\n workspace_settings\n WHERE\n workspace_id = $1\n ", + "query": "\n SELECT\n workspace_id,\n slack_team_id,\n teams_team_id,\n teams_team_name,\n teams_team_guid,\n slack_name,\n slack_command_script,\n teams_command_script,\n slack_email,\n slack_oauth_client_id,\n slack_oauth_client_secret,\n customer_id,\n plan,\n webhook,\n ai_config,\n large_file_storage,\n datatable,\n ducklake,\n git_sync,\n deploy_ui,\n default_app,\n default_scripts,\n mute_critical_alerts,\n color,\n operator_settings,\n git_app_installations,\n auto_invite,\n error_handler,\n success_handler,\n public_app_execution_limit_per_minute,\n error_handler_fallback_to_instance_alerts\n FROM\n workspace_settings\n WHERE\n workspace_id = $1\n ", "describe": { "columns": [ { @@ -75,88 +75,88 @@ }, { "ordinal": 14, - "name": "deploy_to", - "type_info": "Varchar" - }, - { - "ordinal": 15, "name": "ai_config", "type_info": "Jsonb" }, { - "ordinal": 16, + "ordinal": 15, "name": "large_file_storage", "type_info": "Jsonb" }, { - "ordinal": 17, + "ordinal": 16, "name": "datatable", "type_info": "Jsonb" }, { - "ordinal": 18, + "ordinal": 17, "name": "ducklake", "type_info": "Jsonb" }, { - "ordinal": 19, + "ordinal": 18, "name": "git_sync", "type_info": "Jsonb" }, { - "ordinal": 20, + "ordinal": 19, "name": "deploy_ui", "type_info": "Jsonb" }, { - "ordinal": 21, + "ordinal": 20, "name": "default_app", "type_info": "Varchar" }, { - "ordinal": 22, + "ordinal": 21, "name": "default_scripts", "type_info": "Jsonb" }, { - "ordinal": 23, + "ordinal": 22, "name": "mute_critical_alerts", "type_info": "Bool" }, { - "ordinal": 24, + "ordinal": 23, "name": "color", "type_info": "Varchar" }, { - "ordinal": 25, + "ordinal": 24, "name": "operator_settings", "type_info": "Jsonb" }, { - "ordinal": 26, + "ordinal": 25, "name": "git_app_installations", "type_info": "Jsonb" }, { - "ordinal": 27, + "ordinal": 26, "name": "auto_invite", "type_info": "Jsonb" }, { - "ordinal": 28, + "ordinal": 27, "name": "error_handler", "type_info": "Jsonb" }, { - "ordinal": 29, + "ordinal": 28, "name": "success_handler", "type_info": "Jsonb" }, { - "ordinal": 30, + "ordinal": 29, "name": "public_app_execution_limit_per_minute", "type_info": "Int4" + }, + { + "ordinal": 30, + "name": "error_handler_fallback_to_instance_alerts", + "type_info": "Bool" } ], "parameters": { @@ -190,13 +190,13 @@ true, true, true, - true, false, true, true, true, - true + true, + false ] }, - "hash": "a479cd371fb5d1f52e7c727730cf48ab229e63b8dfe377975d48dcd223251e7c" + "hash": "88a6a86285fcfaa778e9716d5072f555dff175feb704c3d825d6100defe91bce" } diff --git a/backend/.sqlx/query-89e284ee0e2a95a12acb8f97373cb6ff95fc498935281928104e71ada9370140.json b/backend/.sqlx/query-89e284ee0e2a95a12acb8f97373cb6ff95fc498935281928104e71ada9370140.json new file mode 100644 index 0000000000..d5125eb331 --- /dev/null +++ b/backend/.sqlx/query-89e284ee0e2a95a12acb8f97373cb6ff95fc498935281928104e71ada9370140.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO usr (workspace_id, email, username, is_admin, role)\n VALUES ('other-workspace', 'test2@windmill.dev', 'test-user-2', true, 'Admin')", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "89e284ee0e2a95a12acb8f97373cb6ff95fc498935281928104e71ada9370140" +} diff --git a/backend/.sqlx/query-925936b0d87ed4b39552eeda5a8b41514101d27f242100cfd8f2669f0eeb3786.json b/backend/.sqlx/query-925936b0d87ed4b39552eeda5a8b41514101d27f242100cfd8f2669f0eeb3786.json new file mode 100644 index 0000000000..26ca2c8eda --- /dev/null +++ b/backend/.sqlx/query-925936b0d87ed4b39552eeda5a8b41514101d27f242100cfd8f2669f0eeb3786.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(\n SELECT 1 FROM workspace\n WHERE (id = $1 AND parent_workspace_id = $2) OR (id = $2 AND parent_workspace_id = $1)\n )", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "925936b0d87ed4b39552eeda5a8b41514101d27f242100cfd8f2669f0eeb3786" +} diff --git a/backend/.sqlx/query-9293d1ae9aa0da9a6a80c1cb74029b71af84859db23f24dcfc0f710ebd78a4d4.json b/backend/.sqlx/query-9293d1ae9aa0da9a6a80c1cb74029b71af84859db23f24dcfc0f710ebd78a4d4.json new file mode 100644 index 0000000000..dff6f2993c --- /dev/null +++ b/backend/.sqlx/query-9293d1ae9aa0da9a6a80c1cb74029b71af84859db23f24dcfc0f710ebd78a4d4.json @@ -0,0 +1,32 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT workspace_id, elem->>'git_repo_resource_path' AS \"repo_path!\",\n elem->'auto_pull'->>'webhook_url' AS webhook_url\n FROM workspace_settings, LATERAL jsonb_array_elements(git_sync->'repositories') AS elem\n WHERE jsonb_typeof(git_sync->'repositories') = 'array'\n AND elem->'auto_pull'->'webhook_id' IS NOT NULL\n AND elem->>'git_repo_resource_path' IS NOT NULL", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "workspace_id", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "repo_path!", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "webhook_url", + "type_info": "Text" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + null, + null + ] + }, + "hash": "9293d1ae9aa0da9a6a80c1cb74029b71af84859db23f24dcfc0f710ebd78a4d4" +} diff --git a/backend/.sqlx/query-94f0e271a67179c78de217ae1f4d7190324533119792b650c6db734a3b99575c.json b/backend/.sqlx/query-94f0e271a67179c78de217ae1f4d7190324533119792b650c6db734a3b99575c.json new file mode 100644 index 0000000000..c284efca75 --- /dev/null +++ b/backend/.sqlx/query-94f0e271a67179c78de217ae1f4d7190324533119792b650c6db734a3b99575c.json @@ -0,0 +1,84 @@ +{ + "db_name": "PostgreSQL", + "query": "WITH RECURSIVE job_tree AS (\n SELECT j.id, j.kind::text, j.flow_step_id, j.parent_job,\n '' as path_label, 0 as depth,\n j.id::text as id_path,\n ''::text as parent_module_type\n FROM v2_job j\n WHERE j.id = $2 AND j.workspace_id = $1\n UNION ALL\n SELECT j.id, j.kind::text, j.flow_step_id, j.parent_job,\n CASE\n WHEN jt.path_label = '' THEN COALESCE(j.flow_step_id, '')\n ELSE jt.path_label || '/' || COALESCE(j.flow_step_id, '')\n END,\n jt.depth + 1,\n jt.id_path || '/' || j.id::text,\n COALESCE((\n SELECT m->'value'->>'type'\n FROM v2_job parent_j\n LEFT JOIN flow_version fv ON fv.id = parent_j.runnable_id\n AND parent_j.kind::text = 'flow'\n LEFT JOIN flow f ON f.path = parent_j.runnable_path\n AND f.workspace_id = parent_j.workspace_id\n LEFT JOIN flow_node fn ON fn.id = parent_j.runnable_id\n CROSS JOIN LATERAL jsonb_array_elements(\n COALESCE(parent_j.raw_flow, fv.value, f.value, fn.flow)->'modules'\n ) m\n WHERE parent_j.id = jt.id\n AND m->>'id' = j.flow_step_id\n LIMIT 1\n ), '')::text\n FROM v2_job j\n JOIN job_tree jt ON j.parent_job = jt.id\n WHERE j.workspace_id = $1\n AND ($3::text[] IS NULL OR j.tag = ANY($3))\n ),\n positions AS (\n SELECT g.parent_job, g.flow_step_id, fj.jid, fj.ord\n FROM (SELECT DISTINCT parent_job, flow_step_id FROM job_tree\n WHERE parent_job IS NOT NULL AND flow_step_id IS NOT NULL) g\n CROSS JOIN LATERAL (\n SELECT COALESCE(\n (SELECT flow_status FROM v2_job_completed WHERE id = g.parent_job),\n (SELECT flow_status FROM v2_job_status WHERE id = g.parent_job)\n ) AS fs\n ) pf\n CROSS JOIN LATERAL (\n SELECT m FROM jsonb_array_elements(pf.fs->'modules') m\n WHERE m->>'id' = g.flow_step_id\n LIMIT 1\n ) md\n CROSS JOIN LATERAL jsonb_array_elements_text(md.m->'flow_jobs')\n WITH ORDINALITY fj(jid, ord)\n ),\n with_sibling_index AS (\n SELECT jt.*,\n ROW_NUMBER() OVER (\n PARTITION BY jt.parent_job, jt.flow_step_id\n ORDER BY pos.ord NULLS LAST, jt.id\n ) as sibling_index,\n COUNT(*) OVER (\n PARTITION BY jt.parent_job, jt.flow_step_id\n ) as sibling_count\n FROM job_tree jt\n LEFT JOIN positions pos ON pos.parent_job = jt.parent_job\n AND pos.flow_step_id = jt.flow_step_id\n AND pos.jid = jt.id::text\n )\n SELECT w.id, w.kind, w.flow_step_id, w.path_label,\n w.sibling_index::int as sibling_index,\n w.sibling_count::int as sibling_count,\n w.depth::int as depth,\n w.parent_module_type,\n coalesce(job_logs.logs, '') as logs,\n COALESCE(job_logs.log_offset, 0) as log_offset,\n job_logs.log_file_index\n FROM with_sibling_index w\n LEFT JOIN job_logs ON job_logs.job_id = w.id\n ORDER BY w.id_path ASC", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "kind", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "flow_step_id", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "path_label", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "sibling_index", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "sibling_count", + "type_info": "Int4" + }, + { + "ordinal": 6, + "name": "depth", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "parent_module_type", + "type_info": "Text" + }, + { + "ordinal": 8, + "name": "logs", + "type_info": "Text" + }, + { + "ordinal": 9, + "name": "log_offset", + "type_info": "Int4" + }, + { + "ordinal": 10, + "name": "log_file_index", + "type_info": "TextArray" + } + ], + "parameters": { + "Left": [ + "Text", + "Uuid", + "TextArray" + ] + }, + "nullable": [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + true + ] + }, + "hash": "94f0e271a67179c78de217ae1f4d7190324533119792b650c6db734a3b99575c" +} diff --git a/backend/.sqlx/query-966e630d2f933e4c699e8462bfff3f8a8219f5621138ebd49dfe56cc20704124.json b/backend/.sqlx/query-966e630d2f933e4c699e8462bfff3f8a8219f5621138ebd49dfe56cc20704124.json new file mode 100644 index 0000000000..41cba49102 --- /dev/null +++ b/backend/.sqlx/query-966e630d2f933e4c699e8462bfff3f8a8219f5621138ebd49dfe56cc20704124.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT EXISTS(\n SELECT 1\n FROM workspace_settings ws\n CROSS JOIN LATERAL jsonb_each(\n CASE WHEN jsonb_typeof(ws.datatable->'datatables') = 'object'\n THEN ws.datatable->'datatables'\n ELSE '{}'::jsonb END\n ) AS dt(key, value)\n WHERE dt.value->'database'->>'resource_type' = 'instance'\n AND dt.value->'database'->>'resource_path' = $1\n AND COALESCE((dt.value->'permissions'->>'enabled')::boolean, false)\n ) AS \"e!\"\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "e!", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "966e630d2f933e4c699e8462bfff3f8a8219f5621138ebd49dfe56cc20704124" +} diff --git a/backend/.sqlx/query-9e19f8203f97e1159928f9afe36d1c5190b6168ded757adf1791fbb9312b41a3.json b/backend/.sqlx/query-9e19f8203f97e1159928f9afe36d1c5190b6168ded757adf1791fbb9312b41a3.json new file mode 100644 index 0000000000..529b2da15d --- /dev/null +++ b/backend/.sqlx/query-9e19f8203f97e1159928f9afe36d1c5190b6168ded757adf1791fbb9312b41a3.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT ahead FROM workspace_diff\n WHERE source_workspace_id = 'test-workspace'\n AND fork_workspace_id = 'wm-fork-tally'\n AND kind = 'script'\n AND path = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "ahead", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "9e19f8203f97e1159928f9afe36d1c5190b6168ded757adf1791fbb9312b41a3" +} diff --git a/backend/.sqlx/query-a6396f4efe3c790da61988981ea5fce4df51a7658b8626158608f929d9682e11.json b/backend/.sqlx/query-a6396f4efe3c790da61988981ea5fce4df51a7658b8626158608f929d9682e11.json new file mode 100644 index 0000000000..4bfaaa6063 --- /dev/null +++ b/backend/.sqlx/query-a6396f4efe3c790da61988981ea5fce4df51a7658b8626158608f929d9682e11.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT path FROM flow WHERE workspace_id = $1 AND archived = false", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "a6396f4efe3c790da61988981ea5fce4df51a7658b8626158608f929d9682e11" +} diff --git a/backend/.sqlx/query-ac09d8de92d8e1ee9b463b87b2374e11ba46e9b392414282d2d67161a6544d11.json b/backend/.sqlx/query-ac09d8de92d8e1ee9b463b87b2374e11ba46e9b392414282d2d67161a6544d11.json new file mode 100644 index 0000000000..4d362ac045 --- /dev/null +++ b/backend/.sqlx/query-ac09d8de92d8e1ee9b463b87b2374e11ba46e9b392414282d2d67161a6544d11.json @@ -0,0 +1,41 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT app.summary, app.policy, app_version.value, app_version.raw_app\n FROM app\n JOIN app_version\n ON app_version.id = app.versions[array_upper(app.versions, 1)]\n WHERE app.workspace_id = $1 AND app.path = $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "summary", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "policy", + "type_info": "Jsonb" + }, + { + "ordinal": 2, + "name": "value", + "type_info": "Json" + }, + { + "ordinal": 3, + "name": "raw_app", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + false, + false, + false, + false + ] + }, + "hash": "ac09d8de92d8e1ee9b463b87b2374e11ba46e9b392414282d2d67161a6544d11" +} diff --git a/backend/.sqlx/query-af4048f53cb6ade24d825129d22624ba95b56ef9e5e4c38da329b3d9e8d2269c.json b/backend/.sqlx/query-af4048f53cb6ade24d825129d22624ba95b56ef9e5e4c38da329b3d9e8d2269c.json new file mode 100644 index 0000000000..32ca1de76f --- /dev/null +++ b/backend/.sqlx/query-af4048f53cb6ade24d825129d22624ba95b56ef9e5e4c38da329b3d9e8d2269c.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_diff_full_scan SET fork_workspace_id = $1 WHERE fork_workspace_id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + }, + "nullable": [] + }, + "hash": "af4048f53cb6ade24d825129d22624ba95b56ef9e5e4c38da329b3d9e8d2269c" +} diff --git a/backend/.sqlx/query-b8e732a03969666444f73397ac153d23ec2af084b2f93da24c920532c1916384.json b/backend/.sqlx/query-b8e732a03969666444f73397ac153d23ec2af084b2f93da24c920532c1916384.json new file mode 100644 index 0000000000..b892061f56 --- /dev/null +++ b/backend/.sqlx/query-b8e732a03969666444f73397ac153d23ec2af084b2f93da24c920532c1916384.json @@ -0,0 +1,110 @@ +{ + "db_name": "PostgreSQL", + "query": "WITH RECURSIVE job_tree AS (\n SELECT j.id, j.kind::text, j.flow_step_id, j.parent_job,\n '' as path_label, 0 as depth,\n j.id::text as id_path,\n ''::text as parent_module_type\n FROM v2_job j\n WHERE j.id = $2 AND j.workspace_id = $1\n UNION ALL\n SELECT j.id, j.kind::text, j.flow_step_id, j.parent_job,\n CASE\n WHEN jt.path_label = '' THEN COALESCE(j.flow_step_id, '')\n ELSE jt.path_label || '/' || COALESCE(j.flow_step_id, '')\n END,\n jt.depth + 1,\n jt.id_path || '/' || j.id::text,\n COALESCE((\n SELECT m->'value'->>'type'\n FROM v2_job parent_j\n LEFT JOIN flow_version fv ON fv.id = parent_j.runnable_id\n AND parent_j.kind::text = 'flow'\n LEFT JOIN flow f ON f.path = parent_j.runnable_path\n AND f.workspace_id = parent_j.workspace_id\n LEFT JOIN flow_node fn ON fn.id = parent_j.runnable_id\n CROSS JOIN LATERAL jsonb_array_elements(\n COALESCE(parent_j.raw_flow, fv.value, f.value, fn.flow)->'modules'\n ) m\n WHERE parent_j.id = jt.id\n AND m->>'id' = j.flow_step_id\n LIMIT 1\n ), '')::text\n FROM v2_job j\n JOIN job_tree jt ON j.parent_job = jt.id\n WHERE j.workspace_id = $1\n AND ($4::text[] IS NULL OR j.tag = ANY($4))\n ),\n positions AS (\n SELECT g.parent_job, g.flow_step_id, fj.jid, fj.ord\n FROM (SELECT DISTINCT parent_job, flow_step_id FROM job_tree\n WHERE parent_job IS NOT NULL AND flow_step_id IS NOT NULL) g\n CROSS JOIN LATERAL (\n SELECT COALESCE(\n (SELECT flow_status FROM v2_job_completed WHERE id = g.parent_job),\n (SELECT flow_status FROM v2_job_status WHERE id = g.parent_job)\n ) AS fs\n ) pf\n CROSS JOIN LATERAL (\n SELECT m FROM jsonb_array_elements(pf.fs->'modules') m\n WHERE m->>'id' = g.flow_step_id\n LIMIT 1\n ) md\n CROSS JOIN LATERAL jsonb_array_elements_text(md.m->'flow_jobs')\n WITH ORDINALITY fj(jid, ord)\n ),\n with_sibling_index AS (\n SELECT jt.*,\n ROW_NUMBER() OVER (\n PARTITION BY jt.parent_job, jt.flow_step_id\n ORDER BY pos.ord NULLS LAST, jt.id\n ) as sibling_index,\n COUNT(*) OVER (\n PARTITION BY jt.parent_job, jt.flow_step_id\n ) as sibling_count\n FROM job_tree jt\n LEFT JOIN positions pos ON pos.parent_job = jt.parent_job\n AND pos.flow_step_id = jt.flow_step_id\n AND pos.jid = jt.id::text\n ),\n limited AS (\n SELECT * FROM with_sibling_index ORDER BY id_path ASC LIMIT $5\n )\n SELECT w.id, w.kind, w.flow_step_id, w.path_label,\n w.sibling_index::int as sibling_index,\n w.sibling_count::int as sibling_count,\n w.depth::int as depth,\n w.parent_module_type,\n c.status::text as completed_status,\n c.duration_ms as \"duration_ms?\",\n COALESCE(c.started_at, q.started_at) as started_at,\n LEFT(c.result::text, $3) as result_prefix,\n length(c.result::text) as result_length,\n q.running as \"q_running?\",\n q.suspend as \"q_suspend?\"\n FROM limited w\n LEFT JOIN v2_job_completed c ON c.id = w.id\n LEFT JOIN v2_job_queue q ON q.id = w.id\n ORDER BY w.id_path ASC", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "kind", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "flow_step_id", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "path_label", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "sibling_index", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "sibling_count", + "type_info": "Int4" + }, + { + "ordinal": 6, + "name": "depth", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "parent_module_type", + "type_info": "Text" + }, + { + "ordinal": 8, + "name": "completed_status", + "type_info": "Text" + }, + { + "ordinal": 9, + "name": "duration_ms?", + "type_info": "Int8" + }, + { + "ordinal": 10, + "name": "started_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 11, + "name": "result_prefix", + "type_info": "Text" + }, + { + "ordinal": 12, + "name": "result_length", + "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "q_running?", + "type_info": "Bool" + }, + { + "ordinal": 14, + "name": "q_suspend?", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Text", + "Uuid", + "Int4", + "TextArray", + "Int8" + ] + }, + "nullable": [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + false, + null, + null, + null, + false, + false + ] + }, + "hash": "b8e732a03969666444f73397ac153d23ec2af084b2f93da24c920532c1916384" +} diff --git a/backend/.sqlx/query-bd594f06413dd21d7e6923e6754b58fbce8c09e6ec8172d9ed94716958a29b40.json b/backend/.sqlx/query-bd594f06413dd21d7e6923e6754b58fbce8c09e6ec8172d9ed94716958a29b40.json new file mode 100644 index 0000000000..5e9e4bfa6e --- /dev/null +++ b/backend/.sqlx/query-bd594f06413dd21d7e6923e6754b58fbce8c09e6ec8172d9ed94716958a29b40.json @@ -0,0 +1,30 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT created_by, COALESCE(flow_innermost_root_job, parent_job) as enclosing_job FROM v2_job WHERE id = $1 AND workspace_id = $2 AND ($3::text[] IS NULL OR tag = ANY($3))", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "created_by", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "enclosing_job", + "type_info": "Uuid" + } + ], + "parameters": { + "Left": [ + "Uuid", + "Text", + "TextArray" + ] + }, + "nullable": [ + false, + null + ] + }, + "hash": "bd594f06413dd21d7e6923e6754b58fbce8c09e6ec8172d9ed94716958a29b40" +} diff --git a/backend/.sqlx/query-c12d7865400f91bfb4e5b3077672b5bf3ca91f9d9bed76d2a70c454e468c5c62.json b/backend/.sqlx/query-c12d7865400f91bfb4e5b3077672b5bf3ca91f9d9bed76d2a70c454e468c5c62.json new file mode 100644 index 0000000000..7f6212aceb --- /dev/null +++ b/backend/.sqlx/query-c12d7865400f91bfb4e5b3077672b5bf3ca91f9d9bed76d2a70c454e468c5c62.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO workspace_diff (source_workspace_id, fork_workspace_id, path, kind, ahead, behind, has_changes)\n SELECT $1, $2, path, kind, 1, 0, NULL\n FROM unnest($3::varchar[], $4::varchar[]) AS t(kind, path)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "VarcharArray", + "VarcharArray" + ] + }, + "nullable": [] + }, + "hash": "c12d7865400f91bfb4e5b3077672b5bf3ca91f9d9bed76d2a70c454e468c5c62" +} diff --git a/backend/.sqlx/query-c9df59253032d0c67cb1992db849efe65c060eda6f97095ffc538d8cb89af0f1.json b/backend/.sqlx/query-c9df59253032d0c67cb1992db849efe65c060eda6f97095ffc538d8cb89af0f1.json new file mode 100644 index 0000000000..dc1185c225 --- /dev/null +++ b/backend/.sqlx/query-c9df59253032d0c67cb1992db849efe65c060eda6f97095ffc538d8cb89af0f1.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "DELETE FROM workspace_diff_full_scan WHERE (source_workspace_id = $1 AND fork_workspace_id = $2)\n OR (source_workspace_id = $2 AND fork_workspace_id = $1)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "c9df59253032d0c67cb1992db849efe65c060eda6f97095ffc538d8cb89af0f1" +} diff --git a/backend/.sqlx/query-cdfa16e7a80edc366a64823ca0e0d7f53f71b178d1b7290b1b96b4d3e73f547b.json b/backend/.sqlx/query-cdfa16e7a80edc366a64823ca0e0d7f53f71b178d1b7290b1b96b4d3e73f547b.json new file mode 100644 index 0000000000..0f8fdaf09e --- /dev/null +++ b/backend/.sqlx/query-cdfa16e7a80edc366a64823ca0e0d7f53f71b178d1b7290b1b96b4d3e73f547b.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT git_sync FROM workspace_settings WHERE workspace_id = $1 FOR UPDATE", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "git_sync", + "type_info": "Jsonb" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + true + ] + }, + "hash": "cdfa16e7a80edc366a64823ca0e0d7f53f71b178d1b7290b1b96b4d3e73f547b" +} diff --git a/backend/.sqlx/query-d20a717824d89e89969e94b024b11d425cb1dbdd132f3fba16c5fec72dd31490.json b/backend/.sqlx/query-d20a717824d89e89969e94b024b11d425cb1dbdd132f3fba16c5fec72dd31490.json new file mode 100644 index 0000000000..9d389a76c8 --- /dev/null +++ b/backend/.sqlx/query-d20a717824d89e89969e94b024b11d425cb1dbdd132f3fba16c5fec72dd31490.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT raw_app FROM app_version WHERE id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "raw_app", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false + ] + }, + "hash": "d20a717824d89e89969e94b024b11d425cb1dbdd132f3fba16c5fec72dd31490" +} diff --git a/backend/.sqlx/query-d27405e2a5dcdcc4eb6d2d9c32e4438fdd1aa44a365d201bb1bb9a19edfac6b1.json b/backend/.sqlx/query-d27405e2a5dcdcc4eb6d2d9c32e4438fdd1aa44a365d201bb1bb9a19edfac6b1.json new file mode 100644 index 0000000000..938ee01f51 --- /dev/null +++ b/backend/.sqlx/query-d27405e2a5dcdcc4eb6d2d9c32e4438fdd1aa44a365d201bb1bb9a19edfac6b1.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT scanned_at FROM workspace_diff_full_scan\n WHERE source_workspace_id = $1 AND fork_workspace_id = $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "scanned_at", + "type_info": "Timestamptz" + } + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "d27405e2a5dcdcc4eb6d2d9c32e4438fdd1aa44a365d201bb1bb9a19edfac6b1" +} diff --git a/backend/.sqlx/query-d51263081dc8bd13d13d6b3d4eac1420f42b3904dbe9d733a02def6307d711d9.json b/backend/.sqlx/query-d51263081dc8bd13d13d6b3d4eac1420f42b3904dbe9d733a02def6307d711d9.json new file mode 100644 index 0000000000..2945af3463 --- /dev/null +++ b/backend/.sqlx/query-d51263081dc8bd13d13d6b3d4eac1420f42b3904dbe9d733a02def6307d711d9.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT app.path, app_version.raw_app FROM app\n JOIN app_version ON app_version.id = app.versions[array_upper(app.versions, 1)]\n WHERE app.workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "raw_app", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "d51263081dc8bd13d13d6b3d4eac1420f42b3904dbe9d733a02def6307d711d9" +} diff --git a/backend/.sqlx/query-d6e209f9fc9af2a29702ddc4529b8596daba82911d9354ba53371b509c314732.json b/backend/.sqlx/query-d6e209f9fc9af2a29702ddc4529b8596daba82911d9354ba53371b509c314732.json new file mode 100644 index 0000000000..0f51be1a44 --- /dev/null +++ b/backend/.sqlx/query-d6e209f9fc9af2a29702ddc4529b8596daba82911d9354ba53371b509c314732.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT name FROM resource_type WHERE workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "name", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "d6e209f9fc9af2a29702ddc4529b8596daba82911d9354ba53371b509c314732" +} diff --git a/backend/.sqlx/query-de5db89535e4e04e8814d8b0d220c3659eeb80034fcb890c5a9943b4ef23e4d4.json b/backend/.sqlx/query-de5db89535e4e04e8814d8b0d220c3659eeb80034fcb890c5a9943b4ef23e4d4.json new file mode 100644 index 0000000000..1a59772918 --- /dev/null +++ b/backend/.sqlx/query-de5db89535e4e04e8814d8b0d220c3659eeb80034fcb890c5a9943b4ef23e4d4.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT datatable || '/' || timestamp || '_' || name FROM datatable_migrations\n WHERE workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "de5db89535e4e04e8814d8b0d220c3659eeb80034fcb890c5a9943b4ef23e4d4" +} diff --git a/backend/.sqlx/query-dfc33795385cb5eef70b481938542d061a5c8474b1cd8092505dcc4507270a62.json b/backend/.sqlx/query-dfc33795385cb5eef70b481938542d061a5c8474b1cd8092505dcc4507270a62.json new file mode 100644 index 0000000000..1af9e13c15 --- /dev/null +++ b/backend/.sqlx/query-dfc33795385cb5eef70b481938542d061a5c8474b1cd8092505dcc4507270a62.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT path FROM variable WHERE workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "dfc33795385cb5eef70b481938542d061a5c8474b1cd8092505dcc4507270a62" +} diff --git a/backend/.sqlx/query-e30be7c812aa294df6899892531083221146338193e38ef7268bacff58270bf8.json b/backend/.sqlx/query-e30be7c812aa294df6899892531083221146338193e38ef7268bacff58270bf8.json new file mode 100644 index 0000000000..172054980e --- /dev/null +++ b/backend/.sqlx/query-e30be7c812aa294df6899892531083221146338193e38ef7268bacff58270bf8.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n WITH RECURSIVE chain AS (\n SELECT id, parent_workspace_id, is_dev_workspace, 0 AS depth\n FROM workspace WHERE id = $1\n UNION ALL\n SELECT w.id, w.parent_workspace_id, w.is_dev_workspace, chain.depth + 1\n FROM workspace w\n JOIN chain ON w.id = chain.parent_workspace_id\n WHERE chain.depth < 20\n )\n SELECT id AS \"id!\" FROM chain\n WHERE parent_workspace_id IS NULL\n OR (is_dev_workspace AND id NOT LIKE 'wm-fork-%')\n ORDER BY depth LIMIT 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id!", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "e30be7c812aa294df6899892531083221146338193e38ef7268bacff58270bf8" +} diff --git a/backend/.sqlx/query-e903f5857d2e15f0472d9f3536493201e0ee5210f684e2735b79f929276cbc04.json b/backend/.sqlx/query-e903f5857d2e15f0472d9f3536493201e0ee5210f684e2735b79f929276cbc04.json new file mode 100644 index 0000000000..eb5085692b --- /dev/null +++ b/backend/.sqlx/query-e903f5857d2e15f0472d9f3536493201e0ee5210f684e2735b79f929276cbc04.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO workspace (id, name, owner) VALUES ('other-workspace', 'other-workspace', 'test-user')", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "e903f5857d2e15f0472d9f3536493201e0ee5210f684e2735b79f929276cbc04" +} diff --git a/backend/.sqlx/query-f1adf9d7a8a53d8e8f3c4eab8a64c2ba707ca8dcda69eba28397c3b0259fc876.json b/backend/.sqlx/query-f1adf9d7a8a53d8e8f3c4eab8a64c2ba707ca8dcda69eba28397c3b0259fc876.json new file mode 100644 index 0000000000..ea62dfde12 --- /dev/null +++ b/backend/.sqlx/query-f1adf9d7a8a53d8e8f3c4eab8a64c2ba707ca8dcda69eba28397c3b0259fc876.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT DISTINCT path FROM script WHERE workspace_id = $1 AND archived = false", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "f1adf9d7a8a53d8e8f3c4eab8a64c2ba707ca8dcda69eba28397c3b0259fc876" +} diff --git a/backend/.sqlx/query-f6f59f768dc0e34f4cad118b5252a554bf51c4581dae48c0f93f859672997544.json b/backend/.sqlx/query-f6f59f768dc0e34f4cad118b5252a554bf51c4581dae48c0f93f859672997544.json new file mode 100644 index 0000000000..f2a3d13c50 --- /dev/null +++ b/backend/.sqlx/query-f6f59f768dc0e34f4cad118b5252a554bf51c4581dae48c0f93f859672997544.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO workspace_settings (workspace_id) VALUES ('other-workspace')", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "f6f59f768dc0e34f4cad118b5252a554bf51c4581dae48c0f93f859672997544" +} diff --git a/backend/.sqlx/query-fb518edc29faa45a1b1503b151cc77c509608825721c01cb3b860c20cda49377.json b/backend/.sqlx/query-fb518edc29faa45a1b1503b151cc77c509608825721c01cb3b860c20cda49377.json new file mode 100644 index 0000000000..9863afb848 --- /dev/null +++ b/backend/.sqlx/query-fb518edc29faa45a1b1503b151cc77c509608825721c01cb3b860c20cda49377.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT 'f/' || name FROM folder WHERE workspace_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "?column?", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "fb518edc29faa45a1b1503b151cc77c509608825721c01cb3b860c20cda49377" +} diff --git a/backend/windmill-api-workspaces/src/datatable_permissions_api.rs b/backend/windmill-api-workspaces/src/datatable_permissions_api.rs index 2ea104a195..b8e6f70e4a 100644 --- a/backend/windmill-api-workspaces/src/datatable_permissions_api.rs +++ b/backend/windmill-api-workspaces/src/datatable_permissions_api.rs @@ -119,6 +119,26 @@ pub(crate) async fn check_shared_database_forbid( database: &DataTableDatabase, self_perms_enabled: bool, ) -> Result<()> { + // A DuckLake catalog on the same instance database always connects as the + // shared role, which protection revokes — enabling would silently break + // every attach to that catalog. + if self_perms_enabled + && database.resource_type + == windmill_common::workspaces::DataTableCatalogResourceType::Instance + && windmill_common::datatable_permissions::instance_database_used_by_ducklake( + db, + &database.resource_path, + ) + .await? + { + return Err(Error::BadRequest(format!( + "A DuckLake catalog is configured on instance database '{}'. DuckLake connects as \ + the shared instance role, which fine-grained permissions revoke on protected \ + databases, so the two cannot share one database. Move the data table (or the \ + lake) to its own database first.", + database.resource_path + ))); + } let resource_type = match database.resource_type { windmill_common::workspaces::DataTableCatalogResourceType::Instance => "instance", windmill_common::workspaces::DataTableCatalogResourceType::Postgresql => "postgresql", diff --git a/backend/windmill-api-workspaces/src/workspaces.rs b/backend/windmill-api-workspaces/src/workspaces.rs index d5272453c6..3ef2bf2514 100644 --- a/backend/windmill-api-workspaces/src/workspaces.rs +++ b/backend/windmill-api-workspaces/src/workspaces.rs @@ -3139,9 +3139,6 @@ async fn edit_datatable_config( } } // An external target must be able to create the enforcement roles. - // Instance targets are skipped: their roles are managed by the main - // pool user, and the instance database may legitimately not be set up - // yet when the config is saved. if self_enabled && dt.database.resource_type == DataTableCatalogResourceType::Postgresql { if let Err(e) = crate::datatable_permissions_api::check_owner_can_create_roles(&db, &w_id, dt).await @@ -3153,6 +3150,31 @@ async fn edit_datatable_config( } } } + // An instance target must get its dedicated owner role NOW: saving the + // config as protected while the shared role still holds CONNECT would + // advertise an enforcement that isn't there — and with the default + // empty grants nothing would ever reach the lazy provisioning path to + // repair it. If the database isn't ready (not set up yet), fall back to + // disabled rather than claim protection. + if self_enabled && dt.database.resource_type == DataTableCatalogResourceType::Instance { + if let Err(e) = windmill_common::datatable_permissions::provision_instance_owner_role( + &db, + &w_id, + &dt.database.resource_path, + ) + .await + { + if self_defaulted { + tracing::info!( + "not enabling data table permissions by default on {}: {e:#}", + dt.database.resource_path + ); + default_disabled.push(name.clone()); + } else { + return Err(e); + } + } + } } for name in default_disabled { if let Some(dt) = new_config.settings.datatables.get_mut(&name) { @@ -4755,6 +4777,16 @@ async fn set_encryption_key( let mut tx = db.begin().await?; + // Before touching the key row: a resolver that already holds + // WORKSPACE_ROLES_LOCK reads the workspace key on a SEPARATE pool + // connection, so updating the row first and then waiting for that lock + // deadlocks in a way Postgres cannot see (the wait crosses connections). + // Taking the lock first makes the two operations strictly ordered. + sqlx::query(windmill_common::datatable_permissions::WORKSPACE_ROLES_LOCK) + .bind(&w_id) + .execute(&mut *tx) + .await?; + sqlx::query!( "UPDATE workspace_key SET key = $1 WHERE workspace_id = $2", request.new_key.clone(), @@ -4819,10 +4851,6 @@ async fn set_encryption_key( // workspace lock keeps role creation from inserting old-key // ciphertext after this scan; the per-role locks keep an in-flight // teardown/sweep from acting across the key switch. Held to commit. - sqlx::query(windmill_common::datatable_permissions::WORKSPACE_ROLES_LOCK) - .bind(&w_id) - .execute(&mut *tx) - .await?; let dt_roles = sqlx::query!( "SELECT role_name, password, owner_creds FROM datatable_ephemeral_role WHERE workspace_id = $1", w_id diff --git a/backend/windmill-common/src/datatable_permissions.rs b/backend/windmill-common/src/datatable_permissions.rs index a29101bdc5..f6dc925507 100644 --- a/backend/windmill-common/src/datatable_permissions.rs +++ b/backend/windmill-common/src/datatable_permissions.rs @@ -447,6 +447,26 @@ async fn connect_instance_db_as_superuser(db: &DB, dbname: &str) -> Result Result<()> { + let version: i32 = sqlx::query_scalar("SELECT current_setting('server_version_num')::int") + .fetch_one(db) + .await + .map_err(|e| Error::internal_err(format!("reading Postgres version: {e:#}")))?; + if version < 160000 { + return Err(Error::BadRequest(format!( + "Fine-grained permissions on instance data tables require PostgreSQL 16 or later \ + (this cluster reports {version}). On older versions a role with CREATEROLE can \ + take over the database's owner role, so the grants could not be enforced. Use an \ + external PostgreSQL data table instead, or upgrade the cluster." + ))); + } + Ok(()) +} + /// Make sure a protected instance database has its dedicated owner role: a /// `LOGIN` role that owns the database's objects, can create the ephemeral /// roles, and is never handed to non-admin SQL. `custom_instance_user` loses @@ -455,6 +475,7 @@ async fn connect_instance_db_as_superuser(db: &DB, dbname: &str) -> Result Result<()> { + ensure_instance_enforcement_supported(db).await?; let role = instance_owner_role_name(dbname); let mut tx = db.begin().await?; sqlx::query(OWNER_ROLE_LOCK) @@ -670,12 +691,79 @@ pub async fn deprovision_instance_owner_role(db: &DB, dbname: &str) -> Result<() /// Best-effort [`deprovision_instance_owner_role`] for the paths where a /// failure must not block the operation (config saves, database re-points). +/// +/// Re-reads the live config first: these run after their transaction commits, +/// so a concurrent enable may already have re-provisioned this database. A +/// blind deprovision would then hand a still-protected database back to the +/// shared role. pub async fn deprovision_instance_owner_role_best_effort(db: &DB, dbname: &str) { + match instance_database_still_protected(db, dbname).await { + Ok(true) => { + tracing::info!( + "skipping deprovision of {dbname}: a data table with permissions enabled still \ + points at it" + ); + return; + } + Ok(false) => {} + Err(e) => { + tracing::warn!("checking protection state of {dbname} before deprovision: {e:#}"); + return; + } + } if let Err(e) = deprovision_instance_owner_role(db, dbname).await { tracing::warn!("deprovisioning owner role of instance database {dbname}: {e:#}"); } } +/// Whether any workspace still has a permissions-enabled data table pointing +/// at this instance database. +async fn instance_database_still_protected(db: &DB, dbname: &str) -> Result { + Ok(sqlx::query_scalar!( + r#" + SELECT EXISTS( + SELECT 1 + FROM workspace_settings ws + CROSS JOIN LATERAL jsonb_each( + CASE WHEN jsonb_typeof(ws.datatable->'datatables') = 'object' + THEN ws.datatable->'datatables' + ELSE '{}'::jsonb END + ) AS dt(key, value) + WHERE dt.value->'database'->>'resource_type' = 'instance' + AND dt.value->'database'->>'resource_path' = $1 + AND COALESCE((dt.value->'permissions'->>'enabled')::boolean, false) + ) AS "e!" + "#, + dbname + ) + .fetch_one(db) + .await?) +} + +/// Whether a DuckLake catalog is configured on this instance database. Such a +/// catalog always connects as the shared role, which protection revokes — so +/// the two cannot coexist on one database. +pub async fn instance_database_used_by_ducklake(db: &DB, dbname: &str) -> Result { + Ok(sqlx::query_scalar!( + r#" + SELECT EXISTS( + SELECT 1 + FROM workspace_settings ws + CROSS JOIN LATERAL jsonb_each( + CASE WHEN jsonb_typeof(ws.ducklake->'ducklakes') = 'object' + THEN ws.ducklake->'ducklakes' + ELSE '{}'::jsonb END + ) AS dl(key, value) + WHERE value->'catalog'->>'resource_type' = 'instance' + AND value->'catalog'->>'resource_path' = $1 + ) AS "e!" + "#, + dbname + ) + .fetch_one(db) + .await?) +} + // --------------------------------------------------------------------------- // Role lifecycle // --------------------------------------------------------------------------- @@ -1392,6 +1480,33 @@ pub async fn teardown_snapshot_roles_best_effort(db: &DB, w_id: &str, snapshot: } } +/// Revoke one caller's ephemeral role on a data table, if it still exists. +/// Best-effort: a failure leaves the bookkeeping row in place, so the expiry +/// sweep retries; the caller is denied either way. +pub(crate) async fn revoke_caller_role( + db: &DB, + w_id: &str, + datatable: &str, + permissioned_as: &str, +) { + let role = ephemeral_role_name(w_id, permissioned_as, datatable); + let exists = sqlx::query_scalar!( + "SELECT 1 FROM datatable_ephemeral_role WHERE role_name = $1", + &role + ) + .fetch_optional(db) + .await + .ok() + .flatten() + .is_some(); + if !exists { + return; + } + if let Err(e) = teardown_role(db, w_id, datatable, &role, None).await { + tracing::warn!("revoking datatable ephemeral role {role} after losing its grants: {e:#}"); + } +} + /// Strict teardown of every role of a workspace, for workspace deletion: the /// bookkeeping rows (and the workspace key their targets are encrypted with) /// are about to cascade away, so every role must be revoked NOW — dropped, or @@ -1644,6 +1759,11 @@ pub async fn get_datatable_resource_from_db_checked( let (matched, memberships) = compute_effective_grants(db, w_id, permissioned_as, grants).await?; if matched.is_empty() { + // Losing the last grant (group/folder membership change, edited + // statements) must revoke the role NOW, not at expiry: the caller may + // have set its password from their own SQL, so a role left LOGIN-capable + // is a live direct connection long after Windmill says "denied". + revoke_caller_role(db, w_id, name, permissioned_as).await; return Err(Error::PermissionDenied(format!( "You have no permissions on data table '{name}'. Ask a workspace admin to grant \ you access in the data table's permission settings."