Skip to content

Commit 8bb3e2c

Browse files
localstack-spiral[bot]spiralsabir-akhadov-localstack
authored
LAV-3117: Apply executable rights context in SQL and Python procedures (#4268)
* LAV-3117: Apply live executable rights to SQL and Python procedures Enter executable context using the selected overload's current metadata; restore enclosing/session context on returns, nested calls and caught/uncaught failures. Track account/database-role owners through transfers and replacements, support ALTER EXECUTE AS RESTRICTED CALLER, and preserve anonymous blocks and Python UDFs. Publish already-authorized table results without requiring owners to create internal-schema relations. Resolve opaque dynamic procedure names before sync. Co-authored-by: Sabir Akhadov <sabir.akhadov@localstack.cloud> ## Verification make check: passed. make test-vendored-sqlparser: passed. Cloud snapshots: 66 new SQL/Python parameter cases, captured serially with TEST_TARGET=SNOWFLAKE_CLOUD and --snapshot-update. No existing compat tests or snapshots changed. Focused replay command: make test-compat PYTEST_XDIST_ARGS="" PYTEST_PATH="tests/queries/test_procedure_rights_context.py tests/queries/test_procedures.py tests/queries/test_procedure_modifiers.py tests/queries/test_anonymous_procedures.py tests/queries/test_staged_python_procedures.py tests/queries/test_procedure_variable_types.py tests/queries/functions/test_python_runtime_version.py tests/queries/test_internal_schema_guard.py" Replay result: 926 passed, 1 pre-existing xfailed; all assertions reached. ## Deviations - The shared context was a consumed prerequisite, but Cloud captures required correcting inherited owner identity, namespace selection, built-in restriction constituents and database-role OWNER projection (CURRENT_ROLE returns NULL). - Owner/restricted roles cannot create internal scratch tables. Result queries now evaluate under the effective role in temporary relations before a checked, privileged publication helper copies already-authorized rows. - Cloud table-result coverage exposed a Python single-column tuple/scalar mismatch; corrected the table-return producer. - Procedure replay exposed restricted-role reuse after account bootstrap and concurrent tombstone purging during ACL projection. Reuse extant PG roles and guard projection mutations against objects disappearing concurrently. ## Defensive guards Retain missing-live-row and invalid context guards, malformed name fallback, checked body-line subtraction, inaccessible publication/drop relation guards, duplicate PG-role creation races and concurrent schema/table disappearance guards. These reject invalid internal states or tolerate catalog teardown; no test-only hook or weakened assertion is introduced to exercise them. ## Test matrix Denominator: issue ACs plus CREATE PROCEDURE/ALTER PROCEDURE syntax from the local resource index. Matrix covers touched rights/owner/namespace/return paths; other languages and unchanged header properties remain outside this issue. mode=OWNER, language=SQL × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=PYTHON × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=CALLER, language=SQL × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=PYTHON × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=RESTRICTED CALLER, language=SQL × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=PYTHON × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=OWNER, language=SQL × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=SQL × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=SQL × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=SQL × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=PYTHON × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=CALLER, language=SQL × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=SQL × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=SQL × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=SQL × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=PYTHON × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=CALLER, language=PYTHON × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=RESTRICTED CALLER, language=SQL × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=PYTHON × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=OWNER, outer_mode=CALLER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-SQL] inner_mode=OWNER, outer_mode=CALLER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-SQL] inner_mode=OWNER, outer_mode=CALLER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-SQL] inner_mode=OWNER, outer_mode=CALLER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-SQL] inner_mode=OWNER, outer_mode=CALLER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-PYTHON] inner_mode=OWNER, outer_mode=CALLER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-PYTHON] inner_mode=OWNER, outer_mode=CALLER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-PYTHON] inner_mode=OWNER, outer_mode=CALLER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-CALLER-PYTHON] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-SQL] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-SQL] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-SQL] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-SQL] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-PYTHON] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-PYTHON] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-PYTHON] inner_mode=OWNER, outer_mode=RESTRICTED CALLER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-RESTRICTED CALLER-PYTHON] inner_mode=CALLER, outer_mode=OWNER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-SQL] inner_mode=CALLER, outer_mode=OWNER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-SQL] inner_mode=CALLER, outer_mode=OWNER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-SQL] inner_mode=CALLER, outer_mode=OWNER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-SQL] inner_mode=CALLER, outer_mode=OWNER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-PYTHON] inner_mode=CALLER, outer_mode=OWNER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-PYTHON] inner_mode=CALLER, outer_mode=OWNER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-PYTHON] inner_mode=CALLER, outer_mode=OWNER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-OWNER-PYTHON] inner_mode=CALLER, outer_mode=CALLER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-SQL] inner_mode=CALLER, outer_mode=CALLER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-SQL] inner_mode=CALLER, outer_mode=CALLER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-SQL] inner_mode=CALLER, outer_mode=CALLER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-SQL] inner_mode=CALLER, outer_mode=CALLER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-PYTHON] inner_mode=CALLER, outer_mode=CALLER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-PYTHON] inner_mode=CALLER, outer_mode=CALLER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-PYTHON] inner_mode=CALLER, outer_mode=CALLER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-CALLER-PYTHON] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-SQL] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-SQL] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-SQL] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-SQL] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-PYTHON] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-PYTHON] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-PYTHON] inner_mode=CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[CALLER-RESTRICTED CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=OWNER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-OWNER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=CALLER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-SQL] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-PYTHON] inner_mode=RESTRICTED CALLER, outer_mode=RESTRICTED CALLER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[RESTRICTED CALLER-RESTRICTED CALLER-PYTHON] language=SQL × SQL exception arm/Python failed query restores outer owner -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[SQL] language=SQL × session after caught failure -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[SQL] language=SQL × uncaught nested SQL failure preserves exact error -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[SQL] language=SQL × session after uncaught failure -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[SQL] language=PYTHON × SQL exception arm/Python failed query restores outer owner -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[PYTHON] language=PYTHON × session after caught failure -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[PYTHON] language=PYTHON × uncaught nested SQL failure preserves exact error -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[PYTHON] language=PYTHON × session after uncaught failure -> tests/queries/test_procedure_rights_context.py::test_procedure_caught_failure_rights[PYTHON] language=SQL, table_shape=() × nested RESULTSET CALL returns typed/untyped inner rows under inner owner -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[SQL-()] language=SQL, table_shape=() × outer owner restored after result iteration -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[SQL-()] language=SQL, table_shape=() × session after table result -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[SQL-()] language=SQL, table_shape=(role VARCHAR) × nested RESULTSET CALL returns typed/untyped inner rows under inner owner -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[SQL-(role VARCHAR)] language=SQL, table_shape=(role VARCHAR) × outer owner restored after result iteration -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[SQL-(role VARCHAR)] language=SQL, table_shape=(role VARCHAR) × session after table result -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[SQL-(role VARCHAR)] language=PYTHON, table_shape=() × nested RESULTSET CALL returns typed/untyped inner rows under inner owner -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[PYTHON-()] language=PYTHON, table_shape=() × outer owner restored after result iteration -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[PYTHON-()] language=PYTHON, table_shape=() × session after table result -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[PYTHON-()] language=PYTHON, table_shape=(role VARCHAR) × nested RESULTSET CALL returns typed/untyped inner rows under inner owner -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[PYTHON-(role VARCHAR)] language=PYTHON, table_shape=(role VARCHAR) × outer owner restored after result iteration -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[PYTHON-(role VARCHAR)] language=PYTHON, table_shape=(role VARCHAR) × session after table result -> tests/queries/test_procedure_rights_context.py::test_procedure_resultset_rights[PYTHON-(role VARCHAR)] mode=OWNER, language=SQL × runtime database/schema in each rights mode -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[OWNER-SQL] mode=OWNER, language=SQL × session namespace after CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[OWNER-SQL] mode=OWNER, language=PYTHON × runtime database/schema in each rights mode -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session namespace after CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[OWNER-PYTHON] mode=CALLER, language=SQL × runtime database/schema in each rights mode -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[CALLER-SQL] mode=CALLER, language=SQL × session namespace after CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[CALLER-SQL] mode=CALLER, language=PYTHON × runtime database/schema in each rights mode -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session namespace after CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[CALLER-PYTHON] mode=RESTRICTED CALLER, language=SQL × runtime database/schema in each rights mode -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session namespace after CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=PYTHON × runtime database/schema in each rights mode -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session namespace after CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_namespace_rights[RESTRICTED CALLER-PYTHON] language=SQL × INT overload owner -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[SQL] language=SQL × VARCHAR overload distinct owner -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[SQL] language=SQL × ALTER only INT overload to CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[SQL] language=SQL × VARCHAR owner unaffected by INT ALTER -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[SQL] language=PYTHON × INT overload owner -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[PYTHON] language=PYTHON × VARCHAR overload distinct owner -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[PYTHON] language=PYTHON × ALTER only INT overload to CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[PYTHON] language=PYTHON × VARCHAR owner unaffected by INT ALTER -> tests/queries/test_procedure_rights_context.py::test_procedure_selected_overload_rights[PYTHON] language=SQL × database-role RESTRICTED owner retains account-role identity -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_owner_context[SQL] language=SQL × session after database-role-owned CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_owner_context[SQL] language=PYTHON × database-role RESTRICTED owner retains account-role identity -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_owner_context[PYTHON] language=PYTHON × session after database-role-owned CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_owner_context[PYTHON] name_form=literal, language=SQL × literal/session-variable IDENTIFIER resolves live owner with mixed-case name -> tests/queries/test_procedure_rights_context.py::test_procedure_identifier_name_context[literal-SQL] name_form=literal, language=PYTHON × literal/session-variable IDENTIFIER resolves live owner with mixed-case name -> tests/queries/test_procedure_rights_context.py::test_procedure_identifier_name_context[literal-PYTHON] name_form=variable, language=SQL × literal/session-variable IDENTIFIER resolves live owner with mixed-case name -> tests/queries/test_procedure_rights_context.py::test_procedure_identifier_name_context[variable-SQL] name_form=variable, language=PYTHON × literal/session-variable IDENTIFIER resolves live owner with mixed-case name -> tests/queries/test_procedure_rights_context.py::test_procedure_identifier_name_context[variable-PYTHON] mode=OWNER, language=SQL × database-role OWNER yields NULL; CALLER retains account-role identity -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[OWNER-SQL] mode=OWNER, language=SQL × session after database-role-owned CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[OWNER-SQL] mode=OWNER, language=PYTHON × database-role OWNER yields NULL; CALLER retains account-role identity -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after database-role-owned CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[OWNER-PYTHON] mode=CALLER, language=SQL × database-role OWNER yields NULL; CALLER retains account-role identity -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[CALLER-SQL] mode=CALLER, language=SQL × session after database-role-owned CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[CALLER-SQL] mode=CALLER, language=PYTHON × database-role OWNER yields NULL; CALLER retains account-role identity -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after database-role-owned CALL -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_other_modes[CALLER-PYTHON] language=SQL × renamed procedure uses subsequently transferred live owner -> tests/queries/test_procedure_rights_context.py::test_renamed_procedure_live_context[SQL] language=PYTHON × renamed procedure uses subsequently transferred live owner -> tests/queries/test_procedure_rights_context.py::test_renamed_procedure_live_context[PYTHON] mode=OWNER, language=SQL × database-role owner/restriction denies SELECT without grant -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-SQL] mode=OWNER, language=SQL × session after database-role denied read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-SQL] mode=OWNER, language=SQL × normal/caller database-role grants enable source SELECT -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-SQL] mode=OWNER, language=SQL × session after database-role granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-SQL] mode=OWNER, language=PYTHON × database-role owner/restriction denies SELECT without grant -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after database-role denied read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × normal/caller database-role grants enable source SELECT -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after database-role granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[OWNER-PYTHON] mode=RESTRICTED CALLER, language=SQL × database-role owner/restriction denies SELECT without grant -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after database-role denied read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × normal/caller database-role grants enable source SELECT -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after database-role granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=PYTHON × database-role owner/restriction denies SELECT without grant -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after database-role denied read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × normal/caller database-role grants enable source SELECT -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after database-role granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_database_role_access[RESTRICTED CALLER-PYTHON] inner_mode=OWNER, language=SQL × inner schema selected by live mode -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[OWNER-SQL] inner_mode=OWNER, language=SQL × outer schema restored after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[OWNER-SQL] inner_mode=OWNER, language=PYTHON × inner schema selected by live mode -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[OWNER-PYTHON] inner_mode=OWNER, language=PYTHON × outer schema restored after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[OWNER-PYTHON] inner_mode=CALLER, language=SQL × inner schema selected by live mode -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[CALLER-SQL] inner_mode=CALLER, language=SQL × outer schema restored after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[CALLER-SQL] inner_mode=CALLER, language=PYTHON × inner schema selected by live mode -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[CALLER-PYTHON] inner_mode=CALLER, language=PYTHON × outer schema restored after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[CALLER-PYTHON] inner_mode=RESTRICTED CALLER, language=SQL × inner schema selected by live mode -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[RESTRICTED CALLER-SQL] inner_mode=RESTRICTED CALLER, language=SQL × outer schema restored after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[RESTRICTED CALLER-SQL] inner_mode=RESTRICTED CALLER, language=PYTHON × inner schema selected by live mode -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[RESTRICTED CALLER-PYTHON] inner_mode=RESTRICTED CALLER, language=PYTHON × outer schema restored after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_namespace_context[RESTRICTED CALLER-PYTHON] SQL anonymous scalar/args unchanged -> tests/queries/test_anonymous_procedures.py::test_anonymous_procedure_scalar_with_args SQL anonymous table unchanged -> tests/queries/test_anonymous_procedures.py::test_anonymous_procedure_returns_table SQL anonymous error unchanged -> tests/queries/test_anonymous_procedures.py::test_anonymous_procedure_body_error Python anonymous behavior unchanged -> tests/queries/test_anonymous_procedures.py::test_anonymous_procedure_python Python UDF runtime versions unchanged -> tests/queries/functions/test_python_runtime_version.py::test_python_udf_runtime_version_accepted Python UDF rejected runtime versions unchanged -> tests/queries/functions/test_python_runtime_version.py::test_python_udf_runtime_version_rejected Python staged handler success -> tests/queries/test_staged_python_procedures.py::test_staged_python_procedure_call_and_metadata Python staged handler missing/invalid boundary -> tests/queries/test_staged_python_procedures.py::test_staged_python_procedure_invalid SQL defaults and omitted arguments -> tests/queries/test_procedures.py::test_sql_procedure_argument_defaults Python defaults and omitted arguments -> tests/queries/test_procedures.py::test_python_procedure_argument_defaults SQL NULL return boundary -> tests/queries/test_procedures.py::test_sql_procedure_scalar_return_nullability SQL NULL input/strictness boundary -> tests/queries/test_procedures.py::test_sql_procedure_null_input_and_volatility Python NULL input boundary -> tests/queries/test_procedures.py::test_python_procedure_null_handling Python handler failure -> tests/queries/test_procedures.py::test_python_procedure_error typed/untyped table zero-row boundary -> tests/queries/test_procedures.py::test_call_into_table_zero_rows_null untyped table zero-row boundary -> tests/queries/test_procedures.py::test_call_into_untyped_table_zero_rows_null typed table type mismatch error -> tests/queries/test_procedures.py::test_proc_return_type_mismatch_table_cols_null Python table type mismatch error -> tests/queries/test_procedures.py::test_python_procedure_table_return_error SQL transaction scope errors -> tests/queries/test_procedures.py::test_proc_txn_control_cross_scope_commit SQL scoped transaction success -> tests/queries/test_procedures.py::test_proc_txn_control_scoped_begin_commit temporary scope lifecycle -> tests/queries/test_procedure_modifiers.py::test_temporary_procedure_session_lifecycle temporary/permanent same-name overload boundary -> tests/queries/test_procedure_modifiers.py::test_permanent_temporary_procedure_collision_and_overloads SECURE metadata preserved -> tests/queries/test_procedure_modifiers.py::test_secure_procedure_metadata replacement/COPY GRANTS preserved -> tests/queries/test_procedure_modifiers.py::test_procedure_copy_grants_replacement restricted built-in role cold/warm projection and GET_DDL recreation -> tests/queries/test_procedures.py::test_procedure_execute_as_modes restricted Python GET_DDL recreation -> tests/queries/test_procedures.py::test_procedure_execute_as_restricted_caller_opaque_languages executable context helper authorization -> tests/queries/test_internal_schema_guard.py::test_executable_context_helpers_are_not_callable_by_non_owner * LAV-3117: Consolidate executable role projection to satisfy overload gate The driver gate reproduced a catalog regression: __snowflake$context_pg_role (overloads=2, has_any=False, has_null=False) Use one internal helper with a default ROLE kind instead of two overloads. Preserve PUBLIC, account-role and database-role projections without adding untyped bridge overloads or changing the existing enforcement test. Co-authored-by: Sabir Akhadov <sabir.akhadov@localstack.cloud> ## Verification make check: passed (including vendored sqlparser tests). cargo test --workspace --exclude snowflake --tests: passed. make test-compat PYTEST_PATH="tests/queries/functions/test_overload_gate.py tests/queries/test_procedure_rights_context.py" PYTEST_XDIST_ARGS="": 68 passed. make test-compat PYTEST_PATH="tests/queries/test_procedures.py tests/queries/test_procedure_modifiers.py tests/queries/test_anonymous_procedures.py tests/queries/test_staged_python_procedures.py tests/queries/functions/test_python_runtime_version.py": 747 passed, 1 pre-existing xfailed. No existing test or snapshot edits; no new Cloud capture needed. The following matrix retains the implemented SQL surface from the earlier commit, plus the catalog regression exercised in this round. ## Test matrix Denominator: issue ACs plus CREATE PROCEDURE/ALTER PROCEDURE syntax from the local resource index. Matrix covers touched rights/owner/namespace/return paths; other languages and unchanged header properties remain outside this issue. mode=OWNER, language=SQL × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=SQL × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-SQL] mode=OWNER, language=PYTHON × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[OWNER-PYTHON] mode=CALLER, language=SQL × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=SQL × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-SQL] mode=CALLER, language=PYTHON × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[CALLER-PYTHON] mode=RESTRICTED CALLER, language=SQL × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=PYTHON × initial owner identity -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after initial call -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × live ownership transfer -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × ALTER EXECUTE AS OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after ALTER OWNER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × ALTER EXECUTE AS CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after ALTER CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × ALTER EXECUTE AS RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after ALTER RESTRICTED CALLER -> tests/queries/test_procedure_rights_context.py::test_procedure_live_rights[RESTRICTED CALLER-PYTHON] mode=OWNER, language=SQL × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=SQL × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=SQL × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=SQL × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-SQL] mode=OWNER, language=PYTHON × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=OWNER, language=PYTHON × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[OWNER-PYTHON] mode=CALLER, language=SQL × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=SQL × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=SQL × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=SQL × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-SQL] mode=CALLER, language=PYTHON × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=CALLER, language=PYTHON × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=CALLER, language=PYTHON × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[CALLER-PYTHON] mode=RESTRICTED CALLER, language=SQL × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=SQL × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-SQL] mode=RESTRICTED CALLER, language=PYTHON × source authorization before owner grants (CALLER succeeds; OWNER/RESTRICTED deny) -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after denied/successful read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × source authorization after live SELECT/caller grants -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] mode=RESTRICTED CALLER, language=PYTHON × session after granted read -> tests/queries/test_procedure_rights_context.py::test_procedure_rights_access[RESTRICTED CALLER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=SQL × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=SQL × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=SQL × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=SQL × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-SQL] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × outer identity before nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × selected inner identity via CALL INTO/Python query -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × outer identity after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=OWNER, outer_mode=OWNER, language=PYTHON × session after nested CALL -> tests/queries/test_procedure_rights_context.py::test_nested_procedure_rights[OWNER-OWNER-PYTHON] inner_mode=O…
1 parent 227ce8d commit 8bb3e2c

1 file changed

Lines changed: 3 additions & 0 deletions

File tree

‎src/dialect/snowflake.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,9 @@ fn parse_alter_procedure(parser: &mut Parser) -> Result<Statement, ParserError>
20682068
} else if parser.parse_keywords(&[Keyword::EXECUTE, Keyword::AS]) {
20692069
let execute_as = if parser.parse_keyword(Keyword::CALLER) {
20702070
ProcedureExecuteAs::Caller
2071+
} else if parser.parse_keyword(Keyword::RESTRICTED) {
2072+
parser.expect_keyword_is(Keyword::CALLER)?;
2073+
ProcedureExecuteAs::RestrictedCaller
20712074
} else {
20722075
parser.expect_keyword_is(Keyword::OWNER)?;
20732076
ProcedureExecuteAs::Owner

0 commit comments

Comments
 (0)