Skip to content
Snippets Groups Projects
Unverified Commit fab1e660 authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Fix filters not working for columns in multi-stage queries (#25259)

parent b004665c
No related branches found
No related tags found
No related merge requests found
......@@ -29,6 +29,7 @@ import { getFieldValues, getRemappings } from "metabase/lib/query/field";
import { DATETIME_UNITS, formatBucketing } from "metabase/lib/query_time";
import { getQuestionIdFromVirtualTableId } from "metabase/lib/saved-questions";
import Aggregation from "metabase-lib/lib/queries/structured/Aggregation";
import Filter from "metabase-lib/lib/queries/structured/Filter";
import StructuredQuery from "metabase-lib/lib/queries/StructuredQuery";
import NativeQuery from "metabase-lib/lib/queries/NativeQuery";
import { infer, MONOTYPE } from "metabase/lib/expressions/typeinferencer";
......@@ -328,6 +329,12 @@ export default class Dimension {
return this.field().isDate() ? null : this.filterOperators()[0];
}
defaultFilterForDimension() {
return new Filter([], null, this.query()).setDimension(this.mbql(), {
useDefaultOperator: true,
});
}
// AGGREGATIONS
/**
......
......@@ -1453,20 +1453,8 @@ class StructuredQueryInner extends AtomicQuery {
}
// TODO: better name may be parseDimension?
parseFieldReference(fieldRef): Dimension | null | undefined {
return Dimension.parseMBQL(fieldRef, this._metadata, this);
}
dimensionForColumn(column) {
if (column) {
const fieldRef = this.fieldReferenceForColumn(column);
if (fieldRef) {
return this.parseFieldReference(fieldRef);
}
}
return null;
parseFieldReference(fieldRef, query = this): Dimension | null | undefined {
return Dimension.parseMBQL(fieldRef, this._metadata, query);
}
setDatasetQuery(datasetQuery: DatasetQuery): StructuredQuery {
......@@ -1548,11 +1536,27 @@ class StructuredQueryInner extends AtomicQuery {
return null;
}
dimensionForColumn(column: Column) {
if (column) {
const fieldRef = this.fieldReferenceForColumn(column);
if (fieldRef) {
const dimension = this.queries()
.flatMap(q => q.dimensions())
.find(d => d.isEqual(fieldRef));
return this.parseFieldReference(fieldRef, dimension?.query());
}
}
return null;
}
/**
* Returns the corresponding {Column} in the "top-level" {StructuredQuery}
*/
topLevelColumn(column: Column): Column | null | undefined {
const dimension = this.dimensionForColumn(column);
const dimension = this.topLevelDimensionForColumn(column);
if (dimension) {
const topDimension = this.topLevelDimension(dimension);
......@@ -1565,6 +1569,16 @@ class StructuredQueryInner extends AtomicQuery {
return null;
}
topLevelDimensionForColumn(column) {
if (column) {
const fieldRef = this.fieldReferenceForColumn(column);
if (fieldRef) {
return this.parseFieldReference(fieldRef);
}
}
}
/**
* returns the corresponding {Dimension} in the sourceQuery, if any
*/
......
......@@ -3,7 +3,6 @@ import React from "react";
import { t } from "ttag";
import { TYPE, isa } from "metabase/lib/types";
import Filter from "metabase-lib/lib/queries/structured/Filter";
import FilterPopover from "metabase/query_builder/components/filters/FilterPopover";
const INVALID_TYPES = [TYPE.Structured];
......@@ -23,10 +22,7 @@ export default function ColumnFilterDrill({ question, clicked }) {
}
const { dimension } = clicked;
const fieldRef = dimension.mbql();
const initialFilter = new Filter([], null, query).setDimension(fieldRef, {
useDefaultOperator: true,
});
const initialFilter = dimension.defaultFilterForDimension();
return [
{
......
import Dimension from "metabase-lib/lib/Dimension";
import { isNumber, isCoordinate } from "metabase/lib/schema_metadata";
export function getTableClickedObjectRowData(
......@@ -92,11 +91,7 @@ export function getTableHeaderClickedObject(
} else {
return {
column,
dimension: Dimension.parseMBQL(
column?.field_ref,
query?.metadata(),
query,
),
dimension: query?.dimensionForColumn(column),
};
}
}
......
import { popover, restore, visitQuestionAdhoc } from "__support__/e2e/helpers";
import { SAMPLE_DB_ID } from "__support__/e2e/cypress_data";
import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database";
const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE;
const questionDetails = {
display: "table",
dataset_query: {
database: SAMPLE_DB_ID,
type: "query",
query: {
"source-query": {
"source-table": PRODUCTS_ID,
aggregation: [["count"]],
breakout: [
["field", PRODUCTS.CREATED_AT, { "temporal-unit": "month" }],
["field", PRODUCTS.CATEGORY, null],
],
},
aggregation: [["count"]],
breakout: [["field", "CATEGORY", { "base-type": "type/Text" }]],
},
},
visualization_settings: {
"table.pivot_column": "CATEGORY",
"table.cell_column": "count",
},
};
describe("issue 25016", () => {
beforeEach(() => {
restore();
cy.signInAsAdmin();
cy.intercept("POST", "/api/dataset").as("dataset");
});
it("should be possible to filter by a column in a multi-stage query (metabase#25016)", () => {
visitQuestionAdhoc(questionDetails);
cy.findByText("Category").click();
popover().within(() => {
cy.findByText("Filter by this column").click();
cy.findByText("Gadget").click();
cy.button("Add filter").click();
});
cy.wait("@dataset");
cy.findByText("Showing 1 row").should("be.visible");
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment