Kouhei Sutou
null+****@clear*****
Thu Jun 29 17:50:16 JST 2017
Kouhei Sutou 2017-06-29 17:50:16 +0900 (Thu, 29 Jun 2017) New Revision: 25bb37a64a7280febba3e0c08f7212fa13255019 https://github.com/pgroonga/pgroonga/commit/25bb37a64a7280febba3e0c08f7212fa13255019 Message: Extract file for pgroonga.query_expand Added files: src/pgrn-query-expand.c Modified files: makefiles/pgroonga-sources.mk src/pgroonga.c Modified: makefiles/pgroonga-sources.mk (+1 -0) =================================================================== --- makefiles/pgroonga-sources.mk 2017-06-29 11:38:55 +0900 (5cd0805) +++ makefiles/pgroonga-sources.mk 2017-06-29 17:50:16 +0900 (dcde72f) @@ -19,6 +19,7 @@ SRCS = \ src/pgrn-options.c \ src/pgrn-pg.c \ src/pgrn-query-escape.c \ + src/pgrn-query-expand.c \ src/pgrn-query-extract-keywords.c \ src/pgrn-snippet-html.c \ src/pgrn-value.c \ Added: src/pgrn-query-expand.c (+194 -0) 100644 =================================================================== --- /dev/null +++ src/pgrn-query-expand.c 2017-06-29 17:50:16 +0900 (3f1c29a) @@ -0,0 +1,194 @@ +#include "pgroonga.h" + +#include "pgrn-compatible.h" + +#include "pgrn-global.h" + +#include <access/relscan.h> +#include <catalog/pg_type.h> +#include <utils/array.h> +#include <utils/builtins.h> +#include <utils/rel.h> +#include <utils/snapmgr.h> + +static grn_ctx *ctx = &PGrnContext; + +PGRN_FUNCTION_INFO_V1(pgroonga_query_expand); + +static Relation +PGrnFindTargetIndex(Relation table, + const char *columnName, + size_t columnNameSize) +{ + Relation index = InvalidRelation; + List *indexOIDList; + ListCell *cell; + + indexOIDList = RelationGetIndexList(table); + foreach(cell, indexOIDList) + { + Oid indexOID = lfirst_oid(cell); + bool isTargetIndex = false; + int i; + + index = index_open(indexOID, NoLock); + for (i = 1; i <= index->rd_att->natts; i++) + { + const char *name = index->rd_att->attrs[i - 1]->attname.data; + if (strlen(name) == columnNameSize && + memcmp(name, columnName, columnNameSize) == 0) + { + isTargetIndex = true; + break; + } + } + + if (isTargetIndex) + break; + + index_close(index, NoLock); + index = InvalidRelation; + } + list_free(indexOIDList); + + return index; +} + +/** + * pgroonga.query_expand(tableName cstring, + * termColumnName text, + * synonymsColumnName text, + * query text) : text + */ +Datum +pgroonga_query_expand(PG_FUNCTION_ARGS) +{ + Datum tableNameDatum = PG_GETARG_DATUM(0); + text *termColumnName = PG_GETARG_TEXT_PP(1); + text *synonymsColumnName = PG_GETARG_TEXT_PP(2); + Datum queryDatum = PG_GETARG_DATUM(3); + Datum tableOIDDatum; + Oid tableOID; + Relation table; + TupleDesc desc; + int i; + Form_pg_attribute synonymsAttribute = NULL; + Relation index; + grn_obj expandedQuery; + + tableOIDDatum = DirectFunctionCall1(regclassin, tableNameDatum); + if (!OidIsValid(tableOIDDatum)) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("pgroonga: query_expand: unknown table name: <%s>", + DatumGetCString(tableNameDatum)))); + } + tableOID = DatumGetObjectId(tableOIDDatum); + + table = RelationIdGetRelation(tableOID); + desc = RelationGetDescr(table); + for (i = 1; i <= desc->natts; i++) + { + Form_pg_attribute attribute = desc->attrs[i - 1]; + if (strlen(attribute->attname.data) == + VARSIZE_ANY_EXHDR(synonymsColumnName) && + strncmp(attribute->attname.data, + VARDATA_ANY(synonymsColumnName), + VARSIZE_ANY_EXHDR(synonymsColumnName)) == 0) + { + synonymsAttribute = attribute; + break; + } + } + if (!synonymsAttribute) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("pgroonga: query_expand: " + "synonyms column doesn't exist: <%s>.<%.*s>", + DatumGetCString(tableNameDatum), + (int)VARSIZE_ANY_EXHDR(synonymsColumnName), + VARDATA_ANY(synonymsColumnName)))); + } + + index = PGrnFindTargetIndex(table, + VARDATA_ANY(termColumnName), + VARSIZE_ANY_EXHDR(termColumnName)); + if (!index) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("pgroonga: query_expand: " + "index for term column doesn't exist: <%s>.<%.*s>", + DatumGetCString(tableNameDatum), + (int)VARSIZE_ANY_EXHDR(termColumnName), + VARDATA_ANY(termColumnName)))); + } + + GRN_TEXT_INIT(&expandedQuery, 0); + { + Snapshot snapshot; + IndexScanDesc scan; + ScanKeyData scanKeys[1]; + HeapTuple tuple; + Datum synonymsDatum; + ArrayType *synonymsArray; + bool isNULL; + + snapshot = GetActiveSnapshot(); + scan = index_beginscan(table, index, snapshot, 1, 0); + ScanKeyInit(&(scanKeys[0]), + 1, + BTEqualStrategyNumber, + 67, // F_TEXTEQ + queryDatum); + index_rescan(scan, scanKeys, 1, NULL, 0); + tuple = index_getnext(scan, ForwardScanDirection); + synonymsDatum = heap_getattr(tuple, + synonymsAttribute->attnum, + desc, + &isNULL); + synonymsArray = DatumGetArrayTypeP(synonymsDatum); + { + int i, n; + + n = ARR_DIMS(synonymsArray)[0]; + for (i = 1; i <= n; i++) + { + Datum synonymDatum; + bool isNULL; + text *synonym; + + synonymDatum = array_ref(synonymsArray, 1, &i, -1, + synonymsAttribute->attlen, + synonymsAttribute->attbyval, + synonymsAttribute->attalign, + &isNULL); + synonym = DatumGetTextP(synonymDatum); + if (GRN_TEXT_LEN(&expandedQuery) > 0) + GRN_TEXT_PUTS(ctx, &expandedQuery, " OR "); + GRN_TEXT_PUT(ctx, &expandedQuery, + VARDATA_ANY(synonym), + VARSIZE_ANY_EXHDR(synonym)); + } + } + index_endscan(scan); + + index_close(index, NoLock); + } + + RelationClose(table); + + { + text *expandedQueryText; + + expandedQueryText = + cstring_to_text_with_len(GRN_TEXT_VALUE(&expandedQuery), + GRN_TEXT_LEN(&expandedQuery)); + GRN_OBJ_FIN(ctx, &expandedQuery); + + PG_RETURN_TEXT_P(expandedQueryText); + } +} + Modified: src/pgroonga.c (+0 -179) =================================================================== --- src/pgroonga.c 2017-06-29 11:38:55 +0900 (452c396) +++ src/pgroonga.c 2017-06-29 17:50:16 +0900 (7cb1ceb) @@ -52,7 +52,6 @@ #include <utils/typcache.h> #include <lib/ilist.h> -#include <utils/snapmgr.h> #include <groonga.h> @@ -140,7 +139,6 @@ extern PGDLLEXPORT void _PG_init(void); PGRN_FUNCTION_INFO_V1(pgroonga_score); PGRN_FUNCTION_INFO_V1(pgroonga_table_name); PGRN_FUNCTION_INFO_V1(pgroonga_command); -PGRN_FUNCTION_INFO_V1(pgroonga_query_expand); /* * Naming conversions: @@ -1419,183 +1417,6 @@ pgroonga_command(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(result); } -static Relation -PGrnFindTargetIndex(Relation table, - const char *columnName, - size_t columnNameSize) -{ - Relation index = InvalidRelation; - List *indexOIDList; - ListCell *cell; - - indexOIDList = RelationGetIndexList(table); - foreach(cell, indexOIDList) - { - Oid indexOID = lfirst_oid(cell); - bool isTargetIndex = false; - int i; - - index = index_open(indexOID, NoLock); - for (i = 1; i <= index->rd_att->natts; i++) - { - const char *name = index->rd_att->attrs[i - 1]->attname.data; - if (strlen(name) == columnNameSize && - memcmp(name, columnName, columnNameSize) == 0) - { - isTargetIndex = true; - break; - } - } - - if (isTargetIndex) - break; - - index_close(index, NoLock); - index = InvalidRelation; - } - list_free(indexOIDList); - - return index; -} - -/** - * pgroonga.query_expand(tableName cstring, - * termColumnName text, - * synonymsColumnName text, - * query text) : text - */ -Datum -pgroonga_query_expand(PG_FUNCTION_ARGS) -{ - Datum tableNameDatum = PG_GETARG_DATUM(0); - text *termColumnName = PG_GETARG_TEXT_PP(1); - text *synonymsColumnName = PG_GETARG_TEXT_PP(2); - Datum queryDatum = PG_GETARG_DATUM(3); - Datum tableOIDDatum; - Oid tableOID; - Relation table; - TupleDesc desc; - int i; - Form_pg_attribute synonymsAttribute = NULL; - Relation index; - grn_obj expandedQuery; - - tableOIDDatum = DirectFunctionCall1(regclassin, tableNameDatum); - if (!OidIsValid(tableOIDDatum)) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_NAME), - errmsg("pgroonga: query_expand: unknown table name: <%s>", - DatumGetCString(tableNameDatum)))); - } - tableOID = DatumGetObjectId(tableOIDDatum); - - table = RelationIdGetRelation(tableOID); - desc = RelationGetDescr(table); - for (i = 1; i <= desc->natts; i++) - { - Form_pg_attribute attribute = desc->attrs[i - 1]; - if (strlen(attribute->attname.data) == - VARSIZE_ANY_EXHDR(synonymsColumnName) && - strncmp(attribute->attname.data, - VARDATA_ANY(synonymsColumnName), - VARSIZE_ANY_EXHDR(synonymsColumnName)) == 0) - { - synonymsAttribute = attribute; - break; - } - } - if (!synonymsAttribute) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_NAME), - errmsg("pgroonga: query_expand: " - "synonyms column doesn't exist: <%s>.<%.*s>", - DatumGetCString(tableNameDatum), - (int)VARSIZE_ANY_EXHDR(synonymsColumnName), - VARDATA_ANY(synonymsColumnName)))); - } - - index = PGrnFindTargetIndex(table, - VARDATA_ANY(termColumnName), - VARSIZE_ANY_EXHDR(termColumnName)); - if (!index) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_NAME), - errmsg("pgroonga: query_expand: " - "index for term column doesn't exist: <%s>.<%.*s>", - DatumGetCString(tableNameDatum), - (int)VARSIZE_ANY_EXHDR(termColumnName), - VARDATA_ANY(termColumnName)))); - } - - GRN_TEXT_INIT(&expandedQuery, 0); - { - Snapshot snapshot; - IndexScanDesc scan; - ScanKeyData scanKeys[1]; - HeapTuple tuple; - Datum synonymsDatum; - ArrayType *synonymsArray; - bool isNULL; - - snapshot = GetActiveSnapshot(); - scan = index_beginscan(table, index, snapshot, 1, 0); - ScanKeyInit(&(scanKeys[0]), - 1, - BTEqualStrategyNumber, - 67, // F_TEXTEQ - queryDatum); - index_rescan(scan, scanKeys, 1, NULL, 0); - tuple = index_getnext(scan, ForwardScanDirection); - synonymsDatum = heap_getattr(tuple, - synonymsAttribute->attnum, - desc, - &isNULL); - synonymsArray = DatumGetArrayTypeP(synonymsDatum); - { - int i, n; - - n = ARR_DIMS(synonymsArray)[0]; - for (i = 1; i <= n; i++) - { - Datum synonymDatum; - bool isNULL; - text *synonym; - - synonymDatum = array_ref(synonymsArray, 1, &i, -1, - synonymsAttribute->attlen, - synonymsAttribute->attbyval, - synonymsAttribute->attalign, - &isNULL); - synonym = DatumGetTextP(synonymDatum); - if (GRN_TEXT_LEN(&expandedQuery) > 0) - GRN_TEXT_PUTS(ctx, &expandedQuery, " OR "); - GRN_TEXT_PUT(ctx, &expandedQuery, - VARDATA_ANY(synonym), - VARSIZE_ANY_EXHDR(synonym)); - } - } - index_endscan(scan); - - index_close(index, NoLock); - } - - RelationClose(table); - - { - text *expandedQueryText; - - expandedQueryText = - cstring_to_text_with_len(GRN_TEXT_VALUE(&expandedQuery), - GRN_TEXT_LEN(&expandedQuery)); - GRN_OBJ_FIN(ctx, &expandedQuery); - - PG_RETURN_TEXT_P(expandedQueryText); - } -} - static void PGrnDatumExtractString(Datum datum, Oid type, -------------- next part -------------- HTML����������������������������...下载