未验证 提交 e279dc7a 编写于 作者: 羽飞's avatar 羽飞 提交者: GitHub

mysql communicator (#124)

tested by mariadb ( Ver 15.1 Distrib 5.5.65-MariaDB, for Linux (x86_64) using readline 5.1)
but failed with obclient
上级 28eee7d5
...@@ -55,7 +55,7 @@ SET(CMAKE_CXX_FLAGS ${CMAKE_COMMON_FLAGS}) ...@@ -55,7 +55,7 @@ SET(CMAKE_CXX_FLAGS ${CMAKE_COMMON_FLAGS})
SET(CMAKE_C_FLAGS ${CMAKE_COMMON_FLAGS}) SET(CMAKE_C_FLAGS ${CMAKE_COMMON_FLAGS})
MESSAGE("CMAKE_CXX_FLAGS is " ${CMAKE_CXX_FLAGS}) MESSAGE("CMAKE_CXX_FLAGS is " ${CMAKE_CXX_FLAGS})
OPTION(ENABLE_ASAN OFF "Enable build with address sanitizer") OPTION(ENABLE_ASAN "Enable build with address sanitizer" ON)
IF (ENABLE_ASAN) IF (ENABLE_ASAN)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
......
...@@ -110,6 +110,16 @@ public: ...@@ -110,6 +110,16 @@ public:
return unix_socket_path_; return unix_socket_path_;
} }
void set_protocol(const char *protocol)
{
protocol_ = protocol;
}
const std::string &get_protocol() const
{
return protocol_;
}
private: private:
std::string std_out_; // The output file std::string std_out_; // The output file
std::string std_err_; // The err output file std::string std_err_; // The err output file
...@@ -119,6 +129,7 @@ private: ...@@ -119,6 +129,7 @@ private:
std::vector<std::string> args; // arguments std::vector<std::string> args; // arguments
int server_port_ = -1; // server port(if valid, will overwrite the port in the config file) int server_port_ = -1; // server port(if valid, will overwrite the port in the config file)
std::string unix_socket_path_; std::string unix_socket_path_;
std::string protocol_;
}; };
ProcessParam *&the_process_param(); ProcessParam *&the_process_param();
......
...@@ -13,23 +13,28 @@ See the Mulan PSL v2 for more details. */ ...@@ -13,23 +13,28 @@ See the Mulan PSL v2 for more details. */
// //
#include "session_event.h" #include "session_event.h"
#include "net/communicator.h"
SessionEvent::SessionEvent(ConnectionContext *client) : client_(client) SessionEvent::SessionEvent(Communicator *comm) : communicator_(comm)
{ {
} }
SessionEvent::~SessionEvent() SessionEvent::~SessionEvent()
{ {
if (sql_result_) {
delete sql_result_;
sql_result_ = nullptr;
}
} }
ConnectionContext *SessionEvent::get_client() const Communicator *SessionEvent::get_communicator() const
{ {
return client_; return communicator_;
} }
Session *SessionEvent::session() const Session *SessionEvent::session() const
{ {
return client_->session; return communicator_->session();
} }
const char *SessionEvent::get_response() const const char *SessionEvent::get_response() const
...@@ -57,12 +62,7 @@ int SessionEvent::get_response_len() const ...@@ -57,12 +62,7 @@ int SessionEvent::get_response_len() const
return response_.size(); return response_.size();
} }
char *SessionEvent::get_request_buf() const char *SessionEvent::get_request_buf()
{ {
return client_->buf; return query_.c_str();
}
int SessionEvent::get_request_buf_len()
{
return SOCKET_BUFFER_SIZE;
} }
...@@ -12,37 +12,42 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,37 +12,42 @@ See the Mulan PSL v2 for more details. */
// Created by Longda on 2021/4/13. // Created by Longda on 2021/4/13.
// //
#ifndef __OBSERVER_SESSION_SESSIONEVENT_H__ #pragma once
#define __OBSERVER_SESSION_SESSIONEVENT_H__
#include <string.h> #include <string.h>
#include <string> #include <string>
#include "common/seda/stage_event.h" #include "common/seda/stage_event.h"
#include "net/connection_context.h" #include "sql/executor/sql_result.h"
class Session; class Session;
class Communicator;
class SqlResult;
class SessionEvent : public common::StageEvent { class SessionEvent : public common::StageEvent {
public: public:
SessionEvent(ConnectionContext *client); SessionEvent(Communicator *client);
virtual ~SessionEvent(); virtual ~SessionEvent();
ConnectionContext *get_client() const; Communicator *get_communicator() const;
Session *session() const; Session *session() const;
void set_query(const std::string &query) { query_ = query; }
void set_sql_result(SqlResult *result) { sql_result_ = result; }
const std::string &query() const { return query_; }
SqlResult *sql_result() const { return sql_result_; }
const char *get_response() const; const char *get_response() const;
void set_response(const char *response); void set_response(const char *response);
void set_response(const char *response, int len); void set_response(const char *response, int len);
void set_response(std::string &&response); void set_response(std::string &&response);
int get_response_len() const; int get_response_len() const;
char *get_request_buf(); const char *get_request_buf(); // TODO remove me
int get_request_buf_len();
private: private:
ConnectionContext *client_; Communicator *communicator_ = nullptr;
SqlResult *sql_result_ = nullptr;
std::string query_;
std::string response_; std::string response_;
}; };
#endif //__OBSERVER_SESSION_SESSIONEVENT_H__
...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */
// Created by Longda on 2021/4/14. // Created by Longda on 2021/4/14.
// //
#ifndef __OBSERVER_SQL_EVENT_SQLEVENT_H__ #pragma once
#define __OBSERVER_SQL_EVENT_SQLEVENT_H__
#include <string> #include <string>
#include "common/seda/stage_event.h" #include "common/seda/stage_event.h"
...@@ -48,4 +47,3 @@ private: ...@@ -48,4 +47,3 @@ private:
Stmt *stmt_ = nullptr; Stmt *stmt_ = nullptr;
}; };
#endif //__SRC_OBSERVER_SQL_EVENT_SQLEVENT_H__
...@@ -20,6 +20,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -20,6 +20,7 @@ See the Mulan PSL v2 for more details. */
#include <iostream> #include <iostream>
#include "init.h" #include "init.h"
#include "ini_setting.h"
#include "common/os/process.h" #include "common/os/process.h"
#include "common/os/signal.h" #include "common/os/signal.h"
#include "net/server.h" #include "net/server.h"
...@@ -37,6 +38,7 @@ void usage() ...@@ -37,6 +38,7 @@ void usage()
std::cout << "-p: server port. if not specified, the item in the config file will be used" << std::endl; std::cout << "-p: server port. if not specified, the item in the config file will be used" << std::endl;
std::cout << "-f: path of config file." << std::endl; std::cout << "-f: path of config file." << std::endl;
std::cout << "-s: use unix socket and the argument is socket address" << std::endl; std::cout << "-s: use unix socket and the argument is socket address" << std::endl;
std::cout << "-P: protocol. {plain, mysql}. plain is default." << std::endl;
exit(0); exit(0);
} }
...@@ -51,7 +53,7 @@ void parse_parameter(int argc, char **argv) ...@@ -51,7 +53,7 @@ void parse_parameter(int argc, char **argv)
// Process args // Process args
int opt; int opt;
extern char *optarg; extern char *optarg;
while ((opt = getopt(argc, argv, "dp:s:f:o:e:h")) > 0) { while ((opt = getopt(argc, argv, "dp:P:s:f:o:e:h")) > 0) {
switch (opt) { switch (opt) {
case 's': case 's':
process_param->set_unix_socket_path(optarg); process_param->set_unix_socket_path(optarg);
...@@ -59,6 +61,9 @@ void parse_parameter(int argc, char **argv) ...@@ -59,6 +61,9 @@ void parse_parameter(int argc, char **argv)
case 'p': case 'p':
process_param->set_server_port(atoi(optarg)); process_param->set_server_port(atoi(optarg));
break; break;
case 'P':
process_param->set_protocol(optarg);
break;
case 'f': case 'f':
process_param->set_conf(optarg); process_param->set_conf(optarg);
break; break;
...@@ -116,6 +121,11 @@ Server *init_server() ...@@ -116,6 +121,11 @@ Server *init_server()
server_param.listen_addr = listen_addr; server_param.listen_addr = listen_addr;
server_param.max_connection_num = max_connection_num; server_param.max_connection_num = max_connection_num;
server_param.port = port; server_param.port = port;
if (0 == strcasecmp(process_param->get_protocol().c_str(), "mysql")) {
server_param.protocol = CommunicateProtocol::MYSQL;
} else {
server_param.protocol = CommunicateProtocol::PLAIN;
}
if (process_param->get_unix_socket_path().size() > 0) { if (process_param->get_unix_socket_path().size() > 0) {
server_param.use_unix_socket = true; server_param.use_unix_socket = true;
......
/* 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/11/17.
//
#include "net/communicator.h"
#include "net/mysql_communicator.h"
#include "sql/expr/tuple.h"
#include "event/session_event.h"
#include "common/lang/mutex.h"
#include "common/io/io.h"
#include "session/session.h"
RC Communicator::init(int fd, Session *session, const std::string &addr)
{
fd_ = fd;
session_ = session;
addr_ = addr;
return RC::SUCCESS;
}
Communicator::~Communicator()
{
if (fd_ >= 0) {
close(fd_);
fd_ = -1;
}
if (session_ != nullptr) {
delete session_;
session_ = nullptr;
}
}
/////////////////////////////////////////////////////////////////////////////////
RC PlainCommunicator::read_event(SessionEvent *&event)
{
RC rc = RC::SUCCESS;
event = nullptr;
int data_len = 0;
int read_len = 0;
const int max_packet_size = 8192;
std::vector<char> buf(max_packet_size);
// 持续接收消息,直到遇到'\0'。将'\0'遇到的后续数据直接丢弃没有处理,因为目前仅支持一收一发的模式
while (true) {
read_len = ::read(fd_, buf.data() + data_len, max_packet_size - data_len);
if (read_len < 0) {
if (errno == EAGAIN) {
continue;
}
break;
}
if (read_len == 0) {
break;
}
if (read_len + data_len > max_packet_size) {
data_len += read_len;
break;
}
bool msg_end = false;
for (int i = 0; i < read_len; i++) {
if (buf[data_len + i] == 0) {
data_len += i + 1;
msg_end = true;
break;
}
}
if (msg_end) {
break;
}
data_len += read_len;
}
if (data_len > max_packet_size) {
LOG_WARN("The length of sql exceeds the limitation %d", max_packet_size);
return RC::IOERR;
}
if (read_len == 0) {
LOG_INFO("The peer has been closed %s\n", addr());
return RC::IOERR;
} else if (read_len < 0) {
LOG_ERROR("Failed to read socket of %s, %s\n", addr(), strerror(errno));
return RC::IOERR;
}
LOG_INFO("receive command(size=%d): %s", data_len, buf.data());
event = new SessionEvent(this);
event->set_query(std::string(buf.data()));
return rc;
}
RC PlainCommunicator::write_state(SessionEvent *event, bool &need_disconnect)
{
SqlResult *sql_result = event->sql_result();
const int buf_size = 2048;
char *buf = new char[buf_size];
const std::string &state_string = sql_result->state_string();
if (state_string.empty()) {
const char *result = RC::SUCCESS == sql_result->return_code() ? "SUCCESS" : "FAILURE";
snprintf(buf, buf_size, "%s\n", result);
} else {
snprintf(buf, buf_size, "%s > %s\n", strrc(sql_result->return_code()), state_string.c_str());
}
int ret = common::writen(fd_, buf, strlen(buf) + 1);
if (ret != 0) {
LOG_WARN("failed to send data to client. err=%s", strerror(errno));
need_disconnect = true;
delete[] buf;
return RC::IOERR;
}
need_disconnect = false;
delete[] buf;
return RC::SUCCESS;
}
RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect)
{
need_disconnect = true;
const char message_terminate = '\0';
SqlResult *sql_result = event->sql_result();
if (nullptr == sql_result) {
const char *response = event->get_response();
int len = event->get_response_len();
int ret = common::writen(fd_, response, len);
if (ret < 0) {
LOG_ERROR("Failed to send data back to client. ret=%d, error=%s", ret, strerror(errno));
return RC::IOERR;
}
ret = common::writen(fd_, &message_terminate, sizeof(message_terminate));
if (ret < 0) {
LOG_ERROR("Failed to send data back to client. ret=%d, error=%s", ret, strerror(errno));
return RC::IOERR;
}
need_disconnect = false;
return RC::SUCCESS;
}
if (RC::SUCCESS != sql_result->return_code() || !sql_result->has_operator()) {
return write_state(event, need_disconnect);
}
RC rc = sql_result->open();
if (rc != RC::SUCCESS) {
sql_result->set_return_code(rc);
return write_state(event, need_disconnect);
}
const TupleSchema &schema = sql_result->tuple_schema();
const int cell_num = schema.cell_num();
for (int i = 0; i < cell_num; i++) {
const TupleCellSpec &spec = schema.cell_at(i);
const char *alias = spec.alias();
if (nullptr != alias || alias[0] != 0) {
if (0 != i) {
const char *delim = " | ";
int ret = common::writen(fd_, delim, strlen(delim));
if (ret != 0) {
LOG_WARN("failed to send data to client. err=%s", strerror(errno));
return RC::IOERR;
}
}
int len = strlen(alias);
int ret = common::writen(fd_, alias, len);
if (ret != 0) {
LOG_WARN("failed to send data to client. err=%s", strerror(errno));
return RC::IOERR;
}
}
}
if (cell_num > 0) {
char newline = '\n';
int ret = common::writen(fd_, &newline, 1);
if (ret != 0) {
LOG_WARN("failed to send data to client. err=%s", strerror(errno));
return RC::IOERR;
}
}
rc = RC::SUCCESS;
Tuple *tuple = nullptr;
while (RC::SUCCESS == (rc = sql_result->next_tuple(tuple))) {
assert(tuple != nullptr);
int cell_num = tuple->cell_num();
for (int i = 0; i < cell_num; i++) {
if (i != 0) {
const char *delim = " | ";
int ret = common::writen(fd_, delim, strlen(delim));
if (ret != 0) {
LOG_WARN("failed to send data to client. err=%s", strerror(errno));
return RC::IOERR;
}
}
TupleCell cell;
rc = tuple->cell_at(i, cell);
if (rc != RC::SUCCESS) {
return rc;
}
std::stringstream ss;
cell.to_string(ss);
std::string cell_str = ss.str();
int ret = common::writen(fd_, cell_str.data(), cell_str.size());
if (ret != RC::SUCCESS) {
LOG_WARN("failed to send data to client. err=%s", strerror(errno));
return RC::IOERR;
}
}
char newline = '\n';
int ret = common::writen(fd_, &newline, 1);
if (ret != 0) {
LOG_WARN("failed to send data to client. err=%s", strerror(errno));
return RC::IOERR;
}
}
if (rc != RC::RECORD_EOF) {
LOG_WARN("operator is done with error. error=%s", strrc(rc));
} else {
rc = RC::SUCCESS;
int ret = common::writen(fd_, &message_terminate, sizeof(message_terminate));
if (ret < 0) {
LOG_ERROR("Failed to send data back to client. ret=%d, error=%s", ret, strerror(errno));
return RC::IOERR;
}
need_disconnect = false;
}
return rc;
}
/////////////////////////////////////////////////////////////////////////////////
Communicator *CommunicatorFactory::create(CommunicateProtocol protocol)
{
switch (protocol) {
case CommunicateProtocol::PLAIN: {
return new PlainCommunicator;
} break;
case CommunicateProtocol::MYSQL: {
return new MysqlCommunicator;
} break;
default: {
return nullptr;
}
}
}
/* 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/11/17.
//
#pragma once
#include <string>
#include <event.h>
#include "rc.h"
struct ConnectionContext;
class SessionEvent;
class Session;
/**
* 负责与客户端通讯
*
* 在listener接收到一个新的连接(参考 server.cpp::accept), 就创建一个Communicator对象。
* 并调用init进行初始化。
* 在server中监听到某个连接有新的消息,就通过Communicator::read_event接收消息。
*/
class Communicator {
public:
virtual ~Communicator();
/**
* 接收到一个新的连接时,进行初始化
*/
virtual RC init(int fd, Session *session, const std::string &addr);
/**
* 监听到有新的数据到达,调用此函数进行接收消息
* 如果需要创建新的任务来处理,那么就创建一个SessionEvent 对象并通过event参数返回。
*/
virtual RC read_event(SessionEvent *&event) = 0;
/**
* 在任务处理完成后,通过此接口将结果返回给客户端
* @param event 任务数据,包括处理的结果
* @param need_disconnect 是否需要断开连接
* @return 处理结果。即使返回不是SUCCESS,也不能直接断开连接,需要通过need_disconnect来判断
* 是否需要断开连接
*/
virtual RC write_result(SessionEvent *event, bool &need_disconnect) = 0;
/**
* 关联的会话信息
*/
Session *session() const { return session_; }
/**
* libevent使用的数据,参考server.cpp
*/
struct event &read_event() { return read_event_; }
/**
* 对端地址
* 如果是unix socket,可能没有意义
*/
const char *addr() const { return addr_.c_str(); }
protected:
Session *session_ = nullptr;
int fd_ = -1;
struct event read_event_;
std::string addr_;
};
/**
* 与客户端进行通讯
* 使用简单的文本通讯协议,每个消息使用'\0'结尾
*/
class PlainCommunicator : public Communicator {
public:
RC read_event(SessionEvent *&event) override;
RC write_result(SessionEvent *event, bool &need_disconnect) override;
private:
RC write_state(SessionEvent *event, bool &need_disconnect);
};
/**
* 当前支持的通讯协议
*/
enum class CommunicateProtocol
{
PLAIN, //! 以'\0'结尾的协议
MYSQL, //! mysql通讯协议。具体实现参考 MysqlCommunicator
};
class CommunicatorFactory
{
public:
Communicator *create(CommunicateProtocol protocol);
};
/* 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/11/22.
//
#include <string.h>
#include <vector>
#include "common/log/log.h"
#include "common/io/io.h"
#include "net/mysql_communicator.h"
#include "event/session_event.h"
#include "sql/operator/string_list_operator.h"
// https://dev.mysql.com/doc/dev/mysql-server/latest/group__group__cs__capabilities__flags.html
// the flags below are negotiate by handshake packet
const uint32_t CLIENT_PROTOCOL_41 = 512;
const uint32_t CLIENT_INTERACTIVE = 1024; // This is an interactive client
const uint32_t CLIENT_TRANSACTIONS = 8192; // Client knows about transactions.
const uint32_t CLIENT_SESSION_TRACK = (1UL << 23); // Capable of handling server state change information
const uint32_t CLIENT_DEPRECATE_EOF = (1UL << 24); // Client no longer needs EOF_Packet and will use OK_Packet instead
const uint32_t CLIENT_OPTIONAL_RESULTSET_METADATA = (1UL << 25); // The client can handle optional metadata information in the resultset.
// Support optional extension for query parameters into the COM_QUERY and COM_STMT_EXECUTE packets.
const uint32_t CLIENT_QUERY_ATTRIBUTES = (1UL << 27);
// https://dev.mysql.com/doc/dev/mysql-server/latest/group__group__cs__column__definition__flags.html
// Column Definition Flags
const uint32_t NOT_NULL_FLAG = 1;
const uint32_t PRI_KEY_FLAG = 2;
const uint32_t UNIQUE_KEY_FLAG = 4;
const uint32_t MULTIPLE_KEY_FLAG = 8;
const uint32_t NUM_FLAG = 32768; // Field is num (for clients)
const uint32_t PART_KEY_FLAG = 16384; // Intern; Part of some key.
enum ResultSetMetaData
{
RESULTSET_METADATA_NONE = 0,
RESULTSET_METADATA_FULL = 1,
};
/**
Column types for MySQL
*/
enum enum_field_types {
MYSQL_TYPE_DECIMAL,
MYSQL_TYPE_TINY,
MYSQL_TYPE_SHORT,
MYSQL_TYPE_LONG,
MYSQL_TYPE_FLOAT,
MYSQL_TYPE_DOUBLE,
MYSQL_TYPE_NULL,
MYSQL_TYPE_TIMESTAMP,
MYSQL_TYPE_LONGLONG,
MYSQL_TYPE_INT24,
MYSQL_TYPE_DATE,
MYSQL_TYPE_TIME,
MYSQL_TYPE_DATETIME,
MYSQL_TYPE_YEAR,
MYSQL_TYPE_NEWDATE, /**< Internal to MySQL. Not used in protocol */
MYSQL_TYPE_VARCHAR,
MYSQL_TYPE_BIT,
MYSQL_TYPE_TIMESTAMP2,
MYSQL_TYPE_DATETIME2, /**< Internal to MySQL. Not used in protocol */
MYSQL_TYPE_TIME2, /**< Internal to MySQL. Not used in protocol */
MYSQL_TYPE_TYPED_ARRAY, /**< Used for replication only */
MYSQL_TYPE_INVALID = 243,
MYSQL_TYPE_BOOL = 244, /**< Currently just a placeholder */
MYSQL_TYPE_JSON = 245,
MYSQL_TYPE_NEWDECIMAL = 246,
MYSQL_TYPE_ENUM = 247,
MYSQL_TYPE_SET = 248,
MYSQL_TYPE_TINY_BLOB = 249,
MYSQL_TYPE_MEDIUM_BLOB = 250,
MYSQL_TYPE_LONG_BLOB = 251,
MYSQL_TYPE_BLOB = 252,
MYSQL_TYPE_VAR_STRING = 253,
MYSQL_TYPE_STRING = 254,
MYSQL_TYPE_GEOMETRY = 255
};
// little endian
// We suppose our platform is little endian too
int store_int1(char *buf, int8_t value)
{
*buf = value;
return 1;
}
int store_int2(char *buf, int16_t value)
{
memcpy(buf, &value, sizeof(value));
return 2;
}
int store_int3(char *buf, int32_t value)
{
memcpy(buf, &value, 3);
return 3;
}
int store_int4(char *buf, int32_t value)
{
memcpy(buf, &value, 4);
return 4;
}
int store_int6(char *buf, int64_t value)
{
memcpy(buf, &value, 6);
return 6;
}
int store_int8(char *buf, int64_t value)
{
memcpy(buf, &value, 8);
return 8;
}
int store_lenenc_int(char *buf, uint64_t value)
{
if (value < 251) {
*buf = (int8_t)value;
return 1;
}
if (value < (2UL << 16)) {
*buf = 0xFC;
memcpy(buf + 1, &value, 2);
return 3;
}
if (value < (2UL << 24)) {
*buf = 0xFD;
memcpy(buf + 1, &value, 3);
return 4;
}
*buf = 0xFE;
memcpy(buf + 1, &value, 8);
return 9;
}
int store_null_terminated_string(char *buf, const char *s)
{
if (nullptr == s || s[0] == 0) {
return 0;
}
const int len = strlen(s) + 1;
memcpy(buf, s, len);
return len;
}
int store_fix_length_string(char *buf, const char *s, int len)
{
if (len == 0) {
return 0;
}
memcpy(buf, s, len);
return len;
}
int store_lenenc_string(char *buf, const char *s)
{
int len = strlen(s);
int pos = store_lenenc_int(buf, len);
store_fix_length_string(buf + pos, s, len);
return pos + len;
}
/**
* 每个包都有一个包头
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_packets.html
* https://mariadb.com/kb/en/0-packet/
*/
struct alignas(1) PacketHeader {
int32_t payload_length:24; //! 当前packet的除掉头的长度
int8_t sequence_id = 0; //! 当前packet在当前处理过程中是第几个包
};
class BasePacket
{
public:
PacketHeader packet_header;
BasePacket(int8_t sequence = 0)
{
packet_header.sequence_id = sequence;
}
virtual ~BasePacket() = default;
virtual RC encode(uint32_t capabilities, std::vector<char> &net_packet) const = 0;
};
/**
* 握手包
* 先由服务端发送到客户端
* 这个包会交互capability与用户名密码
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_v10.html
*/
struct HandshakeV10 : public BasePacket
{
int8_t protocol = 10;
char server_version[7] = "5.7.25";
int32_t thread_id = 3221501807; // conn id
char auth_plugin_data_part_1[9] = "12345678"; // first 8 bytes of the plugin provided data (scramble) // and the filler
int16_t capability_flags_1 = 0xF7DF; // The lower 2 bytes of the Capabilities Flags
int8_t character_set = 83;
int16_t status_flags = 0;
int16_t capability_flags_2 = 0x0000;
int8_t auth_plugin_data_len = 0;
char reserved[10] = {0};
char auth_plugin_data_part_2[13] = "bbbbbbbbbbbb";
HandshakeV10(int8_t sequence = 0) : BasePacket(sequence)
{}
virtual ~HandshakeV10() = default;
/**
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_v10.html
*/
virtual RC encode(uint32_t capabilities, std::vector<char> &net_packet) const override
{
net_packet.resize(100);
char *buf = net_packet.data();
int pos = 0;
pos += 3;
pos += store_int1(buf + pos, packet_header.sequence_id);
pos += store_int1(buf + pos, protocol);
pos += store_null_terminated_string(buf + pos, server_version);
pos += store_int4(buf + pos, thread_id);
pos += store_null_terminated_string(buf + pos, auth_plugin_data_part_1);
pos += store_int2(buf + pos, capability_flags_1);
pos += store_int1(buf + pos, character_set);
pos += store_int2(buf + pos, status_flags);
pos += store_int2(buf + pos, capability_flags_2);
pos += store_int1(buf + pos, auth_plugin_data_len);
pos += store_fix_length_string(buf + pos, reserved, 10);
pos += store_null_terminated_string(buf + pos, auth_plugin_data_part_2);
int payload_length = pos - 4;
store_int3(buf, payload_length);
net_packet.resize(pos);
LOG_TRACE("encode handshake packet with payload length=%d", payload_length);
return RC::SUCCESS;
}
};
struct OkPacket : public BasePacket
{
int8_t header = 0; // 0x00 for ok and 0xFE for EOF
int32_t affected_rows = 0;
int32_t last_insert_id = 0;
int16_t status_flags = 0x22;
int16_t warnings = 0;
std::string info; // human readable status information
OkPacket(int8_t sequence = 0) : BasePacket(sequence)
{}
virtual ~OkPacket() = default;
/**
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_ok_packet.html
*/
virtual RC encode(uint32_t capabilities, std::vector<char> &net_packet) const override
{
net_packet.resize(100);
char *buf = net_packet.data();
int pos = 0;
pos += 3;
pos += store_int1(buf + pos, packet_header.sequence_id);
pos += store_int1(buf + pos, header);
pos += store_lenenc_int(buf + pos, affected_rows);
pos += store_lenenc_int(buf + pos, last_insert_id);
if (capabilities & CLIENT_PROTOCOL_41) {
pos += store_int2(buf + pos, status_flags);
pos += store_int2(buf + pos, warnings);
} else if (capabilities & CLIENT_TRANSACTIONS) {
pos += store_int2(buf + pos, status_flags);
}
if (capabilities & CLIENT_SESSION_TRACK) {
pos += store_lenenc_string(buf + pos, info.c_str());
} else {
pos += store_fix_length_string(buf + pos, info.c_str(), info.length());
}
int32_t payload_length = pos - 4;
LOG_TRACE("encode ok packet with length=%d", payload_length);
store_int3(buf, payload_length);
net_packet.resize(pos);
return RC::SUCCESS;
}
};
struct EofPacket : public BasePacket
{
int8_t header = 0xFE;
int16_t warnings = 0;
int16_t status_flags = 0x22;
EofPacket(int8_t sequence = 0) : BasePacket(sequence)
{}
virtual ~EofPacket() = default;
/**
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_err_packet.html
*/
virtual RC encode(uint32_t capabilities, std::vector<char> &net_packet) const override
{
net_packet.resize(10);
char *buf = net_packet.data();
int pos = 0;
pos += 3;
store_int1(buf + pos, packet_header.sequence_id);
pos += 1;
store_int1(buf + pos, header);
pos += 1;
if (capabilities & CLIENT_PROTOCOL_41) {
store_int2(buf + pos, warnings);
pos += 2;
store_int2(buf + pos, status_flags);
pos += 2;
}
int payload_length = pos - 4;
store_int3(buf, payload_length);
net_packet.resize(pos);
return RC::SUCCESS;
}
};
struct ErrPacket : public BasePacket
{
int8_t header = 0xFF;
int16_t error_code = 0;
char sql_state_marker[1] = {'#'};
std::string sql_state{"HY000"};
std::string error_message;
ErrPacket(int8_t sequence = 0) : BasePacket(sequence)
{}
virtual ~ErrPacket() = default;
/**
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_eof_packet.html
*/
virtual RC encode(uint32_t capabilities, std::vector<char> &net_packet) const override
{
net_packet.resize(1000);
char *buf = net_packet.data();
int pos = 0;
pos += 3;
store_int1(buf + pos, packet_header.sequence_id);
pos += 1;
store_int1(buf + pos, header);
pos += 1;
store_int2(buf + pos, error_code);
pos += 2;
if (capabilities & CLIENT_PROTOCOL_41) {
pos += store_fix_length_string(buf + pos, sql_state_marker, 1);
pos += store_fix_length_string(buf + pos, sql_state.c_str(), 5);
}
pos += store_fix_length_string(buf + pos, error_message.c_str(), error_message.length());
int payload_length = pos - 4;
store_int3(buf, payload_length);
net_packet.resize(pos);
return RC::SUCCESS;
}
};
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_command_phase.html
// https://mariadb.com/kb/en/2-text-protocol/
struct QueryPacket
{
PacketHeader packet_header;
int8_t command; // 0x03: COM_QUERY
std::string query; // the text of the SQL query to execute
};
/**
* decode query packet
* packet_header is not included in net_packet
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query.html
*/
RC decode_query_packet(std::vector<char> &net_packet, QueryPacket &query_packet)
{
// query field is a null terminated string
query_packet.query.assign(net_packet.data() + 1, net_packet.size() - 1);
query_packet.query.append(1, ';');
return RC::SUCCESS;
}
RC create_version_comment_sql_result(SqlResult *&sql_result)
{
TupleSchema tuple_schema;
TupleCellSpec cell_spec("", "", "@@version_comment");
tuple_schema.append_cell(cell_spec);
sql_result = new SqlResult;
sql_result->set_return_code(RC::SUCCESS);
sql_result->set_tuple_schema(tuple_schema);
const char *version_comments = "MiniOB";
StringListOperator *oper = new StringListOperator();
oper->append(version_comments);
sql_result->set_operator(oper);
return RC::SUCCESS;
}
RC MysqlCommunicator::init(int fd, Session *session, const std::string &addr)
{
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase.html
// 按照协议描述,服务端在连接建立后需要先向客户端发送握手信息
RC rc = Communicator::init(fd, session, addr);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to init communicator: %s", strrc(rc));
return rc;
}
HandshakeV10 handshake_packet;
rc = send_packet(handshake_packet);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to send handshake packet to client. addr=%s, error=%s", addr.c_str(), strerror(errno));
return rc;
}
return rc;
}
RC MysqlCommunicator::handle_version_comment(bool &need_disconnect)
{
SqlResult *sql_result = nullptr;
RC rc = create_version_comment_sql_result(sql_result);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to handle version comment. rc=%s", strrc(rc));
return rc;
}
SessionEvent session_event(this);
session_event.set_sql_result(sql_result);
rc = write_result(&session_event, need_disconnect);
return rc;
}
RC MysqlCommunicator::read_event(SessionEvent *&event)
{
RC rc = RC::SUCCESS;
PacketHeader packet_header;
int ret = common::readn(fd_, &packet_header, sizeof(packet_header));
if (ret != 0) {
LOG_WARN("failed to read packet header. length=%d, addr=%s. error=%s", sizeof(packet_header), addr_.c_str(), strerror(errno));
return RC::IOERR;
}
LOG_TRACE("read packet header. length=%d, sequence_id=%d", sizeof(packet_header), packet_header.sequence_id);
sequence_id_ = packet_header.sequence_id + 1;
std::vector<char> buf(packet_header.payload_length);
ret = common::readn(fd_, buf.data(), packet_header.payload_length);
if (ret != 0) {
LOG_WARN("failed to read packet payload. length=%d, addr=%s, error=%s",
packet_header.payload_length, addr_.c_str(), strerror(errno));
return RC::IOERR;
}
LOG_TRACE("read packet payload length=%d", packet_header.payload_length);
event = nullptr;
if (!authed_) {
uint32_t client_flag = *(uint32_t*)buf.data(); // TODO should use decode (little endian as default)
LOG_INFO("client handshake response with capabilities flag=%d", client_flag);
client_capabilities_flag_ = client_flag;
// send ok packet and return
OkPacket ok_packet;
ok_packet.packet_header.sequence_id = sequence_id_;
rc = send_packet(ok_packet);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to send ok packet while auth");
}
authed_ = true;
LOG_INFO("client authed. addr=%s. rc=%s", addr_.c_str(), strrc(rc));
return rc;
}
int8_t command_type = buf[0];
LOG_TRACE("recv command from client =%d", command_type);
if (command_type == 0x03) { // COM_QUERY
QueryPacket query_packet;
rc = decode_query_packet(buf, query_packet);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to decode query packet. packet length=%ld, addr=%s, error=%s", buf.size(), addr(), strrc(rc));
return rc;
}
LOG_TRACE("query command: %s", query_packet.query.c_str());
if (query_packet.query.find("select @@version_comment") != std::string::npos) {
bool need_disconnect;
return handle_version_comment(need_disconnect);
}
event = new SessionEvent(this);
event->set_query(query_packet.query);
} else {
OkPacket ok_packet(sequence_id_);
rc = send_packet(ok_packet);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to send ok packet. command=%d, addr=%s, error=%s", command_type, addr(), strrc(rc));
return rc;
}
}
return rc;
}
RC MysqlCommunicator::write_state(SessionEvent *event, bool &need_disconnect)
{
SqlResult *sql_result = event->sql_result();
const int buf_size = 2048;
char *buf = new char[buf_size];
const std::string &state_string = sql_result->state_string();
if (state_string.empty()) {
const char *result = RC::SUCCESS == sql_result->return_code() ? "SUCCESS" : "FAILURE";
snprintf(buf, buf_size, "%s", result);
} else {
snprintf(buf, buf_size, "%s > %s", strrc(sql_result->return_code()), state_string.c_str());
}
RC rc = RC::SUCCESS;
if (sql_result->return_code() == RC::SUCCESS) {
OkPacket ok_packet;
ok_packet.packet_header.sequence_id = sequence_id_++;
ok_packet.info.assign(buf);
rc = send_packet(ok_packet);
} else {
ErrPacket err_packet;
err_packet.packet_header.sequence_id = sequence_id_++;
err_packet.error_code = static_cast<int>(sql_result->return_code());
err_packet.error_message = buf;
rc = send_packet(err_packet);
}
if (rc != RC::SUCCESS) {
LOG_WARN("failed to send ok packet to client. addr=%s, error=%s", addr(), strrc(rc));
need_disconnect = true;
} else {
need_disconnect = false;
}
delete[] buf;
return rc;
}
RC MysqlCommunicator::write_result(SessionEvent *event, bool &need_disconnect)
{
RC rc = RC::SUCCESS;
need_disconnect = true;
SqlResult *sql_result = event->sql_result();
if (nullptr == sql_result) {
const char *response = event->get_response();
int len = event->get_response_len();
OkPacket ok_packet;// TODO if error occurs, we should send an error packet to client
ok_packet.info.assign(response, len);
rc = send_packet(ok_packet);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to send ok packet to client. addr=%s, rc=%s", addr(), strrc(rc));
return rc;
}
need_disconnect = false;
} else {
if (RC::SUCCESS != sql_result->return_code() || !sql_result->has_operator()) {
return write_state(event, need_disconnect);
}
// send result set
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query_response_text_resultset.html
RC rc = sql_result->open();
if (rc != RC::SUCCESS) {
sql_result->set_return_code(rc);
return write_state(event, need_disconnect);
}
// send metadata : Column Definition
rc = send_column_definition(sql_result, need_disconnect);
if (rc != RC::SUCCESS) {
return rc;
}
rc = send_result_rows(sql_result, need_disconnect);
}
return rc;
}
RC MysqlCommunicator::send_packet(const BasePacket &packet)
{
std::vector<char> net_packet;
RC rc = packet.encode(client_capabilities_flag_, net_packet);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to encode ok packet. rc=%s", strrc(rc));
return rc;
}
int ret = common::writen(fd_, net_packet.data(), net_packet.size());
if (ret != 0) {
LOG_WARN("failed to send packet to client. addr=%s, error=%s", addr(), strerror(errno));
return RC::IOERR;
}
LOG_TRACE("send ok packet success. packet length=%d", net_packet.size());
return rc;
}
/**
* 发送列定义信息
* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query_response_text_resultset.html
* https://mariadb.com/kb/en/result-set-packets/#column-definition-packet
*
* 先发送当前有多少个列
* 然后发送N个包,告诉客户端每个列的信息
*/
RC MysqlCommunicator::send_column_definition(SqlResult *sql_result, bool &need_disconnect)
{
RC rc = RC::SUCCESS;
const TupleSchema &tuple_schema = sql_result->tuple_schema();
const int cell_num = tuple_schema.cell_num();
std::vector<char> net_packet;
net_packet.resize(1024);
char *buf = net_packet.data();
int pos = 0;
pos += 3;
store_int1(buf + pos, sequence_id_++);
pos += 1;
if (client_capabilities_flag_ & CLIENT_OPTIONAL_RESULTSET_METADATA) {
store_int1(buf + pos, static_cast<int>(ResultSetMetaData::RESULTSET_METADATA_FULL));
pos += 1;
LOG_TRACE("client with optional resultset metadata");
} else {
LOG_TRACE("client without optional resultset metadata");
}
pos += store_lenenc_int(buf + pos, cell_num);
int payload_length = pos - 4;
store_int3(buf, payload_length);
net_packet.resize(pos);
int ret = common::writen(fd_, net_packet.data(), net_packet.size());
if (ret != 0){
LOG_WARN("failed to send column count to client. addr=%s, error=%s", addr(), strerror(errno));
need_disconnect = true;
return RC::IOERR;
}
for (int i = 0; i < cell_num; i++) {
net_packet.resize(1024);
buf = net_packet.data();
pos = 0;
pos += 3;
store_int1(buf + pos, sequence_id_++);
pos += 1;
const TupleCellSpec &spec = tuple_schema.cell_at(i);
const char *catalog = "def"; // The catalog used. Currently always "def"
const char *schema = "sys"; // schema name
const char *table = spec.table_name();
const char *org_table = spec.table_name();
const char *name = spec.alias();
//const char *org_name = spec.field_name();
const char *org_name = spec.alias();
int fixed_len_fields = 0x0c;
int character_set = 33;
int column_length = 16384;
int type = MYSQL_TYPE_VAR_STRING;
int16_t flags = 0;
int8_t decimals = 0x1f;
pos += store_lenenc_string(buf + pos, catalog);
pos += store_lenenc_string(buf + pos, schema);
pos += store_lenenc_string(buf + pos, table);
pos += store_lenenc_string(buf + pos, org_table);
pos += store_lenenc_string(buf + pos, name);
pos += store_lenenc_string(buf + pos, org_name);
pos += store_lenenc_int(buf + pos, fixed_len_fields);
store_int2(buf + pos, character_set);
pos += 2;
store_int4(buf + pos, column_length);
pos += 4;
store_int1(buf + pos, type);
pos += 1;
store_int2(buf + pos, flags);
pos += 2;
store_int1(buf + pos, decimals);
pos += 1;
store_int2(buf + pos, 0); // 按照mariadb的文档描述,最后还有一个unused字段int<2>,不过mysql的文档没有给出这样的描述
pos += 2;
payload_length = pos - 4;
store_int3(buf, payload_length);
net_packet.resize(pos);
ret = common::writen(fd_, net_packet.data(), net_packet.size());
if (ret != 0) {
LOG_WARN("failed to write column definition to client. addr=%s, error=%s", addr(), strerror(errno));
need_disconnect = true;
return RC::IOERR;
}
}
if (!(client_capabilities_flag_ & CLIENT_DEPRECATE_EOF)) {
EofPacket eof_packet;
eof_packet.packet_header.sequence_id = sequence_id_++;
eof_packet.status_flags = 0x02;
rc = send_packet(eof_packet);
if (rc != RC::SUCCESS) {
need_disconnect = true;
LOG_WARN("failed to send eof packet to client. addr=%s, error=%s", addr(), strerror(errno));
}
} else {
LOG_TRACE("client use CLIENT_DEPRECATE_EOF");
}
LOG_TRACE("send column definition to client done");
need_disconnect = false;
return RC::SUCCESS;
}
/**
* 发送每行数据
* 一行一个包
*/
RC MysqlCommunicator::send_result_rows(SqlResult *sql_result, bool &need_disconnect)
{
RC rc = RC::SUCCESS;
std::vector<char> packet;
packet.resize(4 * 1024 * 1024); // TODO warning: length cannot be fix
Tuple *tuple = nullptr;
while (RC::SUCCESS == (rc = sql_result->next_tuple(tuple))) {
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query_response_text_resultset.html
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query_response_text_resultset_row.html
// note: if some field is null, send a 0xFB
char *buf = packet.data();
int pos = 0;
pos += 3;
store_int1(buf + pos, sequence_id_++);
pos += 1;
assert(tuple != nullptr);
const int cell_num = tuple->cell_num();
TupleCell tuple_cell;
for (int i = 0; i < cell_num; i++) {
rc = tuple->cell_at(i, tuple_cell);
if (rc != RC::SUCCESS) {
sql_result->set_return_code(rc);
break; // TODO send error packet
}
std::stringstream ss;
tuple_cell.to_string(ss);
pos += store_lenenc_string(buf + pos, ss.str().c_str());
}
int payload_length = pos - 4;
store_int3(buf, payload_length);
int ret = common::writen(fd_, buf, pos);
if (ret != 0) {
LOG_WARN("failed to send row packet to client. addr=%s, error=%s", addr(), strerror(errno));
need_disconnect = true;
return RC::IOERR;
}
}
// 所有行发送完成后,发送一个EOF或OK包
if (client_capabilities_flag_ & CLIENT_DEPRECATE_EOF) {
LOG_TRACE("client has CLIENT_DEPRECATE_EOF, send ok packet");
OkPacket ok_packet;
ok_packet.packet_header.sequence_id = sequence_id_++;
rc = send_packet(ok_packet);
} else {
EofPacket eof_packet;
eof_packet.packet_header.sequence_id = sequence_id_++;
rc = send_packet(eof_packet);
}
LOG_TRACE("send rows to client done");
need_disconnect = false;
return rc;
}
/* 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/11/22.
//
#pragma once
#include "net/communicator.h"
class SqlResult;
class BasePacket;
/**
* 与客户端通讯
* 实现MySQL通讯协议
* 可以参考 https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_PROTOCOL.html
* 或 mariadb文档 https://mariadb.com/kb/en/clientserver-protocol/
*/
class MysqlCommunicator : public Communicator {
public:
/**
* 连接刚开始建立时,进行一些初始化
* 参考MySQL或MariaDB的手册,服务端要首先向客户端发送一个握手包,等客户端回复后,
* 再回复一个OkPacket或ErrPacket
*/
virtual RC init(int fd, Session *session, const std::string &addr) override;
/**
* 有新的消息到达时,接收消息
* 因为MySQL协议的特殊性,收到数据后不一定需要向后流转,比如握手包
*/
virtual RC read_event(SessionEvent *&event) override;
/**
* 将处理结果返回给客户端
*/
virtual RC write_result(SessionEvent *event, bool &need_disconnect) override;
private:
RC send_packet(const BasePacket &packet);
RC write_state(SessionEvent *event, bool &need_disconnect);
/**
* 根据MySQL text protocol 描述,普通的结果分为列信息描述和行数据
* 这里就分为两个函数
*/
RC send_column_definition(SqlResult *sql_result, bool &need_disconnect);
RC send_result_rows(SqlResult *sql_result, bool &need_disconnect);
/**
* 根据实际测试,客户端在连接上来时,会发起一个 version_comment的查询
* 这里就针对这个查询返回一个结果
*/
RC handle_version_comment(bool &need_disconnect);
private:
//! 握手阶段(鉴权),需要做一些特殊处理,所以加个字段单独标记
bool authed_ = false;
//! 有时需要根据握手包中capabilities字段值的不同,而发送或接收不同的包
uint32_t client_capabilities_flag_ = 0;
//! 在一次通讯过程中(一个任务的请求与处理),每个包(packet)都有一个sequence id
//! 这个sequence id是递增的
int8_t sequence_id_ = 0;
};
...@@ -35,6 +35,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -35,6 +35,7 @@ See the Mulan PSL v2 for more details. */
#include "event/session_event.h" #include "event/session_event.h"
#include "session/session.h" #include "session/session.h"
#include "ini_setting.h" #include "ini_setting.h"
#include "net/communicator.h"
#include <common/metrics/metrics_registry.h> #include <common/metrics/metrics_registry.h>
using namespace common; using namespace common;
...@@ -85,7 +86,6 @@ void Server::init() ...@@ -85,7 +86,6 @@ void Server::init()
int Server::set_non_block(int fd) int Server::set_non_block(int fd)
{ {
int flags = fcntl(fd, F_GETFL); int flags = fcntl(fd, F_GETFL);
if (flags == -1) { if (flags == -1) {
LOG_INFO("Failed to get flags of fd :%d. ", fd); LOG_INFO("Failed to get flags of fd :%d. ", fd);
...@@ -100,87 +100,34 @@ int Server::set_non_block(int fd) ...@@ -100,87 +100,34 @@ int Server::set_non_block(int fd)
return 0; return 0;
} }
void Server::close_connection(ConnectionContext *client_context) void Server::close_connection(Communicator *communicator)
{ {
LOG_INFO("Close connection of %s.", client_context->addr); LOG_INFO("Close connection of %s.", communicator->addr());
event_del(&client_context->read_event); event_del(&communicator->read_event());
::close(client_context->fd); delete communicator;
delete client_context->session;
client_context->session = nullptr;
delete client_context;
} }
void Server::recv(int fd, short ev, void *arg) void Server::recv(int fd, short ev, void *arg)
{ {
ConnectionContext *client = (ConnectionContext *)arg; Communicator *comm = (Communicator *)arg;
// Server::send(sev->getClient(), sev->getRequestBuf(), strlen(sev->getRequestBuf()));
int data_len = 0;
int read_len = 0;
int buf_size = sizeof(client->buf);
memset(client->buf, 0, buf_size);
TimerStat timer_stat(*read_socket_metric_);
MUTEX_LOCK(&client->mutex);
// 持续接收消息,直到遇到'\0'。将'\0'遇到的后续数据直接丢弃没有处理,因为目前仅支持一收一发的模式
while (true) {
read_len = ::read(client->fd, client->buf + data_len, buf_size - data_len);
if (read_len < 0) {
if (errno == EAGAIN) {
continue;
}
break;
}
if (read_len == 0) {
break;
}
if (read_len + data_len > buf_size) {
data_len += read_len;
break;
}
bool msg_end = false;
for (int i = 0; i < read_len; i++) {
if (client->buf[data_len + i] == 0) {
data_len += i + 1;
msg_end = true;
break;
}
}
if (msg_end) {
break;
}
data_len += read_len; SessionEvent *event = nullptr;
} RC rc = comm->read_event(event);
if (rc != RC::SUCCESS) {
MUTEX_UNLOCK(&client->mutex); close_connection(comm);
timer_stat.end();
if (data_len > buf_size) {
LOG_WARN("The length of sql exceeds the limitation %d\n", buf_size);
close_connection(client);
return; return;
} }
if (read_len == 0) {
LOG_INFO("The peer has been closed %s\n", client->addr); if (event == nullptr) {
close_connection(client); LOG_WARN("event is null while read event return success");
return;
} else if (read_len < 0) {
LOG_ERROR("Failed to read socket of %s, %s\n", client->addr, strerror(errno));
close_connection(client);
return; return;
} }
session_stage_->add_event(event);
LOG_INFO("receive command(size=%d): %s", data_len, client->buf);
SessionEvent *sev = new SessionEvent(client);
session_stage_->add_event(sev);
} }
#if 0
// 这个函数仅负责发送数据,至于是否是一个完整的消息,由调用者控制 // 这个函数仅负责发送数据,至于是否是一个完整的消息,由调用者控制
int Server::send(ConnectionContext *client, const char *buf, int data_len) int Server::send( *client, const char *buf, int data_len)
{ {
if (buf == nullptr || data_len == 0) { if (buf == nullptr || data_len == 0) {
return 0; return 0;
...@@ -188,7 +135,6 @@ int Server::send(ConnectionContext *client, const char *buf, int data_len) ...@@ -188,7 +135,6 @@ int Server::send(ConnectionContext *client, const char *buf, int data_len)
TimerStat writeStat(*write_socket_metric_); TimerStat writeStat(*write_socket_metric_);
MUTEX_LOCK(&client->mutex);
int ret = common::writen(client->fd, buf, data_len); int ret = common::writen(client->fd, buf, data_len);
if (ret < 0) { if (ret < 0) {
LOG_ERROR("Failed to send data back to client. ret=%d, error=%s", ret, strerror(errno)); LOG_ERROR("Failed to send data back to client. ret=%d, error=%s", ret, strerror(errno));
...@@ -198,9 +144,9 @@ int Server::send(ConnectionContext *client, const char *buf, int data_len) ...@@ -198,9 +144,9 @@ int Server::send(ConnectionContext *client, const char *buf, int data_len)
return -STATUS_FAILED_NETWORK; return -STATUS_FAILED_NETWORK;
} }
MUTEX_UNLOCK(&client->mutex);
return 0; return 0;
} }
#endif
void Server::accept(int fd, short ev, void *arg) void Server::accept(int fd, short ev, void *arg)
{ {
...@@ -244,33 +190,32 @@ void Server::accept(int fd, short ev, void *arg) ...@@ -244,33 +190,32 @@ void Server::accept(int fd, short ev, void *arg)
} }
} }
ConnectionContext *client_context = new ConnectionContext(); Communicator *communicator = instance->communicator_factory_.create(instance->server_param_.protocol);
memset(client_context, 0, sizeof(ConnectionContext)); RC rc = communicator->init(client_fd, new Session(Session::default_session()), addr_str);
client_context->fd = client_fd; if (rc != RC::SUCCESS) {
snprintf(client_context->addr, sizeof(client_context->addr), "%s", addr_str.c_str()); LOG_WARN("failed to init communicator. rc=%s", strrc(rc));
pthread_mutex_init(&client_context->mutex, nullptr); delete communicator;
return;
}
event_set(&client_context->read_event, client_context->fd, EV_READ | EV_PERSIST, recv, client_context); event_set(&communicator->read_event(), client_fd, EV_READ | EV_PERSIST, recv, communicator);
ret = event_base_set(instance->event_base_, &client_context->read_event); ret = event_base_set(instance->event_base_, &communicator->read_event());
if (ret < 0) { if (ret < 0) {
LOG_ERROR( LOG_ERROR("Failed to do event_base_set for read event of %s into libevent, %s",
"Failed to do event_base_set for read event of %s into libevent, %s", client_context->addr, strerror(errno)); communicator->addr(), strerror(errno));
delete client_context; delete communicator;
::close(instance->server_socket_);
return; return;
} }
ret = event_add(&client_context->read_event, nullptr); ret = event_add(&communicator->read_event(), nullptr);
if (ret < 0) { if (ret < 0) {
LOG_ERROR("Failed to event_add for read event of %s into libevent, %s", client_context->addr, strerror(errno)); LOG_ERROR("Failed to event_add for read event of %s into libevent, %s", communicator->addr(), strerror(errno));
delete client_context; delete communicator;
::close(instance->server_socket_);
return; return;
} }
client_context->session = new Session(Session::default_session()); LOG_INFO("Accepted connection from %s\n", communicator->addr());
LOG_INFO("Accepted connection from %s\n", client_context->addr);
} }
int Server::start() int Server::start()
......
...@@ -12,15 +12,15 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,15 +12,15 @@ See the Mulan PSL v2 for more details. */
// Created by Longda on 2021/4/1. // Created by Longda on 2021/4/1.
// //
#ifndef __OBSERVER_NET_SERVER_H__ #pragma once
#define __OBSERVER_NET_SERVER_H__
#include "common/defs.h" #include "common/defs.h"
#include "common/metrics/metrics.h" #include "common/metrics/metrics.h"
#include "common/seda/stage.h" #include "common/seda/stage.h"
#include "net/connection_context.h"
#include "net/server_param.h" #include "net/server_param.h"
class Communicator;
class Server { class Server {
public: public:
Server(ServerParam input_server_param); Server(ServerParam input_server_param);
...@@ -28,7 +28,8 @@ public: ...@@ -28,7 +28,8 @@ public:
public: public:
static void init(); static void init();
static int send(ConnectionContext *client, const char *buf, int data_len); // static int send(ConnectionContext *client, const char *buf, int data_len);
static void close_connection(Communicator *comm);
public: public:
int serve(); int serve();
...@@ -37,7 +38,6 @@ public: ...@@ -37,7 +38,6 @@ public:
private: private:
static void accept(int fd, short ev, void *arg); static void accept(int fd, short ev, void *arg);
// close connection // close connection
static void close_connection(ConnectionContext *client_context);
static void recv(int fd, short ev, void *arg); static void recv(int fd, short ev, void *arg);
private: private:
...@@ -55,17 +55,9 @@ private: ...@@ -55,17 +55,9 @@ private:
ServerParam server_param_; ServerParam server_param_;
CommunicatorFactory communicator_factory_;
static common::Stage *session_stage_; static common::Stage *session_stage_;
static common::SimpleTimer *read_socket_metric_; static common::SimpleTimer *read_socket_metric_;
static common::SimpleTimer *write_socket_metric_; static common::SimpleTimer *write_socket_metric_;
}; };
class Communicator {
public:
virtual ~Communicator() = default;
virtual int init(const ServerParam &server_param) = 0;
virtual int start() = 0;
virtual int stop() = 0;
};
#endif //__OBSERVER_NET_SERVER_H__
...@@ -12,10 +12,10 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,10 +12,10 @@ See the Mulan PSL v2 for more details. */
// Created by Longda on 2021/4/13. // Created by Longda on 2021/4/13.
// //
#ifndef __SRC_OBSERVER_NET_SERVER_PARAM_H__ #pragma once
#define __SRC_OBSERVER_NET_SERVER_PARAM_H__
#include <string> #include <string>
#include "net/communicator.h"
class ServerParam { class ServerParam {
public: public:
...@@ -36,6 +36,6 @@ public: ...@@ -36,6 +36,6 @@ public:
// 如果使用标准输入输出作为通信条件,就不再监听端口 // 如果使用标准输入输出作为通信条件,就不再监听端口
bool use_unix_socket = false; bool use_unix_socket = false;
};
#endif //__SRC_OBSERVER_NET_SERVER_PARAM_H__ CommunicateProtocol protocol;
};
...@@ -27,6 +27,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -27,6 +27,7 @@ See the Mulan PSL v2 for more details. */
#include "event/session_event.h" #include "event/session_event.h"
#include "event/sql_event.h" #include "event/sql_event.h"
#include "net/server.h" #include "net/server.h"
#include "net/communicator.h"
#include "session/session.h" #include "session/session.h"
using namespace common; using namespace common;
...@@ -118,20 +119,14 @@ void SessionStage::callback_event(StageEvent *event, CallbackContext *context) ...@@ -118,20 +119,14 @@ void SessionStage::callback_event(StageEvent *event, CallbackContext *context)
return; return;
} }
const char *response = sev->get_response(); Communicator *communicator = sev->get_communicator();
int len = sev->get_response_len(); bool need_disconnect = false;
if (len <= 0 || response == nullptr) { RC rc = communicator->write_result(sev, need_disconnect);
response = "No data\n"; LOG_INFO("write result return %s", strrc(rc));
len = strlen(response) + 1; if (need_disconnect) {
} Server::close_connection(communicator);
Server::send(sev->get_client(), response, len);
if ('\0' != response[len - 1]) {
// 这里强制性的给发送一个消息终结符,如果需要发送多条消息,需要调整
char end = 0;
Server::send(sev->get_client(), &end, 1);
} }
// sev->done();
LOG_TRACE("Exit\n"); LOG_TRACE("Exit\n");
return; return;
} }
......
...@@ -16,7 +16,6 @@ See the Mulan PSL v2 for more details. */ ...@@ -16,7 +16,6 @@ See the Mulan PSL v2 for more details. */
#define __OBSERVER_SESSION_SESSIONSTAGE_H__ #define __OBSERVER_SESSION_SESSIONSTAGE_H__
#include "common/seda/stage.h" #include "common/seda/stage.h"
#include "net/connection_context.h"
#include "common/metrics/metrics.h" #include "common/metrics/metrics.h"
/** /**
......
...@@ -32,6 +32,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -32,6 +32,7 @@ See the Mulan PSL v2 for more details. */
#include "sql/operator/predicate_operator.h" #include "sql/operator/predicate_operator.h"
#include "sql/operator/delete_operator.h" #include "sql/operator/delete_operator.h"
#include "sql/operator/project_operator.h" #include "sql/operator/project_operator.h"
#include "sql/operator/string_list_operator.h"
#include "sql/stmt/stmt.h" #include "sql/stmt/stmt.h"
#include "sql/stmt/select_stmt.h" #include "sql/stmt/select_stmt.h"
#include "sql/stmt/update_stmt.h" #include "sql/stmt/update_stmt.h"
...@@ -200,18 +201,25 @@ void ExecuteStage::handle_request(common::StageEvent *event) ...@@ -200,18 +201,25 @@ void ExecuteStage::handle_request(common::StageEvent *event)
do_clog_sync(sql_event); do_clog_sync(sql_event);
} }
case SCF_ROLLBACK: { case SCF_ROLLBACK: {
Trx *trx = session_event->get_client()->session->current_trx(); Trx *trx = session_event->session()->current_trx();
RC rc = trx->rollback(); RC rc = trx->rollback();
session->set_trx_multi_operation_mode(false); session->set_trx_multi_operation_mode(false);
session_event->set_response(strrc(rc)); SqlResult *sql_result = new SqlResult;
sql_result->set_return_code(rc);
session_event->set_sql_result(sql_result);
} break; } break;
case SCF_EXIT: { case SCF_EXIT: {
// do nothing // do nothing
const char *response = "Unsupported\n"; SqlResult *sql_result = new SqlResult;
session_event->set_response(response); sql_result->set_return_code(RC::SUCCESS);
session_event->set_sql_result(sql_result);
} break; } break;
default: { default: {
LOG_ERROR("Unsupported command=%d\n", sql->flag); LOG_ERROR("Unsupported command=%d\n", sql->flag);
SqlResult *sql_result = new SqlResult;
sql_result->set_return_code(RC::UNIMPLENMENT);
sql_result->set_state_string("Unsupported command");
session_event->set_sql_result(sql_result);
} }
} }
} }
...@@ -228,25 +236,6 @@ void end_trx_if_need(Session *session, Trx *trx, bool all_right) ...@@ -228,25 +236,6 @@ void end_trx_if_need(Session *session, Trx *trx, bool all_right)
} }
} }
void print_tuple_header(std::ostream &os, const ProjectOperator &oper)
{
const int cell_num = oper.tuple_cell_num();
const TupleCellSpec *cell_spec = nullptr;
for (int i = 0; i < cell_num; i++) {
oper.tuple_cell_spec_at(i, cell_spec);
if (i != 0) {
os << " | ";
}
if (cell_spec->alias()) {
os << cell_spec->alias();
}
}
if (cell_num > 0) {
os << '\n';
}
}
void tuple_to_string(std::ostream &os, const Tuple &tuple) void tuple_to_string(std::ostream &os, const Tuple &tuple)
{ {
TupleCell cell; TupleCell cell;
...@@ -409,15 +398,21 @@ RC ExecuteStage::do_select(SQLStageEvent *sql_event) ...@@ -409,15 +398,21 @@ RC ExecuteStage::do_select(SQLStageEvent *sql_event)
scan_oper = new TableScanOperator(select_stmt->tables()[0]); scan_oper = new TableScanOperator(select_stmt->tables()[0]);
} }
DEFER([&] () {delete scan_oper;}); SqlResult *sql_result = new SqlResult;
PredicateOperator pred_oper(select_stmt->filter_stmt()); PredicateOperator *pred_oper = new PredicateOperator(select_stmt->filter_stmt());
pred_oper.add_child(scan_oper); pred_oper->add_child(scan_oper);
ProjectOperator project_oper; ProjectOperator *project_oper = new ProjectOperator;
project_oper.add_child(&pred_oper); project_oper->add_child(pred_oper);
TupleSchema schema;
for (const Field &field : select_stmt->query_fields()) { for (const Field &field : select_stmt->query_fields()) {
project_oper.add_projection(field.table(), field.meta()); project_oper->add_projection(field.table(), field.meta());
schema.append_cell(field.field_name());
} }
sql_result->set_tuple_schema(schema);
sql_result->set_operator(project_oper);
/*
rc = project_oper.open(); rc = project_oper.open();
if (rc != RC::SUCCESS) { if (rc != RC::SUCCESS) {
LOG_WARN("failed to open operator"); LOG_WARN("failed to open operator");
...@@ -447,21 +442,31 @@ RC ExecuteStage::do_select(SQLStageEvent *sql_event) ...@@ -447,21 +442,31 @@ RC ExecuteStage::do_select(SQLStageEvent *sql_event)
rc = project_oper.close(); rc = project_oper.close();
} }
session_event->set_response(ss.str()); session_event->set_response(ss.str());
*/
session_event->set_sql_result(sql_result);
return rc; return rc;
} }
RC ExecuteStage::do_help(SQLStageEvent *sql_event) RC ExecuteStage::do_help(SQLStageEvent *sql_event)
{ {
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
const char *response = "show tables;\n" const char *strings[] = {
"desc `table name`;\n" "show tables;",
"create table `table name` (`column name` `column type`, ...);\n" "desc `table name`;",
"create index `index name` on `table` (`column`);\n" "create table `table name` (`column name` `column type`, ...);",
"insert into `table` values(`value1`,`value2`);\n" "create index `index name` on `table` (`column`);",
"update `table` set column=value [where `column`=`value`];\n" "insert into `table` values(`value1`,`value2`);",
"delete from `table` [where `column`=`value`];\n" "update `table` set column=value [where `column`=`value`];",
"select [ * | `columns` ] from `table`;\n"; "delete from `table` [where `column`=`value`];",
session_event->set_response(response); "select [ * | `columns` ] from `table`;"
};
StringListOperator *oper = new StringListOperator();
for (size_t i = 0; i < sizeof(strings)/sizeof(strings[0]); i++) {
oper->append(strings[i]);
}
SqlResult *sql_result = new SqlResult;
sql_result->set_operator(oper);
session_event->set_sql_result(sql_result);
return RC::SUCCESS; return RC::SUCCESS;
} }
...@@ -472,44 +477,45 @@ RC ExecuteStage::do_create_table(SQLStageEvent *sql_event) ...@@ -472,44 +477,45 @@ RC ExecuteStage::do_create_table(SQLStageEvent *sql_event)
Db *db = session_event->session()->get_current_db(); Db *db = session_event->session()->get_current_db();
RC rc = db->create_table(create_table.relation_name, RC rc = db->create_table(create_table.relation_name,
create_table.attribute_count, create_table.attributes); create_table.attribute_count, create_table.attributes);
if (rc == RC::SUCCESS) { SqlResult *sql_result = new SqlResult;
session_event->set_response("SUCCESS\n"); sql_result->set_return_code(rc);
} else { sql_event->session_event()->set_sql_result(sql_result);
session_event->set_response("FAILURE\n");
}
return rc; return rc;
} }
RC ExecuteStage::do_create_index(SQLStageEvent *sql_event) RC ExecuteStage::do_create_index(SQLStageEvent *sql_event)
{ {
SqlResult *sql_result = new SqlResult;
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
session_event->set_sql_result(sql_result);
Db *db = session_event->session()->get_current_db(); Db *db = session_event->session()->get_current_db();
const CreateIndex &create_index = sql_event->query()->sstr.create_index; const CreateIndex &create_index = sql_event->query()->sstr.create_index;
Table *table = db->find_table(create_index.relation_name); Table *table = db->find_table(create_index.relation_name);
if (nullptr == table) { if (nullptr == table) {
session_event->set_response("FAILURE\n"); sql_result->set_return_code(RC::SCHEMA_TABLE_NOT_EXIST);
return RC::SCHEMA_TABLE_NOT_EXIST; return RC::SCHEMA_TABLE_NOT_EXIST;
} }
RC rc = table->create_index(nullptr, create_index.index_name, create_index.attribute_name); RC rc = table->create_index(nullptr, create_index.index_name, create_index.attribute_name);
sql_event->session_event()->set_response(rc == RC::SUCCESS ? "SUCCESS\n" : "FAILURE\n"); sql_result->set_return_code(rc);
return rc; return rc;
} }
RC ExecuteStage::do_show_tables(SQLStageEvent *sql_event) RC ExecuteStage::do_show_tables(SQLStageEvent *sql_event)
{ {
SqlResult *sql_result = new SqlResult;
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
session_event->set_sql_result(sql_result);
Db *db = session_event->session()->get_current_db(); Db *db = session_event->session()->get_current_db();
std::vector<std::string> all_tables; std::vector<std::string> all_tables;
db->all_tables(all_tables); db->all_tables(all_tables);
if (all_tables.empty()) { TupleSchema tuple_schema;
session_event->set_response("No table\n"); tuple_schema.append_cell(TupleCellSpec("", "Tables_in_SYS", "Tables_in_SYS"));
} else { sql_result->set_tuple_schema(tuple_schema);
std::stringstream ss; StringListOperator *oper = new StringListOperator;
for (const auto &table : all_tables) { for (const std::string &s : all_tables) {
ss << table << std::endl; oper->append(s);
} }
session_event->set_response(ss.str().c_str()); sql_result->set_operator(oper);
}
return RC::SUCCESS; return RC::SUCCESS;
} }
...@@ -519,13 +525,27 @@ RC ExecuteStage::do_desc_table(SQLStageEvent *sql_event) ...@@ -519,13 +525,27 @@ RC ExecuteStage::do_desc_table(SQLStageEvent *sql_event)
Db *db = sql_event->session_event()->session()->get_current_db(); Db *db = sql_event->session_event()->session()->get_current_db();
const char *table_name = query->sstr.desc_table.relation_name; const char *table_name = query->sstr.desc_table.relation_name;
Table *table = db->find_table(table_name); Table *table = db->find_table(table_name);
std::stringstream ss; SqlResult *sql_result = new SqlResult;
sql_event->session_event()->set_sql_result(sql_result);
if (table != nullptr) { if (table != nullptr) {
table->table_meta().desc(ss); TupleSchema tuple_schema;
tuple_schema.append_cell(TupleCellSpec("", "Field", "Field"));
tuple_schema.append_cell(TupleCellSpec("", "Type", "Type"));
tuple_schema.append_cell(TupleCellSpec("", "Length", "Length"));
// TODO add Key
sql_result->set_tuple_schema(tuple_schema);
StringListOperator *oper = new StringListOperator;
const TableMeta &table_meta = table->table_meta();
for (int i = table_meta.sys_field_num(); i < table_meta.field_num(); i++) {
const FieldMeta *field_meta = table_meta.field(i);
oper->append({field_meta->name(), attr_type_to_string(field_meta->type()),
std::to_string(field_meta->len())});
}
sql_result->set_operator(oper);
} else { } else {
ss << "No such table: " << table_name << std::endl; sql_result->set_return_code(RC::SCHEMA_TABLE_NOT_EXIST);
sql_result->set_state_string("Table not exists");
} }
sql_event->session_event()->set_response(ss.str().c_str());
return RC::SUCCESS; return RC::SUCCESS;
} }
...@@ -533,6 +553,8 @@ RC ExecuteStage::do_insert(SQLStageEvent *sql_event) ...@@ -533,6 +553,8 @@ RC ExecuteStage::do_insert(SQLStageEvent *sql_event)
{ {
Stmt *stmt = sql_event->stmt(); Stmt *stmt = sql_event->stmt();
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
SqlResult *sql_result = new SqlResult;
session_event->set_sql_result(sql_result);
Session *session = session_event->session(); Session *session = session_event->session();
Db *db = session->get_current_db(); Db *db = session->get_current_db();
Trx *trx = session->current_trx(); Trx *trx = session->current_trx();
...@@ -552,23 +574,26 @@ RC ExecuteStage::do_insert(SQLStageEvent *sql_event) ...@@ -552,23 +574,26 @@ RC ExecuteStage::do_insert(SQLStageEvent *sql_event)
CLogRecord *clog_record = nullptr; CLogRecord *clog_record = nullptr;
rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_COMMIT, trx->get_current_id(), clog_record); rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_COMMIT, trx->get_current_id(), clog_record);
if (rc != RC::SUCCESS || clog_record == nullptr) { if (rc != RC::SUCCESS || clog_record == nullptr) {
session_event->set_response("FAILURE\n"); if (rc == RC::SUCCESS) {
rc = RC::INTERNAL;
}
sql_result->set_return_code(rc);
return rc; return rc;
} }
rc = clog_manager->clog_append_record(clog_record); rc = clog_manager->clog_append_record(clog_record);
if (rc != RC::SUCCESS) { if (rc != RC::SUCCESS) {
session_event->set_response("FAILURE\n"); sql_result->set_return_code(rc);
return rc; return rc;
} }
trx->next_current_id(); trx->next_current_id();
session_event->set_response("SUCCESS\n"); sql_result->set_return_code(RC::SUCCESS);
} else { } else {
session_event->set_response("SUCCESS\n"); sql_result->set_return_code(RC::SUCCESS);
} }
} else { } else {
session_event->set_response("FAILURE\n"); sql_result->set_return_code(rc);
} }
return rc; return rc;
} }
...@@ -624,6 +649,8 @@ RC ExecuteStage::do_begin(SQLStageEvent *sql_event) ...@@ -624,6 +649,8 @@ RC ExecuteStage::do_begin(SQLStageEvent *sql_event)
{ {
RC rc = RC::SUCCESS; RC rc = RC::SUCCESS;
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
SqlResult *sql_result = new SqlResult;
session_event->set_sql_result(sql_result);
Session *session = session_event->session(); Session *session = session_event->session();
Db *db = session->get_current_db(); Db *db = session->get_current_db();
Trx *trx = session->current_trx(); Trx *trx = session->current_trx();
...@@ -634,16 +661,12 @@ RC ExecuteStage::do_begin(SQLStageEvent *sql_event) ...@@ -634,16 +661,12 @@ RC ExecuteStage::do_begin(SQLStageEvent *sql_event)
CLogRecord *clog_record = nullptr; CLogRecord *clog_record = nullptr;
rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_BEGIN, trx->get_current_id(), clog_record); rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_BEGIN, trx->get_current_id(), clog_record);
if (rc != RC::SUCCESS || clog_record == nullptr) { if (rc != RC::SUCCESS || clog_record == nullptr) {
session_event->set_response("FAILURE\n"); sql_result->set_return_code(rc);
return rc; return rc;
} }
rc = clog_manager->clog_append_record(clog_record); rc = clog_manager->clog_append_record(clog_record);
if (rc != RC::SUCCESS) { sql_result->set_return_code(rc);
session_event->set_response("FAILURE\n");
} else {
session_event->set_response("SUCCESS\n");
}
return rc; return rc;
} }
...@@ -652,6 +675,8 @@ RC ExecuteStage::do_commit(SQLStageEvent *sql_event) ...@@ -652,6 +675,8 @@ RC ExecuteStage::do_commit(SQLStageEvent *sql_event)
{ {
RC rc = RC::SUCCESS; RC rc = RC::SUCCESS;
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
SqlResult *sql_result = new SqlResult;
session_event->set_sql_result(sql_result);
Session *session = session_event->session(); Session *session = session_event->session();
Db *db = session->get_current_db(); Db *db = session->get_current_db();
Trx *trx = session->current_trx(); Trx *trx = session->current_trx();
...@@ -662,16 +687,12 @@ RC ExecuteStage::do_commit(SQLStageEvent *sql_event) ...@@ -662,16 +687,12 @@ RC ExecuteStage::do_commit(SQLStageEvent *sql_event)
CLogRecord *clog_record = nullptr; CLogRecord *clog_record = nullptr;
rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_COMMIT, trx->get_current_id(), clog_record); rc = clog_manager->clog_gen_record(CLogType::REDO_MTR_COMMIT, trx->get_current_id(), clog_record);
if (rc != RC::SUCCESS || clog_record == nullptr) { if (rc != RC::SUCCESS || clog_record == nullptr) {
session_event->set_response("FAILURE\n"); sql_result->set_return_code(rc);
return rc; return rc;
} }
rc = clog_manager->clog_append_record(clog_record); rc = clog_manager->clog_append_record(clog_record);
if (rc != RC::SUCCESS) { sql_result->set_return_code(rc);
session_event->set_response("FAILURE\n");
} else {
session_event->set_response("SUCCESS\n");
}
trx->next_current_id(); trx->next_current_id();
...@@ -681,16 +702,14 @@ RC ExecuteStage::do_commit(SQLStageEvent *sql_event) ...@@ -681,16 +702,14 @@ RC ExecuteStage::do_commit(SQLStageEvent *sql_event)
RC ExecuteStage::do_clog_sync(SQLStageEvent *sql_event) RC ExecuteStage::do_clog_sync(SQLStageEvent *sql_event)
{ {
RC rc = RC::SUCCESS; RC rc = RC::SUCCESS;
SqlResult *sql_result = new SqlResult;
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
session_event->set_sql_result(sql_result);
Db *db = session_event->session()->get_current_db(); Db *db = session_event->session()->get_current_db();
CLogManager *clog_manager = db->get_clog_manager(); CLogManager *clog_manager = db->get_clog_manager();
rc = clog_manager->clog_sync(); rc = clog_manager->clog_sync();
if (rc != RC::SUCCESS) { sql_result->set_return_code(rc);
session_event->set_response("FAILURE\n");
} else {
session_event->set_response("SUCCESS\n");
}
return rc; return rc;
} }
/* 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/11/18.
//
#include "rc.h"
#include "sql/executor/sql_result.h"
void SqlResult::set_tuple_schema(const TupleSchema &schema)
{
tuple_schema_ = schema;
}
RC SqlResult::open()
{
if (nullptr == operator_) {
return RC::INVALID_ARGUMENT;
}
return operator_->open();
}
RC SqlResult::close()
{
if (nullptr == operator_) {
return RC::INVALID_ARGUMENT;
}
return operator_->close();
}
RC SqlResult::next_tuple(Tuple *&tuple)
{
RC rc = operator_->next();
if (rc != RC::SUCCESS) {
return rc;
}
tuple = operator_->current_tuple();
return rc;
}
/* 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/11/17.
//
#pragma once
#include <string>
#include "sql/expr/tuple.h"
#include "sql/operator/operator.h"
class SqlResult {
public:
SqlResult() = default;
~SqlResult()
{
delete operator_;
operator_ = nullptr;
}
void set_tuple_schema(const TupleSchema &schema);
void set_return_code(RC rc) { return_code_ = rc; }
void set_state_string(const std::string &state_string) { state_string_ = state_string; }
void set_operator(Operator *oper) { operator_ = oper; }
bool has_operator() const { return operator_ != nullptr; }
const TupleSchema &tuple_schema() const { return tuple_schema_; }
RC return_code() const { return return_code_; }
const std::string &state_string() const { return state_string_; }
RC open();
RC close();
RC next_tuple(Tuple *&tuple);
private:
Operator *operator_ = nullptr;
TupleSchema tuple_schema_;
RC return_code_ = RC::SUCCESS;
std::string state_string_;
};
...@@ -17,7 +17,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -17,7 +17,7 @@ See the Mulan PSL v2 for more details. */
RC FieldExpr::get_value(const Tuple &tuple, TupleCell &cell) const RC FieldExpr::get_value(const Tuple &tuple, TupleCell &cell) const
{ {
return tuple.find_cell(field_, cell); return tuple.find_cell(TupleCellSpec(table_name(), field_name()), cell);
} }
RC ValueExpr::get_value(const Tuple &tuple, TupleCell & cell) const RC ValueExpr::get_value(const Tuple &tuple, TupleCell & cell) const
......
...@@ -34,6 +34,7 @@ public: ...@@ -34,6 +34,7 @@ public:
virtual RC get_value(const Tuple &tuple, TupleCell &cell) const = 0; virtual RC get_value(const Tuple &tuple, TupleCell &cell) const = 0;
virtual ExprType type() const = 0; virtual ExprType type() const = 0;
virtual AttrType value_type() const = 0;
}; };
class FieldExpr : public Expression class FieldExpr : public Expression
...@@ -49,6 +50,10 @@ public: ...@@ -49,6 +50,10 @@ public:
{ {
return ExprType::FIELD; return ExprType::FIELD;
} }
AttrType value_type() const override
{
return field_.attr_type();
}
Field &field() Field &field()
{ {
...@@ -94,6 +99,11 @@ public: ...@@ -94,6 +99,11 @@ public:
return ExprType::VALUE; return ExprType::VALUE;
} }
AttrType value_type() const override
{
return tuple_cell_.attr_type();
}
void get_tuple_cell(TupleCell &cell) const { void get_tuple_cell(TupleCell &cell) const {
cell = tuple_cell_; cell = tuple_cell_;
} }
......
...@@ -25,38 +25,17 @@ See the Mulan PSL v2 for more details. */ ...@@ -25,38 +25,17 @@ See the Mulan PSL v2 for more details. */
class Table; class Table;
class TupleCellSpec class TupleSchema
{ {
public: public:
TupleCellSpec() = default; void append_cell(const TupleCellSpec &cell) { cells_.push_back(cell); }
TupleCellSpec(Expression *expr) : expression_(expr) 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()); }
~TupleCellSpec() const TupleCellSpec &cell_at(int i) const { return cells_[i]; }
{
if (expression_) {
delete expression_;
expression_ = nullptr;
}
}
void set_alias(const char *alias)
{
this->alias_ = alias;
}
const char *alias() const
{
return alias_;
}
Expression *expression() const
{
return expression_;
}
private: private:
const char *alias_ = nullptr; std::vector<TupleCellSpec> cells_;
Expression *expression_ = nullptr;
}; };
class Tuple class Tuple
...@@ -67,9 +46,7 @@ public: ...@@ -67,9 +46,7 @@ public:
virtual int cell_num() const = 0; virtual int cell_num() const = 0;
virtual RC cell_at(int index, TupleCell &cell) const = 0; virtual RC cell_at(int index, TupleCell &cell) const = 0;
virtual RC find_cell(const Field &field, TupleCell &cell) const = 0; virtual RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const = 0;
virtual RC cell_spec_at(int index, const TupleCellSpec *&spec) const = 0;
}; };
class RowTuple : public Tuple class RowTuple : public Tuple
...@@ -78,7 +55,7 @@ public: ...@@ -78,7 +55,7 @@ public:
RowTuple() = default; RowTuple() = default;
virtual ~RowTuple() virtual ~RowTuple()
{ {
for (TupleCellSpec *spec : speces_) { for (FieldExpr *spec : speces_) {
delete spec; delete spec;
} }
speces_.clear(); speces_.clear();
...@@ -94,7 +71,7 @@ public: ...@@ -94,7 +71,7 @@ public:
table_ = table; table_ = table;
this->speces_.reserve(fields->size()); this->speces_.reserve(fields->size());
for (const FieldMeta &field : *fields) { for (const FieldMeta &field : *fields) {
speces_.push_back(new TupleCellSpec(new FieldExpr(table, &field))); speces_.push_back(new FieldExpr(table, &field));
} }
} }
...@@ -110,8 +87,7 @@ public: ...@@ -110,8 +87,7 @@ public:
return RC::INVALID_ARGUMENT; return RC::INVALID_ARGUMENT;
} }
const TupleCellSpec *spec = speces_[index]; FieldExpr *field_expr = speces_[index];
FieldExpr *field_expr = (FieldExpr *)spec->expression();
const FieldMeta *field_meta = field_expr->field().meta(); const FieldMeta *field_meta = field_expr->field().meta();
cell.set_type(field_meta->type()); cell.set_type(field_meta->type());
cell.set_data(this->record_->data() + field_meta->offset()); cell.set_data(this->record_->data() + field_meta->offset());
...@@ -119,16 +95,16 @@ public: ...@@ -119,16 +95,16 @@ public:
return RC::SUCCESS; return RC::SUCCESS;
} }
RC find_cell(const Field &field, TupleCell &cell) const override RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const override
{ {
const char *table_name = field.table_name(); const char *table_name = spec.table_name();
const char *field_name = spec.field_name();
if (0 != strcmp(table_name, table_->name())) { if (0 != strcmp(table_name, table_->name())) {
return RC::NOTFOUND; return RC::NOTFOUND;
} }
const char *field_name = field.field_name();
for (size_t i = 0; i < speces_.size(); ++i) { for (size_t i = 0; i < speces_.size(); ++i) {
const FieldExpr * field_expr = (const FieldExpr *)speces_[i]->expression(); const FieldExpr * field_expr = speces_[i];
const Field &field = field_expr->field(); const Field &field = field_expr->field();
if (0 == strcmp(field_name, field.field_name())) { if (0 == strcmp(field_name, field.field_name())) {
return cell_at(i, cell); return cell_at(i, cell);
...@@ -137,6 +113,7 @@ public: ...@@ -137,6 +113,7 @@ public:
return RC::NOTFOUND; return RC::NOTFOUND;
} }
#if 0
RC cell_spec_at(int index, const TupleCellSpec *&spec) const override RC cell_spec_at(int index, const TupleCellSpec *&spec) const override
{ {
if (index < 0 || index >= static_cast<int>(speces_.size())) { if (index < 0 || index >= static_cast<int>(speces_.size())) {
...@@ -146,6 +123,7 @@ public: ...@@ -146,6 +123,7 @@ public:
spec = speces_[index]; spec = speces_[index];
return RC::SUCCESS; return RC::SUCCESS;
} }
#endif
Record &record() Record &record()
{ {
...@@ -159,21 +137,9 @@ public: ...@@ -159,21 +137,9 @@ public:
private: private:
Record *record_ = nullptr; Record *record_ = nullptr;
const Table *table_ = nullptr; const Table *table_ = nullptr;
std::vector<TupleCellSpec *> speces_; std::vector<FieldExpr *> speces_;
}; };
/*
class CompositeTuple : public Tuple
{
public:
int cell_num() const override;
RC cell_at(int index, TupleCell &cell) const = 0;
private:
int cell_num_ = 0;
std::vector<Tuple *> tuples_;
};
*/
class ProjectTuple : public Tuple class ProjectTuple : public Tuple
{ {
public: public:
...@@ -210,13 +176,15 @@ public: ...@@ -210,13 +176,15 @@ public:
} }
const TupleCellSpec *spec = speces_[index]; const TupleCellSpec *spec = speces_[index];
return spec->expression()->get_value(*tuple_, cell); return tuple_->find_cell(*spec, cell);
} }
RC find_cell(const Field &field, TupleCell &cell) const override RC find_cell(const TupleCellSpec &spec, TupleCell &cell) const override
{ {
return tuple_->find_cell(field, cell); return tuple_->find_cell(spec, cell);
} }
#if 0
RC cell_spec_at(int index, const TupleCellSpec *&spec) const override RC cell_spec_at(int index, const TupleCellSpec *&spec) const override
{ {
if (index < 0 || index >= static_cast<int>(speces_.size())) { if (index < 0 || index >= static_cast<int>(speces_.size())) {
...@@ -225,7 +193,43 @@ public: ...@@ -225,7 +193,43 @@ public:
spec = speces_[index]; spec = speces_[index];
return RC::SUCCESS; return RC::SUCCESS;
} }
#endif
private: private:
std::vector<TupleCellSpec *> speces_; std::vector<TupleCellSpec *> speces_;
Tuple *tuple_ = nullptr; Tuple *tuple_ = nullptr;
}; };
class ValueListTuple : public Tuple
{
public:
ValueListTuple() = default;
virtual ~ValueListTuple() = default;
void set_cells(const std::vector<TupleCell> &cells)
{
cells_ = cells;
}
virtual int cell_num() const override
{
return static_cast<int>(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<TupleCell> cells_;
};
...@@ -18,6 +18,27 @@ See the Mulan PSL v2 for more details. */ ...@@ -18,6 +18,27 @@ See the Mulan PSL v2 for more details. */
#include "util/comparator.h" #include "util/comparator.h"
#include "util/util.h" #include "util/util.h"
TupleCellSpec::TupleCellSpec(const char *table_name, const char *field_name, const char *alias)
{
if (table_name) {
table_name_ = table_name;
}
if (field_name) {
field_name_ = field_name;
}
if (alias) {
alias_ = alias;
}
}
TupleCellSpec::TupleCellSpec(const char *alias)
{
if (alias) {
alias_ = alias;
}
}
////////////////////////////////////////////////////////////////////////////////
void TupleCell::to_string(std::ostream &os) const void TupleCell::to_string(std::ostream &os) const
{ {
switch (attr_type_) { switch (attr_type_) {
......
...@@ -18,6 +18,22 @@ See the Mulan PSL v2 for more details. */ ...@@ -18,6 +18,22 @@ See the Mulan PSL v2 for more details. */
#include "storage/common/table.h" #include "storage/common/table.h"
#include "storage/common/field_meta.h" #include "storage/common/field_meta.h"
class TupleCellSpec
{
public:
TupleCellSpec(const char *table_name, const char *field_name, const char *alias = nullptr);
TupleCellSpec(const char *alias);
const char *table_name() const { return table_name_.c_str(); }
const char *field_name() const { return field_name_.c_str(); }
const char *alias() const { return alias_.c_str(); }
private:
std::string table_name_;
std::string field_name_;
std::string alias_;
};
class TupleCell class TupleCell
{ {
public: public:
......
...@@ -36,8 +36,6 @@ public: ...@@ -36,8 +36,6 @@ public:
Tuple * current_tuple() override { Tuple * current_tuple() override {
return nullptr; return nullptr;
} }
//int tuple_cell_num() const override
//RC tuple_cell_spec_at(int index, TupleCellSpec &spec) const override
private: private:
DeleteStmt *delete_stmt_ = nullptr; DeleteStmt *delete_stmt_ = nullptr;
Trx *trx_ = nullptr; Trx *trx_ = nullptr;
......
...@@ -9,24 +9,14 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ...@@ -9,24 +9,14 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */ See the Mulan PSL v2 for more details. */
// //
// Created by Longda on 2021/4/13. // Created by WangYunlai on 2022/11/18.
// //
#ifndef __SRC_OBSERVER_NET_CONNECTION_CONTEXT_H__ #include "sql/operator/operator.h"
#define __SRC_OBSERVER_NET_CONNECTION_CONTEXT_H__
#include <event.h> Operator::~Operator()
#include <ini_setting.h> {
for (Operator *oper : children_) {
class Session; delete oper;
}
typedef struct _ConnectionContext { }
Session *session;
int fd;
struct event read_event;
pthread_mutex_t mutex;
char addr[24];
char buf[SOCKET_BUFFER_SIZE];
} ConnectionContext;
#endif //__SRC_OBSERVER_NET_CONNECTION_CONTEXT_H__
...@@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ...@@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */ See the Mulan PSL v2 for more details. */
// //
// Created by WangYunlai on 2021/6/7. // Created by WangYunlai on 2022/6/7.
// //
#pragma once #pragma once
...@@ -27,15 +27,13 @@ public: ...@@ -27,15 +27,13 @@ public:
Operator() Operator()
{} {}
virtual ~Operator() = default; virtual ~Operator();
virtual RC open() = 0; virtual RC open() = 0;
virtual RC next() = 0; virtual RC next() = 0;
virtual RC close() = 0; virtual RC close() = 0;
virtual Tuple * current_tuple() = 0; virtual Tuple * current_tuple() = 0;
//virtual int tuple_cell_num() const = 0;
//virtual RC tuple_cell_spec_at(int index, TupleCellSpec *&spec) const = 0;
void add_child(Operator *oper) { void add_child(Operator *oper) {
children_.push_back(oper); children_.push_back(oper);
......
...@@ -105,12 +105,3 @@ bool PredicateOperator::do_predicate(RowTuple &tuple) ...@@ -105,12 +105,3 @@ bool PredicateOperator::do_predicate(RowTuple &tuple)
} }
return true; return true;
} }
// int PredicateOperator::tuple_cell_num() const
// {
// return children_[0]->tuple_cell_num();
// }
// RC PredicateOperator::tuple_cell_spec_at(int index, TupleCellSpec &spec) const
// {
// return children_[0]->tuple_cell_spec_at(index, spec);
// }
...@@ -36,8 +36,6 @@ public: ...@@ -36,8 +36,6 @@ public:
RC close() override; RC close() override;
Tuple * current_tuple() override; Tuple * current_tuple() override;
//int tuple_cell_num() const override;
//RC tuple_cell_spec_at(int index, TupleCellSpec &spec) const override;
private: private:
bool do_predicate(RowTuple &tuple); bool do_predicate(RowTuple &tuple);
private: private:
......
...@@ -54,12 +54,6 @@ void ProjectOperator::add_projection(const Table *table, const FieldMeta *field_ ...@@ -54,12 +54,6 @@ void ProjectOperator::add_projection(const Table *table, const FieldMeta *field_
{ {
// 对单表来说,展示的(alias) 字段总是字段名称, // 对单表来说,展示的(alias) 字段总是字段名称,
// 对多表查询来说,展示的alias 需要带表名字 // 对多表查询来说,展示的alias 需要带表名字
TupleCellSpec *spec = new TupleCellSpec(new FieldExpr(table, field_meta)); TupleCellSpec *spec = new TupleCellSpec(table->name(), field_meta->name(), field_meta->name());
spec->set_alias(field_meta->name());
tuple_.add_cell_spec(spec); tuple_.add_cell_spec(spec);
} }
RC ProjectOperator::tuple_cell_spec_at(int index, const TupleCellSpec *&spec) const
{
return tuple_.cell_spec_at(index, spec);
}
...@@ -36,8 +36,6 @@ public: ...@@ -36,8 +36,6 @@ public:
return tuple_.cell_num(); return tuple_.cell_num();
} }
RC tuple_cell_spec_at(int index, const TupleCellSpec *&spec) const;
Tuple * current_tuple() override; Tuple * current_tuple() override;
private: private:
ProjectTuple tuple_; ProjectTuple tuple_;
......
/* 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/11/18.
//
#pragma once
#include <vector>
class StringListOperator : public Operator
{
public:
StringListOperator()
{}
virtual ~StringListOperator() = default;
template <typename InputIt>
void append(InputIt begin, InputIt end)
{
strings_.emplace_back(begin, end);
}
void append(std::initializer_list<std::string> init)
{
strings_.emplace_back(init);
}
template <typename T>
void append( const T &v)
{
strings_.emplace_back(1, v);
}
RC open() override
{
return RC::SUCCESS;
}
RC next() override
{
if (!started_) {
started_ = true;
iterator_ = strings_.begin();
} else if (iterator_ != strings_.end()) {
++iterator_;
}
return iterator_ == strings_.end() ? RC::RECORD_EOF : RC::SUCCESS;
}
virtual RC close() override
{
iterator_ = strings_.end();
return RC::SUCCESS;
}
virtual Tuple * current_tuple() override
{
if (iterator_ == strings_.end()) {
return nullptr;
}
const StringList &string_list = *iterator_;
std::vector<TupleCell> cells;
for (const std::string &s : string_list) {
TupleCell cell(CHARS, const_cast<char *>(s.data()));
cell.set_length(s.length());
cells.push_back(cell);
}
tuple_.set_cells(cells);
return &tuple_;
}
private:
using StringList = std::vector<std::string>;
using StringListList = std::vector<StringList>;
StringListList strings_;
StringListList::iterator iterator_;
bool started_ = false;
ValueListTuple tuple_;
};
...@@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ...@@ -9,7 +9,7 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */ See the Mulan PSL v2 for more details. */
// //
// Created by WangYunlai on 2021/6/7. // Created by WangYunlai on 2022/6/7.
// //
#pragma once #pragma once
...@@ -35,12 +35,6 @@ public: ...@@ -35,12 +35,6 @@ public:
Tuple * current_tuple() override; Tuple * current_tuple() override;
// int tuple_cell_num() const override
// {
// return tuple_.cell_num();
// }
// RC tuple_cell_spec_at(int index, TupleCellSpec &spec) const override;
private: private:
Table *table_ = nullptr; Table *table_ = nullptr;
RecordFileScanner record_scanner_; RecordFileScanner record_scanner_;
......
...@@ -19,14 +19,14 @@ See the Mulan PSL v2 for more details. */ ...@@ -19,14 +19,14 @@ See the Mulan PSL v2 for more details. */
RC parse(char *st, Query *sqln); RC parse(char *st, Query *sqln);
void relation_attr_init(RelAttr *relation_attr, const char *relation_name, const char *attribute_name) void relation_attr_init(RelAttr *relation_attr, char *relation_name, char *attribute_name)
{ {
if (relation_name != nullptr) { if (relation_name != nullptr) {
relation_attr->relation_name = strdup(relation_name); relation_attr->relation_name = relation_name;
} else { } else {
relation_attr->relation_name = nullptr; relation_attr->relation_name = nullptr;
} }
relation_attr->attribute_name = strdup(attribute_name); relation_attr->attribute_name = attribute_name;
} }
void relation_attr_destroy(RelAttr *relation_attr) void relation_attr_destroy(RelAttr *relation_attr)
...@@ -49,6 +49,11 @@ void value_init_float(Value *value, float v) ...@@ -49,6 +49,11 @@ void value_init_float(Value *value, float v)
value->data = malloc(sizeof(v)); value->data = malloc(sizeof(v));
memcpy(value->data, &v, sizeof(v)); memcpy(value->data, &v, sizeof(v));
} }
void value_init_string(Value *value, char *v)
{
value->type = CHARS;
value->data = v;
}
void value_init_string(Value *value, const char *v) void value_init_string(Value *value, const char *v)
{ {
value->type = CHARS; value->type = CHARS;
...@@ -93,9 +98,9 @@ void condition_destroy(Condition *condition) ...@@ -93,9 +98,9 @@ void condition_destroy(Condition *condition)
} }
} }
void attr_info_init(AttrInfo *attr_info, const char *name, AttrType type, size_t length) void attr_info_init(AttrInfo *attr_info, char *name, AttrType type, size_t length)
{ {
attr_info->name = strdup(name); attr_info->name = name;
attr_info->type = type; attr_info->type = type;
attr_info->length = length; attr_info->length = length;
} }
...@@ -110,9 +115,9 @@ void selects_append_attribute(Selects *selects, RelAttr *rel_attr) ...@@ -110,9 +115,9 @@ void selects_append_attribute(Selects *selects, RelAttr *rel_attr)
{ {
selects->attributes[selects->attr_num++] = *rel_attr; selects->attributes[selects->attr_num++] = *rel_attr;
} }
void selects_append_relation(Selects *selects, const char *relation_name) void selects_append_relation(Selects *selects, char *relation_name)
{ {
selects->relations[selects->relation_num++] = strdup(relation_name); selects->relations[selects->relation_num++] = relation_name;
} }
void selects_append_conditions(Selects *selects, Condition conditions[], size_t condition_num) void selects_append_conditions(Selects *selects, Condition conditions[], size_t condition_num)
...@@ -143,11 +148,11 @@ void selects_destroy(Selects *selects) ...@@ -143,11 +148,11 @@ void selects_destroy(Selects *selects)
selects->condition_num = 0; selects->condition_num = 0;
} }
void inserts_init(Inserts *inserts, const char *relation_name, Value values[], size_t value_num) void inserts_init(Inserts *inserts, char *relation_name, Value values[], size_t value_num)
{ {
assert(value_num <= sizeof(inserts->values) / sizeof(inserts->values[0])); assert(value_num <= sizeof(inserts->values) / sizeof(inserts->values[0]));
inserts->relation_name = strdup(relation_name); inserts->relation_name = relation_name;
for (size_t i = 0; i < value_num; i++) { for (size_t i = 0; i < value_num; i++) {
inserts->values[i] = values[i]; inserts->values[i] = values[i];
} }
...@@ -164,9 +169,9 @@ void inserts_destroy(Inserts *inserts) ...@@ -164,9 +169,9 @@ void inserts_destroy(Inserts *inserts)
inserts->value_num = 0; inserts->value_num = 0;
} }
void deletes_init_relation(Deletes *deletes, const char *relation_name) void deletes_init_relation(Deletes *deletes, char *relation_name)
{ {
deletes->relation_name = strdup(relation_name); deletes->relation_name = relation_name;
} }
void deletes_set_conditions(Deletes *deletes, Condition conditions[], size_t condition_num) void deletes_set_conditions(Deletes *deletes, Condition conditions[], size_t condition_num)
...@@ -187,11 +192,11 @@ void deletes_destroy(Deletes *deletes) ...@@ -187,11 +192,11 @@ void deletes_destroy(Deletes *deletes)
deletes->relation_name = nullptr; deletes->relation_name = nullptr;
} }
void updates_init(Updates *updates, const char *relation_name, const char *attribute_name, Value *value, void updates_init(Updates *updates, char *relation_name, char *attribute_name, Value *value,
Condition conditions[], size_t condition_num) Condition conditions[], size_t condition_num)
{ {
updates->relation_name = strdup(relation_name); updates->relation_name = relation_name;
updates->attribute_name = strdup(attribute_name); updates->attribute_name = attribute_name;
updates->value = *value; updates->value = *value;
assert(condition_num <= sizeof(updates->conditions) / sizeof(updates->conditions[0])); assert(condition_num <= sizeof(updates->conditions) / sizeof(updates->conditions[0]));
...@@ -221,9 +226,9 @@ void create_table_append_attribute(CreateTable *create_table, AttrInfo *attr_inf ...@@ -221,9 +226,9 @@ void create_table_append_attribute(CreateTable *create_table, AttrInfo *attr_inf
create_table->attributes[create_table->attribute_count++] = *attr_info; create_table->attributes[create_table->attribute_count++] = *attr_info;
} }
void create_table_init_name(CreateTable *create_table, const char *relation_name) void create_table_init_name(CreateTable *create_table, char *relation_name)
{ {
create_table->relation_name = strdup(relation_name); create_table->relation_name = relation_name;
} }
void create_table_destroy(CreateTable *create_table) void create_table_destroy(CreateTable *create_table)
...@@ -236,9 +241,9 @@ void create_table_destroy(CreateTable *create_table) ...@@ -236,9 +241,9 @@ void create_table_destroy(CreateTable *create_table)
create_table->relation_name = nullptr; create_table->relation_name = nullptr;
} }
void drop_table_init(DropTable *drop_table, const char *relation_name) void drop_table_init(DropTable *drop_table, char *relation_name)
{ {
drop_table->relation_name = strdup(relation_name); drop_table->relation_name = relation_name;
} }
void drop_table_destroy(DropTable *drop_table) void drop_table_destroy(DropTable *drop_table)
...@@ -248,11 +253,11 @@ void drop_table_destroy(DropTable *drop_table) ...@@ -248,11 +253,11 @@ void drop_table_destroy(DropTable *drop_table)
} }
void create_index_init( void create_index_init(
CreateIndex *create_index, const char *index_name, const char *relation_name, const char *attr_name) CreateIndex *create_index, char *index_name, char *relation_name, char *attr_name)
{ {
create_index->index_name = strdup(index_name); create_index->index_name = index_name;
create_index->relation_name = strdup(relation_name); create_index->relation_name = relation_name;
create_index->attribute_name = strdup(attr_name); create_index->attribute_name = attr_name;
} }
void create_index_destroy(CreateIndex *create_index) void create_index_destroy(CreateIndex *create_index)
...@@ -266,9 +271,9 @@ void create_index_destroy(CreateIndex *create_index) ...@@ -266,9 +271,9 @@ void create_index_destroy(CreateIndex *create_index)
create_index->attribute_name = nullptr; create_index->attribute_name = nullptr;
} }
void drop_index_init(DropIndex *drop_index, const char *index_name) void drop_index_init(DropIndex *drop_index, char *index_name)
{ {
drop_index->index_name = strdup(index_name); drop_index->index_name = index_name;
} }
void drop_index_destroy(DropIndex *drop_index) void drop_index_destroy(DropIndex *drop_index)
...@@ -277,9 +282,9 @@ void drop_index_destroy(DropIndex *drop_index) ...@@ -277,9 +282,9 @@ void drop_index_destroy(DropIndex *drop_index)
drop_index->index_name = nullptr; drop_index->index_name = nullptr;
} }
void desc_table_init(DescTable *desc_table, const char *relation_name) void desc_table_init(DescTable *desc_table, char *relation_name)
{ {
desc_table->relation_name = strdup(relation_name); desc_table->relation_name = relation_name;
} }
void desc_table_destroy(DescTable *desc_table) void desc_table_destroy(DescTable *desc_table)
...@@ -288,14 +293,14 @@ void desc_table_destroy(DescTable *desc_table) ...@@ -288,14 +293,14 @@ void desc_table_destroy(DescTable *desc_table)
desc_table->relation_name = nullptr; desc_table->relation_name = nullptr;
} }
void load_data_init(LoadData *load_data, const char *relation_name, const char *file_name) void load_data_init(LoadData *load_data, char *relation_name, char *file_name)
{ {
load_data->relation_name = strdup(relation_name); load_data->relation_name = relation_name;
if (file_name[0] == '\'' || file_name[0] == '\"') { if (file_name[0] == '\'' || file_name[0] == '\"') {
file_name++; file_name++;
} }
char *dup_file_name = strdup(file_name); char *dup_file_name = file_name;
int len = strlen(dup_file_name); int len = strlen(dup_file_name);
if (dup_file_name[len - 1] == '\'' || dup_file_name[len - 1] == '\"') { if (dup_file_name[len - 1] == '\'' || dup_file_name[len - 1] == '\"') {
dup_file_name[len - 1] = 0; dup_file_name[len - 1] = 0;
...@@ -386,6 +391,25 @@ void query_destroy(Query *query) ...@@ -386,6 +391,25 @@ void query_destroy(Query *query)
free(query); free(query);
} }
const char *ATTR_TYPE_NAME[] = {"undefined", "chars", "ints", "floats"};
const char *attr_type_to_string(AttrType type)
{
if (type >= UNDEFINED && type <= FLOATS) {
return ATTR_TYPE_NAME[type];
}
return "unknown";
}
AttrType attr_type_from_string(const char *s)
{
for (unsigned int i = 0; i < sizeof(ATTR_TYPE_NAME) / sizeof(ATTR_TYPE_NAME[0]); i++) {
if (0 == strcmp(ATTR_TYPE_NAME[i], s)) {
return (AttrType)i;
}
}
return UNDEFINED;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int sql_parse(const char *st, Query *sqls); int sql_parse(const char *st, Query *sqls);
......
...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */
// Created by Meiyi // Created by Meiyi
// //
#ifndef __OBSERVER_SQL_PARSER_PARSE_DEFS_H__ #pragma once
#define __OBSERVER_SQL_PARSER_PARSE_DEFS_H__
#include <stddef.h> #include <stddef.h>
...@@ -180,11 +179,12 @@ typedef struct Query { ...@@ -180,11 +179,12 @@ typedef struct Query {
union Queries sstr; union Queries sstr;
} Query; } Query;
void relation_attr_init(RelAttr *relation_attr, const char *relation_name, const char *attribute_name); void relation_attr_init(RelAttr *relation_attr, char *relation_name, char *attribute_name);
void relation_attr_destroy(RelAttr *relation_attr); void relation_attr_destroy(RelAttr *relation_attr);
void value_init_integer(Value *value, int v); void value_init_integer(Value *value, int v);
void value_init_float(Value *value, float v); void value_init_float(Value *value, float v);
void value_init_string(Value *value, char *v);
void value_init_string(Value *value, const char *v); void value_init_string(Value *value, const char *v);
void value_destroy(Value *value); void value_destroy(Value *value);
...@@ -192,44 +192,44 @@ void condition_init(Condition *condition, CompOp comp, int left_is_attr, RelAttr ...@@ -192,44 +192,44 @@ void condition_init(Condition *condition, CompOp comp, int left_is_attr, RelAttr
int right_is_attr, RelAttr *right_attr, Value *right_value); int right_is_attr, RelAttr *right_attr, Value *right_value);
void condition_destroy(Condition *condition); void condition_destroy(Condition *condition);
void attr_info_init(AttrInfo *attr_info, const char *name, AttrType type, size_t length); void attr_info_init(AttrInfo *attr_info, char *name, AttrType type, size_t length);
void attr_info_destroy(AttrInfo *attr_info); void attr_info_destroy(AttrInfo *attr_info);
void selects_init(Selects *selects, ...); void selects_init(Selects *selects, ...);
void selects_append_attribute(Selects *selects, RelAttr *rel_attr); void selects_append_attribute(Selects *selects, RelAttr *rel_attr);
void selects_append_relation(Selects *selects, const char *relation_name); void selects_append_relation(Selects *selects, char *relation_name);
void selects_append_conditions(Selects *selects, Condition conditions[], size_t condition_num); void selects_append_conditions(Selects *selects, Condition conditions[], size_t condition_num);
void selects_destroy(Selects *selects); void selects_destroy(Selects *selects);
void inserts_init(Inserts *inserts, const char *relation_name, Value values[], size_t value_num); void inserts_init(Inserts *inserts, char *relation_name, Value values[], size_t value_num);
void inserts_destroy(Inserts *inserts); void inserts_destroy(Inserts *inserts);
void deletes_init_relation(Deletes *deletes, const char *relation_name); void deletes_init_relation(Deletes *deletes, char *relation_name);
void deletes_set_conditions(Deletes *deletes, Condition conditions[], size_t condition_num); void deletes_set_conditions(Deletes *deletes, Condition conditions[], size_t condition_num);
void deletes_destroy(Deletes *deletes); void deletes_destroy(Deletes *deletes);
void updates_init(Updates *updates, const char *relation_name, const char *attribute_name, Value *value, void updates_init(Updates *updates, char *relation_name, char *attribute_name, Value *value,
Condition conditions[], size_t condition_num); Condition conditions[], size_t condition_num);
void updates_destroy(Updates *updates); void updates_destroy(Updates *updates);
void create_table_append_attribute(CreateTable *create_table, AttrInfo *attr_info); void create_table_append_attribute(CreateTable *create_table, AttrInfo *attr_info);
void create_table_init_name(CreateTable *create_table, const char *relation_name); void create_table_init_name(CreateTable *create_table, char *relation_name);
void create_table_destroy(CreateTable *create_table); void create_table_destroy(CreateTable *create_table);
void drop_table_init(DropTable *drop_table, const char *relation_name); void drop_table_init(DropTable *drop_table, char *relation_name);
void drop_table_destroy(DropTable *drop_table); void drop_table_destroy(DropTable *drop_table);
void create_index_init( void create_index_init(
CreateIndex *create_index, const char *index_name, const char *relation_name, const char *attr_name); CreateIndex *create_index, char *index_name, char *relation_name, char *attr_name);
void create_index_destroy(CreateIndex *create_index); void create_index_destroy(CreateIndex *create_index);
void drop_index_init(DropIndex *drop_index, const char *index_name); void drop_index_init(DropIndex *drop_index, char *index_name);
void drop_index_destroy(DropIndex *drop_index); void drop_index_destroy(DropIndex *drop_index);
void desc_table_init(DescTable *desc_table, const char *relation_name); void desc_table_init(DescTable *desc_table, char *relation_name);
void desc_table_destroy(DescTable *desc_table); void desc_table_destroy(DescTable *desc_table);
void load_data_init(LoadData *load_data, const char *relation_name, const char *file_name); void load_data_init(LoadData *load_data, char *relation_name, char *file_name);
void load_data_destroy(LoadData *load_data); void load_data_destroy(LoadData *load_data);
void query_init(Query *query); void query_init(Query *query);
...@@ -237,4 +237,5 @@ Query *query_create(); // create and init ...@@ -237,4 +237,5 @@ Query *query_create(); // create and init
void query_reset(Query *query); void query_reset(Query *query);
void query_destroy(Query *query); // reset and delete void query_destroy(Query *query); // reset and delete
#endif // __OBSERVER_SQL_PARSER_PARSE_DEFS_H__ const char *attr_type_to_string(AttrType type);
AttrType attr_type_from_string(const char *s);
...@@ -129,10 +129,13 @@ RC ParseStage::handle_request(StageEvent *event) ...@@ -129,10 +129,13 @@ RC ParseStage::handle_request(StageEvent *event)
return RC::INTERNAL; return RC::INTERNAL;
} }
SqlResult *sql_result = new SqlResult;
RC ret = parse(sql.c_str(), query_result); RC ret = parse(sql.c_str(), query_result);
if (ret != RC::SUCCESS) { if (ret != RC::SUCCESS) {
// set error information to event // set error information to event
sql_event->session_event()->set_response("Failed to parse sql\n"); sql_result->set_return_code(ret);
sql_result->set_state_string("Failed to parse sql");
sql_event->session_event()->set_sql_result(sql_result);
query_destroy(query_result); query_destroy(query_result);
return RC::INTERNAL; return RC::INTERNAL;
} }
......
...@@ -106,7 +106,9 @@ void ResolveStage::handle_event(StageEvent *event) ...@@ -106,7 +106,9 @@ void ResolveStage::handle_event(StageEvent *event)
RC rc = Stmt::create_stmt(db, *query, stmt); RC rc = Stmt::create_stmt(db, *query, stmt);
if (rc != RC::SUCCESS && rc != RC::UNIMPLENMENT) { if (rc != RC::SUCCESS && rc != RC::UNIMPLENMENT) {
LOG_WARN("failed to create stmt. rc=%d:%s", rc, strrc(rc)); LOG_WARN("failed to create stmt. rc=%d:%s", rc, strrc(rc));
session_event->set_response("FAILURE\n"); SqlResult *sql_result = new SqlResult;
sql_result->set_return_code(rc);
session_event->set_sql_result(sql_result);
return; return;
} }
......
...@@ -222,21 +222,20 @@ enum yysymbol_kind_t ...@@ -222,21 +222,20 @@ enum yysymbol_kind_t
YYSYMBOL_attr_def = 67, /* attr_def */ YYSYMBOL_attr_def = 67, /* attr_def */
YYSYMBOL_number = 68, /* number */ YYSYMBOL_number = 68, /* number */
YYSYMBOL_type = 69, /* type */ YYSYMBOL_type = 69, /* type */
YYSYMBOL_ID_get = 70, /* ID_get */ YYSYMBOL_insert = 70, /* insert */
YYSYMBOL_insert = 71, /* insert */ YYSYMBOL_value_list = 71, /* value_list */
YYSYMBOL_value_list = 72, /* value_list */ YYSYMBOL_value = 72, /* value */
YYSYMBOL_value = 73, /* value */ YYSYMBOL_delete = 73, /* delete */
YYSYMBOL_delete = 74, /* delete */ YYSYMBOL_update = 74, /* update */
YYSYMBOL_update = 75, /* update */ YYSYMBOL_select = 75, /* select */
YYSYMBOL_select = 76, /* select */ YYSYMBOL_select_attr = 76, /* select_attr */
YYSYMBOL_select_attr = 77, /* select_attr */ YYSYMBOL_attr_list = 77, /* attr_list */
YYSYMBOL_attr_list = 78, /* attr_list */ YYSYMBOL_rel_list = 78, /* rel_list */
YYSYMBOL_rel_list = 79, /* rel_list */ YYSYMBOL_where = 79, /* where */
YYSYMBOL_where = 80, /* where */ YYSYMBOL_condition_list = 80, /* condition_list */
YYSYMBOL_condition_list = 81, /* condition_list */ YYSYMBOL_condition = 81, /* condition */
YYSYMBOL_condition = 82, /* condition */ YYSYMBOL_comOp = 82, /* comOp */
YYSYMBOL_comOp = 83, /* comOp */ YYSYMBOL_load_data = 83 /* load_data */
YYSYMBOL_load_data = 84 /* load_data */
}; };
typedef enum yysymbol_kind_t yysymbol_kind_t; typedef enum yysymbol_kind_t yysymbol_kind_t;
...@@ -546,16 +545,16 @@ union yyalloc ...@@ -546,16 +545,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */ /* YYFINAL -- State number of the termination state. */
#define YYFINAL 2 #define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */ /* YYLAST -- Last index in YYTABLE. */
#define YYLAST 148 #define YYLAST 150
/* YYNTOKENS -- Number of terminals. */ /* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 51 #define YYNTOKENS 51
/* YYNNTS -- Number of nonterminals. */ /* YYNNTS -- Number of nonterminals. */
#define YYNNTS 34 #define YYNNTS 33
/* YYNRULES -- Number of rules. */ /* YYNRULES -- Number of rules. */
#define YYNRULES 76 #define YYNRULES 75
/* YYNSTATES -- Number of states. */ /* YYNSTATES -- Number of states. */
#define YYNSTATES 162 #define YYNSTATES 161
/* YYMAXUTOK -- Last valid token kind. */ /* YYMAXUTOK -- Last valid token kind. */
#define YYMAXUTOK 305 #define YYMAXUTOK 305
...@@ -613,10 +612,10 @@ static const yytype_int16 yyrline[] = ...@@ -613,10 +612,10 @@ static const yytype_int16 yyrline[] =
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
154, 158, 163, 168, 174, 180, 186, 192, 198, 204, 154, 158, 163, 168, 174, 180, 186, 192, 198, 204,
211, 219, 226, 234, 236, 240, 247, 256, 259, 260, 211, 219, 226, 234, 236, 240, 247, 256, 259, 260,
261, 264, 273, 282, 284, 289, 292, 295, 302, 312, 261, 264, 273, 275, 280, 283, 286, 294, 304, 314,
322, 339, 344, 349, 355, 357, 362, 369, 371, 375, 331, 336, 341, 347, 349, 354, 361, 363, 367, 369,
377, 381, 383, 388, 399, 408, 419, 429, 439, 450, 373, 375, 380, 391, 400, 411, 421, 431, 442, 456,
464, 465, 466, 467, 468, 469, 473 457, 458, 459, 460, 461, 465
}; };
#endif #endif
...@@ -641,10 +640,10 @@ static const char *const yytname[] = ...@@ -641,10 +640,10 @@ static const char *const yytname[] =
"FLOAT", "ID", "PATH", "SSS", "STAR", "STRING_V", "$accept", "commands", "FLOAT", "ID", "PATH", "SSS", "STAR", "STRING_V", "$accept", "commands",
"command", "exit", "help", "sync", "begin", "commit", "rollback", "command", "exit", "help", "sync", "begin", "commit", "rollback",
"drop_table", "show_tables", "desc_table", "create_index", "drop_index", "drop_table", "show_tables", "desc_table", "create_index", "drop_index",
"create_table", "attr_def_list", "attr_def", "number", "type", "ID_get", "create_table", "attr_def_list", "attr_def", "number", "type", "insert",
"insert", "value_list", "value", "delete", "update", "select", "value_list", "value", "delete", "update", "select", "select_attr",
"select_attr", "attr_list", "rel_list", "where", "condition_list", "attr_list", "rel_list", "where", "condition_list", "condition", "comOp",
"condition", "comOp", "load_data", YY_NULLPTR "load_data", YY_NULLPTR
}; };
static const char * static const char *
...@@ -668,7 +667,7 @@ static const yytype_int16 yytoknum[] = ...@@ -668,7 +667,7 @@ static const yytype_int16 yytoknum[] =
}; };
#endif #endif
#define YYPACT_NINF (-95) #define YYPACT_NINF (-94)
#define yypact_value_is_default(Yyn) \ #define yypact_value_is_default(Yyn) \
((Yyn) == YYPACT_NINF) ((Yyn) == YYPACT_NINF)
...@@ -682,23 +681,23 @@ static const yytype_int16 yytoknum[] = ...@@ -682,23 +681,23 @@ static const yytype_int16 yytoknum[] =
STATE-NUM. */ STATE-NUM. */
static const yytype_int16 yypact[] = static const yytype_int16 yypact[] =
{ {
-95, 5, -95, 78, 79, 31, -40, 0, 8, -1, -94, 5, -94, 26, 83, 36, -40, 0, 8, -1,
-7, -14, 39, 40, 53, 54, 64, 26, -95, -95, -7, -10, 39, 40, 53, 54, 59, 2, -94, -94,
-95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
-95, -95, -95, -95, -95, -95, 33, 42, 43, 44, -94, -94, -94, -94, -94, -94, 21, 31, 38, 44,
-6, -95, 61, 69, 89, -95, 47, 48, 62, -95, -6, -94, 42, 78, 89, -94, 47, 48, 62, -94,
-95, -95, -95, -95, 60, 80, 65, 95, 97, 55, -94, -94, -94, -94, 60, 80, 65, 95, 97, 55,
56, -95, 57, -95, -95, 75, 74, 63, 58, 66, 56, -94, 57, -94, -94, 75, 74, 61, 58, 63,
67, -95, -95, -5, 90, 92, 91, 15, 108, 76, 66, -94, -94, -5, 90, 92, 98, 15, 108, 77,
87, -95, 98, 59, 101, 72, -95, -95, 73, 74, 85, 64, 99, 100, 72, -94, -94, 73, 74, 35,
-10, -95, -95, 6, -95, 12, 88, -95, -10, 115, -94, -94, 6, -94, 12, 88, -94, 35, 115, -94,
66, 105, -95, -95, -95, 107, 81, 90, 92, 121, -94, -94, 106, 63, 107, 79, 90, 92, 120, 109,
110, 83, -95, -95, -95, -95, -95, -95, 20, 25, 82, -94, -94, -94, -94, -94, -94, 20, 25, 15,
15, -95, 74, 84, 98, 122, 82, 114, -95, -95, -94, 74, 84, 87, 99, 123, 112, -94, -94, -94,
-95, -10, 116, 12, -95, -95, 109, -95, 88, 129, 35, 116, 12, -94, -94, 105, -94, 88, 131, 132,
131, -95, -95, -95, 118, 134, 110, 135, 30, 93, -94, 119, -94, -94, 134, 109, 135, 30, 93, -94,
-95, -95, -95, -95, -95, -95, -95, 113, -95, -95, -94, -94, -94, -94, -94, -94, 113, -94, -94, 96,
96, -95 -94
}; };
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
...@@ -710,37 +709,37 @@ static const yytype_int8 yydefact[] = ...@@ -710,37 +709,37 @@ static const yytype_int8 yydefact[] =
0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20,
19, 14, 15, 16, 17, 9, 10, 11, 12, 13, 19, 14, 15, 16, 17, 9, 10, 11, 12, 13,
8, 5, 7, 6, 4, 18, 0, 0, 0, 0, 8, 5, 7, 6, 4, 18, 0, 0, 0, 0,
54, 51, 0, 0, 0, 23, 0, 0, 0, 24, 53, 50, 0, 0, 0, 23, 0, 0, 0, 24,
25, 26, 22, 21, 0, 0, 0, 0, 0, 0, 25, 26, 22, 21, 0, 0, 0, 0, 0, 0,
0, 52, 0, 29, 28, 0, 59, 0, 0, 0, 0, 51, 0, 29, 28, 0, 58, 0, 0, 0,
0, 27, 31, 54, 54, 57, 0, 0, 0, 0, 0, 27, 31, 53, 53, 56, 0, 0, 0, 0,
0, 41, 33, 0, 0, 0, 55, 53, 0, 59, 0, 0, 33, 0, 0, 54, 52, 0, 58, 0,
0, 45, 46, 0, 47, 0, 61, 48, 0, 0, 44, 45, 0, 46, 0, 60, 47, 0, 0, 38,
0, 0, 38, 39, 40, 36, 0, 54, 57, 0, 39, 40, 36, 0, 0, 0, 53, 56, 0, 42,
43, 0, 70, 71, 72, 73, 74, 75, 0, 0, 0, 69, 70, 71, 72, 73, 74, 0, 0, 0,
0, 60, 59, 0, 33, 0, 0, 0, 56, 58, 59, 58, 0, 0, 33, 0, 0, 55, 57, 49,
50, 0, 0, 0, 65, 63, 66, 64, 61, 0, 0, 0, 0, 64, 62, 65, 63, 60, 0, 0,
0, 34, 32, 37, 0, 0, 43, 0, 0, 0, 37, 0, 34, 32, 0, 42, 0, 0, 0, 61,
62, 49, 76, 35, 30, 44, 42, 0, 67, 68, 48, 75, 35, 30, 43, 41, 0, 66, 67, 0,
0, 69 68
}; };
/* YYPGOTO[NTERM-NUM]. */ /* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] = static const yytype_int8 yypgoto[] =
{ {
-95, -95, -95, -95, -95, -95, -95, -95, -95, -95, -94, -94, -94, -94, -94, -94, -94, -94, -94, -94,
-95, -95, -95, -95, -95, 17, 45, -95, -95, -95, -94, -94, -94, -94, -94, 17, 41, -94, -94, -94,
-95, -3, -90, -95, -95, -95, -95, -71, 36, -85, -2, -89, -94, -94, -94, -94, -71, 43, -84, 9,
9, 28, -94, -95 28, -93, -94
}; };
/* YYDEFGOTO[NTERM-NUM]. */ /* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] = static const yytype_int16 yydefgoto[] =
{ {
-1, 1, 18, 19, 20, 21, 22, 23, 24, 25, -1, 1, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 101, 82, 144, 105, 83, 26, 27, 28, 29, 30, 104, 82, 141, 102, 31,
31, 132, 95, 32, 33, 34, 42, 61, 89, 78, 131, 94, 32, 33, 34, 42, 61, 88, 78, 120,
121, 96, 118, 35 95, 117, 35
}; };
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
...@@ -748,40 +747,42 @@ static const yytype_int16 yydefgoto[] = ...@@ -748,40 +747,42 @@ static const yytype_int16 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] = static const yytype_uint8 yytable[] =
{ {
110, 119, 86, 87, 109, 2, 43, 44, 122, 3, 109, 118, 85, 86, 108, 2, 43, 44, 121, 3,
4, 45, 59, 59, 5, 6, 7, 8, 9, 10, 4, 45, 59, 59, 5, 6, 7, 8, 9, 10,
11, 60, 85, 47, 12, 13, 14, 46, 135, 137, 11, 60, 84, 47, 12, 13, 14, 46, 134, 136,
15, 16, 48, 111, 91, 92, 128, 139, 94, 148, 15, 16, 36, 110, 37, 127, 48, 138, 54, 147,
17, 146, 49, 50, 112, 113, 114, 115, 116, 117, 17, 145, 49, 50, 111, 112, 113, 114, 115, 116,
112, 113, 114, 115, 116, 117, 51, 52, 158, 91, 111, 112, 113, 114, 115, 116, 51, 52, 157, 90,
92, 93, 54, 94, 91, 92, 134, 53, 94, 91, 91, 92, 53, 93, 90, 91, 133, 55, 93, 90,
92, 136, 63, 94, 91, 92, 157, 40, 94, 55, 91, 135, 62, 93, 90, 91, 156, 56, 93, 90,
41, 102, 103, 104, 36, 38, 37, 39, 56, 57, 91, 63, 40, 93, 57, 41, 99, 100, 101, 38,
58, 62, 64, 65, 66, 67, 69, 68, 71, 70, 58, 39, 64, 65, 66, 67, 69, 68, 71, 70,
72, 73, 74, 75, 76, 77, 80, 90, 59, 79, 72, 73, 74, 75, 76, 77, 80, 79, 59, 81,
88, 97, 81, 84, 98, 99, 100, 106, 107, 108, 87, 96, 83, 98, 89, 97, 105, 103, 106, 107,
120, 123, 125, 126, 130, 142, 143, 127, 131, 133, 119, 122, 123, 129, 125, 126, 143, 130, 132, 144,
140, 145, 151, 147, 152, 153, 149, 154, 156, 159, 139, 140, 148, 146, 150, 151, 152, 153, 155, 158,
160, 141, 161, 155, 129, 124, 0, 150, 138 159, 142, 160, 154, 124, 0, 149, 137, 0, 0,
128
}; };
static const yytype_int16 yycheck[] = static const yytype_int16 yycheck[] =
{ {
90, 95, 73, 74, 89, 0, 46, 7, 98, 4, 89, 94, 73, 74, 88, 0, 46, 7, 97, 4,
5, 3, 18, 18, 9, 10, 11, 12, 13, 14, 5, 3, 18, 18, 9, 10, 11, 12, 13, 14,
15, 27, 27, 30, 19, 20, 21, 28, 118, 119, 15, 27, 27, 30, 19, 20, 21, 28, 117, 118,
25, 26, 46, 27, 44, 45, 107, 122, 48, 133, 25, 26, 6, 27, 8, 106, 46, 121, 36, 132,
35, 131, 3, 3, 38, 39, 40, 41, 42, 43, 35, 130, 3, 3, 38, 39, 40, 41, 42, 43,
38, 39, 40, 41, 42, 43, 3, 3, 148, 44, 38, 39, 40, 41, 42, 43, 3, 3, 147, 44,
45, 46, 36, 48, 44, 45, 46, 3, 48, 44, 45, 46, 3, 48, 44, 45, 46, 46, 48, 44,
45, 46, 3, 48, 44, 45, 46, 46, 48, 46, 45, 46, 30, 48, 44, 45, 46, 46, 48, 44,
49, 22, 23, 24, 6, 6, 8, 8, 46, 46, 45, 3, 46, 48, 46, 49, 22, 23, 24, 6,
46, 30, 3, 46, 46, 33, 16, 37, 3, 34, 46, 8, 3, 46, 46, 33, 16, 37, 3, 34,
3, 46, 46, 46, 29, 31, 48, 16, 18, 46, 3, 46, 46, 46, 29, 31, 48, 46, 18, 46,
18, 3, 46, 46, 38, 28, 18, 16, 46, 46, 18, 3, 46, 28, 16, 38, 16, 18, 46, 46,
32, 6, 17, 16, 3, 3, 44, 46, 18, 46, 32, 6, 16, 3, 17, 46, 3, 18, 46, 17,
46, 17, 3, 17, 3, 17, 27, 3, 3, 46, 46, 44, 27, 17, 3, 3, 17, 3, 3, 46,
27, 124, 46, 146, 108, 100, -1, 138, 120 27, 124, 46, 145, 103, -1, 137, 119, -1, -1,
107
}; };
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
...@@ -791,20 +792,20 @@ static const yytype_int8 yystos[] = ...@@ -791,20 +792,20 @@ static const yytype_int8 yystos[] =
0, 52, 0, 4, 5, 9, 10, 11, 12, 13, 0, 52, 0, 4, 5, 9, 10, 11, 12, 13,
14, 15, 19, 20, 21, 25, 26, 35, 53, 54, 14, 15, 19, 20, 21, 25, 26, 35, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
65, 71, 74, 75, 76, 84, 6, 8, 6, 8, 65, 70, 73, 74, 75, 83, 6, 8, 6, 8,
46, 49, 77, 46, 7, 3, 28, 30, 46, 3, 46, 49, 76, 46, 7, 3, 28, 30, 46, 3,
3, 3, 3, 3, 36, 46, 46, 46, 46, 18, 3, 3, 3, 3, 36, 46, 46, 46, 46, 18,
27, 78, 30, 3, 3, 46, 46, 33, 37, 16, 27, 77, 30, 3, 3, 46, 46, 33, 37, 16,
34, 3, 3, 46, 46, 46, 29, 31, 80, 46, 34, 3, 3, 46, 46, 46, 29, 31, 79, 46,
48, 46, 67, 70, 46, 27, 78, 78, 18, 79, 48, 46, 67, 46, 27, 77, 77, 18, 78, 16,
16, 44, 45, 46, 48, 73, 82, 3, 38, 28, 44, 45, 46, 48, 72, 81, 3, 38, 28, 22,
18, 66, 22, 23, 24, 69, 16, 46, 46, 80, 23, 24, 69, 18, 66, 16, 46, 46, 79, 72,
73, 27, 38, 39, 40, 41, 42, 43, 83, 83, 27, 38, 39, 40, 41, 42, 43, 82, 82, 32,
32, 81, 73, 6, 67, 17, 16, 46, 78, 79, 80, 72, 6, 16, 67, 17, 46, 77, 78, 3,
3, 18, 72, 46, 46, 73, 46, 73, 82, 80, 18, 71, 46, 46, 72, 46, 72, 81, 79, 46,
46, 66, 3, 44, 68, 17, 73, 17, 83, 27, 44, 68, 66, 3, 17, 72, 17, 82, 27, 80,
81, 3, 3, 17, 3, 72, 3, 46, 73, 46, 3, 3, 17, 3, 71, 3, 46, 72, 46, 27,
27, 46 46
}; };
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
...@@ -814,10 +815,10 @@ static const yytype_int8 yyr1[] = ...@@ -814,10 +815,10 @@ static const yytype_int8 yyr1[] =
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
63, 64, 65, 66, 66, 67, 67, 68, 69, 69, 63, 64, 65, 66, 66, 67, 67, 68, 69, 69,
69, 70, 71, 72, 72, 73, 73, 73, 74, 75, 69, 70, 71, 71, 72, 72, 72, 73, 74, 75,
76, 77, 77, 77, 78, 78, 78, 79, 79, 80, 76, 76, 76, 77, 77, 77, 78, 78, 79, 79,
80, 81, 81, 82, 82, 82, 82, 82, 82, 82, 80, 80, 81, 81, 81, 81, 81, 81, 81, 82,
83, 83, 83, 83, 83, 83, 84 82, 82, 82, 82, 82, 83
}; };
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
...@@ -827,10 +828,10 @@ static const yytype_int8 yyr2[] = ...@@ -827,10 +828,10 @@ static const yytype_int8 yyr2[] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 2, 2, 2, 2, 2, 4, 3, 3, 1, 2, 2, 2, 2, 2, 2, 4, 3, 3,
9, 4, 8, 0, 3, 5, 2, 1, 1, 1, 9, 4, 8, 0, 3, 5, 2, 1, 1, 1,
1, 1, 9, 0, 3, 1, 1, 1, 5, 8, 1, 9, 0, 3, 1, 1, 1, 5, 8, 7,
7, 1, 2, 4, 0, 3, 5, 0, 3, 0, 1, 2, 4, 0, 3, 5, 0, 3, 0, 3,
3, 0, 3, 3, 3, 3, 3, 5, 5, 7, 0, 3, 3, 3, 3, 3, 5, 5, 7, 1,
1, 1, 1, 1, 1, 1, 8 1, 1, 1, 1, 1, 8
}; };
...@@ -1310,7 +1311,7 @@ yyreduce: ...@@ -1310,7 +1311,7 @@ yyreduce:
{ {
CONTEXT->ssql->flag=SCF_EXIT;//"exit"; CONTEXT->ssql->flag=SCF_EXIT;//"exit";
} }
#line 1314 "yacc_sql.cpp" #line 1315 "yacc_sql.cpp"
break; break;
case 22: /* help: HELP SEMICOLON */ case 22: /* help: HELP SEMICOLON */
...@@ -1318,7 +1319,7 @@ yyreduce: ...@@ -1318,7 +1319,7 @@ yyreduce:
{ {
CONTEXT->ssql->flag=SCF_HELP;//"help"; CONTEXT->ssql->flag=SCF_HELP;//"help";
} }
#line 1322 "yacc_sql.cpp" #line 1323 "yacc_sql.cpp"
break; break;
case 23: /* sync: SYNC SEMICOLON */ case 23: /* sync: SYNC SEMICOLON */
...@@ -1326,7 +1327,7 @@ yyreduce: ...@@ -1326,7 +1327,7 @@ yyreduce:
{ {
CONTEXT->ssql->flag = SCF_SYNC; CONTEXT->ssql->flag = SCF_SYNC;
} }
#line 1330 "yacc_sql.cpp" #line 1331 "yacc_sql.cpp"
break; break;
case 24: /* begin: TRX_BEGIN SEMICOLON */ case 24: /* begin: TRX_BEGIN SEMICOLON */
...@@ -1334,7 +1335,7 @@ yyreduce: ...@@ -1334,7 +1335,7 @@ yyreduce:
{ {
CONTEXT->ssql->flag = SCF_BEGIN; CONTEXT->ssql->flag = SCF_BEGIN;
} }
#line 1338 "yacc_sql.cpp" #line 1339 "yacc_sql.cpp"
break; break;
case 25: /* commit: TRX_COMMIT SEMICOLON */ case 25: /* commit: TRX_COMMIT SEMICOLON */
...@@ -1342,7 +1343,7 @@ yyreduce: ...@@ -1342,7 +1343,7 @@ yyreduce:
{ {
CONTEXT->ssql->flag = SCF_COMMIT; CONTEXT->ssql->flag = SCF_COMMIT;
} }
#line 1346 "yacc_sql.cpp" #line 1347 "yacc_sql.cpp"
break; break;
case 26: /* rollback: TRX_ROLLBACK SEMICOLON */ case 26: /* rollback: TRX_ROLLBACK SEMICOLON */
...@@ -1350,7 +1351,7 @@ yyreduce: ...@@ -1350,7 +1351,7 @@ yyreduce:
{ {
CONTEXT->ssql->flag = SCF_ROLLBACK; CONTEXT->ssql->flag = SCF_ROLLBACK;
} }
#line 1354 "yacc_sql.cpp" #line 1355 "yacc_sql.cpp"
break; break;
case 27: /* drop_table: DROP TABLE ID SEMICOLON */ case 27: /* drop_table: DROP TABLE ID SEMICOLON */
...@@ -1359,7 +1360,7 @@ yyreduce: ...@@ -1359,7 +1360,7 @@ yyreduce:
CONTEXT->ssql->flag = SCF_DROP_TABLE;//"drop_table"; CONTEXT->ssql->flag = SCF_DROP_TABLE;//"drop_table";
drop_table_init(&CONTEXT->ssql->sstr.drop_table, (yyvsp[-1].string)); drop_table_init(&CONTEXT->ssql->sstr.drop_table, (yyvsp[-1].string));
} }
#line 1363 "yacc_sql.cpp" #line 1364 "yacc_sql.cpp"
break; break;
case 28: /* show_tables: SHOW TABLES SEMICOLON */ case 28: /* show_tables: SHOW TABLES SEMICOLON */
...@@ -1367,7 +1368,7 @@ yyreduce: ...@@ -1367,7 +1368,7 @@ yyreduce:
{ {
CONTEXT->ssql->flag = SCF_SHOW_TABLES; CONTEXT->ssql->flag = SCF_SHOW_TABLES;
} }
#line 1371 "yacc_sql.cpp" #line 1372 "yacc_sql.cpp"
break; break;
case 29: /* desc_table: DESC ID SEMICOLON */ case 29: /* desc_table: DESC ID SEMICOLON */
...@@ -1376,7 +1377,7 @@ yyreduce: ...@@ -1376,7 +1377,7 @@ yyreduce:
CONTEXT->ssql->flag = SCF_DESC_TABLE; CONTEXT->ssql->flag = SCF_DESC_TABLE;
desc_table_init(&CONTEXT->ssql->sstr.desc_table, (yyvsp[-1].string)); desc_table_init(&CONTEXT->ssql->sstr.desc_table, (yyvsp[-1].string));
} }
#line 1380 "yacc_sql.cpp" #line 1381 "yacc_sql.cpp"
break; break;
case 30: /* create_index: CREATE INDEX ID ON ID LBRACE ID RBRACE SEMICOLON */ case 30: /* create_index: CREATE INDEX ID ON ID LBRACE ID RBRACE SEMICOLON */
...@@ -1385,7 +1386,7 @@ yyreduce: ...@@ -1385,7 +1386,7 @@ yyreduce:
CONTEXT->ssql->flag = SCF_CREATE_INDEX;//"create_index"; CONTEXT->ssql->flag = SCF_CREATE_INDEX;//"create_index";
create_index_init(&CONTEXT->ssql->sstr.create_index, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string)); create_index_init(&CONTEXT->ssql->sstr.create_index, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
} }
#line 1389 "yacc_sql.cpp" #line 1390 "yacc_sql.cpp"
break; break;
case 31: /* drop_index: DROP INDEX ID SEMICOLON */ case 31: /* drop_index: DROP INDEX ID SEMICOLON */
...@@ -1394,7 +1395,7 @@ yyreduce: ...@@ -1394,7 +1395,7 @@ yyreduce:
CONTEXT->ssql->flag=SCF_DROP_INDEX;//"drop_index"; CONTEXT->ssql->flag=SCF_DROP_INDEX;//"drop_index";
drop_index_init(&CONTEXT->ssql->sstr.drop_index, (yyvsp[-1].string)); drop_index_init(&CONTEXT->ssql->sstr.drop_index, (yyvsp[-1].string));
} }
#line 1398 "yacc_sql.cpp" #line 1399 "yacc_sql.cpp"
break; break;
case 32: /* create_table: CREATE TABLE ID LBRACE attr_def attr_def_list RBRACE SEMICOLON */ case 32: /* create_table: CREATE TABLE ID LBRACE attr_def attr_def_list RBRACE SEMICOLON */
...@@ -1405,72 +1406,63 @@ yyreduce: ...@@ -1405,72 +1406,63 @@ yyreduce:
//临时变量清零 //临时变量清零
CONTEXT->value_length = 0; CONTEXT->value_length = 0;
} }
#line 1409 "yacc_sql.cpp" #line 1410 "yacc_sql.cpp"
break; break;
case 34: /* attr_def_list: COMMA attr_def attr_def_list */ case 34: /* attr_def_list: COMMA attr_def attr_def_list */
#line 236 "yacc_sql.y" #line 236 "yacc_sql.y"
{ } { }
#line 1415 "yacc_sql.cpp" #line 1416 "yacc_sql.cpp"
break; break;
case 35: /* attr_def: ID_get type LBRACE number RBRACE */ case 35: /* attr_def: ID type LBRACE number RBRACE */
#line 241 "yacc_sql.y" #line 241 "yacc_sql.y"
{ {
AttrInfo attribute; AttrInfo attribute;
attr_info_init(&attribute, CONTEXT->id, (AttrType)(yyvsp[-3].number), (yyvsp[-1].number)); attr_info_init(&attribute, (yyvsp[-4].string), (AttrType)(yyvsp[-3].number), (yyvsp[-1].number));
create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute); create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute);
CONTEXT->value_length++; CONTEXT->value_length++;
} }
#line 1426 "yacc_sql.cpp" #line 1427 "yacc_sql.cpp"
break; break;
case 36: /* attr_def: ID_get type */ case 36: /* attr_def: ID type */
#line 248 "yacc_sql.y" #line 248 "yacc_sql.y"
{ {
AttrInfo attribute; AttrInfo attribute;
attr_info_init(&attribute, CONTEXT->id, (AttrType)(yyvsp[0].number), 4); attr_info_init(&attribute, (yyvsp[-1].string), (AttrType)(yyvsp[0].number), 4);
create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute); create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute);
CONTEXT->value_length++; CONTEXT->value_length++;
} }
#line 1437 "yacc_sql.cpp" #line 1438 "yacc_sql.cpp"
break; break;
case 37: /* number: NUMBER */ case 37: /* number: NUMBER */
#line 256 "yacc_sql.y" #line 256 "yacc_sql.y"
{(yyval.number) = (yyvsp[0].number);} {(yyval.number) = (yyvsp[0].number);}
#line 1443 "yacc_sql.cpp" #line 1444 "yacc_sql.cpp"
break; break;
case 38: /* type: INT_T */ case 38: /* type: INT_T */
#line 259 "yacc_sql.y" #line 259 "yacc_sql.y"
{ (yyval.number)=INTS; } { (yyval.number)=INTS; }
#line 1449 "yacc_sql.cpp" #line 1450 "yacc_sql.cpp"
break; break;
case 39: /* type: STRING_T */ case 39: /* type: STRING_T */
#line 260 "yacc_sql.y" #line 260 "yacc_sql.y"
{ (yyval.number)=CHARS; } { (yyval.number)=CHARS; }
#line 1455 "yacc_sql.cpp" #line 1456 "yacc_sql.cpp"
break; break;
case 40: /* type: FLOAT_T */ case 40: /* type: FLOAT_T */
#line 261 "yacc_sql.y" #line 261 "yacc_sql.y"
{ (yyval.number)=FLOATS; } { (yyval.number)=FLOATS; }
#line 1461 "yacc_sql.cpp" #line 1462 "yacc_sql.cpp"
break; break;
case 41: /* ID_get: ID */ case 41: /* insert: INSERT INTO ID VALUES LBRACE value value_list RBRACE SEMICOLON */
#line 265 "yacc_sql.y" #line 265 "yacc_sql.y"
{
char *temp=(yyvsp[0].string);
snprintf(CONTEXT->id, sizeof(CONTEXT->id), "%s", temp);
}
#line 1470 "yacc_sql.cpp"
break;
case 42: /* insert: INSERT INTO ID VALUES LBRACE value value_list RBRACE SEMICOLON */
#line 274 "yacc_sql.y"
{ {
CONTEXT->ssql->flag=SCF_INSERT;//"insert"; CONTEXT->ssql->flag=SCF_INSERT;//"insert";
inserts_init(&CONTEXT->ssql->sstr.insertion, (yyvsp[-6].string), CONTEXT->values, CONTEXT->value_length); inserts_init(&CONTEXT->ssql->sstr.insertion, (yyvsp[-6].string), CONTEXT->values, CONTEXT->value_length);
...@@ -1478,44 +1470,45 @@ yyreduce: ...@@ -1478,44 +1470,45 @@ yyreduce:
//临时变量清零 //临时变量清零
CONTEXT->value_length=0; CONTEXT->value_length=0;
} }
#line 1482 "yacc_sql.cpp" #line 1474 "yacc_sql.cpp"
break; break;
case 44: /* value_list: COMMA value value_list */ case 43: /* value_list: COMMA value value_list */
#line 284 "yacc_sql.y" #line 275 "yacc_sql.y"
{ {
// CONTEXT->values[CONTEXT->value_length++] = *$2; // CONTEXT->values[CONTEXT->value_length++] = *$2;
} }
#line 1490 "yacc_sql.cpp" #line 1482 "yacc_sql.cpp"
break; break;
case 45: /* value: NUMBER */ case 44: /* value: NUMBER */
#line 289 "yacc_sql.y" #line 280 "yacc_sql.y"
{ {
value_init_integer(&CONTEXT->values[CONTEXT->value_length++], (yyvsp[0].number)); value_init_integer(&CONTEXT->values[CONTEXT->value_length++], (yyvsp[0].number));
} }
#line 1498 "yacc_sql.cpp" #line 1490 "yacc_sql.cpp"
break; break;
case 46: /* value: FLOAT */ case 45: /* value: FLOAT */
#line 292 "yacc_sql.y" #line 283 "yacc_sql.y"
{ {
value_init_float(&CONTEXT->values[CONTEXT->value_length++], (yyvsp[0].floats)); value_init_float(&CONTEXT->values[CONTEXT->value_length++], (yyvsp[0].floats));
} }
#line 1506 "yacc_sql.cpp" #line 1498 "yacc_sql.cpp"
break; break;
case 47: /* value: SSS */ case 46: /* value: SSS */
#line 295 "yacc_sql.y" #line 286 "yacc_sql.y"
{ {
(yyvsp[0].string) = substr((yyvsp[0].string),1,strlen((yyvsp[0].string))-2); char *tmp = substr((yyvsp[0].string),1,strlen((yyvsp[0].string))-2);
value_init_string(&CONTEXT->values[CONTEXT->value_length++], (yyvsp[0].string)); value_init_string(&CONTEXT->values[CONTEXT->value_length++], tmp);
free((yyvsp[0].string));
} }
#line 1515 "yacc_sql.cpp" #line 1508 "yacc_sql.cpp"
break; break;
case 48: /* delete: DELETE FROM ID where SEMICOLON */ case 47: /* delete: DELETE FROM ID where SEMICOLON */
#line 303 "yacc_sql.y" #line 295 "yacc_sql.y"
{ {
CONTEXT->ssql->flag = SCF_DELETE;//"delete"; CONTEXT->ssql->flag = SCF_DELETE;//"delete";
deletes_init_relation(&CONTEXT->ssql->sstr.deletion, (yyvsp[-2].string)); deletes_init_relation(&CONTEXT->ssql->sstr.deletion, (yyvsp[-2].string));
...@@ -1523,11 +1516,11 @@ yyreduce: ...@@ -1523,11 +1516,11 @@ yyreduce:
CONTEXT->conditions, CONTEXT->condition_length); CONTEXT->conditions, CONTEXT->condition_length);
CONTEXT->condition_length = 0; CONTEXT->condition_length = 0;
} }
#line 1527 "yacc_sql.cpp" #line 1520 "yacc_sql.cpp"
break; break;
case 49: /* update: UPDATE ID SET ID EQ value where SEMICOLON */ case 48: /* update: UPDATE ID SET ID EQ value where SEMICOLON */
#line 313 "yacc_sql.y" #line 305 "yacc_sql.y"
{ {
CONTEXT->ssql->flag = SCF_UPDATE;//"update"; CONTEXT->ssql->flag = SCF_UPDATE;//"update";
Value *value = &CONTEXT->values[0]; Value *value = &CONTEXT->values[0];
...@@ -1535,11 +1528,11 @@ yyreduce: ...@@ -1535,11 +1528,11 @@ yyreduce:
CONTEXT->conditions, CONTEXT->condition_length); CONTEXT->conditions, CONTEXT->condition_length);
CONTEXT->condition_length = 0; CONTEXT->condition_length = 0;
} }
#line 1539 "yacc_sql.cpp" #line 1532 "yacc_sql.cpp"
break; break;
case 50: /* select: SELECT select_attr FROM ID rel_list where SEMICOLON */ case 49: /* select: SELECT select_attr FROM ID rel_list where SEMICOLON */
#line 323 "yacc_sql.y" #line 315 "yacc_sql.y"
{ {
selects_append_relation(&CONTEXT->ssql->sstr.selection, (yyvsp[-3].string)); selects_append_relation(&CONTEXT->ssql->sstr.selection, (yyvsp[-3].string));
...@@ -1553,85 +1546,85 @@ yyreduce: ...@@ -1553,85 +1546,85 @@ yyreduce:
CONTEXT->select_length=0; CONTEXT->select_length=0;
CONTEXT->value_length = 0; CONTEXT->value_length = 0;
} }
#line 1557 "yacc_sql.cpp" #line 1550 "yacc_sql.cpp"
break; break;
case 51: /* select_attr: STAR */ case 50: /* select_attr: STAR */
#line 339 "yacc_sql.y" #line 331 "yacc_sql.y"
{ {
RelAttr attr; RelAttr attr;
relation_attr_init(&attr, NULL, "*"); relation_attr_init(&attr, NULL, strdup("*"));
selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr); selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
} }
#line 1567 "yacc_sql.cpp" #line 1560 "yacc_sql.cpp"
break; break;
case 52: /* select_attr: ID attr_list */ case 51: /* select_attr: ID attr_list */
#line 344 "yacc_sql.y" #line 336 "yacc_sql.y"
{ {
RelAttr attr; RelAttr attr;
relation_attr_init(&attr, NULL, (yyvsp[-1].string)); relation_attr_init(&attr, NULL, (yyvsp[-1].string));
selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr); selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
} }
#line 1577 "yacc_sql.cpp" #line 1570 "yacc_sql.cpp"
break; break;
case 53: /* select_attr: ID DOT ID attr_list */ case 52: /* select_attr: ID DOT ID attr_list */
#line 349 "yacc_sql.y" #line 341 "yacc_sql.y"
{ {
RelAttr attr; RelAttr attr;
relation_attr_init(&attr, (yyvsp[-3].string), (yyvsp[-1].string)); relation_attr_init(&attr, (yyvsp[-3].string), (yyvsp[-1].string));
selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr); selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
} }
#line 1587 "yacc_sql.cpp" #line 1580 "yacc_sql.cpp"
break; break;
case 55: /* attr_list: COMMA ID attr_list */ case 54: /* attr_list: COMMA ID attr_list */
#line 357 "yacc_sql.y" #line 349 "yacc_sql.y"
{ {
RelAttr attr; RelAttr attr;
relation_attr_init(&attr, NULL, (yyvsp[-1].string)); relation_attr_init(&attr, NULL, (yyvsp[-1].string));
selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr); selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
} }
#line 1597 "yacc_sql.cpp" #line 1590 "yacc_sql.cpp"
break; break;
case 56: /* attr_list: COMMA ID DOT ID attr_list */ case 55: /* attr_list: COMMA ID DOT ID attr_list */
#line 362 "yacc_sql.y" #line 354 "yacc_sql.y"
{ {
RelAttr attr; RelAttr attr;
relation_attr_init(&attr, (yyvsp[-3].string), (yyvsp[-1].string)); relation_attr_init(&attr, (yyvsp[-3].string), (yyvsp[-1].string));
selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr); selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
} }
#line 1607 "yacc_sql.cpp" #line 1600 "yacc_sql.cpp"
break; break;
case 58: /* rel_list: COMMA ID rel_list */ case 57: /* rel_list: COMMA ID rel_list */
#line 371 "yacc_sql.y" #line 363 "yacc_sql.y"
{ {
selects_append_relation(&CONTEXT->ssql->sstr.selection, (yyvsp[-1].string)); selects_append_relation(&CONTEXT->ssql->sstr.selection, (yyvsp[-1].string));
} }
#line 1615 "yacc_sql.cpp" #line 1608 "yacc_sql.cpp"
break; break;
case 60: /* where: WHERE condition condition_list */ case 59: /* where: WHERE condition condition_list */
#line 377 "yacc_sql.y" #line 369 "yacc_sql.y"
{ {
// CONTEXT->conditions[CONTEXT->condition_length++]=*$2; // CONTEXT->conditions[CONTEXT->condition_length++]=*$2;
} }
#line 1623 "yacc_sql.cpp" #line 1616 "yacc_sql.cpp"
break; break;
case 62: /* condition_list: AND condition condition_list */ case 61: /* condition_list: AND condition condition_list */
#line 383 "yacc_sql.y" #line 375 "yacc_sql.y"
{ {
// CONTEXT->conditions[CONTEXT->condition_length++]=*$2; // CONTEXT->conditions[CONTEXT->condition_length++]=*$2;
} }
#line 1631 "yacc_sql.cpp" #line 1624 "yacc_sql.cpp"
break; break;
case 63: /* condition: ID comOp value */ case 62: /* condition: ID comOp value */
#line 389 "yacc_sql.y" #line 381 "yacc_sql.y"
{ {
RelAttr left_attr; RelAttr left_attr;
relation_attr_init(&left_attr, NULL, (yyvsp[-2].string)); relation_attr_init(&left_attr, NULL, (yyvsp[-2].string));
...@@ -1642,11 +1635,11 @@ yyreduce: ...@@ -1642,11 +1635,11 @@ yyreduce:
condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 0, NULL, right_value); condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 0, NULL, right_value);
CONTEXT->conditions[CONTEXT->condition_length++] = condition; CONTEXT->conditions[CONTEXT->condition_length++] = condition;
} }
#line 1646 "yacc_sql.cpp" #line 1639 "yacc_sql.cpp"
break; break;
case 64: /* condition: value comOp value */ case 63: /* condition: value comOp value */
#line 400 "yacc_sql.y" #line 392 "yacc_sql.y"
{ {
Value *left_value = &CONTEXT->values[CONTEXT->value_length - 2]; Value *left_value = &CONTEXT->values[CONTEXT->value_length - 2];
Value *right_value = &CONTEXT->values[CONTEXT->value_length - 1]; Value *right_value = &CONTEXT->values[CONTEXT->value_length - 1];
...@@ -1655,11 +1648,11 @@ yyreduce: ...@@ -1655,11 +1648,11 @@ yyreduce:
condition_init(&condition, CONTEXT->comp, 0, NULL, left_value, 0, NULL, right_value); condition_init(&condition, CONTEXT->comp, 0, NULL, left_value, 0, NULL, right_value);
CONTEXT->conditions[CONTEXT->condition_length++] = condition; CONTEXT->conditions[CONTEXT->condition_length++] = condition;
} }
#line 1659 "yacc_sql.cpp" #line 1652 "yacc_sql.cpp"
break; break;
case 65: /* condition: ID comOp ID */ case 64: /* condition: ID comOp ID */
#line 409 "yacc_sql.y" #line 401 "yacc_sql.y"
{ {
RelAttr left_attr; RelAttr left_attr;
relation_attr_init(&left_attr, NULL, (yyvsp[-2].string)); relation_attr_init(&left_attr, NULL, (yyvsp[-2].string));
...@@ -1670,11 +1663,11 @@ yyreduce: ...@@ -1670,11 +1663,11 @@ yyreduce:
condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 1, &right_attr, NULL); condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 1, &right_attr, NULL);
CONTEXT->conditions[CONTEXT->condition_length++] = condition; CONTEXT->conditions[CONTEXT->condition_length++] = condition;
} }
#line 1674 "yacc_sql.cpp" #line 1667 "yacc_sql.cpp"
break; break;
case 66: /* condition: value comOp ID */ case 65: /* condition: value comOp ID */
#line 420 "yacc_sql.y" #line 412 "yacc_sql.y"
{ {
Value *left_value = &CONTEXT->values[CONTEXT->value_length - 1]; Value *left_value = &CONTEXT->values[CONTEXT->value_length - 1];
RelAttr right_attr; RelAttr right_attr;
...@@ -1684,11 +1677,11 @@ yyreduce: ...@@ -1684,11 +1677,11 @@ yyreduce:
condition_init(&condition, CONTEXT->comp, 0, NULL, left_value, 1, &right_attr, NULL); condition_init(&condition, CONTEXT->comp, 0, NULL, left_value, 1, &right_attr, NULL);
CONTEXT->conditions[CONTEXT->condition_length++] = condition; CONTEXT->conditions[CONTEXT->condition_length++] = condition;
} }
#line 1688 "yacc_sql.cpp" #line 1681 "yacc_sql.cpp"
break; break;
case 67: /* condition: ID DOT ID comOp value */ case 66: /* condition: ID DOT ID comOp value */
#line 430 "yacc_sql.y" #line 422 "yacc_sql.y"
{ {
RelAttr left_attr; RelAttr left_attr;
relation_attr_init(&left_attr, (yyvsp[-4].string), (yyvsp[-2].string)); relation_attr_init(&left_attr, (yyvsp[-4].string), (yyvsp[-2].string));
...@@ -1698,11 +1691,11 @@ yyreduce: ...@@ -1698,11 +1691,11 @@ yyreduce:
condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 0, NULL, right_value); condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 0, NULL, right_value);
CONTEXT->conditions[CONTEXT->condition_length++] = condition; CONTEXT->conditions[CONTEXT->condition_length++] = condition;
} }
#line 1702 "yacc_sql.cpp" #line 1695 "yacc_sql.cpp"
break; break;
case 68: /* condition: value comOp ID DOT ID */ case 67: /* condition: value comOp ID DOT ID */
#line 440 "yacc_sql.y" #line 432 "yacc_sql.y"
{ {
Value *left_value = &CONTEXT->values[CONTEXT->value_length - 1]; Value *left_value = &CONTEXT->values[CONTEXT->value_length - 1];
...@@ -1713,11 +1706,11 @@ yyreduce: ...@@ -1713,11 +1706,11 @@ yyreduce:
condition_init(&condition, CONTEXT->comp, 0, NULL, left_value, 1, &right_attr, NULL); condition_init(&condition, CONTEXT->comp, 0, NULL, left_value, 1, &right_attr, NULL);
CONTEXT->conditions[CONTEXT->condition_length++] = condition; CONTEXT->conditions[CONTEXT->condition_length++] = condition;
} }
#line 1717 "yacc_sql.cpp" #line 1710 "yacc_sql.cpp"
break; break;
case 69: /* condition: ID DOT ID comOp ID DOT ID */ case 68: /* condition: ID DOT ID comOp ID DOT ID */
#line 451 "yacc_sql.y" #line 443 "yacc_sql.y"
{ {
RelAttr left_attr; RelAttr left_attr;
relation_attr_init(&left_attr, (yyvsp[-6].string), (yyvsp[-4].string)); relation_attr_init(&left_attr, (yyvsp[-6].string), (yyvsp[-4].string));
...@@ -1728,56 +1721,56 @@ yyreduce: ...@@ -1728,56 +1721,56 @@ yyreduce:
condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 1, &right_attr, NULL); condition_init(&condition, CONTEXT->comp, 1, &left_attr, NULL, 1, &right_attr, NULL);
CONTEXT->conditions[CONTEXT->condition_length++] = condition; CONTEXT->conditions[CONTEXT->condition_length++] = condition;
} }
#line 1732 "yacc_sql.cpp" #line 1725 "yacc_sql.cpp"
break; break;
case 70: /* comOp: EQ */ case 69: /* comOp: EQ */
#line 464 "yacc_sql.y" #line 456 "yacc_sql.y"
{ CONTEXT->comp = EQUAL_TO; } { CONTEXT->comp = EQUAL_TO; }
#line 1738 "yacc_sql.cpp" #line 1731 "yacc_sql.cpp"
break; break;
case 71: /* comOp: LT */ case 70: /* comOp: LT */
#line 465 "yacc_sql.y" #line 457 "yacc_sql.y"
{ CONTEXT->comp = LESS_THAN; } { CONTEXT->comp = LESS_THAN; }
#line 1744 "yacc_sql.cpp" #line 1737 "yacc_sql.cpp"
break; break;
case 72: /* comOp: GT */ case 71: /* comOp: GT */
#line 466 "yacc_sql.y" #line 458 "yacc_sql.y"
{ CONTEXT->comp = GREAT_THAN; } { CONTEXT->comp = GREAT_THAN; }
#line 1750 "yacc_sql.cpp" #line 1743 "yacc_sql.cpp"
break; break;
case 73: /* comOp: LE */ case 72: /* comOp: LE */
#line 467 "yacc_sql.y" #line 459 "yacc_sql.y"
{ CONTEXT->comp = LESS_EQUAL; } { CONTEXT->comp = LESS_EQUAL; }
#line 1756 "yacc_sql.cpp" #line 1749 "yacc_sql.cpp"
break; break;
case 74: /* comOp: GE */ case 73: /* comOp: GE */
#line 468 "yacc_sql.y" #line 460 "yacc_sql.y"
{ CONTEXT->comp = GREAT_EQUAL; } { CONTEXT->comp = GREAT_EQUAL; }
#line 1762 "yacc_sql.cpp" #line 1755 "yacc_sql.cpp"
break; break;
case 75: /* comOp: NE */ case 74: /* comOp: NE */
#line 469 "yacc_sql.y" #line 461 "yacc_sql.y"
{ CONTEXT->comp = NOT_EQUAL; } { CONTEXT->comp = NOT_EQUAL; }
#line 1768 "yacc_sql.cpp" #line 1761 "yacc_sql.cpp"
break; break;
case 76: /* load_data: LOAD DATA INFILE SSS INTO TABLE ID SEMICOLON */ case 75: /* load_data: LOAD DATA INFILE SSS INTO TABLE ID SEMICOLON */
#line 474 "yacc_sql.y" #line 466 "yacc_sql.y"
{ {
CONTEXT->ssql->flag = SCF_LOAD_DATA; CONTEXT->ssql->flag = SCF_LOAD_DATA;
load_data_init(&CONTEXT->ssql->sstr.load_data, (yyvsp[-1].string), (yyvsp[-4].string)); load_data_init(&CONTEXT->ssql->sstr.load_data, (yyvsp[-1].string), (yyvsp[-4].string));
} }
#line 1777 "yacc_sql.cpp" #line 1770 "yacc_sql.cpp"
break; break;
#line 1781 "yacc_sql.cpp" #line 1774 "yacc_sql.cpp"
default: break; default: break;
} }
...@@ -1971,7 +1964,7 @@ yyreturn: ...@@ -1971,7 +1964,7 @@ yyreturn:
return yyresult; return yyresult;
} }
#line 479 "yacc_sql.y" #line 471 "yacc_sql.y"
//_____________________________________________________________________ //_____________________________________________________________________
extern void scan_string(const char *str, yyscan_t scanner); extern void scan_string(const char *str, yyscan_t scanner);
......
...@@ -237,17 +237,17 @@ attr_def_list: ...@@ -237,17 +237,17 @@ attr_def_list:
; ;
attr_def: attr_def:
ID_get type LBRACE number RBRACE ID type LBRACE number RBRACE
{ {
AttrInfo attribute; AttrInfo attribute;
attr_info_init(&attribute, CONTEXT->id, (AttrType)$2, $4); attr_info_init(&attribute, $1, (AttrType)$2, $4);
create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute); create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute);
CONTEXT->value_length++; CONTEXT->value_length++;
} }
|ID_get type |ID type
{ {
AttrInfo attribute; AttrInfo attribute;
attr_info_init(&attribute, CONTEXT->id, (AttrType)$2, 4); attr_info_init(&attribute, $1, (AttrType)$2, 4);
create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute); create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute);
CONTEXT->value_length++; CONTEXT->value_length++;
} }
...@@ -260,15 +260,6 @@ type: ...@@ -260,15 +260,6 @@ type:
| STRING_T { $$=CHARS; } | STRING_T { $$=CHARS; }
| FLOAT_T { $$=FLOATS; } | FLOAT_T { $$=FLOATS; }
; ;
ID_get:
ID
{
char *temp=$1;
snprintf(CONTEXT->id, sizeof(CONTEXT->id), "%s", temp);
}
;
insert: /*insert 语句的语法解析树*/ insert: /*insert 语句的语法解析树*/
INSERT INTO ID VALUES LBRACE value value_list RBRACE SEMICOLON INSERT INTO ID VALUES LBRACE value value_list RBRACE SEMICOLON
{ {
...@@ -293,8 +284,9 @@ value: ...@@ -293,8 +284,9 @@ value:
value_init_float(&CONTEXT->values[CONTEXT->value_length++], $1); value_init_float(&CONTEXT->values[CONTEXT->value_length++], $1);
} }
|SSS { |SSS {
$1 = substr($1,1,strlen($1)-2); char *tmp = substr($1,1,strlen($1)-2);
value_init_string(&CONTEXT->values[CONTEXT->value_length++], $1); value_init_string(&CONTEXT->values[CONTEXT->value_length++], tmp);
free($1);
} }
; ;
...@@ -338,7 +330,7 @@ select: /* select 语句的语法解析树*/ ...@@ -338,7 +330,7 @@ select: /* select 语句的语法解析树*/
select_attr: select_attr:
STAR { STAR {
RelAttr attr; RelAttr attr;
relation_attr_init(&attr, NULL, "*"); relation_attr_init(&attr, NULL, strdup("*"));
selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr); selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
} }
| ID attr_list { | ID attr_list {
......
...@@ -15,6 +15,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -15,6 +15,7 @@ See the Mulan PSL v2 for more details. */
#include <common/lang/string.h> #include <common/lang/string.h>
#include "storage/common/field_meta.h" #include "storage/common/field_meta.h"
#include "common/log/log.h" #include "common/log/log.h"
#include "sql/parser/parse_defs.h"
#include "json/json.h" #include "json/json.h"
...@@ -24,25 +25,6 @@ const static Json::StaticString FIELD_OFFSET("offset"); ...@@ -24,25 +25,6 @@ const static Json::StaticString FIELD_OFFSET("offset");
const static Json::StaticString FIELD_LEN("len"); const static Json::StaticString FIELD_LEN("len");
const static Json::StaticString FIELD_VISIBLE("visible"); const static Json::StaticString FIELD_VISIBLE("visible");
const char *ATTR_TYPE_NAME[] = {"undefined", "chars", "ints", "floats"};
const char *attr_type_to_string(AttrType type)
{
if (type >= UNDEFINED && type <= FLOATS) {
return ATTR_TYPE_NAME[type];
}
return "unknown";
}
AttrType attr_type_from_string(const char *s)
{
for (unsigned int i = 0; i < sizeof(ATTR_TYPE_NAME) / sizeof(ATTR_TYPE_NAME[0]); i++) {
if (0 == strcmp(ATTR_TYPE_NAME[i], s)) {
return (AttrType)i;
}
}
return UNDEFINED;
}
FieldMeta::FieldMeta() : attr_type_(AttrType::UNDEFINED), attr_offset_(-1), attr_len_(0), visible_(false) FieldMeta::FieldMeta() : attr_type_(AttrType::UNDEFINED), attr_offset_(-1), attr_len_(0), visible_(false)
{} {}
......
...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */
// Created by Meiyi & Wangyunlai on 2021/5/12. // Created by Meiyi & Wangyunlai on 2021/5/12.
// //
#ifndef __OBSERVER_STORAGE_COMMON_FIELD_META_H__ #pragma once
#define __OBSERVER_STORAGE_COMMON_FIELD_META_H__
#include <string> #include <string>
...@@ -53,4 +52,3 @@ protected: ...@@ -53,4 +52,3 @@ protected:
int attr_len_; int attr_len_;
bool visible_; bool visible_;
}; };
#endif // __OBSERVER_STORAGE_COMMON_FIELD_META_H__
\ No newline at end of file
...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */
// Created by Meiyi & Wangyunlai on 2021/5/12. // Created by Meiyi & Wangyunlai on 2021/5/12.
// //
#ifndef __OBSERVER_STORAGE_COMMON_TABLE_H__ #pragma once
#define __OBSERVER_STORAGE_COMMON_TABLE_H__
#include "storage/common/table_meta.h" #include "storage/common/table_meta.h"
...@@ -123,5 +122,3 @@ private: ...@@ -123,5 +122,3 @@ private:
RecordFileHandler *record_handler_ = nullptr; /// 记录操作 RecordFileHandler *record_handler_ = nullptr; /// 记录操作
std::vector<Index *> indexes_; std::vector<Index *> indexes_;
}; };
#endif // __OBSERVER_STORAGE_COMMON_TABLE_H__
...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */ ...@@ -12,8 +12,7 @@ See the Mulan PSL v2 for more details. */
// Created by Meiyi & Wangyunlai on 2021/5/12. // Created by Meiyi & Wangyunlai on 2021/5/12.
// //
#ifndef __OBSERVER_STORAGE_COMMON_TABLE_META_H__ #pragma once
#define __OBSERVER_STORAGE_COMMON_TABLE_META_H__
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -73,5 +72,3 @@ protected: ...@@ -73,5 +72,3 @@ protected:
//@@@ TODO why used static variable? //@@@ TODO why used static variable?
static std::vector<FieldMeta> sys_fields_; static std::vector<FieldMeta> sys_fields_;
}; };
#endif // __OBSERVER_STORAGE_COMMON_TABLE_META_H__
...@@ -148,7 +148,7 @@ void DefaultStorageStage::handle_event(StageEvent *event) ...@@ -148,7 +148,7 @@ void DefaultStorageStage::handle_event(StageEvent *event)
SessionEvent *session_event = sql_event->session_event(); SessionEvent *session_event = sql_event->session_event();
Session *session = session_event->get_client()->session; Session *session = session_event->session();
Db *db = session->get_current_db(); Db *db = session->get_current_db();
const char *dbname = db->name(); const char *dbname = db->name();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册