diff --git a/graph/src/components/store/entity_cache.rs b/graph/src/components/store/entity_cache.rs index 24962b6d8b6..6ea8b988bb2 100644 --- a/graph/src/components/store/entity_cache.rs +++ b/graph/src/components/store/entity_cache.rs @@ -459,16 +459,16 @@ impl EntityCache { // Entity was created (None, EntityOp::Update(mut updates)) | (None, EntityOp::Overwrite(mut updates)) => { + let vid = updates.vid; updates.e.remove_null_fields(); - let data = Arc::new(updates); - self.current - .insert(key.clone(), Some(data.e.clone().into())); + let data = Arc::new(updates.e.clone()); + self.current.insert(key.clone(), Some(data.cheap_clone())); Some(Insert { key, - data: data.e.clone().into(), + data, block, end: None, - vid: data.vid, + vid, }) } // Entity may have been changed @@ -493,16 +493,16 @@ impl EntityCache { } // Entity was removed and then updated, so it will be overwritten (Some(current), EntityOp::Overwrite(data)) => { - let data = Arc::new(data); - self.current - .insert(key.clone(), Some(data.e.clone().into())); - if current != data.e.clone().into() { + let vid = data.vid; + let data = Arc::new(data.e.clone()); + self.current.insert(key.clone(), Some(data.cheap_clone())); + if current != data { Some(Overwrite { key, - data: data.e.clone().into(), + data, block, end: None, - vid: data.vid, + vid, }) } else { None diff --git a/graph/src/schema/input/mod.rs b/graph/src/schema/input/mod.rs index a71be5a500f..222b55bea3a 100644 --- a/graph/src/schema/input/mod.rs +++ b/graph/src/schema/input/mod.rs @@ -1489,9 +1489,9 @@ impl InputSchema { pub fn has_field_with_name(&self, entity_type: &EntityType, field: &str) -> bool { // TODO: check if it is needed - if field == VID { - return true; - } + // if field == VID { + // return true; + // } let field = self.inner.pool.lookup(field); match field { diff --git a/store/postgres/src/relational_queries.rs b/store/postgres/src/relational_queries.rs index 9dea6488396..c91e435818d 100644 --- a/store/postgres/src/relational_queries.rs +++ b/store/postgres/src/relational_queries.rs @@ -16,7 +16,7 @@ use graph::components::store::write::{EntityWrite, RowGroup, WriteChunk}; use graph::components::store::{Child as StoreChild, DerivedEntityQuery}; use graph::data::store::{EntityV, Id, IdType, NULL}; use graph::data::store::{IdList, IdRef, QueryObject}; -use graph::data::subgraph::schema::POI_TABLE; +// use graph::data::subgraph::schema::POI_TABLE; use graph::data::value::{Object, Word}; use graph::data_source::CausalityRegion; use graph::prelude::{ @@ -2241,7 +2241,8 @@ impl<'a> QueryFragment for InsertQuery<'a> { let out = &mut out; out.unsafe_to_cache_prepared(); - let not_poi = self.table.name.as_str() != POI_TABLE; + // let not_poi = self.table.name.as_str() != POI_TABLE; + let not_poi = !self.table.object.is_poi(); // Construct a query // insert into schema.table(column, ...) @@ -4691,7 +4692,8 @@ impl<'a> QueryFragment for CopyEntityBatchQuery<'a> { fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> { out.unsafe_to_cache_prepared(); - let not_poi = self.dst.name.as_str() != POI_TABLE; + // let not_poi = self.dst.name.as_str() != POI_TABLE; + let not_poi = !self.dst.object.is_poi(); // Construct a query // insert into {dst}({columns}) diff --git a/store/test-store/tests/graph/entity_cache.rs b/store/test-store/tests/graph/entity_cache.rs index 15321bca71f..610e4503fa3 100644 --- a/store/test-store/tests/graph/entity_cache.rs +++ b/store/test-store/tests/graph/entity_cache.rs @@ -469,7 +469,7 @@ async fn insert_test_data(store: Arc) -> DeploymentLocator fn create_account_entity(id: &str, name: &str, email: &str, age: i32, vid: i64) -> EntityOperation { let test_entity = - entity! { LOAD_RELATED_SUBGRAPH => id: id, name: name, email: email, age: age, vid: vid }; + entity! { LOAD_RELATED_SUBGRAPH => id: id, name: name, email: email, age: age }; EntityOperation::Set { key: ACCOUNT_TYPE.parse_key(id).unwrap(), @@ -479,8 +479,7 @@ fn create_account_entity(id: &str, name: &str, email: &str, age: i32, vid: i64) fn create_wallet_entity(id: &str, account_id: &Id, balance: i32, vid: i64) -> EntityV { let account_id = Value::from(account_id.clone()); - let e = - entity! { LOAD_RELATED_SUBGRAPH => id: id, account: account_id, balance: balance, vid: vid}; + let e = entity! { LOAD_RELATED_SUBGRAPH => id: id, account: account_id, balance: balance}; EntityV::new(e, vid) } fn create_wallet_operation(id: &str, account_id: &Id, balance: i32, vid: i64) -> EntityOperation { @@ -716,53 +715,49 @@ fn check_for_delete_async_related() { }); } -// #[test] -// fn scoped_get() { -// run_store_test(|mut cache, _store, _deployment, _writable| async move { -// // Key for an existing entity that is in the store -// let account1 = ACCOUNT_TYPE.parse_id("1").unwrap(); -// let key1 = WALLET_TYPE.parse_key("1").unwrap(); -// let wallet1 = create_wallet_entity("1", &account1, 67, 1); - -// // Create a new entity that is not in the store -// let account5 = ACCOUNT_TYPE.parse_id("5").unwrap(); -// let wallet5 = create_wallet_entity("5", &account5, 100, 5); -// let key5 = WALLET_TYPE.parse_key("5").unwrap(); -// cache -// .set(key5.clone(), EntityV::new(wallet5.clone(), 5)) -// .unwrap(); - -// // For the new entity, we can retrieve it with either scope -// let act5 = cache.get(&key5, GetScope::InBlock).unwrap(); -// assert_eq!(Some(&wallet5), act5.as_ref().map(|e| e.as_ref())); -// let act5 = cache.get(&key5, GetScope::Store).unwrap(); -// assert_eq!(Some(&wallet5), act5.as_ref().map(|e| e.as_ref())); - -// // For an entity in the store, we can not get it `InBlock` but with -// // `Store` -// let act1 = cache.get(&key1, GetScope::InBlock).unwrap(); -// assert_eq!(None, act1); -// let act1 = cache.get(&key1, GetScope::Store).unwrap(); -// assert_eq!( -// filter_vid(vec![wallet1.clone()]), -// vec![act1.as_ref().map(|e| e.as_ref()).unwrap().clone()] -// ); -// // Even after reading from the store, the entity is not visible with -// // `InBlock` -// let act1 = cache.get(&key1, GetScope::InBlock).unwrap(); -// assert_eq!(None, act1); -// // But if it gets updated, it becomes visible with either scope -// let mut wallet1 = wallet1; -// wallet1.set("balance", 70).unwrap(); -// cache -// .set(key1.clone(), EntityV::new(wallet1.clone(), 1)) -// .unwrap(); -// let act1 = cache.get(&key1, GetScope::InBlock).unwrap(); -// assert_eq!(Some(&wallet1), act1.as_ref().map(|e| e.as_ref())); -// let act1 = cache.get(&key1, GetScope::Store).unwrap(); -// assert_eq!(Some(&wallet1), act1.as_ref().map(|e| e.as_ref())); -// }) -// } +#[test] +fn scoped_get() { + run_store_test(|mut cache, _store, _deployment, _writable| async move { + // Key for an existing entity that is in the store + let account1 = ACCOUNT_TYPE.parse_id("1").unwrap(); + let key1 = WALLET_TYPE.parse_key("1").unwrap(); + let wallet1 = create_wallet_entity("1", &account1, 67, 1); + + // Create a new entity that is not in the store + let account5 = ACCOUNT_TYPE.parse_id("5").unwrap(); + let wallet5 = create_wallet_entity("5", &account5, 100, 5); + let key5 = WALLET_TYPE.parse_key("5").unwrap(); + cache.set(key5.clone(), wallet5.clone()).unwrap(); + + // For the new entity, we can retrieve it with either scope + let act5 = cache.get(&key5, GetScope::InBlock).unwrap(); + assert_eq!(Some(&wallet5.e), act5.as_ref().map(|e| e.as_ref())); + let act5 = cache.get(&key5, GetScope::Store).unwrap(); + assert_eq!(Some(&wallet5.e), act5.as_ref().map(|e| e.as_ref())); + + // For an entity in the store, we can not get it `InBlock` but with + // `Store` + let act1 = cache.get(&key1, GetScope::InBlock).unwrap(); + assert_eq!(None, act1); + let act1 = cache.get(&key1, GetScope::Store).unwrap(); + assert_eq!( + filter_vid(vec![wallet1.e.clone()]), + vec![act1.as_ref().map(|e| e.as_ref()).unwrap().clone()] + ); + // Even after reading from the store, the entity is not visible with + // `InBlock` + let act1 = cache.get(&key1, GetScope::InBlock).unwrap(); + assert_eq!(None, act1); + // But if it gets updated, it becomes visible with either scope + let mut wallet1 = wallet1; + wallet1.e.set("balance", 70).unwrap(); + cache.set(key1.clone(), wallet1.clone()).unwrap(); + let act1 = cache.get(&key1, GetScope::InBlock).unwrap(); + assert_eq!(Some(&wallet1.e), act1.as_ref().map(|e| e.as_ref())); + let act1 = cache.get(&key1, GetScope::Store).unwrap(); + assert_eq!(Some(&wallet1.e), act1.as_ref().map(|e| e.as_ref())); + }) +} /// Entities should never contain a `__typename` or `g$parent_id` field, if /// they do, that can cause PoI divergences, because entities will differ diff --git a/store/test-store/tests/postgres/graft.rs b/store/test-store/tests/postgres/graft.rs index 1e50ea15388..8498febd573 100644 --- a/store/test-store/tests/postgres/graft.rs +++ b/store/test-store/tests/postgres/graft.rs @@ -257,7 +257,7 @@ fn create_test_entity( seconds_age: age * 31557600, weight: Value::BigDecimal(weight.into()), coffee: coffee, - favorite_color: favorite_color, + favorite_color: favorite_color }; let entity_type = TEST_SUBGRAPH_SCHEMA.entity_type(entity_type).unwrap(); @@ -329,10 +329,9 @@ async fn check_graft( // Make our own entries for block 2 shaq.set("email", "shaq@gmail.com").unwrap(); - // shaq.set("vid", 5i64).unwrap(); let op = EntityOperation::Set { key: user_type.parse_key("3").unwrap(), - data: EntityV::new(shaq, 5), + data: EntityV::new(shaq, 3), }; transact_and_wait(&store, &deployment, BLOCKS[2].clone(), vec![op]) .await diff --git a/store/test-store/tests/postgres/store.rs b/store/test-store/tests/postgres/store.rs index a54a756b0c1..c4d2401f2e5 100644 --- a/store/test-store/tests/postgres/store.rs +++ b/store/test-store/tests/postgres/store.rs @@ -1522,7 +1522,7 @@ fn handle_large_string_with_index() { block: BlockNumber, vid: i64, ) -> EntityModification { - let data = entity! { schema => id: id, name: name, vid: vid }; + let data = entity! { schema => id: id, name: name }; let key = USER_TYPE.parse_key(id).unwrap(); @@ -1622,7 +1622,7 @@ fn handle_large_bytea_with_index() { block: BlockNumber, vid: i64, ) -> EntityModification { - let data = entity! { schema => id: id, bin_name: scalar::Bytes::from(name), vid: vid }; + let data = entity! { schema => id: id, bin_name: scalar::Bytes::from(name) }; let key = USER_TYPE.parse_key(id).unwrap(); @@ -2157,15 +2157,15 @@ fn reorg_tracking() { check_state!(store, 2, 2, 2); // Forward to block 3 - update_john(&subgraph_store, &deployment, 70, &TEST_BLOCK_3_PTR, 30).await; + update_john(&subgraph_store, &deployment, 70, &TEST_BLOCK_3_PTR, 5).await; check_state!(store, 2, 2, 3); // Forward to block 4 - update_john(&subgraph_store, &deployment, 71, &TEST_BLOCK_4_PTR, 40).await; + update_john(&subgraph_store, &deployment, 71, &TEST_BLOCK_4_PTR, 6).await; check_state!(store, 2, 2, 4); // Forward to block 5 - update_john(&subgraph_store, &deployment, 72, &TEST_BLOCK_5_PTR, 50).await; + update_john(&subgraph_store, &deployment, 72, &TEST_BLOCK_5_PTR, 7).await; check_state!(store, 2, 2, 5); // Revert all the way back to block 2