CREATE OR REPLACE FUNCTION storage.search_v2 ( prefix text, bucket_name text, limits int DEFAULT 100, levels int default 1, start_after text DEFAULT '' ) RETURNS TABLE ( key text, name text, id uuid, updated_at timestamptz, created_at timestamptz, metadata jsonb ) SECURITY INVOKER AS $func$ BEGIN RETURN query EXECUTE $sql$ SELECT * FROM ( ( SELECT split_part(name, '/', $4) AS key, name || '/' AS name, NULL::uuid AS id, NULL::timestamptz AS updated_at, NULL::timestamptz AS created_at, NULL::jsonb AS metadata FROM storage.prefixes WHERE name COLLATE "C" LIKE $1 || '%' AND bucket_id = $2 AND level = $4 AND name COLLATE "C" > $5 ORDER BY prefixes.name COLLATE "C" LIMIT $3 ) UNION ALL (SELECT split_part(name, '/', $4) AS key, name, id, updated_at, created_at, metadata FROM storage.objects WHERE name COLLATE "C" LIKE $1 || '%' AND bucket_id = $2 AND level = $4 AND name COLLATE "C" > $5 ORDER BY name COLLATE "C" LIMIT $3) ) obj ORDER BY name COLLATE "C" LIMIT $3; $sql$ USING prefix, bucket_name, limits, levels, start_after; END; $func$ LANGUAGE plpgsql STABLE;