Skip to content

Commit 867fd69

Browse files
author
Zoran Cvetkov
committed
query for both lower and upper range
1 parent 62290c6 commit 867fd69

File tree

3 files changed

+63
-42
lines changed

3 files changed

+63
-42
lines changed

store/postgres/src/block_range.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,27 +135,31 @@ impl<'a> QueryFragment<Pg> for BlockRangeUpperBoundClause<'a> {
135135
/// Helper for generating SQL fragments for selecting entities in a specific block range
136136
#[derive(Debug, Clone, Copy)]
137137
pub enum EntityBlockRange {
138-
Mutable(BlockRange), // TODO: check if this is a proper type here (maybe Range<BlockNumber>?)
138+
Mutable((BlockRange, bool)), // TODO: check if this is a proper type here (maybe Range<BlockNumber>?)
139139
Immutable(BlockRange),
140140
}
141141

142142
impl EntityBlockRange {
143-
pub fn new(immutable: bool, block_range: std::ops::Range<BlockNumber>) -> Self {
143+
pub fn new(
144+
immutable: bool,
145+
block_range: std::ops::Range<BlockNumber>,
146+
is_uppper_range: bool,
147+
) -> Self {
144148
let start: Bound<BlockNumber> = Bound::Included(block_range.start);
145149
let end: Bound<BlockNumber> = Bound::Excluded(block_range.end);
146150
let block_range: BlockRange = BlockRange(start, end);
147151
if immutable {
148152
Self::Immutable(block_range)
149153
} else {
150-
Self::Mutable(block_range)
154+
Self::Mutable((block_range, is_uppper_range))
151155
}
152156
}
153157

154158
/// Output SQL that matches only rows whose block range contains `block`.
155159
pub fn contains<'b>(&'b self, out: &mut AstPass<'_, 'b, Pg>) -> QueryResult<()> {
156160
out.unsafe_to_cache_prepared();
157161
let block_range = match self {
158-
EntityBlockRange::Mutable(br) => br,
162+
EntityBlockRange::Mutable((br, _)) => br,
159163
EntityBlockRange::Immutable(br) => br,
160164
};
161165
let BlockRange(start, finish) = block_range;
@@ -186,7 +190,13 @@ impl EntityBlockRange {
186190

187191
pub fn compare_column(&self, out: &mut AstPass<Pg>) {
188192
match self {
189-
EntityBlockRange::Mutable(_) => out.push_sql(" lower(block_range) "),
193+
EntityBlockRange::Mutable((_, is_upper_range)) => {
194+
if *is_upper_range {
195+
out.push_sql(" upper(block_range) ")
196+
} else {
197+
out.push_sql(" lower(block_range) ")
198+
}
199+
}
190200
EntityBlockRange::Immutable(_) => out.push_sql(" block$ "),
191201
}
192202
}

store/postgres/src/relational.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,10 +529,11 @@ impl Layout {
529529
et_map.insert(et.to_string(), Arc::new(et));
530530
}
531531
let mut entities: BTreeMap<BlockNumber, Vec<EntityWithType>> = BTreeMap::new();
532-
if let Some(vec) = FindRangeQuery::new(&tables, block_range)
532+
if let Some(vec) = FindRangeQuery::new(&tables, false, block_range)
533533
.get_results::<EntityData>(conn)
534534
.optional()?
535535
{
536+
// TODO: issue query with upper range and find modifictions and deletions
536537
for e in vec {
537538
let block = e.clone().deserialize_block_number::<Entity>()?;
538539
let entity_type = e.entity_type(&self.input_schema);

store/postgres/src/relational_queries.rs

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,16 +2009,22 @@ impl<'a, Conn> RunQueryDsl<Conn> for FindQuery<'a> {}
20092009
#[derive(Debug, Clone)]
20102010
pub struct FindRangeQuery<'a> {
20112011
tables: &'a Vec<&'a Table>,
2012+
is_upper_range: bool,
20122013
imm_range: EntityBlockRange,
20132014
mut_range: EntityBlockRange,
20142015
}
20152016

20162017
impl<'a> FindRangeQuery<'a> {
2017-
pub fn new(tables: &'a Vec<&Table>, block_range: Range<BlockNumber>) -> Self {
2018-
let imm_range = EntityBlockRange::new(true, block_range.clone());
2019-
let mut_range = EntityBlockRange::new(false, block_range);
2018+
pub fn new(
2019+
tables: &'a Vec<&Table>,
2020+
is_upper_range: bool,
2021+
block_range: Range<BlockNumber>,
2022+
) -> Self {
2023+
let imm_range = EntityBlockRange::new(true, block_range.clone(), false);
2024+
let mut_range = EntityBlockRange::new(false, block_range, is_upper_range);
20202025
Self {
20212026
tables,
2027+
is_upper_range,
20222028
imm_range,
20232029
mut_range,
20242030
}
@@ -2028,42 +2034,46 @@ impl<'a> FindRangeQuery<'a> {
20282034
impl<'a> QueryFragment<Pg> for FindRangeQuery<'a> {
20292035
fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> {
20302036
out.unsafe_to_cache_prepared();
2037+
let mut first = true;
20312038

2032-
let mut iter = self.tables.iter().peekable();
2033-
while let Some(table) = iter.next() {
2034-
// Generate
2035-
// select '..' as entity, to_jsonb(e.*) as data, block$ as block_number
2036-
// from schema.table e where id = $1
2037-
out.push_sql("select ");
2038-
out.push_bind_param::<Text, _>(table.object.as_str())?;
2039-
out.push_sql(" as entity, to_jsonb(e.*) as data,");
2040-
if table.immutable {
2041-
self.imm_range.compare_column(&mut out)
2042-
} else {
2043-
self.mut_range.compare_column(&mut out)
2044-
}
2045-
out.push_sql("as block_number\n");
2046-
out.push_sql(" from ");
2047-
out.push_sql(table.qualified_name.as_str());
2048-
out.push_sql(" e\n where");
2049-
// TODO: do we need to care about it?
2050-
// if self.table.has_causality_region {
2051-
// out.push_sql("causality_region = ");
2052-
// out.push_bind_param::<Integer, _>(&self.key.causality_region)?;
2053-
// out.push_sql(" and ");
2054-
// }
2055-
if table.immutable {
2056-
self.imm_range.contains(&mut out)?;
2057-
} else {
2058-
self.mut_range.contains(&mut out)?;
2059-
}
2060-
// more elements left?
2061-
if iter.peek().is_some() {
2062-
out.push_sql("\nunion all\n"); // with the next
2063-
} else {
2064-
out.push_sql("\norder by block_number"); // on the last
2039+
for table in self.tables.iter() {
2040+
// the immutable entities don't have upper range and also can't be modified or deleted
2041+
if !(self.is_upper_range && table.immutable) {
2042+
if first {
2043+
first = false;
2044+
} else {
2045+
out.push_sql("\nunion all\n");
2046+
}
2047+
2048+
// Generate
2049+
// select '..' as entity, to_jsonb(e.*) as data, block$ as block_number
2050+
// from schema.table e where id = $1
2051+
out.push_sql("select ");
2052+
out.push_bind_param::<Text, _>(table.object.as_str())?;
2053+
out.push_sql(" as entity, to_jsonb(e.*) as data,");
2054+
if table.immutable {
2055+
self.imm_range.compare_column(&mut out)
2056+
} else {
2057+
self.mut_range.compare_column(&mut out)
2058+
}
2059+
out.push_sql("as block_number, id\n");
2060+
out.push_sql(" from ");
2061+
out.push_sql(table.qualified_name.as_str());
2062+
out.push_sql(" e\n where");
2063+
// TODO: do we need to care about it?
2064+
// if self.table.has_causality_region {
2065+
// out.push_sql("causality_region = ");
2066+
// out.push_bind_param::<Integer, _>(&self.key.causality_region)?;
2067+
// out.push_sql(" and ");
2068+
// }
2069+
if table.immutable {
2070+
self.imm_range.contains(&mut out)?;
2071+
} else {
2072+
self.mut_range.contains(&mut out)?;
2073+
}
20652074
}
20662075
}
2076+
out.push_sql("\norder by block_number, entity, id");
20672077

20682078
Ok(())
20692079
}

0 commit comments

Comments
 (0)