Merge pull request #286 from seebs/storeauto

in Store/SetRow, create field if it doesn't already exist
This commit is contained in:
seebs 2020-04-14 15:33:10 -05:00 committed by GitHub
commit f41bced2ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 5 deletions

View file

@ -2825,15 +2825,27 @@ func (e *executor) executeClearRowShard(ctx context.Context, index string, c *pq
}
// executeSetRow executes a Store() call.
func (e *executor) executeSetRow(ctx context.Context, index string, c *pql.Call, shards []uint64, opt *execOptions) (bool, error) {
func (e *executor) executeSetRow(ctx context.Context, indexName string, c *pql.Call, shards []uint64, opt *execOptions) (bool, error) {
// Ensure the field type supports Store().
fieldName, err := c.FieldArg()
if err != nil {
return false, errors.New("field required for Store()")
}
field := e.Holder.Field(index, fieldName)
field := e.Holder.Field(indexName, fieldName)
if field == nil {
return false, ErrFieldNotFound
// Find index.
index := e.Holder.Index(indexName)
if index == nil {
return false, newNotFoundError(ErrIndexNotFound)
}
// Create field.
field, err = index.CreateField(fieldName, OptFieldTypeSet(CacheTypeNone, 0))
if err != nil {
// We wrap these because we want to indicate that it wasn't found,
// but also the problem we encountered trying to create it.
return false, newNotFoundError(errors.Wrap(err, "creating field"))
}
}
if field.Type() != FieldTypeSet {
return false, fmt.Errorf("can't Store() on a %s field", field.Type())
@ -2841,7 +2853,7 @@ func (e *executor) executeSetRow(ctx context.Context, index string, c *pql.Call,
// Execute calls in bulk on each remote node and merge.
mapFn := func(shard uint64) (interface{}, error) {
return e.executeSetRowShard(ctx, index, c, shard)
return e.executeSetRowShard(ctx, indexName, c, shard)
}
// Merge returned results at coordinating node.
@ -2853,7 +2865,7 @@ func (e *executor) executeSetRow(ctx context.Context, index string, c *pql.Call,
return val || prev.(bool)
}
result, err := e.mapReduce(ctx, index, shards, c, opt, mapFn, reduceFn)
result, err := e.mapReduce(ctx, indexName, shards, c, opt, mapFn, reduceFn)
return result.(bool), err
}

View file

@ -3713,6 +3713,20 @@ func TestExecutor_Execute_SetRow(t *testing.T) {
} else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth - 1, ShardWidth + 1}) {
t.Fatalf("unexpected columns: %+v", bits)
}
// Store row 10 into a table which doesn't exist.
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Store(Row(f=10), nonexistent=20)`}); err != nil {
t.Fatal(err)
} else if res := res.Results[0].(bool); !res {
t.Fatalf("unexpected set row result: %+v", res)
}
// Ensure the row was populated.
if res, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Row(nonexistent=20)`}); err != nil {
t.Fatal(err)
} else if bits := res.Results[0].(*pilosa.Row).Columns(); !reflect.DeepEqual(bits, []uint64{3, ShardWidth - 1, ShardWidth + 1}) {
t.Fatalf("unexpected columns: %+v", bits)
}
})
t.Run("Set_NoSource", func(t *testing.T) {
c := test.MustRunCluster(t, 1)