int ObMultipleScanMerge::write_row(ObRow &row) { int ret = OB_SUCCESS; const ObRowDesc *row_desc = NULL; const ObObj *cell = NULL; ObObj value; uint64_t table_id = OB_INVALID_ID; uint64_t column_id = OB_INVALID_ID; row_desc = row.get_row_desc(); if (NULL == row_desc) { ret = OB_INVALID_ARGUMENT; TBSYS_LOG(WARN, "row_desc is null"); } for (int64_t i = row_desc->get_rowkey_cell_count(); OB_SUCCESS == ret && i < row.get_column_num(); i ++) { if (OB_SUCCESS != (ret = row.raw_get_cell(i, cell, table_id, column_id) )) { TBSYS_LOG(WARN, "fail to get cell:ret[%d]", ret); } else if (OB_SUCCESS != (ret = ob_write_obj(allocator_, *cell, value) )) { TBSYS_LOG(WARN, "fail to write obj:ret[%d]", ret); } else if (OB_SUCCESS != (ret = row.raw_set_cell(i, value) )) { TBSYS_LOG(WARN, "fail to set cell:ret[%d]", ret); } } return ret; }
int ObRowStore::add_row(const ObRowkey *rowkey, const ObRow &row, const StoredRow *&stored_row, int64_t &cur_size_counter) { int ret = OB_SUCCESS; if (is_read_only_) { ret = OB_NOT_SUPPORTED; TBSYS_LOG(WARN, "read only ObRowStore, not allow add row, ret=%d", ret); } else { stored_row = NULL; const int32_t reserved_columns_count = static_cast<int32_t>(reserved_columns_.count()); if (NULL == block_list_head_ || block_list_head_->get_remain_size() <= get_compact_row_min_size(row.get_column_num()) + get_reserved_cells_size(reserved_columns_count)) { ret = new_block(); } int64_t retry = 0; while(OB_SUCCESS == ret && retry < 3) { // in case this row would be rollback rollback_block_list_ = block_list_head_; rollback_iter_pos_ = ((block_list_head_==NULL) ? (-1) : block_list_head_->get_curr_data_pos()); // append OrderByCells OB_ASSERT(block_list_head_); StoredRow *reserved_cells = reinterpret_cast<StoredRow*>(block_list_head_->get_buffer()); reserved_cells->reserved_cells_count_ = static_cast<int32_t>(reserved_columns_count); block_list_head_->advance(get_reserved_cells_size(reserved_columns_count)); if (OB_SUCCESS != (ret = append_row(rowkey, row, *block_list_head_, *reserved_cells))) { if (OB_BUF_NOT_ENOUGH == ret) { // buffer not enough block_list_head_->advance( -get_reserved_cells_size(reserved_columns_count) ); TBSYS_LOG(DEBUG, "block buffer not enough, buff=%p remain_size=%ld block_count=%ld block_size=%ld", block_list_head_, block_list_head_->get_remain_size(), block_count_, block_list_head_->block_size_); ret = OB_SUCCESS; ++retry; if (block_list_head_->is_fresh_block()) { if (block_list_head_ == block_list_tail_) { ob_tc_free(block_list_head_, mod_id_); --block_count_; block_list_head_ = block_list_tail_ = NULL; ret = new_block(BIG_BLOCK_SIZE); } else { // free the last normal block BlockInfo *before_last = NULL; BlockInfo *curr = block_list_tail_; BlockInfo *next = NULL; while (NULL != curr) { next = curr->next_block_; if (next == block_list_head_) { before_last = curr; break; } curr = next; } if (NULL == before_last) { TBSYS_LOG(ERROR, "This branch should not be reached, before_last = NULL"); ret = OB_ERR_UNEXPECTED; } else { block_list_head_ = before_last; block_list_head_->next_block_ = NULL; --block_count_; ob_tc_free(next, mod_id_); ret = new_block(BIG_BLOCK_SIZE); } } } else { ret = new_block(NORMAL_BLOCK_SIZE); } } else { TBSYS_LOG(WARN, "failed to append row, err=%d", ret); } } else { cur_size_counter_ += get_reserved_cells_size(reserved_columns_count); stored_row = reserved_cells; cur_size_counter = cur_size_counter_; break; // done } } // end while if (3 <= retry) { ret = OB_ERR_UNEXPECTED; TBSYS_LOG(ERROR, "unexpected branch"); } } return ret; }
TEST_F(ObSqlQueryServiceTest, basic_test) { ObSqlQueryService query_service; ObOperatorFactoryImpl op_factory; OK(query_service.set_operator_factory(&op_factory)); ObFakeUpsRpcStub2 rpc_stub; rpc_stub.set_ups_scan("./tablet_scan_test_data/ups_table1.ini"); rpc_stub.set_ups_multi_get("./tablet_scan_test_data/ups_table2.ini"); OK(query_service.set_ups_rpc_stub(&rpc_stub)); ObSchemaManagerV2 schema_mgr; tbsys::CConfig cfg; ASSERT_TRUE(schema_mgr.parse_from_file("./tablet_scan_test_data/schema.ini", cfg)); OK(query_service.set_schema_manager(&schema_mgr)); query_service.set_join_batch_count(3); ObSqlExpression expr1, expr2, expr3; ObSqlScanParam sql_scan_param; expr1.set_tid_cid(TABLE_ID, 4); ExprItem item_a; item_a.type_ = T_REF_COLUMN; item_a.value_.cell_.tid = TABLE_ID; item_a.value_.cell_.cid = 4; expr1.add_expr_item(item_a); expr1.add_expr_item_end(); OK(sql_scan_param.add_output_column(expr1)); expr2.set_tid_cid(TABLE_ID, 5); ExprItem item_b; item_b.type_ = T_REF_COLUMN; item_b.value_.cell_.tid = TABLE_ID; item_b.value_.cell_.cid = 5; expr2.add_expr_item(item_b); expr2.add_expr_item_end(); OK(sql_scan_param.add_output_column(expr2)); int64_t start = 100; int64_t end = 1000; ObNewRange range; range.table_id_ = TABLE_ID; CharArena arena; gen_new_range(start, end, arena, range); OK(sql_scan_param.set_range(range)); ObRowDesc row_desc; row_desc.add_column_desc(TABLE_ID, 4); row_desc.add_column_desc(TABLE_ID, 5); ObFileTable result("./tablet_scan_test_data/result.ini"); int err = OB_SUCCESS; int64_t count = 0; ObRow row; const ObRow *result_row = NULL; const ObObj *value = NULL; const ObObj *result_value = NULL; uint64_t table_id = 0; uint64_t column_id = 0; ObNewScanner new_scanner; new_scanner.set_mem_size_limit(1024); bool is_fullfilled = false; int64_t fullfilled_item_num = 0; row.set_row_desc(row_desc); OK(query_service.open(sql_scan_param)); OK(result.open()); int run_times = 0; while(OB_SUCCESS == err) { OK(query_service.fill_scan_data(new_scanner)); OK(new_scanner.get_is_req_fullfilled(is_fullfilled, fullfilled_item_num)); run_times ++; while(OB_SUCCESS == err) { err = new_scanner.get_next_row(row); if(OB_SUCCESS != err) { ASSERT_TRUE(OB_ITER_END == err); err = OB_SUCCESS; break; } OK(result.get_next_row(result_row)); count ++; ASSERT_TRUE(row.get_column_num() > 0); for(int64_t i=0;i<row.get_column_num();i++) { OK(row.raw_get_cell(i, value, table_id, column_id)); OK(result_row->get_cell(table_id, column_id, result_value)); if( *value != *result_value ) { printf("row:[%ld], column[%ld]===========\n", count, i); printf("row: %s\n", print_obj(*value)); printf("result: %s\n", print_obj(*result_value)); } ASSERT_TRUE((*value) == (*result_value)); } } if(is_fullfilled) { break; } } printf("I am runinng %d\n", run_times); printf("fullfilled_item_num %ld\n", fullfilled_item_num); }
int ObRowStore::append_row(const ObRowkey *rowkey, const ObRow &row, BlockInfo &block, StoredRow &stored_row) { int ret = OB_SUCCESS; const int64_t reserved_columns_count = reserved_columns_.count(); ObCompactCellWriter cell_writer; if(NULL == rowkey) { cell_writer.init(block.get_buffer(), block.get_remain_size(), SPARSE); } else { cell_writer.init(block.get_buffer(), block.get_remain_size(), DENSE_SPARSE); } const ObObj *cell = NULL; uint64_t table_id = OB_INVALID_ID; uint64_t column_id = OB_INVALID_ID; ObObj cell_clone; const ObUpsRow *ups_row = dynamic_cast<const ObUpsRow *>(&row); if(OB_SUCCESS == ret && NULL != rowkey) { if(OB_SUCCESS != (ret = cell_writer.append_rowkey(*rowkey))) { TBSYS_LOG(WARN, "append rowkey fail:ret[%d]", ret); } } if(OB_SUCCESS == ret && NULL != ups_row) { if( ups_row->get_is_delete_row() ) { if(OB_SUCCESS != (ret = cell_writer.row_delete())) { TBSYS_LOG(WARN, "append row delete flag fail:ret[%d]", ret); } } } int64_t ext_value = 0; for (int64_t i = 0; OB_SUCCESS == ret && i < row.get_column_num(); ++i) { if (OB_SUCCESS != (ret = row.raw_get_cell(i, cell, table_id, column_id))) { TBSYS_LOG(WARN, "failed to get cell, err=%d", ret); break; } if (OB_SUCCESS == ret) { if (ObExtendType == cell->get_type()) { if(OB_SUCCESS != (ret = cell->get_ext(ext_value))) { TBSYS_LOG(WARN, "get ext value fail:ret[%d]", ret); } else if (ObActionFlag::OP_VALID == ext_value) { if (OB_SUCCESS != (ret = cell_writer.append_escape(ObCellMeta::ES_VALID))) { TBSYS_LOG(WARN, "fail to append escape:ret[%d]", ret); } } else if (ObActionFlag::OP_ROW_DOES_NOT_EXIST == ext_value) { if (OB_SUCCESS != (ret = cell_writer.append_escape(ObCellMeta::ES_NOT_EXIST_ROW))) { TBSYS_LOG(WARN, "fail to append escape:ret[%d]", ret); } } else if(ObActionFlag::OP_NOP != ext_value) { ret = OB_NOT_SUPPORTED; TBSYS_LOG(WARN, "not supported ext value:ext[%ld]", ext_value); } else if(NULL == ups_row) { ret = OB_NOT_SUPPORTED; TBSYS_LOG(WARN, "OP_NOP can only used in ups row"); } else //OP_NOP不需要序列化 { cell_clone = *cell; } } else if (OB_SUCCESS != (ret = cell_writer.append(column_id, *cell, &cell_clone))) { if (OB_BUF_NOT_ENOUGH != ret) { TBSYS_LOG(WARN, "failed to append cell, err=%d", ret); } break; } } if (OB_SUCCESS == ret) { // whether reserve this cell for (int32_t j = 0; j < reserved_columns_count; ++j) { const std::pair<uint64_t,uint64_t> &tid_cid = reserved_columns_.at(j); if (table_id == tid_cid.first && column_id == tid_cid.second) { stored_row.reserved_cells_[j] = cell_clone; break; } } // end for j } } // end for i if (OB_SUCCESS == ret) { if (OB_SUCCESS != (ret = cell_writer.row_finish())) { if (OB_BUF_NOT_ENOUGH != ret) { TBSYS_LOG(WARN, "failed to append cell, err=%d", ret); } } else { stored_row.compact_row_size_ = static_cast<int32_t>(cell_writer.size()); block.advance(cell_writer.size()); cur_size_counter_ += cell_writer.size(); } } return ret; }