metricflow 0.207.0.dev1__tar.gz → 0.207.0.dev2__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 (355) hide show
  1. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/PKG-INFO +3 -3
  2. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/dataflow_plan_builder.py +46 -22
  3. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/node_data_set.py +11 -0
  4. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/dataflow_plan.py +5 -0
  5. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/combine_aggregated_outputs.py +7 -3
  6. metricflow-0.207.0.dev2/metricflow/dataflow/nodes/where_filter.py +85 -0
  7. metricflow-0.207.0.dev2/metricflow/dataflow/optimizer/dataflow_optimizer_factory.py +58 -0
  8. metricflow-0.207.0.dev2/metricflow/dataflow/optimizer/predicate_pushdown_optimizer.py +620 -0
  9. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/metricflow_engine.py +12 -9
  10. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/node_processor.py +177 -21
  11. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/id_prefix.py +1 -0
  12. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/pretty_print.py +1 -1
  13. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/linkable_element.py +44 -5
  14. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/linkable_element_set.py +3 -2
  15. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/linkable_spec_resolver.py +8 -8
  16. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/semantic_model_lookup.py +1 -1
  17. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml +4 -2
  18. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/pyproject.toml +1 -1
  19. metricflow-0.207.0.dev1/metricflow/dataflow/nodes/where_filter.py +0 -55
  20. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/.gitignore +0 -0
  21. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/ATTRIBUTION.md +0 -0
  22. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/LICENSE +0 -0
  23. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/README.md +0 -0
  24. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/__init__.py +0 -0
  25. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/__init__.py +0 -0
  26. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/column_types.py +0 -0
  27. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/mf_column.py +0 -0
  28. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/mf_table.py +0 -0
  29. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/__init__.py +0 -0
  30. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/__init__.py +0 -0
  31. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/measure_additiveness.py +0 -0
  32. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/node_evaluator.py +0 -0
  33. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/partitions.py +0 -0
  34. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/source_node.py +0 -0
  35. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/__init__.py +0 -0
  36. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/add_generated_uuid.py +0 -0
  37. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/aggregate_measures.py +0 -0
  38. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/compute_metrics.py +0 -0
  39. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/constrain_time.py +0 -0
  40. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/filter_elements.py +0 -0
  41. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_conversion_events.py +0 -0
  42. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_over_time.py +0 -0
  43. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_to_base.py +0 -0
  44. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_to_time_spine.py +0 -0
  45. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/metric_time_transform.py +0 -0
  46. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/min_max.py +0 -0
  47. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/order_by_limit.py +0 -0
  48. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/read_sql_source.py +0 -0
  49. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/semi_additive_join.py +0 -0
  50. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/window_reaggregation_node.py +0 -0
  51. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/write_to_data_table.py +0 -0
  52. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/write_to_table.py +0 -0
  53. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/__init__.py +0 -0
  54. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/dataflow_plan_optimizer.py +0 -0
  55. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/__init__.py +0 -0
  56. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/cm_branch_combiner.py +0 -0
  57. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/matching_linkable_specs.py +0 -0
  58. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/source_scan_optimizer.py +0 -0
  59. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/__init__.py +0 -0
  60. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/convert_semantic_model.py +0 -0
  61. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/dataset_classes.py +0 -0
  62. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/semantic_model_adapter.py +0 -0
  63. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/sql_dataset.py +0 -0
  64. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/__init__.py +0 -0
  65. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/models.py +0 -0
  66. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/time_source.py +0 -0
  67. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/__init__.py +0 -0
  68. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/convert_to_execution_plan.py +0 -0
  69. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/dataflow_to_execution.py +0 -0
  70. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/execution_plan.py +0 -0
  71. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/executor.py +0 -0
  72. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/__init__.py +0 -0
  73. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/convert_to_sql_plan.py +0 -0
  74. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/dataflow_to_sql.py +0 -0
  75. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/instance_converters.py +0 -0
  76. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/select_column_gen.py +0 -0
  77. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/spec_transforms.py +0 -0
  78. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/sql_expression_builders.py +0 -0
  79. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/sql_join_builder.py +0 -0
  80. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/time_spine.py +0 -0
  81. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/protocols/__init__.py +0 -0
  82. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/protocols/sql_client.py +0 -0
  83. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/py.typed +0 -0
  84. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/__init__.py +0 -0
  85. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/__init__.py +0 -0
  86. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/column_pruner.py +0 -0
  87. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/optimization_levels.py +0 -0
  88. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/rewriting_sub_query_reducer.py +0 -0
  89. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/sql_query_plan_optimizer.py +0 -0
  90. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/sub_query_reducer.py +0 -0
  91. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/table_alias_simplifier.py +0 -0
  92. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/__init__.py +0 -0
  93. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/big_query.py +0 -0
  94. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/databricks.py +0 -0
  95. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/duckdb_renderer.py +0 -0
  96. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/expr_renderer.py +0 -0
  97. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/postgres.py +0 -0
  98. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/redshift.py +0 -0
  99. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/rendering_constants.py +0 -0
  100. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/snowflake.py +0 -0
  101. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/sql_plan_renderer.py +0 -0
  102. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/trino.py +0 -0
  103. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_column.py +0 -0
  104. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_exprs.py +0 -0
  105. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_plan.py +0 -0
  106. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_table.py +0 -0
  107. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql_request/__init__.py +0 -0
  108. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql_request/sql_request_attributes.py +0 -0
  109. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/__init__.py +0 -0
  110. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/handlers/__init__.py +0 -0
  111. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/handlers/handlers.py +0 -0
  112. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/handlers/python_log.py +0 -0
  113. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/models.py +0 -0
  114. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/reporter.py +0 -0
  115. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/validation/__init__.py +0 -0
  116. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/validation/data_warehouse_model_validator.py +0 -0
  117. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/validation/dataflow_join_validator.py +0 -0
  118. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/__init__.py +0 -0
  119. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/aggregation_properties.py +0 -0
  120. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/api/__init__.py +0 -0
  121. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/api/v0_1/__init__.py +0 -0
  122. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/api/v0_1/saved_query_dependency_resolver.py +0 -0
  123. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/assert_one_arg.py +0 -0
  124. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/collection_helpers/__init__.py +0 -0
  125. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/collection_helpers/dedupe.py +0 -0
  126. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/collection_helpers/merger.py +0 -0
  127. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/__init__.py +0 -0
  128. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/dag_to_text.py +0 -0
  129. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/dag_visualization.py +0 -0
  130. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/mf_dag.py +0 -0
  131. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/sequential_id.py +0 -0
  132. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/errors/__init__.py +0 -0
  133. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/errors/error_classes.py +0 -0
  134. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/filters/__init__.py +0 -0
  135. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/filters/merge_where.py +0 -0
  136. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/filters/time_constraint.py +0 -0
  137. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/instances.py +0 -0
  138. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/__init__.py +0 -0
  139. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/formatting.py +0 -0
  140. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/runtime.py +0 -0
  141. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/__init__.py +0 -0
  142. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/dbt_manifest_parser.py +0 -0
  143. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/linkable_element_property.py +0 -0
  144. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/object_to_reference.py +0 -0
  145. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantic_manifest_lookup.py +0 -0
  146. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantic_model_derivation.py +0 -0
  147. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/__init__.py +0 -0
  148. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/element_group.py +0 -0
  149. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/metric_lookup.py +0 -0
  150. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/semantic_model_container.py +0 -0
  151. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/semantic_model_join_evaluator.py +0 -0
  152. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/spec_converters.py +0 -0
  153. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/transformations/__init__.py +0 -0
  154. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/transformations/dedupe_metric_input_measures.py +0 -0
  155. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/__init__.py +0 -0
  156. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/dunder_scheme.py +0 -0
  157. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/linkable_spec_name.py +0 -0
  158. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/metric_scheme.py +0 -0
  159. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/naming_scheme.py +0 -0
  160. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/object_builder_scheme.py +0 -0
  161. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/object_builder_str.py +0 -0
  162. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/protocols/__init__.py +0 -0
  163. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/protocols/query_parameter.py +0 -0
  164. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/py.typed +0 -0
  165. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/__init__.py +0 -0
  166. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/__init__.py +0 -0
  167. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/candidate_push_down/__init__.py +0 -0
  168. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/candidate_push_down/group_by_item_candidate.py +0 -0
  169. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/candidate_push_down/push_down_visitor.py +0 -0
  170. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/filter_spec_resolution/__init__.py +0 -0
  171. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/filter_spec_resolution/filter_location.py +0 -0
  172. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/filter_spec_resolution/filter_pattern_factory.py +0 -0
  173. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/filter_spec_resolution/filter_spec_lookup.py +0 -0
  174. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/filter_spec_resolution/filter_spec_resolver.py +0 -0
  175. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/group_by_item_resolver.py +0 -0
  176. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/path_prefixable.py +0 -0
  177. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/__init__.py +0 -0
  178. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/dag.py +0 -0
  179. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/dag_builder.py +0 -0
  180. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/input_metric_location.py +0 -0
  181. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/resolution_nodes/__init__.py +0 -0
  182. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/resolution_nodes/base_node.py +0 -0
  183. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/resolution_nodes/measure_source_node.py +0 -0
  184. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/resolution_nodes/metric_resolution_node.py +0 -0
  185. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/resolution_nodes/no_metrics_query_source_node.py +0 -0
  186. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/resolution_nodes/query_resolution_node.py +0 -0
  187. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_path.py +0 -0
  188. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/__init__.py +0 -0
  189. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/filter_spec_resolver/__init__.py +0 -0
  190. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/filter_spec_resolver/invalid_where.py +0 -0
  191. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/__init__.py +0 -0
  192. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/ambiguous_group_by_item.py +0 -0
  193. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/invalid_use_of_date_part.py +0 -0
  194. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/multiple_join_paths.py +0 -0
  195. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/no_common_items.py +0 -0
  196. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/no_matching_items_for_measure.py +0 -0
  197. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/no_matching_items_for_no_metrics_query.py +0 -0
  198. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/no_parent_candidates.py +0 -0
  199. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/issues_base.py +0 -0
  200. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/__init__.py +0 -0
  201. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/cumulative_metric_requires_metric_time.py +0 -0
  202. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/duplicate_metric.py +0 -0
  203. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_limit.py +0 -0
  204. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_metric.py +0 -0
  205. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_min_max_only.py +0 -0
  206. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_order.py +0 -0
  207. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/no_metric_or_group_by.py +0 -0
  208. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/offset_metric_requires_metric_time.py +0 -0
  209. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/string_input_parsing_issue.py +0 -0
  210. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_exceptions.py +0 -0
  211. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_parser.py +0 -0
  212. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_resolution.py +0 -0
  213. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_resolver.py +0 -0
  214. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/resolver_inputs/__init__.py +0 -0
  215. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/resolver_inputs/base_resolver_inputs.py +0 -0
  216. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/resolver_inputs/query_resolver_inputs.py +0 -0
  217. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/similarity.py +0 -0
  218. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/suggestion_generator.py +0 -0
  219. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/__init__.py +0 -0
  220. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/base_validation_rule.py +0 -0
  221. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/duplicate_metric.py +0 -0
  222. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/metric_time_requirements.py +0 -0
  223. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/query_validator.py +0 -0
  224. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/random_id.py +0 -0
  225. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/__init__.py +0 -0
  226. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/column_assoc.py +0 -0
  227. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/dimension_spec_resolver.py +0 -0
  228. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/dunder_column_association_resolver.py +0 -0
  229. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/linkable_spec_set.py +0 -0
  230. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/partition_spec_set.py +0 -0
  231. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/__init__.py +0 -0
  232. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/base_time_grain.py +0 -0
  233. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/entity_link_pattern.py +0 -0
  234. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/match_list_pattern.py +0 -0
  235. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/metric_pattern.py +0 -0
  236. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/metric_time_pattern.py +0 -0
  237. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/no_group_by_metric.py +0 -0
  238. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/none_date_part.py +0 -0
  239. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/spec_pattern.py +0 -0
  240. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/typed_patterns.py +0 -0
  241. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/python_object.py +0 -0
  242. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/query_param_implementations.py +0 -0
  243. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/query_spec.py +0 -0
  244. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/rendered_spec_tracker.py +0 -0
  245. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/spec_classes.py +0 -0
  246. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/spec_set.py +0 -0
  247. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/spec_set_transforms.py +0 -0
  248. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_dimension.py +0 -0
  249. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_entity.py +0 -0
  250. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_metric.py +0 -0
  251. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_time_dimension.py +0 -0
  252. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_transform.py +0 -0
  253. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/__init__.py +0 -0
  254. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/sql_bind_parameters.py +0 -0
  255. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/sql_column_type.py +0 -0
  256. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/sql_join_type.py +0 -0
  257. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/__init__.py +0 -0
  258. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/config_helpers.py +0 -0
  259. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/example_project_configuration.py +0 -0
  260. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/id_helpers.py +0 -0
  261. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/manifest_helpers.py +0 -0
  262. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/metric_time_dimension.py +0 -0
  263. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/__init__.py +0 -0
  264. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/__init__.py +0 -0
  265. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/metrics.yaml +0 -0
  266. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/project_configuration.yaml +0 -0
  267. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/semantic_models/monthly_measures_source.yaml +0 -0
  268. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/semantic_models/yearly_measures_source.yaml +0 -0
  269. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/config_linter_manifest/__init__.py +0 -0
  270. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/config_linter_manifest/multiple_semantic_models_without_divider.yml +0 -0
  271. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/config_linter_manifest/project_configuration.yaml +0 -0
  272. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/cyclic_join_manifest/__init__.py +0 -0
  273. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/cyclic_join_manifest/listings_latest.yaml +0 -0
  274. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/cyclic_join_manifest/listings_latest_cyclic.yaml +0 -0
  275. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/cyclic_join_manifest/project_configuration.yaml +0 -0
  276. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/data_warehouse_validation_manifest/__init__.py +0 -0
  277. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/data_warehouse_validation_manifest/project_configuration.yaml +0 -0
  278. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/data_warehouse_validation_manifest/semantic_models/semantic_model1.yml +0 -0
  279. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/__init__.py +0 -0
  280. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/metrics/bookings_cumulative.yaml +0 -0
  281. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/metrics/bookings_last_month.yaml +0 -0
  282. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/metrics/bookings_monthly_cumulative.yaml +0 -0
  283. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/project_configuration.yaml +0 -0
  284. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/semantic_models/bookings_monthly_source.yaml +0 -0
  285. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/semantic_models/extended_bookings_source.yaml +0 -0
  286. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/semantic_models/listings_extended_source.yaml +0 -0
  287. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/join_types_manifest/__init__.py +0 -0
  288. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/join_types_manifest/bookings_source.yaml +0 -0
  289. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/join_types_manifest/listings_source.yaml +0 -0
  290. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/join_types_manifest/project_configuration.yaml +0 -0
  291. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/multi_hop_join_manifest/__init__.py +0 -0
  292. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/multi_hop_join_manifest/account_month_txns.yaml +0 -0
  293. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/multi_hop_join_manifest/bridge_table.yaml +0 -0
  294. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/multi_hop_join_manifest/customer_other_data.yaml +0 -0
  295. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/multi_hop_join_manifest/customer_table.yaml +0 -0
  296. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/multi_hop_join_manifest/project_configuration.yaml +0 -0
  297. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/multi_hop_join_manifest/third_hop_table.yaml +0 -0
  298. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/non_sm_manifest/__init__.py +0 -0
  299. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/non_sm_manifest/bookings_source.yaml +0 -0
  300. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/non_sm_manifest/listings_latest.yaml +0 -0
  301. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/non_sm_manifest/project_configuration.yaml +0 -0
  302. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/__init__.py +0 -0
  303. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/account_month_txns.yaml +0 -0
  304. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/bridge_table.yaml +0 -0
  305. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/customer_other_data.yaml +0 -0
  306. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/customer_table.yaml +0 -0
  307. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/metrics.yaml +0 -0
  308. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/project_configuration.yaml +0 -0
  309. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/partitioned_multi_hop_join_manifest/third_hop_table.yaml +0 -0
  310. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/__init__.py +0 -0
  311. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/project_configuration.yaml +0 -0
  312. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_accounts.yaml +0 -0
  313. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_bookings.yaml +0 -0
  314. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_companies.yaml +0 -0
  315. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_listings.yaml +0 -0
  316. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_lux_listings.yaml +0 -0
  317. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_metrics.yaml +0 -0
  318. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_users.yaml +0 -0
  319. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/shared/project_configuration.yaml +0 -0
  320. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/__init__.py +0 -0
  321. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/project_configuration.yaml +0 -0
  322. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/saved_queries.yaml +0 -0
  323. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/accounts_source.yaml +0 -0
  324. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/bookings_source.yaml +0 -0
  325. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/buys_source.yaml +0 -0
  326. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/companies.yaml +0 -0
  327. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/id_verifications.yaml +0 -0
  328. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/listings_latest.yaml +0 -0
  329. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/lux_listing_mapping.yaml +0 -0
  330. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/revenue.yaml +0 -0
  331. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/user_sm_source.yaml +0 -0
  332. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/users_latest.yaml +0 -0
  333. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/views_source.yaml +0 -0
  334. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/semantic_models/visits_source.yaml +0 -0
  335. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/__init__.py +0 -0
  336. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/all_entity_measure_source.yaml +0 -0
  337. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/entity_0_dimension_source.yaml +0 -0
  338. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/entity_0_measure_source.yaml +0 -0
  339. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/entity_1_and_entity_2_measure_source.yaml +0 -0
  340. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/entity_1_dimension_source.yaml +0 -0
  341. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/entity_1_measure_source.yaml +0 -0
  342. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/entity_1_to_entity_0_mapping_source.yaml +0 -0
  343. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/entity_2_to_entity_0_mapping_source.yaml +0 -0
  344. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/metrics.yaml +0 -0
  345. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_multi_hop_join_manifest/project_configuration.yaml +0 -0
  346. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/snapshot_helpers.py +0 -0
  347. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/time_helpers.py +0 -0
  348. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/__init__.py +0 -0
  349. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/dateutil_adjuster.py +0 -0
  350. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/time_constants.py +0 -0
  351. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/time_period.py +0 -0
  352. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/time_source.py +0 -0
  353. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/visitor.py +0 -0
  354. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/workarounds/__init__.py +0 -0
  355. {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/workarounds/reference.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: metricflow
3
- Version: 0.207.0.dev1
3
+ Version: 0.207.0.dev2
4
4
  Summary: Translates a simple metric definition into reusable SQL and executes it against the SQL engine of your choice.
5
5
  Project-URL: Documentation, https://docs.getdbt.com/docs/build/about-metricflow
6
6
  Project-URL: Source Code, https://github.com/dbt-labs/metricflow
@@ -18,11 +18,11 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
18
18
  Classifier: Programming Language :: Python :: Implementation :: PyPy
19
19
  Requires-Python: <3.13,>=3.8
20
20
  Requires-Dist: dbt-semantic-interfaces<2.0.0,>=0.6.1
21
- Requires-Dist: dbt-semantic-interfaces==0.6.1
21
+ Requires-Dist: dbt-semantic-interfaces==0.6.5
22
22
  Requires-Dist: graphviz<0.21,>=0.18.2
23
23
  Requires-Dist: jinja2>=3.1.3
24
24
  Requires-Dist: more-itertools<10.2.0,>=8.10.0
25
- Requires-Dist: pydantic<1.11.0,>=1.10.0
25
+ Requires-Dist: pydantic<3.0,>=1.10.0
26
26
  Requires-Dist: python-dateutil<2.10.0,>=2.9.0
27
27
  Requires-Dist: rapidfuzz<4.0,>=3.0
28
28
  Requires-Dist: tabulate>=0.8.9
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  import time
5
5
  from dataclasses import dataclass
6
- from typing import Dict, List, Optional, Sequence, Set, Tuple, Union
6
+ from typing import Dict, FrozenSet, List, Optional, Sequence, Set, Tuple, Union
7
7
 
8
8
  from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
9
9
  from dbt_semantic_interfaces.implementations.metric import PydanticMetricTimeWindow
@@ -82,7 +82,10 @@ from metricflow.dataflow.nodes.where_filter import WhereConstraintNode
82
82
  from metricflow.dataflow.nodes.window_reaggregation_node import WindowReaggregationNode
83
83
  from metricflow.dataflow.nodes.write_to_data_table import WriteToResultDataTableNode
84
84
  from metricflow.dataflow.nodes.write_to_table import WriteToResultTableNode
85
- from metricflow.dataflow.optimizer.dataflow_plan_optimizer import DataflowPlanOptimizer
85
+ from metricflow.dataflow.optimizer.dataflow_optimizer_factory import (
86
+ DataflowPlanOptimization,
87
+ DataflowPlanOptimizerFactory,
88
+ )
86
89
  from metricflow.dataset.dataset_classes import DataSet
87
90
  from metricflow.plan_conversion.node_processor import (
88
91
  PredicateInputType,
@@ -143,7 +146,7 @@ class DataflowPlanBuilder:
143
146
  query_spec: MetricFlowQuerySpec,
144
147
  output_sql_table: Optional[SqlTable] = None,
145
148
  output_selection_specs: Optional[InstanceSpecSet] = None,
146
- optimizers: Sequence[DataflowPlanOptimizer] = (),
149
+ optimizations: FrozenSet[DataflowPlanOptimization] = frozenset(),
147
150
  ) -> DataflowPlan:
148
151
  """Generate a plan for reading the results of a query with the given spec into a data_table or table."""
149
152
  # Workaround for a Pycharm type inspection issue with decorators.
@@ -152,7 +155,7 @@ class DataflowPlanBuilder:
152
155
  query_spec=query_spec,
153
156
  output_sql_table=output_sql_table,
154
157
  output_selection_specs=output_selection_specs,
155
- optimizers=optimizers,
158
+ optimizations=optimizations,
156
159
  )
