Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
Support for SET statements. (#1073)
Browse files Browse the repository at this point in the history
* Add support for SQL SET statement, including DEFAULT.
* Add extra_float_digits as a setting.
* Add application_name as a setting.
* Add transaction_isolation as a setting.
* Add hack around SET SESSION CHARACTERISTICS.

Co-authored-by: Wan Shen Lim <wanshenl@cs.cmu.edu>
Co-authored-by: Matt Butrovich <mbutrovich@gmail.com>
Co-authored-by: Matt Butrovich <mbutrovich@users.noreply.github.com>
  • Loading branch information
4 people committed Aug 16, 2020
1 parent 5d7cc96 commit 3b16bea
Show file tree
Hide file tree
Showing 17 changed files with 484 additions and 243 deletions.
54 changes: 18 additions & 36 deletions src/include/common/error/exception.h
Expand Up @@ -20,12 +20,12 @@ namespace terrier {
#define CONVERSION_EXCEPTION(msg) ConversionException(msg, __FILE__, __LINE__)
#define PARSER_EXCEPTION(msg) ParserException(msg, __FILE__, __LINE__)
#define NETWORK_PROCESS_EXCEPTION(msg) NetworkProcessException(msg, __FILE__, __LINE__)
#define SETTINGS_EXCEPTION(msg) SettingsException(msg, __FILE__, __LINE__)
#define OPTIMIZER_EXCEPTION(msg) OptimizerException(msg, __FILE__, __LINE__)
#define SYNTAX_EXCEPTION(msg) SyntaxException(msg, __FILE__, __LINE__)
#define BINDER_EXCEPTION(msg, code) BinderException(msg, __FILE__, __LINE__, (code))
#define EXECUTION_EXCEPTION(msg) ExecutionException(msg, __FILE__, __LINE__)
#define ABORT_EXCEPTION(msg) AbortException(msg, __FILE__, __LINE__)
#define BINDER_EXCEPTION(msg, code) BinderException(msg, __FILE__, __LINE__, (code))
#define SETTINGS_EXCEPTION(msg, code) SettingsException(msg, __FILE__, __LINE__, (code))

/**
* Exception types
Expand Down Expand Up @@ -135,15 +135,30 @@ class Exception : public std::runtime_error {
e_name(const std::string &msg, const char *file, int line) : Exception(e_type, msg.c_str(), file, line) {} \
}

#define DEFINE_EXCEPTION_WITH_ERRCODE(e_name, e_type) \
class e_name : public Exception { \
e_name() = delete; \
\
public: \
e_name(const char *msg, const char *file, int line, common::ErrorCode code) \
: Exception(e_type, msg, file, line), code_(code) {} \
e_name(const std::string &msg, const char *file, int line, common::ErrorCode code) \
: Exception(e_type, msg.c_str(), file, line), code_(code) {} \
\
/** The SQL error code. */ \
common::ErrorCode code_; \
}

DEFINE_EXCEPTION(NotImplementedException, ExceptionType::NOT_IMPLEMENTED);
DEFINE_EXCEPTION(CatalogException, ExceptionType::CATALOG);
DEFINE_EXCEPTION(NetworkProcessException, ExceptionType::NETWORK);
DEFINE_EXCEPTION(SettingsException, ExceptionType::SETTINGS);
DEFINE_EXCEPTION(OptimizerException, ExceptionType::OPTIMIZER);
DEFINE_EXCEPTION(ConversionException, ExceptionType::CONVERSION);
DEFINE_EXCEPTION(SyntaxException, ExceptionType::SYNTAX);
DEFINE_EXCEPTION(ExecutionException, ExceptionType::EXECUTION);
DEFINE_EXCEPTION(AbortException, ExceptionType::EXECUTION);
DEFINE_EXCEPTION_WITH_ERRCODE(BinderException, ExceptionType::BINDER);
DEFINE_EXCEPTION_WITH_ERRCODE(SettingsException, ExceptionType::SETTINGS);

/**
* Specialized Parser exception since we want a cursor position to get more verbose output
Expand Down Expand Up @@ -196,37 +211,4 @@ class ParserException : public Exception {
uint32_t GetCursorPos() const { return cursorpos_; }
};

/**
* Specialized Binder exception since we want an error code to get more verbose output
*/
class BinderException : public Exception {
public:
BinderException() = delete;

/**
* Creates a new ParserException with the given parameters.
* @param msg exception message to be displayed
* @param file name of the file in which the exception occurred
* @param line line number at which the exception occurred
* @param code sql error code
*/
BinderException(const char *msg, const char *file, int line, common::ErrorCode code)
: Exception(ExceptionType::BINDER, msg, file, line), code_(code) {}

/**
* Creates a new ParserException with the given parameters.
* @param msg exception message to be displayed
* @param file name of the file in which the exception occurred
* @param line line number at which the exception occurred
* @param code sql error code
*/
BinderException(const std::string &msg, const char *file, int line, common::ErrorCode code)
: Exception(ExceptionType::BINDER, msg.c_str(), file, line), code_(code) {}

/**
* sql error code
*/
common::ErrorCode code_;
};

} // namespace terrier
3 changes: 2 additions & 1 deletion src/include/main/db_main.h
Expand Up @@ -351,7 +351,8 @@ class DBMain {
TERRIER_ASSERT(use_execution_ && execution_layer != DISABLED, "TrafficCopLayer needs ExecutionLayer.");
traffic_cop = std::make_unique<trafficcop::TrafficCop>(
txn_layer->GetTransactionManager(), catalog_layer->GetCatalog(), DISABLED,
common::ManagedPointer(stats_storage), optimizer_timeout_, use_query_cache_, execution_mode_);
common::ManagedPointer(settings_manager), common::ManagedPointer(stats_storage), optimizer_timeout_,
use_query_cache_, execution_mode_);
}

std::unique_ptr<NetworkLayer> network_layer = DISABLED;
Expand Down
3 changes: 2 additions & 1 deletion src/include/network/network_defs.h
Expand Up @@ -115,6 +115,8 @@ enum class QueryType : uint8_t {
QUERY_DROP_TRIGGER,
QUERY_DROP_SCHEMA,
QUERY_DROP_VIEW,
// Misc (non-transactional)
QUERY_SET,
// end of what we support in the traffic cop right now
QUERY_RENAME,
QUERY_ALTER,
Expand All @@ -125,7 +127,6 @@ enum class QueryType : uint8_t {
// Misc
QUERY_COPY,
QUERY_ANALYZE,
QUERY_SET,
QUERY_SHOW,
QUERY_OTHER,
QUERY_EXPLAIN,
Expand Down
8 changes: 7 additions & 1 deletion src/include/network/network_util.h
Expand Up @@ -49,11 +49,17 @@ class NetworkUtil {
return type >= QueryType::QUERY_CREATE_TABLE && type <= QueryType::QUERY_DROP_VIEW;
}

/**
* @param type query type from the parser
* @return true for statement types that aren't run in a txn, currently SET but other internal queries might be added
*/
static bool NonTransactionalQueryType(const QueryType type) { return type == QueryType::QUERY_SET; }

/**
* @param type query type from the parser
* @return true if a query that is current not implemented in the system. Order of QueryType enum matters here.
*/
static bool UnsupportedQueryType(const QueryType type) { return type > QueryType::QUERY_DROP_VIEW; }
static bool UnsupportedQueryType(const QueryType type) { return type > QueryType::QUERY_SET; }
};

} // namespace terrier::network
3 changes: 3 additions & 0 deletions src/include/parser/expression/constant_value_expression.h
Expand Up @@ -229,6 +229,9 @@ class ConstantValueExpression : public AbstractExpression {

void Accept(common::ManagedPointer<binder::SqlNodeVisitor> v) override { v->Visit(common::ManagedPointer(this)); }

/** @return A string representation of this ConstantValueExpression. */
std::string ToString() const;

/**
* @return expression serialized to json
*/
Expand Down
44 changes: 40 additions & 4 deletions src/include/parser/variable_set_statement.h
@@ -1,5 +1,9 @@
#pragma once

#include <string>
#include <utility>
#include <vector>

#include "binder/sql_node_visitor.h"
#include "parser/sql_statement.h"
#include "parser/table_ref.h"
Expand All @@ -10,14 +14,46 @@ namespace parser {
* Not sure what this is for. Inherited from old codebase.
*/
class VariableSetStatement : public SQLStatement {
// TODO(WAN): inherited from old codebase.
// It was added to the parser to avoid connection error by Yuchen,
// because JDBC on starting connection will send SET and require a response.
public:
VariableSetStatement() : SQLStatement(StatementType::VARIABLE_SET) {}
/**
* @param parameter_name The name of the parameter.
* @param values The values to set in the parameter.
* @param is_set_default True if the parameter should be set to DEFAULT, in which case values should be empty.
*/
VariableSetStatement(std::string parameter_name, std::vector<common::ManagedPointer<AbstractExpression>> values,
bool is_set_default)
: SQLStatement(StatementType::VARIABLE_SET),
parameter_name_(std::move(parameter_name)),
values_(std::move(values)),
is_set_default_(is_set_default) {
TERRIER_ASSERT((values_.empty() && is_set_default_) || (values_.size() == 1 && !is_set_default_),
"There is only support for setting one value or setting to default.");
}

~VariableSetStatement() override = default;

void Accept(common::ManagedPointer<binder::SqlNodeVisitor> v) override { v->Visit(common::ManagedPointer(this)); }

/** @return The parameter name. */
std::string GetParameterName() { return parameter_name_; }

/** @return The set statement values. */
std::vector<common::ManagedPointer<AbstractExpression>> GetValues() const {
std::vector<common::ManagedPointer<AbstractExpression>> values;
values.reserve(values_.size());
for (const auto &value : values_) {
values.emplace_back(common::ManagedPointer(value));
}
return values;
}

/** @return True if the parameter should be set to DEFAULT. */
bool IsSetDefault() const { return is_set_default_; }

private:
const std::string parameter_name_;
const std::vector<common::ManagedPointer<AbstractExpression>> values_;
bool is_set_default_;
};
} // namespace parser
} // namespace terrier
46 changes: 25 additions & 21 deletions src/include/settings/settings_common.h
Expand Up @@ -4,9 +4,9 @@

