| 1 | /* -*- c-basic-offset: 2 -*- */ |
| 2 | /* |
| 3 | Copyright(C) 2009-2016 Brazil |
| 4 | |
| 5 | This library is free software; you can redistribute it and/or |
| 6 | modify it under the terms of the GNU Lesser General Public |
| 7 | License version 2.1 as published by the Free Software Foundation. |
| 8 | |
| 9 | This library is distributed in the hope that it will be useful, |
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 | Lesser General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU Lesser General Public |
| 15 | License along with this library; if not, write to the Free Software |
| 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 17 | */ |
| 18 | |
| 19 | #pragma once |
| 20 | |
| 21 | #include "grn.h" |
| 22 | #include "grn_ctx.h" |
| 23 | #include "grn_store.h" |
| 24 | #include "grn_rset.h" |
| 25 | |
| 26 | #include <groonga/command.h> |
| 27 | #include <groonga/token_filter.h> |
| 28 | #include <groonga/scorer.h> |
| 29 | |
| 30 | #include <float.h> |
| 31 | |
| 32 | #ifdef __cplusplus |
| 33 | extern "C" { |
| 34 | #endif |
| 35 | |
| 36 | #define GRN_DB_DELIMITER '.' |
| 37 | #define GRN_DB_PSEUDO_COLUMN_PREFIX '_' |
| 38 | |
| 39 | #define GRN_N_RESERVED_TYPES 256 |
| 40 | |
| 41 | typedef struct _grn_db grn_db; |
| 42 | typedef struct _grn_proc grn_proc; |
| 43 | |
| 44 | struct _grn_db { |
| 45 | grn_db_obj obj; |
| 46 | grn_obj *keys; |
| 47 | grn_ja *specs; |
| 48 | grn_hash *config; |
| 49 | grn_tiny_array values; |
| 50 | grn_critical_section lock; |
| 51 | }; |
| 52 | |
| 53 | #define GRN_SERIALIZED_SPEC_INDEX_SPEC 0 |
| 54 | #define GRN_SERIALIZED_SPEC_INDEX_PATH 1 |
| 55 | #define GRN_SERIALIZED_SPEC_INDEX_SOURCE 2 |
| 56 | #define GRN_SERIALIZED_SPEC_INDEX_HOOK 3 |
| 57 | #define GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS 4 |
| 58 | #define GRN_SERIALIZED_SPEC_INDEX_EXPR 4 |
| 59 | |
| 60 | typedef struct { |
| 61 | grn_obj_header ; |
| 62 | grn_id range; |
| 63 | } grn_obj_spec; |
| 64 | |
| 65 | grn_bool grn_db_spec_unpack(grn_ctx *ctx, |
| 66 | grn_id id, |
| 67 | void *encoded_spec, |
| 68 | uint32_t encoded_spec_size, |
| 69 | grn_obj_spec **spec, |
| 70 | grn_obj *decoded_spec, |
| 71 | const char *error_message_tag); |
| 72 | |
| 73 | #define GRN_DB_SPEC_EACH_BEGIN(ctx, cursor, id, spec) do { \ |
| 74 | grn_obj *db = grn_ctx_db((ctx)); \ |
| 75 | grn_db *db_raw = (grn_db *)db; \ |
| 76 | grn_obj decoded_spec; \ |
| 77 | grn_io_win iw; \ |
| 78 | grn_bool iw_need_unref = GRN_FALSE; \ |
| 79 | GRN_OBJ_INIT(&decoded_spec, GRN_VECTOR, 0, GRN_DB_TEXT); \ |
| 80 | GRN_TABLE_EACH_BEGIN((ctx), db, cursor, id) { \ |
| 81 | void *encoded_spec; \ |
| 82 | uint32_t encoded_spec_size; \ |
| 83 | grn_bool success; \ |
| 84 | grn_obj_spec *spec; \ |
| 85 | \ |
| 86 | if (iw_need_unref) { \ |
| 87 | grn_ja_unref(ctx, &iw); \ |
| 88 | iw_need_unref = GRN_FALSE; \ |
| 89 | } \ |
| 90 | encoded_spec = grn_ja_ref((ctx), \ |
| 91 | db_raw->specs, \ |
| 92 | id, \ |
| 93 | &iw, \ |
| 94 | &encoded_spec_size); \ |
| 95 | if (!encoded_spec) { \ |
| 96 | continue; \ |
| 97 | } \ |
| 98 | iw_need_unref = GRN_TRUE; \ |
| 99 | \ |
| 100 | GRN_BULK_REWIND(&decoded_spec); \ |
| 101 | success = grn_db_spec_unpack(ctx, \ |
| 102 | id, \ |
| 103 | encoded_spec, \ |
| 104 | encoded_spec_size, \ |
| 105 | &spec, \ |
| 106 | &decoded_spec, \ |
| 107 | __FUNCTION__); \ |
| 108 | if (!success) { \ |
| 109 | continue; \ |
| 110 | } \ |
| 111 | |
| 112 | #define GRN_DB_SPEC_EACH_END(ctx, cursor) \ |
| 113 | } GRN_TABLE_EACH_END(ctx, cursor); \ |
| 114 | if (iw_need_unref) { \ |
| 115 | grn_ja_unref(ctx, &iw); \ |
| 116 | } \ |
| 117 | GRN_OBJ_FIN((ctx), &decoded_spec); \ |
| 118 | } while(GRN_FALSE) |
| 119 | |
| 120 | void grn_db_init_from_env(void); |
| 121 | |
| 122 | GRN_API grn_rc grn_db_close(grn_ctx *ctx, grn_obj *db); |
| 123 | |
| 124 | grn_obj *grn_db_keys(grn_obj *s); |
| 125 | |
| 126 | void grn_db_generate_pathname(grn_ctx *ctx, |
| 127 | grn_obj *db, |
| 128 | grn_id id, |
| 129 | char *buffer); |
| 130 | |
| 131 | grn_rc _grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id, |
| 132 | grn_table_delete_optarg *optarg); |
| 133 | |
| 134 | grn_id grn_table_get_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size, |
| 135 | void **value); |
| 136 | grn_id grn_table_add_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size, |
| 137 | void **value, int *added); |
| 138 | grn_id grn_table_add_by_key(grn_ctx *ctx, |
| 139 | grn_obj *table, |
| 140 | grn_obj *key, |
| 141 | int *added); |
| 142 | GRN_API grn_rc grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_table_flags *flags, |
| 143 | grn_encoding *encoding, grn_obj **tokenizer, |
| 144 | grn_obj **normalizer, |
| 145 | grn_obj **token_filters); |
| 146 | const char *_grn_table_key(grn_ctx *ctx, grn_obj *table, grn_id id, uint32_t *key_size); |
| 147 | |
| 148 | grn_rc grn_table_search(grn_ctx *ctx, grn_obj *table, |
| 149 | const void *key, uint32_t key_size, |
| 150 | grn_operator mode, grn_obj *res, grn_operator op); |
| 151 | |
| 152 | grn_rc grn_table_fuzzy_search(grn_ctx *ctx, grn_obj *table, |
| 153 | const void *key, uint32_t key_size, |
| 154 | grn_fuzzy_search_optarg *args, grn_obj *res, grn_operator op); |
| 155 | |
| 156 | grn_id grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id); |
| 157 | |
| 158 | int grn_table_get_key2(grn_ctx *ctx, grn_obj *table, grn_id id, grn_obj *bulk); |
| 159 | |
| 160 | grn_table_cursor *grn_table_cursor_open_by_id(grn_ctx *ctx, grn_obj *table, |
| 161 | grn_id min, grn_id max, int flags); |
| 162 | |
| 163 | void grn_table_add_subrec(grn_obj *table, grn_rset_recinfo *ri, double score, |
| 164 | grn_rset_posinfo *pi, int dir); |
| 165 | |
| 166 | grn_obj *grn_obj_graft(grn_ctx *ctx, grn_obj *obj); |
| 167 | |
| 168 | grn_rc grn_column_name_(grn_ctx *ctx, grn_obj *obj, grn_obj *buf); |
| 169 | |
| 170 | |
| 171 | typedef enum { |
| 172 | PROC_INIT = 0, |
| 173 | PROC_NEXT, |
| 174 | PROC_FIN |
| 175 | } grn_proc_phase; |
| 176 | |
| 177 | struct _grn_type { |
| 178 | grn_db_obj obj; |
| 179 | }; |
| 180 | |
| 181 | #define GRN_TYPE_SIZE(type) ((type)->range) |
| 182 | |
| 183 | #define GRN_TABLE_SORT_GEO (0x02<<0) |
| 184 | |
| 185 | #define GRN_OBJ_TMP_OBJECT 0x80000000 |
| 186 | #define GRN_OBJ_TMP_COLUMN 0x40000000 |
| 187 | |
| 188 | #define GRN_DB_OBJP(obj) \ |
| 189 | (obj &&\ |
| 190 | ((GRN_SNIP == ((grn_db_obj *)obj)->header.type) ||\ |
| 191 | ((GRN_CURSOR_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\ |
| 192 | (((grn_db_obj *)obj)->header.type <= GRN_COLUMN_INDEX)))) |
| 193 | |
| 194 | #define GRN_OBJ_TABLEP(obj) \ |
| 195 | (obj &&\ |
| 196 | (GRN_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\ |
| 197 | (((grn_db_obj *)obj)->header.type <= GRN_DB)) |
| 198 | |
| 199 | #define GRN_OBJ_INDEX_COLUMNP(obj) \ |
| 200 | (obj &&\ |
| 201 | DB_OBJ(obj)->header.type == GRN_COLUMN_INDEX) |
| 202 | |
| 203 | #define GRN_OBJ_VECTOR_COLUMNP(obj) \ |
| 204 | (obj &&\ |
| 205 | DB_OBJ(obj)->header.type == GRN_COLUMN_VAR_SIZE &&\ |
| 206 | (DB_OBJ(obj)->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR) |
| 207 | |
| 208 | #define GRN_OBJ_WEIGHT_VECTOR_COLUMNP(obj) \ |
| 209 | (GRN_OBJ_VECTOR_COLUMNP(obj) &&\ |
| 210 | (DB_OBJ(obj)->header.flags & GRN_OBJ_WITH_WEIGHT)) |
| 211 | |
| 212 | struct _grn_hook { |
| 213 | grn_hook *next; |
| 214 | grn_proc *proc; |
| 215 | uint32_t hld_size; |
| 216 | }; |
| 217 | |
| 218 | typedef struct _grn_proc_ctx grn_proc_ctx; |
| 219 | |
| 220 | struct _grn_proc_ctx { |
| 221 | grn_user_data user_data; |
| 222 | grn_proc *proc; |
| 223 | grn_obj *caller; |
| 224 | // grn_obj *obj; |
| 225 | grn_hook *hooks; |
| 226 | grn_hook *currh; |
| 227 | grn_proc_phase phase; |
| 228 | unsigned short nargs; |
| 229 | unsigned short offset; |
| 230 | grn_user_data data[16]; |
| 231 | }; |
| 232 | |
| 233 | struct _grn_proc { |
| 234 | grn_db_obj obj; |
| 235 | grn_obj name_buf; |
| 236 | grn_expr_var *vars; |
| 237 | uint32_t nvars; |
| 238 | /* -- compatible with grn_expr -- */ |
| 239 | grn_proc_type type; |
| 240 | grn_proc_func *funcs[3]; |
| 241 | |
| 242 | union { |
| 243 | struct { |
| 244 | grn_selector_func *selector; |
| 245 | grn_operator selector_op; |
| 246 | grn_bool is_stable; |
| 247 | } function; |
| 248 | struct { |
| 249 | grn_command_run_func *run; |
| 250 | } command; |
| 251 | struct { |
| 252 | grn_token_filter_init_func *init; |
| 253 | grn_token_filter_filter_func *filter; |
| 254 | grn_token_filter_fin_func *fin; |
| 255 | } token_filter; |
| 256 | struct { |
| 257 | grn_scorer_score_func *score; |
| 258 | } scorer; |
| 259 | grn_window_function_func *window_function; |
| 260 | } callbacks; |
| 261 | |
| 262 | void *user_data; |
| 263 | |
| 264 | grn_id module; |
| 265 | // uint32_t nargs; |
| 266 | // uint32_t nresults; |
| 267 | // grn_obj results[16]; |
| 268 | }; |
| 269 | |
| 270 | #define GRN_PROC_GET_VARS() (grn_proc_get_vars(ctx, user_data)) |
| 271 | #define GRN_PROC_GET_VAR(name) (grn_proc_get_var(ctx, user_data, name, strlen(name))) |
| 272 | #define GRN_PROC_GET_VAR_BY_OFFSET(offset) (grn_proc_get_var_by_offset(ctx, user_data, offset)) |
| 273 | #define GRN_PROC_GET_OR_ADD_VAR(name) (grn_proc_get_or_add_var(ctx, user_data, name, strlen(name))) |
| 274 | #define GRN_PROC_ALLOC(domain, flags) (grn_proc_alloc(ctx, user_data, domain, flags)) |
| 275 | |
| 276 | grn_obj *grn_proc_get_vars(grn_ctx *ctx, grn_user_data *user_data); |
| 277 | |
| 278 | grn_obj *grn_proc_get_var(grn_ctx *ctx, grn_user_data *user_data, |
| 279 | const char *name, unsigned int name_size); |
| 280 | |
| 281 | GRN_API grn_obj *grn_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_data, |
| 282 | unsigned int offset); |
| 283 | GRN_API grn_obj *grn_proc_get_or_add_var(grn_ctx *ctx, grn_user_data *user_data, |
| 284 | const char *name, unsigned int name_size); |
| 285 | |
| 286 | GRN_API grn_obj *grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data, |
| 287 | grn_id domain, unsigned char flags); |
| 288 | |
| 289 | GRN_API grn_rc grn_proc_call(grn_ctx *ctx, grn_obj *proc, |
| 290 | int nargs, grn_obj *caller); |
| 291 | |
| 292 | grn_obj *grn_expr_get_or_add_var(grn_ctx *ctx, grn_obj *expr, |
| 293 | const char *name, unsigned int name_size); |
| 294 | |
| 295 | |
| 296 | typedef struct _grn_accessor grn_accessor; |
| 297 | |
| 298 | struct _grn_accessor { |
| 299 | grn_obj_header ; |
| 300 | grn_id range; |
| 301 | /* -- compatible with grn_db_obj -- */ |
| 302 | uint8_t action; |
| 303 | int offset; |
| 304 | grn_obj *obj; |
| 305 | grn_accessor *next; |
| 306 | }; |
| 307 | |
| 308 | enum { |
| 309 | GRN_ACCESSOR_VOID = 0, |
| 310 | GRN_ACCESSOR_GET_ID, |
| 311 | GRN_ACCESSOR_GET_KEY, |
| 312 | GRN_ACCESSOR_GET_VALUE, |
| 313 | GRN_ACCESSOR_GET_SCORE, |
| 314 | GRN_ACCESSOR_GET_NSUBRECS, |
| 315 | GRN_ACCESSOR_GET_MAX, |
| 316 | GRN_ACCESSOR_GET_MIN, |
| 317 | GRN_ACCESSOR_GET_SUM, |
| 318 | GRN_ACCESSOR_GET_AVG, |
| 319 | GRN_ACCESSOR_GET_COLUMN_VALUE, |
| 320 | GRN_ACCESSOR_GET_DB_OBJ, |
| 321 | GRN_ACCESSOR_LOOKUP, |
| 322 | GRN_ACCESSOR_FUNCALL |
| 323 | }; |
| 324 | |
| 325 | #define DB_OBJ(obj) ((grn_db_obj *)obj) |
| 326 | |
| 327 | GRN_API const char *grn_obj_get_value_(grn_ctx *ctx, grn_obj *obj, grn_id id, uint32_t *size); |
| 328 | |
| 329 | /* vector */ |
| 330 | |
| 331 | /* |
| 332 | typedef struct _grn_vector grn_vector; |
| 333 | |
| 334 | struct _grn_vector { |
| 335 | grn_obj str; |
| 336 | uint32_t *offsets; |
| 337 | int n_entries; |
| 338 | }; |
| 339 | |
| 340 | const char *grn_vector_fetch(grn_ctx *ctx, grn_obj *vector, int i, unsigned int *size); |
| 341 | int grn_vector_delimit(grn_ctx *ctx, grn_obj *vector); |
| 342 | int grn_vector_size(grn_ctx *ctx, grn_obj *vector); |
| 343 | */ |
| 344 | |
| 345 | grn_rc grn_vector_delimit(grn_ctx *ctx, grn_obj *v, unsigned int weight, grn_id domain); |
| 346 | grn_rc grn_vector_decode(grn_ctx *ctx, grn_obj *v, const char *data, uint32_t data_size); |
| 347 | |
| 348 | |
| 349 | grn_rc grn_db_init_builtin_types(grn_ctx *ctx); |
| 350 | |
| 351 | /* flag value used for grn_obj.header.flags */ |
| 352 | |
| 353 | #define GRN_OBJ_CUSTOM_NAME (0x01<<12) /* db_obj which has custom name */ |
| 354 | |
| 355 | #define GRN_OBJ_RESOLVE(ctx,obj) \ |
| 356 | (((obj)->header.type != GRN_PTR)\ |
| 357 | ? (obj)\ |
| 358 | : GRN_PTR_VALUE(obj)\ |
| 359 | ? GRN_PTR_VALUE(obj)\ |
| 360 | : grn_ctx_at((ctx), (obj)->header.domain)) |
| 361 | |
| 362 | /* expr */ |
| 363 | |
| 364 | typedef struct _grn_expr grn_expr; |
| 365 | |
| 366 | #define GRN_EXPR_CODE_RELATIONAL_EXPRESSION (0x01) |
| 367 | |
| 368 | typedef struct { |
| 369 | grn_obj *value; |
| 370 | int32_t nargs; |
| 371 | grn_operator op; |
| 372 | uint8_t flags; |
| 373 | int32_t modify; |
| 374 | } grn_expr_code; |
| 375 | |
| 376 | #define GRN_EXPR_CONST_BLK_SIZE GRN_STACK_SIZE |
| 377 | |
| 378 | struct _grn_expr { |
| 379 | grn_db_obj obj; |
| 380 | grn_obj name_buf; |
| 381 | grn_expr_var *vars; |
| 382 | uint32_t nvars; |
| 383 | /* -- compatible with grn_proc -- */ |
| 384 | |
| 385 | uint16_t cacheable; |
| 386 | uint16_t taintable; |
| 387 | grn_obj **const_blks; |
| 388 | grn_obj *values; |
| 389 | grn_expr_code *codes; |
| 390 | uint32_t nconsts; |
| 391 | uint32_t values_curr; |
| 392 | uint32_t values_tail; |
| 393 | uint32_t values_size; |
| 394 | uint32_t codes_curr; |
| 395 | uint32_t codes_size; |
| 396 | |
| 397 | grn_obj objs; |
| 398 | grn_obj dfi; |
| 399 | grn_expr_code *code0; |
| 400 | }; |
| 401 | |
| 402 | grn_rc grn_expr_parser_close(grn_ctx *ctx); |
| 403 | |
| 404 | /** |
| 405 | * grn_table_open: |
| 406 | * @name: The table name to be opened. `NULL` means anonymous table. |
| 407 | * @path: The path of the table to be opened. |
| 408 | * |
| 409 | * Opens an existing table. The table is associated with @name in DB |
| 410 | * that is used by @ctx. grn_ctx_get() is better rather than this |
| 411 | * function when you want to open a permanent named table that is |
| 412 | * registered in DB. |
| 413 | **/ |
| 414 | GRN_API grn_obj *grn_table_open(grn_ctx *ctx, |
| 415 | const char *name, unsigned int name_size, |
| 416 | const char *path); |
| 417 | |
| 418 | /** |
| 419 | * grn_column_open: |
| 420 | * @table: The table for the opened column. |
| 421 | * @name: The column name to be opened. |
| 422 | * @path: The path of the column to be opened. |
| 423 | * @type: The type of the column value. |
| 424 | * |
| 425 | * Opens an existing permanent column. The column is associated with |
| 426 | * @name in @table. grn_ctx_get() is better rather than this function |
| 427 | * when you want to open a column of an permanent table in DB. |
| 428 | **/ |
| 429 | grn_obj *grn_column_open(grn_ctx *ctx, grn_obj *table, |
| 430 | const char *name, unsigned int name_size, |
| 431 | const char *path, grn_obj *type); |
| 432 | |
| 433 | /** |
| 434 | * grn_obj_path_rename: |
| 435 | * @old_path: The current file path. |
| 436 | * @new_path: The new file path. |
| 437 | * |
| 438 | * It renames object's path that is stored in @old_path to @new_path. |
| 439 | **/ |
| 440 | grn_rc grn_obj_path_rename(grn_ctx *ctx, const char *old_path, const char *new_path); |
| 441 | |
| 442 | grn_rc grn_db_check_name(grn_ctx *ctx, const char *name, unsigned int name_size); |
| 443 | #define GRN_DB_CHECK_NAME_ERR(error_context, name, name_size) \ |
| 444 | ERR(GRN_INVALID_ARGUMENT,\ |
| 445 | "%s name can't start with '%c' and contains only 0-9, A-Z, a-z, #, @, - or _: <%.*s>",\ |
| 446 | error_context, GRN_DB_PSEUDO_COLUMN_PREFIX, name_size, name) |
| 447 | |
| 448 | #define GRN_DB_P(s) ((s) && ((grn_db *)s)->obj.header.type == GRN_DB) |
| 449 | #define GRN_DB_PERSISTENT_P(s) (((grn_db *)s)->specs) |
| 450 | |
| 451 | #define GRN_OBJ_GET_VALUE_IMD (0xffffffffU) |
| 452 | |
| 453 | grn_rc grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj); |
| 454 | |
| 455 | #define GRN_ACCESSORP(obj) \ |
| 456 | ((obj) && (((grn_obj *)(obj))->header.type == GRN_ACCESSOR)) |
| 457 | |
| 458 | grn_id grn_obj_register(grn_ctx *ctx, grn_obj *db, const char *name, unsigned int name_size); |
| 459 | int grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj); |
| 460 | void grn_obj_spec_save(grn_ctx *ctx, grn_db_obj *obj); |
| 461 | |
| 462 | grn_rc grn_obj_reinit_for(grn_ctx *ctx, grn_obj *obj, grn_obj *domain_obj); |
| 463 | |
| 464 | void grn_expr_pack(grn_ctx *ctx, grn_obj *buf, grn_obj *expr); |
| 465 | GRN_API grn_rc grn_expr_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *expr); |
| 466 | grn_hash *grn_expr_get_vars(grn_ctx *ctx, grn_obj *expr, unsigned int *nvars); |
| 467 | grn_obj *grn_expr_open(grn_ctx *ctx, grn_obj_spec *spec, const uint8_t *p, const uint8_t *pe); |
| 468 | |
| 469 | GRN_API grn_rc grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table, |
| 470 | grn_table_sort_key *group_key, |
| 471 | grn_obj *result_set, |
| 472 | uint32_t range_gap); |
| 473 | |
| 474 | GRN_API grn_rc grn_column_filter(grn_ctx *ctx, grn_obj *column, |
| 475 | grn_operator op, |
| 476 | grn_obj *value, grn_obj *result_set, |
| 477 | grn_operator set_op); |
| 478 | |
| 479 | typedef struct { |
| 480 | grn_id target; |
| 481 | unsigned int section; |
| 482 | } grn_obj_default_set_value_hook_data; |
| 483 | |
| 484 | grn_obj *grn_obj_default_set_value_hook(grn_ctx *ctx, |
| 485 | int nargs, |
| 486 | grn_obj **args, |
| 487 | grn_user_data *user_data); |
| 488 | |
| 489 | grn_rc grn_pvector_fin(grn_ctx *ctx, grn_obj *obj); |
| 490 | |
| 491 | #ifdef __cplusplus |
| 492 | } |
| 493 | #endif |
| 494 | |