Kouhei Sutou
null+****@clear*****
Fri Jun 30 15:06:13 JST 2017
Kouhei Sutou 2017-06-30 15:06:13 +0900 (Fri, 30 Jun 2017) New Revision: f9486d6baed9afb5e40627eb9156562e758406a3 https://github.com/pgroonga/pgroonga/commit/f9486d6baed9afb5e40627eb9156562e758406a3 Message: query_expand: support hash index Added files: expected/function/query-expand/hash-index.out sql/function/query-expand/hash-index.sql Modified files: src/pgrn-query-expand.c Added: expected/function/query-expand/hash-index.out (+0 -0) 100644 =================================================================== --- /dev/null +++ expected/function/query-expand/hash-index.out 2017-06-30 15:06:13 +0900 (e69de29) Added: sql/function/query-expand/hash-index.sql (+12 -0) 100644 =================================================================== --- /dev/null +++ sql/function/query-expand/hash-index.sql 2017-06-30 15:06:13 +0900 (d1e5766) @@ -0,0 +1,12 @@ +CREATE TABLE synonyms ( + term text, + synonyms text[] +); + +CREATE INDEX synonyms_term_index ON synonyms USING hash (term); + +INSERT INTO synonyms VALUES ('Groonga', ARRAY['Groonga', 'Senna']); + +SELECT pgroonga.query_expand('synonyms', 'term', 'synonyms', 'Groonga'); + +DROP TABLE synonyms; Modified: src/pgrn-query-expand.c (+65 -48) =================================================================== --- src/pgrn-query-expand.c 2017-06-30 11:48:30 +0900 (1b57426) +++ src/pgrn-query-expand.c 2017-06-30 15:06:13 +0900 (d09c870) @@ -6,6 +6,7 @@ #include "pgrn-query-expand.h" #include <access/relscan.h> +#include <catalog/pg_operator.h> #include <catalog/pg_type.h> #include <utils/array.h> #include <utils/builtins.h> @@ -20,6 +21,7 @@ typedef struct { Relation table; Relation index; + AttrNumber indexAttributeNumber; Form_pg_attribute synonymsAttribute; Snapshot snapshot; IndexScanDesc scan; @@ -60,57 +62,68 @@ func_query_expander_postgresql(grn_ctx *ctx, } termText = cstring_to_text_with_len(GRN_TEXT_VALUE(term), GRN_TEXT_LEN(term)); - ScanKeyInit(&(scanKeys[0]), - 1, - BTEqualStrategyNumber, - 67, // F_TEXTEQ - PointerGetDatum(termText)); - index_rescan(currentData.scan, scanKeys, nKeys, NULL, 0); - tuple = index_getnext(currentData.scan, ForwardScanDirection); - if (!tuple) - goto exit; - - synonymsDatum = heap_getattr(tuple, - currentData.synonymsAttribute->attnum, - RelationGetDescr(currentData.table), - &isNULL); - if (isNULL) - goto exit; - { - ArrayType *synonymsArray; - int i, n; - - synonymsArray = DatumGetArrayTypeP(synonymsDatum); - n = ARR_DIMS(synonymsArray)[0]; - if (n > 1) - GRN_TEXT_PUTC(ctx, expandedTerm, '('); - for (i = 1; i <= n; i++) - { - Datum synonymDatum; - bool isNULL; - text *synonym; - - synonymDatum = array_ref(synonymsArray, 1, &i, -1, - currentData.synonymsAttribute->attlen, - currentData.synonymsAttribute->attbyval, - currentData.synonymsAttribute->attalign, + Oid opNo = TextEqualOperator; + Oid opFamily; + int opStrategy; + RegProcedure opFunctionID; + + opFamily = + currentData.index->rd_opfamily[currentData.indexAttributeNumber - 1]; + opStrategy = get_op_opfamily_strategy(opNo, opFamily); + opFunctionID = get_opcode(opNo); + ScanKeyInit(&(scanKeys[0]), + currentData.indexAttributeNumber, + opStrategy, + opFunctionID, + PointerGetDatum(termText)); + index_rescan(currentData.scan, scanKeys, nKeys, NULL, 0); + tuple = index_getnext(currentData.scan, ForwardScanDirection); + if (!tuple) + goto exit; + + synonymsDatum = heap_getattr(tuple, + currentData.synonymsAttribute->attnum, + RelationGetDescr(currentData.table), &isNULL); - synonym = DatumGetTextP(synonymDatum); - if (i > 1) - GRN_TEXT_PUTS(ctx, expandedTerm, " OR "); + if (isNULL) + goto exit; + + { + ArrayType *synonymsArray; + int i, n; + + synonymsArray = DatumGetArrayTypeP(synonymsDatum); + n = ARR_DIMS(synonymsArray)[0]; if (n > 1) GRN_TEXT_PUTC(ctx, expandedTerm, '('); - GRN_TEXT_PUT(ctx, expandedTerm, - VARDATA_ANY(synonym), - VARSIZE_ANY_EXHDR(synonym)); + for (i = 1; i <= n; i++) + { + Datum synonymDatum; + bool isNULL; + text *synonym; + + synonymDatum = array_ref(synonymsArray, 1, &i, -1, + currentData.synonymsAttribute->attlen, + currentData.synonymsAttribute->attbyval, + currentData.synonymsAttribute->attalign, + &isNULL); + synonym = DatumGetTextP(synonymDatum); + if (i > 1) + GRN_TEXT_PUTS(ctx, expandedTerm, " OR "); + if (n > 1) + GRN_TEXT_PUTC(ctx, expandedTerm, '('); + GRN_TEXT_PUT(ctx, expandedTerm, + VARDATA_ANY(synonym), + VARSIZE_ANY_EXHDR(synonym)); + if (n > 1) + GRN_TEXT_PUTC(ctx, expandedTerm, ')'); + } if (n > 1) GRN_TEXT_PUTC(ctx, expandedTerm, ')'); - } - if (n > 1) - GRN_TEXT_PUTC(ctx, expandedTerm, ')'); - rc = GRN_SUCCESS; + rc = GRN_SUCCESS; + } } exit: @@ -181,7 +194,8 @@ PGrnFindSynonymsAttribute(const char *tableName, static Relation PGrnFindTargetIndex(Relation table, const char *columnName, - size_t columnNameSize) + size_t columnNameSize, + AttrNumber *indexAttributeNumber) { Relation index = InvalidRelation; List *indexOIDList; @@ -201,6 +215,7 @@ PGrnFindTargetIndex(Relation table, if (strlen(name) == columnNameSize && memcmp(name, columnName, columnNameSize) == 0) { + *indexAttributeNumber = i; isTargetIndex = true; break; } @@ -251,9 +266,11 @@ pgroonga_query_expand(PG_FUNCTION_ARGS) VARDATA_ANY(synonymsColumnName), VARSIZE_ANY_EXHDR(synonymsColumnName)); - currentData.index = PGrnFindTargetIndex(currentData.table, - VARDATA_ANY(termColumnName), - VARSIZE_ANY_EXHDR(termColumnName)); + currentData.index = + PGrnFindTargetIndex(currentData.table, + VARDATA_ANY(termColumnName), + VARSIZE_ANY_EXHDR(termColumnName), + &(currentData.indexAttributeNumber)); if (!currentData.index) { ereport(ERROR, -------------- next part -------------- HTML����������������������������... 下載