Skip to content

Commit

Permalink
Merge pull request #182 from Qrlew/175-enable-public-tables
Browse files Browse the repository at this point in the history
175 enable public tables
  • Loading branch information
ngrislain authored Nov 13, 2023
2 parents 4ff6b1b + c167dce commit b578b00
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 90 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["Nicolas Grislain <ng@sarus.tech>"]
name = "qrlew"
version = "0.4.11"
version = "0.4.12"
edition = "2021"
description = "Sarus Qrlew Engine"
documentation = "https://docs.rs/qrlew"
Expand All @@ -27,7 +27,7 @@ chrono = { version = "0.4", features = ["serde"] }
sqlparser = "0.39.0"
dot = "0.1"
base64 = "0.21"
rusqlite = { version = "0.29", features = ["chrono"], optional = true }
rusqlite = { version = "0.30", features = ["chrono"], optional = true }
postgres = { version = "0.19", features = ["with-chrono-0_4"] }
r2d2 = "0.8"
r2d2_postgres = "0.18"
Expand Down
50 changes: 25 additions & 25 deletions src/protection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,31 +581,31 @@ mod tests {
// assert!(relation.schema()[0].name() != "peid");
}

// #[test]
// fn test_table_protection_from_field_paths() {
// let database = postgresql::test_database();
// let relations = database.relations();
// let table = relations
// .get(&["item_table".into()])
// .unwrap()
// .as_ref()
// .clone();
// let protection = Protection::from((
// &relations,
// vec![(
// "item_table",
// vec![("order_id", "order_table", "id")],
// "date",
// )],
// Strategy::Soft,
// ));
// // Table
// let table = protection.table(table.try_into().unwrap()).unwrap();
// table.display_dot().unwrap();
// println!("Schema protected = {}", table.schema());
// println!("Query protected = {}", ast::Query::from(&*table));
// assert_eq!(table.schema()[0].name(), ProtectedEntity::protected_entity_id())
// }
#[test]
fn test_table_protection_from_field_paths() {
let database = postgresql::test_database();
let relations = database.relations();
let table = relations
.get(&["item_table".into()])
.unwrap()
.as_ref()
.clone();
let protection = Protection::from((
&relations,
vec![(
"item_table",
vec![("order_id", "order_table", "id")],
"date",
)],
Strategy::Soft,
));
// Table
let table = protection.table(&table.try_into().unwrap()).unwrap();
table.display_dot().unwrap();
println!("Schema protected = {}", table.schema());
println!("Query protected = {}", ast::Query::from(&*table));
assert_eq!(table.schema()[0].name(), ProtectedEntity::protected_entity_id())
}

