[Groonga-commit] pgroonga/pgroonga at 9fd2e0d [master] Support text[]

Back to archive index

Kouhei Sutou null+****@clear*****
Sun Feb 15 00:48:12 JST 2015


Kouhei Sutou	2015-02-15 00:48:12 +0900 (Sun, 15 Feb 2015)

  New Revision: 9fd2e0d4ca9b9d9d2c6b78d5783f5f7070096d1b
  https://github.com/pgroonga/pgroonga/commit/9fd2e0d4ca9b9d9d2c6b78d5783f5f7070096d1b

  Message:
    Support text[]

  Added files:
    expected/array/text/single/contain/bitmapscan.out
    expected/array/text/single/contain/indexscan.out
    expected/array/text/single/contain/seqscan.out
    sql/array/text/single/contain/indexscan.sql
  Modified files:
    Makefile
    pgroonga.c
    pgroonga.h
    pgroonga.sql
    pgroonga_types.c

  Modified: Makefile (+3 -0)
===================================================================
--- Makefile    2015-02-14 22:50:50 +0900 (9fa78f6)
+++ Makefile    2015-02-15 00:48:12 +0900 (4265960)
@@ -40,6 +40,7 @@ installcheck: results/compare/integer/single/between
 installcheck: results/compare/integer/multiple/greater-than-equal
 installcheck: results/compare/integer/order_by_limit
 installcheck: results/compare/timestamp/single/between
+installcheck: results/array/text/single/contain
 installcheck: results/groonga
 
 results/full-text-search/text/single/contain:
@@ -72,5 +73,7 @@ results/compare/integer/order_by_limit:
 	@mkdir -p $@
 results/compare/timestamp/single/between:
 	@mkdir -p $@
+results/array/text/single/contain:
+	@mkdir -p $@
 results/groonga:
 	@mkdir -p $@

  Added: expected/array/text/single/contain/bitmapscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/array/text/single/contain/bitmapscan.out    2015-02-15 00:48:12 +0900 (d2df0e2)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  title text,
+  tags text[]
+);
+INSERT INTO memos VALUES ('PostgreSQL', ARRAY['PostgreSQL']);
+INSERT INTO memos VALUES ('Groonga', ARRAY['Groonga']);
+INSERT INTO memos VALUES ('PGroonga', ARRAY['PostgreSQL', 'Groonga']);
+CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (tags);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+SELECT title, tags
+  FROM memos
+ WHERE tags %% 'Groonga';
+  title   |         tags         
+----------+----------------------
+ Groonga  | {Groonga}
+ PGroonga | {PostgreSQL,Groonga}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/array/text/single/contain/indexscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/array/text/single/contain/indexscan.out    2015-02-15 00:48:12 +0900 (4359d48)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  title text,
+  tags text[]
+);
+INSERT INTO memos VALUES ('PostgreSQL', ARRAY['PostgreSQL']);
+INSERT INTO memos VALUES ('Groonga', ARRAY['Groonga']);
+INSERT INTO memos VALUES ('PGroonga', ARRAY['PostgreSQL', 'Groonga']);
+CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (tags);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+SELECT title, tags
+  FROM memos
+ WHERE tags %% 'Groonga';
+  title   |         tags         
+----------+----------------------
+ Groonga  | {Groonga}
+ PGroonga | {PostgreSQL,Groonga}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/array/text/single/contain/seqscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/array/text/single/contain/seqscan.out    2015-02-15 00:48:12 +0900 (d8b3ced)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  title text,
+  tags text[]
+);
+INSERT INTO memos VALUES ('PostgreSQL', ARRAY['PostgreSQL']);
+INSERT INTO memos VALUES ('Groonga', ARRAY['Groonga']);
+INSERT INTO memos VALUES ('PGroonga', ARRAY['PostgreSQL', 'Groonga']);
+CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (tags);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT title, tags
+  FROM memos
+ WHERE tags %% 'Groonga';
+  title   |         tags         
+----------+----------------------
+ Groonga  | {Groonga}
+ PGroonga | {PostgreSQL,Groonga}
+(2 rows)
+
+DROP TABLE memos;

  Modified: pgroonga.c (+109 -25)
