tuple.h 8.3 KB
Newer Older
羽飞's avatar
羽飞 已提交
1
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
羽飞's avatar
羽飞 已提交
2 3 4 5 6 7 8 9 10 11
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. */

//
羽飞's avatar
羽飞 已提交
12
// Created by Wangyunlai on 2021/5/14.
羽飞's avatar
羽飞 已提交
13 14
//

羽飞's avatar
羽飞 已提交
15
#pragma once
羽飞's avatar
羽飞 已提交
16 17 18

#include <memory>
#include <vector>
羽飞's avatar
羽飞 已提交
19
#include <string>
羽飞's avatar
羽飞 已提交
20

羽飞's avatar
羽飞 已提交
21
#include "common/log/log.h"
羽飞's avatar
羽飞 已提交
22
#include "sql/expr/tuple_cell.h"
羽飞's avatar
羽飞 已提交
23 24
#include "sql/parser/parse.h"
#include "sql/parser/value.h"
羽飞's avatar
羽飞 已提交
25
#include "sql/expr/expression.h"
羽飞's avatar
羽飞 已提交
26
#include "storage/record/record.h"
羽飞's avatar
羽飞 已提交
27 28 29

class Table;

羽飞's avatar
羽飞 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
/**
 * @defgroup Tuple
 * @brief Tuple 元组,表示一行数据,当前返回客户端时使用
 * @details 
 * tuple是一种可以嵌套的数据结构。
 * 比如select t1.a+t2.b from t1, t2;
 * 需要使用下面的结构表示:
 * @code {.cpp}
 *  Project(t1.a+t2.b)
 *        |
 *      Joined
 *      /     \
 *   Row(t1) Row(t2)
 * @endcode
 * 
 */

/**
 * @brief 元组的结构,包含哪些字段(这里成为Cell),每个字段的说明
 * @ingroup Tuple
 */
羽飞's avatar
羽飞 已提交
51 52
class TupleSchema 
{
L
Longda Feng 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
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<int>(cells_.size());
  }
  const TupleCellSpec &cell_at(int i) const
  {
    return cells_[i];
  }
羽飞's avatar
羽飞 已提交
74 75

private:
羽飞's avatar
羽飞 已提交
76
  std::vector<TupleCellSpec> cells_;
羽飞's avatar
羽飞 已提交
77 78
};

羽飞's avatar
羽飞 已提交
79 80 81 82
/**
 * @brief 元组的抽象描述
 * @ingroup Tuple
 */
羽飞's avatar
羽飞 已提交
83 84
class Tuple 
{
羽飞's avatar
羽飞 已提交
85 86
public:
  Tuple() = default;
羽飞's avatar
羽飞 已提交
87
  virtual ~Tuple() = default;
羽飞's avatar
羽飞 已提交
88

羽飞's avatar
羽飞 已提交
89 90 91 92
  /**
   * @brief 获取元组中的Cell的个数
   * @details 个数应该与tuple_schema一致
   */
L
Longda Feng 已提交
93
  virtual int cell_num() const = 0;
羽飞's avatar
羽飞 已提交
94 95 96 97 98 99 100

  /**
   * @brief 获取指定位置的Cell
   * 
   * @param index 位置
   * @param[out] cell  返回的Cell
   */
羽飞's avatar
羽飞 已提交
101
  virtual RC cell_at(int index, Value &cell) const = 0;
羽飞's avatar
羽飞 已提交
102 103 104 105 106 107 108

  /**
   * @brief 根据cell的描述,获取cell的值
   * 
   * @param spec cell的描述
   * @param[out] cell 返回的cell
   */
羽飞's avatar
羽飞 已提交
109
  virtual RC find_cell(const TupleCellSpec &spec, Value &cell) const = 0;
羽飞's avatar
羽飞 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

  virtual std::string to_string() const
  {
    std::string str;
    const int cell_num = this->cell_num();
    for (int i = 0; i < cell_num - 1; i++) {
      Value cell;
      cell_at(i, cell);
      str += cell.to_string();
      str += ", ";
    }

    if (cell_num > 0) {
      Value cell;
      cell_at(cell_num - 1, cell);
      str += cell.to_string();
    }
    return str;
  }
羽飞's avatar
羽飞 已提交
129
};
羽飞's avatar
羽飞 已提交
130

