Skip to content

Commit 9011b72

Browse files
committed
Compute query signature in the correct module
This moves the implementation of `signature()` on `QueryGraph` into the `QuerySignature` module, which is where it logically belongs.
1 parent 084889e commit 9011b72

File tree

6 files changed

+81
-72
lines changed

6 files changed

+81
-72
lines changed

src/sql/mir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use nom_sql::{Column, ColumnSpecification, ConditionBase, ConditionExpression, C
1111
Literal, Operator, SqlQuery, TableKey};
1212
use nom_sql::{LimitClause, OrderClause, SelectStatement};
1313
use sql::query_graph::{JoinRef, OutputColumn, QueryGraph, QueryGraphEdge};
14+
use sql::query_signature::Signature;
1415

1516
use slog;
1617
use std::collections::{HashMap, HashSet};

src/sql/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use self::mir::{MirNodeRef, SqlToMirConverter};
1515
use mir::query::MirQuery;
1616
use self::reuse::{ReuseConfig, ReuseConfigType};
1717
use sql::query_graph::{to_query_graph, QueryGraph};
18+
use sql::query_signature::Signature;
1819

1920
use slog;
2021
use std::collections::HashMap;

src/sql/query_graph.rs

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
use nom_sql::{Column, ConditionBase, ConditionExpression, ConditionTree, FieldExpression,
22
JoinConstraint, JoinOperator, JoinRightSide, Literal, Operator};
33
use nom_sql::SelectStatement;
4-
use nom_sql::ConditionExpression::*;
54

65
use std::cmp::Ordering;
7-
use std::collections::{HashMap, HashSet};
8-
use std::hash::{Hash, Hasher};
6+
use std::collections::HashMap;
97
use std::string::String;
108
use std::vec::Vec;
119

12-
use sql::query_signature::QuerySignature;
13-
1410
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1511
pub struct LiteralColumn {
1612
pub name: String,
@@ -152,73 +148,6 @@ impl QueryGraph {
152148
acc
153149
})
154150
}
155-
156-
/// Used to get a concise signature for a query graph. The `hash` member can be used to check
157-
/// for identical sets of relations and attributes covered (as per Finkelstein algorithm),
158-
/// while `relations` and `attributes` as `HashSet`s that allow for efficient subset checks.
159-
pub fn signature(&self) -> QuerySignature {
160-
use std::collections::hash_map::DefaultHasher;
161-
162-
let mut hasher = DefaultHasher::new();
163-
let rels = self.relations.keys().map(|r| String::as_str(r)).collect();
164-
165-
// Compute relations part of hash
166-
let mut r_vec: Vec<&str> = self.relations.keys().map(String::as_str).collect();
167-
r_vec.sort();
168-
for r in &r_vec {
169-
r.hash(&mut hasher);
170-
}
171-
172-
// Collect attributes from predicates and projected columns
173-
let mut attrs = HashSet::<&Column>::new();
174-
let mut attrs_vec = Vec::<&Column>::new();
175-
for n in self.relations.values() {
176-
for p in &n.predicates {
177-
match *p {
178-
ComparisonOp(ref ct) | LogicalOp(ref ct) => for c in &ct.contained_columns() {
179-
attrs_vec.push(c);
180-
attrs.insert(c);
181-
},
182-
_ => unreachable!(),
183-
}
184-
}
185-
}
186-
for e in self.edges.values() {
187-
match *e {
188-
QueryGraphEdge::Join(ref join_predicates) |
189-
QueryGraphEdge::LeftJoin(ref join_predicates) => for p in join_predicates {
190-
for c in &p.contained_columns() {
191-
attrs_vec.push(c);
192-
attrs.insert(c);
193-
}
194-
},
195-
QueryGraphEdge::GroupBy(ref cols) => for c in cols {
196-
attrs_vec.push(c);
197-
attrs.insert(c);
198-
},
199-
}
200-
}
201-
202-
// Compute attributes part of hash
203-
attrs_vec.sort();
204-
for a in &attrs_vec {
205-
a.hash(&mut hasher);
206-
}
207-
208-
let mut proj_columns: Vec<&OutputColumn> = self.columns.iter().collect();
209-
// Compute projected columns part of hash. We sort here since the order in which columns
210-
// appear does not matter for query graph equivalence.
211-
proj_columns.sort();
212-
for c in proj_columns {
213-
c.hash(&mut hasher);
214-
}
215-
216-
QuerySignature {
217-
relations: rels,
218-
attributes: attrs,
219-
hash: hasher.finish(),
220-
}
221-
}
222151
}
223152

