mirror of
https://github.com/MariaDB/server.git
synced 2026-05-17 20:37:12 +02:00
Update Mroonga to the latest version on 2014-09-21T00:33:44+0900
This commit is contained in:
parent
989dd4d9ec
commit
0cc855cdc8
2027 changed files with 460307 additions and 0 deletions
23
storage/mroonga/lib/Makefile.am
Normal file
23
storage/mroonga/lib/Makefile.am
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
AM_CPPFLAGS = \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir) \
|
||||
$(MYSQL_INCLUDES) \
|
||||
$(GROONGA_CFLAGS) \
|
||||
$(MYSQL_VERSION_CFLAGS)
|
||||
|
||||
libmrn_need_mysql_la_CXXFLAGS = $(AM_CXXFLAGS) $(MYSQL_CFLAGS)
|
||||
|
||||
if WITH_LIBMYSQLSERVICES_COMPAT
|
||||
LIBMYSQLSERVICES_COMPAT = libmysqlservices.la
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES = \
|
||||
$(LIBMYSQLSERVICES_COMPAT) \
|
||||
libmrn_no_mysql.la \
|
||||
libmrn_need_mysql.la
|
||||
|
||||
include libmrn_no_mysql_sources.am
|
||||
include libmrn_need_mysql_sources.am
|
||||
if WITH_LIBMYSQLSERVICES_COMPAT
|
||||
include libmysqlservices_compat_sources.am
|
||||
endif
|
||||
25
storage/mroonga/lib/libmrn_need_mysql_sources.am
Normal file
25
storage/mroonga/lib/libmrn_need_mysql_sources.am
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
libmrn_need_mysql_la_SOURCES = \
|
||||
mrn_index_table_name.cpp \
|
||||
mrn_index_table_name.hpp \
|
||||
mrn_index_column_name.cpp \
|
||||
mrn_index_column_name.hpp \
|
||||
mrn_debug_column_access.cpp \
|
||||
mrn_debug_column_access.hpp \
|
||||
mrn_auto_increment_value_lock.cpp \
|
||||
mrn_auto_increment_value_lock.hpp \
|
||||
mrn_external_lock.cpp \
|
||||
mrn_external_lock.hpp \
|
||||
mrn_multiple_column_key_codec.cpp \
|
||||
mrn_multiple_column_key_codec.hpp \
|
||||
mrn_field_normalizer.cpp \
|
||||
mrn_field_normalizer.hpp \
|
||||
mrn_encoding.cpp \
|
||||
mrn_encoding.hpp \
|
||||
mrn_parameters_parser.cpp \
|
||||
mrn_parameters_parser.hpp \
|
||||
mrn_lock.cpp \
|
||||
mrn_lock.hpp \
|
||||
mrn_condition_converter.cpp \
|
||||
mrn_condition_converter.hpp \
|
||||
mrn_time_converter.cpp \
|
||||
mrn_time_converter.hpp
|
||||
8
storage/mroonga/lib/libmrn_no_mysql_sources.am
Normal file
8
storage/mroonga/lib/libmrn_no_mysql_sources.am
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
libmrn_no_mysql_la_SOURCES = \
|
||||
mrn_match_escalation_threshold_scope.cpp \
|
||||
mrn_match_escalation_threshold_scope.hpp \
|
||||
mrn_path_mapper.cpp \
|
||||
mrn_path_mapper.hpp \
|
||||
mrn_windows.hpp \
|
||||
mrn_smart_grn_obj.cpp \
|
||||
mrn_smart_grn_obj.hpp
|
||||
2
storage/mroonga/lib/libmysqlservices_compat_sources.am
Normal file
2
storage/mroonga/lib/libmysqlservices_compat_sources.am
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
libmysqlservices_la_SOURCES = \
|
||||
mrn_mysqlservices.cpp
|
||||
42
storage/mroonga/lib/mrn_auto_increment_value_lock.cpp
Normal file
42
storage/mroonga/lib/mrn_auto_increment_value_lock.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mrn_auto_increment_value_lock.hpp"
|
||||
|
||||
#if MYSQL_VERSION_ID >= 50500
|
||||
# define AUTO_INCREMENT_VALUE_MUTEX(table_share) (&(table_share->LOCK_ha_data))
|
||||
#else
|
||||
# define AUTO_INCREMENT_VALUE_MUTEX(table_share) (&(table_share->mutex))
|
||||
#endif
|
||||
|
||||
namespace mrn {
|
||||
AutoIncrementValueLock::AutoIncrementValueLock(TABLE_SHARE *table_share)
|
||||
: table_share_(table_share),
|
||||
need_lock_(table_share_->tmp_table == NO_TMP_TABLE) {
|
||||
if (need_lock_) {
|
||||
mysql_mutex_lock(AUTO_INCREMENT_VALUE_MUTEX(table_share_));
|
||||
}
|
||||
}
|
||||
|
||||
AutoIncrementValueLock::~AutoIncrementValueLock() {
|
||||
if (need_lock_) {
|
||||
mysql_mutex_unlock(AUTO_INCREMENT_VALUE_MUTEX(table_share_));
|
||||
}
|
||||
}
|
||||
}
|
||||
36
storage/mroonga/lib/mrn_auto_increment_value_lock.hpp
Normal file
36
storage/mroonga/lib/mrn_auto_increment_value_lock.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_AUTO_INCREMENT_VALUE_LOCK_HPP_
|
||||
#define MRN_AUTO_INCREMENT_VALUE_LOCK_HPP_
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
class AutoIncrementValueLock {
|
||||
TABLE_SHARE *table_share_;
|
||||
bool need_lock_;
|
||||
public:
|
||||
AutoIncrementValueLock(TABLE_SHARE *table_share);
|
||||
~AutoIncrementValueLock();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MRN_AUTO_INCREMENT_VALUE_LOCK_HPP_
|
||||
608
storage/mroonga/lib/mrn_condition_converter.cpp
Normal file
608
storage/mroonga/lib/mrn_condition_converter.cpp
Normal file
|
|
@ -0,0 +1,608 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013-2014 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "mrn_condition_converter.hpp"
|
||||
#include "mrn_time_converter.hpp"
|
||||
#include "mrn_smart_grn_obj.hpp"
|
||||
|
||||
// for debug
|
||||
#define MRN_CLASS_NAME "mrn::ConditionConverter"
|
||||
|
||||
#ifdef MRN_ITEM_HAVE_ITEM_NAME
|
||||
# define MRN_ITEM_FIELD_GET_NAME(item) ((item)->item_name.ptr())
|
||||
# define MRN_ITEM_FIELD_GET_NAME_LENGTH(item) ((item)->item_name.length())
|
||||
#else
|
||||
# define MRN_ITEM_FIELD_GET_NAME(item) ((item)->name)
|
||||
# define MRN_ITEM_FIELD_GET_NAME_LENGTH(item) (strlen((item)->name))
|
||||
#endif
|
||||
|
||||
namespace mrn {
|
||||
ConditionConverter::ConditionConverter(grn_ctx *ctx, grn_obj *table,
|
||||
bool is_storage_mode)
|
||||
: ctx_(ctx),
|
||||
table_(table),
|
||||
is_storage_mode_(is_storage_mode) {
|
||||
GRN_TEXT_INIT(&column_name_, 0);
|
||||
GRN_VOID_INIT(&value_);
|
||||
}
|
||||
|
||||
ConditionConverter::~ConditionConverter() {
|
||||
grn_obj_unlink(ctx_, &column_name_);
|
||||
grn_obj_unlink(ctx_, &value_);
|
||||
}
|
||||
|
||||
bool ConditionConverter::is_convertable(const Item *item) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
if (!item) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
switch (item->type()) {
|
||||
case Item::COND_ITEM:
|
||||
{
|
||||
const Item_cond *cond_item = reinterpret_cast<const Item_cond *>(item);
|
||||
bool convertable = is_convertable(cond_item);
|
||||
DBUG_RETURN(convertable);
|
||||
}
|
||||
break;
|
||||
case Item::FUNC_ITEM:
|
||||
{
|
||||
const Item_func *func_item = reinterpret_cast<const Item_func *>(item);
|
||||
bool convertable = is_convertable(func_item);
|
||||
DBUG_RETURN(convertable);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DBUG_RETURN(false);
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
bool ConditionConverter::is_convertable(const Item_cond *cond_item) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
if (!is_storage_mode_) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
if (cond_item->functype() != Item_func::COND_AND_FUNC) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
List<Item> *argument_list =
|
||||
const_cast<Item_cond *>(cond_item)->argument_list();
|
||||
List_iterator<Item> iterator(*argument_list);
|
||||
const Item *sub_item;
|
||||
while ((sub_item = iterator++)) {
|
||||
if (!is_convertable(sub_item)) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
bool ConditionConverter::is_convertable(const Item_func *func_item) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
switch (func_item->functype()) {
|
||||
case Item_func::EQ_FUNC:
|
||||
case Item_func::LT_FUNC:
|
||||
case Item_func::LE_FUNC:
|
||||
case Item_func::GE_FUNC:
|
||||
case Item_func::GT_FUNC:
|
||||
if (!is_storage_mode_) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
{
|
||||
Item **arguments = func_item->arguments();
|
||||
Item *left_item = arguments[0];
|
||||
Item *right_item = arguments[1];
|
||||
if (left_item->type() != Item::FIELD_ITEM) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
if (!right_item->basic_const_item()) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
bool convertable =
|
||||
is_convertable_binary_operation(static_cast<Item_field *>(left_item),
|
||||
right_item,
|
||||
func_item->functype());
|
||||
DBUG_RETURN(convertable);
|
||||
}
|
||||
break;
|
||||
case Item_func::FT_FUNC:
|
||||
DBUG_RETURN(true);
|
||||
break;
|
||||
case Item_func::BETWEEN:
|
||||
if (!is_storage_mode_) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
{
|
||||
Item **arguments = func_item->arguments();
|
||||
Item *target_item = arguments[0];
|
||||
Item *min_item = arguments[1];
|
||||
Item *max_item = arguments[2];
|
||||
if (target_item->type() != Item::FIELD_ITEM) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
if (!min_item->basic_const_item()) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
if (!max_item->basic_const_item()) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
bool convertable =
|
||||
is_convertable_between(static_cast<Item_field *>(target_item),
|
||||
min_item,
|
||||
max_item);
|
||||
DBUG_RETURN(convertable);
|
||||
}
|
||||
default:
|
||||
DBUG_RETURN(false);
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
bool ConditionConverter::is_convertable_binary_operation(
|
||||
const Item_field *field_item,
|
||||
Item *value_item,
|
||||
Item_func::Functype func_type) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
bool convertable = false;
|
||||
|
||||
enum_field_types field_type = field_item->field_type();
|
||||
NormalizedType normalized_type = normalize_field_type(field_type);
|
||||
switch (normalized_type) {
|
||||
case STRING_TYPE:
|
||||
if (value_item->type() == Item::STRING_ITEM &&
|
||||
func_type == Item_func::EQ_FUNC) {
|
||||
convertable = have_index(field_item, GRN_OP_EQUAL);
|
||||
}
|
||||
break;
|
||||
case INT_TYPE:
|
||||
convertable = value_item->type() == Item::INT_ITEM;
|
||||
break;
|
||||
case TIME_TYPE:
|
||||
if (is_valid_time_value(field_item, value_item)) {
|
||||
convertable = have_index(field_item, func_type);
|
||||
}
|
||||
break;
|
||||
case UNSUPPORTED_TYPE:
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(convertable);
|
||||
}
|
||||
|
||||
bool ConditionConverter::is_convertable_between(const Item_field *field_item,
|
||||
Item *min_item,
|
||||
Item *max_item) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
bool convertable = false;
|
||||
|
||||
enum_field_types field_type = field_item->field_type();
|
||||
NormalizedType normalized_type = normalize_field_type(field_type);
|
||||
switch (normalized_type) {
|
||||
case STRING_TYPE:
|
||||
if (min_item->type() == Item::STRING_ITEM &&
|
||||
max_item->type() == Item::STRING_ITEM) {
|
||||
convertable = have_index(field_item, GRN_OP_LESS);
|
||||
}
|
||||
break;
|
||||
case INT_TYPE:
|
||||
if (min_item->type() == Item::INT_ITEM &&
|
||||
max_item->type() == Item::INT_ITEM) {
|
||||
convertable = have_index(field_item, GRN_OP_LESS);
|
||||
}
|
||||
break;
|
||||
case TIME_TYPE:
|
||||
if (is_valid_time_value(field_item, min_item) &&
|
||||
is_valid_time_value(field_item, max_item)) {
|
||||
convertable = have_index(field_item, GRN_OP_LESS);
|
||||
}
|
||||
break;
|
||||
case UNSUPPORTED_TYPE:
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(convertable);
|
||||
}
|
||||
|
||||
bool ConditionConverter::is_valid_time_value(const Item_field *field_item,
|
||||
Item *value_item) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
MYSQL_TIME mysql_time;
|
||||
bool error = get_time_value(field_item, value_item, &mysql_time);
|
||||
|
||||
DBUG_RETURN(!error);
|
||||
}
|
||||
|
||||
bool ConditionConverter::get_time_value(const Item_field *field_item,
|
||||
Item *value_item,
|
||||
MYSQL_TIME *mysql_time) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
bool error;
|
||||
Item *real_value_item = value_item->real_item();
|
||||
switch (field_item->field_type()) {
|
||||
case MYSQL_TYPE_TIME:
|
||||
error = real_value_item->get_time(mysql_time);
|
||||
break;
|
||||
case MYSQL_TYPE_YEAR:
|
||||
mysql_time->year = static_cast<int>(value_item->val_int());
|
||||
mysql_time->month = 1;
|
||||
mysql_time->day = 1;
|
||||
mysql_time->hour = 0;
|
||||
mysql_time->hour = 0;
|
||||
mysql_time->minute = 0;
|
||||
mysql_time->second_part = 0;
|
||||
mysql_time->neg = false;
|
||||
mysql_time->time_type = MYSQL_TIMESTAMP_DATE;
|
||||
error = false;
|
||||
break;
|
||||
default:
|
||||
error = real_value_item->get_date(mysql_time, TIME_FUZZY_DATE);
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
ConditionConverter::NormalizedType
|
||||
ConditionConverter::normalize_field_type(enum_field_types field_type) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
NormalizedType type = UNSUPPORTED_TYPE;
|
||||
|
||||
switch (field_type) {
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
type = STRING_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_LONG:
|
||||
type = INT_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
type = UNSUPPORTED_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_NULL:
|
||||
type = UNSUPPORTED_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
type = TIME_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
case MYSQL_TYPE_INT24:
|
||||
type = INT_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_TIME:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_YEAR:
|
||||
case MYSQL_TYPE_NEWDATE:
|
||||
type = TIME_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
type = STRING_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_BIT:
|
||||
type = INT_TYPE;
|
||||
break;
|
||||
#ifdef MRN_HAVE_MYSQL_TYPE_TIMESTAMP2
|
||||
case MYSQL_TYPE_TIMESTAMP2:
|
||||
type = TIME_TYPE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
|
||||
case MYSQL_TYPE_DATETIME2:
|
||||
type = TIME_TYPE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef MRN_HAVE_MYSQL_TYPE_TIME2
|
||||
case MYSQL_TYPE_TIME2:
|
||||
type = TIME_TYPE;
|
||||
break;
|
||||
#endif
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
type = STRING_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_ENUM:
|
||||
type = INT_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_SET:
|
||||
type = INT_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
type = STRING_TYPE;
|
||||
break;
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
type = UNSUPPORTED_TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(type);
|
||||
}
|
||||
|
||||
bool ConditionConverter::have_index(const Item_field *field_item,
|
||||
grn_operator _operator) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
grn_obj *column;
|
||||
column = grn_obj_column(ctx_, table_,
|
||||
MRN_ITEM_FIELD_GET_NAME(field_item),
|
||||
MRN_ITEM_FIELD_GET_NAME_LENGTH(field_item));
|
||||
if (!column) {
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
mrn::SmartGrnObj smart_column(ctx_, column);
|
||||
|
||||
int n_indexes = grn_column_index(ctx_, column, _operator, NULL, 0, NULL);
|
||||
bool convertable = (n_indexes > 0);
|
||||
|
||||
DBUG_RETURN(convertable);
|
||||
}
|
||||
|
||||
bool ConditionConverter::have_index(const Item_field *field_item,
|
||||
Item_func::Functype func_type) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
bool have = false;
|
||||
switch (func_type) {
|
||||
case Item_func::EQ_FUNC:
|
||||
have = have_index(field_item, GRN_OP_EQUAL);
|
||||
break;
|
||||
case Item_func::LT_FUNC:
|
||||
have = have_index(field_item, GRN_OP_LESS);
|
||||
break;
|
||||
case Item_func::LE_FUNC:
|
||||
have = have_index(field_item, GRN_OP_LESS_EQUAL);
|
||||
break;
|
||||
case Item_func::GE_FUNC:
|
||||
have = have_index(field_item, GRN_OP_GREATER_EQUAL);
|
||||
break;
|
||||
case Item_func::GT_FUNC:
|
||||
have = have_index(field_item, GRN_OP_GREATER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(have);
|
||||
}
|
||||
|
||||
const Item_func *ConditionConverter::find_match_against(const Item *item) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
if (!item) {
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
switch (item->type()) {
|
||||
case Item::COND_ITEM:
|
||||
if (is_storage_mode_) {
|
||||
Item_cond *cond_item = (Item_cond *)item;
|
||||
if (cond_item->functype() == Item_func::COND_AND_FUNC) {
|
||||
List_iterator<Item> iterator(*((cond_item)->argument_list()));
|
||||
const Item *sub_item;
|
||||
while ((sub_item = iterator++)) {
|
||||
const Item_func *match_against = find_match_against(sub_item);
|
||||
if (match_against) {
|
||||
DBUG_RETURN(match_against);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Item::FUNC_ITEM:
|
||||
{
|
||||
const Item_func *func_item = (const Item_func *)item;
|
||||
switch (func_item->functype()) {
|
||||
case Item_func::FT_FUNC:
|
||||
DBUG_RETURN(func_item);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
void ConditionConverter::convert(const Item *where, grn_obj *expression) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
if (!where || where->type() != Item::COND_ITEM) {
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
Item_cond *cond_item = (Item_cond *)where;
|
||||
List_iterator<Item> iterator(*((cond_item)->argument_list()));
|
||||
const Item *sub_item;
|
||||
while ((sub_item = iterator++)) {
|
||||
switch (sub_item->type()) {
|
||||
case Item::FUNC_ITEM:
|
||||
{
|
||||
const Item_func *func_item = (const Item_func *)sub_item;
|
||||
switch (func_item->functype()) {
|
||||
case Item_func::EQ_FUNC:
|
||||
convert_binary_operation(func_item, expression, GRN_OP_EQUAL);
|
||||
break;
|
||||
case Item_func::LT_FUNC:
|
||||
convert_binary_operation(func_item, expression, GRN_OP_LESS);
|
||||
break;
|
||||
case Item_func::LE_FUNC:
|
||||
convert_binary_operation(func_item, expression, GRN_OP_LESS_EQUAL);
|
||||
break;
|
||||
case Item_func::GE_FUNC:
|
||||
convert_binary_operation(func_item, expression,
|
||||
GRN_OP_GREATER_EQUAL);
|
||||
break;
|
||||
case Item_func::GT_FUNC:
|
||||
convert_binary_operation(func_item, expression, GRN_OP_GREATER);
|
||||
break;
|
||||
case Item_func::BETWEEN:
|
||||
convert_between(func_item, expression);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void ConditionConverter::convert_binary_operation(const Item_func *func_item,
|
||||
grn_obj *expression,
|
||||
grn_operator _operator) {
|
||||
Item **arguments = func_item->arguments();
|
||||
Item *left_item = arguments[0];
|
||||
Item *right_item = arguments[1];
|
||||
if (left_item->type() == Item::FIELD_ITEM) {
|
||||
const Item_field *field_item = static_cast<const Item_field *>(left_item);
|
||||
append_field_value(field_item, expression);
|
||||
append_const_item(field_item, right_item, expression);
|
||||
grn_expr_append_op(ctx_, expression, _operator, 2);
|
||||
grn_expr_append_op(ctx_, expression, GRN_OP_AND, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void ConditionConverter::convert_between(const Item_func *func_item,
|
||||
grn_obj *expression) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
Item **arguments = func_item->arguments();
|
||||
Item *target_item = arguments[0];
|
||||
Item *min_item = arguments[1];
|
||||
Item *max_item = arguments[2];
|
||||
|
||||
grn_obj *between_func = grn_ctx_get(ctx_, "between", strlen("between"));
|
||||
grn_expr_append_obj(ctx_, expression, between_func, GRN_OP_PUSH, 1);
|
||||
|
||||
const Item_field *field_item = static_cast<const Item_field *>(target_item);
|
||||
append_field_value(field_item, expression);
|
||||
|
||||
grn_obj include;
|
||||
mrn::SmartGrnObj smart_include(ctx_, &include);
|
||||
GRN_TEXT_INIT(&include, 0);
|
||||
GRN_TEXT_PUTS(ctx_, &include, "include");
|
||||
append_const_item(field_item, min_item, expression);
|
||||
grn_expr_append_const(ctx_, expression, &include, GRN_OP_PUSH, 1);
|
||||
append_const_item(field_item, max_item, expression);
|
||||
grn_expr_append_const(ctx_, expression, &include, GRN_OP_PUSH, 1);
|
||||
|
||||
grn_expr_append_op(ctx_, expression, GRN_OP_CALL, 5);
|
||||
|
||||
grn_expr_append_op(ctx_, expression, GRN_OP_AND, 2);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void ConditionConverter::append_field_value(const Item_field *field_item,
|
||||
grn_obj *expression) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
GRN_BULK_REWIND(&column_name_);
|
||||
GRN_TEXT_PUT(ctx_, &column_name_,
|
||||
MRN_ITEM_FIELD_GET_NAME(field_item),
|
||||
MRN_ITEM_FIELD_GET_NAME_LENGTH(field_item));
|
||||
grn_expr_append_const(ctx_, expression, &column_name_,
|
||||
GRN_OP_PUSH, 1);
|
||||
grn_expr_append_op(ctx_, expression, GRN_OP_GET_VALUE, 1);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void ConditionConverter::append_const_item(const Item_field *field_item,
|
||||
Item *const_item,
|
||||
grn_obj *expression) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
enum_field_types field_type = field_item->field_type();
|
||||
NormalizedType normalized_type = normalize_field_type(field_type);
|
||||
|
||||
switch (normalized_type) {
|
||||
case STRING_TYPE:
|
||||
grn_obj_reinit(ctx_, &value_, GRN_DB_TEXT, 0);
|
||||
{
|
||||
String *string;
|
||||
string = const_item->val_str(NULL);
|
||||
GRN_TEXT_SET(ctx_, &value_, string->ptr(), string->length());
|
||||
}
|
||||
break;
|
||||
case INT_TYPE:
|
||||
grn_obj_reinit(ctx_, &value_, GRN_DB_INT64, 0);
|
||||
GRN_INT64_SET(ctx_, &value_, const_item->val_int());
|
||||
break;
|
||||
case TIME_TYPE:
|
||||
grn_obj_reinit(ctx_, &value_, GRN_DB_TIME, 0);
|
||||
{
|
||||
MYSQL_TIME mysql_time;
|
||||
get_time_value(field_item, const_item, &mysql_time);
|
||||
bool truncated = false;
|
||||
TimeConverter time_converter;
|
||||
long long int time =
|
||||
time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
|
||||
GRN_TIME_SET(ctx_, &value_, time);
|
||||
}
|
||||
break;
|
||||
case UNSUPPORTED_TYPE:
|
||||
// Should not be occurred.
|
||||
DBUG_PRINT("error",
|
||||
("mroonga: append_const_item: unsupported type: <%d> "
|
||||
"This case should not be occurred.",
|
||||
field_type));
|
||||
grn_obj_reinit(ctx_, &value_, GRN_DB_VOID, 0);
|
||||
break;
|
||||
}
|
||||
grn_expr_append_const(ctx_, expression, &value_, GRN_OP_PUSH, 1);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
82
storage/mroonga/lib/mrn_condition_converter.hpp
Normal file
82
storage/mroonga/lib/mrn_condition_converter.hpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_CONDITION_CONVERTER_HPP_
|
||||
#define MRN_CONDITION_CONVERTER_HPP_
|
||||
|
||||
#include <groonga.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
class ConditionConverter {
|
||||
public:
|
||||
ConditionConverter(grn_ctx *ctx, grn_obj *table, bool is_storage_mode);
|
||||
~ConditionConverter();
|
||||
|
||||
bool is_convertable(const Item *item);
|
||||
const Item_func *find_match_against(const Item *item);
|
||||
// caller must check "where" can be convertable by
|
||||
// is_convertable(). This method doesn't validate "where".
|
||||
void convert(const Item *where, grn_obj *expression);
|
||||
|
||||
private:
|
||||
enum NormalizedType {
|
||||
STRING_TYPE,
|
||||
INT_TYPE,
|
||||
TIME_TYPE,
|
||||
UNSUPPORTED_TYPE,
|
||||
};
|
||||
|
||||
grn_ctx *ctx_;
|
||||
grn_obj *table_;
|
||||
bool is_storage_mode_;
|
||||
grn_obj column_name_;
|
||||
grn_obj value_;
|
||||
|
||||
bool is_convertable(const Item_cond *cond_item);
|
||||
bool is_convertable(const Item_func *func_item);
|
||||
bool is_convertable_binary_operation(const Item_field *field_item,
|
||||
Item *value_item,
|
||||
Item_func::Functype func_type);
|
||||
bool is_convertable_between(const Item_field *field_item,
|
||||
Item *min_item,
|
||||
Item *max_item);
|
||||
bool is_valid_time_value(const Item_field *field_item,
|
||||
Item *value_item);
|
||||
bool get_time_value(const Item_field *field_item,
|
||||
Item *value_item,
|
||||
MYSQL_TIME *mysql_time);
|
||||
bool have_index(const Item_field *field_item, grn_operator _operator);
|
||||
bool have_index(const Item_field *field_item, Item_func::Functype func_type);
|
||||
|
||||
NormalizedType normalize_field_type(enum_field_types field_type);
|
||||
|
||||
void convert_binary_operation(const Item_func *func_item,
|
||||
grn_obj *expression,
|
||||
grn_operator _operator);
|
||||
void convert_between(const Item_func *func_item, grn_obj *expression);
|
||||
void append_field_value(const Item_field *field_item,
|
||||
grn_obj *expression);
|
||||
void append_const_item(const Item_field *field_item,
|
||||
Item *const_item,
|
||||
grn_obj *expression);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MRN_CONDITION_CONVERTER_HPP_ */
|
||||
36
storage/mroonga/lib/mrn_debug_column_access.cpp
Normal file
36
storage/mroonga/lib/mrn_debug_column_access.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mrn_debug_column_access.hpp"
|
||||
|
||||
namespace mrn {
|
||||
DebugColumnAccess::DebugColumnAccess(TABLE *table, MY_BITMAP *bitmap)
|
||||
: table_(table),
|
||||
bitmap_(bitmap) {
|
||||
#ifndef DBUG_OFF
|
||||
map_ = dbug_tmp_use_all_columns(table_, bitmap_);
|
||||
#endif
|
||||
}
|
||||
|
||||
DebugColumnAccess::~DebugColumnAccess() {
|
||||
#ifndef DBUG_OFF
|
||||
dbug_tmp_restore_column_map(bitmap_, map_);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
38
storage/mroonga/lib/mrn_debug_column_access.hpp
Normal file
38
storage/mroonga/lib/mrn_debug_column_access.hpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_DEBUG_COLUMN_ACCESS_HPP_
|
||||
#define MRN_DEBUG_COLUMN_ACCESS_HPP_
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
|
||||
namespace mrn {
|
||||
class DebugColumnAccess {
|
||||
TABLE *table_;
|
||||
MY_BITMAP *bitmap_;
|
||||
#ifndef DBUG_OFF
|
||||
my_bitmap_map *map_;
|
||||
#endif
|
||||
public:
|
||||
DebugColumnAccess(TABLE *table, MY_BITMAP *bitmap);
|
||||
~DebugColumnAccess();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MRN_DEBUG_COLUMN_ACCESS_HPP_
|
||||
222
storage/mroonga/lib/mrn_encoding.cpp
Normal file
222
storage/mroonga/lib/mrn_encoding.cpp
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
|
||||
Copyright(C) 2011-2013 Kentoku SHIBA
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <mrn_err.h>
|
||||
#include "mrn_encoding.hpp"
|
||||
|
||||
namespace mrn {
|
||||
namespace encoding {
|
||||
CHARSET_INFO *mrn_charset_utf8 = NULL;
|
||||
CHARSET_INFO *mrn_charset_utf8mb4 = NULL;
|
||||
CHARSET_INFO *mrn_charset_binary = NULL;
|
||||
CHARSET_INFO *mrn_charset_ascii = NULL;
|
||||
CHARSET_INFO *mrn_charset_latin1_1 = NULL;
|
||||
CHARSET_INFO *mrn_charset_latin1_2 = NULL;
|
||||
CHARSET_INFO *mrn_charset_cp932 = NULL;
|
||||
CHARSET_INFO *mrn_charset_sjis = NULL;
|
||||
CHARSET_INFO *mrn_charset_eucjpms = NULL;
|
||||
CHARSET_INFO *mrn_charset_ujis = NULL;
|
||||
CHARSET_INFO *mrn_charset_koi8r = NULL;
|
||||
|
||||
void init(void) {
|
||||
CHARSET_INFO **cs;
|
||||
MRN_DBUG_ENTER_FUNCTION();
|
||||
for (cs = all_charsets; cs < all_charsets + MY_ALL_CHARSETS_SIZE; cs++)
|
||||
{
|
||||
if (!cs[0])
|
||||
continue;
|
||||
if (!strcmp(cs[0]->csname, "utf8"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_utf8)
|
||||
mrn_charset_utf8 = cs[0];
|
||||
else if (mrn_charset_utf8->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "utf8mb4"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_utf8mb4)
|
||||
mrn_charset_utf8mb4 = cs[0];
|
||||
else if (mrn_charset_utf8mb4->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "binary"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_binary)
|
||||
mrn_charset_binary = cs[0];
|
||||
else if (mrn_charset_binary->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "ascii"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_ascii)
|
||||
mrn_charset_ascii = cs[0];
|
||||
else if (mrn_charset_ascii->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "latin1"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_latin1_1)
|
||||
mrn_charset_latin1_1 = cs[0];
|
||||
else if (mrn_charset_latin1_1->cset != cs[0]->cset)
|
||||
{
|
||||
if (!mrn_charset_latin1_2)
|
||||
mrn_charset_latin1_2 = cs[0];
|
||||
else if (mrn_charset_latin1_2->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "cp932"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_cp932)
|
||||
mrn_charset_cp932 = cs[0];
|
||||
else if (mrn_charset_cp932->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "sjis"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_sjis)
|
||||
mrn_charset_sjis = cs[0];
|
||||
else if (mrn_charset_sjis->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "eucjpms"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_eucjpms)
|
||||
mrn_charset_eucjpms = cs[0];
|
||||
else if (mrn_charset_eucjpms->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "ujis"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_ujis)
|
||||
mrn_charset_ujis = cs[0];
|
||||
else if (mrn_charset_ujis->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cs[0]->csname, "koi8r"))
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: %s is %s [%p]",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
if (!mrn_charset_koi8r)
|
||||
mrn_charset_koi8r = cs[0];
|
||||
else if (mrn_charset_koi8r->cset != cs[0]->cset)
|
||||
DBUG_ASSERT(0);
|
||||
continue;
|
||||
}
|
||||
DBUG_PRINT("info", ("mroonga: %s[%s][%p] is not supported",
|
||||
cs[0]->name, cs[0]->csname, cs[0]->cset));
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
bool set(grn_ctx *ctx, const CHARSET_INFO *charset) {
|
||||
MRN_DBUG_ENTER_FUNCTION();
|
||||
if (!charset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_NONE);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_utf8->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_UTF8);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (mrn_charset_utf8mb4 && charset->cset == mrn_charset_utf8mb4->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_UTF8);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_cp932->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_SJIS);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_eucjpms->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_EUC_JP);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_latin1_1->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_LATIN1);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_latin1_2->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_LATIN1);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_koi8r->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_KOI8R);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_binary->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_NONE);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_ascii->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_UTF8);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_sjis->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_SJIS);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
if (charset->cset == mrn_charset_ujis->cset)
|
||||
{
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_EUC_JP);
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
GRN_CTX_SET_ENCODING(ctx, GRN_ENC_NONE);
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
storage/mroonga/lib/mrn_encoding.hpp
Normal file
35
storage/mroonga/lib/mrn_encoding.hpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_ENCODING_HPP_
|
||||
#define MRN_ENCODING_HPP_
|
||||
|
||||
#include <groonga.h>
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
namespace encoding {
|
||||
void init(void);
|
||||
bool set(grn_ctx *ctx, const CHARSET_INFO *charset);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MRN_ENCODING_HPP_
|
||||
43
storage/mroonga/lib/mrn_external_lock.cpp
Normal file
43
storage/mroonga/lib/mrn_external_lock.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kentoku SHIBA
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mrn_external_lock.hpp"
|
||||
|
||||
namespace mrn {
|
||||
ExternalLock::ExternalLock(THD *thd, handler *handler, int lock_type)
|
||||
: thd_(thd),
|
||||
handler_(handler),
|
||||
lock_type_(lock_type) {
|
||||
if (lock_type_ != F_UNLCK) {
|
||||
error_ = handler_->ha_external_lock(thd_, lock_type);
|
||||
} else {
|
||||
error_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ExternalLock::~ExternalLock() {
|
||||
if (lock_type_ != F_UNLCK) {
|
||||
handler_->ha_external_lock(thd_, F_UNLCK);
|
||||
}
|
||||
}
|
||||
|
||||
int ExternalLock::error() {
|
||||
return error_;
|
||||
}
|
||||
}
|
||||
38
storage/mroonga/lib/mrn_external_lock.hpp
Normal file
38
storage/mroonga/lib/mrn_external_lock.hpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kentoku SHIBA
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_EXTERNAL_LOCK_HPP_
|
||||
#define MRN_EXTERNAL_LOCK_HPP_
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
|
||||
namespace mrn {
|
||||
class ExternalLock {
|
||||
THD *thd_;
|
||||
handler *handler_;
|
||||
int lock_type_;
|
||||
int error_;
|
||||
public:
|
||||
ExternalLock(THD *thd, handler *handler, int lock_type);
|
||||
~ExternalLock();
|
||||
int error();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MRN_EXTERNAL_LOCK_HPP_
|
||||
142
storage/mroonga/lib/mrn_field_normalizer.cpp
Normal file
142
storage/mroonga/lib/mrn_field_normalizer.cpp
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mrn_field_normalizer.hpp"
|
||||
#include "mrn_encoding.hpp"
|
||||
|
||||
// for debug
|
||||
#define MRN_CLASS_NAME "mrn::FieldNormalizer"
|
||||
|
||||
namespace mrn {
|
||||
FieldNormalizer::FieldNormalizer(grn_ctx *ctx, THD *thread, Field *field)
|
||||
: ctx_(ctx),
|
||||
thread_(thread),
|
||||
field_(field) {
|
||||
}
|
||||
|
||||
FieldNormalizer::~FieldNormalizer() {
|
||||
}
|
||||
|
||||
bool FieldNormalizer::should_normalize() {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
DBUG_PRINT("info",
|
||||
("mroonga: result_type = %u", field_->result_type()));
|
||||
DBUG_PRINT("info",
|
||||
("mroonga: charset->name = %s", field_->charset()->name));
|
||||
DBUG_PRINT("info",
|
||||
("mroonga: charset->csname = %s", field_->charset()->csname));
|
||||
DBUG_PRINT("info",
|
||||
("mroonga: charset->state = %u", field_->charset()->state));
|
||||
bool need_normalize_p;
|
||||
if (field_->charset()->state & (MY_CS_BINSORT | MY_CS_CSSORT)) {
|
||||
need_normalize_p = false;
|
||||
DBUG_PRINT("info",
|
||||
("mroonga: should_normalize: false: sort is required"));
|
||||
} else {
|
||||
if (is_text_type()) {
|
||||
need_normalize_p = true;
|
||||
DBUG_PRINT("info", ("mroonga: should_normalize: true: text type"));
|
||||
} else {
|
||||
need_normalize_p = false;
|
||||
DBUG_PRINT("info", ("mroonga: should_normalize: false: no text type"));
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(need_normalize_p);
|
||||
}
|
||||
|
||||
bool FieldNormalizer::is_text_type() {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
bool text_type_p;
|
||||
switch (field_->type()) {
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
text_type_p = true;
|
||||
break;
|
||||
case MYSQL_TYPE_STRING:
|
||||
switch (field_->real_type()) {
|
||||
case MYSQL_TYPE_ENUM:
|
||||
case MYSQL_TYPE_SET:
|
||||
text_type_p = false;
|
||||
break;
|
||||
default:
|
||||
text_type_p = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
text_type_p = false;
|
||||
break;
|
||||
}
|
||||
DBUG_RETURN(text_type_p);
|
||||
}
|
||||
|
||||
grn_obj *FieldNormalizer::normalize(const char *string,
|
||||
unsigned int string_length) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
grn_obj *normalizer = find_grn_normalizer();
|
||||
int flags = 0;
|
||||
grn_encoding original_encoding = GRN_CTX_GET_ENCODING(ctx_);
|
||||
encoding::set(ctx_, field_->charset());
|
||||
grn_obj *grn_string = grn_string_open(ctx_, string, string_length,
|
||||
normalizer, flags);
|
||||
GRN_CTX_SET_ENCODING(ctx_, original_encoding);
|
||||
DBUG_RETURN(grn_string);
|
||||
}
|
||||
|
||||
grn_obj *FieldNormalizer::find_grn_normalizer() {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
const CHARSET_INFO *charset_info = field_->charset();
|
||||
const char *normalizer_name = NULL;
|
||||
const char *default_normalizer_name = "NormalizerAuto";
|
||||
if ((strcmp(charset_info->name, "utf8_general_ci") == 0) ||
|
||||
(strcmp(charset_info->name, "utf8mb4_general_ci") == 0)) {
|
||||
normalizer_name = "NormalizerMySQLGeneralCI";
|
||||
} else if ((strcmp(charset_info->name, "utf8_unicode_ci") == 0) ||
|
||||
(strcmp(charset_info->name, "utf8mb4_unicode_ci") == 0)) {
|
||||
normalizer_name = "NormalizerMySQLUnicodeCI";
|
||||
}
|
||||
|
||||
grn_obj *normalizer = NULL;
|
||||
if (normalizer_name) {
|
||||
normalizer = grn_ctx_get(ctx_, normalizer_name, -1);
|
||||
if (!normalizer) {
|
||||
char error_message[MRN_MESSAGE_BUFFER_SIZE];
|
||||
snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE,
|
||||
"%s normalizer isn't found for %s. "
|
||||
"Install groonga-normalizer-mysql normalizer. "
|
||||
"%s is used as fallback.",
|
||||
normalizer_name,
|
||||
charset_info->name,
|
||||
default_normalizer_name);
|
||||
push_warning(thread_, Sql_condition::WARN_LEVEL_WARN,
|
||||
HA_ERR_UNSUPPORTED, error_message);
|
||||
}
|
||||
}
|
||||
|
||||
if (!normalizer) {
|
||||
normalizer = grn_ctx_get(ctx_, default_normalizer_name, -1);
|
||||
}
|
||||
|
||||
DBUG_RETURN(normalizer);
|
||||
}
|
||||
}
|
||||
47
storage/mroonga/lib/mrn_field_normalizer.hpp
Normal file
47
storage/mroonga/lib/mrn_field_normalizer.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_FIELD_NORMALIZER_HPP_
|
||||
#define MRN_FIELD_NORMALIZER_HPP_
|
||||
|
||||
#include <groonga.h>
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
class FieldNormalizer {
|
||||
public:
|
||||
FieldNormalizer(grn_ctx *ctx, THD *thread, Field *field);
|
||||
~FieldNormalizer();
|
||||
|
||||
bool should_normalize();
|
||||
grn_obj *normalize(const char *string, unsigned int string_length);
|
||||
grn_obj *find_grn_normalizer();
|
||||
|
||||
private:
|
||||
grn_ctx *ctx_;
|
||||
THD *thread_;
|
||||
Field *field_;
|
||||
|
||||
bool is_text_type();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MRN_FIELD_NORMALIZER_HPP_
|
||||
96
storage/mroonga/lib/mrn_index_column_name.cpp
Normal file
96
storage/mroonga/lib/mrn_index_column_name.cpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2011-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
|
||||
#include "mrn_index_column_name.hpp"
|
||||
|
||||
#define MRN_MIN_INDEX_COLUMN_NAME_LENGTH 65
|
||||
|
||||
// for debug
|
||||
#define MRN_CLASS_NAME "mrn::IndexColumnName"
|
||||
|
||||
namespace mrn {
|
||||
IndexColumnName::IndexColumnName(const char *table_name,
|
||||
const char *mysql_column_name)
|
||||
: table_name_(table_name),
|
||||
mysql_column_name_(mysql_column_name) {
|
||||
uchar encoded_mysql_column_name_multibyte[MRN_MAX_KEY_SIZE];
|
||||
const uchar *mysql_column_name_multibyte =
|
||||
reinterpret_cast<const uchar *>(mysql_column_name_);
|
||||
encode(encoded_mysql_column_name_multibyte,
|
||||
encoded_mysql_column_name_multibyte + MRN_MAX_KEY_SIZE,
|
||||
mysql_column_name_multibyte,
|
||||
mysql_column_name_multibyte + strlen(mysql_column_name_));
|
||||
snprintf(name_, MRN_MAX_KEY_SIZE,
|
||||
"%s-%s", table_name_, encoded_mysql_column_name_multibyte);
|
||||
length_ = strlen(name_);
|
||||
if (length_ < MRN_MIN_INDEX_COLUMN_NAME_LENGTH) {
|
||||
memset(name_ + length_, '-', MRN_MIN_INDEX_COLUMN_NAME_LENGTH - length_);
|
||||
length_ = MRN_MIN_INDEX_COLUMN_NAME_LENGTH;
|
||||
name_[length_] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
const char *IndexColumnName::c_str() {
|
||||
return name_;
|
||||
}
|
||||
|
||||
size_t IndexColumnName::length() {
|
||||
return length_;
|
||||
}
|
||||
|
||||
uint IndexColumnName::encode(uchar *encoded_start,
|
||||
uchar *encoded_end,
|
||||
const uchar *mysql_string_start,
|
||||
const uchar *mysql_string_end) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
my_charset_conv_mb_wc mb_wc = system_charset_info->cset->mb_wc;
|
||||
my_charset_conv_wc_mb wc_mb = my_charset_filename.cset->wc_mb;
|
||||
DBUG_PRINT("info", ("mroonga: in=%s", mysql_string_start));
|
||||
encoded_end--;
|
||||
uchar *encoded = encoded_start;
|
||||
const uchar *mysql_string = mysql_string_start;
|
||||
while (mysql_string < mysql_string_end && encoded < encoded_end) {
|
||||
my_wc_t wc;
|
||||
int mb_wc_converted_length;
|
||||
int wc_mb_converted_length;
|
||||
mb_wc_converted_length =
|
||||
(*mb_wc)(NULL, &wc, mysql_string, mysql_string_end);
|
||||
if (mb_wc_converted_length > 0) {
|
||||
wc_mb_converted_length = (*wc_mb)(NULL, wc, encoded, encoded_end);
|
||||
if (wc_mb_converted_length <= 0) {
|
||||
break;
|
||||
}
|
||||
} else if (mb_wc_converted_length == MY_CS_ILSEQ) {
|
||||
*encoded = *mysql_string;
|
||||
mb_wc_converted_length = 1;
|
||||
wc_mb_converted_length = 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
mysql_string += mb_wc_converted_length;
|
||||
encoded += wc_mb_converted_length;
|
||||
}
|
||||
*encoded = '\0';
|
||||
DBUG_PRINT("info", ("mroonga: out=%s", encoded_start));
|
||||
DBUG_RETURN(encoded - encoded_start);
|
||||
}
|
||||
}
|
||||
43
storage/mroonga/lib/mrn_index_column_name.hpp
Normal file
43
storage/mroonga/lib/mrn_index_column_name.hpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2011-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_INDEX_COLUMN_NAME_HPP_
|
||||
#define MRN_INDEX_COLUMN_NAME_HPP_
|
||||
|
||||
#include <mrn_constants.hpp>
|
||||
|
||||
namespace mrn {
|
||||
class IndexColumnName {
|
||||
public:
|
||||
IndexColumnName(const char *table_name, const char *mysql_column_name);
|
||||
const char *c_str();
|
||||
size_t length();
|
||||
private:
|
||||
const char *table_name_;
|
||||
const char *mysql_column_name_;
|
||||
char name_[MRN_MAX_KEY_SIZE];
|
||||
size_t length_;
|
||||
|
||||
uint encode(uchar *encoded_start, uchar *encoded_end,
|
||||
const uchar *mysql_string_start, const uchar *mysql_string_end);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MRN_INDEX_COLUMN_NAME_HPP_ */
|
||||
89
storage/mroonga/lib/mrn_index_table_name.cpp
Normal file
89
storage/mroonga/lib/mrn_index_table_name.cpp
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2011 Kentoku SHIBA
|
||||
Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
|
||||
#include "mrn_index_table_name.hpp"
|
||||
|
||||
// for debug
|
||||
#define MRN_CLASS_NAME "mrn::IndexTableName"
|
||||
|
||||
namespace mrn {
|
||||
IndexTableName::IndexTableName(const char *table_name,
|
||||
const char *mysql_index_name)
|
||||
: table_name_(table_name),
|
||||
mysql_index_name_(mysql_index_name) {
|
||||
uchar encoded_mysql_index_name_multibyte[MRN_MAX_KEY_SIZE];
|
||||
const uchar *mysql_index_name_multibyte =
|
||||
reinterpret_cast<const uchar *>(mysql_index_name_);
|
||||
encode(encoded_mysql_index_name_multibyte,
|
||||
encoded_mysql_index_name_multibyte + MRN_MAX_KEY_SIZE,
|
||||
mysql_index_name_multibyte,
|
||||
mysql_index_name_multibyte + strlen(mysql_index_name_));
|
||||
snprintf(name_, MRN_MAX_KEY_SIZE,
|
||||
"%s-%s", table_name_, encoded_mysql_index_name_multibyte);
|
||||
length_ = strlen(name_);
|
||||
}
|
||||
|
||||
const char *IndexTableName::c_str() {
|
||||
return name_;
|
||||
}
|
||||
|
||||
size_t IndexTableName::length() {
|
||||
return length_;
|
||||
}
|
||||
|
||||
uint IndexTableName::encode(uchar *encoded_start,
|
||||
uchar *encoded_end,
|
||||
const uchar *mysql_string_start,
|
||||
const uchar *mysql_string_end) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
my_charset_conv_mb_wc mb_wc = system_charset_info->cset->mb_wc;
|
||||
my_charset_conv_wc_mb wc_mb = my_charset_filename.cset->wc_mb;
|
||||
DBUG_PRINT("info", ("mroonga: in=%s", mysql_string_start));
|
||||
encoded_end--;
|
||||
uchar *encoded = encoded_start;
|
||||
const uchar *mysql_string = mysql_string_start;
|
||||
while (mysql_string < mysql_string_end && encoded < encoded_end) {
|
||||
my_wc_t wc;
|
||||
int mb_wc_converted_length;
|
||||
int wc_mb_converted_length;
|
||||
mb_wc_converted_length =
|
||||
(*mb_wc)(NULL, &wc, mysql_string, mysql_string_end);
|
||||
if (mb_wc_converted_length > 0) {
|
||||
wc_mb_converted_length = (*wc_mb)(NULL, wc, encoded, encoded_end);
|
||||
if (wc_mb_converted_length <= 0) {
|
||||
break;
|
||||
}
|
||||
} else if (mb_wc_converted_length == MY_CS_ILSEQ) {
|
||||
*encoded = *mysql_string;
|
||||
mb_wc_converted_length = 1;
|
||||
wc_mb_converted_length = 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
mysql_string += mb_wc_converted_length;
|
||||
encoded += wc_mb_converted_length;
|
||||
}
|
||||
*encoded = '\0';
|
||||
DBUG_PRINT("info", ("mroonga: out=%s", encoded_start));
|
||||
DBUG_RETURN(encoded - encoded_start);
|
||||
}
|
||||
}
|
||||
43
storage/mroonga/lib/mrn_index_table_name.hpp
Normal file
43
storage/mroonga/lib/mrn_index_table_name.hpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2011 Kentoku SHIBA
|
||||
Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_INDEX_TABLE_NAME_HPP_
|
||||
#define MRN_INDEX_TABLE_NAME_HPP_
|
||||
|
||||
#include <mrn_constants.hpp>
|
||||
|
||||
namespace mrn {
|
||||
class IndexTableName {
|
||||
public:
|
||||
IndexTableName(const char *table_name, const char *mysql_index_name);
|
||||
const char *c_str();
|
||||
size_t length();
|
||||
private:
|
||||
const char *table_name_;
|
||||
const char *mysql_index_name_;
|
||||
char name_[MRN_MAX_KEY_SIZE];
|
||||
size_t length_;
|
||||
|
||||
uint encode(uchar *encoded_start, uchar *encoded_end,
|
||||
const uchar *mysql_string_start, const uchar *mysql_string_end);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MRN_INDEX_TABLE_NAME_HPP_ */
|
||||
31
storage/mroonga/lib/mrn_lock.cpp
Normal file
31
storage/mroonga/lib/mrn_lock.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mrn_lock.hpp"
|
||||
|
||||
namespace mrn {
|
||||
Lock::Lock(pthread_mutex_t *mutex)
|
||||
: mutex_(mutex) {
|
||||
pthread_mutex_lock(mutex_);
|
||||
}
|
||||
|
||||
Lock::~Lock() {
|
||||
pthread_mutex_unlock(mutex_);
|
||||
}
|
||||
}
|
||||
36
storage/mroonga/lib/mrn_lock.hpp
Normal file
36
storage/mroonga/lib/mrn_lock.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_LOCK_HPP_
|
||||
#define MRN_LOCK_HPP_
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
class Lock {
|
||||
public:
|
||||
Lock(pthread_mutex_t *mutex);
|
||||
~Lock();
|
||||
private:
|
||||
pthread_mutex_t *mutex_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MRN_LOCK_HPP_ */
|
||||
33
storage/mroonga/lib/mrn_match_escalation_threshold_scope.cpp
Normal file
33
storage/mroonga/lib/mrn_match_escalation_threshold_scope.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mrn_match_escalation_threshold_scope.hpp"
|
||||
|
||||
namespace mrn {
|
||||
MatchEscalationThresholdScope::MatchEscalationThresholdScope(
|
||||
grn_ctx *ctx, long long int threshold)
|
||||
: ctx_(ctx),
|
||||
original_threshold_(grn_ctx_get_match_escalation_threshold(ctx_)) {
|
||||
grn_ctx_set_match_escalation_threshold(ctx_, threshold);
|
||||
}
|
||||
|
||||
MatchEscalationThresholdScope::~MatchEscalationThresholdScope() {
|
||||
grn_ctx_set_match_escalation_threshold(ctx_, original_threshold_);
|
||||
}
|
||||
}
|
||||
35
storage/mroonga/lib/mrn_match_escalation_threshold_scope.hpp
Normal file
35
storage/mroonga/lib/mrn_match_escalation_threshold_scope.hpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_MATCH_ESCALATION_THRESHOLD_SCOPE_HPP_
|
||||
#define MRN_MATCH_ESCALATION_THRESHOLD_SCOPE_HPP_
|
||||
|
||||
#include <groonga.h>
|
||||
|
||||
namespace mrn {
|
||||
class MatchEscalationThresholdScope {
|
||||
grn_ctx *ctx_;
|
||||
long long int original_threshold_;
|
||||
public:
|
||||
MatchEscalationThresholdScope(grn_ctx *ctx, long long int threshold);
|
||||
~MatchEscalationThresholdScope();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MRN_MATCH_ESCALATION_THRESHOLD_SCOPE_HPP_
|
||||
548
storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
Normal file
548
storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012-2014 Kouhei Sutou <kou@clear-code.com>
|
||||
Copyright(C) 2013 Kentoku SHIBA
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
|
||||
#include "mrn_multiple_column_key_codec.hpp"
|
||||
#include "mrn_field_normalizer.hpp"
|
||||
#include "mrn_smart_grn_obj.hpp"
|
||||
|
||||
// for debug
|
||||
#define MRN_CLASS_NAME "mrn::MultipleColumnKeyCodec"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define mrn_byte_order_host_to_network(buf, key, size) \
|
||||
{ \
|
||||
uint32 size_ = (uint32)(size); \
|
||||
uint8 *buf_ = (uint8 *)(buf); \
|
||||
uint8 *key_ = (uint8 *)(key); \
|
||||
while (size_--) { *buf_++ = *key_++; } \
|
||||
}
|
||||
#else /* WORDS_BIGENDIAN */
|
||||
#define mrn_byte_order_host_to_network(buf, key, size) \
|
||||
{ \
|
||||
uint32 size_ = (uint32)(size); \
|
||||
uint8 *buf_ = (uint8 *)(buf); \
|
||||
uint8 *key_ = (uint8 *)(key) + size_; \
|
||||
while (size_--) { *buf_++ = *(--key_); } \
|
||||
}
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
namespace mrn {
|
||||
MultipleColumnKeyCodec::MultipleColumnKeyCodec(grn_ctx *ctx,
|
||||
THD *thread,
|
||||
KEY *key_info)
|
||||
: ctx_(ctx),
|
||||
thread_(thread),
|
||||
key_info_(key_info) {
|
||||
}
|
||||
|
||||
MultipleColumnKeyCodec::~MultipleColumnKeyCodec() {
|
||||
}
|
||||
|
||||
int MultipleColumnKeyCodec::encode(const uchar *mysql_key,
|
||||
uint mysql_key_length,
|
||||
uchar *grn_key,
|
||||
uint *grn_key_length) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
int error = 0;
|
||||
const uchar *current_mysql_key = mysql_key;
|
||||
const uchar *mysql_key_end = mysql_key + mysql_key_length;
|
||||
uchar *current_grn_key = grn_key;
|
||||
|
||||
int n_key_parts = KEY_N_KEY_PARTS(key_info_);
|
||||
DBUG_PRINT("info", ("mroonga: n_key_parts=%d", n_key_parts));
|
||||
*grn_key_length = 0;
|
||||
for (int i = 0; i < n_key_parts && current_mysql_key < mysql_key_end; i++) {
|
||||
KEY_PART_INFO *key_part = &(key_info_->key_part[i]);
|
||||
Field *field = key_part->field;
|
||||
DBUG_PRINT("info", ("mroonga: key_part->length=%u", key_part->length));
|
||||
|
||||
if (field->null_bit) {
|
||||
DBUG_PRINT("info", ("mroonga: field has null bit"));
|
||||
*current_grn_key = 0;
|
||||
current_mysql_key += 1;
|
||||
current_grn_key += 1;
|
||||
(*grn_key_length)++;
|
||||
}
|
||||
|
||||
DataType data_type = TYPE_UNKNOWN;
|
||||
uint data_size = 0;
|
||||
get_key_info(key_part, &data_type, &data_size);
|
||||
|
||||
switch (data_type) {
|
||||
case TYPE_UNKNOWN:
|
||||
// TODO: This will not be happen. This is just for
|
||||
// suppressing warnings by gcc -O2. :<
|
||||
error = HA_ERR_UNSUPPORTED;
|
||||
break;
|
||||
case TYPE_LONG_LONG_NUMBER:
|
||||
{
|
||||
long long int long_long_value = 0;
|
||||
switch (data_size) {
|
||||
case 3:
|
||||
long_long_value = (long long int)sint3korr(current_mysql_key);
|
||||
break;
|
||||
case 8:
|
||||
long_long_value = (long long int)sint8korr(current_mysql_key);
|
||||
break;
|
||||
}
|
||||
mrn_byte_order_host_to_network(current_grn_key, &long_long_value,
|
||||
data_size);
|
||||
*((uint8 *)(current_grn_key)) ^= 0x80;
|
||||
}
|
||||
break;
|
||||
case TYPE_NUMBER:
|
||||
mrn_byte_order_host_to_network(current_grn_key, current_mysql_key, data_size);
|
||||
{
|
||||
Field_num *number_field = (Field_num *)field;
|
||||
if (!number_field->unsigned_flag) {
|
||||
*((uint8 *)(current_grn_key)) ^= 0x80;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
{
|
||||
float value;
|
||||
float4get(value, current_mysql_key);
|
||||
encode_float(value, data_size, current_grn_key);
|
||||
}
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
{
|
||||
double value;
|
||||
float8get(value, current_mysql_key);
|
||||
encode_double(value, data_size, current_grn_key);
|
||||
}
|
||||
break;
|
||||
case TYPE_BYTE_SEQUENCE:
|
||||
memcpy(current_grn_key, current_mysql_key, data_size);
|
||||
break;
|
||||
case TYPE_BYTE_REVERSE:
|
||||
encode_reverse(current_mysql_key, data_size, current_grn_key);
|
||||
break;
|
||||
case TYPE_BYTE_BLOB:
|
||||
encode_blob(field, current_mysql_key, current_grn_key, &data_size);
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
||||
current_mysql_key += data_size;
|
||||
current_grn_key += data_size;
|
||||
*grn_key_length += data_size;
|
||||
}
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
int MultipleColumnKeyCodec::decode(const uchar *grn_key,
|
||||
uint grn_key_length,
|
||||
uchar *mysql_key,
|
||||
uint *mysql_key_length) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
int error = 0;
|
||||
const uchar *current_grn_key = grn_key;
|
||||
const uchar *grn_key_end = grn_key + grn_key_length;
|
||||
uchar *current_mysql_key = mysql_key;
|
||||
|
||||
int n_key_parts = KEY_N_KEY_PARTS(key_info_);
|
||||
DBUG_PRINT("info", ("mroonga: n_key_parts=%d", n_key_parts));
|
||||
*mysql_key_length = 0;
|
||||
for (int i = 0; i < n_key_parts && current_grn_key < grn_key_end; i++) {
|
||||
KEY_PART_INFO *key_part = &(key_info_->key_part[i]);
|
||||
Field *field = key_part->field;
|
||||
DBUG_PRINT("info", ("mroonga: key_part->length=%u", key_part->length));
|
||||
|
||||
if (field->null_bit) {
|
||||
DBUG_PRINT("info", ("mroonga: field has null bit"));
|
||||
*current_mysql_key = 0;
|
||||
current_grn_key += 1;
|
||||
current_mysql_key += 1;
|
||||
(*mysql_key_length)++;
|
||||
}
|
||||
|
||||
DataType data_type = TYPE_UNKNOWN;
|
||||
uint data_size = 0;
|
||||
get_key_info(key_part, &data_type, &data_size);
|
||||
|
||||
switch (data_type) {
|
||||
case TYPE_UNKNOWN:
|
||||
// TODO: This will not be happen. This is just for
|
||||
// suppressing warnings by gcc -O2. :<
|
||||
error = HA_ERR_UNSUPPORTED;
|
||||
break;
|
||||
case TYPE_LONG_LONG_NUMBER:
|
||||
{
|
||||
long long int long_long_value = 0;
|
||||
switch (data_size) {
|
||||
case 3:
|
||||
long_long_value = (long long int)sint3korr(current_grn_key);
|
||||
break;
|
||||
case 8:
|
||||
long_long_value = (long long int)sint8korr(current_grn_key);
|
||||
break;
|
||||
}
|
||||
*((uint8 *)(&long_long_value)) ^= 0x80;
|
||||
mrn_byte_order_host_to_network(current_mysql_key, &long_long_value,
|
||||
data_size);
|
||||
}
|
||||
break;
|
||||
case TYPE_NUMBER:
|
||||
{
|
||||
uchar buffer[8];
|
||||
memcpy(buffer, current_grn_key, data_size);
|
||||
Field_num *number_field = (Field_num *)field;
|
||||
if (!number_field->unsigned_flag) {
|
||||
buffer[0] ^= 0x80;
|
||||
}
|
||||
mrn_byte_order_host_to_network(current_mysql_key, buffer,
|
||||
data_size);
|
||||
}
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
decode_float(current_grn_key, current_mysql_key, data_size);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
decode_double(current_grn_key, current_mysql_key, data_size);
|
||||
break;
|
||||
case TYPE_BYTE_SEQUENCE:
|
||||
memcpy(current_mysql_key, current_grn_key, data_size);
|
||||
break;
|
||||
case TYPE_BYTE_REVERSE:
|
||||
decode_reverse(current_grn_key, current_mysql_key, data_size);
|
||||
break;
|
||||
case TYPE_BYTE_BLOB:
|
||||
memcpy(current_mysql_key,
|
||||
current_grn_key + data_size,
|
||||
HA_KEY_BLOB_LENGTH);
|
||||
memcpy(current_mysql_key + HA_KEY_BLOB_LENGTH,
|
||||
current_grn_key,
|
||||
data_size);
|
||||
data_size += HA_KEY_BLOB_LENGTH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
||||
current_grn_key += data_size;
|
||||
current_mysql_key += data_size;
|
||||
*mysql_key_length += data_size;
|
||||
}
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
uint MultipleColumnKeyCodec::size() {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
int n_key_parts = KEY_N_KEY_PARTS(key_info_);
|
||||
DBUG_PRINT("info", ("mroonga: n_key_parts=%d", n_key_parts));
|
||||
|
||||
uint total_size = 0;
|
||||
for (int i = 0; i < n_key_parts; ++i) {
|
||||
KEY_PART_INFO *key_part = &(key_info_->key_part[i]);
|
||||
Field *field = key_part->field;
|
||||
DBUG_PRINT("info", ("mroonga: key_part->length=%u", key_part->length));
|
||||
|
||||
if (field->null_bit) {
|
||||
DBUG_PRINT("info", ("mroonga: field has null bit"));
|
||||
++total_size;
|
||||
}
|
||||
|
||||
DataType data_type = TYPE_UNKNOWN;
|
||||
uint data_size = 0;
|
||||
get_key_info(key_part, &data_type, &data_size);
|
||||
total_size += data_size;
|
||||
if (data_type == TYPE_BYTE_BLOB) {
|
||||
total_size += HA_KEY_BLOB_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(total_size);
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::get_key_info(KEY_PART_INFO *key_part,
|
||||
DataType *data_type,
|
||||
uint *data_size) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
*data_type = TYPE_UNKNOWN;
|
||||
*data_size = 0;
|
||||
|
||||
Field *field = key_part->field;
|
||||
switch (field->real_type()) {
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DECIMAL"));
|
||||
*data_type = TYPE_BYTE_SEQUENCE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_YEAR:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TINY"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 1;
|
||||
break;
|
||||
case MYSQL_TYPE_SHORT:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_SHORT"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 2;
|
||||
break;
|
||||
case MYSQL_TYPE_LONG:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_LONG"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 4;
|
||||
break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_FLOAT"));
|
||||
*data_type = TYPE_FLOAT;
|
||||
*data_size = 4;
|
||||
break;
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DOUBLE"));
|
||||
*data_type = TYPE_DOUBLE;
|
||||
*data_size = 8;
|
||||
break;
|
||||
case MYSQL_TYPE_NULL:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_NULL"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 1;
|
||||
break;
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_NEWDATE:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATETIME"));
|
||||
*data_type = TYPE_BYTE_REVERSE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_LONGLONG"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 8;
|
||||
break;
|
||||
case MYSQL_TYPE_INT24:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_INT24"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 3;
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TIME"));
|
||||
*data_type = TYPE_LONG_LONG_NUMBER;
|
||||
*data_size = 3;
|
||||
break;
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_VARCHAR"));
|
||||
*data_type = TYPE_BYTE_BLOB;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
case MYSQL_TYPE_BIT:
|
||||
// TODO
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_BIT"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 1;
|
||||
break;
|
||||
#ifdef MRN_HAVE_MYSQL_TYPE_TIMESTAMP2
|
||||
case MYSQL_TYPE_TIMESTAMP2:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TIMESTAMP2"));
|
||||
*data_type = TYPE_BYTE_SEQUENCE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
#endif
|
||||
#ifdef MRN_HAVE_MYSQL_TYPE_DATETIME2
|
||||
case MYSQL_TYPE_DATETIME2:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_DATETIME2"));
|
||||
*data_type = TYPE_BYTE_SEQUENCE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
#endif
|
||||
#ifdef MRN_HAVE_MYSQL_TYPE_TIME2
|
||||
case MYSQL_TYPE_TIME2:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_TIME2"));
|
||||
*data_type = TYPE_BYTE_SEQUENCE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
#endif
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_NEWDECIMAL"));
|
||||
*data_type = TYPE_BYTE_SEQUENCE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
case MYSQL_TYPE_ENUM:
|
||||
// TODO
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_ENUM"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 1;
|
||||
break;
|
||||
case MYSQL_TYPE_SET:
|
||||
// TODO
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_SET"));
|
||||
*data_type = TYPE_NUMBER;
|
||||
*data_size = 1;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
// TODO
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_BLOB"));
|
||||
*data_type = TYPE_BYTE_BLOB;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
// TODO
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_STRING"));
|
||||
*data_type = TYPE_BYTE_SEQUENCE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
// TODO
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TYPE_GEOMETRY"));
|
||||
*data_type = TYPE_BYTE_SEQUENCE;
|
||||
*data_size = key_part->length;
|
||||
break;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::encode_float(volatile float value, uint data_size,
|
||||
uchar *grn_key) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
int n_bits = (data_size * 8 - 1);
|
||||
volatile int *int_value_pointer = (int *)(&value);
|
||||
int int_value = *int_value_pointer;
|
||||
int_value ^= ((int_value >> n_bits) | (1 << n_bits));
|
||||
mrn_byte_order_host_to_network(grn_key, &int_value, data_size);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::decode_float(const uchar *grn_key,
|
||||
uchar *mysql_key,
|
||||
uint data_size) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
int int_value;
|
||||
mrn_byte_order_host_to_network(&int_value, grn_key, data_size);
|
||||
int max_bit = (data_size * 8 - 1);
|
||||
*((int *)mysql_key) =
|
||||
int_value ^ (((int_value ^ (1 << max_bit)) >> max_bit) |
|
||||
(1 << max_bit));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::encode_double(volatile double value, uint data_size,
|
||||
uchar *grn_key) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
int n_bits = (data_size * 8 - 1);
|
||||
volatile long long int *long_long_value_pointer = (long long int *)(&value);
|
||||
volatile long long int long_long_value = *long_long_value_pointer;
|
||||
long_long_value ^= ((long_long_value >> n_bits) | (1LL << n_bits));
|
||||
mrn_byte_order_host_to_network(grn_key, &long_long_value, data_size);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::decode_double(const uchar *grn_key,
|
||||
uchar *mysql_key,
|
||||
uint data_size) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
long long int long_long_value;
|
||||
mrn_byte_order_host_to_network(&long_long_value, grn_key, data_size);
|
||||
int max_bit = (data_size * 8 - 1);
|
||||
*((long long int *)mysql_key) =
|
||||
long_long_value ^ (((long_long_value ^ (1LL << max_bit)) >> max_bit) |
|
||||
(1LL << max_bit));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::encode_reverse(const uchar *mysql_key, uint data_size,
|
||||
uchar *grn_key) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
for (uint i = 0; i < data_size; i++) {
|
||||
grn_key[i] = mysql_key[data_size - i - 1];
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::decode_reverse(const uchar *grn_key,
|
||||
uchar *mysql_key,
|
||||
uint data_size) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
for (uint i = 0; i < data_size; i++) {
|
||||
mysql_key[i] = grn_key[data_size - i - 1];
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
void MultipleColumnKeyCodec::encode_blob(Field *field,
|
||||
const uchar *mysql_key,
|
||||
uchar *grn_key,
|
||||
uint *data_size) {
|
||||
FieldNormalizer normalizer(ctx_, thread_, field);
|
||||
if (normalizer.should_normalize()) {
|
||||
#if HA_KEY_BLOB_LENGTH != 2
|
||||
# error "TODO: support HA_KEY_BLOB_LENGTH != 2 case if it is needed"
|
||||
#endif
|
||||
const char *blob_data =
|
||||
reinterpret_cast<const char *>(mysql_key + HA_KEY_BLOB_LENGTH);
|
||||
uint16 blob_data_length = *((uint16 *)(mysql_key));
|
||||
grn_obj *grn_string = normalizer.normalize(blob_data,
|
||||
blob_data_length);
|
||||
mrn::SmartGrnObj smart_grn_string(ctx_, grn_string);
|
||||
const char *normalized;
|
||||
unsigned int normalized_length = 0;
|
||||
grn_string_get_normalized(ctx_, grn_string,
|
||||
&normalized, &normalized_length, NULL);
|
||||
uint16 new_blob_data_length;
|
||||
if (normalized_length <= UINT_MAX16) {
|
||||
memcpy(grn_key, normalized, normalized_length);
|
||||
if (normalized_length < *data_size) {
|
||||
memset(grn_key + normalized_length,
|
||||
'\0', *data_size - normalized_length);
|
||||
}
|
||||
new_blob_data_length = normalized_length;
|
||||
} else {
|
||||
push_warning_printf(thread_,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED,
|
||||
"normalized data truncated "
|
||||
"for multiple column index: "
|
||||
"normalized-data-size: <%u> "
|
||||
"max-data-size: <%u> "
|
||||
"column-name: <%s> "
|
||||
"data: <%.*s>",
|
||||
normalized_length,
|
||||
UINT_MAX16,
|
||||
field->field_name,
|
||||
blob_data_length, blob_data);
|
||||
memcpy(grn_key, normalized, blob_data_length);
|
||||
new_blob_data_length = blob_data_length;
|
||||
}
|
||||
memcpy(grn_key + *data_size, &new_blob_data_length, HA_KEY_BLOB_LENGTH);
|
||||
} else {
|
||||
memcpy(grn_key + *data_size, mysql_key, HA_KEY_BLOB_LENGTH);
|
||||
memcpy(grn_key, mysql_key + HA_KEY_BLOB_LENGTH, *data_size);
|
||||
}
|
||||
*data_size += HA_KEY_BLOB_LENGTH;
|
||||
}
|
||||
}
|
||||
70
storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
Normal file
70
storage/mroonga/lib/mrn_multiple_column_key_codec.hpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_MULTIPLE_COLUMN_KEY_CODEC_HPP_
|
||||
#define MRN_MULTIPLE_COLUMN_KEY_CODEC_HPP_
|
||||
|
||||
#include <groonga.h>
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
class MultipleColumnKeyCodec {
|
||||
public:
|
||||
MultipleColumnKeyCodec(grn_ctx *ctx, THD *thread, KEY *key_info);
|
||||
~MultipleColumnKeyCodec();
|
||||
|
||||
int encode(const uchar *mysql_key, uint mysql_key_length,
|
||||
uchar *grn_key, uint *grn_key_length);
|
||||
int decode(const uchar *grn_key, uint grn_key_length,
|
||||
uchar *mysql_key, uint *mysql_key_length);
|
||||
uint size();
|
||||
|
||||
private:
|
||||
enum DataType {
|
||||
TYPE_UNKNOWN,
|
||||
TYPE_LONG_LONG_NUMBER,
|
||||
TYPE_NUMBER,
|
||||
TYPE_FLOAT,
|
||||
TYPE_DOUBLE,
|
||||
TYPE_BYTE_SEQUENCE,
|
||||
TYPE_BYTE_REVERSE,
|
||||
TYPE_BYTE_BLOB
|
||||
};
|
||||
|
||||
grn_ctx *ctx_;
|
||||
THD *thread_;
|
||||
KEY *key_info_;
|
||||
|
||||
void get_key_info(KEY_PART_INFO *key_part,
|
||||
DataType *data_type, uint *data_size);
|
||||
|
||||
void encode_float(volatile float value, uint data_size, uchar *grn_key);
|
||||
void decode_float(const uchar *grn_key, uchar *mysql_key, uint data_size);
|
||||
void encode_double(volatile double value, uint data_size, uchar *grn_key);
|
||||
void decode_double(const uchar *grn_key, uchar *mysql_key, uint data_size);
|
||||
void encode_reverse(const uchar *mysql_key, uint data_size, uchar *grn_key);
|
||||
void decode_reverse(const uchar *grn_key, uchar *mysql_key, uint data_size);
|
||||
void encode_blob(Field *field,
|
||||
const uchar *mysql_key, uchar *grn_key, uint *data_size);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MRN_MULTIPLE_COLUMN_KEY_CODEC_HPP_
|
||||
32
storage/mroonga/lib/mrn_mysqlservices.cpp
Normal file
32
storage/mroonga/lib/mrn_mysqlservices.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
/*
|
||||
Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
/*
|
||||
void *thd_alloc(MYSQL_THD thd, unsigned int size)
|
||||
{
|
||||
return thd->alloc(size);
|
||||
}
|
||||
*/
|
||||
176
storage/mroonga/lib/mrn_parameters_parser.cpp
Normal file
176
storage/mroonga/lib/mrn_parameters_parser.cpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2011-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mrn_parameters_parser.hpp"
|
||||
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
class Parameter {
|
||||
public:
|
||||
char *key_;
|
||||
char *value_;
|
||||
|
||||
Parameter(const char *key, unsigned int key_length,
|
||||
const char *value, unsigned int value_length)
|
||||
: key_(my_strndup(key, key_length, MYF(0))),
|
||||
value_(my_strndup(value, value_length, MYF(0))) {
|
||||
};
|
||||
~Parameter() {
|
||||
if (key_) {
|
||||
my_free(key_, MYF(0));
|
||||
}
|
||||
if (value_) {
|
||||
my_free(value_, MYF(0));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ParametersParser::ParametersParser(const char *input,
|
||||
unsigned int input_length)
|
||||
: input_(input),
|
||||
input_length_(input_length),
|
||||
parameters_(NULL) {
|
||||
}
|
||||
|
||||
ParametersParser::~ParametersParser() {
|
||||
for (LIST *next = parameters_; next; next = next->next) {
|
||||
Parameter *parameter = static_cast<Parameter *>(next->data);
|
||||
delete parameter;
|
||||
}
|
||||
list_free(parameters_, false);
|
||||
}
|
||||
|
||||
void ParametersParser::parse() {
|
||||
const char *current = input_;
|
||||
const char *end = input_ + input_length_;
|
||||
for (; current < end; ++current) {
|
||||
if (is_white_space(current[0])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *key = current;
|
||||
unsigned int key_length = 0;
|
||||
while (current < end &&
|
||||
!is_white_space(current[0]) &&
|
||||
current[0] != '\'' && current[0] != '"' && current[0] != ',') {
|
||||
++current;
|
||||
++key_length;
|
||||
}
|
||||
if (current == end) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (current < end && is_white_space(current[0])) {
|
||||
++current;
|
||||
}
|
||||
if (current == end) {
|
||||
break;
|
||||
}
|
||||
current = parse_value(current, end, key, key_length);
|
||||
if (!current) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (current < end && is_white_space(current[0])) {
|
||||
++current;
|
||||
}
|
||||
if (current == end) {
|
||||
break;
|
||||
}
|
||||
if (current[0] != ',') {
|
||||
// TODO: report error
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *ParametersParser::parse_value(const char *current,
|
||||
const char *end,
|
||||
const char *key,
|
||||
unsigned int key_length) {
|
||||
char quote = current[0];
|
||||
if (quote != '\'' && quote != '"') {
|
||||
// TODO: report error
|
||||
return NULL;
|
||||
}
|
||||
++current;
|
||||
|
||||
bool found = false;
|
||||
static const unsigned int max_value_length = 4096;
|
||||
char value[max_value_length];
|
||||
unsigned int value_length = 0;
|
||||
for (; current < end && value_length < max_value_length; ++current) {
|
||||
if (current[0] == quote) {
|
||||
Parameter *parameter = new Parameter(key, key_length,
|
||||
value, value_length);
|
||||
list_push(parameters_, parameter);
|
||||
found = true;
|
||||
++current;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (current[0]) {
|
||||
case '\\':
|
||||
if (current + 1 == end) {
|
||||
break;
|
||||
}
|
||||
switch (current[1]) {
|
||||
case 'b':
|
||||
value[value_length] = '\b';
|
||||
break;
|
||||
case 'n':
|
||||
value[value_length] = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
value[value_length] = '\r';
|
||||
break;
|
||||
case 't':
|
||||
value[value_length] = '\t';
|
||||
break;
|
||||
default:
|
||||
value[value_length] = current[1];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
value[value_length] = current[0];
|
||||
break;
|
||||
}
|
||||
++value_length;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// TODO: report error
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
const char *ParametersParser::operator[](const char *key) {
|
||||
for (LIST *next = parameters_; next; next = next->next) {
|
||||
Parameter *parameter = static_cast<Parameter *>(next->data);
|
||||
if (strcasecmp(parameter->key_, key) == 0) {
|
||||
return parameter->value_;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
59
storage/mroonga/lib/mrn_parameters_parser.hpp
Normal file
59
storage/mroonga/lib/mrn_parameters_parser.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2011-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_PARAMETERS_PARSER_HPP_
|
||||
#define MRN_PARAMETERS_PARSER_HPP_
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
#include <my_list.h>
|
||||
|
||||
namespace mrn {
|
||||
class ParametersParser {
|
||||
public:
|
||||
ParametersParser(const char *input, unsigned int input_length);
|
||||
~ParametersParser();
|
||||
void parse();
|
||||
const char *operator[](const char *key);
|
||||
|
||||
private:
|
||||
const char *input_;
|
||||
unsigned int input_length_;
|
||||
|
||||
LIST *parameters_;
|
||||
|
||||
bool is_white_space(char character) {
|
||||
switch (character) {
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
};
|
||||
const char *parse_value(const char *current, const char *end,
|
||||
const char *key, unsigned int key_length);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MRN_PARAMETERS_PARSER_HPP_ */
|
||||
196
storage/mroonga/lib/mrn_path_mapper.cpp
Normal file
196
storage/mroonga/lib/mrn_path_mapper.cpp
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2010 Tetsuro IKEDA
|
||||
Copyright(C) 2011-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "mrn_path_mapper.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <mrn_mysql.h>
|
||||
|
||||
namespace mrn {
|
||||
char *PathMapper::default_path_prefix = NULL;
|
||||
char *PathMapper::default_mysql_data_home_path = NULL;
|
||||
|
||||
PathMapper::PathMapper(const char *mysql_path,
|
||||
const char *path_prefix,
|
||||
const char *mysql_data_home_path)
|
||||
: mysql_path_(mysql_path),
|
||||
path_prefix_(path_prefix),
|
||||
mysql_data_home_path_(mysql_data_home_path) {
|
||||
db_path_[0] = '\0';
|
||||
db_name_[0] = '\0';
|
||||
table_name_[0] = '\0';
|
||||
mysql_table_name_[0] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* "./${db}/${table}" ==> "${db}.mrn"
|
||||
* "./${db}/" ==> "${db}.mrn"
|
||||
* "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
|
||||
* "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0.mrn"
|
||||
*/
|
||||
const char *PathMapper::db_path() {
|
||||
if (db_path_[0] != '\0') {
|
||||
return db_path_;
|
||||
}
|
||||
|
||||
if (mysql_path_[0] == FN_CURLIB && mysql_path_[1] == FN_LIBCHAR) {
|
||||
if (path_prefix_) {
|
||||
strcpy(db_path_, path_prefix_);
|
||||
}
|
||||
|
||||
int i = 2, j = strlen(db_path_), len;
|
||||
len = strlen(mysql_path_);
|
||||
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
|
||||
db_path_[j++] = mysql_path_[i++];
|
||||
}
|
||||
db_path_[j] = '\0';
|
||||
} else if (mysql_data_home_path_) {
|
||||
int len = strlen(mysql_path_);
|
||||
int mysql_data_home_len = strlen(mysql_data_home_path_);
|
||||
if (len > mysql_data_home_len &&
|
||||
!strncmp(mysql_path_, mysql_data_home_path_, mysql_data_home_len)) {
|
||||
int i = mysql_data_home_len, j;
|
||||
if (path_prefix_ && path_prefix_[0] == FN_LIBCHAR) {
|
||||
strcpy(db_path_, path_prefix_);
|
||||
j = strlen(db_path_);
|
||||
} else {
|
||||
memcpy(db_path_, mysql_data_home_path_, mysql_data_home_len);
|
||||
if (path_prefix_) {
|
||||
if (path_prefix_[0] == FN_CURLIB &&
|
||||
path_prefix_[1] == FN_LIBCHAR) {
|
||||
strcpy(&db_path_[mysql_data_home_len], &path_prefix_[2]);
|
||||
} else {
|
||||
strcpy(&db_path_[mysql_data_home_len], path_prefix_);
|
||||
}
|
||||
j = strlen(db_path_);
|
||||
} else {
|
||||
j = mysql_data_home_len;
|
||||
}
|
||||
}
|
||||
|
||||
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
|
||||
db_path_[j++] = mysql_path_[i++];
|
||||
}
|
||||
if (i == len) {
|
||||
memcpy(db_path_, mysql_path_, len);
|
||||
} else {
|
||||
db_path_[j] = '\0';
|
||||
}
|
||||
} else {
|
||||
strcpy(db_path_, mysql_path_);
|
||||
}
|
||||
} else {
|
||||
strcpy(db_path_, mysql_path_);
|
||||
}
|
||||
strcat(db_path_, MRN_DB_FILE_SUFFIX);
|
||||
return db_path_;
|
||||
}
|
||||
|
||||
/**
|
||||
* "./${db}/${table}" ==> "${db}"
|
||||
* "./${db}/" ==> "${db}"
|
||||
* "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0" ==>
|
||||
* "/tmp/mysql-test/var/tmp/mysqld.1/#sql27c5_1_0"
|
||||
*/
|
||||
const char *PathMapper::db_name() {
|
||||
if (db_name_[0] != '\0') {
|
||||
return db_name_;
|
||||
}
|
||||
|
||||
if (mysql_path_[0] == FN_CURLIB && mysql_path_[1] == FN_LIBCHAR) {
|
||||
int i = 2, j = 0, len;
|
||||
len = strlen(mysql_path_);
|
||||
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
|
||||
db_name_[j++] = mysql_path_[i++];
|
||||
}
|
||||
db_name_[j] = '\0';
|
||||
} else if (mysql_data_home_path_) {
|
||||
int len = strlen(mysql_path_);
|
||||
int mysql_data_home_len = strlen(mysql_data_home_path_);
|
||||
if (len > mysql_data_home_len &&
|
||||
!strncmp(mysql_path_, mysql_data_home_path_, mysql_data_home_len)) {
|
||||
int i = mysql_data_home_len, j = 0;
|
||||
while (mysql_path_[i] != FN_LIBCHAR && i < len) {
|
||||
db_name_[j++] = mysql_path_[i++];
|
||||
}
|
||||
if (i == len) {
|
||||
memcpy(db_name_, mysql_path_, len);
|
||||
} else {
|
||||
db_name_[j] = '\0';
|
||||
}
|
||||
} else {
|
||||
strcpy(db_name_, mysql_path_);
|
||||
}
|
||||
} else {
|
||||
strcpy(db_name_, mysql_path_);
|
||||
}
|
||||
return db_name_;
|
||||
}
|
||||
|
||||
/**
|
||||
* "./${db}/${table}" ==> "${table}" (with encoding first '_')
|
||||
*/
|
||||
const char *PathMapper::table_name() {
|
||||
if (table_name_[0] != '\0') {
|
||||
return table_name_;
|
||||
}
|
||||
|
||||
int len = strlen(mysql_path_);
|
||||
int i = len, j = 0;
|
||||
for (; mysql_path_[--i] != FN_LIBCHAR ;) {}
|
||||
if (mysql_path_[i + 1] == '_') {
|
||||
table_name_[j++] = '@';
|
||||
table_name_[j++] = '0';
|
||||
table_name_[j++] = '0';
|
||||
table_name_[j++] = '5';
|
||||
table_name_[j++] = 'f';
|
||||
i++;
|
||||
}
|
||||
for (; i < len ;) {
|
||||
table_name_[j++] = mysql_path_[++i];
|
||||
}
|
||||
table_name_[j] = '\0';
|
||||
return table_name_;
|
||||
}
|
||||
|
||||
/**
|
||||
* "./${db}/${table}" ==> "${table}" (without encoding first '_')
|
||||
*/
|
||||
const char *PathMapper::mysql_table_name() {
|
||||
if (mysql_table_name_[0] != '\0') {
|
||||
return mysql_table_name_;
|
||||
}
|
||||
|
||||
int len = strlen(mysql_path_);
|
||||
int i = len, j = 0;
|
||||
for (; mysql_path_[--i] != FN_LIBCHAR ;) {}
|
||||
for (; i < len ;) {
|
||||
mysql_table_name_[j++] = mysql_path_[++i];
|
||||
}
|
||||
mysql_table_name_[j] = '\0';
|
||||
return mysql_table_name_;
|
||||
}
|
||||
}
|
||||
51
storage/mroonga/lib/mrn_path_mapper.hpp
Normal file
51
storage/mroonga/lib/mrn_path_mapper.hpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2010 Tetsuro IKEDA
|
||||
Copyright(C) 2010-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2012 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_PATH_MAPPER_HPP_
|
||||
#define MRN_PATH_MAPPER_HPP_
|
||||
|
||||
#include <mrn_constants.hpp>
|
||||
|
||||
namespace mrn {
|
||||
class PathMapper {
|
||||
public:
|
||||
static char *default_path_prefix;
|
||||
static char *default_mysql_data_home_path;
|
||||
|
||||
PathMapper(const char *mysql_path,
|
||||
const char *path_prefix=default_path_prefix,
|
||||
const char *mysql_data_home_path=default_mysql_data_home_path);
|
||||
const char *db_path();
|
||||
const char *db_name();
|
||||
const char *table_name();
|
||||
const char *mysql_table_name();
|
||||
private:
|
||||
const char *mysql_path_;
|
||||
const char *path_prefix_;
|
||||
const char *mysql_data_home_path_;
|
||||
char db_path_[MRN_MAX_PATH_SIZE];
|
||||
char db_name_[MRN_MAX_PATH_SIZE];
|
||||
char table_name_[MRN_MAX_PATH_SIZE];
|
||||
char mysql_table_name_[MRN_MAX_PATH_SIZE];
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MRN_PATH_MAPPER_HPP_ */
|
||||
53
storage/mroonga/lib/mrn_smart_grn_obj.cpp
Normal file
53
storage/mroonga/lib/mrn_smart_grn_obj.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mrn_smart_grn_obj.hpp"
|
||||
|
||||
namespace mrn {
|
||||
SmartGrnObj::SmartGrnObj(grn_ctx *ctx, grn_obj *obj)
|
||||
: ctx_(ctx),
|
||||
obj_(obj) {
|
||||
}
|
||||
|
||||
SmartGrnObj::SmartGrnObj(grn_ctx *ctx, const char *name, int name_size)
|
||||
: ctx_(ctx),
|
||||
obj_(NULL) {
|
||||
if (name_size < 0) {
|
||||
name_size = strlen(name);
|
||||
}
|
||||
obj_ = grn_ctx_get(ctx_, name, name_size);
|
||||
}
|
||||
|
||||
SmartGrnObj::SmartGrnObj(grn_ctx *ctx, grn_id id)
|
||||
: ctx_(ctx),
|
||||
obj_(grn_ctx_at(ctx_, id)) {
|
||||
}
|
||||
|
||||
SmartGrnObj::~SmartGrnObj() {
|
||||
if (obj_) {
|
||||
grn_obj_unlink(ctx_, obj_);
|
||||
}
|
||||
}
|
||||
|
||||
grn_obj *SmartGrnObj::get() {
|
||||
return obj_;
|
||||
}
|
||||
}
|
||||
39
storage/mroonga/lib/mrn_smart_grn_obj.hpp
Normal file
39
storage/mroonga/lib/mrn_smart_grn_obj.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2014 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_SMART_GRN_OBJ_HPP_
|
||||
#define MRN_SMART_GRN_OBJ_HPP_
|
||||
|
||||
#include <groonga.h>
|
||||
|
||||
namespace mrn {
|
||||
class SmartGrnObj {
|
||||
grn_ctx *ctx_;
|
||||
grn_obj *obj_;
|
||||
public:
|
||||
SmartGrnObj(grn_ctx *ctx, grn_obj *obj);
|
||||
SmartGrnObj(grn_ctx *ctx, const char *name, int name_size=-1);
|
||||
SmartGrnObj(grn_ctx *ctx, grn_id id);
|
||||
~SmartGrnObj();
|
||||
|
||||
grn_obj *get();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MRN_SMART_GRN_OBJ_HPP_
|
||||
260
storage/mroonga/lib/mrn_time_converter.cpp
Normal file
260
storage/mroonga/lib/mrn_time_converter.cpp
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2010-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "mrn_time_converter.hpp"
|
||||
|
||||
#ifdef min
|
||||
# undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
# undef max
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
|
||||
// for debug
|
||||
#define MRN_CLASS_NAME "mrn::TimeConverter"
|
||||
|
||||
namespace mrn {
|
||||
TimeConverter::TimeConverter() {
|
||||
}
|
||||
|
||||
TimeConverter::~TimeConverter() {
|
||||
}
|
||||
|
||||
time_t TimeConverter::tm_to_time_gm(struct tm *time, bool *truncated) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
*truncated = true;
|
||||
struct tm gmdate;
|
||||
time->tm_yday = -1;
|
||||
time->tm_isdst = -1;
|
||||
time_t sec_t = mktime(time);
|
||||
if (time->tm_yday == -1) {
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if (!gmtime_r(&sec_t, &gmdate)) {
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
int32 mrn_utc_diff_in_seconds =
|
||||
(
|
||||
time->tm_mday > 25 && gmdate.tm_mday == 1 ? -1 :
|
||||
time->tm_mday == 1 && gmdate.tm_mday > 25 ? 1 :
|
||||
time->tm_mday - gmdate.tm_mday
|
||||
) * 24 * 60 * 60 +
|
||||
(time->tm_hour - gmdate.tm_hour) * 60 * 60 +
|
||||
(time->tm_min - gmdate.tm_min) * 60 +
|
||||
(time->tm_sec - gmdate.tm_sec);
|
||||
DBUG_PRINT("info", ("mroonga: time->tm_year=%d", time->tm_year));
|
||||
DBUG_PRINT("info", ("mroonga: time->tm_mon=%d", time->tm_mon));
|
||||
DBUG_PRINT("info", ("mroonga: time->tm_mday=%d", time->tm_mday));
|
||||
DBUG_PRINT("info", ("mroonga: time->tm_hour=%d", time->tm_hour));
|
||||
DBUG_PRINT("info", ("mroonga: time->tm_min=%d", time->tm_min));
|
||||
DBUG_PRINT("info", ("mroonga: time->tm_sec=%d", time->tm_sec));
|
||||
DBUG_PRINT("info", ("mroonga: mrn_utc_diff_in_seconds=%d",
|
||||
mrn_utc_diff_in_seconds));
|
||||
if (mrn_utc_diff_in_seconds > 0) {
|
||||
if (sec_t > std::numeric_limits<time_t>::max() - mrn_utc_diff_in_seconds) {
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
} else {
|
||||
if (sec_t < std::numeric_limits<time_t>::min() - mrn_utc_diff_in_seconds) {
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
*truncated = false;
|
||||
DBUG_RETURN(sec_t + mrn_utc_diff_in_seconds);
|
||||
}
|
||||
|
||||
long long int TimeConverter::tm_to_grn_time(struct tm *time, int usec,
|
||||
bool *truncated) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
long long int sec = tm_to_time_gm(time, truncated);
|
||||
|
||||
DBUG_PRINT("info", ("mroonga: sec=%lld", sec));
|
||||
DBUG_PRINT("info", ("mroonga: usec=%d", usec));
|
||||
|
||||
long long int grn_time = *truncated ? 0 : GRN_TIME_PACK(sec, usec);
|
||||
|
||||
DBUG_RETURN(grn_time);
|
||||
}
|
||||
|
||||
long long int TimeConverter::mysql_time_to_grn_time(MYSQL_TIME *mysql_time,
|
||||
bool *truncated) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
||||
int usec = mysql_time->second_part;
|
||||
long long int grn_time = 0;
|
||||
|
||||
*truncated = false;
|
||||
switch (mysql_time->time_type) {
|
||||
case MYSQL_TIMESTAMP_DATE:
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATE"));
|
||||
struct tm date;
|
||||
memset(&date, 0, sizeof(struct tm));
|
||||
date.tm_year = mysql_time->year - TM_YEAR_BASE;
|
||||
if (mysql_time->month > 0) {
|
||||
date.tm_mon = mysql_time->month - 1;
|
||||
} else {
|
||||
date.tm_mon = 0;
|
||||
*truncated = true;
|
||||
}
|
||||
if (mysql_time->day > 0) {
|
||||
date.tm_mday = mysql_time->day;
|
||||
} else {
|
||||
date.tm_mday = 1;
|
||||
*truncated = true;
|
||||
}
|
||||
DBUG_PRINT("info", ("mroonga: tm_year=%d", date.tm_year));
|
||||
DBUG_PRINT("info", ("mroonga: tm_mon=%d", date.tm_mon));
|
||||
DBUG_PRINT("info", ("mroonga: tm_mday=%d", date.tm_mday));
|
||||
bool tm_truncated = false;
|
||||
grn_time = tm_to_grn_time(&date, usec, &tm_truncated);
|
||||
if (tm_truncated) {
|
||||
*truncated = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_DATETIME:
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATETIME"));
|
||||
struct tm datetime;
|
||||
memset(&datetime, 0, sizeof(struct tm));
|
||||
datetime.tm_year = mysql_time->year - TM_YEAR_BASE;
|
||||
if (mysql_time->month > 0) {
|
||||
datetime.tm_mon = mysql_time->month - 1;
|
||||
} else {
|
||||
datetime.tm_mon = 0;
|
||||
*truncated = true;
|
||||
}
|
||||
if (mysql_time->day > 0) {
|
||||
datetime.tm_mday = mysql_time->day;
|
||||
} else {
|
||||
datetime.tm_mday = 1;
|
||||
*truncated = true;
|
||||
}
|
||||
datetime.tm_hour = mysql_time->hour;
|
||||
datetime.tm_min = mysql_time->minute;
|
||||
datetime.tm_sec = mysql_time->second;
|
||||
DBUG_PRINT("info", ("mroonga: tm_year=%d", datetime.tm_year));
|
||||
DBUG_PRINT("info", ("mroonga: tm_mon=%d", datetime.tm_mon));
|
||||
DBUG_PRINT("info", ("mroonga: tm_mday=%d", datetime.tm_mday));
|
||||
DBUG_PRINT("info", ("mroonga: tm_hour=%d", datetime.tm_hour));
|
||||
DBUG_PRINT("info", ("mroonga: tm_min=%d", datetime.tm_min));
|
||||
DBUG_PRINT("info", ("mroonga: tm_sec=%d", datetime.tm_sec));
|
||||
bool tm_truncated = false;
|
||||
grn_time = tm_to_grn_time(&datetime, usec, &tm_truncated);
|
||||
if (tm_truncated) {
|
||||
*truncated = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_TIME:
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_TIME"));
|
||||
int sec =
|
||||
mysql_time->hour * 60 * 60 +
|
||||
mysql_time->minute * 60 +
|
||||
mysql_time->second;
|
||||
DBUG_PRINT("info", ("mroonga: sec=%d", sec));
|
||||
grn_time = GRN_TIME_PACK(sec, usec);
|
||||
if (mysql_time->neg) {
|
||||
grn_time = -grn_time;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DBUG_PRINT("info", ("mroonga: default"));
|
||||
grn_time = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_RETURN(grn_time);
|
||||
}
|
||||
|
||||
void TimeConverter::grn_time_to_mysql_time(long long int grn_time,
|
||||
MYSQL_TIME *mysql_time) {
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
long long int sec;
|
||||
int usec;
|
||||
GRN_TIME_UNPACK(grn_time, sec, usec);
|
||||
DBUG_PRINT("info", ("mroonga: sec=%lld", sec));
|
||||
DBUG_PRINT("info", ("mroonga: usec=%d", usec));
|
||||
switch (mysql_time->time_type) {
|
||||
case MYSQL_TIMESTAMP_DATE:
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATE"));
|
||||
struct tm date;
|
||||
time_t sec_t = sec;
|
||||
// TODO: Add error check
|
||||
gmtime_r(&sec_t, &date);
|
||||
DBUG_PRINT("info", ("mroonga: tm_year=%d", date.tm_year));
|
||||
mysql_time->year = date.tm_year + TM_YEAR_BASE;
|
||||
DBUG_PRINT("info", ("mroonga: tm_mon=%d", date.tm_mon));
|
||||
mysql_time->month = date.tm_mon + 1;
|
||||
DBUG_PRINT("info", ("mroonga: tm_mday=%d", date.tm_mday));
|
||||
mysql_time->day = date.tm_mday;
|
||||
}
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_DATETIME:
|
||||
{
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATETIME"));
|
||||
struct tm date;
|
||||
time_t sec_t = sec;
|
||||
// TODO: Add error check
|
||||
gmtime_r(&sec_t, &date);
|
||||
DBUG_PRINT("info", ("mroonga: tm_year=%d", date.tm_year));
|
||||
mysql_time->year = date.tm_year + TM_YEAR_BASE;
|
||||
DBUG_PRINT("info", ("mroonga: tm_mon=%d", date.tm_mon));
|
||||
mysql_time->month = date.tm_mon + 1;
|
||||
DBUG_PRINT("info", ("mroonga: tm_mday=%d", date.tm_mday));
|
||||
mysql_time->day = date.tm_mday;
|
||||
DBUG_PRINT("info", ("mroonga: tm_hour=%d", date.tm_hour));
|
||||
mysql_time->hour = date.tm_hour;
|
||||
DBUG_PRINT("info", ("mroonga: tm_min=%d", date.tm_min));
|
||||
mysql_time->minute = date.tm_min;
|
||||
DBUG_PRINT("info", ("mroonga: tm_sec=%d", date.tm_sec));
|
||||
mysql_time->second = date.tm_sec;
|
||||
mysql_time->second_part = usec;
|
||||
}
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_TIME:
|
||||
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_TIME"));
|
||||
if (sec < 0) {
|
||||
mysql_time->neg = true;
|
||||
sec = -sec;
|
||||
}
|
||||
mysql_time->hour = static_cast<unsigned int>(sec / 60 / 60);
|
||||
mysql_time->minute = sec / 60 % 60;
|
||||
mysql_time->second = sec % 60;
|
||||
mysql_time->second_part = usec;
|
||||
break;
|
||||
default:
|
||||
DBUG_PRINT("info", ("mroonga: default"));
|
||||
break;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
47
storage/mroonga/lib/mrn_time_converter.hpp
Normal file
47
storage/mroonga/lib/mrn_time_converter.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2010-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_TIME_CONVERTER_HPP_
|
||||
#define MRN_TIME_CONVERTER_HPP_
|
||||
|
||||
#include <groonga.h>
|
||||
#include <mrn_mysql_compat.h>
|
||||
|
||||
namespace mrn {
|
||||
class TimeConverter {
|
||||
public:
|
||||
static const long long int TM_YEAR_BASE = 1900;
|
||||
|
||||
TimeConverter();
|
||||
~TimeConverter();
|
||||
|
||||
long long int mysql_time_to_grn_time(MYSQL_TIME *mysql_time,
|
||||
bool *truncated);
|
||||
|
||||
long long int tm_to_grn_time(struct tm *time, int usec, bool *truncated);
|
||||
|
||||
void grn_time_to_mysql_time(long long int grn_time, MYSQL_TIME *mysql_time);
|
||||
|
||||
private:
|
||||
time_t tm_to_time_gm(struct tm *time, bool *truncated);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* MRN_TIME_CONVERTER_HPP_ */
|
||||
31
storage/mroonga/lib/mrn_windows.hpp
Normal file
31
storage/mroonga/lib/mrn_windows.hpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
/*
|
||||
Copyright(C) 2010 Tetsuro IKEDA
|
||||
Copyright(C) 2010-2013 Kentoku SHIBA
|
||||
Copyright(C) 2011-2013 Kouhei Sutou <kou@clear-code.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MRN_WINDOWS_HPP_
|
||||
#define MRN_WINDOWS_HPP_
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define MRN_API __declspec(dllexport)
|
||||
#else
|
||||
# define MRN_API
|
||||
#endif
|
||||
|
||||
#endif /* MRN_WINDOWS_HPP_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue