@@ -19,69 +19,120 @@ package edu.berkeley.cs.rise.opaque
19
19
20
20
import org .apache .spark .sql .Strategy
21
21
import org .apache .spark .sql .catalyst .expressions .Alias
22
+ import org .apache .spark .sql .catalyst .expressions .And
22
23
import org .apache .spark .sql .catalyst .expressions .Ascending
23
24
import org .apache .spark .sql .catalyst .expressions .Attribute
24
25
import org .apache .spark .sql .catalyst .expressions .Expression
25
26
import org .apache .spark .sql .catalyst .expressions .IntegerLiteral
27
+ import org .apache .spark .sql .catalyst .expressions .IsNotNull
26
28
import org .apache .spark .sql .catalyst .expressions .Literal
27
29
import org .apache .spark .sql .catalyst .expressions .NamedExpression
28
30
import org .apache .spark .sql .catalyst .expressions .SortOrder
31
+ import org .apache .spark .sql .catalyst .expressions .aggregate ._
29
32
import org .apache .spark .sql .catalyst .planning .ExtractEquiJoinKeys
30
- import org .apache .spark .sql .catalyst .plans .logical .Join
31
- import org .apache .spark .sql .catalyst .plans .logical .JoinHint
32
- import org .apache .spark .sql .catalyst .plans .logical .LogicalPlan
33
+ import org .apache .spark .sql .catalyst .planning .PhysicalAggregation
34
+ import org .apache .spark .sql .catalyst .plans .logical ._
33
35
import org .apache .spark .sql .execution .SparkPlan
34
36
35
37
import edu .berkeley .cs .rise .opaque .execution ._
36
38
import edu .berkeley .cs .rise .opaque .logical ._
37
39
38
40
object OpaqueOperators extends Strategy {
41
+
42
+ def isEncrypted (plan : LogicalPlan ): Boolean = {
43
+ plan.find {
44
+ case _ : OpaqueOperator => true
45
+ case _ => false
46
+ }.nonEmpty
47
+ }
48
+
49
+ def isEncrypted (plan : SparkPlan ): Boolean = {
50
+ plan.find {
51
+ case _ : OpaqueOperatorExec => true
52
+ case _ => false
53
+ }.nonEmpty
54
+ }
55
+
39
56
def apply (plan : LogicalPlan ): Seq [SparkPlan ] = plan match {
40
- case EncryptedProject (projectList, child) =>
57
+ case Project (projectList, child) if isEncrypted( child) =>
41
58
EncryptedProjectExec (projectList, planLater(child)) :: Nil
42
59
43
- case EncryptedFilter (condition, child) =>
60
+ // We don't support null values yet, so there's no point in checking whether the output of an
61
+ // encrypted operator is null
62
+ case p @ Filter (And (IsNotNull (_), IsNotNull (_)), child) if isEncrypted(child) =>
63
+ planLater(child) :: Nil
64
+ case p @ Filter (IsNotNull (_), child) if isEncrypted(child) =>
65
+ planLater(child) :: Nil
66
+
67
+ case Filter (condition, child) if isEncrypted(child) =>
44
68
EncryptedFilterExec (condition, planLater(child)) :: Nil
45
69
46
- case EncryptedSort (order, child) =>
47
- EncryptedSortExec (order, planLater(child)) :: Nil
48
-
49
- case EncryptedJoin (left, right, joinType, condition) =>
50
- Join (left, right, joinType, condition, JoinHint .NONE ) match {
51
- case ExtractEquiJoinKeys (_, leftKeys, rightKeys, condition, _, _, _) =>
52
- val (leftProjSchema, leftKeysProj, tag) = tagForJoin(leftKeys, left.output, true )
53
- val (rightProjSchema, rightKeysProj, _) = tagForJoin(rightKeys, right.output, false )
54
- val leftProj = EncryptedProjectExec (leftProjSchema, planLater(left))
55
- val rightProj = EncryptedProjectExec (rightProjSchema, planLater(right))
56
- val unioned = EncryptedUnionExec (leftProj, rightProj)
57
- val sorted = EncryptedSortExec (sortForJoin(leftKeysProj, tag, unioned.output), unioned)
58
- val joined = EncryptedSortMergeJoinExec (
59
- joinType,
60
- leftKeysProj,
61
- rightKeysProj,
62
- leftProjSchema.map(_.toAttribute),
63
- rightProjSchema.map(_.toAttribute),
64
- (leftProjSchema ++ rightProjSchema).map(_.toAttribute),
65
- sorted)
66
- val tagsDropped = EncryptedProjectExec (dropTags(left.output, right.output), joined)
67
- val filtered = condition match {
68
- case Some (condition) => EncryptedFilterExec (condition, tagsDropped)
69
- case None => tagsDropped
70
- }
71
- filtered :: Nil
72
- case _ => Nil
70
+ case Sort (sortExprs, global, child) if isEncrypted(child) =>
71
+ EncryptedSortExec (sortExprs, planLater(child)) :: Nil
72
+
73
+ case p @ ExtractEquiJoinKeys (joinType, leftKeys, rightKeys, condition, left, right, _) if isEncrypted(p) =>
74
+ val (leftProjSchema, leftKeysProj, tag) = tagForJoin(leftKeys, left.output, true )
75
+ val (rightProjSchema, rightKeysProj, _) = tagForJoin(rightKeys, right.output, false )
76
+ val leftProj = EncryptedProjectExec (leftProjSchema, planLater(left))
77
+ val rightProj = EncryptedProjectExec (rightProjSchema, planLater(right))
78
+ val unioned = EncryptedUnionExec (leftProj, rightProj)
79
+ val sorted = EncryptedSortExec (sortForJoin(leftKeysProj, tag, unioned.output), unioned)
80
+ val joined = EncryptedSortMergeJoinExec (
81
+ joinType,
82
+ leftKeysProj,
83
+ rightKeysProj,
84
+ leftProjSchema.map(_.toAttribute),
85
+ rightProjSchema.map(_.toAttribute),
86
+ (leftProjSchema ++ rightProjSchema).map(_.toAttribute),
87
+ sorted)
88
+ val tagsDropped = EncryptedProjectExec (dropTags(left.output, right.output), joined)
89
+ val filtered = condition match {
90
+ case Some (condition) => EncryptedFilterExec (condition, tagsDropped)
91
+ case None => tagsDropped
73
92
}
93
+ filtered :: Nil
74
94
75
- case a @ EncryptedAggregate (groupingExpressions, aggExpressions, child) =>
76
- EncryptedAggregateExec (groupingExpressions, aggExpressions, planLater(child)) :: Nil
95
+ case a @ PhysicalAggregation (groupingExpressions, aggExpressions, resultExpressions, child)
96
+ if (isEncrypted(child) && aggExpressions.forall(expr => expr.isInstanceOf [AggregateExpression ])) =>
97
+ val aggregateExpressions = aggExpressions.map(expr => expr.asInstanceOf [AggregateExpression ]).map(_.copy(mode = Complete ))
77
98
78
- case EncryptedUnion (left, right) =>
99
+ EncryptedProjectExec (resultExpressions,
100
+ EncryptedAggregateExec (
101
+ groupingExpressions, aggregateExpressions,
102
+ EncryptedSortExec (
103
+ groupingExpressions.map(e => SortOrder (e, Ascending )), planLater(child)))) :: Nil
104
+
105
+ case p @ Union (Seq (left, right)) if isEncrypted(p) =>
79
106
EncryptedUnionExec (planLater(left), planLater(right)) :: Nil
80
107
81
- case EncryptedLocalLimit (IntegerLiteral (limit), child) =>
108
+ case ReturnAnswer (rootPlan) => rootPlan match {
109
+ case Limit (IntegerLiteral (limit), Sort (sortExprs, true , child)) if isEncrypted(child) =>
110
+ EncryptedGlobalLimitExec (limit,
111
+ EncryptedLocalLimitExec (limit,
112
+ EncryptedSortExec (sortExprs, planLater(child)))) :: Nil
113
+
114
+ case Limit (IntegerLiteral (limit), Project (projectList, child)) if isEncrypted(child) =>
115
+ EncryptedGlobalLimitExec (limit,
116
+ EncryptedLocalLimitExec (limit,
117
+ EncryptedProjectExec (projectList, planLater(child)))) :: Nil
118
+
119
+ case _ => Nil
120
+ }
121
+
122
+ case Limit (IntegerLiteral (limit), Sort (sortExprs, true , child)) if isEncrypted(child) =>
123
+ EncryptedGlobalLimitExec (limit,
124
+ EncryptedLocalLimitExec (limit,
125
+ EncryptedSortExec (sortExprs, planLater(child)))) :: Nil
126
+
127
+ case Limit (IntegerLiteral (limit), Project (projectList, child)) if isEncrypted(child) =>
128
+ EncryptedGlobalLimitExec (limit,
129
+ EncryptedLocalLimitExec (limit,
130
+ EncryptedProjectExec (projectList, planLater(child)))) :: Nil
131
+
132
+ case LocalLimit (IntegerLiteral (limit), child) if isEncrypted(child) =>
82
133
EncryptedLocalLimitExec (limit, planLater(child)) :: Nil
83
134
84
- case EncryptedGlobalLimit (IntegerLiteral (limit), child) =>
135
+ case GlobalLimit (IntegerLiteral (limit), child) if isEncrypted( child) =>
85
136
EncryptedGlobalLimitExec (limit, planLater(child)) :: Nil
86
137
87
138
case Encrypt (child) =>
0 commit comments