@@ -23,6 +23,7 @@ import (
2323const (
2424 DefaultKeyTranslateBatchSize = 100000
2525 existenceFieldName = "_exists"
26+ existenceViewName = "existence" // this should match top level featurebase viewExistence
2627)
2728
2829// TODO if using column translation, column ids might get way out of
@@ -573,6 +574,10 @@ func (b *Batch) Add(rec Row) error {
573574 case int64 :
574575 b .values [field .Name ] = append (b .values [field .Name ], val )
575576 case []string :
577+ // note that a length of 0 can be valid, and represents an
578+ // empty set. an empty set counts as a non-NULL value for
579+ // SQL purposes -- it means the existence view bit should
580+ // get set.
576581 if val == nil {
577582 continue
578583 }
@@ -608,7 +613,10 @@ func (b *Batch) Add(rec Row) error {
608613 }
609614 b .rowIDSets [field .Name ] = append (rowIDSets , rowIDs )
610615 case []uint64 :
611- // if length is 0, that's still a valid, empty, set
616+ // note that a length of 0 can be valid, and represents an
617+ // empty set. an empty set counts as a non-NULL value for
618+ // SQL purposes -- it means the existence view bit should
619+ // get set.
612620 if val == nil {
613621 continue
614622 }
@@ -1363,8 +1371,8 @@ func (b *Batch) makeFragments(frags, clearFrags fragments) (fragments, fragments
13631371 // the API treats "" as standard
13641372 curBM = frags .GetOrCreate (curShard , field .Name , "" )
13651373 clearBM = clearFrags .GetOrCreate (curShard , field .Name , "" )
1366- if opts .TrackExistence {
1367- existCurBM = frags .GetOrCreate (curShard , field .Name , "existence" )
1374+ if opts .ActuallyTrackingExistence () {
1375+ existCurBM = frags .GetOrCreate (curShard , field .Name , existenceViewName )
13681376 }
13691377 }
13701378 if row != nilSentinel {
@@ -1375,7 +1383,7 @@ func (b *Batch) makeFragments(frags, clearFrags fragments) (fragments, fragments
13751383 // the NoStandardView case would be great.
13761384 if ! (opts .Type == featurebase .FieldTypeTime && opts .NoStandardView ) {
13771385 curBM .DirectAdd (row * shardWidth + (col % shardWidth ))
1378- if opts .TrackExistence {
1386+ if opts .ActuallyTrackingExistence () {
13791387 existCurBM .DirectAdd (col % shardWidth )
13801388 }
13811389 }
@@ -1398,9 +1406,14 @@ func (b *Batch) makeFragments(frags, clearFrags fragments) (fragments, fragments
13981406 // we want to make sure that at this point, the "set"
13991407 // fragments don't contain the bit that we're clearing
14001408 curBM .DirectRemoveN (clearRow * shardWidth + (col % shardWidth ))
1401- // don't set the existence bit, probably? i don't actually quite
1402- // understand the higher level semantics here.
1403- if opts .TrackExistence {
1409+ // Because this is RowIDs, not RowIDSets, there's only one
1410+ // bit. We should not be setting the existence bit based on
1411+ // this value, if we're actually clearing it. This doesn't
1412+ // mean we will clear an existing existence bit, though.
1413+ // The case where we would clear an existence bit is the
1414+ // case where someone specified row[mutexField].Clears = nil,
1415+ // which is far from here.
1416+ if opts .ActuallyTrackingExistence () {
14041417 existCurBM .DirectRemoveN (col % shardWidth )
14051418 }
14061419 }
@@ -1427,13 +1440,14 @@ func (b *Batch) makeFragments(frags, clearFrags fragments) (fragments, fragments
14271440 if col / shardWidth != curShard {
14281441 curShard = col / shardWidth
14291442 curBM = frags .GetOrCreate (curShard , fname , "" )
1430- if opts .TrackExistence {
1431- existCurBM = frags .GetOrCreate (curShard , fname , "existence" )
1443+ if opts .ActuallyTrackingExistence () {
1444+ existCurBM = frags .GetOrCreate (curShard , fname , existenceViewName )
14321445 }
14331446 }
14341447 if len (rowIDs ) == 0 {
1435- // you can validly specify an empty set, which is not the same as a null
1436- if opts .TrackExistence && ! (opts .Type == featurebase .FieldTypeTime && opts .NoStandardView ) && rowIDs != nil {
1448+ // you can validly specify an empty set, which is not the same as a null,
1449+ // but which still ought to set the existence bit if we're tracking that.
1450+ if opts .ActuallyTrackingExistence () && rowIDs != nil {
14371451 existCurBM .DirectAdd (col % shardWidth )
14381452 }
14391453 continue
@@ -1447,7 +1461,7 @@ func (b *Batch) makeFragments(frags, clearFrags fragments) (fragments, fragments
14471461 for _ , row := range rowIDs {
14481462 curBM .DirectAdd (row * shardWidth + (col % shardWidth ))
14491463 }
1450- if opts .TrackExistence {
1464+ if opts .ActuallyTrackingExistence () {
14511465 existCurBM .DirectAdd (col % shardWidth )
14521466 }
14531467 }
@@ -1578,9 +1592,9 @@ func (b *Batch) makeSingleValFragments(frags, clearFrags fragments) (fragments,
15781592 bitmap := frags .GetOrCreate (shard , field .Name , "standard" )
15791593 clearBM := clearFrags .GetOrCreate (shard , field .Name , "standard" )
15801594 var existBM , existClearBM * roaring.Bitmap
1581- if field .Options .TrackExistence {
1582- existBM = frags .GetOrCreate (shard , field .Name , "existence" )
1583- existClearBM = clearFrags .GetOrCreate (shard , field .Name , "existence" )
1595+ if field .Options .ActuallyTrackingExistence () {
1596+ existBM = frags .GetOrCreate (shard , field .Name , existenceViewName )
1597+ existClearBM = clearFrags .GetOrCreate (shard , field .Name , existenceViewName )
15841598 }
15851599 for i , id := range ids {
15861600 if i + 1 < len (ids ) {
@@ -1594,9 +1608,9 @@ func (b *Batch) makeSingleValFragments(frags, clearFrags fragments) (fragments,
15941608 shard = id / shardWidth
15951609 bitmap = frags .GetOrCreate (shard , field .Name , "standard" )
15961610 clearBM = clearFrags .GetOrCreate (shard , field .Name , "standard" )
1597- if field .Options .TrackExistence {
1598- existBM = frags .GetOrCreate (shard , field .Name , "existence" )
1599- existClearBM = clearFrags .GetOrCreate (shard , field .Name , "existence" )
1611+ if field .Options .ActuallyTrackingExistence () {
1612+ existBM = frags .GetOrCreate (shard , field .Name , existenceViewName )
1613+ existClearBM = clearFrags .GetOrCreate (shard , field .Name , existenceViewName )
16001614 }
16011615 }
16021616 fragmentColumn := id % shardWidth
@@ -1605,10 +1619,10 @@ func (b *Batch) makeSingleValFragments(frags, clearFrags fragments) (fragments,
16051619 // clearSentinel is used for deletion
16061620 // so this value should only be added if its not clearSentinel
16071621 bitmap .Add (row * shardWidth + fragmentColumn )
1608- if field .Options .TrackExistence {
1622+ if field .Options .ActuallyTrackingExistence () {
16091623 existBM .Add (fragmentColumn )
16101624 }
1611- } else if field .Options .TrackExistence {
1625+ } else if field .Options .ActuallyTrackingExistence () {
16121626 existClearBM .Add (fragmentColumn )
16131627 }
16141628 }
@@ -1638,8 +1652,8 @@ func (b *Batch) makeSingleValFragments(frags, clearFrags fragments) (fragments,
16381652 fragmentColumn := recID % shardWidth
16391653
16401654 clearBM .Add (fragmentColumn )
1641- if field .Options .TrackExistence {
1642- existClearBM := clearFrags .GetOrCreate (shard , field .Name , "existence" )
1655+ if field .Options .ActuallyTrackingExistence () {
1656+ existClearBM := clearFrags .GetOrCreate (shard , field .Name , existenceViewName )
16431657
16441658 existClearBM .Add (fragmentColumn )
16451659 }
@@ -1665,8 +1679,8 @@ func (b *Batch) makeSingleValFragments(frags, clearFrags fragments) (fragments,
16651679
16661680 fragmentColumn := recID % shardWidth
16671681 clearBM .Add (fragmentColumn )
1668- if field .Options .TrackExistence {
1669- exist := frags .GetOrCreate (shard , field .Name , "existence" )
1682+ if field .Options .ActuallyTrackingExistence () {
1683+ exist := frags .GetOrCreate (shard , field .Name , existenceViewName )
16701684 exist .Add (fragmentColumn )
16711685 }
16721686
0 commit comments