Navigation Menu

Skip to content

Commit

Permalink
Support query syntax by "@@"
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Jan 22, 2015
1 parent 69c1ad3 commit 02d4451
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 11 deletions.
3 changes: 3 additions & 0 deletions Makefile
Expand Up @@ -19,11 +19,14 @@ PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)

installcheck: results/text/single/contain
installcheck: results/text/single/match
installcheck: results/text/single/and
installcheck: results/text/multiple/contain

results/text/single/contain:
@mkdir -p results/text/single/contain
results/text/single/match:
@mkdir -p results/text/single/match
results/text/single/and:
@mkdir -p results/text/single/and
results/text/multiple/contain:
Expand Down
20 changes: 20 additions & 0 deletions expected/text/single/match/bitmapscan.out
@@ -0,0 +1,20 @@
CREATE TABLE memos (
id integer,
content text
);
INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
CREATE INDEX grnindex ON memos USING pgroonga (content);
SET enable_seqscan = off;
SET enable_indexscan = off;
SET enable_bitmapscan = on;
SELECT id, content
FROM memos
WHERE content @@ 'groonga postgresql';
id | content
----+-------------------------------------------------------
3 | PGroonga is a PostgreSQL extension that uses Groonga.
(1 row)

DROP TABLE memos;
20 changes: 20 additions & 0 deletions expected/text/single/match/indexscan.out
@@ -0,0 +1,20 @@
CREATE TABLE memos (
id integer,
content text
);
INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
CREATE INDEX grnindex ON memos USING pgroonga (content);
SET enable_seqscan = off;
SET enable_indexscan = on;
SET enable_bitmapscan = off;
SELECT id, content
FROM memos
WHERE content @@ 'groonga postgresql';
id | content
----+-------------------------------------------------------
3 | PGroonga is a PostgreSQL extension that uses Groonga.
(1 row)

DROP TABLE memos;
20 changes: 20 additions & 0 deletions expected/text/single/match/seqscan.out
@@ -0,0 +1,20 @@
CREATE TABLE memos (
id integer,
content text
);
INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
CREATE INDEX grnindex ON memos USING pgroonga (content);
SET enable_seqscan = on;
SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT id, content
FROM memos
WHERE content @@ 'groonga postgresql';
id | content
----+-------------------------------------------------------
3 | PGroonga is a PostgreSQL extension that uses Groonga.
(1 row)

DROP TABLE memos;
31 changes: 30 additions & 1 deletion pgroonga--0.2.0.sql
Expand Up @@ -29,6 +29,33 @@ CREATE OPERATOR %% (
);


CREATE FUNCTION pgroonga.match(text, text)
RETURNS bool
AS 'MODULE_PATHNAME', 'pgroonga_match'
LANGUAGE C
IMMUTABLE
STRICT;

CREATE FUNCTION pgroonga.match(bpchar, bpchar)
RETURNS bool
AS 'MODULE_PATHNAME', 'pgroonga_match'
LANGUAGE C
IMMUTABLE
STRICT;

CREATE OPERATOR @@ (
PROCEDURE = pgroonga.match,
LEFTARG = text,
RIGHTARG = text
);

CREATE OPERATOR @@ (
PROCEDURE = pgroonga.match,
LEFTARG = bpchar,
RIGHTARG = bpchar
);


CREATE FUNCTION pgroonga.insert(internal)
RETURNS bool
AS 'MODULE_PATHNAME', 'pgroonga_insert'
Expand Down Expand Up @@ -125,7 +152,7 @@ CREATE FUNCTION pgroonga.get_timestamptz(internal, internal, timestamptz)

INSERT INTO pg_catalog.pg_am VALUES(
'pgroonga', -- amname
7, -- amstrategies
8, -- amstrategies
3, -- amsupport
true, -- amcanorder
true, -- amcanorderbyop
Expand Down Expand Up @@ -165,6 +192,7 @@ CREATE OPERATOR CLASS pgroonga.text_ops DEFAULT FOR TYPE text
OPERATOR 5 >,
OPERATOR 6 <>,
OPERATOR 7 %%,
OPERATOR 8 @@,
FUNCTION 1 pgroonga.typeof(oid, integer),
FUNCTION 2 pgroonga.get_text(internal, internal, text);

Expand All @@ -177,6 +205,7 @@ CREATE OPERATOR CLASS pgroonga.bpchar_ops DEFAULT FOR TYPE bpchar
OPERATOR 5 >,
OPERATOR 6 <>,
OPERATOR 7 %%,
OPERATOR 8 @@,
FUNCTION 1 pgroonga.typeof(oid, integer),
FUNCTION 2 pgroonga.get_bpchar(internal, internal, bpchar);

Expand Down
63 changes: 53 additions & 10 deletions pgroonga.c
Expand Up @@ -501,6 +501,24 @@ pgroonga_contains_bpchar(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(contained);
}

/**
* pgroonga.match(text, query) : bool
*/
Datum
pgroonga_match(PG_FUNCTION_ARGS)
{
#ifdef NOT_USED
text *text = PG_GETARG_TEXT_PP(0);
text *query = PG_GETARG_TEXT_PP(1);
#endif

ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("groonga: operator @@ is available only in index scans")));

PG_RETURN_BOOL(false);
}

