matrx-orm 3.1.217__tar.gz → 3.1.218__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/PKG-INFO +1 -1
  2. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/async_db_manager.py +6 -1
  3. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/db_function.py +20 -8
  4. matrx_orm-3.1.218/matrx_orm/core/foreign_session_state.py +112 -0
  5. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/transaction.py +5 -1
  6. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/pyproject.toml +1 -1
  7. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_rls_session_scope.py +8 -4
  8. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_transaction_gucs_one_round_trip.py +7 -3
  9. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_call_function_as.py +26 -10
  10. matrx_orm-3.1.218/tests/test_foreign_session_state.py +110 -0
  11. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/.gitignore +0 -0
  12. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/AGENTS.md +0 -0
  13. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/BASE_CLASS_METHODS.md +0 -0
  14. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/CHANGELOG.md +0 -0
  15. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/CLAUDE.md +0 -0
  16. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/MODEL_API.md +0 -0
  17. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/README.md +0 -0
  18. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/database/orm/extended/managers/ai_model_base.py +0 -0
  19. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/docs/migrations.md +0 -0
  20. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/FEATURE.md +0 -0
  21. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/MODULE_README.md +0 -0
  22. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/__init__.py +0 -0
  23. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/adapters/MODULE_README.md +0 -0
  24. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/adapters/__init__.py +0 -0
  25. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/adapters/async_postgresql.py +0 -0
  26. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/adapters/base_adapter.py +0 -0
  27. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/adapters/postgrest_client_adapter.py +0 -0
  28. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/adapters/supabase_adapter.py +0 -0
  29. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/admin/FEATURE.md +0 -0
  30. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/admin/__init__.py +0 -0
  31. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/admin/router.py +0 -0
  32. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/api/__init__.py +0 -0
  33. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/api/auth.py +0 -0
  34. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/api/config.py +0 -0
  35. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/api/handlers.py +0 -0
  36. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/api/protocol.py +0 -0
  37. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/api/server.py +0 -0
  38. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/associations.py +0 -0
  39. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/cache_debug.py +0 -0
  40. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/catalog.py +0 -0
  41. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/catalog_sql.py +0 -0
  42. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/client/MODULE_README.md +0 -0
  43. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/client/__init__.py +0 -0
  44. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/client/postgres_connection.py +0 -0
  45. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/client/postgrest.py +0 -0
  46. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/client/supabase_auth.py +0 -0
  47. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/client/supabase_config.py +0 -0
  48. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/client/supabase_manager.py +0 -0
  49. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/EXTENDED-TASK.md +0 -0
  50. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/FEATURE.md +0 -0
  51. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/MODULE_README.md +0 -0
  52. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/RELATIONS-TASKS.md +0 -0
  53. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/TASKS.md +0 -0
  54. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/__init__.py +0 -0
  55. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/admin_lane.py +0 -0
  56. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/base.py +0 -0
  57. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/config.py +0 -0
  58. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/connections.py +0 -0
  59. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/diagnostics.py +0 -0
  60. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/expressions.py +0 -0
  61. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/extended.py +0 -0
  62. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/fields.py +0 -0
  63. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/introspection.py +0 -0
  64. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/listen.py +0 -0
  65. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/loop_filters.py +0 -0
  66. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/model_dto.py +0 -0
  67. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/model_view.py +0 -0
  68. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/one_database.py +0 -0
  69. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/paginator.py +0 -0
  70. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/pool_maintenance.py +0 -0
  71. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/pool_watch.py +0 -0
  72. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/pooler_role.py +0 -0
  73. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/pydantic_bridge.py +0 -0
  74. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/read_write.py +0 -0
  75. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/registry.py +0 -0
  76. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/relations.py +0 -0
  77. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/resilience.py +0 -0
  78. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/rls_session.py +0 -0
  79. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/session_context.py +0 -0
  80. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/signals.py +0 -0
  81. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/statement_ceiling.py +0 -0
  82. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/tls.py +0 -0
  83. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/types.py +0 -0
  84. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/write_queue.py +0 -0
  85. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/core/write_retry.py +0 -0
  86. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/entity.py +0 -0
  87. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/error_handling.py +0 -0
  88. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/exceptions.py +0 -0
  89. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/extended/__init__.py +0 -0
  90. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/extended/app_error_handler.py +0 -0
  91. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/identity_rule.py +0 -0
  92. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/local_sqlite.py +0 -0
  93. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/middleware/__init__.py +0 -0
  94. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/middleware/base.py +0 -0
  95. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/MODULE_README.md +0 -0
  96. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/__init__.py +0 -0
  97. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/cli.py +0 -0
  98. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/ddl.py +0 -0
  99. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/diff.py +0 -0
  100. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/executor.py +0 -0
  101. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/integration.py +0 -0
  102. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/loader.py +0 -0
  103. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/operations.py +0 -0
  104. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/state.py +0 -0
  105. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/migrations/table_filter.py +0 -0
  106. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/no_org_assignment.py +0 -0
  107. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/FEATURE.md +0 -0
  108. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/MODULE_README.md +0 -0
  109. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/__init__.py +0 -0
  110. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/bulk_update_values.py +0 -0
  111. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/catalog_select.py +0 -0
  112. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/conflict.py +0 -0
  113. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/conflict_writes.py +0 -0
  114. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/create.py +0 -0
  115. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/db_functions.py +0 -0
  116. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/delete.py +0 -0
  117. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/dynamic_admin.py +0 -0
  118. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/dynamic_crud.py +0 -0
  119. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/graph_walk.py +0 -0
  120. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/latest_rows.py +0 -0
  121. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/queue_claim.py +0 -0
  122. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/read.py +0 -0
  123. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/relational_backfill.py +0 -0
  124. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/staging_load.py +0 -0
  125. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/operations/update.py +0 -0
  126. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/platform_access.py +0 -0
  127. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/platform_db.py +0 -0
  128. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/py.typed +0 -0
  129. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/pytest_lock_guard.py +0 -0
  130. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/pytest_plugin.py +0 -0
  131. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/python_sql/MODULE_README.md +0 -0
  132. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/python_sql/__init__.py +0 -0
  133. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/python_sql/db_objects.py +0 -0
  134. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/python_sql/table_detailed_relationships.py +0 -0
  135. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/python_sql/table_typescript_relationship.py +0 -0
  136. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/query/FEATURE.md +0 -0
  137. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/query/MODULE_README.md +0 -0
  138. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/query/__init__.py +0 -0
  139. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/query/builder.py +0 -0
  140. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/query/executor.py +0 -0
  141. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/resources/__init__.py +0 -0
  142. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/resources/additional-assigners-2026-09-12.json +0 -0
  143. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/resources/org_assignment_trigger_baseline.json +0 -0
  144. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/FEATURE.md +0 -0
  145. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/MODULE_README.md +0 -0
  146. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/__init__.py +0 -0
  147. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/code_handler.py +0 -0
  148. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/codegen_writer.py +0 -0
  149. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/columns.py +0 -0
  150. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/common.py +0 -0
  151. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/diff_preview.py +0 -0
  152. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/entity_capabilities.py +0 -0
  153. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/excluded_targets.py +0 -0
  154. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/generator.py +0 -0
  155. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/helpers/__init__.py +0 -0
  156. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/helpers/base_generators.py +0 -0
  157. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/helpers/entity_generators.py +0 -0
  158. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/helpers/git_checker.py +0 -0
  159. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/package_wiring.py +0 -0
  160. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/relationships.py +0 -0
  161. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/runner.py +0 -0
  162. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/schema.py +0 -0
  163. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/schema_manager.py +0 -0
  164. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/tables.py +0 -0
  165. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/schema_builder/views.py +0 -0
  166. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/FEATURE.md +0 -0
  167. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/__init__.py +0 -0
  168. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/attachments.py +0 -0
  169. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/backup_restore.py +0 -0
  170. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/crypto.py +0 -0
  171. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/host_authorization.py +0 -0
  172. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/items.py +0 -0
  173. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/model.py +0 -0
  174. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/mutation_receipts.py +0 -0
  175. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/native_enable.py +0 -0
  176. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/native_lifecycle.py +0 -0
  177. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/native_passkeys.py +0 -0
  178. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/native_source.py +0 -0
  179. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/org_service.py +0 -0
  180. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/org_vault_gate.py +0 -0
  181. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/service.py +0 -0
  182. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/secrets_battery/vault_history.py +0 -0
  183. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/README.md +0 -0
  184. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/__init__.py +0 -0
  185. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/coalesce.py +0 -0
  186. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/dag.py +0 -0
  187. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/errors.py +0 -0
  188. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/fallback.py +0 -0
  189. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/flush.py +0 -0
  190. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/lifecycle.py +0 -0
  191. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/managed.py +0 -0
  192. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/op.py +0 -0
  193. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/reads.py +0 -0
  194. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/session.py +0 -0
  195. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/session/telemetry.py +0 -0
  196. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/sql_executor/MODULE_README.md +0 -0
  197. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/sql_executor/__init__.py +0 -0
  198. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/sql_executor/executor.py +0 -0
  199. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/sql_executor/queries.py +0 -0
  200. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/sql_executor/registry.py +0 -0
  201. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/sql_executor/types.py +0 -0
  202. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/sql_executor/utils.py +0 -0
  203. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/state.py +0 -0
  204. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/utils/__init__.py +0 -0
  205. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/utils/sql_utils.py +0 -0
  206. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/utils/type_converters.py +0 -0
  207. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/matrx_orm/write_actor.py +0 -0
  208. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/scripts/git-branches.sh +0 -0
  209. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/scripts/publish.sh +0 -0
  210. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/scripts/release.sh +0 -0
  211. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/MODULE_README.md +0 -0
  212. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/__init__.py +0 -0
  213. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/conftest.py +0 -0
  214. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/MODULE_README.md +0 -0
  215. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/__init__.py +0 -0
  216. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_adapter_registry.py +0 -0
  217. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_admin_db_columns.py +0 -0
  218. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_admin_response_rendering.py +0 -0
  219. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_admin_search_negation.py +0 -0
  220. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_admin_search_sentinels.py +0 -0
  221. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_advisory_lock.py +0 -0
  222. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_agent_message.py +0 -0
  223. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_api_auth.py +0 -0
  224. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_api_config.py +0 -0
  225. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_api_handlers.py +0 -0
  226. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_api_protocol.py +0 -0
  227. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_array_agg_order_by.py +0 -0
  228. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_association_trigger_actor_naming.py +0 -0
  229. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_associations.py +0 -0
  230. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_associations_wiring.py +0 -0
  231. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_bulk_hydration_offload.py +0 -0
  232. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_bulk_update_by_pk.py +0 -0
  233. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_bulk_upsert_increment_set_fields.py +0 -0
  234. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_cache_debug.py +0 -0
  235. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_call_function.py +0 -0
  236. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_case_when.py +0 -0
  237. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_catalog.py +0 -0
  238. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_column_scoped_writes.py +0 -0
  239. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_committed_row_guard.py +0 -0
  240. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_composite_pk_filter.py +0 -0
  241. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_composite_pk_write_paths.py +0 -0
  242. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_config.py +0 -0
  243. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_conflict_target.py +0 -0
  244. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_conflict_writes.py +0 -0
  245. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_connection_codecs.py +0 -0
  246. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_connection_poison_guard.py +0 -0
  247. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_connection_primitives.py +0 -0
  248. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_count_composite_distinct.py +0 -0
  249. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_count_limit_param_leak.py +0 -0
  250. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_db_function_field.py +0 -0
  251. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_ddl_generator.py +0 -0
  252. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_deadlock_retry.py +0 -0
  253. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_derived_table.py +0 -0
  254. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_dirty_tracking.py +0 -0
  255. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_dynamic_crud.py +0 -0
  256. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_exceptions.py +0 -0
  257. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_execute_query_integrity_mapping.py +0 -0
  258. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_expression_primitives.py +0 -0
  259. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_fields.py +0 -0
  260. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_filter_jsonb_agg_array_index.py +0 -0
  261. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_fk_cycle_resolution.py +0 -0
  262. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_from_alias.py +0 -0
  263. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_fts.py +0 -0
  264. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_func_expression_args.py +0 -0
  265. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_graph_walk.py +0 -0
  266. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_having_annotate_alias.py +0 -0
  267. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_insert_ignore_and_admin_primitives.py +0 -0
  268. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_introspect_rls_policies.py +0 -0
  269. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_join_and_aggregate.py +0 -0
  270. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_latest_rows.py +0 -0
  271. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_listen_notify.py +0 -0
  272. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_local_sqlite.py +0 -0
  273. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_lock_contention_retry.py +0 -0
  274. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_managed_write_guard.py +0 -0
  275. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_matrx_entity.py +0 -0
  276. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_migration_diff_types.py +0 -0
  277. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_migration_loader.py +0 -0
  278. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_model_instance.py +0 -0
  279. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_model_meta.py +0 -0
  280. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_optimistic_concurrency.py +0 -0
  281. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_order_by_expression.py +0 -0
  282. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_org_assignment_inventory.py +0 -0
  283. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_orm_banners_are_client_safe.py +0 -0
  284. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_parameter_name_hydration.py +0 -0
  285. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_patch_jsonb_path.py +0 -0
  286. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_percentile_cont.py +0 -0
  287. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_persisted_count.py +0 -0
  288. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_person_scoped_session_bypasses_shared_cache.py +0 -0
  289. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_pool_create_never_wedges.py +0 -0
  290. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_pool_holder_census.py +0 -0
  291. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_pool_loop_recreation.py +0 -0
  292. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_pool_maintenance.py +0 -0
  293. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_postgrest_filters.py +0 -0
  294. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_pydantic_bridge.py +0 -0
  295. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_query_builder.py +0 -0
  296. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_query_error_detail.py +0 -0
  297. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_query_executor_sql.py +0 -0
  298. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_query_timeout.py +0 -0
  299. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_querybuilder_clone_semantics.py +0 -0
  300. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_queue_claim.py +0 -0
  301. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_read_connection_retry.py +0 -0
  302. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_read_write_declared.py +0 -0
  303. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_registry.py +0 -0
  304. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_registry_multi_database.py +0 -0
  305. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_registry_multi_schema.py +0 -0
  306. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_relational_backfill.py +0 -0
  307. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_relations.py +0 -0
  308. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_resilience.py +0 -0
  309. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_schema_exists.py +0 -0
  310. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_session_advisory_lock.py +0 -0
  311. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_standalone_write_session_context.py +0 -0
  312. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_state_cache.py +0 -0
  313. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_subquery_filter_raw.py +0 -0
  314. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_subquery_in_filter.py +0 -0
  315. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_subquery_nested_expressions.py +0 -0
  316. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_supabase_auth.py +0 -0
  317. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_supabase_config.py +0 -0
  318. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_tls.py +0 -0
  319. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_transaction_database_identity.py +0 -0
  320. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_transaction_pool_release_sends_nothing.py +0 -0
  321. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_typed_join_projection.py +0 -0
  322. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_typed_predicates.py +0 -0
  323. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_update_case_expression.py +0 -0
  324. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_update_subquery.py +0 -0
  325. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_update_with_rebase.py +0 -0
  326. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_upsert_default_leak.py +0 -0
  327. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_upsert_with_conflict.py +0 -0
  328. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_values_jsonb_decode.py +0 -0
  329. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_watched_lifecycle.py +0 -0
  330. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_write_queue_deadline.py +0 -0
  331. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level1/test_write_retry_semantics.py +0 -0
  332. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/MODULE_README.md +0 -0
  333. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/__init__.py +0 -0
  334. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/conftest.py +0 -0
  335. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_bulk_ops.py +0 -0
  336. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_cache_integration.py +0 -0
  337. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_crud.py +0 -0
  338. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_foreign_keys.py +0 -0
  339. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_m2m.py +0 -0
  340. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_manager.py +0 -0
  341. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_migrations_live.py +0 -0
  342. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_query_execution.py +0 -0
  343. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/test_schema_diff.py +0 -0
  344. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/level2/verify_committed_row_guard_pg17.py +0 -0
  345. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/live_pooler_role.py +0 -0
  346. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/native_source_cases.py +0 -0
  347. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/native_source_oracle.rs +0 -0
  348. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project/.env.example +0 -0
  349. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project/README.md +0 -0
  350. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project/__init__.py +0 -0
  351. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project/generate.py +0 -0
  352. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project/generated/.gitkeep +0 -0
  353. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project/matrx_orm.yaml +0 -0
  354. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project/test_schema_generation.py +0 -0
  355. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project_desktop/.env.example +0 -0
  356. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project_desktop/README.md +0 -0
  357. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project_desktop/__init__.py +0 -0
  358. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project_desktop/client_example.py +0 -0
  359. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project_desktop/client_example.ts +0 -0
  360. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project_desktop/client_supabase_example.py +0 -0
  361. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/sample_project_desktop/server.py +0 -0
  362. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/entity_tests.py +0 -0
  363. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_base_generation.py +0 -0
  364. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_composite_pk_fk_generation.py +0 -0
  365. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_composite_unique_generation.py +0 -0
  366. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_dto_identity_generation.py +0 -0
  367. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_entity_capability_generation.py +0 -0
  368. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_enum_ordering.py +0 -0
  369. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_excluded_fk_targets.py +0 -0
  370. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_generate_schema.py +0 -0
  371. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_junction_analysis.py +0 -0
  372. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_multi_schema_output.py +0 -0
  373. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_schema_analysis.py +0 -0
  374. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_sql_expression_defaults.py +0 -0
  375. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_table_relationships_query.py +0 -0
  376. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema/test_view_generation.py +0 -0
  377. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema_builder/test_array_default_parsing.py +0 -0
  378. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema_builder/test_focused_generation_plan.py +0 -0
  379. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema_builder/test_host_models_aggregator.py +0 -0
  380. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/schema_builder/test_never_filter_columns.py +0 -0
  381. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/__init__.py +0 -0
  382. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/conftest.py +0 -0
  383. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_a_failed_capture_still_names_the_failure.py +0 -0
  384. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_cache_no_downgrade.py +0 -0
  385. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_capture_poison_proof.py +0 -0
  386. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_coalesce.py +0 -0
  387. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_dag.py +0 -0
  388. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_disk_spill_fallback.py +0 -0
  389. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_flush_individual_fallback.py +0 -0
  390. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_governed_write.py +0 -0
  391. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_managed.py +0 -0
  392. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_op_enqueue_site.py +0 -0
  393. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_reads.py +0 -0
  394. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_record_error_bounded_insert.py +0 -0
  395. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_record_error_storm.py +0 -0
  396. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_session.py +0 -0
  397. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/session/test_spill_guard_plugin.py +0 -0
  398. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_a_backend_handed_over_mid_transaction_never_takes_our_writes.py +0 -0
  399. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_a_list_of_uuids_binds_as_uuid_array.py +0 -0
  400. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_a_read_only_backend_never_refuses_our_writes.py +0 -0
  401. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_a_sealed_field_shows_no_character_of_its_value.py +0 -0
  402. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_array_arg_element_type.py +0 -0
  403. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_attachment_mutation_serialization.py +0 -0
  404. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_backup_alias_conflict.py +0 -0
  405. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_backup_history_restore.py +0 -0
  406. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_backup_restore_live.py +0 -0
  407. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_call_function_none_mode.py +0 -0
  408. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_composite_fk_is_not_a_column_fk.py +0 -0
  409. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_database_name_alias.py +0 -0
  410. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_db_functions.py +0 -0
  411. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_dsn_password_masking.py +0 -0
  412. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_dynamic_select_unregistered.py +0 -0
  413. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_immutable_insert_or_exact_verify.py +0 -0
  414. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_keyed_digest.py +0 -0
  415. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_model_cls_refactor.py +0 -0
  416. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_native_enable.py +0 -0
  417. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_native_lifecycle.py +0 -0
  418. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_native_lifecycle_fences.py +0 -0
  419. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_native_passkey_receipts.py +0 -0
  420. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_native_source.py +0 -0
  421. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_no_blocking_asyncpg_tls.py +0 -0
  422. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_one_database.py +0 -0
  423. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_order_by_desc_nulls_last.py +0 -0
  424. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_org_vault_gate.py +0 -0
  425. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_package_wiring_views.py +0 -0
  426. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_pooler_role_guard.py +0 -0
  427. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_secret_audit_names_its_organization.py +0 -0
  428. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_secrets_battery.py +0 -0
  429. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_secrets_minting_keys.py +0 -0
  430. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_shared_lock_guard.py +0 -0
  431. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_sql_param_casts.py +0 -0
  432. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_statement_ceiling_warning.py +0 -0
  433. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_sync_twins_guard.py +0 -0
  434. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_update_result_truthiness.py +0 -0
  435. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_user_visible_lookup.py +0 -0
  436. {matrx_orm-3.1.217 → matrx_orm-3.1.218}/tests/test_vault_aggregate_recovery_stateful.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: matrx-orm
