Skip to content

Sanity check for empty variables #3021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -1678,9 +1678,16 @@ func (sg *SubGraph) fillVars(mp map[string]varValue) error {
default:
// This var does not match any uids or vals but we are still trying to access it.
if v.Typ == gql.ValueVar {
// * * * * * * * * * * * * * * * * * * *
// Default value vars
// * * * * * * * * * * * * * * * * * * *
//
// Provide a default value for valueVarAggregation() to eval val().
// This is a noop for aggregation funcs that would fail.
// The zero aggs won't show because there are no uids matched.
//
// NOTE: If you need to make type assertions that might involve
// default value vars, use `Safe()` func and not val.Value directly.
mp[v.Name].Vals[0] = types.Val{}
sg.Params.uidToVal = mp[v.Name].Vals
}
Expand Down
2 changes: 1 addition & 1 deletion types/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ func (v Val) MarshalJSON() ([]byte, error) {
case GeoID:
return geojson.Marshal(v.Value.(geom.T))
case StringID, DefaultID:
return json.Marshal(v.Value.(string))
return json.Marshal(v.Safe().(string))
case PasswordID:
return json.Marshal(v.Value.(string))
}
Expand Down
14 changes: 14 additions & 0 deletions types/scalar_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,20 @@ type Val struct {
Value interface{}
}

// Safe ensures that Val's Value is not nil. This is useful when doing type
// assertions and default values might be involved.
// This function won't change the original v.Value, may it be nil.
// See: "Default value vars" in `fillVars()`
// Returns a safe v.Value suitable for type assertions.
func (v Val) Safe() interface{} {
if v.Value == nil {
// get zero value for this v.Tid
va := ValueForType(v.Tid)
return va.Value
}
return v.Value
}

// TypeForName returns the type corresponding to the given name.
// If name is not recognized, it returns nil.
func TypeForName(name string) (TypeID, bool) {
Expand Down
2 changes: 1 addition & 1 deletion types/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func less(a, b Val) bool {
case UidID:
return (a.Value.(uint64) < b.Value.(uint64))
case StringID, DefaultID:
return (a.Value.(string)) < (b.Value.(string))
return (a.Safe().(string)) < (b.Safe().(string))
}
return false
}
Expand Down