157
160
 
158
161
  def _build_query_output_node(
@@ -184,7 +187,11 @@ class DataflowPlanBuilder:
184
187
  )
185
188
  )
186
189
 
187
- predicate_pushdown_state = PredicatePushdownState(time_range_constraint=query_spec.time_range_constraint)
190
+ predicate_pushdown_state = PredicatePushdownState(
191
+ time_range_constraint=query_spec.time_range_constraint,
192
+ where_filter_specs=(),
193
+ pushdown_enabled_types=frozenset({PredicateInputType.TIME_RANGE_CONSTRAINT}),
194
+ )
188
195
 
189
196
  return self._build_metrics_output_node(
190
197
  metric_specs=tuple(
@@ -206,7 +213,7 @@ class DataflowPlanBuilder:
206
213
  query_spec: MetricFlowQuerySpec,
207
214
  output_sql_table: Optional[SqlTable],
208
215
  output_selection_specs: Optional[InstanceSpecSet],
209
- optimizers: Sequence[DataflowPlanOptimizer],
216
+ optimizations: FrozenSet[DataflowPlanOptimization],
210
217
  ) -> DataflowPlan:
211
218
  metrics_output_node = self._build_query_output_node(query_spec=query_spec)
212
219
 
@@ -220,7 +227,11 @@ class DataflowPlanBuilder:
220
227
 
221
228
  plan_id = DagId.from_id_prefix(StaticIdPrefix.DATAFLOW_PLAN_PREFIX)
222
229
  plan = DataflowPlan(sink_nodes=[sink_node], plan_id=plan_id)
223
- for optimizer in optimizers:
230
+ return self._optimize_plan(plan, optimizations)
231
+
232
+ def _optimize_plan(self, plan: DataflowPlan, optimizations: FrozenSet[DataflowPlanOptimization]) -> DataflowPlan:
233
+ optimizer_factory = DataflowPlanOptimizerFactory(self._node_data_set_resolver)
234
+ for optimizer in optimizer_factory.get_optimizers(optimizations):
224
235
  logger.info(f"Applying {optimizer.__class__.__name__}")
225
236
  try:
226
237
  plan = optimizer.optimize(plan)
@@ -251,6 +262,7 @@ class DataflowPlanBuilder:
251
262
  disabled_pushdown_state = PredicatePushdownState.with_pushdown_disabled()
252
263
  time_range_only_pushdown_state = PredicatePushdownState(
253
264
  time_range_constraint=predicate_pushdown_state.time_range_constraint,
265
+ where_filter_specs=tuple(),
254
266
  pushdown_enabled_types=frozenset([PredicateInputType.TIME_RANGE_CONSTRAINT]),
255
267
  )
256
268
 
@@ -511,7 +523,6 @@ class DataflowPlanBuilder:
511
523
  ),
512
524
  descendent_filter_specs=metric_spec.filter_specs,
513
525
  )
514
-
515
526
  logger.info(
516
527
  f"For\n{indent(mf_pformat(metric_spec))}"
517
528
  f"\nneeded measure is:"
@@ -568,6 +579,9 @@ class DataflowPlanBuilder:
568
579
 
569
580
  # If metric is offset, we'll apply where constraint after offset to avoid removing values
570
581
  # unexpectedly. Time constraint will be applied by INNER JOINing to time spine.
582
+ # We may consider encapsulating this in pushdown state later, but as of this moment pushdown
583
+ # is about post-join to pre-join for dimension access, and relies on the builder to collect
584
+ # predicates from query and metric specs and make them available at measure level.
571
585
  if not metric_spec.has_time_offset:
572
586
  filter_specs.extend(metric_spec.filter_specs)
573
587
 
@@ -623,8 +637,7 @@ class DataflowPlanBuilder:
623
637
  )
624
638
 
625
639
  if len(metric_spec.filter_specs) > 0:
626
- merged_where_filter = WhereFilterSpec.merge_iterable(metric_spec.filter_specs)
627
- output_node = WhereConstraintNode(parent_node=output_node, where_constraint=merged_where_filter)
640
+ output_node = WhereConstraintNode(parent_node=output_node, where_specs=metric_spec.filter_specs)
628
641
  if not extraneous_linkable_specs.is_subset_of(queried_linkable_specs):