===================================================================
--- pgroonga.c    2015-02-14 22:50:50 +0900 (af953b3)
+++ pgroonga.c    2015-02-15 00:48:12 +0900 (b3a97f8)
@@ -16,6 +16,7 @@
 #include <miscadmin.h>
 #include <storage/ipc.h>
 #include <storage/lmgr.h>
+#include <utils/array.h>
 #include <utils/builtins.h>
 #include <utils/lsyscache.h>
 #include <utils/selfuncs.h>
@@ -47,6 +48,7 @@ typedef struct PGrnCreateData
 	Oid relNode;
 	bool forFullTextSearch;
 	grn_id attributeTypeID;
+	unsigned char attributeFlags;
 } PGrnCreateData;
 
 typedef struct PGrnBuildStateData
@@ -93,6 +95,7 @@ PG_FUNCTION_INFO_V1(pgroonga_table_name);
 PG_FUNCTION_INFO_V1(pgroonga_command);
 
 PG_FUNCTION_INFO_V1(pgroonga_contain_text);
+PG_FUNCTION_INFO_V1(pgroonga_contain_text_array);
 PG_FUNCTION_INFO_V1(pgroonga_contain_bpchar);
 PG_FUNCTION_INFO_V1(pgroonga_match);
 
@@ -368,16 +371,16 @@ PGrnCheck(const char *message)
 }
 
 static grn_id
-PGrnGetType(Relation index, AttrNumber n)
+PGrnGetType(Relation index, AttrNumber n, unsigned char *flags)
 {
 	TupleDesc desc = RelationGetDescr(index);
 	Form_pg_attribute attr;
 	grn_id typeID = GRN_ID_NIL;
+	unsigned char typeFlags = 0;
 	int32 maxlen;
 
 	attr = desc->attrs[n];
 
-	/* TODO: support array and record types. */
 	switch (attr->atttypid)
 	{
 	case BOOLOID:
@@ -425,6 +428,10 @@ PGrnGetType(Relation index, AttrNumber n)
 		typeID = GRN_DB_TOKYO_GEO_POINT or GRN_DB_WGS84_GEO_POINT;
 		break;
 #endif
+	case TEXTARRAYOID:
+		typeID = GRN_DB_SHORT_TEXT;
+		typeFlags |= GRN_OBJ_VECTOR;
+		break;
 	default:
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -432,6 +439,11 @@ PGrnGetType(Relation index, AttrNumber n)
 		break;
 	}
 
+	if (flags)
+	{
+		*flags = typeFlags;
+	}
+
 	return typeID;
 }
 
@@ -446,6 +458,17 @@ PGrnGetValue(Relation index, AttrNumber n, grn_obj *buffer, Datum value)
 				  value);
 }
 
