diff --git a/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts b/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts index 00b9d44..95b4daa 100644 --- a/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts +++ b/packages/grafana-data/src/transformations/matchers/nameMatcher.test.ts @@ -456,6 +456,36 @@ it('Support fallback multiple names matchers', () => { expect(matcher(frame.fields[1], frame, [])).toBeFalsy(); }); +it('Should only match the field named time when the frame has more time fields', () => { + const frame: DataFrame = { + fields: [ + { name: 'time', type: FieldType.time, config: {}, values: [1, 2] }, + { name: 'Shifted Time', type: FieldType.time, config: {}, values: [3, 4] }, + { name: 'A-series', type: FieldType.number, config: {}, values: [1, 2] }, + ], + length: 2, + }; + + const nameMatcher = getFieldMatcher({ + id: FieldMatcherID.byName, + options: 'time', + }); + expect(nameMatcher(frame.fields[0], frame, [frame])).toBeTruthy(); + expect(nameMatcher(frame.fields[1], frame, [frame])).toBeFalsy(); + expect(nameMatcher(frame.fields[2], frame, [frame])).toBeFalsy(); + + const namesMatcher = getFieldMatcher({ + id: FieldMatcherID.byNames, + options: { + mode: ByNamesMatcherMode.include, + names: ['time', 'A-series'], + }, + }); + expect(namesMatcher(frame.fields[0], frame, [frame])).toBeTruthy(); + expect(namesMatcher(frame.fields[1], frame, [frame])).toBeFalsy(); + expect(namesMatcher(frame.fields[2], frame, [frame])).toBeTruthy(); +}); + describe('Fields returned by query with refId', () => { it('Match all fields in frame with refId: A', () => { const data = [ diff --git a/packages/grafana-data/src/transformations/matchers/nameMatcher.ts b/packages/grafana-data/src/transformations/matchers/nameMatcher.ts index 2ab10da..03f1739 100644 --- a/packages/grafana-data/src/transformations/matchers/nameMatcher.ts +++ b/packages/grafana-data/src/transformations/matchers/nameMatcher.ts @@ -115,8 +115,16 @@ function fieldNameFallback(fields: Set) { ); }; } else if (fields.has('Time') || fields.has('time')) { - fallback = (field: Field, frame: DataFrame) => { - return frame.meta?.typeVersion == null && field.type === FieldType.time; + const timeNames = ['Time', 'time'].filter((name) => fields.has(name)); + fallback = (field: Field, frame: DataFrame, allFrames: DataFrame[]) => { + return ( + frame.meta?.typeVersion == null && + field.type === FieldType.time && + // A field that already carries the name is matched directly, so other time fields must not be pulled in + !frame.fields.some( + (f) => timeNames.includes(f.name) || timeNames.includes(getFieldDisplayName(f, frame, allFrames)) + ) + ); }; }