Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #23 from groonga/query-flags
Browse files Browse the repository at this point in the history
Add --query_flags option to select command
  • Loading branch information
daijiro committed Aug 7, 2012
2 parents 92a6d60 + eb4d32f commit e30f50f
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 11 deletions.
36 changes: 36 additions & 0 deletions doc/source/reference/commands/select.txt
Expand Up @@ -40,6 +40,7 @@ Syntax
[cache=yes]
[match_escalation_threshold=0]
[query_expansion=null]
[query_flags=ALLOW_PRAGMA|ALLOW_COLUMN]

Usage
-----
Expand Down Expand Up @@ -534,6 +535,41 @@ more liked entries.
The ``select`` command outputs records that ``n_likes`` column value
is equal to or more than ``10`` from ``Entries`` table.

.. _query-flags:

``query_flags``
"""""""""""""""

It customs ``query`` parameter syntax. You cannot update column value
by ``query`` parameter by default. But if you specify
``ALLOW_COLUMN|ALLOW_UPDATE`` as ``query_flags``, you can update
column value ``query``.

Here are available values:

* ``ALLOW_PRAGMA``
* ``ALLOW_COLUMN``
* ``ALLOW_UPDATE``

``ALLOW_PRAGMA`` enables pragma at the head of ``query``.

``ALLOW_COLUMN`` enables search againt columns that are not included
in ``match_columns``. To specify column, there are ``COLUMN:...``
syntaxes.

``ALLOW_UPDATE`` enables column update by ``query`` with
``COLUMN:=NEW_VALUE`` syntax. ``ALLOW_COLUMN`` is also required to
update column because the column update syntax specifies column.

They can be combined by separated ``|`` such as
``ALLOW_COLUMN|ALLOW_UPDATE``.

The default value is ``ALLOW_PRAGMA|ALLOW_COLUMN``.

TODO: example

See also :doc:`/reference/grn_expr/query_syntax`.

Output related parameters
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
6 changes: 3 additions & 3 deletions doc/source/reference/grn_expr/query_syntax.txt
Expand Up @@ -564,9 +564,9 @@ Assignment expression
---------------------

This section is for advanced users. Because assignment expression is
disabled in ``--query`` option of :doc:`/reference/commands/select`. You need to
use groonga as a library instead of server or command line tool for
assignment expression.
disabled in ``--query`` option of :doc:`/reference/commands/select` by
default. You need to specify ``ALLOW_COLUMN|ALLOW_UPDATE`` as
``--query_flags`` option value to enable assignment expression.

Assignment expression in query syntax has some limitations. So you
should use :doc:`/reference/grn_expr/script_syntax` instead of query syntax for
Expand Down
67 changes: 59 additions & 8 deletions lib/proc.c
Expand Up @@ -246,6 +246,43 @@ exit :
#define DEFAULT_DRILLDOWN_OUTPUT_COLUMNS "_key, _nsubrecs"
#define DUMP_COLUMNS "_id, _key, _value, *"

static grn_expr_flags
grn_parse_query_flags(grn_ctx *ctx, const char *query_flags,
unsigned int query_flags_len)
{
grn_expr_flags flags = 0;
const char *query_flags_end = query_flags + query_flags_len;

while (query_flags < query_flags_end) {
if (*query_flags == '|' || *query_flags == ' ') {
query_flags += 1;
continue;
}

#define CHECK_EXPR_FLAG(name)\
if (((query_flags_end - query_flags) >= (sizeof(#name) - 1)) &&\
(!memcmp(query_flags, #name, sizeof(#name) - 1))) {\
flags |= GRN_EXPR_ ## name;\
query_flags += sizeof(#name);\
break;\
}
switch (*query_flags) {
case 'A' :
CHECK_EXPR_FLAG(ALLOW_PRAGMA);
CHECK_EXPR_FLAG(ALLOW_COLUMN);
CHECK_EXPR_FLAG(ALLOW_UPDATE);
default :
ERR(GRN_INVALID_ARGUMENT, "invalid query flag: <%.*s>",
(int)(query_flags_end - query_flags), query_flags);
return 0;
}
#undef CHECK_EXPR_FLAG

}

return flags;
}

grn_rc
grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
const char *match_columns, unsigned int match_columns_len,
Expand All @@ -261,7 +298,8 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
int drilldown_offset, int drilldown_limit,
const char *cache, unsigned int cache_len,
const char *match_escalation_threshold, unsigned int match_escalation_threshold_len,
const char *query_expansion, unsigned int query_expansion_len)
const char *query_expansion, unsigned int query_expansion_len,
const char *query_flags, unsigned int query_flags_len)
{
uint32_t nkeys, nhits;
uint16_t cacheable = 1, taintable = 0;
Expand All @@ -274,8 +312,8 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
uint32_t cache_key_size = table_len + 1 + match_columns_len + 1 + query_len + 1 +
filter_len + 1 + scorer_len + 1 + sortby_len + 1 + output_columns_len + 1 +
drilldown_len + 1 + drilldown_sortby_len + 1 +
drilldown_output_columns_len + 1 +
match_escalation_threshold_len + 1 + query_expansion_len + 1 +
drilldown_output_columns_len + 1 + match_escalation_threshold_len + 1 +
query_expansion_len + 1 + query_flags_len + 1 +
sizeof(grn_content_type) + sizeof(int) * 4;
long long int threshold, original_threshold = 0;
if (cache_key_size <= GRN_TABLE_MAX_KEY_SIZE) {
Expand Down Expand Up @@ -305,6 +343,8 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
cp += match_escalation_threshold_len; *cp++ = '\0';
memcpy(cp, query_expansion, query_expansion_len);
cp += query_expansion_len; *cp++ = '\0';
memcpy(cp, query_flags, query_flags_len);
cp += query_flags_len; *cp++ = '\0';
memcpy(cp, &output_type, sizeof(grn_content_type)); cp += sizeof(grn_content_type);
memcpy(cp, &offset, sizeof(int)); cp += sizeof(int);
memcpy(cp, &limit, sizeof(int)); cp += sizeof(int);
Expand Down Expand Up @@ -346,7 +386,16 @@ grn_select(grn_ctx *ctx, const char *table, unsigned int table_len,
grn_expr_flags flags;
grn_obj query_expansion_buf;
GRN_TEXT_INIT(&query_expansion_buf, 0);
flags = GRN_EXPR_SYNTAX_QUERY|GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
flags = GRN_EXPR_SYNTAX_QUERY;
if (query_flags_len) {
flags |= grn_parse_query_flags(ctx, query_flags, query_flags_len);
} else {
flags |= GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN;
if (ctx->rc) {
grn_obj_unlink(ctx, cond);
goto exit;
}
}
if (query_expansion_len) {
grn_obj *query_expansion_column;
query_expansion_column = grn_ctx_get(ctx, query_expansion, query_expansion_len);
Expand Down Expand Up @@ -591,7 +640,8 @@ proc_select(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
drilldown_offset, drilldown_limit,
GRN_TEXT_VALUE(VAR(14)), GRN_TEXT_LEN(VAR(14)),
GRN_TEXT_VALUE(VAR(15)), GRN_TEXT_LEN(VAR(15)),
GRN_TEXT_VALUE(VAR(16)), GRN_TEXT_LEN(VAR(16)))) {
GRN_TEXT_VALUE(VAR(16)), GRN_TEXT_LEN(VAR(16)),
GRN_TEXT_VALUE(VAR(17)), GRN_TEXT_LEN(VAR(17)))) {
}
return NULL;
}
Expand Down Expand Up @@ -2790,7 +2840,7 @@ func_edit_distance(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_
void
grn_db_init_builtin_query(grn_ctx *ctx)
{
grn_expr_var vars[18];
grn_expr_var vars[19];

DEF_VAR(vars[0], "name");
DEF_VAR(vars[1], "table");
Expand All @@ -2810,8 +2860,9 @@ grn_db_init_builtin_query(grn_ctx *ctx)
DEF_VAR(vars[15], "cache");
DEF_VAR(vars[16], "match_escalation_threshold");
DEF_VAR(vars[17], "query_expansion");
DEF_COMMAND("define_selector", proc_define_selector, 18, vars);
DEF_COMMAND("select", proc_select, 17, vars + 1);
DEF_VAR(vars[18], "query_flags");
DEF_COMMAND("define_selector", proc_define_selector, 19, vars);
DEF_COMMAND("select", proc_select, 18, vars + 1);

DEF_VAR(vars[0], "values");
DEF_VAR(vars[1], "table");
Expand Down
88 changes: 88 additions & 0 deletions test/function/suite/select/query_flags/allow_update.expected
@@ -0,0 +1,88 @@
table_create Users TABLE_HASH_KEY ShortText
[[0,0.0,0.0],true]
column_create Users age COLUMN_SCALAR UInt32
[[0,0.0,0.0],true]
load --table Users
[
{"_key": "alice", "age": 18},
{"_key": "bob", "age": 20}
]
[[0,0.0,0.0],2]
select Users --query "age:=19" --query_flags "ALLOW_COLUMN|ALLOW_UPDATE"
[
[
0,
0.0,
0.0
],
[
[
[
2
],
[
[
"_id",
"UInt32"
],
[
"_key",
"ShortText"
],
[
"age",
"UInt32"
]
],
[
1,
"alice",
19
],
[
2,
"bob",
19
]
]
]
]
select Users
[
[
0,
0.0,
0.0
],
[
[
[
2
],
[
[
"_id",
"UInt32"
],
[
"_key",
"ShortText"
],
[
"age",
"UInt32"
]
],
[
1,
"alice",
19
],
[
2,
"bob",
19
]
]
]
]
14 changes: 14 additions & 0 deletions test/function/suite/select/query_flags/allow_update.test
@@ -0,0 +1,14 @@
table_create Users TABLE_HASH_KEY ShortText
column_create Users age COLUMN_SCALAR UInt32

load --table Users
[
{"_key": "alice", "age": 18},
{"_key": "bob", "age": 20}
]

select Users \
--query "age:=19" \
--query_flags "ALLOW_COLUMN|ALLOW_UPDATE"

select Users

0 comments on commit e30f50f

Please sign in to comment.