羽飞's avatar
羽飞 已提交
131 132 133 134 135
/**
 * @brief 一行数据的元组
 * @ingroup Tuple
 * @details 直接就是获取表中的一条记录
 */
羽飞's avatar
羽飞 已提交
136 137
class RowTuple : public Tuple 
{
羽飞's avatar
羽飞 已提交
138 139
public:
  RowTuple() = default;
羽飞's avatar
羽飞 已提交
140 141
  virtual ~RowTuple()
  {
羽飞's avatar
羽飞 已提交
142
    for (FieldExpr *spec : speces_) {
羽飞's avatar
羽飞 已提交
143 144 145 146
      delete spec;
    }
    speces_.clear();
  }
L
Longda Feng 已提交
147

羽飞's avatar
羽飞 已提交
148
  void set_record(Record *record)
149
  {
羽飞's avatar
羽飞 已提交
150
    this->record_ = record;
羽飞's avatar
羽飞 已提交
151 152
  }

羽飞's avatar
羽飞 已提交
153
  void set_schema(const Table *table, const std::vector<FieldMeta> *fields)
154
  {
羽飞's avatar
羽飞 已提交
155 156 157
    table_ = table;
    this->speces_.reserve(fields->size());
    for (const FieldMeta &field : *fields) {
羽飞's avatar
羽飞 已提交
158
      speces_.push_back(new FieldExpr(table, &field));
羽飞's avatar
羽飞 已提交
159
    }
羽飞's avatar
羽飞 已提交
160 161
  }

羽飞's avatar
羽飞 已提交
162
  int cell_num() const override
163
  {
羽飞's avatar
羽飞 已提交
164
    return speces_.size();
羽飞's avatar
羽飞 已提交
165 166
  }

羽飞's avatar
羽飞 已提交
167
  RC cell_at(int index, Value &cell) const override
168
  {
羽飞's avatar
羽飞 已提交
169
    if (index < 0 || index >= static_cast<int>(speces_.size())) {
羽飞's avatar
羽飞 已提交
170 171 172 173
      LOG_WARN("invalid argument. index=%d", index);
      return RC::INVALID_ARGUMENT;
    }

羽飞's avatar
羽飞 已提交
174
    FieldExpr *field_expr = speces_[index];
羽飞's avatar
羽飞 已提交
175 176
    const FieldMeta *field_meta = field_expr->field().meta();
    cell.set_type(field_meta->type());
羽飞's avatar
羽飞 已提交
177
    cell.set_data(this->record_->data() + field_meta->offset(), field_meta->len());
羽飞's avatar
羽飞 已提交
178
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
179 180
  }

羽飞's avatar
羽飞 已提交
181
  RC find_cell(const TupleCellSpec &spec, Value &cell) const override
羽飞's avatar
羽飞 已提交
182
  {
羽飞's avatar
羽飞 已提交
183 184
    const char *table_name = spec.table_name();
    const char *field_name = spec.field_name();
羽飞's avatar
羽飞 已提交
185 186 187 188
    if (0 != strcmp(table_name, table_->name())) {
      return RC::NOTFOUND;
    }

羽飞's avatar
羽飞 已提交
189
    for (size_t i = 0; i < speces_.size(); ++i) {
L
Longda Feng 已提交
190
      const FieldExpr *field_expr = speces_[i];
羽飞's avatar
羽飞 已提交
191 192
      const Field &field = field_expr->field();
      if (0 == strcmp(field_name, field.field_name())) {
L
Longda Feng 已提交
193
        return cell_at(i, cell);
羽飞's avatar
羽飞 已提交
194 195 196 197 198
      }
    }
    return RC::NOTFOUND;
  }

L
Longda Feng 已提交
199
#if 0
羽飞's avatar
羽飞 已提交
200
  RC cell_spec_at(int index, const TupleCellSpec *&spec) const override
201
  {
羽飞's avatar
羽飞 已提交
202
    if (index < 0 || index >= static_cast<int>(speces_.size())) {
羽飞's avatar
羽飞 已提交
203 204 205
      LOG_WARN("invalid argument. index=%d", index);
      return RC::INVALID_ARGUMENT;
    }
羽飞's avatar
羽飞 已提交
206
    spec = speces_[index];
羽飞's avatar
羽飞 已提交
207
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
208
  }
L
Longda Feng 已提交
209
#endif
羽飞's avatar
羽飞 已提交
210

羽飞's avatar
羽飞 已提交
211
  Record &record()
212
  {
羽飞's avatar
羽飞 已提交
213
    return *record_;
羽飞's avatar
羽飞 已提交
214 215
  }

羽飞's avatar
羽飞 已提交
216
  const Record &record() const
217
  {
羽飞's avatar
羽飞 已提交
218
    return *record_;
羽飞's avatar
羽飞 已提交
219
  }
L
Longda Feng 已提交
220

羽飞's avatar
羽飞 已提交
221
private:
羽飞's avatar
羽飞 已提交
222
  Record *record_ = nullptr;
羽飞's avatar
羽飞 已提交
223
  const Table *table_ = nullptr;
羽飞's avatar
羽飞 已提交
224
  std::vector<FieldExpr *> speces_;
羽飞's avatar
羽飞 已提交
225
};
羽飞's avatar
羽飞 已提交
226

羽飞's avatar
羽飞 已提交
227 228 229 230 231 232 233
/**
 * @brief 从一行数据中,选择部分字段组成的元组,也就是投影操作
 * @ingroup Tuple
 * @details 一般在select语句中使用。
 * 投影也可以是很复杂的操作,比如某些字段需要做类型转换、重命名、表达式运算、函数计算等。
 * 当前的实现是比较简单的,只是选择部分字段,不做任何其他操作。
 */
羽飞's avatar
羽飞 已提交
234 235
class ProjectTuple : public Tuple 
{
羽飞's avatar
羽飞 已提交
236 237
public:
  ProjectTuple() = default;
羽飞's avatar
羽飞 已提交
238 239 240 241 242 243 244
  virtual ~ProjectTuple()
  {
    for (TupleCellSpec *spec : speces_) {
      delete spec;
    }
    speces_.clear();
  }
羽飞's avatar
羽飞 已提交
245 246 247 248 249 250

  void set_tuple(Tuple *tuple)
  {
    this->tuple_ = tuple;
  }

羽飞's avatar
羽飞 已提交
251
  void add_cell_spec(TupleCellSpec *spec)
羽飞's avatar
羽飞 已提交
252 253 254 255 256 257 258 259
  {
    speces_.push_back(spec);
  }
  int cell_num() const override
  {
    return speces_.size();
  }

羽飞's avatar
羽飞 已提交
260
  RC cell_at(int index, Value &cell) const override
羽飞's avatar
羽飞 已提交
261
  {
羽飞's avatar
羽飞 已提交
262
    if (index < 0 || index >= static_cast<int>(speces_.size())) {
羽飞's avatar
羽飞 已提交
263
      return RC::INTERNAL;
羽飞's avatar
羽飞 已提交
264 265
    }
    if (tuple_ == nullptr) {
羽飞's avatar
羽飞 已提交
266
      return RC::INTERNAL;
羽飞's avatar
羽飞 已提交
267 268
    }

羽飞's avatar
羽飞 已提交
269
    const TupleCellSpec *spec = speces_[index];
羽飞's avatar
羽飞 已提交
270
    return tuple_->find_cell(*spec, cell);
羽飞's avatar
羽飞 已提交
271 272
  }

羽飞's avatar
羽飞 已提交
273
  RC find_cell(const TupleCellSpec &spec, Value &cell) const override
羽飞's avatar
羽飞 已提交
274
  {
羽飞's avatar
羽飞 已提交
275
    return tuple_->find_cell(spec, cell);
羽飞's avatar
羽飞 已提交
276
  }
羽飞's avatar
羽飞 已提交
277

L
Longda Feng 已提交
278
#if 0
羽飞's avatar
羽飞 已提交
279
  RC cell_spec_at(int index, const TupleCellSpec *&spec) const override
羽飞's avatar
羽飞 已提交
280
  {
羽飞's avatar
羽飞 已提交
281
    if (index < 0 || index >= static_cast<int>(speces_.size())) {
羽飞's avatar
羽飞 已提交
282 283 284 285 286
      return RC::NOTFOUND;
    }
    spec = speces_[index];
    return RC::SUCCESS;
  }
L
Longda Feng 已提交
287
#endif
羽飞's avatar
羽飞 已提交
288
private:
羽飞's avatar
羽飞 已提交
289
  std::vector<TupleCellSpec *> speces_;
羽飞's avatar
羽飞 已提交
290 291
  Tuple *tuple_ = nullptr;
};
羽飞's avatar
羽飞 已提交
292

