@@ -129,8 +129,97 @@ public struct FilterNot: Codable, Hashable, Equatable, Sendable {
129129 public let field : Filter
130130}
131131
132+ /// The equality filter matches rows where a column value equals a specific value.
133+ public struct FilterEquals : Codable , Hashable , Equatable , Sendable {
134+ public init ( column: String , matchValueType: MatchValueType , matchValue: MatchValue ) {
135+ self . column = column
136+ self . matchValueType = matchValueType
137+ self . matchValue = matchValue
138+ }
139+
140+ public enum MatchValueType : String , Codable , Hashable , Equatable , Sendable {
141+ case string = " STRING "
142+ case long = " LONG "
143+ case double = " DOUBLE "
144+ case float = " FLOAT "
145+ case arrayString = " ARRAY<STRING> "
146+ case arrayLong = " ARRAY<LONG> "
147+ case arrayDouble = " ARRAY<DOUBLE> "
148+ case arrayFloat = " ARRAY<FLOAT> "
149+ }
150+
151+ public enum MatchValue : Hashable , Equatable , Sendable {
152+ case string( String )
153+ case int( Int )
154+ case double( Double )
155+ case arrayString( [ String ] )
156+ case arrayInt( [ Int ] )
157+ case arrayDouble( [ Double ] )
158+ }
159+
160+ public let column : String
161+ public let matchValueType : MatchValueType
162+ public let matchValue : MatchValue
163+ }
164+
165+ extension FilterEquals . MatchValue : Codable {
166+ public init ( from decoder: Decoder ) throws {
167+ let container = try decoder. singleValueContainer ( )
168+
169+ if let arrayString = try ? container. decode ( [ String ] . self) {
170+ self = . arrayString( arrayString)
171+ } else if let arrayInt = try ? container. decode ( [ Int ] . self) {
172+ self = . arrayInt( arrayInt)
173+ } else if let arrayDouble = try ? container. decode ( [ Double ] . self) {
174+ self = . arrayDouble( arrayDouble)
175+ } else if let string = try ? container. decode ( String . self) {
176+ self = . string( string)
177+ } else if let int = try ? container. decode ( Int . self) {
178+ self = . int( int)
179+ } else if let double = try ? container. decode ( Double . self) {
180+ self = . double( double)
181+ } else {
182+ throw DecodingError . typeMismatch (
183+ FilterEquals . MatchValue. self,
184+ DecodingError . Context (
185+ codingPath: decoder. codingPath,
186+ debugDescription: " Expected String, Int, Double, or array types "
187+ )
188+ )
189+ }
190+ }
191+
192+ public func encode( to encoder: Encoder ) throws {
193+ var container = encoder. singleValueContainer ( )
194+
195+ switch self {
196+ case . string( let value) :
197+ try container. encode ( value)
198+ case . int( let value) :
199+ try container. encode ( value)
200+ case . double( let value) :
201+ try container. encode ( value)
202+ case . arrayString( let value) :
203+ try container. encode ( value)
204+ case . arrayInt( let value) :
205+ try container. encode ( value)
206+ case . arrayDouble( let value) :
207+ try container. encode ( value)
208+ }
209+ }
210+ }
211+
212+ /// The null filter matches rows where a column value is null.
213+ public struct FilterNull : Codable , Hashable , Equatable , Sendable {
214+ public init ( column: String ) {
215+ self . column = column
216+ }
217+
218+ public let column : String
219+ }
220+
132221/// A filter is a JSON object indicating which rows of data should be included in the computation
133- /// for a query. It’ s essentially the equivalent of the WHERE clause in SQL.
222+ /// for a query. It' s essentially the equivalent of the WHERE clause in SQL.
134223public indirect enum Filter : Codable , Hashable , Equatable , Sendable {
135224 /// The selector filter will match a specific dimension with a specific value.
136225 /// Selector filters can be used as the base filters for more complex Boolean
@@ -157,6 +246,12 @@ public indirect enum Filter: Codable, Hashable, Equatable, Sendable {
157246 // to, less than or equal to, and "between"
158247 case range( FilterRange )
159248
249+ /// The equality filter matches rows where a column value equals a specific value.
250+ case equals( FilterEquals )
251+
252+ /// The null filter matches rows where a column value is null.
253+ case null( FilterNull )
254+
160255 // logical expression filters
161256 case and( FilterExpression )
162257 case or( FilterExpression )
@@ -179,14 +274,18 @@ public indirect enum Filter: Codable, Hashable, Equatable, Sendable {
179274 self = try . interval( FilterInterval ( from: decoder) )
180275 case " regex " :
181276 self = try . regex( FilterRegex ( from: decoder) )
277+ case " range " :
278+ self = try . range( FilterRange ( from: decoder) )
279+ case " equals " :
280+ self = try . equals( FilterEquals ( from: decoder) )
281+ case " null " :
282+ self = try . null( FilterNull ( from: decoder) )
182283 case " and " :
183284 self = try . and( FilterExpression ( from: decoder) )
184285 case " or " :
185286 self = try . or( FilterExpression ( from: decoder) )
186287 case " not " :
187288 self = try . not( FilterNot ( from: decoder) )
188- case " range " :
189- self = try . range( FilterRange ( from: decoder) )
190289 default :
191290 throw EncodingError . invalidValue ( " Invalid type " , . init( codingPath: [ CodingKeys . type] , debugDescription: " Invalid Type " , underlyingError: nil ) )
192291 }
@@ -216,6 +315,12 @@ public indirect enum Filter: Codable, Hashable, Equatable, Sendable {
216315 case let . range( range) :
217316 try container. encode ( " range " , forKey: . type)
218317 try range. encode ( to: encoder)
318+ case let . equals( equals) :
319+ try container. encode ( " equals " , forKey: . type)
320+ try equals. encode ( to: encoder)
321+ case let . null( null) :
322+ try container. encode ( " null " , forKey: . type)
323+ try null. encode ( to: encoder)
219324 case let . and( and) :
220325 try container. encode ( " and " , forKey: . type)
221326 try and. encode ( to: encoder)
0 commit comments