@@ -33,37 +33,64 @@ struct Environment {
3333 /// during a query. However if they do a `SELECT *` it should
3434 /// not be included into the result columns
3535 let explicitAccessOnly : Bool
36+ /// Whether or not this value is inherited from a parent environment.
37+ /// In a subquery we inherit the values from the parent environment
38+ /// but with the caveat that they are overridable and won't be consider
39+ /// ambiguous if something was inserted with the same name.
40+ let isFromParent : Bool
3641 }
3742
3843 init ( ) { }
44+
45+ private init ( identifiers: OrderedDictionary < Substring , TypeContainer > ) {
46+ self . identifiers = identifiers
47+ }
3948
4049 /// Inserts or updates the type for the given name
4150 mutating func upsert( _ name: Substring , ty: Type , explicitAccessOnly: Bool = false ) {
4251 identifiers [ name] = TypeContainer (
4352 type: ty,
4453 isAmbiguous: false ,
45- explicitAccessOnly: explicitAccessOnly
54+ explicitAccessOnly: explicitAccessOnly,
55+ isFromParent: false
4656 )
4757 }
4858
4959 /// Inserts the type for the given name. If the name
5060 /// already exists it will be marked as ambiguous
5161 mutating func insert( _ name: Substring , ty: Type , explicitAccessOnly: Bool = false ) {
52- if let existing = identifiers [ name] {
62+ // If it already exists, mark it as ambiguous except for the case
63+ // where its from a parent environment.
64+ if let existing = identifiers [ name] , !existing. isFromParent {
5365 identifiers [ name] = TypeContainer (
5466 type: existing. type,
5567 isAmbiguous: true ,
56- explicitAccessOnly: explicitAccessOnly
68+ explicitAccessOnly: explicitAccessOnly,
69+ isFromParent: false
5770 )
5871 } else {
5972 identifiers [ name] = TypeContainer (
6073 type: ty,
6174 isAmbiguous: false ,
62- explicitAccessOnly: explicitAccessOnly
75+ explicitAccessOnly: explicitAccessOnly,
76+ isFromParent: false
6377 )
6478 }
6579 }
6680
81+ /// Returns a copy of `self` but with all identifiers in the environment
82+ /// as overridable since they are from a parent environment.
83+ func asParent( ) -> Environment {
84+ return Environment ( identifiers: identifiers. mapValues { container in
85+ TypeContainer (
86+ type: container. type,
87+ isAmbiguous: container. isAmbiguous,
88+ explicitAccessOnly: container. explicitAccessOnly,
89+ isFromParent: true
90+ )
91+ } )
92+ }
93+
6794 mutating func rename( _ key: Substring , to newValue: Substring ) {
6895 guard let value = identifiers [ key] else { return }
6996 identifiers [ key] = nil
0 commit comments