mirror of
https://github.com/MariaDB/server.git
synced 2026-04-22 00:05:33 +02:00
Merge branch 'ks-10.1-mroonga' into 10.1
This commit is contained in:
commit
d79fd5ba7f
1798 changed files with 171923 additions and 108728 deletions
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright(C) 2015 Brazil
|
||||
# Copyright(C) 2015-2017 Brazil
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -38,3 +38,104 @@ else()
|
|||
install(TARGETS vector_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
|
||||
endif()
|
||||
target_link_libraries(vector_functions libgroonga)
|
||||
|
||||
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/string_sources.am
|
||||
STRING_SOURCES)
|
||||
set_source_files_properties(${STRING_SOURCES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
|
||||
if(GRN_EMBED)
|
||||
add_library(string_functions STATIC ${STRING_SOURCES})
|
||||
set_target_properties(
|
||||
string_functions
|
||||
PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
add_library(string_functions MODULE ${STRING_SOURCES})
|
||||
set_target_properties(string_functions PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "string")
|
||||
install(TARGETS string_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
|
||||
endif()
|
||||
target_link_libraries(string_functions libgroonga)
|
||||
|
||||
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/number_sources.am
|
||||
NUMBER_SOURCES)
|
||||
set_source_files_properties(${NUMBER_SOURCES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
|
||||
if(GRN_EMBED)
|
||||
add_library(number_functions STATIC ${NUMBER_SOURCES})
|
||||
set_target_properties(
|
||||
number_functions
|
||||
PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
add_library(number_functions MODULE ${NUMBER_SOURCES})
|
||||
set_target_properties(number_functions PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "number")
|
||||
install(TARGETS number_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
|
||||
endif()
|
||||
target_link_libraries(number_functions libgroonga "${M_LIBS}")
|
||||
|
||||
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/time_sources.am
|
||||
TIME_SOURCES)
|
||||
set_source_files_properties(${TIME_SOURCES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
|
||||
if(GRN_EMBED)
|
||||
add_library(time_functions STATIC ${TIME_SOURCES})
|
||||
set_target_properties(
|
||||
time_functions
|
||||
PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
add_library(time_functions MODULE ${TIME_SOURCES})
|
||||
set_target_properties(time_functions PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "time")
|
||||
install(TARGETS time_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
|
||||
endif()
|
||||
target_link_libraries(time_functions libgroonga)
|
||||
|
||||
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/index_column_sources.am
|
||||
INDEX_COLUMN_SOURCES)
|
||||
set_source_files_properties(${INDEX_COLUMN_SOURCES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
|
||||
if(GRN_EMBED)
|
||||
add_library(index_column_functions STATIC ${INDEX_COLUMN_SOURCES})
|
||||
set_target_properties(
|
||||
index_column_functions
|
||||
PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
add_library(index_column_functions MODULE ${INDEX_COLUMN_SOURCES})
|
||||
set_target_properties(index_column_functions PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "index_column")
|
||||
install(TARGETS index_column_functions
|
||||
DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
|
||||
endif()
|
||||
target_link_libraries(index_column_functions libgroonga)
|
||||
|
||||
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/math_sources.am
|
||||
MATH_SOURCES)
|
||||
set_source_files_properties(${MATH_SOURCES}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
|
||||
if(GRN_EMBED)
|
||||
add_library(math_functions STATIC ${MATH_SOURCES})
|
||||
set_target_properties(
|
||||
math_functions
|
||||
PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
add_library(math_functions MODULE ${MATH_SOURCES})
|
||||
set_target_properties(math_functions PROPERTIES
|
||||
PREFIX ""
|
||||
OUTPUT_NAME "math")
|
||||
install(TARGETS math_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
|
||||
endif()
|
||||
target_link_libraries(math_functions libgroonga)
|
||||
|
|
|
|||
|
|
@ -16,5 +16,18 @@ LIBS = \
|
|||
|
||||
function_plugins_LTLIBRARIES =
|
||||
function_plugins_LTLIBRARIES += vector.la
|
||||
function_plugins_LTLIBRARIES += string.la
|
||||
function_plugins_LTLIBRARIES += number.la
|
||||
function_plugins_LTLIBRARIES += time.la
|
||||
function_plugins_LTLIBRARIES += index_column.la
|
||||
function_plugins_LTLIBRARIES += math.la
|
||||
|
||||
include vector_sources.am
|
||||
include string_sources.am
|
||||
include number_sources.am
|
||||
include time_sources.am
|
||||
include index_column_sources.am
|
||||
include math_sources.am
|
||||
|
||||
number_la_LIBADD = -lm
|
||||
math_la_LIBADD = -lm
|
||||
|
|
|
|||
266
storage/mroonga/vendor/groonga/plugins/functions/index_column.c
vendored
Normal file
266
storage/mroonga/vendor/groonga/plugins/functions/index_column.c
vendored
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2017 Brazil
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
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 GRN_EMBEDDED
|
||||
# define GRN_PLUGIN_FUNCTION_TAG functions_time
|
||||
#endif
|
||||
|
||||
#include <groonga/plugin.h>
|
||||
|
||||
static grn_rc
|
||||
selector_index_column_df_ratio_between(grn_ctx *ctx,
|
||||
grn_obj *table,
|
||||
grn_obj *index,
|
||||
int n_args,
|
||||
grn_obj **args,
|
||||
grn_obj *res,
|
||||
grn_operator op)
|
||||
{
|
||||
grn_rc rc = GRN_SUCCESS;
|
||||
grn_obj *index_column;
|
||||
grn_ii *ii;
|
||||
double min;
|
||||
double max;
|
||||
grn_obj *source_table;
|
||||
unsigned int n_documents;
|
||||
grn_posting posting;
|
||||
|
||||
if ((n_args - 1) != 3) {
|
||||
GRN_PLUGIN_ERROR(ctx,
|
||||
GRN_INVALID_ARGUMENT,
|
||||
"index_column_df_ratio_between(): "
|
||||
"wrong number of arguments (%d for 3)", n_args - 1);
|
||||
rc = ctx->rc;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
index_column = args[1];
|
||||
ii = (grn_ii *)index_column;
|
||||
min = GRN_FLOAT_VALUE(args[2]);
|
||||
max = GRN_FLOAT_VALUE(args[3]);
|
||||
|
||||
source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index_column));
|
||||
n_documents = grn_table_size(ctx, source_table);
|
||||
memset(&posting, 0, sizeof(grn_posting));
|
||||
posting.sid = 1;
|
||||
|
||||
if (op == GRN_OP_AND) {
|
||||
GRN_TABLE_EACH_BEGIN(ctx, res, cursor, record_id) {
|
||||
void *key;
|
||||
grn_id term_id;
|
||||
uint32_t n_match_documents;
|
||||
double df_ratio;
|
||||
|
||||
grn_table_cursor_get_key(ctx, cursor, &key);
|
||||
term_id = *(grn_id *)key;
|
||||
n_match_documents = grn_ii_estimate_size(ctx, ii, term_id);
|
||||
if (n_match_documents > n_documents) {
|
||||
n_match_documents = n_documents;
|
||||
}
|
||||
df_ratio = (double)n_match_documents / (double)n_documents;
|
||||
if (min <= df_ratio && df_ratio <= max) {
|
||||
posting.rid = term_id;
|
||||
grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
|
||||
}
|
||||
} GRN_TABLE_EACH_END(ctx, cursor);
|
||||
grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
|
||||
} else {
|
||||
GRN_TABLE_EACH_BEGIN(ctx, table, cursor, term_id) {
|
||||
uint32_t n_match_documents;
|
||||
double df_ratio;
|
||||
|
||||
n_match_documents = grn_ii_estimate_size(ctx, ii, term_id);
|
||||
if (n_match_documents > n_documents) {
|
||||
n_match_documents = n_documents;
|
||||
}
|
||||
df_ratio = (double)n_match_documents / (double)n_documents;
|
||||
{
|
||||
void *key;
|
||||
int key_size;
|
||||
key_size = grn_table_cursor_get_key(ctx, cursor, &key);
|
||||
}
|
||||
if (min <= df_ratio && df_ratio <= max) {
|
||||
posting.rid = term_id;
|
||||
grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op);
|
||||
}
|
||||
} GRN_TABLE_EACH_END(ctx, cursor);
|
||||
}
|
||||
|
||||
exit :
|
||||
return rc;
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_index_column_df_ratio(grn_ctx *ctx,
|
||||
int n_args,
|
||||
grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
grn_obj *term_table;
|
||||
grn_obj *index_column_name;
|
||||
grn_obj *index_column;
|
||||
grn_ii *ii;
|
||||
grn_id term_id;
|
||||
|
||||
if (n_args != 1) {
|
||||
GRN_PLUGIN_ERROR(ctx,
|
||||
GRN_INVALID_ARGUMENT,
|
||||
"index_column_df_ratio(): "
|
||||
"wrong number of arguments (%d for 1)", n_args - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
grn_obj *expr;
|
||||
grn_obj *variable;
|
||||
|
||||
expr = grn_plugin_proc_get_caller(ctx, user_data);
|
||||
if (!expr) {
|
||||
GRN_PLUGIN_ERROR(ctx,
|
||||
GRN_INVALID_ARGUMENT,
|
||||
"index_column_df_ratio(): "
|
||||
"called directly");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
variable = grn_expr_get_var_by_offset(ctx, expr, 0);
|
||||
if (!variable) {
|
||||
GRN_PLUGIN_ERROR(ctx,
|
||||
GRN_INVALID_ARGUMENT,
|
||||
"index_column_df_ratio(): "
|
||||
"caller expression must have target record information");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
term_table = grn_ctx_at(ctx, variable->header.domain);
|
||||
term_id = GRN_RECORD_VALUE(variable);
|
||||
while (GRN_TRUE) {
|
||||
grn_obj *key_type;
|
||||
|
||||
key_type = grn_ctx_at(ctx, term_table->header.domain);
|
||||
if (!grn_obj_is_table(ctx, key_type)) {
|
||||
break;
|
||||
}
|
||||
|
||||
grn_table_get_key(ctx, term_table, term_id, &term_id, sizeof(grn_id));
|
||||
term_table = key_type;
|
||||
}
|
||||
}
|
||||
|
||||
index_column_name = args[0];
|
||||
if (!grn_obj_is_text_family_bulk(ctx, index_column_name)) {
|
||||
grn_obj inspected;
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, index_column_name);
|
||||
GRN_PLUGIN_ERROR(ctx,
|
||||
GRN_INVALID_ARGUMENT,
|
||||
"index_column_df_ratio(): "
|
||||
"the first argument must be index column name: %.*s",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
index_column = grn_obj_column(ctx,
|
||||
term_table,
|
||||
GRN_TEXT_VALUE(index_column_name),
|
||||
GRN_TEXT_LEN(index_column_name));
|
||||
if (!index_column) {
|
||||
GRN_PLUGIN_ERROR(ctx,
|
||||
GRN_INVALID_ARGUMENT,
|
||||
"index_column_df_ratio(): "
|
||||
"nonexistent object: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(index_column_name),
|
||||
GRN_TEXT_VALUE(index_column_name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!grn_obj_is_index_column(ctx, index_column)) {
|
||||
grn_obj inspected;
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, index_column);
|
||||
GRN_PLUGIN_ERROR(ctx,
|
||||
GRN_INVALID_ARGUMENT,
|
||||
"index_column_df_ratio(): "
|
||||
"the first argument must be index column: %.*s",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
if (grn_obj_is_accessor(ctx, index_column)) {
|
||||
grn_obj_unlink(ctx, index_column);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ii = (grn_ii *)index_column;
|
||||
|
||||
{
|
||||
grn_obj *source_table;
|
||||
unsigned int n_documents;
|
||||
uint32_t n_match_documents;
|
||||
double df_ratio;
|
||||
grn_obj *df_ratio_value;
|
||||
|
||||
source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index_column));
|
||||
n_documents = grn_table_size(ctx, source_table);
|
||||
n_match_documents = grn_ii_estimate_size(ctx, ii, term_id);
|
||||
if (n_match_documents > n_documents) {
|
||||
n_match_documents = n_documents;
|
||||
}
|
||||
df_ratio = (double)n_match_documents / (double)n_documents;
|
||||
|
||||
df_ratio_value = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_FLOAT, 0);
|
||||
if (!df_ratio_value) {
|
||||
return NULL;
|
||||
}
|
||||
GRN_FLOAT_SET(ctx, df_ratio_value, df_ratio);
|
||||
return df_ratio_value;
|
||||
}
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_INIT(grn_ctx *ctx)
|
||||
{
|
||||
return ctx->rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_REGISTER(grn_ctx *ctx)
|
||||
{
|
||||
grn_obj *selector_proc;
|
||||
|
||||
selector_proc = grn_proc_create(ctx, "index_column_df_ratio_between", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
NULL, NULL, NULL, 0, NULL);
|
||||
grn_proc_set_selector(ctx, selector_proc,
|
||||
selector_index_column_df_ratio_between);
|
||||
grn_proc_set_selector_operator(ctx, selector_proc, GRN_OP_NOP);
|
||||
|
||||
grn_proc_create(ctx, "index_column_df_ratio", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_index_column_df_ratio, NULL, NULL, 0, NULL);
|
||||
|
||||
return ctx->rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_FIN(grn_ctx *ctx)
|
||||
{
|
||||
return GRN_SUCCESS;
|
||||
}
|
||||
2
storage/mroonga/vendor/groonga/plugins/functions/index_column_sources.am
vendored
Normal file
2
storage/mroonga/vendor/groonga/plugins/functions/index_column_sources.am
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
index_column_la_SOURCES = \
|
||||
index_column.c
|
||||
142
storage/mroonga/vendor/groonga/plugins/functions/math.c
vendored
Normal file
142
storage/mroonga/vendor/groonga/plugins/functions/math.c
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2017 Brazil
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
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 GRN_EMBEDDED
|
||||
# define GRN_PLUGIN_FUNCTION_TAG functions_math
|
||||
#endif
|
||||
|
||||
#include <groonga/plugin.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static grn_obj *
|
||||
func_math_abs(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
grn_obj *number;
|
||||
grn_obj *grn_abs_number = NULL;
|
||||
|
||||
if (n_args != 1) {
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"math_abs(): wrong number of arguments (%d for 1)",
|
||||
n_args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
number = args[0];
|
||||
if (!(number->header.type == GRN_BULK &&
|
||||
grn_type_id_is_number_family(ctx, number->header.domain))) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, number);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"math_abs(): the first argument must be a number: "
|
||||
"<%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define ABS_AS_IS(return_type, to_type, getter, setter) { \
|
||||
grn_abs_number = grn_plugin_proc_alloc(ctx, \
|
||||
user_data, \
|
||||
(return_type), \
|
||||
0); \
|
||||
if (!grn_abs_number) { \
|
||||
return NULL; \
|
||||
} \
|
||||
setter(ctx, grn_abs_number, getter(number)); \
|
||||
}
|
||||
#define ABS_CONVERT_TYPE(func, return_type, to_type, getter, setter) { \
|
||||
grn_abs_number = grn_plugin_proc_alloc(ctx, \
|
||||
user_data, \
|
||||
(return_type), \
|
||||
0); \
|
||||
if (!grn_abs_number) { \
|
||||
return NULL; \
|
||||
} else { \
|
||||
to_type abs_number_raw = (to_type)(func)(getter(number)); \
|
||||
setter(ctx, grn_abs_number, abs_number_raw); \
|
||||
} \
|
||||
}
|
||||
|
||||
switch (number->header.domain) {
|
||||
case GRN_DB_INT8:
|
||||
ABS_CONVERT_TYPE(abs, GRN_DB_UINT8, uint8_t, GRN_INT8_VALUE, GRN_UINT8_SET);
|
||||
break;
|
||||
case GRN_DB_UINT8:
|
||||
ABS_AS_IS(GRN_DB_UINT8, uint8_t, GRN_UINT8_VALUE, GRN_UINT8_SET);
|
||||
break;
|
||||
case GRN_DB_INT16:
|
||||
ABS_CONVERT_TYPE(abs, GRN_DB_UINT16, uint16_t, GRN_INT16_VALUE, GRN_UINT16_SET);
|
||||
break;
|
||||
case GRN_DB_UINT16:
|
||||
ABS_AS_IS(GRN_DB_UINT16, uint16_t, GRN_UINT16_VALUE, GRN_UINT16_SET);
|
||||
break;
|
||||
case GRN_DB_INT32:
|
||||
ABS_CONVERT_TYPE(labs, GRN_DB_UINT32, uint32_t, GRN_INT32_VALUE, GRN_UINT32_SET);
|
||||
break;
|
||||
case GRN_DB_UINT32:
|
||||
ABS_AS_IS(GRN_DB_UINT32, uint32_t, GRN_UINT32_VALUE, GRN_UINT32_SET);
|
||||
break;
|
||||
case GRN_DB_INT64:
|
||||
ABS_CONVERT_TYPE(llabs, GRN_DB_UINT64, uint64_t, GRN_INT64_VALUE, GRN_UINT64_SET);
|
||||
break;
|
||||
case GRN_DB_UINT64:
|
||||
ABS_AS_IS(GRN_DB_UINT64, uint64_t, GRN_UINT64_VALUE, GRN_UINT64_SET);
|
||||
break;
|
||||
case GRN_DB_FLOAT:
|
||||
ABS_CONVERT_TYPE(fabs, GRN_DB_FLOAT, double, GRN_FLOAT_VALUE, GRN_FLOAT_SET);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
#undef ABS_CONVERT_TYPE
|
||||
#undef ABS_AS_IS
|
||||
|
||||
return grn_abs_number;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_INIT(grn_ctx *ctx)
|
||||
{
|
||||
return ctx->rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_REGISTER(grn_ctx *ctx)
|
||||
{
|
||||
grn_rc rc = GRN_SUCCESS;
|
||||
|
||||
grn_proc_create(ctx,
|
||||
"math_abs", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_math_abs,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_FIN(grn_ctx *ctx)
|
||||
{
|
||||
return GRN_SUCCESS;
|
||||
}
|
||||
2
storage/mroonga/vendor/groonga/plugins/functions/math_sources.am
vendored
Normal file
2
storage/mroonga/vendor/groonga/plugins/functions/math_sources.am
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
math_la_SOURCES = \
|
||||
math.c
|
||||
187
storage/mroonga/vendor/groonga/plugins/functions/number.c
vendored
Normal file
187
storage/mroonga/vendor/groonga/plugins/functions/number.c
vendored
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2016 Brazil
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
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 GRN_EMBEDDED
|
||||
# define GRN_PLUGIN_FUNCTION_TAG functions_number
|
||||
#endif
|
||||
|
||||
#include <groonga/plugin.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static grn_obj *
|
||||
func_number_classify(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
grn_obj *number;
|
||||
grn_obj *interval;
|
||||
grn_obj casted_interval;
|
||||
grn_obj *classed_number;
|
||||
|
||||
if (n_args != 2) {
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"number_classify(): wrong number of arguments (%d for 2)",
|
||||
n_args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
number = args[0];
|
||||
if (!(number->header.type == GRN_BULK &&
|
||||
grn_type_id_is_number_family(ctx, number->header.domain))) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, number);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"number_classify(): the first argument must be a number: "
|
||||
"<%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
interval = args[1];
|
||||
if (!(interval->header.type == GRN_BULK &&
|
||||
grn_type_id_is_number_family(ctx, interval->header.domain))) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, interval);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"number_classify(): the second argument must be a number: "
|
||||
"<%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
classed_number = grn_plugin_proc_alloc(ctx,
|
||||
user_data,
|
||||
number->header.domain,
|
||||
0);
|
||||
if (!classed_number) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GRN_VALUE_FIX_SIZE_INIT(&casted_interval, 0, number->header.domain);
|
||||
grn_obj_cast(ctx, interval, &casted_interval, GRN_FALSE);
|
||||
|
||||
#define CLASSIFY_RAW(type, getter, setter, classifier) { \
|
||||
type number_raw; \
|
||||
type interval_raw; \
|
||||
type class_raw; \
|
||||
type classed_number_raw; \
|
||||
\
|
||||
number_raw = getter(number); \
|
||||
interval_raw = getter(&casted_interval); \
|
||||
class_raw = classifier(number_raw, interval_raw); \
|
||||
classed_number_raw = class_raw * interval_raw; \
|
||||
setter(ctx, classed_number, classed_number_raw); \
|
||||
}
|
||||
|
||||
#define CLASSIFIER_INT(number_raw, interval_raw) \
|
||||
(number_raw) < 0 ? \
|
||||
((((number_raw) + 1) / (interval_raw)) - 1) : \
|
||||
(((number_raw) / (interval_raw)))
|
||||
|
||||
#define CLASSIFY_INT(type, getter, setter) \
|
||||
CLASSIFY_RAW(type, getter, setter, CLASSIFIER_INT)
|
||||
|
||||
#define CLASSIFIER_UINT(number_raw, interval_raw) \
|
||||
((number_raw) / (interval_raw))
|
||||
|
||||
#define CLASSIFY_UINT(type, getter, setter) \
|
||||
CLASSIFY_RAW(type, getter, setter, CLASSIFIER_UINT)
|
||||
|
||||
#define CLASSIFIER_FLOAT(number_raw, interval_raw) \
|
||||
floor((number_raw) / (interval_raw))
|
||||
|
||||
#define CLASSIFY_FLOAT(getter, setter) \
|
||||
CLASSIFY_RAW(double, getter, setter, CLASSIFIER_FLOAT)
|
||||
|
||||
switch (number->header.domain) {
|
||||
case GRN_DB_INT8 :
|
||||
CLASSIFY_INT(int8_t, GRN_INT8_VALUE, GRN_INT8_SET);
|
||||
break;
|
||||
case GRN_DB_UINT8 :
|
||||
CLASSIFY_UINT(uint8_t, GRN_UINT8_VALUE, GRN_UINT8_SET);
|
||||
break;
|
||||
case GRN_DB_INT16 :
|
||||
CLASSIFY_INT(int16_t, GRN_INT16_VALUE, GRN_INT16_SET);
|
||||
break;
|
||||
case GRN_DB_UINT16 :
|
||||
CLASSIFY_UINT(uint16_t, GRN_UINT16_VALUE, GRN_UINT16_SET);
|
||||
break;
|
||||
case GRN_DB_INT32 :
|
||||
CLASSIFY_INT(int32_t, GRN_INT32_VALUE, GRN_INT32_SET);
|
||||
break;
|
||||
case GRN_DB_UINT32 :
|
||||
CLASSIFY_UINT(uint32_t, GRN_UINT32_VALUE, GRN_UINT32_SET);
|
||||
break;
|
||||
case GRN_DB_INT64 :
|
||||
CLASSIFY_INT(int64_t, GRN_INT64_VALUE, GRN_INT64_SET);
|
||||
break;
|
||||
case GRN_DB_UINT64 :
|
||||
CLASSIFY_UINT(uint64_t, GRN_UINT64_VALUE, GRN_UINT64_SET);
|
||||
break;
|
||||
case GRN_DB_FLOAT :
|
||||
CLASSIFY_FLOAT(GRN_FLOAT_VALUE, GRN_FLOAT_SET);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
#undef CLASSIFY_FLOAT
|
||||
#undef CLASSIFIER_FLAOT
|
||||
#undef CLASSIFY_UINT
|
||||
#undef CLASSIFIER_UINT
|
||||
#undef CLASSIFY_INT
|
||||
#undef CLASSIFIER_INT
|
||||
#undef CLASSIFY_RAW
|
||||
|
||||
GRN_OBJ_FIN(ctx, &casted_interval);
|
||||
|
||||
return classed_number;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_INIT(grn_ctx *ctx)
|
||||
{
|
||||
return ctx->rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_REGISTER(grn_ctx *ctx)
|
||||
{
|
||||
grn_rc rc = GRN_SUCCESS;
|
||||
|
||||
grn_proc_create(ctx,
|
||||
"number_classify", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_number_classify,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_FIN(grn_ctx *ctx)
|
||||
{
|
||||
return GRN_SUCCESS;
|
||||
}
|
||||
2
storage/mroonga/vendor/groonga/plugins/functions/number_sources.am
vendored
Normal file
2
storage/mroonga/vendor/groonga/plugins/functions/number_sources.am
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
number_la_SOURCES = \
|
||||
number.c
|
||||
299
storage/mroonga/vendor/groonga/plugins/functions/string.c
vendored
Normal file
299
storage/mroonga/vendor/groonga/plugins/functions/string.c
vendored
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2016 Brazil
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
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 GRN_EMBEDDED
|
||||
# define GRN_PLUGIN_FUNCTION_TAG functions_string
|
||||
#endif
|
||||
|
||||
#include <groonga/plugin.h>
|
||||
|
||||
/*
|
||||
* func_string_length() returns the number of characters in a string.
|
||||
* If the string contains an invalid byte sequence, this function returns the
|
||||
* number of characters before the invalid byte sequence.
|
||||
*/
|
||||
static grn_obj *
|
||||
func_string_length(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
grn_obj *target;
|
||||
unsigned int length = 0;
|
||||
grn_obj *grn_length;
|
||||
|
||||
if (n_args != 1) {
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"string_length(): wrong number of arguments (%d for 1)",
|
||||
n_args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target = args[0];
|
||||
if (!(target->header.type == GRN_BULK &&
|
||||
((target->header.domain == GRN_DB_SHORT_TEXT) ||
|
||||
(target->header.domain == GRN_DB_TEXT) ||
|
||||
(target->header.domain == GRN_DB_LONG_TEXT)))) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, target);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"string_length(): target object must be a text bulk: "
|
||||
"<%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
const char *s = GRN_TEXT_VALUE(target);
|
||||
const char *e = GRN_TEXT_VALUE(target) + GRN_TEXT_LEN(target);
|
||||
const char *p;
|
||||
unsigned int cl = 0;
|
||||
for (p = s; p < e && (cl = grn_charlen(ctx, p, e)); p += cl) {
|
||||
length++;
|
||||
}
|
||||
}
|
||||
|
||||
grn_length = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_UINT32, 0);
|
||||
if (!grn_length) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GRN_UINT32_SET(ctx, grn_length, length);
|
||||
|
||||
return grn_length;
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_string_substring(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
grn_obj *target;
|
||||
grn_obj *from_raw;
|
||||
grn_obj *length_raw = NULL;
|
||||
int64_t from = 0;
|
||||
int64_t length = -1;
|
||||
const char *start = NULL;
|
||||
const char *end = NULL;
|
||||
grn_obj *substring;
|
||||
|
||||
if (n_args < 2) {
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"string_substring(): wrong number of arguments (%d for 2..3)",
|
||||
n_args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target = args[0];
|
||||
from_raw = args[1];
|
||||
if (n_args == 3) {
|
||||
length_raw = args[2];
|
||||
}
|
||||
|
||||
if (!(target->header.type == GRN_BULK &&
|
||||
grn_type_id_is_text_family(ctx, target->header.domain))) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, target);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"string_substring(): target object must be a text bulk: "
|
||||
"<%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: extract as grn_func_arg_int64() */
|
||||
if (!grn_type_id_is_number_family(ctx, from_raw->header.domain)) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, from_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"string_substring(): from must be a number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
if (from_raw->header.domain == GRN_DB_INT32) {
|
||||
from = GRN_INT32_VALUE(from_raw);
|
||||
} else if (from_raw->header.domain == GRN_DB_INT64) {
|
||||
from = GRN_INT64_VALUE(from_raw);
|
||||
} else {
|
||||
grn_obj buffer;
|
||||
grn_rc rc;
|
||||
|
||||
GRN_INT64_INIT(&buffer, 0);
|
||||
rc = grn_obj_cast(ctx, from_raw, &buffer, GRN_FALSE);
|
||||
if (rc == GRN_SUCCESS) {
|
||||
from = GRN_INT64_VALUE(&buffer);
|
||||
}
|
||||
GRN_OBJ_FIN(ctx, &buffer);
|
||||
|
||||
if (rc != GRN_SUCCESS) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, from_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, rc,
|
||||
"string_substring(): "
|
||||
"failed to cast from value to number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (length_raw) {
|
||||
/* TODO: extract as grn_func_arg_int64() */
|
||||
if (!grn_type_id_is_number_family(ctx, length_raw->header.domain)) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, length_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"string_substring(): length must be a number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
if (length_raw->header.domain == GRN_DB_INT32) {
|
||||
length = GRN_INT32_VALUE(length_raw);
|
||||
} else if (length_raw->header.domain == GRN_DB_INT64) {
|
||||
length = GRN_INT64_VALUE(length_raw);
|
||||
} else {
|
||||
grn_obj buffer;
|
||||
grn_rc rc;
|
||||
|
||||
GRN_INT64_INIT(&buffer, 0);
|
||||
rc = grn_obj_cast(ctx, length_raw, &buffer, GRN_FALSE);
|
||||
if (rc == GRN_SUCCESS) {
|
||||
length = GRN_INT64_VALUE(&buffer);
|
||||
}
|
||||
GRN_OBJ_FIN(ctx, &buffer);
|
||||
|
||||
if (rc != GRN_SUCCESS) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, length_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, rc,
|
||||
"string_substring(): "
|
||||
"failed to cast length value to number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
substring = grn_plugin_proc_alloc(ctx, user_data, target->header.domain, 0);
|
||||
if (!substring) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GRN_BULK_REWIND(substring);
|
||||
|
||||
if (GRN_TEXT_LEN(target) == 0) {
|
||||
return substring;
|
||||
}
|
||||
if (length == 0) {
|
||||
return substring;
|
||||
}
|
||||
|
||||
while (from < 0) {
|
||||
from += GRN_TEXT_LEN(target);
|
||||
}
|
||||
|
||||
{
|
||||
const char *p;
|
||||
|
||||
start = NULL;
|
||||
p = GRN_TEXT_VALUE(target);
|
||||
end = p + GRN_TEXT_LEN(target);
|
||||
|
||||
if (from == 0) {
|
||||
start = p;
|
||||
} else {
|
||||
unsigned int char_length = 0;
|
||||
size_t n_chars = 0;
|
||||
|
||||
for (;
|
||||
p < end && (char_length = grn_charlen(ctx, p, end));
|
||||
p += char_length, n_chars++) {
|
||||
if (n_chars == from) {
|
||||
start = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (start && length > 0) {
|
||||
unsigned int char_length = 0;
|
||||
size_t n_chars = 0;
|
||||
|
||||
for (;
|
||||
p < end && (char_length = grn_charlen(ctx, p, end));
|
||||
p += char_length, n_chars++) {
|
||||
if (n_chars == length) {
|
||||
end = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (start) {
|
||||
GRN_TEXT_SET(ctx, substring, start, end - start);
|
||||
}
|
||||
|
||||
return substring;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_INIT(grn_ctx *ctx)
|
||||
{
|
||||
return ctx->rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_REGISTER(grn_ctx *ctx)
|
||||
{
|
||||
grn_rc rc = GRN_SUCCESS;
|
||||
|
||||
grn_proc_create(ctx, "string_length", -1, GRN_PROC_FUNCTION, func_string_length,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
grn_proc_create(ctx, "string_substring", -1, GRN_PROC_FUNCTION, func_string_substring,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_FIN(grn_ctx *ctx)
|
||||
{
|
||||
return GRN_SUCCESS;
|
||||
}
|
||||
2
storage/mroonga/vendor/groonga/plugins/functions/string_sources.am
vendored
Normal file
2
storage/mroonga/vendor/groonga/plugins/functions/string_sources.am
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
string_la_SOURCES = \
|
||||
string.c
|
||||
376
storage/mroonga/vendor/groonga/plugins/functions/time.c
vendored
Normal file
376
storage/mroonga/vendor/groonga/plugins/functions/time.c
vendored
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2016 Brazil
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
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 GRN_EMBEDDED
|
||||
# define GRN_PLUGIN_FUNCTION_TAG functions_time
|
||||
#endif
|
||||
|
||||
#include <groonga/plugin.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
typedef enum {
|
||||
GRN_TIME_CLASSIFY_UNIT_SECOND,
|
||||
GRN_TIME_CLASSIFY_UNIT_MINUTE,
|
||||
GRN_TIME_CLASSIFY_UNIT_HOUR,
|
||||
GRN_TIME_CLASSIFY_UNIT_DAY,
|
||||
GRN_TIME_CLASSIFY_UNIT_WEEK,
|
||||
GRN_TIME_CLASSIFY_UNIT_MONTH,
|
||||
GRN_TIME_CLASSIFY_UNIT_YEAR
|
||||
} grn_time_classify_unit;
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_raw(grn_ctx *ctx,
|
||||
int n_args,
|
||||
grn_obj **args,
|
||||
grn_user_data *user_data,
|
||||
const char *function_name,
|
||||
grn_time_classify_unit unit)
|
||||
{
|
||||
grn_obj *time;
|
||||
uint32_t interval_raw = 1;
|
||||
grn_obj *classed_time;
|
||||
grn_bool accept_interval = GRN_TRUE;
|
||||
|
||||
switch (unit) {
|
||||
case GRN_TIME_CLASSIFY_UNIT_SECOND :
|
||||
case GRN_TIME_CLASSIFY_UNIT_MINUTE :
|
||||
case GRN_TIME_CLASSIFY_UNIT_HOUR :
|
||||
accept_interval = GRN_TRUE;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_DAY :
|
||||
case GRN_TIME_CLASSIFY_UNIT_WEEK :
|
||||
accept_interval = GRN_FALSE;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_MONTH :
|
||||
case GRN_TIME_CLASSIFY_UNIT_YEAR :
|
||||
accept_interval = GRN_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (accept_interval) {
|
||||
if (!(n_args == 1 || n_args == 2)) {
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"%s(): "
|
||||
"wrong number of arguments (%d for 1..2)",
|
||||
function_name,
|
||||
n_args);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (n_args != 1) {
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"%s(): "
|
||||
"wrong number of arguments (%d for 1)",
|
||||
function_name,
|
||||
n_args);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
time = args[0];
|
||||
if (!(time->header.type == GRN_BULK &&
|
||||
time->header.domain == GRN_DB_TIME)) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, time);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"%s(): "
|
||||
"the first argument must be a time: "
|
||||
"<%.*s>",
|
||||
function_name,
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (n_args == 2) {
|
||||
grn_obj *interval;
|
||||
grn_obj casted_interval;
|
||||
|
||||
interval = args[1];
|
||||
if (!(interval->header.type == GRN_BULK &&
|
||||
grn_type_id_is_number_family(ctx, interval->header.domain))) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, interval);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"%s(): "
|
||||
"the second argument must be a number: "
|
||||
"<%.*s>",
|
||||
function_name,
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GRN_VALUE_FIX_SIZE_INIT(&casted_interval, 0, GRN_DB_UINT32);
|
||||
grn_obj_cast(ctx, interval, &casted_interval, GRN_FALSE);
|
||||
interval_raw = GRN_UINT32_VALUE(&casted_interval);
|
||||
GRN_OBJ_FIN(ctx, &casted_interval);
|
||||
|
||||
if (interval_raw == 0) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, interval);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"%s(): "
|
||||
"the second argument must not be zero: "
|
||||
"<%.*s>",
|
||||
function_name,
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int64_t time_raw;
|
||||
struct tm tm;
|
||||
int64_t classed_time_raw;
|
||||
|
||||
time_raw = GRN_TIME_VALUE(time);
|
||||
if (!grn_time_to_tm(ctx, time_raw, &tm)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (unit) {
|
||||
case GRN_TIME_CLASSIFY_UNIT_SECOND :
|
||||
tm.tm_sec = (tm.tm_sec / interval_raw) * interval_raw;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_MINUTE :
|
||||
tm.tm_min = (tm.tm_min / interval_raw) * interval_raw;
|
||||
tm.tm_sec = 0;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_HOUR :
|
||||
tm.tm_hour = (tm.tm_hour / interval_raw) * interval_raw;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_DAY :
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_WEEK :
|
||||
if ((tm.tm_mday - tm.tm_wday) >= 0) {
|
||||
tm.tm_mday -= tm.tm_wday;
|
||||
} else {
|
||||
int n_underflowed_mday = -(tm.tm_mday - tm.tm_wday);
|
||||
int mday;
|
||||
int max_mday = 31;
|
||||
|
||||
if (tm.tm_mon == 0) {
|
||||
tm.tm_year--;
|
||||
tm.tm_mon = 11;
|
||||
} else {
|
||||
tm.tm_mon--;
|
||||
}
|
||||
|
||||
for (mday = max_mday; mday > n_underflowed_mday; mday--) {
|
||||
int64_t unused;
|
||||
tm.tm_mday = mday;
|
||||
if (grn_time_from_tm(ctx, &unused, &tm)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tm.tm_mday -= n_underflowed_mday;
|
||||
}
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_MONTH :
|
||||
tm.tm_mon = (tm.tm_mon / interval_raw) * interval_raw;
|
||||
tm.tm_mday = 1;
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
break;
|
||||
case GRN_TIME_CLASSIFY_UNIT_YEAR :
|
||||
tm.tm_year = (((1900 + tm.tm_year) / interval_raw) * interval_raw) - 1900;
|
||||
tm.tm_mon = 0;
|
||||
tm.tm_mday = 1;
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!grn_time_from_tm(ctx, &classed_time_raw, &tm)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
classed_time = grn_plugin_proc_alloc(ctx,
|
||||
user_data,
|
||||
time->header.domain,
|
||||
0);
|
||||
if (!classed_time) {
|
||||
return NULL;
|
||||
}
|
||||
GRN_TIME_SET(ctx, classed_time, classed_time_raw);
|
||||
|
||||
return classed_time;
|
||||
}
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_second(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
return func_time_classify_raw(ctx,
|
||||
n_args,
|
||||
args,
|
||||
user_data,
|
||||
"time_classify_second",
|
||||
GRN_TIME_CLASSIFY_UNIT_SECOND);
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_minute(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
return func_time_classify_raw(ctx,
|
||||
n_args,
|
||||
args,
|
||||
user_data,
|
||||
"time_classify_minute",
|
||||
GRN_TIME_CLASSIFY_UNIT_MINUTE);
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_hour(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
return func_time_classify_raw(ctx,
|
||||
n_args,
|
||||
args,
|
||||
user_data,
|
||||
"time_classify_hour",
|
||||
GRN_TIME_CLASSIFY_UNIT_HOUR);
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_day(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
return func_time_classify_raw(ctx,
|
||||
n_args,
|
||||
args,
|
||||
user_data,
|
||||
"time_classify_day",
|
||||
GRN_TIME_CLASSIFY_UNIT_DAY);
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_week(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
return func_time_classify_raw(ctx,
|
||||
n_args,
|
||||
args,
|
||||
user_data,
|
||||
"time_classify_week",
|
||||
GRN_TIME_CLASSIFY_UNIT_WEEK);
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_month(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
return func_time_classify_raw(ctx,
|
||||
n_args,
|
||||
args,
|
||||
user_data,
|
||||
"time_classify_month",
|
||||
GRN_TIME_CLASSIFY_UNIT_MONTH);
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_time_classify_year(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
return func_time_classify_raw(ctx,
|
||||
n_args,
|
||||
args,
|
||||
user_data,
|
||||
"time_classify_year",
|
||||
GRN_TIME_CLASSIFY_UNIT_YEAR);
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_INIT(grn_ctx *ctx)
|
||||
{
|
||||
return ctx->rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_REGISTER(grn_ctx *ctx)
|
||||
{
|
||||
grn_rc rc = GRN_SUCCESS;
|
||||
|
||||
grn_proc_create(ctx,
|
||||
"time_classify_second", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_time_classify_second,
|
||||
NULL, NULL, 0, NULL);
|
||||
grn_proc_create(ctx,
|
||||
"time_classify_minute", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_time_classify_minute,
|
||||
NULL, NULL, 0, NULL);
|
||||
grn_proc_create(ctx,
|
||||
"time_classify_hour", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_time_classify_hour,
|
||||
NULL, NULL, 0, NULL);
|
||||
grn_proc_create(ctx,
|
||||
"time_classify_day", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_time_classify_day,
|
||||
NULL, NULL, 0, NULL);
|
||||
grn_proc_create(ctx,
|
||||
"time_classify_week", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_time_classify_week,
|
||||
NULL, NULL, 0, NULL);
|
||||
grn_proc_create(ctx,
|
||||
"time_classify_month", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_time_classify_month,
|
||||
NULL, NULL, 0, NULL);
|
||||
grn_proc_create(ctx,
|
||||
"time_classify_year", -1,
|
||||
GRN_PROC_FUNCTION,
|
||||
func_time_classify_year,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_FIN(grn_ctx *ctx)
|
||||
{
|
||||
return GRN_SUCCESS;
|
||||
}
|
||||
2
storage/mroonga/vendor/groonga/plugins/functions/time_sources.am
vendored
Normal file
2
storage/mroonga/vendor/groonga/plugins/functions/time_sources.am
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
time_la_SOURCES = \
|
||||
time.c
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- c-basic-offset: 2 -*- */
|
||||
/*
|
||||
Copyright(C) 2015 Brazil
|
||||
Copyright(C) 2015-2017 Brazil
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -70,6 +70,307 @@ func_vector_size(grn_ctx *ctx, int n_args, grn_obj **args,
|
|||
return grn_size;
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_vector_slice(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
grn_obj *target;
|
||||
grn_obj *from_raw = NULL;
|
||||
grn_obj *length_raw = NULL;
|
||||
int64_t from = 0;
|
||||
int64_t length = -1;
|
||||
uint32_t to = 0;
|
||||
uint32_t size = 0;
|
||||
grn_obj *slice;
|
||||
|
||||
if (n_args < 2 || n_args > 3) {
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"vector_slice(): wrong number of arguments (%d for 2..3)",
|
||||
n_args);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target = args[0];
|
||||
from_raw = args[1];
|
||||
if (n_args == 3) {
|
||||
length_raw = args[2];
|
||||
}
|
||||
switch (target->header.type) {
|
||||
case GRN_VECTOR :
|
||||
case GRN_PVECTOR :
|
||||
case GRN_UVECTOR :
|
||||
size = grn_vector_size(ctx, target);
|
||||
break;
|
||||
default :
|
||||
{
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, target, &inspected);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"vector_slice(): target object must be vector: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!grn_type_id_is_number_family(ctx, from_raw->header.domain)) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, from_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"vector_slice(): from must be a number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
if (from_raw->header.domain == GRN_DB_INT32) {
|
||||
from = GRN_INT32_VALUE(from_raw);
|
||||
} else if (from_raw->header.domain == GRN_DB_INT64) {
|
||||
from = GRN_INT64_VALUE(from_raw);
|
||||
} else {
|
||||
grn_obj buffer;
|
||||
grn_rc rc;
|
||||
|
||||
GRN_INT64_INIT(&buffer, 0);
|
||||
rc = grn_obj_cast(ctx, from_raw, &buffer, GRN_FALSE);
|
||||
if (rc == GRN_SUCCESS) {
|
||||
from = GRN_INT64_VALUE(&buffer);
|
||||
}
|
||||
GRN_OBJ_FIN(ctx, &buffer);
|
||||
|
||||
if (rc != GRN_SUCCESS) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, from_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, rc,
|
||||
"vector_slice(): "
|
||||
"failed to cast from value to number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (length_raw) {
|
||||
if (!grn_type_id_is_number_family(ctx, length_raw->header.domain)) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, length_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
|
||||
"vector_slice(): length must be a number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
if (length_raw->header.domain == GRN_DB_INT32) {
|
||||
length = GRN_INT32_VALUE(length_raw);
|
||||
} else if (length_raw->header.domain == GRN_DB_INT64) {
|
||||
length = GRN_INT64_VALUE(length_raw);
|
||||
} else {
|
||||
grn_obj buffer;
|
||||
grn_rc rc;
|
||||
|
||||
GRN_INT64_INIT(&buffer, 0);
|
||||
rc = grn_obj_cast(ctx, length_raw, &buffer, GRN_FALSE);
|
||||
if (rc == GRN_SUCCESS) {
|
||||
length = GRN_INT64_VALUE(&buffer);
|
||||
}
|
||||
GRN_OBJ_FIN(ctx, &buffer);
|
||||
|
||||
if (rc != GRN_SUCCESS) {
|
||||
grn_obj inspected;
|
||||
|
||||
GRN_TEXT_INIT(&inspected, 0);
|
||||
grn_inspect(ctx, &inspected, length_raw);
|
||||
GRN_PLUGIN_ERROR(ctx, rc,
|
||||
"vector_slice(): "
|
||||
"failed to cast length value to number: <%.*s>",
|
||||
(int)GRN_TEXT_LEN(&inspected),
|
||||
GRN_TEXT_VALUE(&inspected));
|
||||
GRN_OBJ_FIN(ctx, &inspected);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
slice = grn_plugin_proc_alloc(ctx, user_data, target->header.domain, GRN_OBJ_VECTOR);
|
||||
if (!slice) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (target->header.flags & GRN_OBJ_WITH_WEIGHT) {
|
||||
slice->header.flags |= GRN_OBJ_WITH_WEIGHT;
|
||||
}
|
||||
|
||||
if (length < 0) {
|
||||
length = size + length + 1;
|
||||
}
|
||||
|
||||
if (length > size) {
|
||||
length = size;
|
||||
}
|
||||
|
||||
if (length <= 0) {
|
||||
return slice;
|
||||
}
|
||||
|
||||
while (from < 0) {
|
||||
from += size;
|
||||
}
|
||||
|
||||
to = from + length;
|
||||
if (to > size) {
|
||||
to = size;
|
||||
}
|
||||
|
||||
switch (target->header.type) {
|
||||
case GRN_VECTOR :
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = from; i < to; i++) {
|
||||
const char *content;
|
||||
unsigned int content_length;
|
||||
unsigned int weight;
|
||||
grn_id domain;
|
||||
content_length = grn_vector_get_element(ctx, target, i,
|
||||
&content, &weight, &domain);
|
||||
grn_vector_add_element(ctx, slice,
|
||||
content, content_length, weight, domain);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRN_PVECTOR :
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = from; i < to; i++) {
|
||||
grn_obj *element = GRN_PTR_VALUE_AT(target, i);
|
||||
GRN_PTR_PUT(ctx, slice, element);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRN_UVECTOR :
|
||||
{
|
||||
grn_obj *domain;
|
||||
|
||||
domain = grn_ctx_at(ctx, target->header.domain);
|
||||
if (grn_obj_is_table(ctx, domain)) {
|
||||
unsigned int i;
|
||||
for (i = from; i < to; i++) {
|
||||
grn_id id;
|
||||
unsigned int weight;
|
||||
id = grn_uvector_get_element(ctx, target, i, &weight);
|
||||
grn_uvector_add_element(ctx, slice, id, weight);
|
||||
}
|
||||
} else {
|
||||
#define PUT_SLICE_VALUES(type) do { \
|
||||
unsigned int i; \
|
||||
for (i = from; i < to; i++) { \
|
||||
GRN_ ## type ## _PUT(ctx, \
|
||||
slice, \
|
||||
GRN_ ## type ## _VALUE_AT(target, i)); \
|
||||
} \
|
||||
} while (GRN_FALSE)
|
||||
switch (target->header.domain) {
|
||||
case GRN_DB_BOOL :
|
||||
PUT_SLICE_VALUES(BOOL);
|
||||
break;
|
||||
case GRN_DB_INT8 :
|
||||
PUT_SLICE_VALUES(INT8);
|
||||
break;
|
||||
case GRN_DB_UINT8 :
|
||||
PUT_SLICE_VALUES(UINT8);
|
||||
break;
|
||||
case GRN_DB_INT16 :
|
||||
PUT_SLICE_VALUES(INT16);
|
||||
break;
|
||||
case GRN_DB_UINT16 :
|
||||
PUT_SLICE_VALUES(UINT16);
|
||||
break;
|
||||
case GRN_DB_INT32 :
|
||||
PUT_SLICE_VALUES(INT32);
|
||||
break;
|
||||
case GRN_DB_UINT32 :
|
||||
PUT_SLICE_VALUES(UINT32);
|
||||
break;
|
||||
case GRN_DB_INT64 :
|
||||
PUT_SLICE_VALUES(INT64);
|
||||
break;
|
||||
case GRN_DB_UINT64 :
|
||||
PUT_SLICE_VALUES(UINT64);
|
||||
break;
|
||||
case GRN_DB_FLOAT :
|
||||
PUT_SLICE_VALUES(FLOAT);
|
||||
break;
|
||||
case GRN_DB_TIME :
|
||||
PUT_SLICE_VALUES(TIME);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#undef PUT_SLICE_VALUES
|
||||
}
|
||||
|
||||
return slice;
|
||||
}
|
||||
|
||||
static grn_obj *
|
||||
func_vector_new(grn_ctx *ctx, int n_args, grn_obj **args,
|
||||
grn_user_data *user_data)
|
||||
{
|
||||
grn_obj *vector = NULL;
|
||||
int i;
|
||||
|
||||
if (n_args == 0) {
|
||||
return grn_plugin_proc_alloc(ctx, user_data, GRN_DB_UINT32, GRN_OBJ_VECTOR);
|
||||
}
|
||||
|
||||
vector = grn_plugin_proc_alloc(ctx,
|
||||
user_data,
|
||||
args[0]->header.domain,
|
||||
GRN_OBJ_VECTOR);
|
||||
if (!vector) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_args; i++) {
|
||||
grn_obj *element = args[i];
|
||||
switch (vector->header.type) {
|
||||
case GRN_VECTOR :
|
||||
grn_vector_add_element(ctx,
|
||||
vector,
|
||||
GRN_BULK_HEAD(element),
|
||||
GRN_BULK_VSIZE(element),
|
||||
0,
|
||||
element->header.domain);
|
||||
break;
|
||||
case GRN_UVECTOR :
|
||||
grn_bulk_write(ctx,
|
||||
vector,
|
||||
GRN_BULK_HEAD(element),
|
||||
GRN_BULK_VSIZE(element));
|
||||
break;
|
||||
case GRN_PVECTOR :
|
||||
GRN_PTR_PUT(ctx, vector, element);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
grn_rc
|
||||
GRN_PLUGIN_INIT(grn_ctx *ctx)
|
||||
{
|
||||
|
|
@ -84,6 +385,12 @@ GRN_PLUGIN_REGISTER(grn_ctx *ctx)
|
|||
grn_proc_create(ctx, "vector_size", -1, GRN_PROC_FUNCTION, func_vector_size,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
grn_proc_create(ctx, "vector_slice", -1, GRN_PROC_FUNCTION, func_vector_slice,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
grn_proc_create(ctx, "vector_new", -1, GRN_PROC_FUNCTION, func_vector_new,
|
||||
NULL, NULL, 0, NULL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue