data-flow-control 0.2.1__tar.gz → 0.2.3__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 (193) hide show
  1. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/Cargo.lock +3 -3
  2. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/Cargo.toml +1 -1
  3. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/PKG-INFO +1 -1
  4. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/aggregate_registry.rs +10 -0
  5. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/columns.rs +73 -259
  6. data_flow_control-0.2.3/passant-core/src/rewriter/joint_lineage/grouped_projection.rs +245 -0
  7. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/joint_lineage.rs +13 -0
  8. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/mod.rs +1 -0
  9. data_flow_control-0.2.3/passant-core/src/rewriter/sink_columns.rs +396 -0
  10. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/pyproject.toml +1 -1
  11. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/LICENSE +0 -0
  12. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/Cargo.toml +0 -0
  13. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/benches/rewrite_perf.rs +0 -0
  14. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/catalog/dimension.rs +0 -0
  15. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/catalog.rs +0 -0
  16. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/diagnostics.rs +0 -0
  17. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/explain.rs +0 -0
  18. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/full_push.rs +0 -0
  19. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/identifiers.rs +0 -0
  20. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/intern.rs +0 -0
  21. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/ir.rs +0 -0
  22. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/lib.rs +0 -0
  23. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/optimizer.rs +0 -0
  24. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/parser.rs +0 -0
  25. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/partial_push.rs +0 -0
  26. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/planner.rs +0 -0
  27. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy.rs +0 -0
  28. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_compile.rs +0 -0
  29. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_index.rs +0 -0
  30. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_parser.rs +0 -0
  31. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_pgn.pest +0 -0
  32. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_store/branch.rs +0 -0
  33. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_store/compiled.rs +0 -0
  34. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_store/delete.rs +0 -0
  35. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_store/indexes.rs +0 -0
  36. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_store/memory.rs +0 -0
  37. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/policy_store/mod.rs +0 -0
  38. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/query_analysis.rs +0 -0
  39. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/resolution_placement.rs +0 -0
  40. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/resolution_registry.rs +0 -0
  41. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewrite_stats.rs +0 -0
  42. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewrite_strategy.rs +0 -0
  43. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/aggregates.rs +0 -0
  44. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/constraint_preprocess.rs +0 -0
  45. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/derived_policy.rs +0 -0
  46. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/dimensions.rs +0 -0
  47. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/exists.rs +0 -0
  48. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/expr.rs +0 -0
  49. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/helpers.rs +0 -0
  50. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/insert_output_policy.rs +0 -0
  51. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/joint_lineage/terminal_distinct.rs +0 -0
  52. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/joint_lineage/terminal_except.rs +0 -0
  53. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/joint_lineage/terminal_intersect.rs +0 -0
  54. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/limit.rs +0 -0
  55. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/output_scope.rs +0 -0
  56. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/plan/actions.rs +0 -0
  57. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/plan/applicability.rs +0 -0
  58. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/plan/dominance.rs +0 -0
  59. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/plan/mod.rs +0 -0
  60. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/plan/scope_plan.rs +0 -0
  61. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/plan/write_plan.rs +0 -0
  62. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/policy_expr.rs +0 -0
  63. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/projection.rs +0 -0
  64. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/resolution.rs +0 -0
  65. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/scope.rs +0 -0
  66. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/select.rs +0 -0
  67. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/types.rs +0 -0
  68. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/rewriter/write_path.rs +0 -0
  69. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/semiring.rs +0 -0
  70. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/source_set_index.rs +0 -0
  71. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/source_sets/analysis.rs +0 -0
  72. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/source_sets/annotations.rs +0 -0
  73. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/source_sets/branch.rs +0 -0
  74. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/source_sets/mod.rs +0 -0
  75. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/source_sets/rewrites.rs +0 -0
  76. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/source_sets/split.rs +0 -0
  77. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/ast_stats.rs +0 -0
  78. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/builders.rs +0 -0
  79. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/columns.rs +0 -0
  80. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/dialect.rs +0 -0
  81. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/expr.rs +0 -0
  82. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/expr_key.rs +0 -0
  83. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/mod.rs +0 -0
  84. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/parse.rs +0 -0
  85. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/sql/render.rs +0 -0
  86. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/statement_tables.rs +0 -0
  87. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/src/threshold.rs +0 -0
  88. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/common/duckdb.rs +0 -0
  89. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/common/mod.rs +0 -0
  90. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/conformance.rs +0 -0
  91. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/main.rs +0 -0
  92. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/partial_push.rs +0 -0
  93. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/pgn.rs +0 -0
  94. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/pgn_unique.rs +0 -0
  95. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/policy_storage.rs +0 -0
  96. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/rewrite_api_parity.rs +0 -0
  97. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/semiring.rs +0 -0
  98. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/source_sets.rs +0 -0
  99. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/symmetric_self_join.rs +0 -0
  100. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/threshold.rs +0 -0
  101. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/completion/unique_not_unique.rs +0 -0
  102. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/dialect.rs +0 -0
  103. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/execution/insert.rs +0 -0
  104. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/execution/kill.rs +0 -0
  105. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/execution/main.rs +0 -0
  106. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/execution/oracle.rs +0 -0
  107. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/execution/remove.rs +0 -0
  108. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/execution/update.rs +0 -0
  109. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/expected/duckdb/remove_scan.sql +0 -0
  110. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/expected/postgres/remove_scan.sql +0 -0
  111. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/expected/sqlite/remove_scan.sql +0 -0
  112. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/explain_strategy.rs +0 -0
  113. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/column_propagation.rs +0 -0
  114. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/dimensions.rs +0 -0
  115. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/exists_join.rs +0 -0
  116. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/having_where.rs +0 -0
  117. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/identifiers.rs +0 -0
  118. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/insert_shapes.rs +0 -0
  119. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/main.rs +0 -0
  120. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/multi_source.rs +0 -0
  121. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/operators.rs +0 -0
  122. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/query_shapes.rs +0 -0
  123. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/gaps/scalar_subquery.rs +0 -0
  124. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/indexed_candidate_differential.rs +0 -0
  125. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/insert_values_body.rs +0 -0
  126. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/kill_null_guard_regression.rs +0 -0
  127. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/paper_examples.rs +0 -0
  128. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/parser.rs +0 -0
  129. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/planner.rs +0 -0
  130. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/policy.rs +0 -0
  131. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/policy_dialect.rs +0 -0
  132. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/policy_store_memory.rs +0 -0
  133. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/derived_policy.rs +0 -0
  134. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/in_semijoin.rs +0 -0
  135. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/insert.rs +0 -0
  136. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/joins.rs +0 -0
  137. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/main.rs +0 -0
  138. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/meal_deduction.rs +0 -0
  139. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/output.rs +0 -0
  140. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/recursive.rs +0 -0
  141. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/scan.rs +0 -0
  142. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite/update.rs +0 -0
  143. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite_candidate_regression.rs +0 -0
  144. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite_fast_paths.rs +0 -0
  145. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite_large_registry.rs +0 -0
  146. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/rewrite_stats_timings.rs +0 -0
  147. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/scan_ready_expr.rs +0 -0
  148. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/source_set_split_no_parse.rs +0 -0
  149. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/sql_builders.rs +0 -0
  150. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/sql_columns.rs +0 -0
  151. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-core/tests/ui_resolution.rs +0 -0
  152. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/Cargo.toml +0 -0
  153. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/src/bindings/catalog.rs +0 -0
  154. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/src/bindings/errors.rs +0 -0
  155. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/src/bindings/mod.rs +0 -0
  156. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/src/bindings/planner.rs +0 -0
  157. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/src/bindings/policy.rs +0 -0
  158. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/src/bindings/stats.rs +0 -0
  159. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/passant-py/src/lib.rs +0 -0
  160. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/__init__.py +0 -0
  161. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/_rust.py +0 -0
  162. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/__init__.py +0 -0
  163. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/_retry.py +0 -0
  164. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/base.py +0 -0
  165. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/clickhouse.py +0 -0
  166. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/datafusion.py +0 -0
  167. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/duckdb.py +0 -0
  168. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/kill.py +0 -0
  169. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/pg_catalog.py +0 -0
  170. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/postgres.py +0 -0
  171. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/registry.py +0 -0
  172. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/sqlite.py +0 -0
  173. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/adapters/umbra.py +0 -0
  174. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/aggregate_introspection.py +0 -0
  175. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/catalog.py +0 -0
  176. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/connection.py +0 -0
  177. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/dialect.py +0 -0
  178. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/errors.py +0 -0
  179. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/__init__.py +0 -0
  180. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/agent.py +0 -0
  181. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/call_tool_with_dataflow.py +0 -0
  182. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/database.py +0 -0
  183. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/middleware.py +0 -0
  184. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/schema.py +0 -0
  185. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/sql_validation.py +0 -0
  186. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/tool_spec.py +0 -0
  187. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/langchain/wrapper.py +0 -0
  188. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/options.py +0 -0
  189. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/planner.py +0 -0
  190. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/policy.py +0 -0
  191. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/tools/__init__.py +0 -0
  192. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/tools/retry.py +0 -0
  193. {data_flow_control-0.2.1 → data_flow_control-0.2.3}/python/data_flow_control/ui.py +0 -0
