Fixed query expression so that 'true' and 'false' are now boolean literals
Also describe queries in the log file
This commit is contained in:
parent
700a1a2253
commit
aaf3c17934
|
@ -1,8 +1,48 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
|
import (
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
|
||||||
|
"github.com/lmika/audax/internal/dynamo-browse/models/itemrender"
|
||||||
|
)
|
||||||
|
|
||||||
type QueryExecutionPlan struct {
|
type QueryExecutionPlan struct {
|
||||||
CanQuery bool
|
CanQuery bool
|
||||||
Expression expression.Expression
|
Expression expression.Expression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (qep QueryExecutionPlan) Describe(dp DescribingPrinter) {
|
||||||
|
if qep.CanQuery {
|
||||||
|
dp.Println(" execute as: query")
|
||||||
|
} else {
|
||||||
|
dp.Println(" execute as: scan")
|
||||||
|
}
|
||||||
|
|
||||||
|
if keyCond := aws.ToString(qep.Expression.KeyCondition()); keyCond != "" {
|
||||||
|
dp.Printf(" key condition: %v", keyCond)
|
||||||
|
}
|
||||||
|
if cond := aws.ToString(qep.Expression.Condition()); cond != "" {
|
||||||
|
dp.Printf(" condition: %v", cond)
|
||||||
|
}
|
||||||
|
if filter := aws.ToString(qep.Expression.Filter()); filter != "" {
|
||||||
|
dp.Printf(" filter: %v", filter)
|
||||||
|
}
|
||||||
|
if names := qep.Expression.Names(); len(names) > 0 {
|
||||||
|
dp.Println(" names:")
|
||||||
|
for k, v := range names {
|
||||||
|
dp.Printf(" %v = %v", k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if values := qep.Expression.Values(); len(values) > 0 {
|
||||||
|
dp.Println(" values:")
|
||||||
|
for k, v := range values {
|
||||||
|
r := itemrender.ToRenderer(v)
|
||||||
|
dp.Printf(" %v (%v) = %v", k, r.TypeName(), r.StringValue())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribingPrinter interface {
|
||||||
|
Println(v ...any)
|
||||||
|
Printf(format string, v ...any)
|
||||||
|
}
|
||||||
|
|
|
@ -83,9 +83,13 @@ type astPlaceholder struct {
|
||||||
type astLiteralValue struct {
|
type astLiteralValue struct {
|
||||||
StringVal *string `parser:"@String"`
|
StringVal *string `parser:"@String"`
|
||||||
IntVal *int64 `parser:"| @Int"`
|
IntVal *int64 `parser:"| @Int"`
|
||||||
|
TrueBoolValue bool `parser:"| @KwdTrue"`
|
||||||
|
FalseBoolValue bool `parser:"| @KwdFalse"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var scanner = lexer.MustSimple([]lexer.SimpleRule{
|
var scanner = lexer.MustSimple([]lexer.SimpleRule{
|
||||||
|
{Name: "KwdTrue", Pattern: `true`},
|
||||||
|
{Name: "KwdFalse", Pattern: `false`},
|
||||||
{Name: "Eq", Pattern: `=|[\\^]=|[!]=`},
|
{Name: "Eq", Pattern: `=|[\\^]=|[!]=`},
|
||||||
{Name: "Cmp", Pattern: `<[=]?|>[=]?`},
|
{Name: "Cmp", Pattern: `<[=]?|>[=]?`},
|
||||||
{Name: "String", Pattern: `"(\\"|[^"])*"`},
|
{Name: "String", Pattern: `"(\\"|[^"])*"`},
|
||||||
|
|
|
@ -158,6 +158,14 @@ func TestModExpr_Query(t *testing.T) {
|
||||||
scanCase("greater or equal to value", `num >= 100`, `#0 >= :0`,
|
scanCase("greater or equal to value", `num >= 100`, `#0 >= :0`,
|
||||||
exprNameIsNumber(0, 0, "num", "100"),
|
exprNameIsNumber(0, 0, "num", "100"),
|
||||||
),
|
),
|
||||||
|
scanCase("is true", `bool = true`, `#0 = :0`,
|
||||||
|
exprName(0, "bool"),
|
||||||
|
exprValueIsBool(0, true),
|
||||||
|
),
|
||||||
|
scanCase("is false", `bool = false`, `#0 = :0`,
|
||||||
|
exprName(0, "bool"),
|
||||||
|
exprValueIsBool(0, false),
|
||||||
|
),
|
||||||
scanCase("with disjunctions",
|
scanCase("with disjunctions",
|
||||||
`pk="prefix" or sk="another"`,
|
`pk="prefix" or sk="another"`,
|
||||||
`(#0 = :0) OR (#1 = :1)`,
|
`(#0 = :0) OR (#1 = :1)`,
|
||||||
|
@ -846,6 +854,12 @@ func exprValueIsNumber(valIdx int, expected string) func(ss *scanScenario) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func exprValueIsBool(valIdx int, expected bool) func(ss *scanScenario) {
|
||||||
|
return func(ss *scanScenario) {
|
||||||
|
ss.expectedValues[fmt.Sprintf(":%d", valIdx)] = &types.AttributeValueMemberBOOL{Value: expected}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func exprNameIsString(idx, valIdx int, name string, expected string) func(ss *scanScenario) {
|
func exprNameIsString(idx, valIdx int, name string, expected string) func(ss *scanScenario) {
|
||||||
return func(ss *scanScenario) {
|
return func(ss *scanScenario) {
|
||||||
ss.expectedNames[fmt.Sprintf("#%d", idx)] = name
|
ss.expectedNames[fmt.Sprintf("#%d", idx)] = name
|
||||||
|
|
|
@ -51,6 +51,10 @@ func (a *astLiteralValue) goValue() (any, error) {
|
||||||
return s, nil
|
return s, nil
|
||||||
case a.IntVal != nil:
|
case a.IntVal != nil:
|
||||||
return *a.IntVal, nil
|
return *a.IntVal, nil
|
||||||
|
case a.TrueBoolValue:
|
||||||
|
return true, nil
|
||||||
|
case a.FalseBoolValue:
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("unrecognised type")
|
return nil, errors.New("unrecognised type")
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,15 +59,18 @@ func (s *Service) doScan(
|
||||||
|
|
||||||
runAsQuery = plan.CanQuery
|
runAsQuery = plan.CanQuery
|
||||||
filterExpr = &plan.Expression
|
filterExpr = &plan.Expression
|
||||||
|
|
||||||
|
log.Printf("Running query over '%v'", tableInfo.Name)
|
||||||
|
plan.Describe(log.Default())
|
||||||
|
} else {
|
||||||
|
log.Printf("Performing scan over '%v'", tableInfo.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var results []models.Item
|
var results []models.Item
|
||||||
var lastEvalKey map[string]types.AttributeValue
|
var lastEvalKey map[string]types.AttributeValue
|
||||||
if runAsQuery {
|
if runAsQuery {
|
||||||
log.Printf("executing query")
|
|
||||||
results, lastEvalKey, err = s.provider.QueryItems(ctx, tableInfo.Name, filterExpr, exclusiveStartKey, limit)
|
results, lastEvalKey, err = s.provider.QueryItems(ctx, tableInfo.Name, filterExpr, exclusiveStartKey, limit)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("executing scan")
|
|
||||||
results, lastEvalKey, err = s.provider.ScanItems(ctx, tableInfo.Name, filterExpr, exclusiveStartKey, limit)
|
results, lastEvalKey, err = s.provider.ScanItems(ctx, tableInfo.Name, filterExpr, exclusiveStartKey, limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue