Skip to content

Conditions isn't moved to PREWHERE if a row policy presents #69777

@vitlibar

Description

@vitlibar

Example:

CREATE TABLE tbl1(a Int32, b Int32) ENGINE=MergeTree ORDER BY tuple();
INSERT INTO tbl1 VALUES (1, 2);

A simple query

EXPLAIN PLAN actions=1 SELECT * FROM tbl1 WHERE b=2;

moves the WHERE condition to PREWHERE:

    ┌─explain──────────────────────────────────────────────────────────────────────────────────────┐
 1. │ Expression ((Project names + Projection))                                                    │
 2. │ Actions: INPUT : 0 -> __table1.a Int32 : 0                                                   │
 3. │          INPUT : 1 -> __table1.b Int32 : 1                                                   │
 4. │          ALIAS __table1.a :: 0 -> a Int32 : 2                                                │
 5. │          ALIAS __table1.b :: 1 -> b Int32 : 0                                                │
 6. │ Positions: 2 0                                                                               │
 7. │   Expression                                                                                 │
 8. │   Actions: INPUT : 0 -> a Int32 : 0                                                          │
 9. │            INPUT : 1 -> b Int32 : 1                                                          │
10. │            ALIAS a :: 0 -> __table1.a Int32 : 2                                              │
11. │            ALIAS b :: 1 -> __table1.b Int32 : 0                                              │
12. │   Positions: 2 0                                                                             │
13. │     ReadFromMergeTree (default.tbl1)                                                         │
14. │     ReadType: Default                                                                        │
15. │     Parts: 1                                                                                 │
16. │     Granules: 1                                                                              │
17. │     Prewhere info                                                                            │
18. │     Need filter: 1                                                                           │
19. │       Prewhere filter                                                                        │
20. │       Prewhere filter column: equals(__table1.b, 2_UInt8) (removed)                          │
21. │       Actions: INPUT : 0 -> b Int32 : 0                                                      │
22. │                COLUMN Const(UInt8) -> 2_UInt8 UInt8 : 1                                      │
23. │                FUNCTION equals(b : 0, 2_UInt8 :: 1) -> equals(__table1.b, 2_UInt8) UInt8 : 2 │
24. │       Positions: 0 2                                                                         │
    └──────────────────────────────────────────────────────────────────────────────────────────────┘

However if there is another condition inside a row policy:

CREATE ROW POLICY pol1 ON tbl1 USING a=1 TO CURRENT_USER;
EXPLAIN PLAN actions=1 SELECT * FROM tbl1 WHERE b=2;

then it doesn't move the WHERE condition to PREWHERE:

    ┌─explain───────────────────────────────────────────────────────────────────────────────────┐
 1. │ Expression ((Project names + Projection))                                                 │
 2. │ Actions: INPUT : 0 -> __table1.a Int32 : 0                                                │
 3. │          INPUT : 1 -> __table1.b Int32 : 1                                                │
 4. │          ALIAS __table1.a :: 0 -> a Int32 : 2                                             │
 5. │          ALIAS __table1.b :: 1 -> b Int32 : 0                                             │
 6. │ Positions: 2 0                                                                            │
 7. │   Filter ((WHERE + Change column names to column identifiers))                            │
 8. │   Filter column: equals(__table1.b, 2_UInt8) (removed)                                    │
 9. │   Actions: INPUT : 0 -> a Int32 : 0                                                       │
10. │            INPUT : 1 -> b Int32 : 1                                                       │
11. │            COLUMN Const(UInt8) -> 2_UInt8 UInt8 : 2                                       │
12. │            ALIAS a :: 0 -> __table1.a Int32 : 3                                           │
13. │            ALIAS b : 1 -> __table1.b Int32 : 0                                            │
14. │            FUNCTION equals(b :: 1, 2_UInt8 :: 2) -> equals(__table1.b, 2_UInt8) UInt8 : 4 │
15. │   Positions: 4 3 0                                                                        │
16. │     ReadFromMergeTree (default.tbl1)                                                      │
17. │     ReadType: Default                                                                     │
18. │     Parts: 1                                                                              │
19. │     Granules: 1                                                                           │
20. │     Prewhere info                                                                         │
21. │     Need filter: 1                                                                        │
22. │       Prewhere filter                                                                     │
23. │       Prewhere filter column: equals(a, 1_UInt8) (removed)                                │
24. │       Actions: INPUT : 0 -> a Int32 : 0                                                   │
25. │                COLUMN Const(UInt8) -> 1_UInt8 UInt8 : 1                                   │
26. │                FUNCTION equals(a : 0, 1_UInt8 :: 1) -> equals(a, 1_UInt8) UInt8 : 2       │
27. │       Positions: 2 0                                                                      │
    └───────────────────────────────────────────────────────────────────────────────────────────┘

Since it moved to PREWHERE the condition from the row policy condition it looks like moving the row policy's condition to PREWHERE somehow prevents ClickHouse from moving the WHERE condition to PREWHERE.

Metadata

Metadata

Assignees

No one assigned

    Labels

    analyzerIssues and pull-requests related to new analyzerperformance

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions