build(deps): bump github.com/CiscoM31/godata from 1.0.8 to 1.0.9

Bumps [github.com/CiscoM31/godata](https://github.com/CiscoM31/godata) from 1.0.8 to 1.0.9.
- [Release notes](https://github.com/CiscoM31/godata/releases)
- [Commits](https://github.com/CiscoM31/godata/compare/v1.0.8...v1.0.9)

---
updated-dependencies:
- dependency-name: github.com/CiscoM31/godata
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-12-08 06:17:00 +00:00
committed by Ralf Haferkamp
parent c767076313
commit 0ad8d25d0c
5 changed files with 115 additions and 74 deletions

2
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/owncloud/ocis/v2
go 1.21
require (
github.com/CiscoM31/godata v1.0.8
github.com/CiscoM31/godata v1.0.9
github.com/KimMachineGun/automemlimit v0.3.0
github.com/Masterminds/semver v1.5.0
github.com/MicahParks/keyfunc v1.9.0

4
go.sum
View File

@@ -793,8 +793,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CiscoM31/godata v1.0.8 h1:ZhPjm1dSwZWMUvb33P4bcVm048iiQ1wbncoCc9bLChQ=
github.com/CiscoM31/godata v1.0.8/go.mod h1:ZMiT6JuD3Rm83HEtiTx4JEChsd25YCrxchKGag/sdTc=
github.com/CiscoM31/godata v1.0.9 h1:7ovi2efjWb6RloX96AJqBB9eyIfBdarzj8kzg7glPC4=
github.com/CiscoM31/godata v1.0.9/go.mod h1:ZMiT6JuD3Rm83HEtiTx4JEChsd25YCrxchKGag/sdTc=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/KimMachineGun/automemlimit v0.3.0 h1:khgwM5ESVN85cE6Bq2ozMAAWDfrOEwQ51D/YlmThE04=

View File

@@ -42,21 +42,23 @@ const (
ExpressionTokenFunc // Function, e.g. contains, substring...
ExpressionTokenLambdaNav // "/" token when used in lambda expression, e.g. tags/any()
ExpressionTokenLambda // [10] any(), all() lambda functions
ExpressionTokenCase // A case() statement. See https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_case
ExpressionTokenCasePair // A case statement expression pair [ <boolean expression> : <value expression> ]
ExpressionTokenNull //
ExpressionTokenIt // The '$it' token
ExpressionTokenRoot // The '$root' token
ExpressionTokenRoot // [15] The '$root' token
ExpressionTokenFloat // A floating point value.
ExpressionTokenInteger // [15] An integer value
ExpressionTokenInteger // An integer value
ExpressionTokenString // SQUOTE *( SQUOTE-in-string / pchar-no-SQUOTE ) SQUOTE
ExpressionTokenDate // A date value
ExpressionTokenTime // A time value
ExpressionTokenTime // [20] A time value
ExpressionTokenDateTime // A date-time value
ExpressionTokenBoolean // [20]
ExpressionTokenLiteral //
ExpressionTokenBoolean // A literal boolean value
ExpressionTokenLiteral // A literal non-boolean value
ExpressionTokenDuration // duration = [ "duration" ] SQUOTE durationValue SQUOTE
ExpressionTokenGuid // A 128-bit GUID
ExpressionTokenGuid // [25] A 128-bit GUID
ExpressionTokenAssignement // The '=' assignement for function arguments.
ExpressionTokenGeographyPolygon // [25]
ExpressionTokenGeographyPolygon //
ExpressionTokenGeometryPolygon //
expressionTokenLast
)
@@ -74,6 +76,8 @@ func (e ExpressionTokenType) String() string {
"ExpressionTokenFunc",
"ExpressionTokenLambdaNav",
"ExpressionTokenLambda",
"ExpressionTokenCase",
"ExpressionTokenCasePair",
"ExpressionTokenNull",
"ExpressionTokenIt",
"ExpressionTokenRoot",
@@ -121,23 +125,8 @@ func (p *ExpressionParser) ParseExpressionString(ctx context.Context, expression
if tree == nil || tree.Token == nil {
return nil, BadRequestError("Expression cannot be nil")
}
if p.ExpectBoolExpr {
switch tree.Token.Type {
case ExpressionTokenBoolean:
// Valid boolean expression
case ExpressionTokenLogical:
// eq|ne|gt|ge|lt|le|and|or|not|has|in
// Valid boolean expression
case ExpressionTokenFunc:
// We need to know the return type of the function.
// TODO
case ExpressionTokenLambdaNav:
// Lambda Navigation.
// Valid boolean expression
default:
// Not a boolean expression
return nil, BadRequestError("Expression does not return a boolean value")
}
if p.ExpectBoolExpr && !p.isBooleanExpression(tree.Token) {
return nil, BadRequestError("Expression does not return a boolean value")
}
return &GoDataExpression{tree, expression}, nil
}
@@ -220,6 +209,7 @@ func NewExpressionTokenizer() *Tokenizer {
// anyExpr = "any" OPEN BWS [ lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr ] BWS CLOSE
// allExpr = "all" OPEN BWS lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr BWS CLOSE
t.Add("(?i)^(?P<token>(any|all))[\\s(]", ExpressionTokenLambda)
t.Add("(?i)^(?P<token>(case))[\\s(]", ExpressionTokenCase)
t.Add("^null", ExpressionTokenNull)
t.Add("^\\$it", ExpressionTokenIt)
t.Add("^\\$root", ExpressionTokenRoot)
@@ -288,52 +278,58 @@ func NewExpressionParser() *ExpressionParser {
parser.DefineOperator("and", 2, OpAssociationLeft, 2)
parser.DefineOperator("or", 2, OpAssociationLeft, 1)
parser.DefineOperator("=", 2, OpAssociationRight, 0) // Function argument assignment. E.g. MyFunc(Arg1='abc')
parser.DefineFunction("contains", []int{2})
parser.DefineFunction("endswith", []int{2})
parser.DefineFunction("startswith", []int{2})
parser.DefineFunction("exists", []int{2})
parser.DefineFunction("length", []int{1})
parser.DefineFunction("indexof", []int{2})
parser.DefineFunction("substring", []int{2, 3})
parser.DefineFunction("substringof", []int{2})
parser.DefineFunction("tolower", []int{1})
parser.DefineFunction("toupper", []int{1})
parser.DefineFunction("trim", []int{1})
parser.DefineFunction("concat", []int{2})
parser.DefineFunction("year", []int{1})
parser.DefineFunction("month", []int{1})
parser.DefineFunction("day", []int{1})
parser.DefineFunction("hour", []int{1})
parser.DefineFunction("minute", []int{1})
parser.DefineFunction("second", []int{1})
parser.DefineFunction("fractionalseconds", []int{1})
parser.DefineFunction("date", []int{1})
parser.DefineFunction("time", []int{1})
parser.DefineFunction("totaloffsetminutes", []int{1})
parser.DefineFunction("now", []int{0})
parser.DefineFunction("maxdatetime", []int{0})
parser.DefineFunction("mindatetime", []int{0})
parser.DefineFunction("totalseconds", []int{1})
parser.DefineFunction("round", []int{1})
parser.DefineFunction("floor", []int{1})
parser.DefineFunction("ceiling", []int{1})
parser.DefineFunction("isof", []int{1, 2}) // isof function can take one or two arguments.
parser.DefineFunction("cast", []int{2})
parser.DefineFunction("geo.distance", []int{2})
parser.DefineFunction("contains", []int{2}, true)
parser.DefineFunction("endswith", []int{2}, true)
parser.DefineFunction("startswith", []int{2}, true)
parser.DefineFunction("exists", []int{2}, true)
parser.DefineFunction("length", []int{1}, false)
parser.DefineFunction("indexof", []int{2}, false)
parser.DefineFunction("substring", []int{2, 3}, false)
parser.DefineFunction("substringof", []int{2}, false)
parser.DefineFunction("tolower", []int{1}, false)
parser.DefineFunction("toupper", []int{1}, false)
parser.DefineFunction("trim", []int{1}, false)
parser.DefineFunction("concat", []int{2}, false)
parser.DefineFunction("year", []int{1}, false)
parser.DefineFunction("month", []int{1}, false)
parser.DefineFunction("day", []int{1}, false)
parser.DefineFunction("hour", []int{1}, false)
parser.DefineFunction("minute", []int{1}, false)
parser.DefineFunction("second", []int{1}, false)
parser.DefineFunction("fractionalseconds", []int{1}, false)
parser.DefineFunction("date", []int{1}, false)
parser.DefineFunction("time", []int{1}, false)
parser.DefineFunction("totaloffsetminutes", []int{1}, false)
parser.DefineFunction("now", []int{0}, false)
parser.DefineFunction("maxdatetime", []int{0}, false)
parser.DefineFunction("mindatetime", []int{0}, false)
parser.DefineFunction("totalseconds", []int{1}, false)
parser.DefineFunction("round", []int{1}, false)
parser.DefineFunction("floor", []int{1}, false)
parser.DefineFunction("ceiling", []int{1}, false)
parser.DefineFunction("isof", []int{1, 2}, true) // isof function can take one or two arguments.
parser.DefineFunction("cast", []int{2}, false)
parser.DefineFunction("geo.distance", []int{2}, false)
// The geo.intersects function has the following signatures:
// Edm.Boolean geo.intersects(Edm.GeographyPoint,Edm.GeographyPolygon)
// Edm.Boolean geo.intersects(Edm.GeometryPoint,Edm.GeometryPolygon)
// The geo.intersects function returns true if the specified point lies within the interior
// or on the boundary of the specified polygon, otherwise it returns false.
parser.DefineFunction("geo.intersects", []int{2})
parser.DefineFunction("geo.intersects", []int{2}, false)
// The geo.length function has the following signatures:
// Edm.Double geo.length(Edm.GeographyLineString)
// Edm.Double geo.length(Edm.GeometryLineString)
// The geo.length function returns the total length of its line string parameter
// in the coordinate reference system signified by its SRID.
parser.DefineFunction("geo.length", []int{1})
parser.DefineFunction("any", []int{0, 2}) // 'any' can take either zero or one argument.
parser.DefineFunction("all", []int{2})
parser.DefineFunction("geo.length", []int{1}, false)
// 'any' can take either zero or two arguments with the later having the form any(d:d/Prop eq 1).
// Godata interprets the colon as an argument delimiter and considers the function to have two arguments.
parser.DefineFunction("any", []int{0, 2}, true)
// 'all' requires two arguments of a form similar to 'any'.
parser.DefineFunction("all", []int{2}, true)
// Define 'case' as a function accepting 1-10 arguments. Each argument is a pair of expressions separated by a colon.
// See https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_case
parser.DefineFunction("case", []int{1,2,3,4,5,6,7,8,9,10}, true)
return parser
}

View File

@@ -233,6 +233,7 @@ func (o *Operator) WithListExprPreference(v bool) *Operator {
type Function struct {
Token string // The function token
Params []int // The number of parameters this function accepts
ReturnsBool bool // Indicates if the function has a boolean return value
}
type ParseNode struct {
@@ -291,11 +292,12 @@ func (p *Parser) DefineOperator(token string, operands, assoc, precedence int) *
return op
}
// DefineFunction adds a function to the language
// params is the number of parameters this function accepts
func (p *Parser) DefineFunction(token string, params []int) *Function {
// DefineFunction adds a function to the language.
// - params is the number of parameters this function accepts
// - returnsBool indicates if the function has a boolean return value
func (p *Parser) DefineFunction(token string, params []int, returnsBool bool) *Function {
sort.Sort(sort.Reverse(sort.IntSlice(params)))
f := &Function{token, params}
f := &Function{token, params, returnsBool}
p.Functions[token] = f
return f
}
@@ -304,6 +306,7 @@ func (p *Parser) DefineFunction(token string, params []int) *Function {
type CustomFunctionInput struct {
Name string // case-insensitive function name
NumParams []int // number of allowed parameters
ReturnsBool bool // indicates if the function has a boolean return value
}
// DefineCustomFunctions introduces additional function names to be considered as legal function
@@ -322,7 +325,7 @@ func DefineCustomFunctions(functions []CustomFunctionInput) error {
return fmt.Errorf("custom function '%s' may not override odata operator", name)
}
GlobalExpressionParser.DefineFunction(name, v.NumParams)
GlobalExpressionParser.DefineFunction(name, v.NumParams, v.ReturnsBool)
funcNames = append(funcNames, name)
}
@@ -362,6 +365,29 @@ func (p *Parser) isOperator(token *Token) bool {
return ok
}
// isBooleanExpression returns True when the expression token 't' has a resulting boolean value
func (p *Parser) isBooleanExpression(t *Token) bool {
switch t.Type {
case ExpressionTokenBoolean:
// Valid boolean expression
case ExpressionTokenLogical:
// eq|ne|gt|ge|lt|le|and|or|not|has|in
// Valid boolean expression
case ExpressionTokenFunc:
// Depends on function return type
f := p.Functions[t.Value]
if !f.ReturnsBool {
return false
}
case ExpressionTokenLambdaNav:
// Lambda Navigation.
// Valid boolean expression
default:
return false
}
return true
}
// InfixToPostfix parses the input string of tokens using the given definitions of operators
// and functions.
// Everything else is assumed to be a literal.
@@ -653,12 +679,31 @@ func (p *Parser) PostfixToTree(ctx context.Context, queue *tokenQueue) (*ParseNo
return nil, fmt.Errorf("expected list expression token, got '%v'", n.Token.Type)
}
// Get function parameters.
// Some functions, e.g. substring, can take a variable number of arguments.
for _, c := range n.Children {
c.Parent = node
if node.Token.Type == ExpressionTokenCase {
// Create argument pairs for case() statement by translating flat list into pairs
if len(n.Children)%2 != 0 {
return nil, fmt.Errorf("expected even number of comma-separated arguments to case statement")
}
for i:=0; i<len(n.Children); i+=2 {
if !p.isBooleanExpression(n.Children[i].Token) {
return nil, fmt.Errorf("expected boolean expression in case statement")
}
c := &ParseNode{
Token: &Token{Type: ExpressionTokenCasePair},
Parent: node,
Children: []*ParseNode{n.Children[i],n.Children[i+1]},
}
node.Children = append(node.Children, c)
}
} else {
// Collapse function arguments as direct children of function node
for _, c := range n.Children {
c.Parent = node
}
node.Children = n.Children
}
node.Children = n.Children
// Some functions, e.g. substring, can take a variable number of arguments. Enforce legal number of arguments
foundMatch := false
f := p.Functions[node.Token.Value]
for _, expectedArgCount := range f.Params {

2
vendor/modules.txt vendored
View File

@@ -8,7 +8,7 @@ github.com/Azure/go-ntlmssp
## explicit; go 1.16
github.com/BurntSushi/toml
github.com/BurntSushi/toml/internal
# github.com/CiscoM31/godata v1.0.8
# github.com/CiscoM31/godata v1.0.9
## explicit; go 1.19
github.com/CiscoM31/godata
# github.com/KimMachineGun/automemlimit v0.3.0