3
- Version: 3.1.217
3
+ Version: 3.1.218
4
4
  Summary: Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching
5
5
  Project-URL: Homepage, https://github.com/AI-Matrix-Engine/aidream-current
6
6
  Project-URL: Repository, https://github.com/AI-Matrix-Engine/aidream-current
@@ -19,6 +19,7 @@ from matrx_orm.core.config import (
19
19
  resolve_pool_mode,
20
20
  )
21
21
  from matrx_orm.error_handling import handle_orm_operation
22
+ from matrx_orm.core.foreign_session_state import run_clearing_foreign_restrict
22
23
  from matrx_orm.core.pooler_role import (
23
24
  VERIFY_EMPTY_READS,
24
25
  assert_no_session_role_change,
@@ -1463,7 +1464,11 @@ class AsyncDatabaseManager:
1463
1464
  in_transaction=False,
1464
1465
  )
1465
1466
  try:
1466
- results = await conn.fetch(query, *args, timeout=driver_timeout)
1467
+ results = await run_clearing_foreign_restrict(
1468
+ conn,
1469
+ lambda: conn.fetch(query, *args, timeout=driver_timeout),
1470
+ what=f"execute_query {query[:80]!r}",
1471
+ )
1467
1472
  if read_attempt > 0:
1468
1473
  logger.warning(
1469
1474
  "[read-retry] SELECT HEALED on attempt %d after a "
@@ -69,6 +69,7 @@ from dataclasses import dataclass
69
69
  from typing import Any, Literal
70
70
 
71
71
  from matrx_orm.core.async_db_manager import AsyncDatabaseManager
72
+ from matrx_orm.core.foreign_session_state import run_clearing_foreign_restrict
72
73
  from matrx_orm.core.statement_ceiling import DriverTimeout, resolve_driver_timeout
73
74
  from matrx_orm.core.transaction import get_active_connection
74
75
  from matrx_orm.core.write_retry import (
@@ -336,7 +337,11 @@ async def call_function(
336
337
 
337
338
  async def _attempt() -> Any:
338
339
  async with AsyncDatabaseManager.get_connection(database) as conn:
339
- return await invoke(conn)
340
+ # Outside a transaction: a parse-time refusal caused by another pooler
341
+ # client's leaked restrict_nonsystem_relation_kind re-runs once, clearing it.
342
+ return await run_clearing_foreign_restrict(
343
+ conn, lambda: invoke(conn), what=f"call_function {schema}.{function}"
344
+ )
340
345
 
341
346
  # An RPC reaches Postgres on a RAW connection, bypassing execute_query
342
347
  # entirely, so it needs THE ONE loop explicitly — otherwise a deadlock inside
@@ -401,13 +406,20 @@ async def call_function_as(
401
406
  operation=f"call_function_as {schema}.{function}",
402
407
  in_transaction=False,
403
408
  )
404
- if mode == "none":
405
- await conn.execute(sql, *bound_args, timeout=driver_timeout)
406
- return None
407
- if mode == "rows":
408
- rows = await conn.fetch(sql, *bound_args, timeout=driver_timeout)
409
- return [dict(r) for r in rows]
410
- return await conn.fetchval(sql, *bound_args, timeout=driver_timeout)
409
+
410
+ async def run() -> Any:
411
+ if mode == "none":
412
+ await conn.execute(sql, *bound_args, timeout=driver_timeout)
413
+ return None
414
+ if mode == "rows":
415
+ rows = await conn.fetch(sql, *bound_args, timeout=driver_timeout)
416
+ return [dict(r) for r in rows]
417
+ return await conn.fetchval(sql, *bound_args, timeout=driver_timeout)
418
+
419
+ # Same parse-time refusal class as call_function (foreign_session_state).
420
+ return await run_clearing_foreign_restrict(
421
+ conn, run, what=f"call_function_as {schema}.{function}"
422
+ )
411
423
 
412
424
  return await run_with_lock_retry(_attempt, config_name=database, query=sql, args=bound_args)
413
425
 
@@ -0,0 +1,112 @@
1
+ """Session state another client left on a shared server connection.
2
+
3
+ WHY THIS EXISTS. We reach Postgres through Supavisor in TRANSACTION mode: every
4
+ client shares the same pool of server connections, and Supavisor does not reset
5
+ session state between clients. ``pg_dump`` (17.x) begins every run with a
6
+ SESSION-level ``SET restrict_nonsystem_relation_kind = 'view, foreign-table'``.
7
+ A dump pointed at the transaction pooler (port 6543) leaves that setting on
8
+ whichever server connection the ``SET`` landed on, and every later statement of
9
+ ours that touches a view through that connection is refused at parse time::
10
+
11
+ 55000 ObjectNotInPrerequisiteStateError:
12
+ access to non-system view "organization_member" is restricted
13
+
14
+ Measured 2026-10-05 05:49-09:04 UTC: ~50 platform errors (SEO runs list, mandate
15
+ resolution, membership checks, file downloads), each pinned to a few poisoned
16
+ backends that kept failing for minutes.
17
+
18
+ THE DEFENCE (two halves, both here so they cannot drift apart):
19
+
20
+ 1. Every ORM transaction clears the setting transaction-locally at BEGIN
21
+ (:data:`CLEARED_GUCS`, merged into ``transaction._opening_statement_gucs``).
22
+ It rides the one opening statement, so it costs nothing.
23
+ 2. A statement OUTSIDE a transaction cannot carry a ``SET LOCAL`` in the same
24
+ round trip. When one is refused with exactly this parse-time error, it is
25
+ re-run ONCE inside a transaction that clears the setting first. The refusal
26
+ happens during parse/rewrite, before anything executes, so the re-run is
27
+ side-effect free. The cause is logged as a WARNING once per connection so it
28
+ never hides.
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import logging
34
+ import weakref
35
+ from typing import Any, Awaitable, Callable, TypeVar
36
+
37
+ logger = logging.getLogger(__name__)
38
+
39
+ RESTRICT_GUC = "restrict_nonsystem_relation_kind"
40
+
41
+ # Merged into every top-level transaction's opening GUCs. '' = no restriction
42
+ # (the server default); set_config(..., true) scopes it to the transaction.
43
+ CLEARED_GUCS: dict[str, str] = {RESTRICT_GUC: ""}
44
+
45
+ _OBJECT_NOT_IN_PREREQUISITE_STATE = "55000"
46
+
47
+ T = TypeVar("T")
48
+
49
+ _warned: "weakref.WeakSet[Any]" = weakref.WeakSet()
50
+ _warned_ids: set[int] = set()
51
+
52
+
53
+ def is_foreign_restrict_refusal(exc: BaseException) -> bool:
54
+ """True iff ``exc`` is the parse-time refusal caused by a leaked restrict GUC."""
55
+ if getattr(exc, "sqlstate", None) != _OBJECT_NOT_IN_PREREQUISITE_STATE:
56
+ return False
57
+ text = str(exc)
58
+ return "access to non-system" in text and "is restricted" in text
59
+
60
+
61
+ def _warn_once(conn: Any, exc: BaseException, what: str) -> None:
62
+ try:
63
+ if conn in _warned:
64
+ return
65
+ _warned.add(conn)
66
+ except TypeError: # not weak-referenceable
67
+ if id(conn) in _warned_ids:
68
+ return
69
+ _warned_ids.add(id(conn))
70
+ logger.warning(
71
+ "[foreign-session-state] %s was refused because the shared server connection "
72
+ "carries %s from another client (a pg_dump through the transaction pooler sets it "
73
+ "session-wide and Supavisor does not reset it): %s — re-running once in a "
74
+ "transaction that clears it",
75
+ what,
76
+ RESTRICT_GUC,
77
+ exc,
78
+ )
79
+
80
+
81
+ async def clear_in_transaction(conn: Any) -> None:
82
+ """Clear the restrict GUC for the current transaction on ``conn``."""
83
+ await conn.execute("SELECT set_config($1, '', true)", RESTRICT_GUC)
84
+
85
+
86
+ async def run_clearing_foreign_restrict(
87
+ conn: Any, run: Callable[[], Awaitable[T]], *, what: str = "statement"
88
+ ) -> T:
89
+ """Run ``run()`` (one statement on ``conn``, outside any transaction).
90
+
91
+ On the leaked-restrict refusal, run it once more inside a transaction on the
92
+ same client connection that clears the setting first. Any other error, or a
93
+ second refusal, propagates unchanged.
94
+ """
95
+ try:
96
+ return await run()
97
+ except Exception as exc:
98
+ if not is_foreign_restrict_refusal(exc):
99
+ raise
100
+ _warn_once(conn, exc, what)
101
+ async with conn.transaction():
102
+ await clear_in_transaction(conn)
103
+ return await run()
104
+
105
+
106
+ __all__ = [
107
+ "CLEARED_GUCS",
108
+ "RESTRICT_GUC",
109
+ "clear_in_transaction",
110
+ "is_foreign_restrict_refusal",
111
+ "run_clearing_foreign_restrict",
112
+ ]
@@ -460,9 +460,13 @@ def _opening_statement_gucs(opening_gucs: dict[str, str]) -> dict[str, str]:
460
460
  (a later name wins, exactly as sequential ``set_config`` calls did). ``role``
461
461
  is always LAST: everything before it is set while still the privileged role.
462
462
  """
463
+ from matrx_orm.core.foreign_session_state import CLEARED_GUCS
463
464
  from matrx_orm.core.session_context import session_context_gucs
464
465
 
465
- merged = {**_TRANSACTION_CEILINGS, **session_context_gucs(), **opening_gucs}
466
+ # CLEARED_GUCS first: session state another pooler client may have left on this
467
+ # server connection (pg_dump's restrict_nonsystem_relation_kind) is cleared for
468
+ # every transaction; anything the opener declares still wins.
469
+ merged = {**CLEARED_GUCS, **_TRANSACTION_CEILINGS, **session_context_gucs(), **opening_gucs}
466
470
  if "role" in merged:
467
471
  merged["role"] = merged.pop("role")
468
472
  return merged
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "matrx-orm"
3
- version = "3.1.217"
3
+ version = "3.1.218"
4
4
  description = "Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -77,10 +77,11 @@ async def test_rls_session_commits_transaction_local_role(monkeypatch: pytest.Mo
77
77
  assert [sql for sql, _args in conn.calls] == [
78
78
  "BEGIN",
79
79
  "SELECT set_config($1, $2, true), set_config($3, $4, true), "
80
- "set_config($5, $6, true), set_config($7, $8, true)",
80
+ "set_config($5, $6, true), set_config($7, $8, true), set_config($9, $10, true)",
81
81
  "COMMIT",
82
82
  ]
83
83
  assert conn.calls[1][1] == (
84
+ "restrict_nonsystem_relation_kind", "",
84
85
  "request.jwt.claims", '{"sub":"user-id","role":"authenticated"}',
85
86
  "statement_timeout", "30000",
86
87
  "idle_in_transaction_session_timeout", "30000",
@@ -116,10 +117,12 @@ async def test_lock_timeout_is_transaction_local_and_precedes_the_role(
116
117
  assert [sql for sql, _args in conn.calls] == [
117
118
  "BEGIN",
118
119
  "SELECT set_config($1, $2, true), set_config($3, $4, true), "
119
- "set_config($5, $6, true), set_config($7, $8, true), set_config($9, $10, true)",
120
+ "set_config($5, $6, true), set_config($7, $8, true), set_config($9, $10, true), "
121
+ "set_config($11, $12, true)",
120
122
  "COMMIT",
121
123
  ]
122
124
  assert conn.calls[1][1] == (
125
+ "restrict_nonsystem_relation_kind", "",
123
126
  "request.jwt.claims", '{"role":"matrx_provisioner"}',
124
127
  "statement_timeout", "180000",
125
128
  "lock_timeout", "55000",
@@ -174,8 +177,9 @@ async def test_declared_context_and_rls_settings_share_one_round_trip_role_last(
174
177
  assert [sql for sql, _ in conn.calls][0::2] == ["BEGIN", "COMMIT"]
175
178
  assert len(conn.calls) == 3
176
179
  names = conn.calls[1][1][0::2]
177
- assert names[0] == "lock_timeout"
178
- assert names[1] == "app.actor_tier"
180
+ assert names[0] == "restrict_nonsystem_relation_kind" # foreign session state cleared first
181
+ assert names[1] == "lock_timeout"
182
+ assert names[2] == "app.actor_tier"
179
183
  assert names.index("request.jwt.claims") < names.index("role")
180
184
  assert names[-1] == "role"
181
185
 
@@ -66,8 +66,9 @@ async def test_begin_sets_ceilings_and_declared_context_in_one_round_trip(monkey
66
66
  gucs = [call for call in conn.calls if "set_config" in call[0]]
67
67
  assert len(gucs) == 1, statements
68
68
  sql, args = gucs[0]
69
- assert sql.count("set_config(") == 4
69
+ assert sql.count("set_config(") == 5
70
70
  assert args == (
71
+ "restrict_nonsystem_relation_kind", "",
71
72
  "lock_timeout", "5000",
72
73
  "app.actor_tier", "agent",
73
74
  "app.actor_system", "flashcards",
@@ -76,14 +77,17 @@ async def test_begin_sets_ceilings_and_declared_context_in_one_round_trip(monkey
76
77
 
77
78
 
78
79
  @pytest.mark.asyncio
79
- async def test_nothing_declared_emits_nothing(monkeypatch) -> None:
80
+ async def test_nothing_declared_emits_only_the_foreign_state_clear(monkeypatch) -> None:
80
81
  conn = _Connection()
81
82
  monkeypatch.setattr(AdapterRegistry, "get", lambda _db: _Adapter(conn))
82
83
  monkeypatch.setattr(transaction_module, "_TRANSACTION_CEILINGS", {})
83
84
  configure_session_context(None)
84
85
  async with transaction_module.transaction("quiet"):
85
86
  pass
86
- assert [sql for sql, _ in conn.calls] == ["BEGIN", "COMMIT"]
87
+ # The one GUC every transaction carries: another pooler client's leaked
88
+ # restrict_nonsystem_relation_kind is cleared (matrx_orm.core.foreign_session_state).
89
+ assert [sql for sql, _ in conn.calls] == ["BEGIN", "SELECT set_config($1, $2, true)", "COMMIT"]
90
+ assert conn.calls[1][1] == ("restrict_nonsystem_relation_kind", "")
87
91
 
88
92
 
89
93
  def test_a_bad_guc_name_is_refused_before_it_reaches_sql() -> None:
@@ -2,8 +2,8 @@
2
2
 
3
3
  The kernel's set form (``iam.accessible_entity_ids``) reads the person from
4
4
  ``auth.uid()``. The primitive must (1) never ride the caller's ambient transaction,
5
- (2) set the claims transaction-local BEFORE the call, inside one explicit
6
- transaction, and (3) refuse an empty person instead of returning the kernel's
5
+ (2) set the claims transaction-local BEFORE the call, in the same single statement
6
+ (its own transaction), and (3) refuse an empty person instead of returning the kernel's
7
7
  empty answer as if it were real.
8
8
  """
9
9
 
@@ -52,7 +52,14 @@ def log(monkeypatch):
52
52
  return calls
53
53
 
54
54
 
55
- async def test_claims_are_set_inside_one_transaction_before_the_call(log):
55
+ async def test_claims_are_set_transaction_local_in_the_same_single_statement(log):
56
+ """ONE round trip: a MATERIALIZED CTE sets the claims, the call is correlated to it.
57
+
58
+ The single statement is its own transaction, so the claims end with it. No
59
+ BEGIN/COMMIT and no separate set_config trip (four trips before 2026-09-27). The
60
+ restrict_nonsystem_relation_kind clear (foreign_session_state) is NOT sent on a
61
+ healthy connection; it only rides a re-run after the parse-time refusal.
62
+ """
56
63
  out = await db_function.call_function_as(
57
64
  "11111111-1111-4111-8111-111111111111",
58
65
  "db",
@@ -62,21 +69,30 @@ async def test_claims_are_set_inside_one_transaction_before_the_call(log):
62
69
  db_function.TypedArg("viewer", "public.permission_level"),
63
70
  )
64
71
  assert out == ["a", "b"]
65
- kinds = [c[0] for c in log]
66
- assert kinds == ["acquire", "BEGIN", "execute", "fetchval", "COMMIT"]
67
- set_claims = log[2]
68
- assert "set_config('request.jwt.claims', $1, true)" in set_claims[1]
69
- assert json.loads(set_claims[2][0]) == {
72
+ assert [c[0] for c in log] == ["acquire", "fetchval"]
73
+ _, sql, args = log[1]
74
+ assert sql == (
75
+ "WITH _claims AS MATERIALIZED (SELECT set_config('request.jwt.claims', $1, true) AS c) "
76
+ 'SELECT (SELECT "iam"."accessible_entity_ids"($2, $3::"public"."permission_level") '
77
+ "WHERE _claims.c IS NOT NULL) FROM _claims"
78
+ )
79
+ assert json.loads(args[0]) == {
70
80
  "sub": "11111111-1111-4111-8111-111111111111",
71
81
  "role": "authenticated",
72
82
  }
73
- assert log[3][1] == 'SELECT "iam"."accessible_entity_ids"($1, $2::"public"."permission_level")'
83
+ assert args[1:] == ("processed_document", "viewer")
84
+ assert "restrict_nonsystem_relation_kind" not in sql
74
85
 
75
86
 
76
87
  async def test_rows_mode_selects_from_the_function(log):
77
88
  rows = await db_function.call_function_as("u", "db", "platform", "search_items", "q", mode="rows")
78
89
  assert rows == [{"id": 1}]
79
- assert log[3][1] == 'SELECT * FROM "platform"."search_items"($1)'
90
+ assert [c[0] for c in log] == ["acquire", "fetch"]
91
+ assert log[1][1] == (
92
+ "WITH _claims AS MATERIALIZED (SELECT set_config('request.jwt.claims', $1, true) AS c) "
93
+ 'SELECT f.* FROM _claims, LATERAL (SELECT * FROM "platform"."search_items"($2) '
94
+ "WHERE _claims.c IS NOT NULL) f"
95
+ )
80
96
 
81
97
 
82
98
  async def test_an_empty_person_is_refused_not_answered_empty(log):
@@ -0,0 +1,110 @@
1
+ """A pooled server connection poisoned by another client's restrict GUC never fails our reads.
2
+
3
+ pg_dump through the transaction pooler leaves ``restrict_nonsystem_relation_kind = 'view'``
4
+ on a shared server connection; every view read through it is refused at parse time (55000).
5
+ This fake connection behaves exactly like that backend: it refuses a view read unless the
6
+ current transaction cleared the setting. Live proof: scripts/verify_foreign_restrict_guc_live.py.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ from contextlib import asynccontextmanager
13
+ from typing import Any
14
+
15
+ import asyncpg
16
+ import pytest
17
+
18
+ from matrx_orm.core import foreign_session_state as fss
19
+ from matrx_orm.core.transaction import _opening_statement_gucs
20
+
21
+
22
+ def _refusal() -> Exception:
23
+ exc = asyncpg.exceptions.ObjectNotInPrerequisiteStateError(
24
+ 'access to non-system view "organization_member" is restricted'
25
+ )
26
+ exc.sqlstate = "55000"
27
+ return exc
28
+
29
+
30
+ class PoisonedConnection:
31
+ """Session carries restrict=view; a transaction may clear it locally."""
32
+
33
+ def __init__(self) -> None:
34
+ self.session_restrict = "view"
35
+ self.local_restrict: str | None = None
36
+ self.in_tx = False
37
+ self.executed: list[str] = []
38
+ self.view_reads = 0
39
+
40
+ @asynccontextmanager
41
+ async def transaction(self):
42
+ self.in_tx = True
43
+ try:
44
+ yield
45
+ finally:
46
+ self.in_tx = False
47
+ self.local_restrict = None
48
+
49
+ async def execute(self, sql: str, *args: Any) -> str:
50
+ self.executed.append(sql)
51
+ if "set_config" in sql and args and args[0] == fss.RESTRICT_GUC:
52
+ assert self.in_tx, "the clear must be transaction-local"
53
+ self.local_restrict = ""
54
+ return "SELECT 1"
55
+
56
+ async def fetchval(self, sql: str, *args: Any) -> Any:
57
+ effective = self.local_restrict if self.local_restrict is not None else self.session_restrict
58
+ if "view" in effective:
59
+ raise _refusal()
60
+ self.view_reads += 1
61
+ return 42
62
+
63
+
64
+ def test_every_transaction_clears_the_restrict_guc_first() -> None:
65
+ gucs = _opening_statement_gucs({})
66
+ assert gucs[fss.RESTRICT_GUC] == ""
67
+ # An opener can still declare its own value, and role stays last.
68
+ assert _opening_statement_gucs({fss.RESTRICT_GUC: "view"})[fss.RESTRICT_GUC] == "view"
69
+ assert list(_opening_statement_gucs({"role": "authenticated"}))[-1] == "role"
70
+
71
+
72
+ def test_statement_outside_a_transaction_heals_on_a_poisoned_connection(caplog) -> None:
73
+ conn = PoisonedConnection()
74
+ with caplog.at_level("WARNING"):
75
+ value = asyncio.run(
76
+ fss.run_clearing_foreign_restrict(conn, lambda: conn.fetchval("select v"), what="t")
77
+ )
78
+ assert value == 42
79
+ assert conn.view_reads == 1
80
+ assert conn.session_restrict == "view" # session never touched — only the transaction
81
+ assert any(fss.RESTRICT_GUC in r.getMessage() for r in caplog.records)
82
+
83
+
84
+ def test_warning_is_once_per_connection(caplog) -> None:
85
+ conn = PoisonedConnection()
86
+ with caplog.at_level("WARNING"):
87
+ for _ in range(3):
88
+ asyncio.run(fss.run_clearing_foreign_restrict(conn, lambda: conn.fetchval("x")))
89
+ assert sum(fss.RESTRICT_GUC in r.getMessage() for r in caplog.records) == 1
90
+
91
+
92
+ def test_other_55000_errors_are_not_rerun() -> None:
93
+ conn = PoisonedConnection()
94
+ calls = 0
95
+
96
+ async def run() -> Any:
97
+ nonlocal calls
98
+ calls += 1
99
+ exc = asyncpg.exceptions.ObjectNotInPrerequisiteStateError("currval is not yet defined")
100
+ exc.sqlstate = "55000"
101
+ raise exc
102
+
103
+ with pytest.raises(asyncpg.exceptions.ObjectNotInPrerequisiteStateError):
104
+ asyncio.run(fss.run_clearing_foreign_restrict(conn, run))
105
+ assert calls == 1
106
+
107
+
108
+ def test_classifier() -> None:
109
+ assert fss.is_foreign_restrict_refusal(_refusal())
110
+ assert not fss.is_foreign_restrict_refusal(RuntimeError("access to non-system view x is restricted"))
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes