Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #25 from groonga/support-selector
Browse files Browse the repository at this point in the history
Support custom selector definition
  • Loading branch information
daijiro committed Aug 14, 2012
2 parents abb125f + 1f8dd65 commit f9035f7
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 24 deletions.
9 changes: 9 additions & 0 deletions lib/db.h
Expand Up @@ -153,6 +153,10 @@ typedef struct {
(GRN_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\
(((grn_db_obj *)obj)->header.type <= GRN_DB))

typedef grn_rc grn_selector_func(grn_ctx *ctx, grn_obj *index,
int nargs, grn_obj **args,
grn_obj *res, grn_operator op);

typedef struct _grn_proc_ctx grn_proc_ctx;

struct _grn_proc_ctx {
Expand All @@ -177,6 +181,8 @@ struct _grn_proc {
grn_proc_type type;
grn_proc_func *funcs[3];

grn_selector_func *selector;

grn_id module;
// uint32_t nargs;
// uint32_t nresults;
Expand All @@ -196,6 +202,9 @@ GRN_API grn_obj *grn_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_da
GRN_API grn_obj *grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data,
grn_id domain, grn_obj_flags flags);

grn_rc grn_proc_set_selector(grn_ctx *ctx, grn_obj *proc,
grn_selector_func selector);

grn_obj *grn_expr_get_or_add_var(grn_ctx *ctx, grn_obj *expr,
const char *name, unsigned int name_size);

Expand Down
39 changes: 25 additions & 14 deletions lib/expr.c
Expand Up @@ -32,6 +32,12 @@ function_proc_p(grn_obj *obj)
((grn_proc *)obj)->type == GRN_PROC_FUNCTION);
}

static inline int
selector_proc_p(grn_obj *obj)
{
return (function_proc_p(obj) && ((grn_proc *)obj)->selector);
}

grn_obj *
grn_expr_alloc(grn_ctx *ctx, grn_obj *expr, grn_id domain, grn_obj_flags flags)
{
Expand Down Expand Up @@ -141,6 +147,17 @@ grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data, grn_id domain, grn_obj_fl
return pctx->caller ? grn_expr_alloc(ctx, (grn_obj *)pctx->caller, domain, flags) : NULL;
}

grn_rc
grn_proc_set_selector(grn_ctx *ctx, grn_obj *proc, grn_selector_func selector)
{
grn_proc *proc_ = (grn_proc *)proc;
if (!function_proc_p(proc)) {
return GRN_INVALID_ARGUMENT;
}
proc_->selector = selector;
return GRN_SUCCESS;
}

/* grn_expr */

static const char *opstrs[] = {
Expand Down Expand Up @@ -4247,20 +4264,14 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
break;
case GRN_OP_CALL :
if (si->flags & SCAN_ACCESSOR) {
} else {
char buf[GRN_TABLE_MAX_KEY_SIZE];
int len = grn_obj_name(ctx, si->args[0], buf,
GRN_TABLE_MAX_KEY_SIZE);
/* geo_in_circle and geo_in_rectangle only */
if (len == 13 && !memcmp(buf, "geo_in_circle", 13)) {
/* TODO: error check */
grn_selector_geo_in_circle(ctx, index, si->args, si->nargs,
res, si->logical_op);
done++;
} else if (len == 16 && !memcmp(buf, "geo_in_rectangle", 16)) {
/* TODO: error check */
grn_selector_geo_in_rectangle(ctx, index, si->args, si->nargs,
res, si->logical_op);
} else if (selector_proc_p(si->args[0])) {
grn_rc rc;
grn_proc *proc = si->args[0];
rc = proc->selector(ctx, index, si->nargs, si->args,
res, si->logical_op);
if (rc) {
/* TODO: report error */
} else {
done++;
}
}
Expand Down
5 changes: 3 additions & 2 deletions lib/geo.c
Expand Up @@ -673,7 +673,8 @@ typedef double (*grn_geo_distance_raw_func)(grn_ctx *ctx,
grn_geo_point *point2);

grn_rc
grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj, grn_obj **args, int nargs,
grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj,
int nargs, grn_obj **args,
grn_obj *res, grn_operator op)
{
grn_geo_approximate_type type = GRN_GEO_APPROXIMATE_RECTANGLE;
Expand Down Expand Up @@ -884,7 +885,7 @@ exit :

grn_rc
grn_selector_geo_in_rectangle(grn_ctx *ctx, grn_obj *obj,
grn_obj **args, int nargs,
int nargs, grn_obj **args,
grn_obj *res, grn_operator op)
{
if (nargs == 4) {
Expand Down
10 changes: 6 additions & 4 deletions lib/geo.h
Expand Up @@ -133,10 +133,12 @@ grn_rc grn_geo_select_in_circle(grn_ctx *ctx,
grn_obj *res,
grn_operator op);

grn_rc grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj, grn_obj **args,
int nargs, grn_obj *res, grn_operator op);
grn_rc grn_selector_geo_in_rectangle(grn_ctx *ctx, grn_obj *obj, grn_obj **args,
int nargs, grn_obj *res, grn_operator op);
grn_rc grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj,
int nargs, grn_obj **args,
grn_obj *res, grn_operator op);
grn_rc grn_selector_geo_in_rectangle(grn_ctx *ctx, grn_obj *obj,
int nargs, grn_obj **args,
grn_obj *res, grn_operator op);

GRN_API grn_bool grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
grn_obj *radius_or_point,
Expand Down
15 changes: 11 additions & 4 deletions lib/proc.c
Expand Up @@ -2973,11 +2973,18 @@ grn_db_init_builtin_query(grn_ctx *ctx)

grn_proc_create(ctx, "now", 3, GRN_PROC_FUNCTION, func_now, NULL, NULL, 0, vars);

grn_proc_create(ctx, "geo_in_circle", 13, GRN_PROC_FUNCTION,
func_geo_in_circle, NULL, NULL, 0, NULL);
{
grn_obj *selector_proc;

selector_proc = grn_proc_create(ctx, "geo_in_circle", 13, GRN_PROC_FUNCTION,
func_geo_in_circle, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, grn_selector_geo_in_circle);

grn_proc_create(ctx, "geo_in_rectangle", 16, GRN_PROC_FUNCTION,
func_geo_in_rectangle, NULL, NULL, 0, NULL);
selector_proc = grn_proc_create(ctx, "geo_in_rectangle", 16,
GRN_PROC_FUNCTION,
func_geo_in_rectangle, NULL, NULL, 0, NULL);
grn_proc_set_selector(ctx, selector_proc, grn_selector_geo_in_rectangle);
}

grn_proc_create(ctx, "geo_distance", 12, GRN_PROC_FUNCTION,
func_geo_distance, NULL, NULL, 0, NULL);
Expand Down

0 comments on commit f9035f7

Please sign in to comment.