羽飞's avatar
羽飞 已提交
293 294 295 296
/**
 * @brief 一些常量值组成的Tuple
 * @ingroup Tuple
 */
羽飞's avatar
羽飞 已提交
297 298
class ValueListTuple : public Tuple 
{
L
Longda Feng 已提交
299
public:
羽飞's avatar
羽飞 已提交
300 301 302
  ValueListTuple() = default;
  virtual ~ValueListTuple() = default;

羽飞's avatar
羽飞 已提交
303
  void set_cells(const std::vector<Value> &cells)
羽飞's avatar
羽飞 已提交
304 305 306 307 308 309 310 311 312
  {
    cells_ = cells;
  }

  virtual int cell_num() const override
  {
    return static_cast<int>(cells_.size());
  }

羽飞's avatar
羽飞 已提交
313
  virtual RC cell_at(int index, Value &cell) const override
羽飞's avatar
羽飞 已提交
314 315 316 317 318 319 320 321 322
  {
    if (index < 0 || index >= cell_num()) {
      return RC::NOTFOUND;
    }

    cell = cells_[index];
    return RC::SUCCESS;
  }

羽飞's avatar
羽飞 已提交
323
  virtual RC find_cell(const TupleCellSpec &spec, Value &cell) const override
羽飞's avatar
羽飞 已提交
324 325 326 327 328
  {
    return RC::INTERNAL;
  }

private:
羽飞's avatar
羽飞 已提交
329
  std::vector<Value> cells_;
羽飞's avatar
羽飞 已提交
330
};
羽飞's avatar
羽飞 已提交
331 332

/**
羽飞's avatar
羽飞 已提交
333 334 335
 * @brief 将两个tuple合并为一个tuple
 * @ingroup Tuple
 * @details 在join算子中使用
羽飞's avatar
羽飞 已提交
336
 */
羽飞's avatar
羽飞 已提交
337 338
class JoinedTuple : public Tuple 
{
羽飞's avatar
羽飞 已提交
339 340 341 342
public:
  JoinedTuple() = default;
  virtual ~JoinedTuple() = default;

L
Longda Feng 已提交
343 344 345 346 347 348 349 350 351
  void set_left(Tuple *left)
  {
    left_ = left;
  }
  void set_right(Tuple *right)
  {
    right_ = right;
  }

羽飞's avatar
羽飞 已提交
352 353 354 355 356
  int cell_num() const override
  {
    return left_->cell_num() + right_->cell_num();
  }

羽飞's avatar
羽飞 已提交
357
  RC cell_at(int index, Value &value) const override
羽飞's avatar
羽飞 已提交
358 359
  {
    const int left_cell_num = left_->cell_num();
L
Longda Feng 已提交
360
    if (index > 0 && index < left_cell_num) {
羽飞's avatar
羽飞 已提交
361
      return left_->cell_at(index, value);
羽飞's avatar
羽飞 已提交
362 363 364
    }

    if (index >= left_cell_num && index < left_cell_num + right_->cell_num()) {
羽飞's avatar
羽飞 已提交
365
      return right_->cell_at(index - left_cell_num, value);
羽飞's avatar
羽飞 已提交
366 367 368 369 370
    }

    return RC::NOTFOUND;
  }

羽飞's avatar
羽飞 已提交
371
  RC find_cell(const TupleCellSpec &spec, Value &value) const override
羽飞's avatar
羽飞 已提交
372
  {
羽飞's avatar
羽飞 已提交
373
    RC rc = left_->find_cell(spec, value);
羽飞's avatar
羽飞 已提交
374 375 376 377
    if (rc == RC::SUCCESS || rc != RC::NOTFOUND) {
      return rc;
    }

羽飞's avatar
羽飞 已提交
378
    return right_->find_cell(spec, value);
羽飞's avatar
羽飞 已提交
379
  }
L
Longda Feng 已提交
380

羽飞's avatar
羽飞 已提交
381
private:
L
Longda Feng 已提交
382 383
  Tuple *left_ = nullptr;
  Tuple *right_ = nullptr;
羽飞's avatar
羽飞 已提交
384
};