@@ -1593,7 +1593,7 @@ dependencies = [
1593
1593
 
1594
1594
  [[package]]
1595
1595
  name = "passant-cli"
1596
- version = "0.2.1"
1596
+ version = "0.2.3"
1597
1597
  dependencies = [
1598
1598
  "anyhow",
1599
1599
  "assert_cmd",
@@ -1605,7 +1605,7 @@ dependencies = [
1605
1605
 
1606
1606
  [[package]]
1607
1607
  name = "passant-core"
1608
- version = "0.2.1"
1608
+ version = "0.2.3"
1609
1609
  dependencies = [
1610
1610
  "anyhow",
1611
1611
  "criterion",
@@ -1623,7 +1623,7 @@ dependencies = [
1623
1623
 
1624
1624
  [[package]]
1625
1625
  name = "passant-py"
1626
- version = "0.2.1"
1626
+ version = "0.2.3"
1627
1627
  dependencies = [
1628
1628
  "passant-core",
1629
1629
  "pyo3",
@@ -3,7 +3,7 @@ members = ["passant-core", "passant-py"]
3
3
  resolver = "2"
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.1"
6
+ version = "0.2.3"
7
7
  edition = "2024"
8
8
  license = "MIT"
9
9
  authors = ["Charlie Summers"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-flow-control
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Requires-Dist: duckdb>=1.3.0
5
5
  Requires-Dist: numpy>=1.24.4
6
6
  Requires-Dist: sqlglot==28.3.0
@@ -184,6 +184,7 @@ impl AggregateRegistry {
184
184
  self.expr_contains_aggregate(left) || self.expr_contains_aggregate(right)
185
185
  }
186
186
  Expr::Nested(expr)
187
+ | Expr::Cast { expr, .. }
187
188
  | Expr::UnaryOp { expr, .. }
188
189
  | Expr::IsFalse(expr)
189
190
  | Expr::IsNotFalse(expr)
@@ -624,6 +625,15 @@ mod tests {
624
625
  assert!(registry.expr_contains_aggregate(&expr));
625
626
  }
626
627
 
628
+ #[test]
629
+ fn expr_contains_aggregate_inside_cast() {
630
+ let registry = AggregateRegistry::for_dialect(SqlDialect::DuckDb);
631
+ let expr = crate::sql::parse_projection_expr("CAST(list(c.id) AS VARCHAR)").unwrap();
632
+ assert!(registry.expr_contains_aggregate(&expr));
633
+ let scalar = crate::sql::parse_projection_expr("CAST(c.id AS VARCHAR)").unwrap();
634
+ assert!(!registry.expr_contains_aggregate(&scalar));
635
+ }
636
+
627
637
  #[test]
628
638
  fn lookup_schema_qualified_introspected_aggregate() {
629
639
  let registry = AggregateRegistry::for_dialect(SqlDialect::Postgres).merge_introspected(&[
@@ -2,8 +2,8 @@ use std::collections::{HashMap, HashSet};
2
2
 
3
3
  use sqlparser::ast::{Expr, FunctionArg, FunctionArgExpr, FunctionArguments, Ident};
4
4
 
5
- use crate::diagnostics::{ErrorKind, RewriteError};
6
- use crate::identifiers::{AliasByBase, ColumnName, QualifiedColumn, TableName};
5
+ use crate::diagnostics::RewriteError;
6
+ use crate::identifiers::{AliasByBase, ColumnName, QualifiedColumn};
7
7
 
8
8
  use super::helpers::OUTPUT_MARKER;
9
9
 
@@ -96,10 +96,10 @@ pub(crate) fn apply_policy_sink_column_replacements(
96
96
  expr
97
97
  };
98
98
  if let Some(sink_alias) = sink_alias {
99
- expr = replace_sink_columns(expr, sink_alias, sink_expr_by_column);
99
+ expr = replace_sink_columns(expr, sink_alias, sink_expr_by_column)?;
100
100
  }
101
101
  if !(sink_overlaps_source && sink_alias.is_some()) {
102
- expr = replace_sink_columns(expr, sink, sink_expr_by_column);
102
+ expr = replace_sink_columns(expr, sink, sink_expr_by_column)?;
103
103
  }
104
104
  Ok(expr)
105
105
  }
@@ -124,69 +124,8 @@ pub(crate) fn replace_sink_columns(
124
124
  expr: Expr,
125
125
  sink: &str,
126
126
  sink_expr_by_column: &HashMap<String, Expr>,
127
- ) -> Expr {
128
- let sink_table = TableName::parse(sink);
129
- match expr {
130
- Expr::CompoundIdentifier(parts) if parts.len() >= 2 => {
131
- if let Some(column) = QualifiedColumn::from_compound_identifier(&parts)
132
- && sink_table.matches_name(column.table.as_str())
133
- {
134
- return sink_expr_by_column
135
- .get(&column.column.key())
136
- .cloned()
137
- .unwrap_or(Expr::CompoundIdentifier(parts));
138
- }
139
- Expr::CompoundIdentifier(parts)
140
- }
141
- Expr::BinaryOp { left, op, right } => Expr::BinaryOp {
142
- left: Box::new(replace_sink_columns(*left, sink, sink_expr_by_column)),
143
- op,
144
- right: Box::new(replace_sink_columns(*right, sink, sink_expr_by_column)),
145
- },
146
- Expr::Nested(expr) => Expr::Nested(Box::new(replace_sink_columns(
147
- *expr,
148
- sink,
149
- sink_expr_by_column,
150
- ))),
151
- Expr::UnaryOp { op, expr } => Expr::UnaryOp {
152
- op,
153
- expr: Box::new(replace_sink_columns(*expr, sink, sink_expr_by_column)),
154
- },
155
- Expr::IsNull(expr) => Expr::IsNull(Box::new(replace_sink_columns(
156
- *expr,
157
- sink,
158
- sink_expr_by_column,
159
- ))),
160
- Expr::IsNotNull(expr) => Expr::IsNotNull(Box::new(replace_sink_columns(
161
- *expr,
162
- sink,
163
- sink_expr_by_column,
164
- ))),
165
- Expr::Case {
166
- operand,
167
- conditions,
168
- results,
169
- else_result,
170
- } => Expr::Case {
171
- operand: operand
172
- .map(|expr| Box::new(replace_sink_columns(*expr, sink, sink_expr_by_column))),
173
- conditions: conditions
174
- .into_iter()
175
- .map(|expr| replace_sink_columns(expr, sink, sink_expr_by_column))
176
- .collect(),
177
- results: results
178
- .into_iter()
179
- .map(|expr| replace_sink_columns(expr, sink, sink_expr_by_column))
180
- .collect(),
181
- else_result: else_result
182
- .map(|expr| Box::new(replace_sink_columns(*expr, sink, sink_expr_by_column))),
183
- },
184
- Expr::Function(mut function) => {
185
- replace_sink_columns_in_function(&mut function, sink, sink_expr_by_column);
186
- Expr::Function(function)
187
- }
188
- other => other,
189
- }
127
+ ) -> Result<Expr, RewriteError> {
128
+ super::sink_columns::replace(expr, sink, sink_expr_by_column, None)
190
129
  }
191
130
 
192
131
  fn replace_sink_columns_strict(
@@ -195,137 +134,12 @@ fn replace_sink_columns_strict(
195
134
  sink_expr_by_column: &HashMap<String, Expr>,
196
135
  ambiguous_output_columns: &HashSet<String>,
197
136
  ) -> Result<Expr, RewriteError> {
198
- let sink_table = TableName::parse(sink);
199
- match expr {
200
- Expr::CompoundIdentifier(parts) if parts.len() >= 2 => {
201
- if let Some(column) = QualifiedColumn::from_compound_identifier(&parts)
202
- && sink_table.matches_name(column.table.as_str())
203
- {
204
- let key = column.column.key();
205
- if ambiguous_output_columns.contains(&key) {
206
- return Err(RewriteError::unsupported(
207
- ErrorKind::InvalidSinkColumn,
208
- format!(
209
- "ambiguous _OUTPUT_ column '{}': multiple projected expressions share this output name",
210
- column.column.as_str()
211
- ),
212
- ));
213
- }
214
- if let Some(replacement) = sink_expr_by_column.get(&key) {
215
- return Ok(replacement.clone());
216
- }
217
- return Err(RewriteError::catalog(
218
- ErrorKind::InvalidSinkColumn,
219
- format!(
220
- "{sink}.{} is not a projected output column",
221
- column.column.as_str()
222
- ),
223
- Some(sink.to_string()),
224
- Some(column.column.as_str().to_string()),
225
- ));
226
- }
227
- Ok(Expr::CompoundIdentifier(parts))
228
- }
229
- Expr::BinaryOp { left, op, right } => Ok(Expr::BinaryOp {
230
- left: Box::new(replace_sink_columns_strict(
231
- *left,
232
- sink,
233
- sink_expr_by_column,
234
- ambiguous_output_columns,
235
- )?),
236
- op,
237
- right: Box::new(replace_sink_columns_strict(
238
- *right,
239
- sink,
240
- sink_expr_by_column,
241
- ambiguous_output_columns,
242
- )?),
243
- }),
244
- Expr::Nested(expr) => Ok(Expr::Nested(Box::new(replace_sink_columns_strict(
245
- *expr,
246
- sink,
247
- sink_expr_by_column,
248
- ambiguous_output_columns,
249
- )?))),
250
- Expr::UnaryOp { op, expr } => Ok(Expr::UnaryOp {
251
- op,
252
- expr: Box::new(replace_sink_columns_strict(
253
- *expr,
254
- sink,
255
- sink_expr_by_column,
256
- ambiguous_output_columns,
257
- )?),
258
- }),
259
- Expr::IsNull(expr) => Ok(Expr::IsNull(Box::new(replace_sink_columns_strict(
260
- *expr,
261
- sink,
262
- sink_expr_by_column,
263
- ambiguous_output_columns,
264
- )?))),
265
- Expr::IsNotNull(expr) => Ok(Expr::IsNotNull(Box::new(replace_sink_columns_strict(
266
- *expr,
267
- sink,
268
- sink_expr_by_column,
269
- ambiguous_output_columns,
270
- )?))),
271
- Expr::Case {
272
- operand,
273
- conditions,
274
- results,
275
- else_result,
276
- } => Ok(Expr::Case {
277
- operand: match operand {
278
- Some(expr) => Some(Box::new(replace_sink_columns_strict(
279
- *expr,
280
- sink,
281
- sink_expr_by_column,
282
- ambiguous_output_columns,
283
- )?)),
284
- None => None,
285
- },
286
- conditions: conditions
287
- .into_iter()
288
- .map(|expr| {
289
- replace_sink_columns_strict(
290
- expr,
291
- sink,
292
- sink_expr_by_column,
293
- ambiguous_output_columns,
294
- )
295
- })
296
- .collect::<Result<Vec<_>, _>>()?,
297
- results: results
298
- .into_iter()
299
- .map(|expr| {
300
- replace_sink_columns_strict(
301
- expr,
302
- sink,
303
- sink_expr_by_column,
304
- ambiguous_output_columns,
305
- )
306
- })
307
- .collect::<Result<Vec<_>, _>>()?,
308
- else_result: match else_result {
309
- Some(expr) => Some(Box::new(replace_sink_columns_strict(
310
- *expr,
311
- sink,
312
- sink_expr_by_column,
313
- ambiguous_output_columns,
314
- )?)),
315
- None => None,
316
- },
317
- }),
318
- Expr::Function(mut function) => {
319
- replace_sink_columns_strict_in_function(
320
- &mut function,
321
- sink,
322
- sink_expr_by_column,
323
- ambiguous_output_columns,
324
- )?;
325
- Ok(Expr::Function(function))
326
- }
327
- other => Ok(other),
328
- }
137
+ super::sink_columns::replace(
138
+ expr,
139
+ sink,
140
+ sink_expr_by_column,
141
+ Some(ambiguous_output_columns),
142
+ )
329
143
  }
330
144
 
331
145
  pub(crate) fn collect_compound_columns_by_name(expr: &Expr, columns: &mut HashMap<String, Expr>) {
@@ -484,65 +298,6 @@ fn replace_source_alias_qualifiers_in_function(
484
298
  }
485
299
  }
486
300
 
487
- fn replace_sink_columns_in_function(
488
- function: &mut sqlparser::ast::Function,
489
- sink: &str,
490
- sink_expr_by_column: &HashMap<String, Expr>,
491
- ) {
492
- let FunctionArguments::List(args) = &mut function.args else {
493
- return;
494
- };
495
- for arg in &mut args.args {
496
- match arg {
497
- FunctionArg::Unnamed(FunctionArgExpr::Expr(expr))
498
- | FunctionArg::Named {
499
- arg: FunctionArgExpr::Expr(expr),
500
- ..
501
- }
502
- | FunctionArg::ExprNamed {
503
- arg: FunctionArgExpr::Expr(expr),
504
- ..
505
- } => {
506
- *expr = replace_sink_columns(expr.clone(), sink, sink_expr_by_column);
507
- }
508
- _ => {}
509
- }
510
- }
511
- }
512
-
513
- fn replace_sink_columns_strict_in_function(
514
- function: &mut sqlparser::ast::Function,
515
- sink: &str,
516
- sink_expr_by_column: &HashMap<String, Expr>,
517
- ambiguous_output_columns: &HashSet<String>,
518
- ) -> Result<(), RewriteError> {
519
- let FunctionArguments::List(args) = &mut function.args else {
520
- return Ok(());
521
- };
522
- for arg in &mut args.args {
523
- match arg {
524
- FunctionArg::Unnamed(FunctionArgExpr::Expr(expr))
525
- | FunctionArg::Named {
526
- arg: FunctionArgExpr::Expr(expr),
527
- ..
528
- }
529
- | FunctionArg::ExprNamed {
530
- arg: FunctionArgExpr::Expr(expr),
531
- ..
532
- } => {
533
- *expr = replace_sink_columns_strict(
534
- expr.clone(),
535
- sink,
536
- sink_expr_by_column,
537
- ambiguous_output_columns,
538
- )?;
539
- }
540
- _ => {}
541
- }
542
- }
543
- Ok(())
544
- }
545
-
546
301
  pub(crate) fn rewrite_column_qualifiers(expr: &mut Expr, alias_by_base: &AliasByBase) {
547
302
  match expr {
548
303
  Expr::CompoundIdentifier(parts) if parts.len() >= 2 => {
@@ -750,7 +505,7 @@ mod tests {
750
505
  ),
751
506
  ] {
752
507
  assert_eq!(
753
- replace_sink_columns(parse_expr(input), "reports", &columns),
508
+ replace_sink_columns(parse_expr(input), "reports", &columns).unwrap(),
754
509
  parse_expr(expected),
755
510
  "{input}"
756
511
  );
@@ -816,12 +571,71 @@ mod tests {
816
571
  let columns = HashMap::from([("amount".to_string(), parse_expr("input.cost"))]);
817
572
  let original = parse_expr("other.amount IS NULL OR other.amount IS NOT NULL");
818
573
  assert_eq!(
819
- replace_sink_columns(original.clone(), "reports", &columns),
574
+ replace_sink_columns(original.clone(), "reports", &columns).unwrap(),
575
+ original
576
+ );
577
+ assert_eq!(
578
+ apply_output_marker_replacements(original.clone(), &columns, &HashSet::new()).unwrap(),
820
579
  original
821
580
  );
581
+ }
582
+ #[test]
583
+ fn nested_output_references_preserve_strict_validation() {
584
+ let columns = HashMap::from([("amount".to_string(), parse_expr("input.cost"))]);
585
+ let ambiguous = HashSet::from(["amount".to_string()]);
586
+ let error = apply_output_marker_replacements(
587
+ parse_expr("EXISTS (SELECT 1 WHERE _OUTPUT_.amount > 0)"),
588
+ &columns,
589
+ &ambiguous,
590
+ )
591
+ .expect_err("nested ambiguous output must fail closed");
592
+ assert!(error.to_string().contains("ambiguous _OUTPUT_ column"));
593
+ let error = apply_output_marker_replacements(
594
+ parse_expr("EXISTS (SELECT 1 WHERE _OUTPUT_.missing > 0)"),
595
+ &columns,
596
+ &HashSet::new(),
597
+ )
598
+ .expect_err("nested missing output must fail closed");
599
+ assert!(error.to_string().contains("not a projected output column"));
600
+ }
601
+
602
+ #[test]
603
+ fn output_subquery_replaces_only_free_references() {
604
+ let columns = HashMap::from([("amount".to_string(), parse_expr("input.cost"))]);
605
+ let original =
606
+ parse_expr("EXISTS (SELECT 1 FROM lookup AS _OUTPUT_ WHERE _OUTPUT_.amount > 0)");
822
607
  assert_eq!(
823
608
  apply_output_marker_replacements(original.clone(), &columns, &HashSet::new()).unwrap(),
824
609
  original
825
610
  );
611
+ assert_eq!(
612
+ apply_output_marker_replacements(
613
+ parse_expr("EXISTS (SELECT 1 WHERE _OUTPUT_.amount > 0)"),
614
+ &columns,
615
+ &HashSet::new()
616
+ )
617
+ .unwrap(),
618
+ parse_expr("EXISTS (SELECT 1 WHERE input.cost > 0)")
619
+ );
620
+ }
621
+
622
+ #[test]
623
+ fn unrelated_complex_subquery_is_unchanged() {
624
+ let columns = HashMap::from([("amount".to_string(), parse_expr("1"))]);
625
+ let original =
626
+ parse_expr("EXISTS (SELECT 1 FROM sales PIVOT (sum(amount) FOR month IN ('JAN'))) ");
627
+ assert_eq!(
628
+ replace_sink_columns(original.clone(), "sink", &columns).unwrap(),
629
+ original
630
+ );
631
+ let relevant = parse_expr(
632
+ "EXISTS (SELECT sink.amount FROM sales PIVOT (sum(amount) FOR month IN ('JAN'))) ",
633
+ );
634
+ assert!(
635
+ replace_sink_columns(relevant, "sink", &columns)
636
+ .unwrap_err()
637
+ .to_string()
638
+ .contains("operator-specific scope")
639
+ );
826
640
  }
827
641
  }