dynamo-browse/internal/dynamo-browse/models/queryexpr/binops.go
Leon Mika a1717572c5
issue-22: Fixed expressions so that queries will be executed as queries (#25)
Augmented expressions so that queries that can be executed as queries on DynamoDB can be done so.
Also added an IR tree which is a simplified representation of the AST and will be used to plan the query.
2022-09-19 21:14:03 +10:00

82 lines
2 KiB
Go

package queryexpr
import (
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
"github.com/lmika/audax/internal/dynamo-browse/models"
"github.com/pkg/errors"
)
func (a *astBinOp) evalToIR(info *models.TableInfo) (irAtom, error) {
v, err := a.Value.goValue()
if err != nil {
return nil, err
}
switch a.Op {
case "=":
return irFieldEq{name: a.Name, value: v}, nil
case "^=":
strValue, isStrValue := v.(string)
if !isStrValue {
return nil, errors.New("operand '^=' must be string")
}
return irFieldBeginsWith{name: a.Name, prefix: strValue}, nil
}
return nil, errors.Errorf("unrecognised operator: %v", a.Op)
}
func (a *astBinOp) String() string {
return a.Name + a.Op + a.Value.String()
}
type irFieldEq struct {
name string
value any
}
func (a irFieldEq) canBeExecutedAsQuery(info *models.TableInfo, qci *queryCalcInfo) bool {
if a.name == info.Keys.PartitionKey || a.name == info.Keys.SortKey {
return qci.addKey(info, a.name)
}
return false
}
func (a irFieldEq) calcQueryForScan(info *models.TableInfo) (expression.ConditionBuilder, error) {
return expression.Name(a.name).Equal(expression.Value(a.value)), nil
}
func (a irFieldEq) calcQueryForQuery(info *models.TableInfo) (expression.KeyConditionBuilder, error) {
return expression.Key(a.name).Equal(expression.Value(a.value)), nil
}
func (a irFieldEq) operandFieldName() string {
return a.name
}
type irFieldBeginsWith struct {
name string
prefix string
}
func (a irFieldBeginsWith) canBeExecutedAsQuery(info *models.TableInfo, qci *queryCalcInfo) bool {
if a.name == info.Keys.SortKey {
return qci.addKey(info, a.name)
}
return false
}
func (a irFieldBeginsWith) calcQueryForScan(info *models.TableInfo) (expression.ConditionBuilder, error) {
return expression.Name(a.name).BeginsWith(a.prefix), nil
}
func (a irFieldBeginsWith) calcQueryForQuery(info *models.TableInfo) (expression.KeyConditionBuilder, error) {
return expression.Key(a.name).BeginsWith(a.prefix), nil
}
func (a irFieldBeginsWith) operandFieldName() string {
return a.name
}