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.
This commit is contained in:
Leon Mika 2022-09-19 21:14:03 +10:00 committed by GitHub
parent 0063d7c6d5
commit a1717572c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 492 additions and 101 deletions

View file

@ -11,6 +11,7 @@ import (
type TableProvider interface {
ListTables(ctx context.Context) ([]string, error)
DescribeTable(ctx context.Context, tableName string) (*models.TableInfo, error)
QueryItems(ctx context.Context, tableName string, filterExpr *expression.Expression, maxItems int) ([]models.Item, error)
ScanItems(ctx context.Context, tableName string, filterExpr *expression.Expression, maxItems int) ([]models.Item, error)
DeleteItem(ctx context.Context, tableName string, key map[string]types.AttributeValue) error
PutItem(ctx context.Context, name string, item models.Item) error

View file

@ -4,6 +4,7 @@ import (
"context"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
"github.com/lmika/audax/internal/common/sliceutils"
"log"
"strings"
"github.com/lmika/audax/internal/dynamo-browse/models"
@ -33,66 +34,39 @@ func (s *Service) Scan(ctx context.Context, tableInfo *models.TableInfo) (*model
}
func (s *Service) doScan(ctx context.Context, tableInfo *models.TableInfo, expr models.Queryable) (*models.ResultSet, error) {
var filterExpr *expression.Expression
var (
filterExpr *expression.Expression
runAsQuery bool
err error
)
if expr != nil {
plan, err := expr.Plan(tableInfo)
if err != nil {
return nil, err
}
// TEMP
if plan.CanQuery {
return nil, errors.Errorf("queries not yet supported")
}
runAsQuery = plan.CanQuery
filterExpr = &plan.Expression
}
results, err := s.provider.ScanItems(ctx, tableInfo.Name, filterExpr, 1000)
var results []models.Item
if runAsQuery {
log.Printf("executing query")
results, err = s.provider.QueryItems(ctx, tableInfo.Name, filterExpr, 1000)
} else {
log.Printf("executing scan")
results, err = s.provider.ScanItems(ctx, tableInfo.Name, filterExpr, 1000)
}
if err != nil {
return nil, errors.Wrapf(err, "unable to scan table %v", tableInfo.Name)
}
// Get the columns
//seenColumns := make(map[string]int)
//seenColumns[tableInfo.Keys.PartitionKey] = 0
//if tableInfo.Keys.SortKey != "" {
// seenColumns[tableInfo.Keys.SortKey] = 1
//}
//
//for _, definedAttribute := range tableInfo.DefinedAttributes {
// if _, seen := seenColumns[definedAttribute]; !seen {
// seenColumns[definedAttribute] = len(seenColumns)
// }
//}
//
//otherColsRank := len(seenColumns)
//for _, result := range results {
// for k := range result {
// if _, isSeen := seenColumns[k]; !isSeen {
// seenColumns[k] = otherColsRank
// }
// }
//}
//
//columns := make([]string, 0, len(seenColumns))
//for k := range seenColumns {
// columns = append(columns, k)
//}
//sort.Slice(columns, func(i, j int) bool {
// if seenColumns[columns[i]] == seenColumns[columns[j]] {
// return columns[i] < columns[j]
// }
// return seenColumns[columns[i]] < seenColumns[columns[j]]
//})
models.Sort(results, tableInfo)
resultSet := &models.ResultSet{
TableInfo: tableInfo,
Query: expr,
//Columns: columns,
}
resultSet.SetItems(results)
resultSet.RefreshColumns()