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.
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/PKG-INFO +3 -3
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/dataflow_plan_builder.py +46 -22
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/node_data_set.py +11 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/dataflow_plan.py +5 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/combine_aggregated_outputs.py +7 -3
- metricflow-0.207.0.dev2/metricflow/dataflow/nodes/where_filter.py +85 -0
- metricflow-0.207.0.dev2/metricflow/dataflow/optimizer/dataflow_optimizer_factory.py +58 -0
- metricflow-0.207.0.dev2/metricflow/dataflow/optimizer/predicate_pushdown_optimizer.py +620 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/metricflow_engine.py +12 -9
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/node_processor.py +177 -21
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/id_prefix.py +1 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/pretty_print.py +1 -1
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/linkable_element.py +44 -5
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/linkable_element_set.py +3 -2
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/linkable_spec_resolver.py +8 -8
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/semantic_model_lookup.py +1 -1
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/metrics.yaml +4 -2
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/pyproject.toml +1 -1
- metricflow-0.207.0.dev1/metricflow/dataflow/nodes/where_filter.py +0 -55
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/.gitignore +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/ATTRIBUTION.md +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/LICENSE +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/README.md +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/column_types.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/mf_column.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/data_table/mf_table.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/measure_additiveness.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/node_evaluator.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/partitions.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/source_node.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/add_generated_uuid.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/aggregate_measures.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/compute_metrics.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/constrain_time.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/filter_elements.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_conversion_events.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_over_time.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_to_base.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/join_to_time_spine.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/metric_time_transform.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/min_max.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/order_by_limit.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/read_sql_source.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/semi_additive_join.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/window_reaggregation_node.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/write_to_data_table.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/nodes/write_to_table.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/dataflow_plan_optimizer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/cm_branch_combiner.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/matching_linkable_specs.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/optimizer/source_scan/source_scan_optimizer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/convert_semantic_model.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/dataset_classes.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/semantic_model_adapter.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataset/sql_dataset.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/models.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/engine/time_source.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/convert_to_execution_plan.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/dataflow_to_execution.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/execution_plan.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/execution/executor.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/convert_to_sql_plan.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/dataflow_to_sql.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/instance_converters.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/select_column_gen.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/spec_transforms.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/sql_expression_builders.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/sql_join_builder.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/plan_conversion/time_spine.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/protocols/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/protocols/sql_client.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/py.typed +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/column_pruner.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/optimization_levels.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/rewriting_sub_query_reducer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/sql_query_plan_optimizer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/sub_query_reducer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/optimizer/table_alias_simplifier.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/big_query.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/databricks.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/duckdb_renderer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/expr_renderer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/postgres.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/redshift.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/rendering_constants.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/snowflake.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/sql_plan_renderer.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/render/trino.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_column.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_exprs.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_plan.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql/sql_table.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql_request/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/sql_request/sql_request_attributes.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/handlers/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/handlers/handlers.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/handlers/python_log.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/models.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/telemetry/reporter.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/validation/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/validation/data_warehouse_model_validator.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/validation/dataflow_join_validator.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/aggregation_properties.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/api/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/api/v0_1/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/api/v0_1/saved_query_dependency_resolver.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/assert_one_arg.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/collection_helpers/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/collection_helpers/dedupe.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/collection_helpers/merger.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/dag_to_text.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/dag_visualization.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/mf_dag.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/dag/sequential_id.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/errors/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/errors/error_classes.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/filters/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/filters/merge_where.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/filters/time_constraint.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/instances.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/formatting.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/mf_logging/runtime.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/dbt_manifest_parser.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/linkable_element_property.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/object_to_reference.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantic_manifest_lookup.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantic_model_derivation.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/element_group.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/metric_lookup.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/semantic_model_container.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/semantics/semantic_model_join_evaluator.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/spec_converters.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/transformations/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/model/transformations/dedupe_metric_input_measures.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/dunder_scheme.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/linkable_spec_name.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/metric_scheme.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/naming_scheme.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/object_builder_scheme.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/naming/object_builder_str.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/protocols/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/protocols/query_parameter.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/py.typed +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/candidate_push_down/__init__.py +0 -0
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/filter_spec_resolution/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/filter_spec_resolution/filter_location.py +0 -0
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/group_by_item_resolver.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/path_prefixable.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/dag.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/dag_builder.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/input_metric_location.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_dag/resolution_nodes/__init__.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/group_by_item/resolution_path.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/filter_spec_resolver/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/filter_spec_resolver/invalid_where.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/__init__.py +0 -0
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/multiple_join_paths.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/no_common_items.py +0 -0
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/group_by_item_resolver/no_parent_candidates.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/issues_base.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/cumulative_metric_requires_metric_time.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/duplicate_metric.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_limit.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_metric.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_min_max_only.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/invalid_order.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/no_metric_or_group_by.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/offset_metric_requires_metric_time.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/issues/parsing/string_input_parsing_issue.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_exceptions.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_parser.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_resolution.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/query_resolver.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/resolver_inputs/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/resolver_inputs/base_resolver_inputs.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/resolver_inputs/query_resolver_inputs.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/similarity.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/suggestion_generator.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/base_validation_rule.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/duplicate_metric.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/metric_time_requirements.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/query/validation_rules/query_validator.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/random_id.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/column_assoc.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/dimension_spec_resolver.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/dunder_column_association_resolver.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/linkable_spec_set.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/partition_spec_set.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/base_time_grain.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/entity_link_pattern.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/match_list_pattern.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/metric_pattern.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/metric_time_pattern.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/no_group_by_metric.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/none_date_part.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/spec_pattern.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/patterns/typed_patterns.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/python_object.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/query_param_implementations.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/query_spec.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/rendered_spec_tracker.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/spec_classes.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/spec_set.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/spec_set_transforms.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_dimension.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_entity.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_metric.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_time_dimension.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/specs/where_filter_transform.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/sql_bind_parameters.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/sql_column_type.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/sql/sql_join_type.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/config_helpers.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/example_project_configuration.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/id_helpers.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/manifest_helpers.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/metric_time_dimension.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/ambiguous_resolution_manifest/metrics.yaml +0 -0
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/config_linter_manifest/__init__.py +0 -0
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/cyclic_join_manifest/__init__.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/extended_date_manifest/__init__.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/join_types_manifest/__init__.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/non_sm_manifest/__init__.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/project_configuration.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_accounts.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_bookings.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_companies.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_listings.yaml +0 -0
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_metrics.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/scd_manifest/scd_users.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/shared/project_configuration.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/project_configuration.yaml +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/semantic_manifest_yamls/simple_manifest/saved_queries.yaml +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/snapshot_helpers.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/test_helpers/time_helpers.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/__init__.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/dateutil_adjuster.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/time_constants.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/time_period.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/time/time_source.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/visitor.py +0 -0
- {metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow_semantics/workarounds/__init__.py +0 -0
- {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.
|
|
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.
|
|
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<
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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.
|
{metricflow-0.207.0.dev1 → metricflow-0.207.0.dev2}/metricflow/dataflow/builder/node_data_set.py
RENAMED
|
@@ -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
|
|
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[
|
|
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)
|