Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.

Commit 0a562aa

Browse files
committed
Merge branch 'main' into datetime
2 parents 7456f14 + eac5ddf commit 0a562aa

File tree

29 files changed

+1334
-111
lines changed

29 files changed

+1334
-111
lines changed

docs/public/docs/limitations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Currently supported:
3838
including: `boolean`, `match`, `match phrase`, `multi-match`, `query string`, `nested`, `match all`, `exists`, `prefix`, `range`, `term`, `terms`, `wildcard`
3939
- most popular [Aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html),
4040
including: `avg`, `cardinality`, `max`, `min`, `percentile ranks`, `percentiles`, `stats`, `sum`, `top hits`, `top metrics`, `value count`,
41-
`date histogram`, `date range`, `filter`, `filters`, `histogram`, `range`, `singificant terms`, `terms`, `ip prefix`, `ip range`, `geo_bounds`, `geohash_grid`
41+
`date histogram`, `date range`, `filter`, `filters`, `histogram`, `range`, `significant terms`, `terms`, `ip prefix`, `ip range`, `geo_bounds`, `geohash_grid`
4242

4343
Which as a result allows you to run Kibana/OSD queries and dashboards on data residing in ClickHouse/Hydrolix.
4444

examples/kibana-sample-data/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ services:
7676
command: [ "/bin/bash", "-c", "/local_mount/run.sh" ]
7777
clickhouse:
7878
# user: 'default', no password
79-
image: clickhouse/clickhouse-server:23.12.2.59-alpine
79+
image: clickhouse/clickhouse-server:24.5.3.5-alpine
8080
ports:
8181
- "8123:8123"
8282
- "9000:9000"