#[test]
fn test_join_protection() {
Expand Down
26 changes: 14 additions & 12 deletions src/rewriting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use crate::{
};

use rewriting_rule::{
BaseRewriter, BaseRewritingRulesEliminator, BaseRewritingRulesSelector,
BaseRewritingRulesSetter, BaseScore,
Rewriter, RewritingRulesEliminator, RewritingRulesSelector,
RewritingRulesSetter, Score,
};

#[derive(Debug)]
Expand Down Expand Up @@ -73,20 +73,21 @@ impl Relation {
protected_entity: ProtectedEntity,
budget: Budget,
) -> Result<RelationWithPrivateQuery> {
let relation_with_rules = self.set_rewriting_rules(BaseRewritingRulesSetter::new(
let relation_with_rules = self.set_rewriting_rules(RewritingRulesSetter::new(
relations,
synthetic_data,
protected_entity,
budget,
));
let relation_with_rules =
relation_with_rules.map_rewriting_rules(BaseRewritingRulesEliminator);
relation_with_rules.map_rewriting_rules(RewritingRulesEliminator);
relation_with_rules
.select_rewriting_rules(BaseRewritingRulesSelector)
.select_rewriting_rules(RewritingRulesSelector)
.into_iter()
.filter_map(|rwrr| match rwrr.attributes().output() {
Property::Public | Property::ProtectedEntityPreserving => Some((
rwrr.rewrite(BaseRewriter::new(relations)),
rwrr.accept(BaseScore),
rwrr.rewrite(Rewriter::new(relations)),
rwrr.accept(Score),
)),
property => None,
})
Expand All @@ -102,20 +103,21 @@ impl Relation {
protected_entity: ProtectedEntity,
budget: Budget,
) -> Result<RelationWithPrivateQuery> {
let relation_with_rules = self.set_rewriting_rules(BaseRewritingRulesSetter::new(
let relation_with_rules = self.set_rewriting_rules(RewritingRulesSetter::new(
relations,
synthetic_data,
protected_entity,
budget,
));
let relation_with_rules =
relation_with_rules.map_rewriting_rules(BaseRewritingRulesEliminator);
relation_with_rules.map_rewriting_rules(RewritingRulesEliminator);
relation_with_rules
.select_rewriting_rules(BaseRewritingRulesSelector)
.select_rewriting_rules(RewritingRulesSelector)
.into_iter()
.filter_map(|rwrr| match rwrr.attributes().output() {
Property::Public | Property::Published | Property::DifferentiallyPrivate => Some((
rwrr.rewrite(BaseRewriter::new(relations)),
rwrr.accept(BaseScore),
rwrr.rewrite(Rewriter::new(relations)),
rwrr.accept(Score),
)),
property => None,
})
Expand Down
114 changes: 63 additions & 51 deletions src/rewriting/rewriting_rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,42 +575,52 @@ impl<'a> RelationWithRewritingRule<'a> {
// # Implement various rewriting rules visitors

/// A basic rewriting rule setter
pub struct BaseRewritingRulesSetter {
pub struct RewritingRulesSetter<'a> {
relations: &'a Hierarchy<Arc<Relation>>,
synthetic_data: SyntheticData,
protected_entity: ProtectedEntity,
budget: Budget,
}
// TODO implement this properly

impl BaseRewritingRulesSetter {
impl<'a> RewritingRulesSetter<'a> {
pub fn new(
relations: &'a Hierarchy<Arc<Relation>>,
synthetic_data: SyntheticData,
protected_entity: ProtectedEntity,
budget: Budget,
) -> BaseRewritingRulesSetter {
BaseRewritingRulesSetter {
) -> RewritingRulesSetter {
RewritingRulesSetter {
relations,
synthetic_data,
protected_entity,
budget,
}
}
}

impl<'a> SetRewritingRulesVisitor<'a> for BaseRewritingRulesSetter {
impl<'a> SetRewritingRulesVisitor<'a> for RewritingRulesSetter<'a> {
fn table(&self, table: &'a Table) -> Vec<RewritingRule> {
vec![
RewritingRule::new(vec![], Property::Private, Parameters::None),
RewritingRule::new(
vec![],
Property::SyntheticData,
Parameters::SyntheticData(self.synthetic_data.clone()),
),
RewritingRule::new(
vec![],
Property::ProtectedEntityPreserving,
Parameters::ProtectedEntity(self.protected_entity.clone()),
),
]
if self.protected_entity.iter()
.find(|(name, _field_path)| table.name() == self.relations[name.as_str()].name())
.is_some() {
vec![
RewritingRule::new(vec![], Property::Private, Parameters::None),
RewritingRule::new(
vec![],
Property::SyntheticData,
Parameters::SyntheticData(self.synthetic_data.clone()),
),
RewritingRule::new(
vec![],
Property::ProtectedEntityPreserving,
Parameters::ProtectedEntity(self.protected_entity.clone()),
),
]
} else {
vec![
RewritingRule::new(vec![], Property::Public, Parameters::None),
]
}
}

fn map(&self, map: &'a Map, input: Arc<RelationWithRewritingRules<'a>>) -> Vec<RewritingRule> {
Expand Down Expand Up @@ -651,7 +661,6 @@ impl<'a> SetRewritingRulesVisitor<'a> for BaseRewritingRulesSetter {
Property::Published,
Parameters::None,
),
RewritingRule::new(vec![Property::Public], Property::Public, Parameters::None),
RewritingRule::new(
vec![Property::ProtectedEntityPreserving],
Property::DifferentiallyPrivate,
Expand Down Expand Up @@ -775,9 +784,9 @@ impl<'a> SetRewritingRulesVisitor<'a> for BaseRewritingRulesSetter {
}

/// A basic rewriting rule eliminator
pub struct BaseRewritingRulesEliminator; // TODO implement this properly
pub struct RewritingRulesEliminator;

impl<'a> MapRewritingRulesVisitor<'a> for BaseRewritingRulesEliminator {
impl<'a> MapRewritingRulesVisitor<'a> for RewritingRulesEliminator {
fn table(&self, table: &'a Table, rewriting_rules: &'a [RewritingRule]) -> Vec<RewritingRule> {
rewriting_rules.into_iter().cloned().collect()
}
Expand Down Expand Up @@ -882,9 +891,9 @@ impl<'a> MapRewritingRulesVisitor<'a> for BaseRewritingRulesEliminator {
}

/// A basic rewriting rule selector
pub struct BaseRewritingRulesSelector; // TODO implement this properly
pub struct RewritingRulesSelector;

impl<'a> SelectRewritingRuleVisitor<'a> for BaseRewritingRulesSelector {
impl<'a> SelectRewritingRuleVisitor<'a> for RewritingRulesSelector {
fn table(&self, table: &'a Table, rewriting_rules: &'a [RewritingRule]) -> Vec<RewritingRule> {
rewriting_rules.into_iter().cloned().collect()
}
Expand Down Expand Up @@ -959,9 +968,9 @@ impl<'a> SelectRewritingRuleVisitor<'a> for BaseRewritingRulesSelector {
}

/// Compute the number of DP ops
pub struct BaseBudgetDispatcher;
pub struct BudgetDispatcher;

impl<'a> Visitor<'a, RelationWithRewritingRule<'a>, usize> for BaseBudgetDispatcher {
impl<'a> Visitor<'a, RelationWithRewritingRule<'a>, usize> for BudgetDispatcher {
fn visit(
&self,
acceptor: &'a RelationWithRewritingRule<'a>,
Expand All @@ -978,9 +987,9 @@ impl<'a> Visitor<'a, RelationWithRewritingRule<'a>, usize> for BaseBudgetDispatc
}

/// Compute the score
pub struct BaseScore;
pub struct Score;

impl<'a> Visitor<'a, RelationWithRewritingRule<'a>, f64> for BaseScore {
impl<'a> Visitor<'a, RelationWithRewritingRule<'a>, f64> for Score {
fn visit(
&self,
acceptor: &'a RelationWithRewritingRule<'a>,
Expand All @@ -1000,15 +1009,15 @@ impl<'a> Visitor<'a, RelationWithRewritingRule<'a>, f64> for BaseScore {
}
}

pub struct BaseRewriter<'a>(&'a Hierarchy<Arc<Relation>>); // TODO implement this properly
pub struct Rewriter<'a>(&'a Hierarchy<Arc<Relation>>); // TODO implement this properly

impl<'a> BaseRewriter<'a> {
pub fn new(relations: &'a Hierarchy<Arc<Relation>>) -> BaseRewriter<'a> {
BaseRewriter(relations)
impl<'a> Rewriter<'a> {
pub fn new(relations: &'a Hierarchy<Arc<Relation>>) -> Rewriter<'a> {
Rewriter(relations)
}
}

impl<'a> RewriteVisitor<'a> for BaseRewriter<'a> {
impl<'a> RewriteVisitor<'a> for Rewriter<'a> {
fn table(
&self,
table: &'a Table,
Expand Down Expand Up @@ -1282,21 +1291,22 @@ mod tests {
let relation = Relation::try_from(query.with(&relations)).unwrap();
relation.display_dot().unwrap();
// Add rewritting rules
let relation_with_rules = relation.set_rewriting_rules(BaseRewritingRulesSetter::new(
let relation_with_rules = relation.set_rewriting_rules(RewritingRulesSetter::new(
&relations,
synthetic_data,
protected_entity,
budget,
));
relation_with_rules.display_dot().unwrap();
let relation_with_rules =
relation_with_rules.map_rewriting_rules(BaseRewritingRulesEliminator);
relation_with_rules.map_rewriting_rules(RewritingRulesEliminator);
relation_with_rules.display_dot().unwrap();
for rwrr in relation_with_rules.select_rewriting_rules(BaseRewritingRulesSelector) {
for rwrr in relation_with_rules.select_rewriting_rules(RewritingRulesSelector) {
rwrr.display_dot().unwrap();
let num_dp = rwrr.accept(BaseBudgetDispatcher);
let num_dp = rwrr.accept(BudgetDispatcher);
println!("DEBUG SPLIT BUDGET IN {}", num_dp);
println!("DEBUG SCORE {}", rwrr.accept(BaseScore));
let relation_with_private_query = rwrr.rewrite(BaseRewriter(&relations));
println!("DEBUG SCORE {}", rwrr.accept(Score));
let relation_with_private_query = rwrr.rewrite(Rewriter(&relations));
println!(
"PrivateQuery: {:?}",
relation_with_private_query.private_query()
Expand Down Expand Up @@ -1344,21 +1354,22 @@ mod tests {
let relation = Relation::try_from(query.with(&relations)).unwrap();
relation.display_dot().unwrap();
// Add rewritting rules
let relation_with_rules = relation.set_rewriting_rules(BaseRewritingRulesSetter::new(
let relation_with_rules = relation.set_rewriting_rules(RewritingRulesSetter::new(
&relations,
synthetic_data,
protected_entity,
budget,
));
relation_with_rules.display_dot().unwrap();
let relation_with_rules =
relation_with_rules.map_rewriting_rules(BaseRewritingRulesEliminator);
relation_with_rules.map_rewriting_rules(RewritingRulesEliminator);
relation_with_rules.display_dot().unwrap();
for rwrr in relation_with_rules.select_rewriting_rules(BaseRewritingRulesSelector) {
for rwrr in relation_with_rules.select_rewriting_rules(RewritingRulesSelector) {
rwrr.display_dot().unwrap();
let num_dp = rwrr.accept(BaseBudgetDispatcher);
let num_dp = rwrr.accept(BudgetDispatcher);
println!("DEBUG SPLIT BUDGET IN {}", num_dp);
println!("DEBUG SCORE {}", rwrr.accept(BaseScore));
let relation_with_private_query = rwrr.rewrite(BaseRewriter(&relations));
println!("DEBUG SCORE {}", rwrr.accept(Score));
let relation_with_private_query = rwrr.rewrite(Rewriter(&relations));
println!(
"PrivateQuery: {:?}",
relation_with_private_query.private_query()
Expand Down Expand Up @@ -1403,21 +1414,22 @@ mod tests {
let relation = Relation::try_from(query.with(&relations)).unwrap();
relation.display_dot().unwrap();
// Add rewritting rules
let relation_with_rules = relation.set_rewriting_rules(BaseRewritingRulesSetter::new(
let relation_with_rules = relation.set_rewriting_rules(RewritingRulesSetter::new(
&relations,
synthetic_data,
protected_entity,
budget,
));
relation_with_rules.display_dot().unwrap();
let relation_with_rules =
relation_with_rules.map_rewriting_rules(BaseRewritingRulesEliminator);
relation_with_rules.map_rewriting_rules(RewritingRulesEliminator);
relation_with_rules.display_dot().unwrap();
for rwrr in relation_with_rules.select_rewriting_rules(BaseRewritingRulesSelector) {
for rwrr in relation_with_rules.select_rewriting_rules(RewritingRulesSelector) {
rwrr.display_dot().unwrap();
let num_dp = rwrr.accept(BaseBudgetDispatcher);
let num_dp = rwrr.accept(BudgetDispatcher);
println!("DEBUG SPLIT BUDGET IN {}", num_dp);
println!("DEBUG SCORE {}", rwrr.accept(BaseScore));
let relation_with_private_query = rwrr.rewrite(BaseRewriter(&relations));
println!("DEBUG SCORE {}", rwrr.accept(Score));
let relation_with_private_query = rwrr.rewrite(Rewriter(&relations));
println!(
"PrivateQuery: {:?}",
relation_with_private_query.private_query()
Expand Down

0 comments on commit b578b00

Please sign in to comment.