+static void
+PGrnGetQuery(Relation index, AttrNumber n, grn_obj *buffer, Datum value)
+{
+	FmgrInfo *function;
+
+	function = index_getprocinfo(index, n + 1, PGrnGetQueryProc);
+	FunctionCall3(function,
+				  PointerGetDatum(ctx), PointerGetDatum(buffer),
+				  value);
+}
+
 static grn_obj *
 PGrnLookup(const char *name, int errorLevel)
 {
@@ -516,28 +539,37 @@ PGrnCreateColumn(grn_obj	*table,
 static bool
 PGrnIsForFullTextSearchIndex(Relation index)
 {
-	Oid containStrategyOID;
-	containStrategyOID = get_opfamily_member(index->rd_opfamily[0],
-											 index->rd_opcintype[0],
-											 index->rd_opcintype[0],
-											 PGrnContainStrategyNumber);
-	return (containStrategyOID != InvalidOid);
+	Oid queryStrategyOID;
+	queryStrategyOID = get_opfamily_member(index->rd_opfamily[0],
+										   index->rd_opcintype[0],
+										   index->rd_opcintype[0],
+										   PGrnQueryStrategyNumber);
+	return (queryStrategyOID != InvalidOid);
 }
 
 static void
 PGrnCreateDataColumn(PGrnCreateData *data)
 {
-	grn_obj_flags flags = GRN_OBJ_COLUMN_SCALAR;
+	grn_obj_flags flags = 0;
 
-	if (PGrnIsLZ4Available)
+	if (data->attributeFlags & GRN_OBJ_VECTOR)
+	{
+		flags |= GRN_OBJ_COLUMN_VECTOR;
+	}
+	else
 	{
-		switch (data->attributeTypeID)
+		flags |= GRN_OBJ_COLUMN_SCALAR;
+
+		if (PGrnIsLZ4Available)
 		{
-		case GRN_DB_SHORT_TEXT:
-		case GRN_DB_TEXT:
-		case GRN_DB_LONG_TEXT:
-			flags |= GRN_OBJ_COMPRESS_LZ4;
-			break;
+			switch (data->attributeTypeID)
+			{
+			case GRN_DB_SHORT_TEXT:
+			case GRN_DB_TEXT:
+			case GRN_DB_LONG_TEXT:
+				flags |= GRN_OBJ_COMPRESS_LZ4;
+				break;
+			}
 		}
 	}
 
@@ -634,7 +666,8 @@ PGrnCreate(Relation index, grn_obj **idsTable, grn_obj *lexicons)
 
 	for (data.i = 0; data.i < data.desc->natts; data.i++)
 	{
-		data.attributeTypeID = PGrnGetType(index, data.i);
+		data.attributeTypeID = PGrnGetType(index, data.i,
+										   &(data.attributeFlags));
 		PGrnCreateDataColumn(&data);
 		PGrnCreateIndexColumn(&data);
 	}
@@ -891,6 +924,49 @@ pgroonga_contain_text(PG_FUNCTION_ARGS)
 }
 
 /**
+ * pgroonga.contain(target text[], query text) : bool
+ */
+Datum
+pgroonga_contain_text_array(PG_FUNCTION_ARGS)
+{
+	ArrayType *target = PG_GETARG_ARRAYTYPE_P(0);
+	text *query = PG_GETARG_TEXT_PP(1);
+	bool contained = false;
+	grn_obj elementBuffer;
+	int i, n;
+
+	grn_obj_reinit(ctx, &buffer, GRN_DB_TEXT, 0);
+	GRN_TEXT_SET(ctx, &buffer, VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query));
+
+	GRN_TEXT_INIT(&elementBuffer, GRN_OBJ_DO_SHALLOW_COPY);
+
+	n = ARR_DIMS(target)[0];
+	for (i = 1; i <= n; i++)
+	{
+		Datum elementDatum;
+		text *element;
+		bool isNULL;
+
+		elementDatum = array_ref(target, 1, &i, -1, -1, false, 'i', &isNULL);
+		if (isNULL)
+			continue;
+
+		element = DatumGetTextPP(elementDatum);
+		GRN_TEXT_SET(ctx, &elementBuffer,
+					 VARDATA_ANY(element), VARSIZE_ANY_EXHDR(element));
+		if (grn_operator_exec_equal(ctx, &buffer, &elementBuffer))
+		{
+			contained = true;
+			break;
+		}
+	}
+
+	GRN_OBJ_FIN(ctx, &elementBuffer);
+
+	PG_RETURN_BOOL(contained);
+}
+
+/**
  * pgroonga.contain(doc bpchar, key bpchar) : bool
  */
 Datum
@@ -943,13 +1019,16 @@ PGrnInsert(grn_ctx *ctx,
 	{
 		grn_obj *dataColumn;
 		NameData *name = &(desc->attrs[i]->attname);
+		grn_id domain;
+		unsigned char flags;
 
 		if (isnull[i])
 			continue;
 
 		dataColumn = grn_obj_column(ctx, idsTable,
 									name->data, strlen(name->data));
-		grn_obj_reinit(ctx, &buffer, PGrnGetType(index, i), 0);
+		domain = PGrnGetType(index, i, &flags);
+		grn_obj_reinit(ctx, &buffer, domain, flags);
 		PGrnGetValue(index, i, &buffer, values[i]);
 		grn_obj_set_value(ctx, dataColumn, id, &buffer, GRN_OBJ_SET);
 		grn_obj_unlink(ctx, dataColumn);
@@ -1151,8 +1230,13 @@ PGrnSearchBuildConditions(IndexScanDesc scan,
 
 		grn_expr_append_op(ctx, matchTarget, GRN_OP_GET_MEMBER, 2);
 
-		grn_obj_reinit(ctx, &buffer, PGrnGetType(index, key->sk_attno - 1), 0);
-		PGrnGetValue(index, key->sk_attno - 1, &buffer, key->sk_argument);
+		{
+			grn_id domain;
+			unsigned char flags = 0;
+			domain = PGrnGetType(index, key->sk_attno - 1, NULL);
+			grn_obj_reinit(ctx, &buffer, domain, flags);
+		}
+		PGrnGetQuery(index, key->sk_attno - 1, &buffer, key->sk_argument);
 
 		switch (key->sk_strategy)
 		{
@@ -1396,7 +1480,7 @@ PGrnFillBorder(IndexScanDesc scan,
 		grn_id domain;
 
 		attrNumber = key->sk_attno - 1;
-		domain = PGrnGetType(index, attrNumber);
+		domain = PGrnGetType(index, attrNumber, NULL);
 		switch (key->sk_strategy)
 		{
 		case PGrnLessStrategyNumber:
@@ -1404,7 +1488,7 @@ PGrnFillBorder(IndexScanDesc scan,
 			if (maxBorderValue->header.type != GRN_DB_VOID)
 			{
 				grn_obj_reinit(ctx, &buffer, domain, 0);
-				PGrnGetValue(index, attrNumber, &buffer, key->sk_argument);
+				PGrnGetQuery(index, attrNumber, &buffer, key->sk_argument);
 				if (!PGrnIsMeaningfullMaxBorderValue(maxBorderValue,
 													 &buffer,
 													 *flags,
@@ -1414,7 +1498,7 @@ PGrnFillBorder(IndexScanDesc scan,
 				}
 			}
 			grn_obj_reinit(ctx, maxBorderValue, domain, 0);
-			PGrnGetValue(index, attrNumber, maxBorderValue, key->sk_argument);
+			PGrnGetQuery(index, attrNumber, maxBorderValue, key->sk_argument);
 			*max = GRN_BULK_HEAD(maxBorderValue);
 			*maxSize = GRN_BULK_VSIZE(maxBorderValue);
 			*flags &= ~(GRN_CURSOR_LT | GRN_CURSOR_LE);
@@ -1432,7 +1516,7 @@ PGrnFillBorder(IndexScanDesc scan,
 			if (minBorderValue->header.type != GRN_DB_VOID)
 			{
 				grn_obj_reinit(ctx, &buffer, domain, 0);
-				PGrnGetValue(index, attrNumber, &buffer,
+				PGrnGetQuery(index, attrNumber, &buffer,
 							 key->sk_argument);
 				if (!PGrnIsMeaningfullMinBorderValue(minBorderValue,
 													 &buffer,
@@ -1443,7 +1527,7 @@ PGrnFillBorder(IndexScanDesc scan,
 				}
 			}
 			grn_obj_reinit(ctx, minBorderValue, domain, 0);
-			PGrnGetValue(index, attrNumber, minBorderValue, key->sk_argument);
+			PGrnGetQuery(index, attrNumber, minBorderValue, key->sk_argument);
 			*min = GRN_BULK_HEAD(minBorderValue);
 			*minSize = GRN_BULK_VSIZE(minBorderValue);
 			*flags &= ~(GRN_CURSOR_GT | GRN_CURSOR_GE);

  Modified: pgroonga.h (+3 -0)
===================================================================
--- pgroonga.h    2015-02-14 22:50:50 +0900 (a1c6399)
+++ pgroonga.h    2015-02-15 00:48:12 +0900 (e9bdf06)
@@ -33,6 +33,7 @@
 
 /* Groonga support functions */
 #define PGrnGetValueProc				1
+#define PGrnGetQueryProc				2
 
 /* file and table names */
 #define PGrnDatabaseBasename			"pgrn"
@@ -49,6 +50,7 @@ extern Datum PGDLLEXPORT pgroonga_table_name(PG_FUNCTION_ARGS);
 extern Datum PGDLLEXPORT pgroonga_command(PG_FUNCTION_ARGS);
 
 extern Datum PGDLLEXPORT pgroonga_contain_text(PG_FUNCTION_ARGS);
+extern Datum PGDLLEXPORT pgroonga_contain_text_array(PG_FUNCTION_ARGS);
 extern Datum PGDLLEXPORT pgroonga_contain_bpchar(PG_FUNCTION_ARGS);
 extern Datum PGDLLEXPORT pgroonga_match(PG_FUNCTION_ARGS);
 
@@ -69,6 +71,7 @@ extern Datum PGDLLEXPORT pgroonga_options(PG_FUNCTION_ARGS);
 int pgroonga_bpchar_size(const BpChar *bpchar);
 
 extern Datum PGDLLEXPORT pgroonga_get_text(PG_FUNCTION_ARGS);
+extern Datum PGDLLEXPORT pgroonga_get_text_array(PG_FUNCTION_ARGS);
 extern Datum PGDLLEXPORT pgroonga_get_bpchar(PG_FUNCTION_ARGS);
 extern Datum PGDLLEXPORT pgroonga_get_bool(PG_FUNCTION_ARGS);
 extern Datum PGDLLEXPORT pgroonga_get_int2(PG_FUNCTION_ARGS);

  Modified: pgroonga.sql (+67 -12)
===================================================================
--- pgroonga.sql    2015-02-14 22:50:50 +0900 (5baaee4)
+++ pgroonga.sql    2015-02-15 00:48:12 +0900 (cea4a69)
@@ -30,6 +30,13 @@ CREATE FUNCTION pgroonga.contain(text, text)
 	IMMUTABLE
 	STRICT;
 
+CREATE FUNCTION pgroonga.contain(target text[], query text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_contain_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
 CREATE FUNCTION pgroonga.contain(bpchar, bpchar)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_contain_bpchar'
@@ -45,6 +52,12 @@ CREATE OPERATOR %% (
 
 CREATE OPERATOR %% (
 	PROCEDURE = pgroonga.contain,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
+CREATE OPERATOR %% (
+	PROCEDURE = pgroonga.contain,
 	LEFTARG = bpchar,
 	RIGHTARG = bpchar
 );
@@ -57,6 +70,13 @@ CREATE FUNCTION pgroonga.match(text, text)
 	IMMUTABLE
 	STRICT;
 
+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'
@@ -72,6 +92,12 @@ CREATE OPERATOR @@ (
 
 CREATE OPERATOR @@ (
 	PROCEDURE = pgroonga.match,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
+CREATE OPERATOR @@ (
+	PROCEDURE = pgroonga.match,
 	LEFTARG = bpchar,
 	RIGHTARG = bpchar
 );
@@ -130,6 +156,10 @@ CREATE FUNCTION pgroonga.get_text(internal, internal, text)
 	RETURNS void
 	AS 'MODULE_PATHNAME', 'pgroonga_get_text'
 	LANGUAGE C;
+CREATE FUNCTION pgroonga.get_text_array(internal, internal, text[])
+	RETURNS void
+	AS 'MODULE_PATHNAME', 'pgroonga_get_text_array'
+	LANGUAGE C;
 CREATE FUNCTION pgroonga.get_bpchar(internal, internal, bpchar)
 	RETURNS void
 	AS 'MODULE_PATHNAME', 'pgroonga_get_bpchar'
@@ -206,7 +236,8 @@ CREATE OPERATOR CLASS pgroonga.full_text_search_text_ops DEFAULT FOR TYPE text
 		OPERATOR 6 pg_catalog.~~,
 		OPERATOR 7 %%,
 		OPERATOR 8 @@,
-		FUNCTION 1 pgroonga.get_text(internal, internal, text);
+		FUNCTION 1 pgroonga.get_text(internal, internal, text),
+		FUNCTION 2 pgroonga.get_text(internal, internal, text);
 
 CREATE OPERATOR CLASS pgroonga.text_ops FOR TYPE text
 	USING pgroonga AS
@@ -215,13 +246,28 @@ CREATE OPERATOR CLASS pgroonga.text_ops FOR TYPE text
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_text(internal, internal, text);
+		FUNCTION 1 pgroonga.get_text(internal, internal, text),
+		FUNCTION 2 pgroonga.get_text(internal, internal, text);
+
+CREATE OPERATOR CLASS pgroonga.full_text_search_text_array_ops FOR TYPE text[]
+	USING pgroonga AS
+		OPERATOR 7 %% (text[], text),
+		OPERATOR 8 @@ (text[], text),
+		FUNCTION 1 pgroonga.get_text_array(internal, internal, text[]),
+		FUNCTION 2 pgroonga.get_text(internal, internal, text);
+
+CREATE OPERATOR CLASS pgroonga.text_array_ops DEFAULT FOR TYPE text[]
+	USING pgroonga AS
+		OPERATOR 7 %% (text[], text),
+		FUNCTION 1 pgroonga.get_text_array(internal, internal, text[]),
+		FUNCTION 2 pgroonga.get_text(internal, internal, text);
 
 CREATE OPERATOR CLASS pgroonga.full_text_search_bpchar_ops DEFAULT FOR TYPE bpchar
 	USING pgroonga AS
 		OPERATOR 7 %%,
 		OPERATOR 8 @@,
-		FUNCTION 1 pgroonga.get_bpchar(internal, internal, bpchar);
+		FUNCTION 1 pgroonga.get_bpchar(internal, internal, bpchar),
+		FUNCTION 2 pgroonga.get_bpchar(internal, internal, bpchar);
 
 CREATE OPERATOR CLASS pgroonga.bpchar_ops FOR TYPE bpchar
 	USING pgroonga AS
@@ -230,7 +276,8 @@ CREATE OPERATOR CLASS pgroonga.bpchar_ops FOR TYPE bpchar
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_bpchar(internal, internal, bpchar);
+		FUNCTION 1 pgroonga.get_bpchar(internal, internal, bpchar),
+		FUNCTION 2 pgroonga.get_bpchar(internal, internal, bpchar);
 
 CREATE OPERATOR CLASS pgroonga.bool_ops DEFAULT FOR TYPE bool
 	USING pgroonga AS
@@ -239,7 +286,8 @@ CREATE OPERATOR CLASS pgroonga.bool_ops DEFAULT FOR TYPE bool
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_bool(internal, internal, bool);
+		FUNCTION 1 pgroonga.get_bool(internal, internal, bool),
+		FUNCTION 2 pgroonga.get_bool(internal, internal, bool);
 
 CREATE OPERATOR CLASS pgroonga.int2_ops DEFAULT FOR TYPE int2
 	USING pgroonga AS
@@ -248,7 +296,8 @@ CREATE OPERATOR CLASS pgroonga.int2_ops DEFAULT FOR TYPE int2
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_int2(internal, internal, int2);
+		FUNCTION 1 pgroonga.get_int2(internal, internal, int2),
+		FUNCTION 2 pgroonga.get_int2(internal, internal, int2);
 
 CREATE OPERATOR CLASS pgroonga.int4_ops DEFAULT FOR TYPE int4
 	USING pgroonga AS
@@ -257,7 +306,8 @@ CREATE OPERATOR CLASS pgroonga.int4_ops DEFAULT FOR TYPE int4
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_int4(internal, internal, int4);
+		FUNCTION 1 pgroonga.get_int4(internal, internal, int4),
+		FUNCTION 2 pgroonga.get_int4(internal, internal, int4);
 
 CREATE OPERATOR CLASS pgroonga.int8_ops DEFAULT FOR TYPE int8
 	USING pgroonga AS
@@ -266,7 +316,8 @@ CREATE OPERATOR CLASS pgroonga.int8_ops DEFAULT FOR TYPE int8
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_int8(internal, internal, int8);
+		FUNCTION 1 pgroonga.get_int8(internal, internal, int8),
+		FUNCTION 2 pgroonga.get_int8(internal, internal, int8);
 
 CREATE OPERATOR CLASS pgroonga.float4_ops DEFAULT FOR TYPE float4
 	USING pgroonga AS
@@ -275,7 +326,8 @@ CREATE OPERATOR CLASS pgroonga.float4_ops DEFAULT FOR TYPE float4
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_float4(internal, internal, float4);
+		FUNCTION 1 pgroonga.get_float4(internal, internal, float4),
+		FUNCTION 2 pgroonga.get_float4(internal, internal, float4);
 
 CREATE OPERATOR CLASS pgroonga.float8_ops DEFAULT FOR TYPE float8
 	USING pgroonga AS
@@ -284,7 +336,8 @@ CREATE OPERATOR CLASS pgroonga.float8_ops DEFAULT FOR TYPE float8
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_float8(internal, internal, float8);
+		FUNCTION 1 pgroonga.get_float8(internal, internal, float8),
+		FUNCTION 2 pgroonga.get_float8(internal, internal, float8);
 
 CREATE OPERATOR CLASS pgroonga.timestamp_ops DEFAULT FOR TYPE timestamp
 	USING pgroonga AS
@@ -293,7 +346,8 @@ CREATE OPERATOR CLASS pgroonga.timestamp_ops DEFAULT FOR TYPE timestamp
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_timestamp(internal, internal, timestamp);
+		FUNCTION 1 pgroonga.get_timestamp(internal, internal, timestamp),
+		FUNCTION 2 pgroonga.get_timestamp(internal, internal, timestamp);
 
 CREATE OPERATOR CLASS pgroonga.timestamptz_ops DEFAULT FOR TYPE timestamptz
 	USING pgroonga AS
@@ -302,4 +356,5 @@ CREATE OPERATOR CLASS pgroonga.timestamptz_ops DEFAULT FOR TYPE timestamptz
 		OPERATOR 3 =,
 		OPERATOR 4 >=,
 		OPERATOR 5 >,
-		FUNCTION 1 pgroonga.get_timestamptz(internal, internal, timestamptz);
+		FUNCTION 1 pgroonga.get_timestamptz(internal, internal, timestamptz),
+		FUNCTION 2 pgroonga.get_timestamptz(internal, internal, timestamptz);

  Modified: pgroonga_types.c (+33 -0)
===================================================================
--- pgroonga_types.c    2015-02-14 22:50:50 +0900 (243f1cf)
+++ pgroonga_types.c    2015-02-15 00:48:12 +0900 (e8221c8)
@@ -6,6 +6,7 @@
 #include "pgroonga.h"
 
 #include <catalog/pg_type.h>
+#include <utils/array.h>
 #include <utils/builtins.h>
 #include <utils/timestamp.h>
 
@@ -30,6 +31,7 @@ pgroonga_bpchar_size(const BpChar *arg)
 }
 
 PG_FUNCTION_INFO_V1(pgroonga_get_text);
+PG_FUNCTION_INFO_V1(pgroonga_get_text_array);
 PG_FUNCTION_INFO_V1(pgroonga_get_bpchar);
 PG_FUNCTION_INFO_V1(pgroonga_get_bool);
 PG_FUNCTION_INFO_V1(pgroonga_get_int2);
@@ -62,6 +64,37 @@ pgroonga_get_text(PG_FUNCTION_ARGS)
 }
 
 Datum
+pgroonga_get_text_array(PG_FUNCTION_ARGS)
+{
+	grn_ctx	*ctx = (grn_ctx *) PG_GETARG_POINTER(0);
+	grn_obj	*obj = (grn_obj *) PG_GETARG_POINTER(1);
+	ArrayType *value = PG_GETARG_ARRAYTYPE_P(2);
+	int i, n;
+
+	n = ARR_DIMS(value)[0];
+	for (i = 1; i <= n; i++)
+	{
+		int weight = 0;
+		Datum elementDatum;
+		text *element;
+		bool isNULL;
+
+		elementDatum = array_ref(value, 1, &i, -1, -1, false, 'i', &isNULL);
+		if (isNULL)
+			continue;
+
+		element = DatumGetTextPP(elementDatum);
+		grn_vector_add_element(ctx, obj,
+							   VARDATA_ANY(element),
+							   VARSIZE_ANY_EXHDR(element),
+							   weight,
+							   obj->header.domain);
+	}
+
+	PG_RETURN_VOID();
+}
+
+Datum
 pgroonga_get_bpchar(PG_FUNCTION_ARGS)
 {
 	grn_ctx	   *ctx = (grn_ctx *) PG_GETARG_POINTER(0);

  Added: sql/array/text/single/contain/indexscan.sql (+20 -0) 100644
===================================================================
--- /dev/null
+++ sql/array/text/single/contain/indexscan.sql    2015-02-15 00:48:12 +0900 (9cb0a1e)
@@ -0,0 +1,20 @@
+CREATE TABLE memos (
+  title text,
+  tags text[]
+);
+
+INSERT INTO memos VALUES ('PostgreSQL', ARRAY['PostgreSQL']);
+INSERT INTO memos VALUES ('Groonga', ARRAY['Groonga']);
+INSERT INTO memos VALUES ('PGroonga', ARRAY['PostgreSQL', 'Groonga']);
+
+CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (tags);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+SELECT title, tags
+  FROM memos
+ WHERE tags %% 'Groonga';
+
+DROP TABLE memos;
-------------- next part --------------
HTML����������������������������...
Descargar 



More information about the Groonga-commit mailing list
Back to archive index