diff --git a/bigtable/integration_test.go b/bigtable/integration_test.go index 3242d4c900a..fa145b1cf86 100644 --- a/bigtable/integration_test.go +++ b/bigtable/integration_test.go @@ -1218,6 +1218,216 @@ func TestIntegration_FullReadStats(t *testing.T) { rowsReturnedCount: 2, rowsSeenCount: 4, }, + { + desc: "read range from empty, with ColumnRangeFilter", + rr: RowRange{}, + filter: ColumnRangeFilter("follows", "", "u"), + cellsReturnedCount: 6, + cellsSeenCount: 7, + rowsReturnedCount: 4, + rowsSeenCount: 4, + }, + { + desc: "read range from start to empty, with ColumnRangeFilter", + rr: RowRange{}, + filter: ColumnRangeFilter("follows", "h", ""), + cellsReturnedCount: 5, + cellsSeenCount: 5, + rowsReturnedCount: 4, + rowsSeenCount: 4, + }, + { + desc: "read with RowKeyFilter", + rr: RowRange{}, + filter: RowKeyFilter(".*wash.*"), + cellsReturnedCount: 1, + cellsSeenCount: 4, + rowsReturnedCount: 1, + rowsSeenCount: 4, + }, + { + desc: "read with RowKeyFilter unicode", + rr: RowRange{}, + filter: RowKeyFilter(".*j§.*"), + cellsReturnedCount: 2, + cellsSeenCount: 5, + rowsReturnedCount: 1, + rowsSeenCount: 4, + }, + { + desc: "read with RowKeyFilter escaped", + rr: RowRange{}, + filter: RowKeyFilter(`.*j\xC2\xA7.*`), + cellsReturnedCount: 2, + cellsSeenCount: 5, + rowsReturnedCount: 1, + rowsSeenCount: 4, + }, + { + desc: "read with RowKeyFilter, prefix", + rr: RowRange{}, + filter: RowKeyFilter("gwash"), + cellsReturnedCount: 0, + cellsSeenCount: 0, + rowsReturnedCount: 0, + rowsSeenCount: 0, + }, + { + desc: "read with RowKeyFilter, no matches", + rr: RowRange{}, + filter: RowKeyFilter(".*xxx.*"), + cellsReturnedCount: 0, + cellsSeenCount: 4, + rowsReturnedCount: 0, + rowsSeenCount: 4, + }, + { + desc: "read with FamilyFilter, no matches", + rr: RowRange{}, + filter: FamilyFilter(".*xxx.*"), + cellsReturnedCount: 0, + cellsSeenCount: 0, + rowsReturnedCount: 0, + rowsSeenCount: 0, + }, + { + desc: "read with ColumnFilter + row limit", + rr: RowRange{}, + filter: ColumnFilter(".*j.*"), // matches "j§adams" and "tjefferson" + limit: LimitRows(2), + cellsReturnedCount: 2, + cellsSeenCount: 3, + rowsReturnedCount: 2, + rowsSeenCount: 2, + }, + { + desc: "apply labels to the result rows", + rr: RowRange{}, + filter: LabelFilter("test-label"), + limit: LimitRows(2), + cellsReturnedCount: 3, + cellsSeenCount: 3, + rowsReturnedCount: 2, + rowsSeenCount: 2, + }, + { + desc: "read all, strip values", + rr: RowRange{}, + filter: StripValueFilter(), + cellsReturnedCount: 7, + cellsSeenCount: 7, + rowsReturnedCount: 4, + rowsSeenCount: 4, + }, + { + desc: "read with ColumnFilter + row limit + strip values", + rr: RowRange{}, + filter: ChainFilters(ColumnFilter(".*j.*"), StripValueFilter()), // matches "j§adams" and "tjefferson" + limit: LimitRows(2), + cellsReturnedCount: 2, + cellsSeenCount: 3, + rowsReturnedCount: 2, + rowsSeenCount: 2, + }, + { + desc: "read with condition, strip values on true", + rr: RowRange{}, + filter: ConditionFilter(ColumnFilter(".*j.*"), StripValueFilter(), nil), + cellsReturnedCount: 7, + cellsSeenCount: 13, + rowsReturnedCount: 4, + rowsSeenCount: 8, + }, + { + desc: "read with condition, strip values on false", + rr: RowRange{}, + filter: ConditionFilter(ColumnFilter(".*xxx.*"), nil, StripValueFilter()), + cellsReturnedCount: 7, + cellsSeenCount: 14, + rowsReturnedCount: 4, + rowsSeenCount: 8, + }, + { + desc: "read with ValueRangeFilter + row limit", + rr: RowRange{}, + filter: ValueRangeFilter([]byte("1"), []byte("5")), // matches our value of "1" + limit: LimitRows(2), + cellsReturnedCount: 3, + cellsSeenCount: 3, + rowsReturnedCount: 2, + rowsSeenCount: 2, + }, + { + desc: "read with ValueRangeFilter, no match on exclusive end", + rr: RowRange{}, + filter: ValueRangeFilter([]byte("0"), []byte("1")), // no match + cellsReturnedCount: 0, + cellsSeenCount: 7, + rowsReturnedCount: 0, + rowsSeenCount: 4, + }, + { + desc: "read with ValueRangeFilter, no matches", + rr: RowRange{}, + filter: ValueRangeFilter([]byte("3"), []byte("5")), // matches nothing + cellsReturnedCount: 0, + cellsSeenCount: 7, + rowsReturnedCount: 0, + rowsSeenCount: 4, + }, + { + desc: "read with InterleaveFilter, no matches on all filters", + rr: RowRange{}, + filter: InterleaveFilters(ColumnFilter(".*x.*"), ColumnFilter(".*z.*")), + cellsReturnedCount: 0, + cellsSeenCount: 7, + rowsReturnedCount: 0, + rowsSeenCount: 4, + }, + { + desc: "read with InterleaveFilter, no duplicate cells", + rr: RowRange{}, + filter: InterleaveFilters(ColumnFilter(".*g.*"), ColumnFilter(".*j.*")), + cellsReturnedCount: 6, + cellsSeenCount: 7, + rowsReturnedCount: 4, + rowsSeenCount: 4, + }, + { + desc: "read with InterleaveFilter, with duplicate cells", + rr: RowRange{}, + filter: InterleaveFilters(ColumnFilter(".*g.*"), ColumnFilter(".*g.*")), + cellsReturnedCount: 4, + cellsSeenCount: 7, + rowsReturnedCount: 2, + rowsSeenCount: 4, + }, + { + desc: "read with a RowRangeList and no filter", + rr: RowRangeList{NewRange("gargamel", "hubbard"), InfiniteRange("wmckinley")}, + cellsReturnedCount: 2, + cellsSeenCount: 2, + rowsReturnedCount: 2, + rowsSeenCount: 2, + }, + { + desc: "chain that excludes rows and matches nothing, in a condition", + rr: RowRange{}, + filter: ConditionFilter(ChainFilters(ColumnFilter(".*j.*"), ColumnFilter(".*mckinley.*")), StripValueFilter(), nil), + cellsReturnedCount: 0, + cellsSeenCount: 11, + rowsReturnedCount: 0, + rowsSeenCount: 8, + }, + { + desc: "chain that ends with an interleave that has no match. covers #804", + rr: RowRange{}, + filter: ConditionFilter(ChainFilters(ColumnFilter(".*j.*"), InterleaveFilters(ColumnFilter(".*x.*"), ColumnFilter(".*z.*"))), StripValueFilter(), nil), + cellsReturnedCount: 0, + cellsSeenCount: 11, + rowsReturnedCount: 0, + rowsSeenCount: 8, + }, } { t.Run(test.desc, func(t *testing.T) { var opts []ReadOption