Skip to content

Commit

Permalink
Refactor "WhereFilterClauseHook" to make it clearer (separating code …
Browse files Browse the repository at this point in the history
…into auxiliar functions)
  • Loading branch information
rogerlucena committed Oct 13, 2020
1 parent 2b9e4e4 commit f8c694c
Showing 1 changed file with 47 additions and 22 deletions.
69 changes: 47 additions & 22 deletions bql/semantic/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,45 @@ func whereObjectClause() ElementHook {
return hook
}

// addOperationToWorkingFilter takes the filter operation in its string format and tries to add the
// correspondent filter.Operation to workingFilter.
func addOperationToWorkingFilter(op string, workingFilter *FilterClause) error {
if workingFilter == nil {
return fmt.Errorf("could not add filter function %q to nil filter clause (which is still nil probably because a call to st.ResetWorkingFilterClause was not made before start processing the first filter clause)", op)
}
if !workingFilter.Operation.IsEmpty() {
return fmt.Errorf("invalid filter function %q on filter clause since already set to %q", op, workingFilter.Operation)
}
lowercaseOp := strings.ToLower(op)
if _, ok := filter.SupportedOperations[lowercaseOp]; !ok {
return fmt.Errorf("filter function %q on filter clause is not supported", op)
}

workingFilter.Operation = filter.SupportedOperations[lowercaseOp]
return nil
}

// addBindingToWorkingFilter takes the given binding and tries to add it to workingFilter.
func addBindingToWorkingFilter(bndg string, workingFilter *FilterClause) error {
if workingFilter == nil {
return fmt.Errorf("could not add binding %q to nil filter clause (which is still nil probably because a call to st.ResetWorkingFilterClause was not made before start processing the first filter clause)", bndg)
}
if workingFilter.Operation.IsEmpty() {
return fmt.Errorf("could not add binding %q to a filter clause that does not have a filter function previously set", bndg)
}
if workingFilter.Binding != "" {
return fmt.Errorf("invalid binding %q on filter clause since already set to %q", bndg, workingFilter.Binding)
}

workingFilter.Binding = bndg
return nil
}

// isValidFilterClause returns true if the given filter clause is valid and complete.
func isValidFilterClause(f *FilterClause) bool {
return f != nil && !f.Operation.IsEmpty() && f.Binding != ""
}

// whereFilterClause returns an element hook that updates the working filter clause and,
// if the filter clause is complete, populates the filters list of the statement.
func whereFilterClause() ElementHook {
Expand All @@ -683,36 +722,22 @@ func whereFilterClause() ElementHook {
}

tkn := ce.Token()
currFilter := st.WorkingFilter()
switch tkn.Type {
case lexer.ItemFilterFunction:
if currFilter == nil {
return nil, fmt.Errorf("could not add filter function %q to nil filter clause", tkn.Text)
}
if !currFilter.Operation.IsEmpty() {
return nil, fmt.Errorf("invalid filter function %q on filter clause since already set to %q", tkn.Text, currFilter.Operation)
}
lowercaseFilter := strings.ToLower(tkn.Text)
if _, ok := filter.SupportedOperations[lowercaseFilter]; !ok {
return nil, fmt.Errorf("filter function %q on filter clause is not supported", tkn.Text)
err := addOperationToWorkingFilter(tkn.Text, st.WorkingFilter())
if err != nil {
return nil, err
}
currFilter.Operation = filter.SupportedOperations[lowercaseFilter]
return hook, nil
case lexer.ItemBinding:
if currFilter == nil {
return nil, fmt.Errorf("could not add binding %q to nil filter clause", tkn.Text)
}
if currFilter.Operation.IsEmpty() {
return nil, fmt.Errorf("could not add binding %q to a filter clause that does not have a filter function previously set", tkn.Text)
}
if currFilter.Binding != "" {
return nil, fmt.Errorf("invalid binding %q on filter clause since already set to %q", tkn.Text, currFilter.Binding)
err := addBindingToWorkingFilter(tkn.Text, st.WorkingFilter())
if err != nil {
return nil, err
}
currFilter.Binding = tkn.Text
return hook, nil
case lexer.ItemRPar:
if currFilter == nil || currFilter.Operation.IsEmpty() || currFilter.Binding == "" {
return nil, fmt.Errorf("could not add invalid working filter %q to the statement filters list", currFilter)
if !isValidFilterClause(st.WorkingFilter()) {
return nil, fmt.Errorf("could not add invalid working filter %q to the statement filters list", st.WorkingFilter())
}
st.AddWorkingFilterClause()
}
Expand Down

0 comments on commit f8c694c

Please sign in to comment.