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);
}
}