提交 3d84e93f 编写于 作者: 羽飞's avatar 羽飞

select and delete can work now

1. select return all columns;
2. no tuple header now;
3. predicate works now.
上级 95c306f9
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/6/27.
//
#include "common/log/log.h"
#include "sql/executor/delete_operator.h"
#include "storage/common/record.h"
#include "storage/common/table.h"
#include "sql/stmt/delete_stmt.h"
RC DeleteOperator::open()
{
if (children_.size() != 1) {
LOG_WARN("delete operator must has 1 child");
return RC::INTERNAL;
}
Operator *child = children_[0];
RC rc = child->open();
if (rc != RC::SUCCESS) {
LOG_WARN("failed to open child operator: %s", strrc(rc));
return rc;
}
Record record;
Table *table = delete_stmt_->table();
while (RC::SUCCESS == (rc = child->next())) {
rc = child->current_record(record);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to get current record: %s", strrc(rc));
return rc;
}
rc = table->delete_record(nullptr, &record);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to delete record: %s", strrc(rc));
return rc;
}
}
return RC::SUCCESS;
}
RC DeleteOperator::next()
{
return RC::RECORD_EOF;
}
RC DeleteOperator::close()
{
children_[0]->close();
return RC::SUCCESS;
}
......@@ -9,12 +9,12 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/9.
// Created by WangYunlai on 2022/6/9.
//
#pragma once
#include "sql/parser/parse.h"
#include "sql/executor/operator.h"
#include "rc.h"
class DeleteStmt;
......@@ -26,12 +26,15 @@ public:
: delete_stmt_(delete_stmt)
{}
virtual ~InsertOperator() = default;
virtual ~DeleteOperator() = default;
RC open() override;
RC next() override;
RC close() override;
RC current_record(Record &record) override {
return RC::GENERIC_ERROR;
}
private:
InsertStmt *insert_stmt_ = nullptr;
DeleteStmt *delete_stmt_ = nullptr;
};
......@@ -28,6 +28,8 @@ See the Mulan PSL v2 for more details. */
#include "sql/executor/execution_node.h"
#include "sql/executor/tuple.h"
#include "sql/executor/table_scan_operator.h"
#include "sql/executor/predicate_operator.h"
#include "sql/executor/delete_operator.h"
#include "sql/stmt/stmt.h"
#include "sql/stmt/select_stmt.h"
#include "sql/stmt/update_stmt.h"
......@@ -130,7 +132,7 @@ void ExecuteStage::handle_request(common::StageEvent *event)
if (stmt != nullptr) {
switch (stmt->type()) {
case StmtType::SELECT: {
do_select((SelectStmt *)stmt, session_event);
do_select(sql_event);
} break;
case StmtType::INSERT: {
do_insert(sql_event);
......@@ -139,7 +141,7 @@ void ExecuteStage::handle_request(common::StageEvent *event)
//do_update((UpdateStmt *)stmt, session_event);
} break;
case StmtType::DELETE: {
//do_delete((DeleteStmt *)stmt, session_event);
do_delete(sql_event);
} break;
}
} else {
......@@ -227,11 +229,6 @@ void record_to_string(std::ostream &os, const Record &record)
break;
}
const FieldMeta *field_meta = field.meta();
if (!field_meta->visible()) {
continue;
}
if (!first_field) {
os << " | ";
} else {
......@@ -240,8 +237,10 @@ void record_to_string(std::ostream &os, const Record &record)
field.to_string(os);
}
}
RC ExecuteStage::do_select(SelectStmt *select_stmt, SessionEvent *session_event)
RC ExecuteStage::do_select(SQLStageEvent *sql_event)
{
SelectStmt *select_stmt = (SelectStmt *)(sql_event->stmt());
SessionEvent *session_event = sql_event->session_event();
RC rc = RC::SUCCESS;
if (select_stmt->tables().size() != 1) {
LOG_WARN("select more than 1 tables is not supported");
......@@ -526,3 +525,29 @@ RC ExecuteStage::do_insert(SQLStageEvent *sql_event)
}
return rc;
}
RC ExecuteStage::do_delete(SQLStageEvent *sql_event)
{
Stmt *stmt = sql_event->stmt();
SessionEvent *session_event = sql_event->session_event();
if (stmt == nullptr) {
LOG_WARN("cannot find statement");
return RC::GENERIC_ERROR;
}
DeleteStmt *delete_stmt = (DeleteStmt *)stmt;
TableScanOperator scan_oper(delete_stmt->table());
PredicateOperator pred_oper(delete_stmt->filter_stmt());
pred_oper.add_child(&scan_oper);
DeleteOperator delete_oper(delete_stmt);
delete_oper.add_child(&pred_oper);
RC rc = delete_oper.open();
if (rc != RC::SUCCESS) {
session_event->set_response("FAILURE");
} else {
session_event->set_response("SUCCESS");
}
return rc;
}
......@@ -44,8 +44,9 @@ protected:
RC do_create_index(SQLStageEvent *sql_event);
RC do_show_tables(SQLStageEvent *sql_event);
RC do_desc_table(SQLStageEvent *sql_event);
RC do_select(SelectStmt *select_stmt, SessionEvent *session_event);
RC do_select(SQLStageEvent *sql_event);
RC do_insert(SQLStageEvent *sql_event);
RC do_delete(SQLStageEvent *sql_event);
protected:
private:
......
......@@ -14,8 +14,7 @@ See the Mulan PSL v2 for more details. */
#pragma once
#include "common/seda/stage.h"
#include "sql/parser/parse.h"
#include <vector>
#include "rc.h"
class Record;
......@@ -33,5 +32,11 @@ public:
virtual RC close() = 0;
virtual RC current_record(Record &record) = 0;
private:
void add_child(Operator *oper) {
children_.push_back(oper);
}
protected:
std::vector<Operator *> children_;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/6/27.
//
#pragma once
#include "common/log/log.h"
#include "sql/executor/predicate_operator.h"
#include "storage/common/record.h"
#include "sql/stmt/filter_stmt.h"
#include "storage/common/field.h"
RC PredicateOperator::open()
{
if (children_.size() != 1) {
LOG_WARN("predicate operator must has one child");
return RC::INTERNAL;
}
return children_[0]->open();
}
RC PredicateOperator::next()
{
RC rc = RC::SUCCESS;
Operator *oper = children_[0];
Record record;
while (RC::SUCCESS == (rc = oper->next())) {
rc = oper->current_record(record);
if (rc != RC::SUCCESS) {
break;
}
if (do_predicate(record)) {
return rc;
}
}
return rc;
}
RC PredicateOperator::close()
{
children_[0]->close();
return RC::SUCCESS;
}
RC PredicateOperator::current_record(Record &record)
{
return children_[0]->current_record(record);
}
void get_cell(const Record &record, const FilterItem &filter_item, Field &cell)
{
if (filter_item.is_attr()) {
cell.set_data(record.data() + filter_item.field().field()->offset());
cell.set_type(filter_item.field().field()->type());
} else {
cell.set_data((char *)filter_item.value().data);
cell.set_type(filter_item.value().type);
}
}
bool PredicateOperator::do_predicate(Record &record)
{
if (filter_stmt_ == nullptr) {
return true;
}
for (const FilterUnit &filter_unit : filter_stmt_->filter_units()) {
const FilterItem & left = filter_unit.left();
const FilterItem & right = filter_unit.right();
CompOp comp = filter_unit.comp();
Field left_cell;
Field right_cell;
get_cell(record, left, left_cell);
get_cell(record, right, right_cell);
const int compare = left_cell.compare(right_cell);
switch (comp) {
case EQUAL_TO: return 0 == compare;
case LESS_EQUAL: return compare <= 0;
case NOT_EQUAL: return compare != 0;
case LESS_THAN: return compare < 0;
case GREAT_EQUAL: return compare >= 0;
case GREAT_THAN: return compare > 0;
default: {
LOG_WARN("invalid compare type: %d", comp);
}
}
}
return false;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/6/27.
//
#pragma once
#include "sql/executor/operator.h"
class FilterStmt;
class PredicateOperator : public Operator
{
public:
PredicateOperator(FilterStmt *filter_stmt)
: filter_stmt_(filter_stmt)
{}
virtual ~PredicateOperator() = default;
RC open() override;
RC next() override;
RC close() override;
RC current_record(Record &record) override;
private:
bool do_predicate(Record &record);
private:
FilterStmt *filter_stmt_ = nullptr;
};
......@@ -29,18 +29,6 @@ RC TableScanOperator::next()
RC rc = record_scanner_.next(current_record_);
current_record_.set_fields(table_->table_meta().field_metas());
while (rc == RC::SUCCESS) {
//if (predicate_ != nullptr && predicate_->filter(current_record_)) {
return rc;
//}
if (record_scanner_.has_next()) {
rc = record_scanner_.next(current_record_);
current_record_.set_fields(table_->table_meta().field_metas());
} else {
rc = RC::RECORD_EOF;
}
}
return rc;
}
......
......@@ -26,11 +26,7 @@ class TableScanOperator : public Operator
{
public:
TableScanOperator(Table *table)
: table_(table), predicate_(nullptr)
{}
TableScanOperator(Table *table, Predicate *pred)
: table_(table), predicate_(pred)
: table_(table)
{}
virtual ~TableScanOperator() = default;
......@@ -43,6 +39,5 @@ public:
private:
Table *table_ = nullptr;
RecordFileScanner record_scanner_;
Predicate *predicate_ = nullptr;
Record current_record_;
};
......@@ -92,6 +92,10 @@ public:
void set_comp(CompOp comp) {
comp_ = comp;
}
CompOp comp() const {
return comp_;
}
FilterItem &left() {
return left_;
}
......
#include "storage/common/field.h"
#include "common/log/log.h"
#include "util/comparator.h"
void Field::to_string(std::ostream &os) const
{
switch (meta_->type()) {
switch (attr_type_) {
case INTS: {
os << *(int *)data_;
} break;
......@@ -19,7 +20,29 @@ void Field::to_string(std::ostream &os) const
}
} break;
default: {
LOG_WARN("unsupported attr type: %d", meta_->type());
LOG_WARN("unsupported attr type: %d", attr_type_);
} break;
}
}
int Field::compare(const Field &other) const
{
if (this->attr_type_ == other.attr_type_) {
switch (this->attr_type_) {
case INTS: return compare_int(this->data_, other.data_);
case FLOATS: return compare_float(this->data_, other.data_);
case CHARS: return compare_string(this->data_, other.data_, 4);
default: {
LOG_WARN("unsupported type: %d", this->attr_type_);
}
}
} else if (this->attr_type_ == INTS && other.attr_type_ == FLOATS) {
float this_data = *(int *)data_;
return compare_float(&this_data, other.data_);
} else if (this->attr_type_ == FLOATS && other.attr_type_ == INTS) {
float other_data = *(int *)other.data_;
return compare_float(data_, &other_data);
}
LOG_WARN("not supported");
return -1; // TODO return rc?
}
......@@ -4,7 +4,7 @@
#include "storage/common/table.h"
#include "storage/common/field_meta.h"
class Field
class Field // TODO rename to Cell
{
public:
Field() = default;
......@@ -12,17 +12,20 @@ public:
Field(FieldMeta *meta, char *data) : Field(nullptr, meta, data)
{}
Field(Table *table, FieldMeta *meta, char *data)
: table_(table), meta_(meta), data_(data)
: table_(table), attr_type_(meta->type()), data_(data)
{}
void set_table(Table *table) { this->table_ = table; }
void set_meta(const FieldMeta *meta) { this->meta_ = meta; }
void set_type(AttrType type) { this->attr_type_ = type; }
void set_data(char *data) { this->data_ = data; }
void set_data(const char *data) { this->set_data(const_cast<char *>(data)); }
const FieldMeta *meta() const { return meta_; }
void to_string(std::ostream &os) const;
int compare(const Field &other) const;
private:
Table *table_ = nullptr;
const FieldMeta *meta_ = nullptr;
AttrType attr_type_ = UNDEFINED;
char *data_ = nullptr; // real data. no need to move to field_meta.offset
};
......@@ -11,7 +11,7 @@ RC Record::field_at(int index, Field &field) const
}
const FieldMeta &field_meta = (*fields_)[index];
field.set_meta(&field_meta);
field.set_type(field_meta.type());
field.set_data(this->data_ + field_meta.offset());
return RC::SUCCESS;
}
......
......@@ -55,6 +55,7 @@ public:
RC update_record(Trx *trx, const char *attribute_name, const Value *value, int condition_num,
const Condition conditions[], int *updated_count);
RC delete_record(Trx *trx, ConditionFilter *filter, int *deleted_count);
RC delete_record(Trx *trx, Record *record);
RC scan_record(Trx *trx, ConditionFilter *filter, int limit, void *context,
void (*record_reader)(const char *data, void *context));
......@@ -85,7 +86,6 @@ private:
IndexScanner *find_index_for_scan(const DefaultConditionFilter &filter);
RC insert_record(Trx *trx, Record *record);
RC delete_record(Trx *trx, Record *record);
private:
friend class RecordUpdater;
......
......@@ -16,4 +16,4 @@ See the Mulan PSL v2 for more details. */
int compare_int(void *arg1, void *arg2);
int compare_float(void *arg1, void *arg2);
int compare_string(void *arg1, void *arg2);
int compare_string(void *arg1, void *arg2, int max_length);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册