2018-03-14 11:27:27 +08:00
|
|
|
/* $%BEGINLICENSE%$
|
|
|
|
Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; version 2 of the
|
|
|
|
License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
|
|
02110-1301 USA
|
|
|
|
|
|
|
|
$%ENDLICENSE%$ */
|
|
|
|
|
2018-03-06 14:00:39 +08:00
|
|
|
#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"
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_select(sql_context_t *st, sql_select_t *select)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
st->rw_flag |= CF_READ;
|
|
|
|
sql_context_add_stmt(st, STMT_SELECT, select);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_delete(sql_context_t *st, sql_delete_t *del)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (st->rc != PARSE_OK) {
|
|
|
|
g_warning("Delete Parse Error");
|
|
|
|
}
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_DELETE, del);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_update(sql_context_t *st, sql_update_t *update)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (st->rc != PARSE_OK) {
|
|
|
|
g_warning("Update Parse Error");
|
|
|
|
}
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_UPDATE, update);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_insert(sql_context_t *st, sql_insert_t *insert)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (st->rc != PARSE_OK) {
|
|
|
|
g_warning("Insert Parse Error");
|
|
|
|
}
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_INSERT, insert);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_start_transaction(sql_context_t *st)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (st->rc != PARSE_OK) {
|
|
|
|
g_warning("Start transaction parse Error");
|
|
|
|
}
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_START, NULL);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_commit_transaction(sql_context_t *st)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (st->rc != PARSE_OK) {
|
|
|
|
g_warning("COMMIT transaction parse Error");
|
|
|
|
}
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_COMMIT, NULL);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_rollback_transaction(sql_context_t *st)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (st->rc != PARSE_OK) {
|
|
|
|
g_warning("ROLLBACK transaction parse Error");
|
|
|
|
}
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_ROLLBACK, NULL);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_savepoint(sql_context_t *st, int tk, char *name)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (st->rc != PARSE_OK) {
|
|
|
|
g_warning("SAVE POINT parse Error");
|
|
|
|
}
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_SAVEPOINT, name);
|
|
|
|
}
|
|
|
|
|
2018-12-12 11:20:05 +08:00
|
|
|
void
|
|
|
|
sql_drop_database(sql_context_t *st, sql_drop_database_t *drop_database)
|
|
|
|
{
|
|
|
|
st->rw_flag |= CF_WRITE;
|
|
|
|
sql_context_add_stmt(st, STMT_DROP_DATABASE, drop_database);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
static gboolean
|
|
|
|
string_array_contains(const char **sa, int size, const char *str)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
int i = 0;
|
2018-03-20 14:19:44 +08:00
|
|
|
for (; i < size; ++i) {
|
2018-03-06 14:00:39 +08:00
|
|
|
if (strcasecmp(sa[i], str) == 0)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_set_variable(sql_context_t *ps, sql_expr_list_t *exps)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (ps->property) {
|
2018-03-20 14:19:44 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, "Commanding comment is not allowed in SET clause");
|
2018-03-06 14:00:39 +08:00
|
|
|
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)) {
|
2018-03-20 14:19:44 +08:00
|
|
|
sql_context_set_error(ps, PARSE_SYNTAX_ERR, "syntax error in SET");
|
2018-03-06 14:00:39 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (p->left && p->left->var_scope == SCOPE_GLOBAL) {
|
2018-03-20 14:19:44 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, "Only session scope SET is supported now");
|
2018-03-06 14:00:39 +08:00
|
|
|
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) {
|
2018-03-20 14:19:44 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, "This sql_mode is not supported");
|
2018-03-06 14:00:39 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
} else if (!sql_filter_vars_is_allowed(var_name, value)) {
|
2018-11-21 14:56:47 +08:00
|
|
|
char msg[128];
|
|
|
|
snprintf(msg, 128, "SET of %s is not supported", var_name);
|
2018-03-06 14:00:39 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, msg);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
2018-03-20 14:19:44 +08:00
|
|
|
out:
|
2018-03-06 14:00:39 +08:00
|
|
|
sql_context_add_stmt(ps, STMT_SET, exps);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_set_names(sql_context_t *ps, char *val)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (ps->property) {
|
2018-03-20 14:19:44 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, "Commanding comment is not allowed in SET clause");
|
2018-03-06 14:00:39 +08:00
|
|
|
g_free(val);
|
|
|
|
return;
|
|
|
|
}
|
2018-03-20 14:19:44 +08:00
|
|
|
const char *charsets[] = { "latin1", "ascii", "gb2312", "gbk", "utf8", "utf8mb4", "big5" };
|
2018-03-06 14:00:39 +08:00
|
|
|
int cs_size = sizeof(charsets) / sizeof(char *);
|
|
|
|
if (!string_array_contains(charsets, cs_size, val)) {
|
2018-11-21 14:56:47 +08:00
|
|
|
char msg[128] = { 0 };
|
|
|
|
snprintf(msg, 128, "Unknown character set: %s", val);
|
2018-03-06 14:00:39 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, msg);
|
|
|
|
g_free(val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sql_context_add_stmt(ps, STMT_SET_NAMES, val);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_set_transaction(sql_context_t *ps, int scope, int rw_feature, int level)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
if (ps->property) {
|
2018-03-20 14:19:44 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, "Commanding comment is not allowed in SET clause");
|
2018-03-06 14:00:39 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (scope == SCOPE_GLOBAL) {
|
2018-03-20 14:19:44 +08:00
|
|
|
sql_context_set_error(ps, PARSE_NOT_SUPPORT, "GLOBAL scope SET TRANSACTION is not supported now");
|
2018-03-06 14:00:39 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_use_database(sql_context_t *ps, char *val)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
ps->rw_flag |= CF_READ;
|
|
|
|
sql_context_add_stmt(ps, STMT_USE, val);
|
|
|
|
}
|
|
|
|
|
2018-03-20 14:19:44 +08:00
|
|
|
void
|
|
|
|
sql_explain_table(sql_context_t *ps, sql_src_list_t *table)
|
2018-03-06 14:00:39 +08:00
|
|
|
{
|
|
|
|
ps->rw_flag |= CF_READ;
|
|
|
|
sql_context_add_stmt(ps, STMT_EXPLAIN_TABLE, table);
|
|
|
|
}
|