629
642
  output_node = FilterElementsNode(
630
643
  parent_node=output_node,
@@ -723,17 +736,21 @@ class DataflowPlanBuilder:
723
736
 
724
737
  return CombineAggregatedOutputsNode(parent_nodes=output_nodes)
725
738
 
726
- def build_plan_for_distinct_values(self, query_spec: MetricFlowQuerySpec) -> DataflowPlan:
739
+ def build_plan_for_distinct_values(
740
+ self, query_spec: MetricFlowQuerySpec, optimizations: FrozenSet[DataflowPlanOptimization] = frozenset()
741
+ ) -> DataflowPlan:
727
742
  """Generate a plan that would get the distinct values of a linkable instance.
728
743
 
729
744
  e.g. distinct listing__country_latest for bookings by listing__country_latest
730
745
  """
731
746
  # Workaround for a Pycharm type inspection issue with decorators.
732
747
  # noinspection PyArgumentList
733
- return self._build_plan_for_distinct_values(query_spec)
748
+ return self._build_plan_for_distinct_values(query_spec, optimizations=optimizations)
734
749
 
735
750
  @log_runtime()
736
- def _build_plan_for_distinct_values(self, query_spec: MetricFlowQuerySpec) -> DataflowPlan:
751
+ def _build_plan_for_distinct_values(
752
+ self, query_spec: MetricFlowQuerySpec, optimizations: FrozenSet[DataflowPlanOptimization]
753
+ ) -> DataflowPlan:
737
754
  assert not query_spec.metric_specs, "Can't build distinct values plan with metrics."
738
755
  query_level_filter_specs: Sequence[WhereFilterSpec] = ()
739
756
  if query_spec.filter_intersection is not None and len(query_spec.filter_intersection.where_filters) > 0:
@@ -751,7 +768,9 @@ class DataflowPlanBuilder:
751
768
  required_linkable_specs, _ = self.__get_required_and_extraneous_linkable_specs(
752
769
  queried_linkable_specs=query_spec.linkable_specs, filter_specs=query_level_filter_specs
753
770
  )
754
- predicate_pushdown_state = PredicatePushdownState(time_range_constraint=query_spec.time_range_constraint)
771
+ predicate_pushdown_state = PredicatePushdownState(
772
+ time_range_constraint=query_spec.time_range_constraint, where_filter_specs=query_level_filter_specs
773
+ )
755
774
  dataflow_recipe = self._find_dataflow_recipe(
756
775
  linkable_spec_set=required_linkable_specs, predicate_pushdown_state=predicate_pushdown_state
757
776
  )
@@ -763,9 +782,7 @@ class DataflowPlanBuilder:
763
782
  output_node = JoinOnEntitiesNode(left_node=output_node, join_targets=dataflow_recipe.join_targets)
764
783
 
765
784
  if len(query_level_filter_specs) > 0:
766
- output_node = WhereConstraintNode(
767
- parent_node=output_node, where_constraint=WhereFilterSpec.merge_iterable(query_level_filter_specs)
768
- )
785
+ output_node = WhereConstraintNode(parent_node=output_node, where_specs=query_level_filter_specs)
769
786
  if query_spec.time_range_constraint:
770
787
  output_node = ConstrainTimeRangeNode(
771
788
  parent_node=output_node, time_range_constraint=query_spec.time_range_constraint
@@ -782,7 +799,8 @@ class DataflowPlanBuilder:
782
799
  parent_node=output_node, order_by_specs=query_spec.order_by_specs, limit=query_spec.limit
783
800
  )
784
801
 
785
- return DataflowPlan(sink_nodes=[sink_node])
802
+ plan = DataflowPlan(sink_nodes=[sink_node])
803
+ return self._optimize_plan(plan, optimizations)
786
804
 
787
805
  @staticmethod
788
806
  def build_sink_node(
@@ -954,7 +972,14 @@ class DataflowPlanBuilder:
954
972
  node_data_set_resolver=self._node_data_set_resolver,
955
973
  )
956
974
 
957
- if predicate_pushdown_state.has_pushdown_potential:
975
+ if predicate_pushdown_state.has_pushdown_potential and default_join_type is not SqlJoinType.FULL_OUTER:
976
+ # TODO: encapsulate join type and distinct values state and eventually move this to a DataflowPlanOptimizer
977
+ # This works today because all of our subsequent join configuration operations preserve the join type
978
+ # as-is, or else switch it to a CROSS JOIN or INNER JOIN type, both of which are safe for predicate
979
+ # pushdown. However, there is currently no way to enforce that invariant, so we will need to move
980
+ # to a model where we evaluate the join nodes themselves and decide on whether or not to push down
981
+ # the predicate. This will be much more straightforward once we finish encapsulating our existing
982
+ # time range constraint pushdown controls into this mechanism.
958
983
  candidate_nodes_for_left_side_of_join = list(
959
984
  node_processor.apply_matching_filter_predicates(
960
985
  source_nodes=candidate_nodes_for_left_side_of_join,
@@ -1504,12 +1529,11 @@ class DataflowPlanBuilder:
1504
1529
  )
1505
1530
 
1506
1531
  pre_aggregate_node: DataflowPlanNode = cumulative_metric_constrained_node or unaggregated_measure_node
1507
- merged_where_filter_spec = WhereFilterSpec.merge_iterable(metric_input_measure_spec.filter_specs)
1508
1532
  if len(metric_input_measure_spec.filter_specs) > 0:
1509
1533
  # Apply where constraint on the node
1510
1534
  pre_aggregate_node = WhereConstraintNode(
1511
1535
  parent_node=pre_aggregate_node,
1512
- where_constraint=merged_where_filter_spec,
1536
+ where_specs=metric_input_measure_spec.filter_specs,
1513
1537
  )
1514
1538
 
1515
1539
  if non_additive_dimension_spec is not None:
@@ -1579,7 +1603,7 @@ class DataflowPlanBuilder:
1579
1603
  ]
1580
1604
  if len(queried_filter_specs) > 0:
1581
1605
  output_node = WhereConstraintNode(
1582
- parent_node=output_node, where_constraint=WhereFilterSpec.merge_iterable(queried_filter_specs)
1606
+ parent_node=output_node, where_specs=queried_filter_specs, always_apply=True
1583
1607
  )
1584
1608
 
1585
1609
  # TODO: this will break if you query by agg_time_dimension but apply a time constraint on metric_time.
@@ -2,8 +2,11 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING, Dict, Optional, Sequence
4
4
 
5
+ from metricflow_semantics.dag.id_prefix import StaticIdPrefix
6
+ from metricflow_semantics.dag.sequential_id import SequentialIdGenerator
5
7
  from metricflow_semantics.mf_logging.runtime import log_block_runtime
6
8
  from metricflow_semantics.specs.column_assoc import ColumnAssociationResolver
9
+ from typing_extensions import override
7
10
 
8
11
  from metricflow.dataflow.dataflow_plan import (
9
12
  DataflowPlanNode,
@@ -93,3 +96,11 @@ class DataflowPlanNodeOutputDataSetResolver(DataflowToSqlQueryPlanConverter):
93
96
  semantic_manifest_lookup=self._semantic_manifest_lookup,
94
97
  _node_to_output_data_set=dict(self._node_to_output_data_set),
95
98
  )
99
+
100
+ @override
101
+ def _next_unique_table_alias(self) -> str:
102
+ """Return the next unique table alias to use in generating queries.
103
+
104
+ This uses a separate prefix in order to minimize subquery ID thrash.
105
+ """
106
+ return SequentialIdGenerator.create_next_id(StaticIdPrefix.NODE_RESOLVER_SUB_QUERY).str_value
@@ -215,6 +215,11 @@ class DataflowPlan(MetricFlowDag[DataflowPlanNode]):
215
215
  def sink_node(self) -> DataflowPlanNode: # noqa: D102
216
216
  return self._sink_nodes[0]
217
217
 
218
+ @property
219
+ def node_count(self) -> int:
220
+ """Returns the number of nodes in the DataflowPlan."""
221
+ return len(DataflowPlan.__all_nodes_in_subgraph(self.sink_node))
222
+
218
223
  @staticmethod
219
224
  def __all_nodes_in_subgraph(node: DataflowPlanNode) -> Sequence[DataflowPlanNode]:
220
225
  """Node accessor for retrieving a flattened sequence of all nodes in the subgraph upstream of the input node.
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Sequence, Union
3
+ from typing import Sequence
4
4
 
5
5
  from metricflow_semantics.dag.id_prefix import IdPrefix, StaticIdPrefix
6
6
  from metricflow_semantics.visitor import VisitorOutputT
@@ -16,8 +16,13 @@ class CombineAggregatedOutputsNode(DataflowPlanNode):
16
16
 
17
17
  def __init__( # noqa: D107
18
18
  self,
19
- parent_nodes: Sequence[Union[DataflowPlanNode, DataflowPlanNode]],
19
+ parent_nodes: Sequence[DataflowPlanNode],
20
20
  ) -> None:
21
+ num_parents = len(parent_nodes)
22
+ assert num_parents > 1, (
23
+ "The CombineAggregatedOutputsNode is intended to merge the output datasets from 2 or more nodes, but this "
24
+ f"node is being initialized with with only {num_parents} parent(s)."
25
+ )
21
26
  super().__init__(node_id=self.create_unique_id(), parent_nodes=parent_nodes)
22
27
 
23
28
  @classmethod
@@ -37,5 +42,4 @@ class CombineAggregatedOutputsNode(DataflowPlanNode):
37
42
  def with_new_parents( # noqa: D102
38
43
  self, new_parent_nodes: Sequence[DataflowPlanNode]
39
44
  ) -> CombineAggregatedOutputsNode:
40
- assert len(new_parent_nodes) == 1
41
45
  return CombineAggregatedOutputsNode(parent_nodes=new_parent_nodes)
@@ -0,0 +1,85 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Sequence
4
+
5
+ from metricflow_semantics.dag.id_prefix import IdPrefix, StaticIdPrefix
6
+ from metricflow_semantics.dag.mf_dag import DisplayedProperty
7
+ from metricflow_semantics.specs.spec_classes import WhereFilterSpec
8
+ from metricflow_semantics.visitor import VisitorOutputT
9
+
10
+ from metricflow.dataflow.dataflow_plan import DataflowPlanNode, DataflowPlanNodeVisitor
11
+
12
+
13
+ class WhereConstraintNode(DataflowPlanNode):
14
+ """Remove rows using a WHERE clause."""
15
+
16
+ def __init__(
17
+ self,
18
+ parent_node: DataflowPlanNode,
19
+ where_specs: Sequence[WhereFilterSpec],
20
+ always_apply: bool = False,
21
+ ) -> None:
22
+ """Initializer.
23
+
24
+ WhereConstraintNodes must always have exactly one parent, since they always wrap a single subquery input.
25
+
26
+ The always_apply parameter serves as an indicator for a WhereConstraintNode that is added to a plan in order
27
+ to clean up null outputs from a pre-join filter. For example, when doing time spine joins to fill null values
28
+ for metric outputs sometimes that join will result in rows with null values for various dimension attributes.
29
+ By re-applying the filter expression after the join step we will discard those unexpected output rows created
30
+ by the join (rather than the underlying inputs). In this case, we must ensure that the filters defined in this
31
+ node are always applied at the moment this node is processed, regardless of whether or not they've been pushed
32
+ down through the DAG.
33
+ """
34
+ self._where_specs = where_specs
35
+ self.parent_node = parent_node
36
+ self.always_apply = always_apply
37
+ super().__init__(node_id=self.create_unique_id(), parent_nodes=(parent_node,))
38
+
39
+ @classmethod
40
+ def id_prefix(cls) -> IdPrefix: # noqa: D102
41
+ return StaticIdPrefix.DATAFLOW_NODE_WHERE_CONSTRAINT_ID_PREFIX
42
+
43
+ @property
44
+ def where(self) -> WhereFilterSpec:
45
+ """Returns the specs for the elements that it should pass."""
46
+ return WhereFilterSpec.merge_iterable(self._where_specs)
47
+
48
+ @property
49
+ def input_where_specs(self) -> Sequence[WhereFilterSpec]:
50
+ """Returns the discrete set of input where filter specs for this node.
51
+
52
+ This is useful for things like predicate pushdown, where we need to differentiate between individual specs
53
+ for pushdown operations on the filter spec level. We merge them for things like rendering and node comparisons,
54
+ but in some cases we may be able to push down a subset of the input specs for efficiency reasons.
55
+ """
56
+ return self._where_specs
57
+
58
+ def accept(self, visitor: DataflowPlanNodeVisitor[VisitorOutputT]) -> VisitorOutputT: # noqa: D102
59
+ return visitor.visit_where_constraint_node(self)
60
+
61
+ @property
62
+ def description(self) -> str: # noqa: D102
63
+ # Can't put the where condition here as it can cause rendering issues when there are SQL execution parameters.
64
+ # e.g. "Constrain Output with WHERE listing__country = :1"
65
+ return "Constrain Output with WHERE"
66
+
67
+ @property
68
+ def displayed_properties(self) -> Sequence[DisplayedProperty]: # noqa: D102
69
+ properties = tuple(super().displayed_properties) + (DisplayedProperty("where_condition", self.where),)
70
+ if self.always_apply:
71
+ properties = properties + (DisplayedProperty("All filters always applied:", self.always_apply),)
72
+ return properties
73
+
74
+ def functionally_identical(self, other_node: DataflowPlanNode) -> bool: # noqa: D102
75
+ return (
76
+ isinstance(other_node, self.__class__)
77
+ and other_node.where == self.where
78
+ and other_node.always_apply == self.always_apply
79
+ )
80
+
81
+ def with_new_parents(self, new_parent_nodes: Sequence[DataflowPlanNode]) -> WhereConstraintNode: # noqa: D102
82
+ assert len(new_parent_nodes) == 1
83
+ return WhereConstraintNode(
84
+ parent_node=new_parent_nodes[0], where_specs=self.input_where_specs, always_apply=self.always_apply
85
+ )
@@ -0,0 +1,58 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum
4
+ from typing import FrozenSet, List, Sequence
5
+
6
+ from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
7
+
8
+ from metricflow.dataflow.builder.node_data_set import DataflowPlanNodeOutputDataSetResolver
9
+ from metricflow.dataflow.optimizer.dataflow_plan_optimizer import DataflowPlanOptimizer
10
+ from metricflow.dataflow.optimizer.predicate_pushdown_optimizer import PredicatePushdownOptimizer
11
+ from metricflow.dataflow.optimizer.source_scan.source_scan_optimizer import SourceScanOptimizer
12
+
13
+
14
+ class DataflowPlanOptimization(Enum):
15
+ """Enumeration of optimization types available for execution.
16
+
17
+ Values indicate order of application. We apply the source scan optimizer first because it reduces input branches,
18
+ making for maximally parsimonious queries prior to application of predicate pushdown. Note this is safe only
19
+ because the SourceScanOptimizer combines from the CombineAggregatedOutputNode, and will only combine branches
20
+ from there to source if they are functionally identical (i.e., they have all of the same WhereConstraintNode
21
+ configurations).
22
+ """
23
+
24
+ SOURCE_SCAN = 0
25
+ PREDICATE_PUSHDOWN = 1
26
+
27
+ @staticmethod
28
+ def all_optimizations() -> FrozenSet[DataflowPlanOptimization]:
29
+ """Convenience method for getting a set of all available optimizations."""
30
+ return frozenset((DataflowPlanOptimization.SOURCE_SCAN, DataflowPlanOptimization.PREDICATE_PUSHDOWN))
31
+
32
+
33
+ class DataflowPlanOptimizerFactory:
34
+ """Factory class for initializing an enumerated set of optimizers.
35
+
36
+ This allows us to centralize initialization and, most importantly, share class instances with cached high cost
37
+ processing between the DataflowPlanBuilder and the optimizer instances requiring that functionality.
38
+ """
39
+
40
+ def __init__(self, node_data_set_resolver: DataflowPlanNodeOutputDataSetResolver) -> None:
41
+ """Initializer.
42
+
43
+ This collects all of the initialization requirements for the optimizers it manages.
44
+ """
45
+ self._node_data_set_resolver = node_data_set_resolver
46
+
47
+ def get_optimizers(self, optimizations: FrozenSet[DataflowPlanOptimization]) -> Sequence[DataflowPlanOptimizer]:
48
+ """Initializes and returns a sequence of optimizers matching the input optimization requests."""
49
+ optimizers: List[DataflowPlanOptimizer] = []
50
+ for optimization in sorted(list(optimizations), key=lambda x: x.value):
51
+ if optimization is DataflowPlanOptimization.SOURCE_SCAN:
52
+ optimizers.append(SourceScanOptimizer())
53
+ elif optimization is DataflowPlanOptimization.PREDICATE_PUSHDOWN:
54
+ optimizers.append(PredicatePushdownOptimizer(self._node_data_set_resolver))
55
+ else:
56
+ assert_values_exhausted(optimization)
57
+
58
+ return tuple(optimizers)