@@ -152,63 +152,117 @@ func (s *SchemaCheckPass) applyIpTransformations(indexSchema schema.Schema, quer
152152 return query , nil
153153}
154154
155- func (s * SchemaCheckPass ) applyGeoTransformations (currentSchema schema.Schema , query * model.Query ) (* model.Query , error ) {
156- fromTable := query .TableName
155+ func (s * SchemaCheckPass ) applyGeoTransformations (schemaInstance schema.Schema , query * model.Query ) (* model.Query , error ) {
156+
157+ replace := make (map [string ]model.Expr )
158+
159+ for _ , field := range schemaInstance .Fields {
160+ if field .Type .Name == schema .QuesmaTypePoint .Name {
161+
162+ lon := model .NewColumnRef (field .InternalPropertyName .AsString () + "::lon" )
163+ lat := model .NewColumnRef (field .InternalPropertyName .AsString () + "::lat" )
164+
165+ // This is a workaround. Clickhouse Point is defined as Tuple. We need to know the type of the tuple.
166+ // In this step we merge two columns into single map here. Map is in elastic format.
167+
168+ // In this point we assume that Quesma point type is stored into two separate columns.
169+ replace [field .PropertyName .AsString ()] = model .NewFunction ("map" ,
170+ model .NewLiteral ("'lat'" ),
171+ lat ,
172+ model .NewLiteral ("'lon'" ),
173+ lon )
174+
175+ // these a just if we need multifields support
176+ replace [field .PropertyName .AsString ()+ ".lat" ] = lat
177+ replace [field .PropertyName .AsString ()+ ".lon" ] = lon
178+
179+ // if the point is stored as a single column, we need to extract the lat and lon
180+ //replace[field.PropertyName.AsString()] = model.NewFunction("give_me_point", model.NewColumnRef(field.InternalPropertyName.AsString()))
181+ //replace[field.PropertyName.AsString()+".lat"] = model.NewFunction("give_me_lat", model.NewColumnRef(field.InternalPropertyName.AsString()))
182+ //replace[field.PropertyName.AsString()+".lon"] = model.NewFunction("give_me_lon", model.NewColumnRef(field.InternalPropertyName.AsString()))
183+
184+ }
185+ }
157186
158187 visitor := model .NewBaseVisitor ()
159- visitor .OverrideVisitSelectCommand = func (b * model.BaseExprVisitor , e model.SelectCommand ) interface {} {
160- if s .schemaRegistry == nil {
161- logger .Error ().Msg ("Schema registry is not set" )
162- return e
163- }
164- schemaInstance , exists := s .schemaRegistry .FindSchema (schema .TableName (fromTable ))
165- if ! exists {
166- logger .Error ().Msgf ("Schema fot table %s not found" , fromTable )
167- return e
168- }
169- var groupBy []model.Expr
170- for _ , expr := range e .GroupBy {
171- groupByExpr := expr .Accept (b ).(model.Expr )
172- if col , ok := expr .(model.ColumnRef ); ok {
173- // This checks if the column is of type point
174- // and if it is, it appends the lat and lon columns to the group by clause
175- field := schemaInstance .Fields [schema .FieldName (col .ColumnName )]
176- if field .Type .Name == schema .QuesmaTypePoint .Name {
177- // TODO suffixes ::lat, ::lon are hardcoded for now
178- groupBy = append (groupBy , model .NewColumnRef (field .InternalPropertyName .AsString ()+ "::lat" ))
179- groupBy = append (groupBy , model .NewColumnRef (field .InternalPropertyName .AsString ()+ "::lon" ))
180- } else {
181- groupBy = append (groupBy , groupByExpr )
188+
189+ visitor .OverrideVisitColumnRef = func (b * model.BaseExprVisitor , e model.ColumnRef ) interface {} {
190+ if expr , ok := replace [e .ColumnName ]; ok {
191+ return expr
192+ }
193+ return e
194+ }
195+
196+ visitor .OverrideVisitFunction = func (b * model.BaseExprVisitor , e model.FunctionExpr ) interface {} {
197+
198+ var suffix string
199+ switch e .Name {
200+ case model .QuesmaGeoLatFunction :
201+ suffix = ".lat"
202+ case model .QuesmaGeoLonFunction :
203+ suffix = ".lon"
204+ }
205+
206+ if suffix != "" && len (e .Args ) == 1 {
207+ if col , ok := e .Args [0 ].(model.ColumnRef ); ok {
208+ if expr , ok := replace [col .ColumnName + suffix ]; ok {
209+ return expr
182210 }
183- } else {
184- groupBy = append (groupBy , groupByExpr )
185211 }
186212 }
187- var columns []model.Expr
188- for _ , expr := range e .Columns {
213+
214+ return model .NewFunction (e .Name , b .VisitChildren (e .Args )... )
215+ }
216+
217+ visitor .OverrideVisitSelectCommand = func (v * model.BaseExprVisitor , query model.SelectCommand ) interface {} {
218+ var columns , groupBy []model.Expr
219+ var orderBy []model.OrderByExpr
220+ from := query .FromClause
221+ where := query .WhereClause
222+
223+ for _ , expr := range query .Columns {
224+ var alias string
189225 if col , ok := expr .(model.ColumnRef ); ok {
190- // This checks if the column is of type point
191- // and if it is, it appends the lat and lon columns to the select clause
192- field := schemaInstance .Fields [schema .FieldName (col .ColumnName )]
193- if field .Type .Name == schema .QuesmaTypePoint .Name {
194- // TODO suffixes ::lat, ::lon are hardcoded for now
195- columns = append (columns , model .NewColumnRef (field .InternalPropertyName .AsString ()+ "::lat" ))
196- columns = append (columns , model .NewColumnRef (field .InternalPropertyName .AsString ()+ "::lon" ))
197- } else {
198- columns = append (columns , expr .Accept (b ).(model.Expr ))
226+ if _ , ok := replace [col .ColumnName ]; ok {
227+ alias = col .ColumnName
199228 }
200- } else {
201- columns = append (columns , expr .Accept (b ).(model.Expr ))
202229 }
230+
231+ col := expr .Accept (v ).(model.Expr )
232+
233+ if alias != "" {
234+ col = model .NewAliasedExpr (col , alias )
235+ }
236+
237+ columns = append (columns , col )
238+ }
239+ for _ , expr := range query .GroupBy {
240+ groupBy = append (groupBy , expr .Accept (v ).(model.Expr ))
241+ }
242+ for _ , expr := range query .OrderBy {
243+ orderBy = append (orderBy , expr .Accept (v ).(model.OrderByExpr ))
244+ }
245+ if query .FromClause != nil {
246+ from = query .FromClause .Accept (v ).(model.Expr )
247+ }
248+ if query .WhereClause != nil {
249+ where = query .WhereClause .Accept (v ).(model.Expr )
203250 }
204251
205- var fromClause model.Expr
206- if e .FromClause != nil {
207- fromClause = e .FromClause .Accept (b ).(model.Expr )
252+ var namedCTEs []* model.CTE
253+ if query .NamedCTEs != nil {
254+ for _ , cte := range query .NamedCTEs {
255+ namedCTEs = append (namedCTEs , cte .Accept (v ).(* model.CTE ))
256+ }
208257 }
209258
210- return model .NewSelectCommand (columns , groupBy , e .OrderBy ,
211- fromClause , e .WhereClause , e .LimitBy , e .Limit , e .SampleLimit , e .IsDistinct , e .NamedCTEs )
259+ var limitBy []model.Expr
260+ if query .LimitBy != nil {
261+ for _ , expr := range query .LimitBy {
262+ limitBy = append (limitBy , expr .Accept (v ).(model.Expr ))
263+ }
264+ }
265+ return model .NewSelectCommand (columns , groupBy , orderBy , from , where , limitBy , query .Limit , query .SampleLimit , query .IsDistinct , namedCTEs )
212266 }
213267
214268 expr := query .SelectCommand .Accept (visitor )
@@ -329,9 +383,6 @@ func (s *SchemaCheckPass) applyWildcardExpansion(indexSchema schema.Schema, quer
329383
330384 cols := make ([]string , 0 , len (indexSchema .Fields ))
331385 for _ , col := range indexSchema .Fields {
332- if col .Type .Name == schema .QuesmaTypePoint .Name { // Temporary workaround for kibana_flights
333- continue
334- }
335386 cols = append (cols , col .InternalPropertyName .AsString ())
336387 }
337388 sort .Strings (cols )
@@ -520,38 +571,6 @@ func (s *SchemaCheckPass) Transform(queries []*model.Query) ([]*model.Query, err
520571 return queries , nil
521572}
522573
523- type GeoIpResultTransformer struct {
524- schemaRegistry schema.Registry
525- fromTable string
526- }
527-
528- func (g * GeoIpResultTransformer ) Transform (result [][]model.QueryResultRow ) ([][]model.QueryResultRow , error ) {
529- if g .schemaRegistry == nil {
530- logger .Error ().Msg ("Schema registry is not set" )
531- return result , nil
532- }
533- schemaInstance , exists := g .schemaRegistry .FindSchema (schema .TableName (g .fromTable ))
534- if ! exists {
535- logger .Error ().Msgf ("Schema fot table %s not found" , g .fromTable )
536- return result , nil
537- }
538- for i , rows := range result {
539- for j , row := range rows {
540- for k , col := range row .Cols {
541- if strings .Contains (col .ColName , "::lat" ) {
542- colType := schemaInstance .Fields [schema .FieldName (strings .TrimSuffix (col .ColName , "::lat" ))].Type
543- result [i ][j ].Cols [k ].ColType = colType
544- }
545- if strings .Contains (col .ColName , "::lon" ) {
546- colType := schemaInstance .Fields [schema .FieldName (strings .TrimSuffix (col .ColName , "::lon" ))].Type
547- result [i ][j ].Cols [k ].ColType = colType
548- }
549- }
550- }
551- }
552- return result , nil
553- }
554-
555574// ArrayResultTransformer is a transformer that transforms array columns into string representation
556575type ArrayResultTransformer struct {
557576}
0 commit comments