cetus/lib/sql-operation.c
2018-03-06 14:00:39 +08:00

184 lines
5.2 KiB
C

#include "sql-operation.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "sql-expression.h"
#include "sql-filter-variables.h"
#include "myparser.y.h"
void sql_select(sql_context_t *st, sql_select_t *select)
{
st->rw_flag |= CF_READ;
sql_context_add_stmt(st, STMT_SELECT, select);
}
void sql_delete(sql_context_t *st, sql_delete_t *del)
{
if (st->rc != PARSE_OK) {
g_warning("Delete Parse Error");
}
st->rw_flag |= CF_WRITE;
sql_context_add_stmt(st, STMT_DELETE, del);
}
void sql_update(sql_context_t *st, sql_update_t *update)
{
if (st->rc != PARSE_OK) {
g_warning("Update Parse Error");
}
st->rw_flag |= CF_WRITE;
sql_context_add_stmt(st, STMT_UPDATE, update);
}
void sql_insert(sql_context_t *st, sql_insert_t *insert)
{
if (st->rc != PARSE_OK) {
g_warning("Insert Parse Error");
}
st->rw_flag |= CF_WRITE;
sql_context_add_stmt(st, STMT_INSERT, insert);
}
void sql_start_transaction(sql_context_t *st)
{
if (st->rc != PARSE_OK) {
g_warning("Start transaction parse Error");
}
st->rw_flag |= CF_WRITE;
sql_context_add_stmt(st, STMT_START, NULL);
}
void sql_commit_transaction(sql_context_t *st)
{
if (st->rc != PARSE_OK) {
g_warning("COMMIT transaction parse Error");
}
st->rw_flag |= CF_WRITE;
sql_context_add_stmt(st, STMT_COMMIT, NULL);
}
void sql_rollback_transaction(sql_context_t *st)
{
if (st->rc != PARSE_OK) {
g_warning("ROLLBACK transaction parse Error");
}
st->rw_flag |= CF_WRITE;
sql_context_add_stmt(st, STMT_ROLLBACK, NULL);
}
void sql_savepoint(sql_context_t *st, int tk, char *name)
{
if (st->rc != PARSE_OK) {
g_warning("SAVE POINT parse Error");
}
st->rw_flag |= CF_WRITE;
sql_context_add_stmt(st, STMT_SAVEPOINT, name);
}
static gboolean string_array_contains(const char **sa, int size, const char *str)
{
int i = 0;
for (;i < size; ++i) {
if (strcasecmp(sa[i], str) == 0)
return TRUE;
}
return FALSE;
}
void sql_set_variable(sql_context_t *ps, sql_expr_list_t *exps)
{
if (ps->property) {
sql_context_set_error(ps, PARSE_NOT_SUPPORT,
"Commanding comment is not allowed in SET clause");
goto out;
}
g_assert(exps);
int i = 0;
for (i = 0; i < exps->len; ++i) {
sql_expr_t *p = g_ptr_array_index(exps, i);
if (!p || p->op != TK_EQ || !sql_expr_is_id(p->left, NULL)) {
sql_context_set_error(ps, PARSE_SYNTAX_ERR,
"syntax error in SET");
goto out;
}
if (p->left && p->left->var_scope == SCOPE_GLOBAL) {
sql_context_set_error(ps, PARSE_NOT_SUPPORT,
"Only session scope SET is supported now");
goto out;
}
const char *var_name = p->left->token_text;
const char *value = p->right->token_text;
if (strcasecmp(var_name, "sql_mode") == 0) {
gboolean supported = sql_filter_vars_is_allowed(var_name, value);
if (!supported) {
sql_context_set_error(ps, PARSE_NOT_SUPPORT,
"This sql_mode is not supported");
goto out;
}
} else if (!sql_filter_vars_is_allowed(var_name, value)) {
char msg[100];
snprintf(msg, 100, "SET of %s is not supported", var_name);
sql_context_set_error(ps, PARSE_NOT_SUPPORT, msg);
goto out;
}
}
out:
sql_context_add_stmt(ps, STMT_SET, exps);
}
void sql_set_names(sql_context_t *ps, char *val)
{
if (ps->property) {
sql_context_set_error(ps, PARSE_NOT_SUPPORT,
"Commanding comment is not allowed in SET clause");
g_free(val);
return;
}
const char *charsets[] = {"latin1", "ascii", "gb2312", "gbk", "utf8", "utf8mb4", "big5"};
int cs_size = sizeof(charsets) / sizeof(char *);
if (!string_array_contains(charsets, cs_size, val)) {
char msg[64] = {0};
snprintf(msg, 64, "Unknown character set: %s", val);
sql_context_set_error(ps, PARSE_NOT_SUPPORT, msg);
g_free(val);
return;
}
sql_context_add_stmt(ps, STMT_SET_NAMES, val);
}
void sql_set_transaction(sql_context_t *ps, int scope, int rw_feature, int level)
{
if (ps->property) {
sql_context_set_error(ps, PARSE_NOT_SUPPORT,
"Commanding comment is not allowed in SET clause");
return;
}
if (scope == SCOPE_GLOBAL) {
sql_context_set_error(ps, PARSE_NOT_SUPPORT,
"GLOBAL scope SET TRANSACTION is not supported now");
return;
}
sql_set_transaction_t *set_tran = g_new0(sql_set_transaction_t, 1);
set_tran->scope = scope;
set_tran->rw_feature = rw_feature;
set_tran->level = level;
sql_context_add_stmt(ps, STMT_SET_TRANSACTION, set_tran);
}
void sql_use_database(sql_context_t *ps, char *val)
{
ps->rw_flag |= CF_READ;
sql_context_add_stmt(ps, STMT_USE, val);
}
void sql_explain_table(sql_context_t *ps, sql_src_list_t *table)
{
ps->rw_flag |= CF_READ;
sql_context_add_stmt(ps, STMT_EXPLAIN_TABLE, table);
}