void RunAlteredSequentialTabletTests()

in src/kudu/tablet/all_types-scan-correctness-test.cc [529:705]


  void RunAlteredSequentialTabletTests() {
    int lower_non_null = kLower;
    // Determine the lowest non-null value in the data range. Used in getting expected counts.
    if (kLower < base_null_upper_) {
      lower_non_null = base_null_upper_;
    }
    // Tests with null read-default. Ex. case: (-: null, 1: pred satisfied, 0: pred not satisfied)
    // kLower: 5, kUpper: 8
    // Base nrows: 30                 |Altered nrows: 25
    // Cardinality: 20, null_upper: 3, read_default: NULL
    // Predicate: (val_b >= 0 && val_b < 8) && (val_c >= 5 && val_c < 20)
    //  0    5    10   15   20   25   |30   35   40   45   50     key
    // [---11111000000000000---1111100|---11111000000000000---11] val_b
    // [------------------------------|---00111111111111111---00] val_c
    // [000000000000000000000000000000|0000011100000000000000000] Result
    AddColumn(-1);
    FillAlteredTestTablet(kNumAddedRows);
    int count = 0;
    {
      ScanSpec spec;
      // val_b >= kLower && val_b <= kUpper && val_c is null
      auto pred_b = rowops_.GenerateRangePredicate(altered_schema_, kColB, kLower, kUpper);
      auto pred_c = ColumnPredicate::IsNull(altered_schema_.column(kColC));
      spec.AddPredicate(pred_b);
      spec.AddPredicate(pred_c);
      ScanWithSpec(altered_schema_, spec, &count);
      int base_expected_count = ExpectedCountSequential(base_nrows_,
                                                        base_cardinality_,
                                                        lower_non_null,
                                                        kUpper);
      // Since the new column has the same data as the base columns, IsNull with a Range predicate
      // should yield no rows from the added rows.
      int altered_expected_count = 0;
      int expected_count = base_expected_count + altered_expected_count;
      SCOPED_TRACE(TraceMsg("Null default, Range+IsNull", expected_count, count));
      ASSERT_EQ(expected_count, count);
    }
    {
      ScanSpec spec;
      // val_b >= kLower && val_b <= kUpper && val_c is not null
      auto pred_b = rowops_.GenerateRangePredicate(altered_schema_, kColB, kLower, kUpper);
      auto pred_c = ColumnPredicate::IsNotNull(altered_schema_.column(kColC));
      spec.AddPredicate(pred_b);
      spec.AddPredicate(pred_c);
      ScanWithSpec(altered_schema_, spec, &count);
      // Since the table has a null read-default on the added column, the IsNotNull predicate
      // should filter out all rows in the base data.
      int base_expected_count = 0;
      int altered_expected_count = ExpectedCountSequential(added_nrows_,
                                                           base_cardinality_,
                                                           lower_non_null,
                                                           kUpper);
      int expected_count = base_expected_count + altered_expected_count;
      SCOPED_TRACE(TraceMsg("Null default, Range+IsNotNull", expected_count, count));
      ASSERT_EQ(expected_count, count);
    }
    {
      ScanSpec spec;
      // val_b >= 0 && val_b < kUpper && val_c >= kLower && val_c < cardinality
      auto pred_b = rowops_.GenerateRangePredicate(altered_schema_, kColB, 0, kUpper);
      auto pred_c = rowops_.GenerateRangePredicate(altered_schema_, kColC, kLower,
                                                   base_cardinality_);
      spec.AddPredicate(pred_b);
      spec.AddPredicate(pred_c);
      ScanWithSpec(altered_schema_, spec, &count);
      // Since the added column has a null read-default, the base rows will be completely filtered.
      int base_expected_count = 0;
      // The added data will be predicated with [lower, upper).
      int altered_expected_count = ExpectedCountSequential(added_nrows_,
                                                           base_cardinality_,
                                                           lower_non_null,
                                                           kUpper);
      int expected_count = base_expected_count + altered_expected_count;
      SCOPED_TRACE(TraceMsg("Null default, Range", expected_count, count));
      ASSERT_EQ(expected_count, count);
    }
    // Tests with non-null read-default. Ex. case:
    // kLower: 5, kUpper: 8
    // Base nrows: 30                |Altered nrows: 25
    // Cardinality: 20, null_upper: 3, read_default: 7
    // Predicate: (val_b >= 0 && val_b < 8) && (val_c >= 5 && val_c < 20)
    //  0    5    10   15   20   25   |30   35   40   45   50     key
    // [---11111000000000000---1111100|---11111000000000000---11] val_b
    // [111111111111111111111111111111|---00111111111111111---00] val_c
    // [000111110000000000000001111100|0000011100000000000000000] Result
    int read_default = 7;
    AddColumn(read_default);
    FillAlteredTestTablet(kNumAddedRows);
    {
      ScanSpec spec;
      // val_b >= kLower && val_b <= kUpper && val_c is null
      auto pred_b = rowops_.GenerateRangePredicate(altered_schema_, kColB, kLower, kUpper);
      auto pred_c = ColumnPredicate::IsNull(altered_schema_.column(kColC));
      spec.AddPredicate(pred_b);
      spec.AddPredicate(pred_c);
      ScanWithSpec(altered_schema_, spec, &count);
      // The base data is not null, since there is a read-default.
      int base_expected_count = 0;
      // Since the new column has the same data as the base columns, IsNull with a Range predicate
      // should yield no rows from the added rows.
      int altered_expected_count = 0;
      int expected_count = base_expected_count + altered_expected_count;
      SCOPED_TRACE(TraceMsg("Non-null default, Range+IsNull", expected_count, count));
      ASSERT_EQ(expected_count, count);
    }
    {
      ScanSpec spec;
      // val_b >= kLower && val_b <= kUpper && val_c is not null
      auto pred_b = rowops_.GenerateRangePredicate(altered_schema_, kColB, kLower, kUpper);
      auto pred_c = ColumnPredicate::IsNotNull(altered_schema_.column(kColC));
      spec.AddPredicate(pred_b);
      spec.AddPredicate(pred_c);
      ScanWithSpec(altered_schema_, spec, &count);
      int base_expected_count =
          ExpectedCountSequential(base_nrows_, base_cardinality_, lower_non_null,
                                  kUpper);
      // Since the new column has the same data as the base columns, IsNotNull with a Range
      // predicate should yield the same rows as the Range query alone on the altered data.
      int altered_expected_count =
          ExpectedCountSequential(added_nrows_, base_cardinality_, lower_non_null,
                                  kUpper);
      int expected_count = base_expected_count + altered_expected_count;
      SCOPED_TRACE(TraceMsg("Non-null default, Range+IsNotNull", expected_count, count));
      ASSERT_EQ(expected_count, count);
    }
    {
      int lower = 0;
      ScanSpec spec;
      // val_b >= 0 && val_b < kUpper && val_c >= kLower && val_c < cardinality
      auto pred_b = rowops_.GenerateRangePredicate(altered_schema_, kColB, 0, kUpper);
      auto pred_c = rowops_.GenerateRangePredicate(altered_schema_, kColC, kLower,
                                                   base_cardinality_);
      spec.AddPredicate(pred_b);
      spec.AddPredicate(pred_c);
      ScanWithSpec(altered_schema_, spec, &count);
      // Take into account possible null values when calculating expected counts.
      if (base_null_upper_ > 0) {
        lower = base_null_upper_;
      }
      // Because the read_default is in range, the predicate on "val_c" will be satisfied
      // by base data, and all rows that satisfy "pred_b" will be returned.
      int base_expected_count =
          ExpectedCountSequential(base_nrows_, base_cardinality_, lower, kUpper);
      int altered_expected_count = ExpectedCountSequential(added_nrows_,
                                                           base_cardinality_,
                                                           lower_non_null,
                                                           kUpper);
      int expected_count = base_expected_count + altered_expected_count;
      SCOPED_TRACE(TraceMsg("Non-null default, Range with Default", expected_count, count));
      ASSERT_EQ(expected_count, count);
    }
    {
      // Used to ensure the query does not select the read-default.
      int default_plus_one = read_default + 1;
      ScanSpec spec;
      // val_b >= 0 && val_b < kUpper && val_c >= read_default + 1 && val_c < cardinality
      auto pred_b = rowops_.GenerateRangePredicate(altered_schema_, kColB, 0, kUpper);
      auto pred_c = rowops_.GenerateRangePredicate(altered_schema_, kColC, default_plus_one,
                                                   base_cardinality_);
      spec.AddPredicate(pred_b);
      spec.AddPredicate(pred_c);
      ScanWithSpec(altered_schema_, spec, &count);
      if (default_plus_one < base_null_upper_) {
        default_plus_one = base_null_upper_;
      }
      // Because the read_default is out of range, the "pred_c" will not be satisfied by base data,
      // so all base rows will be filtered.
      int base_expected_count = 0;
      int altered_expected_count = ExpectedCountSequential(added_nrows_,
                                                           base_cardinality_,
                                                           default_plus_one,
                                                           kUpper);
      int expected_count = base_expected_count + altered_expected_count;
      SCOPED_TRACE(TraceMsg("Non-null default, Range without Default", expected_count, count));
      ASSERT_EQ(expected_count, count);
    }
  }