/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. miniob is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2 THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // // Created by Wangyunlai on 2021/5/14. // #pragma once #include #include #include "common/log/log.h" #include "sql/parser/parse.h" #include "sql/expr/tuple_cell.h" #include "sql/expr/expression.h" #include "storage/record/record.h" class Table; class TupleSchema { public: void append_cell(const TupleCellSpec &cell) { cells_.push_back(cell); } void append_cell(const char *table, const char *field) { append_cell(TupleCellSpec(table, field)); } void append_cell(const char *alias) { append_cell(TupleCellSpec(alias)); } int cell_num() const { return static_cast(cells_.size()); } const TupleCellSpec &cell_at(int i) const { return cells_[i]; } private: std::vector cells_; }; class Tuple { public: Tuple() = default; virtual ~Tuple() = default; virtual int cell_num() const = 0; virtual RC cell_at(int index, TupleCell &cell) const = 0; virtual RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const = 0; }; class RowTuple : public Tuple { public: RowTuple() = default; virtual ~RowTuple() { for (FieldExpr *spec : speces_) { delete spec; } speces_.clear(); } void set_record(Record *record) { this->record_ = record; } void set_schema(const Table *table, const std::vector *fields) { table_ = table; this->speces_.reserve(fields->size()); for (const FieldMeta &field : *fields) { speces_.push_back(new FieldExpr(table, &field)); } } int cell_num() const override { return speces_.size(); } RC cell_at(int index, TupleCell &cell) const override { if (index < 0 || index >= static_cast(speces_.size())) { LOG_WARN("invalid argument. index=%d", index); return RC::INVALID_ARGUMENT; } FieldExpr *field_expr = speces_[index]; const FieldMeta *field_meta = field_expr->field().meta(); cell.set_type(field_meta->type()); cell.set_data(this->record_->data() + field_meta->offset(), field_meta->len()); return RC::SUCCESS; } RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const override { const char *table_name = spec.table_name(); const char *field_name = spec.field_name(); if (0 != strcmp(table_name, table_->name())) { return RC::NOTFOUND; } for (size_t i = 0; i < speces_.size(); ++i) { const FieldExpr *field_expr = speces_[i]; const Field &field = field_expr->field(); if (0 == strcmp(field_name, field.field_name())) { return cell_at(i, cell); } } return RC::NOTFOUND; } #if 0 RC cell_spec_at(int index, const TupleCellSpec *&spec) const override { if (index < 0 || index >= static_cast(speces_.size())) { LOG_WARN("invalid argument. index=%d", index); return RC::INVALID_ARGUMENT; } spec = speces_[index]; return RC::SUCCESS; } #endif Record &record() { return *record_; } const Record &record() const { return *record_; } private: Record *record_ = nullptr; const Table *table_ = nullptr; std::vector speces_; }; class ProjectTuple : public Tuple { public: ProjectTuple() = default; virtual ~ProjectTuple() { for (TupleCellSpec *spec : speces_) { delete spec; } speces_.clear(); } void set_tuple(Tuple *tuple) { this->tuple_ = tuple; } void add_cell_spec(TupleCellSpec *spec) { speces_.push_back(spec); } int cell_num() const override { return speces_.size(); } RC cell_at(int index, TupleCell &cell) const override { if (index < 0 || index >= static_cast(speces_.size())) { return RC::INTERNAL; } if (tuple_ == nullptr) { return RC::INTERNAL; } const TupleCellSpec *spec = speces_[index]; return tuple_->find_cell(*spec, cell); } RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const override { return tuple_->find_cell(spec, cell); } #if 0 RC cell_spec_at(int index, const TupleCellSpec *&spec) const override { if (index < 0 || index >= static_cast(speces_.size())) { return RC::NOTFOUND; } spec = speces_[index]; return RC::SUCCESS; } #endif private: std::vector speces_; Tuple *tuple_ = nullptr; }; class ValueListTuple : public Tuple { public: ValueListTuple() = default; virtual ~ValueListTuple() = default; void set_cells(const std::vector &cells) { cells_ = cells; } virtual int cell_num() const override { return static_cast(cells_.size()); } virtual RC cell_at(int index, TupleCell &cell) const override { if (index < 0 || index >= cell_num()) { return RC::NOTFOUND; } cell = cells_[index]; return RC::SUCCESS; } virtual RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const override { return RC::INTERNAL; } private: std::vector cells_; }; /** * 将两个tuple合并为一个tuple * 在join算子中使用 */ class JoinedTuple : public Tuple { public: JoinedTuple() = default; virtual ~JoinedTuple() = default; void set_left(Tuple *left) { left_ = left; } void set_right(Tuple *right) { right_ = right; } int cell_num() const override { return left_->cell_num() + right_->cell_num(); } RC cell_at(int index, TupleCell &cell) const override { const int left_cell_num = left_->cell_num(); if (index > 0 && index < left_cell_num) { return left_->cell_at(index, cell); } if (index >= left_cell_num && index < left_cell_num + right_->cell_num()) { return right_->cell_at(index - left_cell_num, cell); } return RC::NOTFOUND; } RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const override { RC rc = left_->find_cell(spec, cell); if (rc == RC::SUCCESS || rc != RC::NOTFOUND) { return rc; } return right_->find_cell(spec, cell); } private: Tuple *left_ = nullptr; Tuple *right_ = nullptr; };