Compare commits

..

1 Commits

Author SHA1 Message Date
Nikhil Soni
7f5bc3a4f3 refactor(traces-qb): drop logicalForResolvedColumn
Its family branch is unreachable now that select asks metadata first. Reaching
it requires FieldFor to succeed, which requires a context on the key (getColumn
declines an unspecified one); a key carrying a context has already been put to
MatchingLogicalFields, and only lands here when that came back empty. Calling
the same function again with the same arguments therefore cannot match, and the
method reduces to the single-member field it falls back to.

Instrumenting the branch and running the traces suites confirms it: no call
reaches it with a non-empty match set.

Assisted-by: Claude Opus 5
2026-08-25 16:27:43 +05:30

View File

@@ -353,19 +353,6 @@ func (m *fieldMapper) resolveColumnExprs(
return exprs, existExprs, columns, nil
}
// logicalForResolvedColumn returns the logical field(s) a directly-resolvable key names.
// Resolving to a column answers only that the key is addressable, not that it names one
// field: the scope JSON column resolves for both a declared path and a same-named scope
// attribute. Metadata is what tells those homes apart, so every match it reports is kept,
// the way the filter path keeps them. Only a name metadata does not know falls back to
// the key as given.
func (m *fieldMapper) logicalForResolvedColumn(ctx context.Context, orgID valuer.UUID, field *telemetrytypes.TelemetryFieldKey, keys map[string][]*telemetrytypes.TelemetryFieldKey) []*telemetrytypes.LogicalField {
if matches := querybuilder.MatchingLogicalFields(ctx, orgID, m.fl, field, keys); len(matches) > 0 {
return matches
}
return []*telemetrytypes.LogicalField{telemetrytypes.SingleLogicalField(field.Name, field)}
}
// upgradeToFamilies swaps single-member candidates for their family when the
// metadata map proves membership. Candidate order and every non-family
// candidate stay exactly as the legacy flow produced them; sibling candidates
@@ -426,19 +413,32 @@ func (m *fieldMapper) ColumnExpressionFor(
keys map[string][]*telemetrytypes.TelemetryFieldKey,
) (string, error) {
// Resolve the candidate logical field(s).
// Resolve the candidate logical field(s). A key carrying a context is asked of metadata
// first, the way the filter path asks: the probe below only answers whether a key
// resolves to a column and stands in for whether it names one field, so a column that
// resolves for either of two homes -- a declared scope path or a same-named scope
// attribute -- would be reported as resolved while still being ambiguous. A bare key
// cannot resolve through the probe at all (getColumn needs a context), so it already
// reaches CandidateKeys, which consults metadata itself, and is left alone here.
var candidates []*telemetrytypes.LogicalField
switch _, err := m.FieldFor(ctx, orgID, startNs, endNs, field); {
case err == nil:
candidates = m.logicalForResolvedColumn(ctx, orgID, field, keys)
case errors.Is(err, qbtypes.ErrColumnNotFound):
raw := m.CandidateKeys(ctx, orgID, field, nil, keys)
if len(raw) == 0 {
return "", errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "field `%s` not found", field.Name).WithSuggestions(errors.NewSuggestionsOnLevenshteinDistance(field.Name, errors.NounKeys, maps.Keys(keys))...)
if field.FieldContext != telemetrytypes.FieldContextUnspecified {
candidates = querybuilder.MatchingLogicalFields(ctx, orgID, m.fl, field, keys)
}
if len(candidates) == 0 {
switch _, err := m.FieldFor(ctx, orgID, startNs, endNs, field); {
case err == nil:
// Metadata knows nothing about this name (it was asked above, or the key is
// bare and cannot resolve here at all), so the column stands alone.
candidates = []*telemetrytypes.LogicalField{telemetrytypes.SingleLogicalField(field.Name, field)}
case errors.Is(err, qbtypes.ErrColumnNotFound):
raw := m.CandidateKeys(ctx, orgID, field, nil, keys)
if len(raw) == 0 {
return "", errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "field `%s` not found", field.Name).WithSuggestions(errors.NewSuggestionsOnLevenshteinDistance(field.Name, errors.NounKeys, maps.Keys(keys))...)
}
candidates = m.upgradeToFamilies(ctx, orgID, field, querybuilder.WrapAsLogicalFields(field.Name, raw), keys)
default:
return "", err
}
candidates = m.upgradeToFamilies(ctx, orgID, field, querybuilder.WrapAsLogicalFields(field.Name, raw), keys)
default:
return "", err
}
// Group-by/order (String) and aggregation (String/Float64): every candidate is