Skip to content

Commit

Permalink
Only report required quals when listing missing quals. Closes #159
Browse files Browse the repository at this point in the history
  • Loading branch information
kaidaguerre committed Aug 2, 2021
1 parent 2d0f728 commit 8789604
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 23 deletions.
46 changes: 27 additions & 19 deletions plugin/key_column_qual_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,48 +39,56 @@ func (m KeyColumnQualMap) String() string {
return strings.Join(strs, "\n")
}

func (m KeyColumnQualMap) SatisfiesKeyColumns(columns KeyColumnSlice) (bool, KeyColumnSlice) {
log.Printf("[TRACE] SatisfiesKeyColumns %v", columns)
func (m KeyColumnQualMap) GetUnsatisfiedKeyColumns(columns KeyColumnSlice) KeyColumnSlice {
log.Printf("[TRACE] GetUnsatisfiedKeyColumns %v", columns)

if columns == nil {
return true, nil
return nil
}
var unsatisfiedKeyColumns KeyColumnSlice
satisfiedCount := map[string]int{
Required: 0,
AnyOf: 0,
Optional: 0,
satisfiedMap := map[string]KeyColumnSlice{
Required: {},
AnyOf: {},
Optional: {},
}
unsatisfiedCount := map[string]int{
Required: 0,
AnyOf: 0,
Optional: 0,
unsatisfiedMap := map[string]KeyColumnSlice{
Required: {},
AnyOf: {},
Optional: {},
}

for _, keyColumn := range columns {
// look for this key column in our map
k := m[keyColumn.Name]
satisfied := k != nil && k.SatisfiesKeyColumn(keyColumn)
if satisfied {
satisfiedCount[keyColumn.Require]++

satisfiedMap[keyColumn.Require] = append(satisfiedMap[keyColumn.Require], keyColumn)
log.Printf("[TRACE] key column satisfied %v", keyColumn)

} else {
unsatisfiedCount[keyColumn.Require]++
unsatisfiedKeyColumns = append(unsatisfiedKeyColumns, keyColumn)
unsatisfiedMap[keyColumn.Require] = append(unsatisfiedMap[keyColumn.Require], keyColumn)
log.Printf("[TRACE] key column NOT satisfied %v", keyColumn)
// if this was NOT an optional key column, we are not satisfied
}
}

// we are satisfied if:
// all Required key columns are satisfied
// either there is at least 1 satisfied AnyOf key columns, or there are no AnyOf columns
res := unsatisfiedCount[Required] == 0 && (satisfiedCount[AnyOf] > 0 || unsatisfiedCount[AnyOf] == 0)
anyOfSatisfied := len(satisfiedMap[AnyOf]) > 0 || len(unsatisfiedMap[AnyOf]) == 0
if !anyOfSatisfied {
unsatisfiedKeyColumns = unsatisfiedMap[AnyOf]
}
// if any 'required' are unsatisfied, we are unsatisfied
requiredSatisfied := len(unsatisfiedMap[Required]) == 0
if !requiredSatisfied {
unsatisfiedKeyColumns = append(unsatisfiedKeyColumns, unsatisfiedMap[Required]...)
}

log.Printf("[TRACE] satisfied: %v", satisfiedMap)
log.Printf("[TRACE] unsatisfied: %v", unsatisfiedMap)
log.Printf("[TRACE] unsatisfied required KeyColumns %v", unsatisfiedKeyColumns)

log.Printf("[TRACE] SatisfiesKeyColumns result: %v\nsatisfiedCount %v\nunsatisfiedCount %v\nunsatisfiedKeyColumns %v", res, satisfiedCount, unsatisfiedCount, unsatisfiedKeyColumns)
return res, unsatisfiedKeyColumns
return unsatisfiedKeyColumns
}

// ToQualMap converts the map into a simpler map of column to []Quals
Expand Down
2 changes: 1 addition & 1 deletion plugin/query_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func (d *QueryData) setFetchType(table *Table) {
// build a qual map from Get key columns
qualMap := NewKeyColumnQualValueMap(d.QueryContext.UnsafeQuals, table.Get.KeyColumns)
// now see whether the qual map has everything required for the get call
if satisfied, _ := qualMap.SatisfiesKeyColumns(table.Get.KeyColumns); satisfied {
if unsatisfiedColumns := qualMap.GetUnsatisfiedKeyColumns(table.Get.KeyColumns); len(unsatisfiedColumns) == 0 {
log.Printf("[TRACE] Set fetchType to fetchTypeGet")
d.KeyColumnQuals = qualMap.ToEqualsQualValueMap()
d.Quals = qualMap
Expand Down
6 changes: 3 additions & 3 deletions plugin/table_fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,9 @@ func (t *Table) executeListCall(ctx context.Context, queryData *QueryData) {
}()

// verify we have the necessary quals
isSatisfied, unsatisfiedColumns := queryData.Quals.SatisfiesKeyColumns(t.List.KeyColumns)
if !isSatisfied {
err := status.Error(codes.Internal, fmt.Sprintf("'List' call is missing required quals: \n%s", unsatisfiedColumns.String()))
unsatisfiedColumns := queryData.Quals.GetUnsatisfiedKeyColumns(t.List.KeyColumns)
if len(unsatisfiedColumns) > 0 {
err := status.Error(codes.Internal, fmt.Sprintf("'List' call is missing required quals: %s", unsatisfiedColumns.String()))
queryData.streamError(err)
return
}
Expand Down

0 comments on commit 8789604

Please sign in to comment.