github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/query/parser/promql/options.go (about)

     1  // Copyright (c) 2019 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package promql
    22  
    23  import (
    24  	"time"
    25  
    26  	"github.com/m3db/m3/src/query/models"
    27  	"github.com/m3db/m3/src/query/parser"
    28  	xclock "github.com/m3db/m3/src/x/clock"
    29  
    30  	"github.com/prometheus/prometheus/model/labels"
    31  	pql "github.com/prometheus/prometheus/promql/parser"
    32  )
    33  
    34  // ParseFunctionExpr parses arguments to a function expression, returning
    35  // a function, a bool indicating whether the function is a noop,
    36  // and any errors during execution.
    37  type ParseFunctionExpr func(
    38  	name string,
    39  	argValues []interface{},
    40  	stringValues []string,
    41  	hasArgValue bool,
    42  	inner string,
    43  	tagOptions models.TagOptions,
    44  ) (parser.Params, bool, error)
    45  
    46  // ParseFn is a function that parses a query to a Prometheus expression.
    47  type ParseFn func(query string) (pql.Expr, error)
    48  
    49  func defaultParseFn(query string) (pql.Expr, error) {
    50  	return pql.ParseExpr(query)
    51  }
    52  
    53  // MetricSelectorFn is a function that parses a query to Prometheus selectors.
    54  type MetricSelectorFn func(query string) ([]*labels.Matcher, error)
    55  
    56  func defaultMetricSelectorFn(query string) ([]*labels.Matcher, error) {
    57  	return pql.ParseMetricSelector(query)
    58  }
    59  
    60  func defaultNowFn() time.Time {
    61  	return time.Now()
    62  }
    63  
    64  // ParseOptions are options for the Prometheus parser.
    65  type ParseOptions interface {
    66  	// ParseFn gets the parse function.
    67  	ParseFn() ParseFn
    68  	// SetParseFn sets the parse function.
    69  	SetParseFn(ParseFn) ParseOptions
    70  
    71  	// MetricSelectorFn gets the metric selector function.
    72  	MetricSelectorFn() MetricSelectorFn
    73  	// SetMetricSelectorFn sets the metric selector function.
    74  	SetMetricSelectorFn(MetricSelectorFn) ParseOptions
    75  
    76  	// FunctionParseExpr gets the parsing function.
    77  	FunctionParseExpr() ParseFunctionExpr
    78  	// SetFunctionParseExpr sets the parsing function.
    79  	SetFunctionParseExpr(ParseFunctionExpr) ParseOptions
    80  
    81  	// NowFn gets the now function.
    82  	NowFn() xclock.NowFn
    83  	// SetNowFn sets the now function.
    84  	SetNowFn(xclock.NowFn) ParseOptions
    85  
    86  	// RequireStartEndTime returns whether requests require a start and end time.
    87  	RequireStartEndTime() bool
    88  	// SetRequireStartEndTime sets whether requests require a start and end time.
    89  	SetRequireStartEndTime(bool) ParseOptions
    90  }
    91  
    92  type parseOptions struct {
    93  	parseFn             ParseFn
    94  	selectorFn          MetricSelectorFn
    95  	fnParseExpr         ParseFunctionExpr
    96  	nowFn               xclock.NowFn
    97  	requireStartEndTime bool
    98  }
    99  
   100  // NewParseOptions creates a new parse options.
   101  func NewParseOptions() ParseOptions {
   102  	return &parseOptions{
   103  		parseFn:     defaultParseFn,
   104  		selectorFn:  defaultMetricSelectorFn,
   105  		fnParseExpr: NewFunctionExpr,
   106  		nowFn:       defaultNowFn,
   107  	}
   108  }
   109  
   110  func (o *parseOptions) ParseFn() ParseFn {
   111  	return o.parseFn
   112  }
   113  
   114  func (o *parseOptions) SetParseFn(f ParseFn) ParseOptions {
   115  	opts := *o
   116  	opts.parseFn = f
   117  	return &opts
   118  }
   119  
   120  func (o *parseOptions) MetricSelectorFn() MetricSelectorFn {
   121  	return o.selectorFn
   122  }
   123  
   124  func (o *parseOptions) SetMetricSelectorFn(f MetricSelectorFn) ParseOptions {
   125  	opts := *o
   126  	opts.selectorFn = f
   127  	return &opts
   128  }
   129  
   130  func (o *parseOptions) FunctionParseExpr() ParseFunctionExpr {
   131  	return o.fnParseExpr
   132  }
   133  
   134  func (o *parseOptions) SetFunctionParseExpr(f ParseFunctionExpr) ParseOptions {
   135  	opts := *o
   136  	opts.fnParseExpr = f
   137  	return &opts
   138  }
   139  
   140  func (o *parseOptions) NowFn() xclock.NowFn {
   141  	return o.nowFn
   142  }
   143  
   144  func (o *parseOptions) SetNowFn(f xclock.NowFn) ParseOptions {
   145  	opts := *o
   146  	opts.nowFn = f
   147  	return &opts
   148  }
   149  
   150  func (o *parseOptions) RequireStartEndTime() bool {
   151  	return o.requireStartEndTime
   152  }
   153  
   154  func (o *parseOptions) SetRequireStartEndTime(r bool) ParseOptions {
   155  	opts := *o
   156  	opts.requireStartEndTime = r
   157  	return &opts
   158  }