static void
GrnInsert(grn_ctx *ctx,
Relation index,
Expand Down Expand Up @@ -646,6 +664,7 @@ GrnSearch(IndexScanDesc scan)
ScanKey key = &(scan->keyData[i]);
grn_bool isValidStrategy = GRN_TRUE;
grn_obj *matchTarget, *matchTargetVariable;
grn_operator operator = GRN_OP_NOP;

/* NULL key is not supported */
if (key->sk_flags & SK_ISNULL)
Expand All @@ -665,31 +684,30 @@ GrnSearch(IndexScanDesc scan)
grn_obj_reinit(ctx, &buffer, GrnGetType(index, key->sk_attno - 1), 0);
GrnGetValue(index, key->sk_attno - 1, &buffer, key->sk_argument);

grn_expr_append_obj(ctx, expression, matchTarget, GRN_OP_PUSH, 1);
grn_expr_append_const(ctx, expression, &buffer, GRN_OP_PUSH, 1);

switch (key->sk_strategy)
{
case GrnLessStrategyNumber:
grn_expr_append_op(ctx, expression, GRN_OP_LESS, 2);
operator = GRN_OP_LESS;
break;
case GrnLessEqualStrategyNumber:
grn_expr_append_op(ctx, expression, GRN_OP_LESS_EQUAL, 2);
operator = GRN_OP_LESS_EQUAL;
break;
case GrnEqualStrategyNumber:
grn_expr_append_op(ctx, expression, GRN_OP_EQUAL, 2);
operator = GRN_OP_EQUAL;
break;
case GrnGreaterEqualStrategyNumber:
grn_expr_append_op(ctx, expression, GRN_OP_GREATER_EQUAL, 2);
operator = GRN_OP_GREATER_EQUAL;
break;
case GrnGreaterStrategyNumber:
grn_expr_append_op(ctx, expression, GRN_OP_GREATER, 2);
operator = GRN_OP_GREATER;
break;
case GrnNotEqualStrategyNumber:
grn_expr_append_op(ctx, expression, GRN_OP_NOT_EQUAL, 2);
operator = GRN_OP_NOT_EQUAL;
break;
case GrnContainStrategyNumber:
grn_expr_append_op(ctx, expression, GRN_OP_MATCH, 2);
operator = GRN_OP_MATCH;
break;
case GrnQueryStrategyNumber:
break;
default:
ereport(ERROR,
Expand All @@ -702,6 +720,31 @@ GrnSearch(IndexScanDesc scan)
if (!isValidStrategy)
continue;

if (key->sk_strategy == GrnQueryStrategyNumber)
{
grn_rc rc;
grn_expr_flags flags =
GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
rc = grn_expr_parse(ctx, expression,
GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer),
matchTarget, GRN_OP_MATCH, GRN_OP_AND,
flags);
if (rc != GRN_SUCCESS)
{
/* TODO: free expression, matchTargets and so on. */
ereport(ERROR,
(errcode(GrnRCToPgErrorCode(rc)),
errmsg("pgroonga: failed to parse expression: %s",
ctx->errbuf)));
}
}
else
{
grn_expr_append_obj(ctx, expression, matchTarget, GRN_OP_PUSH, 1);
grn_expr_append_const(ctx, expression, &buffer, GRN_OP_PUSH, 1);
grn_expr_append_op(ctx, expression, operator, 2);
}

if (nExpressions > 0)
grn_expr_append_op(ctx, expression, GRN_OP_AND, 2);
nExpressions++;
Expand Down
1 change: 1 addition & 0 deletions pgroonga.h
Expand Up @@ -38,6 +38,7 @@ extern void PGDLLEXPORT _PG_init(void);

extern Datum PGDLLEXPORT pgroonga_contains_text(PG_FUNCTION_ARGS);
extern Datum PGDLLEXPORT pgroonga_contains_bpchar(PG_FUNCTION_ARGS);
extern Datum PGDLLEXPORT pgroonga_match(PG_FUNCTION_ARGS);

extern Datum PGDLLEXPORT pgroonga_insert(PG_FUNCTION_ARGS);
extern Datum PGDLLEXPORT pgroonga_beginscan(PG_FUNCTION_ARGS);
Expand Down
20 changes: 20 additions & 0 deletions sql/text/single/match/bitmapscan.sql
@@ -0,0 +1,20 @@
CREATE TABLE memos (
id integer,
content text
);

INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');

CREATE INDEX grnindex ON memos USING pgroonga (content);

SET enable_seqscan = off;
SET enable_indexscan = off;
SET enable_bitmapscan = on;

SELECT id, content
FROM memos
WHERE content @@ 'groonga postgresql';

DROP TABLE memos;
20 changes: 20 additions & 0 deletions sql/text/single/match/indexscan.sql
@@ -0,0 +1,20 @@
CREATE TABLE memos (
id integer,
content text
);

INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');

CREATE INDEX grnindex ON memos USING pgroonga (content);

SET enable_seqscan = off;
SET enable_indexscan = on;
SET enable_bitmapscan = off;

SELECT id, content
FROM memos
WHERE content @@ 'groonga postgresql';

DROP TABLE memos;
20 changes: 20 additions & 0 deletions sql/text/single/match/seqscan.sql
@@ -0,0 +1,20 @@
CREATE TABLE memos (
id integer,
content text
);

INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');

CREATE INDEX grnindex ON memos USING pgroonga (content);

SET enable_seqscan = on;
SET enable_indexscan = off;
SET enable_bitmapscan = off;

SELECT id, content
FROM memos
WHERE content @@ 'groonga postgresql';

DROP TABLE memos;

0 comments on commit 02d4451

Please sign in to comment.