examples/kibana-sample-data/kibana/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ add_sample_dataset() {
6161
wait_until_available
6262

6363
add_sample_dataset "flights"
64-
#add_sample_dataset "logs"
64+
add_sample_dataset "logs"
6565
add_sample_dataset "ecommerce"
6666

6767
echo -n "Adding data view logs-generic... "

examples/kibana-sample-data/quesma/config/local-dev.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ processors:
5454
type: geo_point
5555
"OriginLocation":
5656
type: geo_point
57+
kibana_sample_data_logs:
58+
target: [ my-clickhouse-data-source ]
59+
schemaOverrides:
60+
fields:
61+
timestamp:
62+
type: alias
63+
targetColumnName: "@timestamp"
64+
ip:
65+
type: ip
66+
clientip:
67+
type: ip
68+
"geo.coordinates":
69+
type: geo_point
70+
"geo.src":
71+
type: keyword
5772
logs-generic-default:
5873
target:
5974
- my-clickhouse-data-source
@@ -103,6 +118,21 @@ processors:
103118
type: geo_point
104119
"OriginLocation":
105120
type: geo_point
121+
kibana_sample_data_logs:
122+
target: [ my-clickhouse-data-source ]
123+
schemaOverrides:
124+
fields:
125+
timestamp:
126+
type: alias
127+
targetColumnName: "@timestamp"
128+
ip:
129+
type: ip
130+
clientip:
131+
type: ip
132+
"geo.coordinates":
133+
type: geo_point
134+
"geo.src":
135+
type: keyword
106136
logs-generic-default:
107137
target:
108138
- my-clickhouse-data-source

platform/config/config_v2.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,22 @@ type Processor struct {
115115
const DefaultWildcardIndexName = "*"
116116

117117
// Configuration of QuesmaV1ProcessorQuery and QuesmaV1ProcessorIngest
118-
type QuesmaProcessorConfig struct {
119-
UseCommonTable bool `koanf:"useCommonTable"`
120-
IndexConfig IndicesConfigs `koanf:"indexes"`
121-
// DefaultTargetConnectorType is used in V2 code only
122-
DefaultTargetConnectorType string //it is not serialized to maintain configuration BWC, so it's basically just populated from '*' config in `config_v2.go`
123-
}
118+
type (
119+
QuesmaProcessorConfig struct {
120+
UseCommonTable bool `koanf:"useCommonTable"`
121+
IndexConfig IndicesConfigs `koanf:"indexes"`
122+
// DefaultTargetConnectorType is used in V2 code only
123+
DefaultTargetConnectorType string //it is not serialized to maintain configuration BWC, so it's basically just populated from '*' config in `config_v2.go`
124+
}
125+
IndicesConfigs map[string]IndexConfiguration
126+
)
124127

125-
type IndicesConfigs map[string]IndexConfiguration
128+
func (p *QuesmaProcessorConfig) IsFieldMapSyntaxEnabled(indexName string) bool {
129+
if indexConf, exists := p.IndexConfig[indexName]; exists {
130+
return indexConf.EnableFieldMapSyntax
131+
}
132+
return false
133+
}
126134

127135
func LoadV2Config() QuesmaNewConfiguration {
128136
var v2config QuesmaNewConfiguration

platform/frontend_connectors/route_handlers.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ func HandleGetIndex(sr schema.Registry, index string) (*quesma_api.Result, error
162162
return getIndexResult(index, mappings)
163163
}
164164

165-
func HandleTermsEnum(ctx context.Context, indexPattern string, body types.JSON, lm clickhouse.LogManagerIFace, sr schema.Registry, dependencies quesma_api.Dependencies) (*quesma_api.Result, error) {
166-
if responseBody, err := terms_enum.HandleTermsEnum(ctx, indexPattern, body, lm, sr, dependencies.DebugInfoCollector()); err != nil {
165+
func HandleTermsEnum(ctx context.Context, indexPattern string, body types.JSON, lm clickhouse.LogManagerIFace, sr schema.Registry,
166+
isFieldMapSyntaxEnabled bool, dependencies quesma_api.Dependencies) (*quesma_api.Result, error) {
167+
if responseBody, err := terms_enum.HandleTermsEnum(ctx, indexPattern, body, lm, sr, isFieldMapSyntaxEnabled, dependencies.DebugInfoCollector()); err != nil {
167168
return nil, err
168169
} else {
169170
return elasticsearchQueryResult(string(responseBody), http.StatusOK), nil

platform/frontend_connectors/router_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,8 @@ func configureRouter(cfg *config.QuesmaConfiguration, sr schema.Registry, lm *cl
391391
return nil, errors.New("invalid request body, expecting JSON")
392392
}
393393

394-
if responseBody, err := terms_enum.HandleTermsEnum(ctx, req.Params["index"], body, lm, sr, console); err != nil {
394+
const isFieldMapSyntaxEnabled = false
395+
if responseBody, err := terms_enum.HandleTermsEnum(ctx, req.Params["index"], body, lm, sr, isFieldMapSyntaxEnabled, console); err != nil {
395396
return nil, err
396397
} else {
397398
return elasticsearchQueryResult(string(responseBody), http.StatusOK), nil

platform/frontend_connectors/router_v2.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,12 @@ func ConfigureSearchRouterV2(cfg *config.QuesmaConfiguration, dependencies quesm
251251
if err != nil {
252252
return nil, errors.New("invalid request body, expecting JSON")
253253
}
254-
return HandleTermsEnum(ctx, indexPattern, body, lm, sr, dependencies)
254+
255+
var isFieldMapSyntaxEnabled bool
256+
if indexCfg, exists := cfg.IndexConfig[indexPattern]; exists {
257+
isFieldMapSyntaxEnabled = indexCfg.EnableFieldMapSyntax
258+
}
259+
return HandleTermsEnum(ctx, indexPattern, body, lm, sr, isFieldMapSyntaxEnabled, dependencies)
255260
})
256261

257262
router.Register(routes.EQLSearch, and(method("GET", "POST"), matchedAgainstPattern(tableResolver)), func(ctx context.Context, req *quesma_api.Request, _ http.ResponseWriter) (*quesma_api.Result, error) {

platform/frontend_connectors/schema_map_transformation.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ func (v *mapTypeResolver) isMap(fieldName string) (exists bool, scope searchScop
5050
if !ok {
5151
return false, scope, fieldName
5252
}
53-
col, ok := v.indexSchema.Fields[schema.FieldName(tableColumnName.InternalPropertyName.AsString())]
5453

54+
col, ok := v.indexSchema.Fields[schema.FieldName(tableColumnName.InternalPropertyName.AsString())]
5555
if ok {
5656
if strings.HasPrefix(col.InternalPropertyType, "Map") {
5757
return true, scope, tableColumnName.InternalPropertyName.AsString()
@@ -72,12 +72,10 @@ func NewMapTypeVisitor(resolver mapTypeResolver) model.ExprVisitor {
7272
visitor := model.NewBaseVisitor()
7373

7474
visitor.OverrideVisitColumnRef = func(b *model.BaseExprVisitor, e model.ColumnRef) interface{} {
75-
isMap, _, realName := resolver.isMap(e.ColumnName)
76-
if !isMap {
77-
return e
75+
if isMap, _, realName := resolver.isMap(e.ColumnName); isMap {
76+
return model.NewColumnRefWithTable(realName, e.TableAlias)
7877
}
79-
80-
return model.NewColumnRef(realName)
78+
return e.Clone()
8179
}
8280

8381
visitor.OverrideVisitInfix = func(b *model.BaseExprVisitor, e model.InfixExpr) interface{} {

platform/frontend_connectors/schema_transformer.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/QuesmaOrg/quesma/platform/util"
1616
"github.com/k0kubun/pp"
1717
"slices"
18+
"github.com/QuesmaOrg/quesma/platform/transformations"
1819
"sort"
1920
"strings"
2021
)
@@ -714,6 +715,7 @@ func (s *SchemaCheckPass) applyTimestampField(ctx context.Context, indexSchema s
714715

715716
}
716717

718+
<<<<<<< HEAD
717719
func (s *SchemaCheckPass) applyTimestampFieldd(ctx context.Context, indexSchema schema.Schema, query *model.Query) (*model.Query, error) {
718720
table, ok := s.tableDiscovery.TableDefinitions().Load(query.TableName)
719721
if !ok {
@@ -1015,6 +1017,7 @@ func (s *SchemaCheckPass) applyFieldMapSyntax(ctx context.Context, indexSchema s
10151017
}
10161018

10171019
func (s *SchemaCheckPass) applyFieldEncoding(ctx context.Context, indexSchema schema.Schema, query *model.Query) (*model.Query, error) {
1020+
10181021
table, ok := s.tableDiscovery.TableDefinitions().Load(query.TableName)
10191022
if !ok {
10201023
return nil, fmt.Errorf("table %s not found", query.TableName)
@@ -1280,7 +1283,9 @@ func (s *SchemaCheckPass) Transform(ctx context.Context, queries []*model.Query)
12801283
{TransformationName: "PhysicalFromExpressionTransformation", Transformation: s.applyPhysicalFromExpression},
12811284
{TransformationName: "WildcardExpansion", Transformation: s.applyWildcardExpansion},
12821285
{TransformationName: "RuntimeMappings", Transformation: s.applyRuntimeMappings},
1283-
{TransformationName: "FieldMapSyntaxTransformation", Transformation: s.applyFieldMapSyntax},
1286+
{TransformationName: "AllNecessaryCommonTransformations", Transformation: func(schema schema.Schema, query *model.Query) (*model.Query, error) {
1287+
return transformations.ApplyAllNecessaryCommonTransformations(query, schema, s.cfg.MapFieldsDiscoveringEnabled)
1288+
}},
12841289
{TransformationName: "AliasColumnsTransformation", Transformation: s.applyAliasColumns},
12851290
{TransformationName: "UnixTimestampToDateTimeTransformation", Transformation: s.applyTimestampFieldd},
12861291

@@ -1411,7 +1416,6 @@ func (s *SchemaCheckPass) applyMatchOperator(ctx context.Context, indexSchema sc
14111416
return model.NewInfixExpr(lhs, "ILIKE", rhs.Clone())
14121417
}
14131418
equal := func() model.Expr {
1414-
rhsValue = strings.Trim(rhsValue, "%")
14151419
return model.NewInfixExpr(lhs, "=", rhs.Clone())
14161420
}
14171421

@@ -1428,6 +1432,8 @@ func (s *SchemaCheckPass) applyMatchOperator(ctx context.Context, indexSchema sc
14281432
// TODO: improve? we seem to be `ilike'ing` too much
14291433
switch field.Type.String() {
14301434
case schema.QuesmaTypeInteger.Name, schema.QuesmaTypeLong.Name, schema.QuesmaTypeUnsignedLong.Name, schema.QuesmaTypeFloat.Name, schema.QuesmaTypeBoolean.Name:
1435+
rhs.Value = strings.Trim(rhsValue, "%")
1436+
rhs.EscapeType = model.NormalNotEscaped
14311437
return equal()
14321438
default:
14331439
return ilike()

0 commit comments

Comments
 (0)