diff --git a/src/libtable/test/ob_batch_execute_test.cpp b/src/libtable/test/ob_batch_execute_test.cpp index 6a1bda8900..53c3912835 100644 --- a/src/libtable/test/ob_batch_execute_test.cpp +++ b/src/libtable/test/ob_batch_execute_test.cpp @@ -6219,6 +6219,44 @@ TEST_F(TestBatchExecute, htable_scan_with_filter) ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity)); } + // case : PageFilter + fprintf(stderr, "case: PageFilter\n"); + // check + { + // page size is 3 + htable_filter.set_filter(ObString::make_string("PageFilter(3)")); + ObTableEntityIterator *iter = nullptr; + ASSERT_EQ(OB_SUCCESS, the_table->execute_query(query, iter)); + + const ObITableEntity *result_entity = NULL; + int cqids_sorted[4] = {1, 3, 4, 7}; + int64_t timestamps[2] = {7, 6}; + for (int64_t i = 0; i < 3; ++i) { + // only 3 rowkeys (equals to page size) + sprintf(rows[i], "row%ld", 50+i); + key1.set_varbinary(ObString::make_string(rows[i])); + for (int64_t j = 0; j < 4; ++j) { + // 4 qualifier + sprintf(qualifier2[j], "cq%d", cqids_sorted[j]); + key2.set_varbinary(ObString::make_string(qualifier2[j])); + for (int64_t k = 0; k < 2; ++k) + { + key3.set_int(timestamps[k]); + ASSERT_EQ(OB_SUCCESS, iter->get_next_entity(result_entity)); + ObObj rk, cq, ts, val; + ASSERT_EQ(OB_SUCCESS, result_entity->get_property(K, rk)); + ASSERT_EQ(OB_SUCCESS, result_entity->get_property(Q, cq)); + ASSERT_EQ(OB_SUCCESS, result_entity->get_property(T, ts)); + ASSERT_EQ(OB_SUCCESS, result_entity->get_property(V, val)); + ASSERT_EQ(key1, rk); + ASSERT_EQ(key2, cq); + ASSERT_EQ(key3, ts); + } // end for + } + } + ASSERT_EQ(OB_ITER_END, iter->get_next_entity(result_entity)); + } + // case : ColumnCountGetFilter fprintf(stderr, "case: ColumnCountGetFilter\n"); // check diff --git a/src/observer/table/htable_filter_tab.cxx b/src/observer/table/htable_filter_tab.cxx index ba0214f653..fc940a7056 100644 --- a/src/observer/table/htable_filter_tab.cxx +++ b/src/observer/table/htable_filter_tab.cxx @@ -464,9 +464,9 @@ static const yytype_int8 yyrhs[] = static const yytype_uint16 yyrline[] = { 0, 55, 55, 62, 83, 104, 125, 146, 161, 176, - 183, 185, 207, 229, 251, 273, 301, 329, 336, 351, - 375, 397, 400, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 414 + 183, 185, 207, 229, 251, 273, 301, 329, 344, 359, + 383, 405, 408, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 422 }; #endif @@ -1809,17 +1809,25 @@ yyreduce: /* Line 1455 of yacc.c */ #line 330 "../../../src/observer/table/htable_filter_tab.yxx" { - int &ret = parse_ctx->error_code_ = OB_NOT_SUPPORTED; - UNUSED(ret); - ob_hfilter_error(&((yyloc)), parse_ctx, "PageFilter not supported"); - YYABORT; + int &ret = parse_ctx->error_code_ = OB_SUCCESS; + (yyval.fval) = OB_NEWx(hfilter::PageFilter, parse_ctx->allocator(), (yyvsp[(3) - (4)].lval)); + if (nullptr == (yyval.fval)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("no memory", K(ret)); + } else if (OB_FAIL(parse_ctx->store_filter((yyval.fval)))) { + LOG_WARN("failed to store filter", K(ret)); + } + if (OB_SUCCESS != ret) { + ob_hfilter_error(&((yyloc)), parse_ctx, "failed to parse PageFilter"); + YYABORT; + } ;} break; case 18: /* Line 1455 of yacc.c */ -#line 337 "../../../src/observer/table/htable_filter_tab.yxx" +#line 345 "../../../src/observer/table/htable_filter_tab.yxx" { int &ret = parse_ctx->error_code_ = OB_SUCCESS; (yyval.fval) = OB_NEWx(hfilter::ColumnCountGetFilter, parse_ctx->allocator(), (yyvsp[(3) - (4)].lval)); @@ -1839,7 +1847,7 @@ yyreduce: case 19: /* Line 1455 of yacc.c */ -#line 352 "../../../src/observer/table/htable_filter_tab.yxx" +#line 360 "../../../src/observer/table/htable_filter_tab.yxx" { int &ret = parse_ctx->error_code_ = OB_SUCCESS; hfilter::Comparable *comparable = nullptr; @@ -1868,7 +1876,7 @@ yyreduce: case 20: /* Line 1455 of yacc.c */ -#line 376 "../../../src/observer/table/htable_filter_tab.yxx" +#line 384 "../../../src/observer/table/htable_filter_tab.yxx" { int &ret = parse_ctx->error_code_ = OB_SUCCESS; hfilter::Comparable *comparable = nullptr; @@ -1893,91 +1901,91 @@ yyreduce: case 21: /* Line 1455 of yacc.c */ -#line 397 "../../../src/observer/table/htable_filter_tab.yxx" +#line 405 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.sval) = (yyvsp[(1) - (1)].sval); ;} break; case 22: /* Line 1455 of yacc.c */ -#line 400 "../../../src/observer/table/htable_filter_tab.yxx" +#line 408 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.sval) = (yyvsp[(1) - (1)].sval); ;} break; case 23: /* Line 1455 of yacc.c */ -#line 403 "../../../src/observer/table/htable_filter_tab.yxx" +#line 411 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::LESS; ;} break; case 24: /* Line 1455 of yacc.c */ -#line 404 "../../../src/observer/table/htable_filter_tab.yxx" +#line 412 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::LESS_OR_EQUAL; ;} break; case 25: /* Line 1455 of yacc.c */ -#line 405 "../../../src/observer/table/htable_filter_tab.yxx" +#line 413 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::EQUAL; ;} break; case 26: /* Line 1455 of yacc.c */ -#line 406 "../../../src/observer/table/htable_filter_tab.yxx" +#line 414 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::NOT_EQUAL; ;} break; case 27: /* Line 1455 of yacc.c */ -#line 407 "../../../src/observer/table/htable_filter_tab.yxx" +#line 415 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::GREATER; ;} break; case 28: /* Line 1455 of yacc.c */ -#line 408 "../../../src/observer/table/htable_filter_tab.yxx" +#line 416 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::GREATER_OR_EQUAL; ;} break; case 29: /* Line 1455 of yacc.c */ -#line 409 "../../../src/observer/table/htable_filter_tab.yxx" +#line 417 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::NO_OP; ;} break; case 30: /* Line 1455 of yacc.c */ -#line 410 "../../../src/observer/table/htable_filter_tab.yxx" +#line 418 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::IS; ;} break; case 31: /* Line 1455 of yacc.c */ -#line 411 "../../../src/observer/table/htable_filter_tab.yxx" +#line 419 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.cmp_op) = hfilter::CompareOperator::IS_NOT; ;} break; case 32: /* Line 1455 of yacc.c */ -#line 415 "../../../src/observer/table/htable_filter_tab.yxx" +#line 423 "../../../src/observer/table/htable_filter_tab.yxx" { (yyval.sval) = (yyvsp[(1) - (1)].sval); ;} break; /* Line 1455 of yacc.c */ -#line 2013 "../../../src/observer/table/htable_filter_tab.cxx" +#line 2021 "../../../src/observer/table/htable_filter_tab.cxx" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2196,6 +2204,6 @@ yyreturn: /* Line 1675 of yacc.c */ -#line 417 "../../../src/observer/table/htable_filter_tab.yxx" +#line 425 "../../../src/observer/table/htable_filter_tab.yxx" diff --git a/src/observer/table/htable_filter_tab.yxx b/src/observer/table/htable_filter_tab.yxx index b02aa18df3..1f888432b8 100644 --- a/src/observer/table/htable_filter_tab.yxx +++ b/src/observer/table/htable_filter_tab.yxx @@ -328,10 +328,18 @@ simple_filter: } | PageFilter '(' INT_VALUE ')' { - int &ret = parse_ctx->error_code_ = OB_NOT_SUPPORTED; - UNUSED(ret); - ob_hfilter_error(&(@$), parse_ctx, "PageFilter not supported"); - YYABORT; + int &ret = parse_ctx->error_code_ = OB_SUCCESS; + $$ = OB_NEWx(hfilter::PageFilter, parse_ctx->allocator(), $3); + if (nullptr == $$) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("no memory", K(ret)); + } else if (OB_FAIL(parse_ctx->store_filter($$))) { + LOG_WARN("failed to store filter", K(ret)); + } + if (OB_SUCCESS != ret) { + ob_hfilter_error(&(@$), parse_ctx, "failed to parse PageFilter"); + YYABORT; + } } | ColumnCountGetFilter '(' INT_VALUE ')' { diff --git a/src/observer/table/ob_htable_filters.cpp b/src/observer/table/ob_htable_filters.cpp index aa67a20743..872499c684 100644 --- a/src/observer/table/ob_htable_filters.cpp +++ b/src/observer/table/ob_htable_filters.cpp @@ -821,6 +821,19 @@ bool SingleColumnValueFilter::filter_row() LOG_DEBUG("[yzfdebug] filter row", K_(found_column), K_(matched_column), K_(filter_if_missing)); return found_column_ ? (!matched_column_) : (filter_if_missing_); } + +//////////////////////////////////////////////////////////////// +bool PageFilter::filter_row() +{ + rows_accepted_++; + return rows_accepted_ > page_size_; +} + +bool PageFilter::filter_all_remaining() +{ + return rows_accepted_ >= page_size_; +} + //////////////////////////////////////////////////////////////// void ColumnCountGetFilter::reset() { diff --git a/src/observer/table/ob_htable_filters.h b/src/observer/table/ob_htable_filters.h index 5f7eb0fd6b..7073b87cbc 100644 --- a/src/observer/table/ob_htable_filters.h +++ b/src/observer/table/ob_htable_filters.h @@ -448,6 +448,26 @@ private: DISALLOW_COPY_AND_ASSIGN(SingleColumnValueFilter); }; +/// Simple filter that limits results to a specific page size +class PageFilter: public FilterBase +{ +public: + PageFilter(int64_t page_size) + : page_size_(page_size), + rows_accepted_(0) + {} + virtual ~PageFilter() {} + virtual bool filter_row() override; + virtual bool has_filter_row() override { return true; } + virtual bool filter_all_remaining() override; + TO_STRING_KV("filter", "PageFilter", K_(page_size), K_(rows_accepted)); +private: + int64_t page_size_; + int64_t rows_accepted_; + // disallow copy + DISALLOW_COPY_AND_ASSIGN(PageFilter); +}; + /// Simple filter that returns first N columns on row only. class ColumnCountGetFilter: public FilterBase {