// This allows the settings defined once to be used in different contexts.
// When __SETTING_GFLAGS_DEFINE__ is set,
// setting definitions will be exposed through glfags definitions.
// setting definitions will be exposed through gflags definitions.
// When __SETTING_GFLAGS_DECLARE__ is set,
// setting definitions will be exposed through glfags declarations.
// setting definitions will be exposed through gflags declarations.
// When __SETTING_DEFINE__ is set,
// setting definitions will be exposed through definitions in settings_manager.
// When __SETTING_POPULATE__ is set,
Expand Down Expand Up @@ -143,12 +143,14 @@
ValidateSetting(terrier::settings::Param::name, {type::TypeId::BOOLEAN, execution::sql::BoolVal(default_value)}, \
{type::TypeId::BOOLEAN, execution::sql::BoolVal(default_value)});

#define SETTING_string(name, description, default_value, is_mutable, callback_fn) \
std::string default_value_string{default_value}; \
auto string_val = execution::sql::ValueUtil::CreateStringVal(default_value_string); \
auto default_value_cve = std::make_unique<parser::ConstantValueExpression>(type::TypeId::VARCHAR, string_val.first, \
std::move(string_val.second)); \
ValidateSetting(terrier::settings::Param::name, *default_value_cve, *default_value_cve);
#define SETTING_string(name, description, default_value, is_mutable, callback_fn) \
{ \
std::string default_value_string{default_value}; \
auto string_val = execution::sql::ValueUtil::CreateStringVal(default_value_string); \
auto default_value_cve = std::make_unique<parser::ConstantValueExpression>( \
type::TypeId::VARCHAR, string_val.first, std::move(string_val.second)); \
ValidateSetting(terrier::settings::Param::name, *default_value_cve, *default_value_cve); \
}
#endif

#ifdef __SETTING_ENUM__
Expand Down Expand Up @@ -222,18 +224,20 @@
{type::TypeId::BOOLEAN, execution::sql::BoolVal(default_value)}, is_mutable, 0, 0, \
&callback_fn));