224153
/// Splits top level conjunctions into multiple predicates

src/sql/query_signature.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
use nom_sql::Column;
2+
use nom_sql::ConditionExpression::*;
23

34
use std::collections::HashSet;
45
use std::hash::{Hash, Hasher};
56

7+
use sql::query_graph::{OutputColumn, QueryGraph, QueryGraphEdge};
8+
9+
pub trait Signature {
10+
fn signature(&self) -> QuerySignature;
11+
}
12+
613
#[derive(Clone, Debug)]
714
pub struct QuerySignature<'a> {
815
pub relations: HashSet<&'a str>,
@@ -66,6 +73,75 @@ impl<'a> QuerySignature<'a> {
6673
}
6774
}
6875

76+
impl Signature for QueryGraph {
77+
/// Used to get a concise signature for a query graph. The `hash` member can be used to check
78+
/// for identical sets of relations and attributes covered (as per Finkelstein algorithm),
79+
/// while `relations` and `attributes` as `HashSet`s that allow for efficient subset checks.
80+
fn signature(&self) -> QuerySignature {
81+
use std::collections::hash_map::DefaultHasher;
82+
83+
let mut hasher = DefaultHasher::new();
84+
let rels = self.relations.keys().map(|r| String::as_str(r)).collect();
85+
86+
// Compute relations part of hash
87+
let mut r_vec: Vec<&str> = self.relations.keys().map(String::as_str).collect();
88+
r_vec.sort();
89+
for r in &r_vec {
90+
r.hash(&mut hasher);
91+
}
92+
93+
// Collect attributes from predicates and projected columns
94+
let mut attrs = HashSet::<&Column>::new();
95+
let mut attrs_vec = Vec::<&Column>::new();
96+
for n in self.relations.values() {
97+
for p in &n.predicates {
98+
match *p {
99+
ComparisonOp(ref ct) | LogicalOp(ref ct) => for c in &ct.contained_columns() {
100+
attrs_vec.push(c);
101+
attrs.insert(c);
102+
},
103+
_ => unreachable!(),
104+
}
105+
}
106+
}
107+
for e in self.edges.values() {
108+
match *e {
109+
QueryGraphEdge::Join(ref join_predicates) |
110+
QueryGraphEdge::LeftJoin(ref join_predicates) => for p in join_predicates {
111+
for c in &p.contained_columns() {
112+
attrs_vec.push(c);
113+
attrs.insert(c);
114+
}
115+
},
116+
QueryGraphEdge::GroupBy(ref cols) => for c in cols {
117+
attrs_vec.push(c);
118+
attrs.insert(c);
119+
},
120+
}
121+
}
122+
123+
// Compute attributes part of hash
124+
attrs_vec.sort();
125+
for a in &attrs_vec {
126+
a.hash(&mut hasher);
127+
}
128+
129+
let mut proj_columns: Vec<&OutputColumn> = self.columns.iter().collect();
130+
// Compute projected columns part of hash. We sort here since the order in which columns
131+
// appear does not matter for query graph equivalence.
132+
proj_columns.sort();
133+
for c in proj_columns {
134+
c.hash(&mut hasher);
135+
}
136+
137+
QuerySignature {
138+
relations: rels,
139+
attributes: attrs,
140+
hash: hasher.finish(),
141+
}
142+
}
143+
}
144+
69145
#[cfg(test)]
70146
mod tests {
71147
use super::*;

src/sql/reuse/finkelstein.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use sql::reuse::helpers::predicate_implication::complex_predicate_implies;
22
use sql::reuse::{ReuseConfiguration, ReuseType};
33
use sql::query_graph::{QueryGraph, QueryGraphEdge};
4+
use sql::query_signature::Signature;
45
use mir::query::MirQuery;
56

67
use std::vec::Vec;

src/sql/reuse/relaxed.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use sql::reuse::helpers::predicate_implication::complex_predicate_implies;
22
use sql::reuse::{ReuseConfiguration, ReuseType};
33
use sql::query_graph::{QueryGraph, QueryGraphEdge};
4+
use sql::query_signature::Signature;
45
use mir::query::MirQuery;
56

67
use std::vec::Vec;

0 commit comments

Comments
 (0)