Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table scan not getting eliminated for a predicate non-satisfiable due to a CAST domain #16515

Closed
findepi opened this issue Mar 13, 2023 · 6 comments · Fixed by #17013
Closed
Assignees
Labels
bug Something isn't working performance

Comments

@findepi
Copy link
Member

findepi commented Mar 13, 2023

USE memory.default;
DROP TABLE IF EXISTS t;
CREATE TABLE t(a_char_5 char(5));
INSERT INTO t VALUES 'abcde', '11   ', NULL;

SELECT * FROM t WHERE CAST(a_char_5 AS varchar(1)) = '11';
EXPLAIN SELECT * FROM t WHERE CAST(a_char_5 AS varchar(1)) = '11';

In 408 and 409 the table scan was getting eliminated

 a_char_5
----------
(0 rows)

Query 20230313_083847_00012_7epwa, FINISHED, 1 node
http://localhost:8080/ui/query.html?20230313_083847_00012_7epwa
Splits: 1 total, 1 done (100.00%)
CPU Time: 0.0s total,     0 rows/s,     0B/s, 0% active
Per Node: 0.0 parallelism,     0 rows/s,     0B/s
Parallelism: 0.0
Peak Memory: 0B
0.04 [0 rows, 0B] [0 rows/s, 0B/s]

                              Query Plan
-----------------------------------------------------------------------
 Trino version: 408
 Fragment 0 [SINGLE]
     Output layout: [a_char]
     Output partitioning: SINGLE []
     Output[columnNames = [a_char_5]]
     │   Layout: [a_char:char(5)]
     │   Estimates: {rows: 0 (0B), cpu: 0, memory: 0B, network: 0B}
     │   a_char_5 := a_char
     └─ Values[]
            Layout: [a_char:char(5)]
            Estimates: {rows: 0 (0B), cpu: 0, memory: 0B, network: 0B}

410 produces correct result, but table scan is not removed from the plan

 a_char_5
----------
(0 rows)

Query 20230313_084012_00005_jin96, FINISHED, 1 node
http://localhost:8080/ui/query.html?20230313_084012_00005_jin96
Splits: 4 total, 4 done (100.00%)
CPU Time: 0.0s total,   272 rows/s, 1.95KB/s, 8% active
Per Node: 0.0 parallelism,     6 rows/s,    44B/s
Parallelism: 0.0
Peak Memory: 256B
0.50 [3 rows, 22B] [6 rows/s, 44B/s]

                                                         Query Plan
----------------------------------------------------------------------------------------------------------------------------
 Trino version: 410
 Fragment 0 [SOURCE]
     Output layout: [a_char]
     Output partitioning: SINGLE []
     Output[columnNames = [a_char_5]]
     │   Layout: [a_char:char(5)]
     │   Estimates: {rows: ? (?), cpu: 0, memory: 0B, network: 0B}
     │   a_char_5 := a_char
     └─ ScanFilter[table = memory:0, filterPredicate = ((CAST("a_char" AS varchar(1)) IS NULL) AND CAST(null AS boolean))]
            Layout: [a_char:char(5)]
            Estimates: {rows: 3 (165B), cpu: 165, memory: 0B, network: 0B}/{rows: ? (?), cpu: 165, memory: 0B, network: 0B}
            a_char := 0
@findepi findepi added bug Something isn't working performance labels Mar 13, 2023
@findepi findepi changed the title Table scan not getting eliminated Table scan not getting eliminated for a predicate non-satisfiable due to a CAST domain Mar 13, 2023
@assaf2 assaf2 self-assigned this Mar 13, 2023
@assaf2
Copy link
Member

assaf2 commented Mar 23, 2023

It's caused by #16444, I will add this case to #16206

@findepi
Copy link
Member Author

findepi commented Mar 23, 2023

It's caused by #16444,

before that change, what was the optimizer / rule which was eliminating the table scan?

@assaf2
Copy link
Member

assaf2 commented Mar 23, 2023

PushPredicateIntoTableScan eliminated the table scan at the exact if clause I'm expanding at #16206:

if (newDomain.isNone()) {
// TODO: DomainTranslator.fromPredicate can infer that the expression is "false" in some cases (TupleDomain.none()).
// This should move to another rule that simplifies the filter using that logic and then rely on RemoveTrivialFilters
// to turn the subtree into a Values node
return Optional.of(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
}

(I will also add a dedicated rule as you requested)

@findepi
Copy link
Member Author

findepi commented Mar 24, 2023

PushPredicateIntoTableScan eliminated the table scan at the exact if clause

Do you understand why, before #16444, the DomainTranslator would produce newDomain.isNone(), but not so after that PR?

@assaf2
Copy link
Member

assaf2 commented Mar 26, 2023

@findepi because DomainTranslator translates NullLiteral but not Cast (of null)

@Override
protected ExtractionResult visitNullLiteral(NullLiteral node, Boolean complement)
{
return new ExtractionResult(TupleDomain.none(), TRUE_LITERAL);
}

I've added such a translation instead of expanding the if clause I mentioned earlier.
My PR is now ready, please take a look- #16206

@findepi
Copy link
Member Author

findepi commented Mar 28, 2023

thanks @assaf2 for getting to the bottom of the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working performance
Development

Successfully merging a pull request may close this issue.

2 participants