#define SETTING_string(name, description, default_value, is_mutable, callback_fn) \
const std::string_view value_string{FLAGS_##name}; \
auto string_val = execution::sql::ValueUtil::CreateStringVal(value_string); \
\
const std::string_view default_value_string{default_value}; \
auto default_value_string_val = execution::sql::ValueUtil::CreateStringVal(default_value_string); \
\
param_map.emplace( \
terrier::settings::Param::name, \
terrier::settings::ParamInfo( \
#name, {type::TypeId::VARCHAR, string_val.first, std::move(string_val.second)}, description, \
{type::TypeId::VARCHAR, default_value_string_val.first, std::move(default_value_string_val.second)}, \
is_mutable, 0, 0, &callback_fn));
#define SETTING_string(name, description, default_value, is_mutable, callback_fn) \
{ \
const std::string_view value_string{FLAGS_##name}; \
auto string_val = execution::sql::ValueUtil::CreateStringVal(value_string); \
\
const std::string_view default_value_string{default_value}; \
auto default_value_string_val = execution::sql::ValueUtil::CreateStringVal(default_value_string); \
\
param_map.emplace( \
terrier::settings::Param::name, \
terrier::settings::ParamInfo( \
#name, {type::TypeId::VARCHAR, string_val.first, std::move(string_val.second)}, description, \
{type::TypeId::VARCHAR, default_value_string_val.first, std::move(default_value_string_val.second)}, \
is_mutable, 0, 0, &callback_fn)); \
}

#endif
26 changes: 26 additions & 0 deletions src/include/settings/settings_defs.h
Expand Up @@ -154,6 +154,16 @@ SETTING_int64(
terrier::settings::Callbacks::NoOp
)

SETTING_int(
extra_float_digits,
"Sets the number of digits displayed for floating-point values. (default : 1)",
1,
-15,
3,
true,
terrier::settings::Callbacks::NoOp
)

SETTING_bool(
metrics,
"Metrics sub-system for various components (default: true).",
Expand Down Expand Up @@ -233,3 +243,19 @@ SETTING_bool(
false,
terrier::settings::Callbacks::NoOp
)

SETTING_string(
application_name,
"The name of the application (default: NO_NAME)",
"NO_NAME",
true,
terrier::settings::Callbacks::NoOp
)

SETTING_string(
transaction_isolation,
"The default isolation level (default: TRANSACTION_READ_COMMITTED)",
"TRANSACTION_READ_COMMITTED",
true,
terrier::settings::Callbacks::NoOp
)
26 changes: 25 additions & 1 deletion src/include/settings/settings_manager.h
Expand Up @@ -6,6 +6,7 @@
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "common/action_context.h"
#include "common/error/exception.h"
Expand Down Expand Up @@ -73,6 +74,12 @@ class SettingsManager {
*/
std::string GetString(Param param);

/**
* Get a copy of the default setting for a given parameter.
* @param name setting name
*/
const parser::ConstantValueExpression &GetDefault(const std::string &name);

/**
* Set the value of an integer setting
* @param param setting name
Expand Down Expand Up @@ -128,27 +135,44 @@ class SettingsManager {
*/
void ValidateParams();

/**
* Set the given parameter.
* @param name The parameter name.
* @param values The parameter's new value(s).
*/
void SetParameter(const std::string &name,
const std::vector<common::ManagedPointer<parser::AbstractExpression>> &values);

/**
* Construct settings param map from settings_defs.h
* @param param_map
*/
static void ConstructParamMap( // NOLINT
static void ConstructParamMap(
std::unordered_map<terrier::settings::Param, terrier::settings::ParamInfo> &param_map); // NOLINT

private:
common::ManagedPointer<DBMain> db_main_;
std::unordered_map<settings::Param, settings::ParamInfo> param_map_;
std::unordered_map<std::string, settings::Param> param_name_map_;

common::SharedLatch latch_;

void ValidateSetting(Param param, const parser::ConstantValueExpression &min_value,
const parser::ConstantValueExpression &max_value);

/** @return The Param corresponding to the given name; throws exception if doesn't exist. */
Param GetParam(const std::string &name) const;
/** @return The ParamInfo corresponding to the given parameter; throws exception if doesn't exist. */
const ParamInfo &GetParamInfo(const settings::Param &param) const;

parser::ConstantValueExpression &GetValue(Param param);
bool SetValue(Param param, parser::ConstantValueExpression value);
bool ValidateValue(const parser::ConstantValueExpression &value, const parser::ConstantValueExpression &min_value,
const parser::ConstantValueExpression &max_value);
common::ActionState InvokeCallback(Param param, void *old_value, void *new_value,
common::ManagedPointer<common::ActionContext> action_context);

static void EmptySetterCallback(common::ManagedPointer<common::ActionContext> action_context UNUSED_ATTRIBUTE) {}
};

} // namespace terrier::settings

0 comments on commit 3b16bea

Please sign in to comment.