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

optimizer: filter scan rule #834

Open
crwen opened this issue Feb 28, 2024 · 2 comments
Open

optimizer: filter scan rule #834

crwen opened this issue Feb 28, 2024 · 2 comments

Comments

@crwen
Copy link

crwen commented Feb 28, 2024

pub fn filter_scan_rule() -> Vec<Rewrite> { vec![
// pushdown range condition to scan
rw!("filter-scan";
"(filter ?cond (scan ?table ?columns true))" =>
"(scan ?table ?columns ?cond)"
if is_primary_key_range("?cond")
),
rw!("filter-scan-1";
"(filter (and ?cond1 ?cond2) (scan ?table ?columns true))" =>
"(filter ?cond2 (scan ?table ?columns ?cond1))"
if is_primary_key_range("?cond1")
),
]}

Here's my understanding: When there are predicates on primary key, we should push them down to the storage layer. Is that right?

But it seems not to work when I execute statements like select pk from t where pk > 1. And the filter passed to scan function is always None. It looks like these:

> explain select a from t2 where a > 17;
Filter { cond: > { lhs: a, rhs: 17 }, cost: 68.4, rows: 20 }
└── Scan { table: t2, list: [ a ], filter: null, cost: 40, rows: 40 }

Maybe the true in "(scan ?table ?columns true)" should be replaced to null? Because it seems to work if I change it.

> explain select a from t2 where a > 17;
Scan { table: t2, list: [ a ], filter: > { lhs: a, rhs: 17 }, cost: 40, rows: 40 }
@skyzh
Copy link
Member

skyzh commented Feb 28, 2024

maybe related: #795? But it's a known issue and if you want to fix that, please submit a pull request, thanks!

@crwen
Copy link
Author

crwen commented Feb 29, 2024

It seems like that the filter is true by default, instead of null. So the solution may be like this in #795?

fn bind_table_factor(&mut self, table: TableFactor) -> Result {
match table {
TableFactor::Table { name, alias, .. } => {
let (table_id, is_internal) = self.bind_table_id(&name)?;
let cols = self.bind_table_def(&name, alias, false)?;
let id = if is_internal {
self.egraph.add(Node::Internal([table_id, cols]))
} else {
let true_ = self.egraph.add(Node::true_());
self.egraph.add(Node::Scan([table_id, cols, true_]))
};

github-merge-queue bot pushed a commit that referenced this issue Apr 12, 2024
related to #794 #834 , add some new rules and change scan's default
filter to true(this make it match with the "filter-scan" rule)

Signed-off-by: kysshsy <kysshsy@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants