mysql5/mysql-5.7.27/sql/rules_table_service.cc

210 lines
5.4 KiB
C++

/* Copyright (c) 2015, 2017, 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,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
/**
@file rules_table_service.cc
Implementation of the service for accessing the rewrite rules table.
*/
#include <mysql/service_rules_table.h>
#include "thr_lock.h"
#include "table.h"
#include "handler.h"
#include "my_base.h"
#include "my_bitmap.h"
#include "field.h"
#include "sql_string.h"
#include "transaction.h"
#include "sql_base.h"
namespace rules_table_service
{
int MY_ATTRIBUTE((visibility("default")))
dummy_function_to_ensure_we_are_linked_into_the_server() { return 1; }
const char *db_name= "query_rewrite";
const char *table_name= "rewrite_rules";
int Cursor::read()
{
TABLE *table= m_table_list->table;
m_last_read_status= table->file->ha_rnd_next(table->record[0]);
if (m_last_read_status != 0)
m_is_finished= true;
return m_last_read_status;
}
void free_string(const char *str) { delete [] str; }
static void add_column(MY_BITMAP *map, Cursor::column_id column)
{
if (column != Cursor::ILLEGAL_COLUMN_ID)
bitmap_set_bit(map, column);
}
Cursor::Cursor(MYSQL_THD mysql_thd) :
m_thd(mysql_thd),
m_table_list(NULL),
m_is_finished(true),
m_table_is_malformed(true)
{
m_table_list= new TABLE_LIST;
if (m_table_list == NULL)
return; // Error
// The below function will memset() the whole object with 0's.
m_table_list->init_one_table(db_name, strlen(db_name),
table_name, strlen(table_name),
"alias", TL_WRITE_DEFAULT);
m_table_list->updating= true;
if (open_and_lock_tables(m_thd, m_table_list, MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY))
return; // Error
TABLE *table= m_table_list->table;
if (table == NULL)
return; // Error
m_pattern_column= field_index("pattern");
m_pattern_database_column= field_index("pattern_database");
m_replacement_column= field_index("replacement");
m_enabled_column= field_index("enabled");
// The following columns are not required for the Cursor to work.
m_message_column= field_index("message");
m_pattern_digest_column= field_index("pattern_digest");
m_normalized_pattern_column= field_index("normalized_pattern");
if (m_pattern_column == ILLEGAL_COLUMN_ID ||
m_pattern_database_column == ILLEGAL_COLUMN_ID ||
m_replacement_column == ILLEGAL_COLUMN_ID ||
m_enabled_column == ILLEGAL_COLUMN_ID)
{
trans_rollback_stmt(m_thd);
close_thread_tables(m_thd);
/*
We are never going to use this table, we might as well get rid of the
reference to it.
*/
delete m_table_list;
m_table_list= NULL;
m_table_is_malformed= true;
return; // Error
}
else
m_table_is_malformed= false;
add_column(table->read_set, pattern_column());
add_column(table->read_set, pattern_database_column());
add_column(table->read_set, replacement_column());
add_column(table->read_set, enabled_column());
add_column(table->read_set, message_column());
add_column(table->write_set, enabled_column());
add_column(table->write_set, message_column());
add_column(table->write_set, pattern_digest_column());
add_column(table->write_set, normalized_pattern_column());
if (m_table_list->table->file->ha_rnd_init(true) != 0)
return; // Error
// No error occured, set this to false.
m_is_finished= false;
read();
}
const char *Cursor::fetch_string(int fieldno)
{
Field **fields= m_table_list->table->field;
Field *field= fields[fieldno];
if (field->is_null())
return NULL;
String value_buf;
String *value= field->val_str(&value_buf);
size_t length= value->length();
char *res= new char[length + 1];
strncpy(res, value->ptr(), length);
res[length]= '\0';
return res;
}
int Cursor::field_index(const char *field_name)
{
TABLE *table= m_table_list->table;
for (uint i= 0; i < table->s->fields; ++i)
if (strcmp(table->field[i]->field_name, field_name) == 0)
return i;
return -1;
}
void Cursor::make_writeable()
{
TABLE *table= m_table_list->table;
memcpy(table->record[1], table->record[0], table->s->rec_buff_length);
}
void Cursor::set(int colno, const char* str, size_t length)
{
TABLE *table= m_table_list->table;
Field *field= table->field[colno];
const CHARSET_INFO *charset= &my_charset_utf8_unicode_ci;
if (str == NULL)
field->set_null(0);
else
{
field->store(str, length, charset);
field->set_notnull(0);
}
}
int Cursor::write()
{
TABLE *table= m_table_list->table;
return table->file->ha_update_row(table->record[1], table->record[0]);
}
bool Cursor::had_serious_read_error() const
{
return
m_last_read_status != 0 &&
m_last_read_status != HA_ERR_END_OF_FILE;
}
Cursor::~Cursor()
{
if (m_table_list != NULL && m_table_list->table != NULL)
m_table_list->table->file->ha_rnd_end();
delete m_table_list;
}
Cursor end() { return Cursor(); }
}