Navigation Menu

Skip to content

Commit

Permalink
in_records: support customizing mode
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Apr 19, 2017
1 parent 9ed9d6d commit 25ed307
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 22 deletions.
99 changes: 83 additions & 16 deletions lib/proc/proc_in_records.c
Expand Up @@ -29,6 +29,7 @@ func_in_records(grn_ctx *ctx,
grn_obj *found;
grn_obj *condition_table;
grn_obj condition_columns;
grn_operator_exec_func **condition_functions = NULL;
int i;

found = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_BOOL, 0);
Expand All @@ -37,18 +38,18 @@ func_in_records(grn_ctx *ctx,
}
GRN_BOOL_SET(ctx, found, GRN_FALSE);

if (n_args < 3) {
if (n_args < 4) {
GRN_PLUGIN_ERROR(ctx,
GRN_INVALID_ARGUMENT,
"in_records(): wrong number of arguments (%d for 3..)",
"in_records(): wrong number of arguments (%d for 4..)",
n_args);
return found;
}

if ((n_args % 2) != 1) {
if ((n_args % 3) != 1) {
GRN_PLUGIN_ERROR(ctx,
GRN_INVALID_ARGUMENT,
"in_records(): the number of arguments must be odd (%d)",
"in_records(): the number of arguments must be 1 + 3n (%d)",
n_args);
return found;
}
Expand All @@ -68,10 +69,12 @@ func_in_records(grn_ctx *ctx,
}

GRN_PTR_INIT(&condition_columns, GRN_OBJ_VECTOR, GRN_ID_NIL);
for (i = 1; i < n_args; i += 2) {
grn_obj *column_name = args[i + 1];
for (i = 1; i < n_args; i += 3) {
int column_name_i = i + 2;
grn_obj *column_name;
grn_obj *condition_column;

column_name = args[column_name_i];
if (!grn_obj_is_text_family_bulk(ctx, column_name)) {
grn_obj inspected;
GRN_TEXT_INIT(&inspected, 0);
Expand All @@ -81,7 +84,7 @@ func_in_records(grn_ctx *ctx,
"in_records(): "
"the %dth argument must be column name as string: "
"<%.*s>",
i + 1,
column_name_i,
(int)GRN_TEXT_LEN(&inspected),
GRN_TEXT_VALUE(&inspected));
GRN_OBJ_FIN(ctx, &inspected);
Expand All @@ -100,7 +103,7 @@ func_in_records(grn_ctx *ctx,
"in_records(): "
"the %dth argument must be existing column name: "
"<%.*s>: <%.*s>",
i + 1,
column_name_i,
(int)GRN_TEXT_LEN(column_name),
GRN_TEXT_VALUE(column_name),
(int)GRN_TEXT_LEN(&inspected),
Expand All @@ -111,18 +114,79 @@ func_in_records(grn_ctx *ctx,
GRN_PTR_PUT(ctx, &condition_columns, condition_column);
}

condition_functions =
GRN_PLUGIN_MALLOCN(ctx, grn_operator_exec_func *, (n_args - 1 / 3));
for (i = 1; i < n_args; i += 3) {
int nth = (i - 1) / 3;
int mode_name_i = i + 1;
grn_obj *mode_name;
grn_operator mode;

mode_name = args[mode_name_i];
mode = grn_proc_option_value_mode(ctx,
mode_name,
GRN_OP_EQUAL,
"in_records()");
if (ctx->rc != GRN_SUCCESS) {
goto exit;
}

switch (mode) {
case GRN_OP_EQUAL :
condition_functions[nth] = grn_operator_exec_equal;
break;
case GRN_OP_NOT_EQUAL :
condition_functions[nth] = grn_operator_exec_not_equal;
break;
case GRN_OP_LESS :
condition_functions[nth] = grn_operator_exec_less;
break;
case GRN_OP_GREATER :
condition_functions[nth] = grn_operator_exec_greater;
break;
case GRN_OP_LESS_EQUAL :
condition_functions[nth] = grn_operator_exec_less_equal;
break;
case GRN_OP_GREATER_EQUAL :
condition_functions[nth] = grn_operator_exec_greater_equal;
break;
case GRN_OP_MATCH :
condition_functions[nth] = grn_operator_exec_match;
break;
case GRN_OP_PREFIX :
condition_functions[nth] = grn_operator_exec_prefix;
break;
case GRN_OP_REGEXP :
condition_functions[nth] = grn_operator_exec_regexp;
break;
default :
GRN_PLUGIN_ERROR(ctx,
GRN_INVALID_ARGUMENT,
"in_records(): "
"the %dth argument is unsupported mode: <%.*s>",
mode_name_i,
(int)GRN_TEXT_LEN(mode_name),
GRN_TEXT_VALUE(mode_name));
goto exit;
break;
}
}

{
grn_obj condition_column_value;

GRN_VOID_INIT(&condition_column_value);
GRN_TABLE_EACH_BEGIN(ctx, condition_table, cursor, id) {
grn_bool found_record = GRN_TRUE;

for (i = 1; i < n_args; i += 2) {
grn_obj *value = args[i];
for (i = 1; i < n_args; i += 3) {
int nth = (i - 1) / 3;
grn_obj *condition_column;
grn_operator_exec_func *condition_function;
grn_obj *value = args[i];

condition_column = GRN_PTR_VALUE_AT(&condition_columns, (i - 1) / 2);
condition_column = GRN_PTR_VALUE_AT(&condition_columns, nth);
condition_function = condition_functions[nth];
if (grn_obj_is_data_column(ctx, condition_column)) {
grn_bool found_value = GRN_FALSE;

Expand All @@ -132,9 +196,9 @@ func_in_records(grn_ctx *ctx,
id,
&condition_column_value);

found_value = grn_operator_exec_equal(ctx,
value,
&condition_column_value);
found_value = condition_function(ctx,
value,
&condition_column_value);
if (ctx->rc != GRN_SUCCESS) {
found_record = GRN_FALSE;
break;
Expand All @@ -159,10 +223,13 @@ func_in_records(grn_ctx *ctx,
}

exit :
GRN_PLUGIN_FREE(ctx, condition_functions);

for (i = 1; i < n_args; i += 2) {
int nth = (i - 1) / 3;
grn_obj *condition_column;
condition_column = GRN_PTR_VALUE_AT(&condition_columns, (i - 1) / 2);
if (condition_column->header.type == GRN_ACCESSOR) {
condition_column = GRN_PTR_VALUE_AT(&condition_columns, nth);
if (condition_column && condition_column->header.type == GRN_ACCESSOR) {
grn_obj_unlink(ctx, condition_column);
}
}
Expand Down
55 changes: 55 additions & 0 deletions test/command/suite/select/function/in_records/match.expected
@@ -0,0 +1,55 @@
table_create Conditions TABLE_NO_KEY
[[0,0.0,0.0],true]
column_create Conditions user_pattern COLUMN_SCALAR ShortText
[[0,0.0,0.0],true]
table_create Logs TABLE_NO_KEY
[[0,0.0,0.0],true]
column_create Logs user COLUMN_SCALAR ShortText
[[0,0.0,0.0],true]
load --table Conditions
[
{"user_pattern": "ali"},
{"user_pattern": "ris"}
]
[[0,0.0,0.0],2]
load --table Logs
[
{"user": "alice"},
{"user": "bob"},
{"user": "chris"},
{"user": "david"}
]
[[0,0.0,0.0],4]
select Logs --filter 'in_records(Conditions, user, "@", "user_pattern")'
[
[
0,
0.0,
0.0
],
[
[
[
2
],
[
[
"_id",
"UInt32"
],
[
"user",
"ShortText"
]
],
[
1,
"alice"
],
[
3,
"chris"
]
]
]
]
22 changes: 22 additions & 0 deletions test/command/suite/select/function/in_records/match.test
@@ -0,0 +1,22 @@
table_create Conditions TABLE_NO_KEY
column_create Conditions user_pattern COLUMN_SCALAR ShortText

table_create Logs TABLE_NO_KEY
column_create Logs user COLUMN_SCALAR ShortText

load --table Conditions
[
{"user_pattern": "ali"},
{"user_pattern": "ris"}
]

load --table Logs
[
{"user": "alice"},
{"user": "bob"},
{"user": "chris"},
{"user": "david"}
]

select Logs \
--filter 'in_records(Conditions, user, "@", "user_pattern")'
Expand Up @@ -37,7 +37,7 @@ load --table Logs
{"user": "david", "tag": "tag2", "time": "2017-04-20 11:22:33"}
]
[[0,0.0,0.0],5]
select Logs --filter 'in_records(Reports, user, "user", tag, "tag", time_classify_day(time), "day")'
select Logs --filter 'in_records(Reports, user, "==", "user", tag, "==", "tag", time_classify_day(time), "==", "day")'
[
[
0,
Expand Down
6 changes: 3 additions & 3 deletions test/command/suite/select/function/in_records/multiple.test
Expand Up @@ -32,6 +32,6 @@ load --table Logs

select Logs \
--filter 'in_records(Reports, \
user, "user", \
tag, "tag", \
time_classify_day(time), "day")'
user, "==", "user", \
tag, "==", "tag", \
time_classify_day(time), "==", "day")'
2 changes: 1 addition & 1 deletion test/command/suite/select/function/in_records/one.expected
Expand Up @@ -22,7 +22,7 @@ load --table Logs
{"user": "david"}
]
[[0,0.0,0.0],4]
select Logs --filter 'in_records(Reports, user, "user")'
select Logs --filter 'in_records(Reports, user, "==", "user")'
[
[
0,
Expand Down
2 changes: 1 addition & 1 deletion test/command/suite/select/function/in_records/one.test
Expand Up @@ -21,4 +21,4 @@ load --table Logs
]

select Logs \
--filter 'in_records(Reports, user, "user")'
--filter 'in_records(Reports, user, "==", "user")'

0 comments on commit 25ed307

Please sign in to comment.