@@ -18,7 +18,10 @@ import {
1818 promqlLabelSelectorItem ,
1919 promqlRangeSelectorItem ,
2020} from '../complete_items' ;
21- import { getPromqlFunctionSuggestions } from '../../definitions/utils/promql' ;
21+ import {
22+ getPromqlFunctionSuggestions ,
23+ getPromqlOperatorSuggestions ,
24+ } from '../../definitions/utils/promql' ;
2225import { ESQL_NUMBER_TYPES , ESQL_STRING_TYPES } from '../../definitions/types' ;
2326import { getPromqlParam , PROMQL_PARAM_NAMES } from './utils' ;
2427import { TIME_SYSTEM_PARAMS } from '../../definitions/utils/literals' ;
@@ -28,6 +31,7 @@ import type { ICommandCallbacks, ICommandContext } from '../types';
2831const promqlParamItems = getPromqlParamKeySuggestions ( ) ;
2932const promqlParamTexts = promqlParamItems . map ( ( { text } ) => text ) ;
3033const promqlFunctionSuggestions = getPromqlFunctionSuggestions ( ) ;
34+ const promqlOperatorLabels = getPromqlOperatorSuggestions ( ) . map ( ( { label } ) => label ) ;
3135const promqlFunctionLabels = promqlFunctionSuggestions . map ( ( { label } ) => label ) ;
3236const promqlFunctionWrappedTexts = promqlFunctionSuggestions
3337 . slice ( 0 , 1 )
@@ -465,6 +469,23 @@ describe('inside query', () => {
465469 } ) ;
466470 } ) ;
467471
472+ test ( 'suggests operators after complete expression inside aggregation' , async ( ) => {
473+ const query = 'PROMQL step="5m" sum(rate(doubleField[5m]) ' ;
474+
475+ await expectPromqlSuggestions ( query , {
476+ labelsContain : promqlOperatorLabels ,
477+ } ) ;
478+ } ) ;
479+
480+ test ( 'suggests operands (not operators) after binary operator inside aggregation' , async ( ) => {
481+ const query = 'PROMQL step="5m" sum(rate(doubleField[5m]) * ' ;
482+
483+ await expectPromqlSuggestions ( query , {
484+ labelsContain : [ 'rate' , 'sum' , 'avg' ] ,
485+ labelsNotContain : promqlOperatorLabels ,
486+ } ) ;
487+ } ) ;
488+
468489 test ( 'excludes user-defined columns from field suggestions' , async ( ) => {
469490 await expectPromqlSuggestions ( 'PROMQL sum( ' , {
470491 labelsNotContain : [ 'var0' , 'col0' ] ,
@@ -722,6 +743,62 @@ describe('after query (pipe suggestions)', () => {
722743 textsNotContain : [ pipeCompleteItem . text ] ,
723744 } ) ;
724745 } ) ;
746+
747+ test ( 'suggests RHS operand items after arithmetic operator at query boundary' , async ( ) => {
748+ const numericFields = getFieldNamesByType ( ESQL_NUMBER_TYPES , true ) ;
749+ const query = 'PROMQL step="5m" (sum(rate(doubleField[5m]))) + ' ;
750+
751+ await expectPromqlSuggestions (
752+ query ,
753+ {
754+ labelsContain : [ 'abs' , ...numericFields ] ,
755+ textsContain : [ '${0:0}' ] ,
756+ textsNotContain : [ pipeCompleteItem . text , promqlByCompleteItem . text ] ,
757+ } ,
758+ mockCallbacks
759+ ) ;
760+ } ) ;
761+
762+ test ( 'suggests RHS operand items after operator following selector with labels' , async ( ) => {
763+ const numericFields = getFieldNamesByType ( ESQL_NUMBER_TYPES , true ) ;
764+ const query = 'PROMQL step="5m" quantile(0, doubleField{label!~"value"} * ' ;
765+
766+ await expectPromqlSuggestions (
767+ query ,
768+ {
769+ labelsContain : numericFields ,
770+ textsContain : [ '${0:0}' ] ,
771+ } ,
772+ mockCallbacks
773+ ) ;
774+ } ) ;
775+
776+ test ( 'suggests RHS operand items after minus operator' , async ( ) => {
777+ const numericFields = getFieldNamesByType ( ESQL_NUMBER_TYPES , true ) ;
778+ const query = 'PROMQL step="5m" quantile(0, doubleField - ' ;
779+
780+ await expectPromqlSuggestions (
781+ query ,
782+ {
783+ labelsContain : numericFields ,
784+ textsContain : [ '${0:0}' ] ,
785+ } ,
786+ mockCallbacks
787+ ) ;
788+ } ) ;
789+
790+ test ( 'suggests label selector after metric name in RHS of operator' , async ( ) => {
791+ const query =
792+ 'PROMQL index=tsdb_index step="5m" sum(quantile(0.9, doubleField{label!~"value"} * doubleField ' ;
793+
794+ await expectPromqlSuggestions (
795+ query ,
796+ {
797+ textsContain : [ promqlLabelSelectorItem . text ] ,
798+ } ,
799+ mockCallbacks
800+ ) ;
801+ } ) ;
725802} ) ;
726803
727804describe ( 'param value suggestions' , ( ) => {
0 commit comments