@@ -17,7 +17,7 @@ import (
17
17
"golang.org/x/exp/slices"
18
18
)
19
19
20
- func (print * Printer ) Datas (bundle * llx.CodeBundle , results map [string ]* llx.RawResult ) string {
20
+ func (print * Printer ) Datas (bundle * llx.ExpandedCodeBundle , results map [string ]* llx.RawResult ) string {
21
21
var res strings.Builder
22
22
i := 0
23
23
for _ , v := range results {
@@ -33,17 +33,18 @@ func (print *Printer) Datas(bundle *llx.CodeBundle, results map[string]*llx.RawR
33
33
// Results prints a full query with all data points
34
34
// NOTE: ensure that results only contains results that match the bundle!
35
35
func (print * Printer ) Results (bundle * llx.CodeBundle , results map [string ]* llx.RawResult ) string {
36
+ ebundle := bundle .Expand ()
36
37
assessment := llx .Results2Assessment (bundle , results )
37
38
38
39
if assessment != nil {
39
- return print .Assessment (bundle , assessment )
40
+ return print .Assessment (ebundle , assessment )
40
41
}
41
42
42
- return print .Datas (bundle , results )
43
+ return print .Datas (ebundle , results )
43
44
}
44
45
45
46
// Assessment prints a complete comparable assessment
46
- func (print * Printer ) Assessment (bundle * llx.CodeBundle , assessment * llx.Assessment ) string {
47
+ func (print * Printer ) Assessment (bundle * llx.ExpandedCodeBundle , assessment * llx.Assessment ) string {
47
48
var res strings.Builder
48
49
49
50
var indent string
@@ -74,7 +75,7 @@ func isBooleanOp(op string) bool {
74
75
return op == "&&" || op == "||"
75
76
}
76
77
77
- func (print * Printer ) assessment (bundle * llx.CodeBundle , assessment * llx.AssessmentItem , indent string ) string {
78
+ func (print * Printer ) assessment (bundle * llx.ExpandedCodeBundle , assessment * llx.AssessmentItem , indent string ) string {
78
79
var codeID string
79
80
if bundle .CodeV2 != nil {
80
81
codeID = bundle .CodeV2 .Id
@@ -161,15 +162,15 @@ func (print *Printer) assessment(bundle *llx.CodeBundle, assessment *llx.Assessm
161
162
}
162
163
163
164
// Result prints the llx raw result into a string
164
- func (print * Printer ) Result (result * llx.RawResult , bundle * llx.CodeBundle ) string {
165
+ func (print * Printer ) Result (result * llx.RawResult , bundle * llx.ExpandedCodeBundle ) string {
165
166
if result == nil {
166
167
return "< no result? >"
167
168
}
168
169
169
170
return print .DataWithLabel (result .Data , result .CodeID , bundle , "" )
170
171
}
171
172
172
- func (print * Printer ) label (ref string , bundle * llx.CodeBundle , isResource bool ) string {
173
+ func (print * Printer ) label (ref string , bundle * llx.ExpandedCodeBundle , isResource bool ) string {
173
174
if bundle == nil {
174
175
return ""
175
176
}
@@ -187,7 +188,7 @@ func (print *Printer) label(ref string, bundle *llx.CodeBundle, isResource bool)
187
188
return print .Primary (label ) + ": "
188
189
}
189
190
190
- func (print * Printer ) defaultLabel (ref string , bundle * llx.CodeBundle ) string {
191
+ func (print * Printer ) defaultLabel (ref string , bundle * llx.ExpandedCodeBundle ) string {
191
192
if bundle == nil {
192
193
return ""
193
194
}
@@ -205,7 +206,7 @@ func (print *Printer) defaultLabel(ref string, bundle *llx.CodeBundle) string {
205
206
return print .Primary (label ) + "="
206
207
}
207
208
208
- func isDefaultField (ref string , bundle * llx.CodeBundle , defaultFields []string ) bool {
209
+ func isDefaultField (ref string , bundle * llx.ExpandedCodeBundle , defaultFields []string ) bool {
209
210
if bundle == nil {
210
211
return false
211
212
}
@@ -223,7 +224,7 @@ func isDefaultField(ref string, bundle *llx.CodeBundle, defaultFields []string)
223
224
return slices .Contains (defaultFields , label )
224
225
}
225
226
226
- func (print * Printer ) array (typ types.Type , data []interface {}, codeID string , bundle * llx.CodeBundle , indent string ) string {
227
+ func (print * Printer ) array (typ types.Type , data []interface {}, codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
227
228
if len (data ) == 0 {
228
229
return "[]"
229
230
}
@@ -265,7 +266,7 @@ func (print *Printer) assessmentTemplate(template string, data []string) string
265
266
return res
266
267
}
267
268
268
- func (print * Printer ) dataAssessment (codeID string , data map [string ]interface {}, bundle * llx.CodeBundle ) string {
269
+ func (print * Printer ) dataAssessment (codeID string , data map [string ]interface {}, bundle * llx.ExpandedCodeBundle ) string {
269
270
var assertion * llx.AssertionMessage
270
271
var ok bool
271
272
@@ -309,31 +310,57 @@ func (print *Printer) dataAssessment(codeID string, data map[string]interface{},
309
310
return print .assessmentTemplate (assertion .Template , fields )
310
311
}
311
312
312
- func (print * Printer ) refMap (typ types.Type , data map [string ]interface {}, codeID string , bundle * llx.CodeBundle , indent string ) string {
313
+ func (print * Printer ) block (typ types.Type , data map [string ]interface {}, codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
313
314
if len (data ) == 0 {
314
315
return "{}"
315
316
}
316
317
317
318
var res strings.Builder
318
319
319
- // we need to separate entries that are unlabelled (eg part of an assertion)
320
- labeledKeys := []string {}
321
- keys := sortx .Keys (data )
322
- for i := range keys {
323
- if _ , ok := bundle .Labels .Labels [keys [i ]]; ok {
324
- labeledKeys = append (labeledKeys , keys [i ])
325
- }
326
- }
327
-
328
- code := bundle .CodeV2
329
- ep := code .Blocks [0 ].Entrypoints [0 ]
330
- chunk := code .Chunk (ep )
331
320
listType := ""
332
- switch chunk .Id {
333
- case "$one" , "$all" , "$none" , "$any" :
334
- ref := chunk .Function .Binding
335
- listChunk := code .Chunk (ref )
336
- listType = types .Type (listChunk .Type ()).Child ().Label ()
321
+ code := bundle .CodeV2
322
+ var block * llx.Block
323
+ var funBlock * llx.Block
324
+ if blockRef , ok := bundle .Ref2CodeID [codeID ]; ok {
325
+ block = code .Block (blockRef )
326
+ }
327
+ if len (block .Entrypoints ) > 0 {
328
+ ep := block .Entrypoints [0 ]
329
+ chunk := code .Chunk (ep )
330
+ switch chunk .Id {
331
+ case "{}" :
332
+ arg := chunk .Function .Args [0 ]
333
+ fref := arg .RawData ().Value .(uint64 )
334
+ funBlock = bundle .CodeV2 .Block (fref )
335
+ case "$one" , "$all" , "$none" , "$any" :
336
+ ref := chunk .Function .Binding
337
+ listChunk := code .Chunk (ref )
338
+ listType = types .Type (listChunk .Type ()).Child ().Label ()
339
+ }
340
+ }
341
+
342
+ // collect all checksums that will be considered for printing of this
343
+ // block's data
344
+ dataChecksums := []string {}
345
+
346
+ // We generally prefer to directly access the function block and
347
+ // collect only the entrypoints. The raw data contains both entrypoints
348
+ // and datapoints and the latter are only needed to provide additional
349
+ // information on the output.
350
+ if funBlock != nil && len (funBlock .Entrypoints ) > 0 {
351
+ for _ , ep := range funBlock .Entrypoints {
352
+ csum := code .Checksums [ep ]
353
+ if _ , ok := bundle .Labels .Labels [csum ]; ok {
354
+ dataChecksums = append (dataChecksums , csum )
355
+ }
356
+ }
357
+ } else {
358
+ keys := sortx .Keys (data )
359
+ for i := range keys {
360
+ if _ , ok := bundle .Labels .Labels [keys [i ]]; ok {
361
+ dataChecksums = append (dataChecksums , keys [i ])
362
+ }
363
+ }
337
364
}
338
365
339
366
nonDefaultFields := []string {}
@@ -345,7 +372,7 @@ func (print *Printer) refMap(typ types.Type, data map[string]interface{}, codeID
345
372
}
346
373
}
347
374
348
- for _ , k := range labeledKeys {
375
+ for _ , k := range dataChecksums {
349
376
if k == "_" {
350
377
continue
351
378
}
@@ -371,8 +398,34 @@ func (print *Printer) refMap(typ types.Type, data map[string]interface{}, codeID
371
398
372
399
if len (nonDefaultFields ) > 0 {
373
400
res .WriteString ("{\n " )
401
+ skipFields := map [string ]struct {}{}
402
+ for _ , k := range nonDefaultFields {
403
+ if ref , ok := bundle .Ref2CodeID [k ]; ok {
404
+ skip := []string {}
405
+ assessment := code .Entrypoint2Assessment (bundle .CodeBundle , ref , func (s string ) (* llx.RawResult , bool ) {
406
+ found , ok := data [s ]
407
+ if ! ok {
408
+ return nil , false
409
+ }
410
+ skip = append (skip , s )
411
+ return & llx.RawResult {Data : found .(* llx.RawData ), CodeID : codeID }, true
412
+ })
413
+ if assessment != nil {
414
+ res .WriteString (indent )
415
+ res .WriteString (" " )
416
+ res .WriteString (print .assessment (bundle , assessment , indent + " " ))
417
+ res .WriteByte ('\n' )
418
+ for _ , v := range skip {
419
+ skipFields [v ] = struct {}{}
420
+ }
421
+
422
+ continue
423
+ }
424
+ }
425
+ }
426
+
374
427
for _ , k := range nonDefaultFields {
375
- if k == "_" {
428
+ if _ , ok := skipFields [ k ]; ok {
376
429
continue
377
430
}
378
431
@@ -404,7 +457,7 @@ func (print *Printer) refMap(typ types.Type, data map[string]interface{}, codeID
404
457
return res .String ()
405
458
}
406
459
407
- func (print * Printer ) stringMap (typ types.Type , data map [string ]interface {}, codeID string , bundle * llx.CodeBundle , indent string ) string {
460
+ func (print * Printer ) stringMap (typ types.Type , data map [string ]interface {}, codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
408
461
if len (data ) == 0 {
409
462
return "{}"
410
463
}
@@ -423,7 +476,7 @@ func (print *Printer) stringMap(typ types.Type, data map[string]interface{}, cod
423
476
return res .String ()
424
477
}
425
478
426
- func (print * Printer ) dict (typ types.Type , raw interface {}, codeID string , bundle * llx.CodeBundle , indent string ) string {
479
+ func (print * Printer ) dict (typ types.Type , raw interface {}, codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
427
480
if raw == nil {
428
481
return print .Secondary ("null" )
429
482
}
@@ -488,7 +541,7 @@ func (print *Printer) dict(typ types.Type, raw interface{}, codeID string, bundl
488
541
}
489
542
}
490
543
491
- func (print * Printer ) intMap (typ types.Type , data map [int ]interface {}, codeID string , bundle * llx.CodeBundle , indent string ) string {
544
+ func (print * Printer ) intMap (typ types.Type , data map [int ]interface {}, codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
492
545
var res strings.Builder
493
546
res .WriteString ("{\n " )
494
547
@@ -515,7 +568,7 @@ func isCodeBlock(codeID string, bundle *llx.CodeBundle) bool {
515
568
return ok
516
569
}
517
570
518
- func (print * Printer ) resourceContext (data any , checksum string , bundle * llx.CodeBundle , indent string ) (string , bool ) {
571
+ func (print * Printer ) resourceContext (data any , checksum string , bundle * llx.ExpandedCodeBundle , indent string ) (string , bool ) {
519
572
m , ok := data .(map [string ]any )
520
573
if ! ok {
521
574
return "" , false
@@ -577,7 +630,7 @@ func (print *Printer) resourceContext(data any, checksum string, bundle *llx.Cod
577
630
return r , true
578
631
}
579
632
580
- func (print * Printer ) autoExpand (blockRef uint64 , data interface {}, bundle * llx.CodeBundle , indent string ) string {
633
+ func (print * Printer ) autoExpand (blockRef uint64 , data interface {}, bundle * llx.ExpandedCodeBundle , indent string ) string {
581
634
var res strings.Builder
582
635
583
636
if arr , ok := data .([]interface {}); ok {
@@ -675,7 +728,7 @@ func (print *Printer) autoExpand(blockRef uint64, data interface{}, bundle *llx.
675
728
return res .String ()
676
729
}
677
730
678
- func (print * Printer ) Data (typ types.Type , data interface {}, codeID string , bundle * llx.CodeBundle , indent string ) string {
731
+ func (print * Printer ) Data (typ types.Type , data interface {}, codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
679
732
if typ .NotSet () {
680
733
return "no data available"
681
734
}
@@ -781,7 +834,7 @@ func (print *Printer) Data(typ types.Type, data interface{}, codeID string, bund
781
834
return llx .ScoreString (data .([]byte ))
782
835
783
836
case types .Block :
784
- return print .refMap (typ , data .(map [string ]interface {} ), codeID , bundle , indent )
837
+ return print .block (typ , data .(map [string ]any ), codeID , bundle , indent )
785
838
786
839
case types .Version :
787
840
return print .Secondary (data .(string ))
@@ -837,7 +890,7 @@ func (print *Printer) Data(typ types.Type, data interface{}, codeID string, bund
837
890
}
838
891
839
892
// DataWithLabel prints RawData into a string
840
- func (print * Printer ) DataWithLabel (r * llx.RawData , codeID string , bundle * llx.CodeBundle , indent string ) string {
893
+ func (print * Printer ) DataWithLabel (r * llx.RawData , codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
841
894
b := strings.Builder {}
842
895
if r .Error != nil {
843
896
b .WriteString (print .Error (strings .TrimSpace (r .Error .Error ())))
@@ -871,7 +924,7 @@ func (print *Printer) CompilerStats(stats mqlc.CompilerStats) string {
871
924
}
872
925
873
926
// CodeBundle prints the contents of the MQL query
874
- func (print * Printer ) CodeBundle (bundle * llx.CodeBundle ) string {
927
+ func (print * Printer ) CodeBundle (bundle * llx.ExpandedCodeBundle ) string {
875
928
var res strings.Builder
876
929
877
930
res .WriteString (print .CodeV2 (bundle .CodeV2 , bundle , "" ))
@@ -884,7 +937,7 @@ func (print *Printer) CodeBundle(bundle *llx.CodeBundle) string {
884
937
return res .String ()
885
938
}
886
939
887
- func (print * Printer ) CodeV2 (code * llx.CodeV2 , bundle * llx.CodeBundle , indent string ) string {
940
+ func (print * Printer ) CodeV2 (code * llx.CodeV2 , bundle * llx.ExpandedCodeBundle , indent string ) string {
888
941
var res strings.Builder
889
942
indent += " "
890
943
@@ -903,6 +956,18 @@ func (print *Printer) CodeV2(code *llx.CodeV2, bundle *llx.CodeBundle, indent st
903
956
}
904
957
res .WriteString ("]\n " )
905
958
959
+ if len (block .Datapoints ) > 0 {
960
+ res .WriteString (indent )
961
+ res .WriteString ("datapoints: [" )
962
+ for idx , ep := range block .Datapoints {
963
+ res .WriteString (fmt .Sprintf ("<%d,%d>" , ep >> 32 , ep & 0xFFFFFFFF ))
964
+ if idx != len (block .Datapoints )- 1 {
965
+ res .WriteString (" " )
966
+ }
967
+ }
968
+ res .WriteString ("]\n " )
969
+ }
970
+
906
971
for j := range block .Chunks {
907
972
res .WriteString (" " )
908
973
print .chunkV2 (j , block .Chunks [j ], block , bundle , indent , & res )
@@ -912,7 +977,7 @@ func (print *Printer) CodeV2(code *llx.CodeV2, bundle *llx.CodeBundle, indent st
912
977
return res .String ()
913
978
}
914
979
915
- func (print * Printer ) chunkV2 (idx int , chunk * llx.Chunk , block * llx.Block , bundle * llx.CodeBundle , indent string , w * strings.Builder ) {
980
+ func (print * Printer ) chunkV2 (idx int , chunk * llx.Chunk , block * llx.Block , bundle * llx.ExpandedCodeBundle , indent string , w * strings.Builder ) {
916
981
sidx := strconv .Itoa (idx + 1 ) + ": "
917
982
918
983
switch chunk .Call {
@@ -948,7 +1013,7 @@ func (print *Printer) chunkV2(idx int, chunk *llx.Chunk, block *llx.Block, bundl
948
1013
w .WriteString ("\n " )
949
1014
}
950
1015
951
- func (print * Printer ) functionV2 (f * llx.Function , codeID string , bundle * llx.CodeBundle , indent string ) string {
1016
+ func (print * Printer ) functionV2 (f * llx.Function , codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
952
1017
argsStr := ""
953
1018
if len (f .Args ) > 0 {
954
1019
argsStr = " (" + strings .TrimSpace (print .primitives (f .Args , codeID , bundle , indent )) + ")"
@@ -960,7 +1025,7 @@ func (print *Printer) functionV2(f *llx.Function, codeID string, bundle *llx.Cod
960
1025
argsStr
961
1026
}
962
1027
963
- func (print * Printer ) primitives (list []* llx.Primitive , codeID string , bundle * llx.CodeBundle , indent string ) string {
1028
+ func (print * Printer ) primitives (list []* llx.Primitive , codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
964
1029
if len (list ) == 0 {
965
1030
return ""
966
1031
}
@@ -978,7 +1043,7 @@ func (print *Printer) primitives(list []*llx.Primitive, codeID string, bundle *l
978
1043
}
979
1044
980
1045
// Primitive prints the llx primitive to a string
981
- func (print * Printer ) Primitive (primitive * llx.Primitive , codeID string , bundle * llx.CodeBundle , indent string ) string {
1046
+ func (print * Printer ) Primitive (primitive * llx.Primitive , codeID string , bundle * llx.ExpandedCodeBundle , indent string ) string {
982
1047
if primitive == nil {
983
1048
return "?"
984
1049
}
0 commit comments