Kouhei Sutou
null+****@clear*****
Mon Sep 5 00:15:02 JST 2016
Kouhei Sutou 2016-09-05 00:15:02 +0900 (Mon, 05 Sep 2016) New Revision: 4fe50283b6cdef29274235aa7772ad6e9500fd8e https://github.com/pgroonga/pgroonga/commit/4fe50283b6cdef29274235aa7772ad6e9500fd8e Message: Support IN by integers GitHub: fix #21 Reported by yongxianggao-chanjet. Thanks!!! Added files: expected/compare/integer/single/in/bitmapscan.out expected/compare/integer/single/in/indexscan.out expected/compare/integer/single/in/seqscan.out sql/compare/integer/single/in/bitmapscan.sql sql/compare/integer/single/in/indexscan.sql sql/compare/integer/single/in/seqscan.sql Modified files: src/pgroonga.c Added: expected/compare/integer/single/in/bitmapscan.out (+29 -0) 100644 =================================================================== --- /dev/null +++ expected/compare/integer/single/in/bitmapscan.out 2016-09-05 00:15:02 +0900 (a54f247) @@ -0,0 +1,29 @@ +CREATE TABLE ids ( + id integer +); +INSERT INTO ids VALUES (2); +INSERT INTO ids VALUES (7); +INSERT INTO ids VALUES (6); +INSERT INTO ids VALUES (4); +INSERT INTO ids VALUES (5); +INSERT INTO ids VALUES (8); +INSERT INTO ids VALUES (1); +INSERT INTO ids VALUES (10); +INSERT INTO ids VALUES (3); +INSERT INTO ids VALUES (9); +CREATE INDEX pgroonga_index ON ids USING pgroonga (id); +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; +SELECT id + FROM ids + WHERE id IN (6, 1, 7) + ORDER BY id ASC; + id +---- + 1 + 6 + 7 +(3 rows) + +DROP TABLE ids; Added: expected/compare/integer/single/in/indexscan.out (+29 -0) 100644 =================================================================== --- /dev/null +++ expected/compare/integer/single/in/indexscan.out 2016-09-05 00:15:02 +0900 (f26d047) @@ -0,0 +1,29 @@ +CREATE TABLE ids ( + id integer +); +INSERT INTO ids VALUES (2); +INSERT INTO ids VALUES (7); +INSERT INTO ids VALUES (6); +INSERT INTO ids VALUES (4); +INSERT INTO ids VALUES (5); +INSERT INTO ids VALUES (8); +INSERT INTO ids VALUES (1); +INSERT INTO ids VALUES (10); +INSERT INTO ids VALUES (3); +INSERT INTO ids VALUES (9); +CREATE INDEX pgroonga_index ON ids USING pgroonga (id); +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; +SELECT id + FROM ids + WHERE id IN (6, 1, 7) + ORDER BY id ASC; + id +---- + 1 + 6 + 7 +(3 rows) + +DROP TABLE ids; Added: expected/compare/integer/single/in/seqscan.out (+28 -0) 100644 =================================================================== --- /dev/null +++ expected/compare/integer/single/in/seqscan.out 2016-09-05 00:15:02 +0900 (e3f9ba0) @@ -0,0 +1,28 @@ +CREATE TABLE ids ( + id integer +); +INSERT INTO ids VALUES (2); +INSERT INTO ids VALUES (7); +INSERT INTO ids VALUES (6); +INSERT INTO ids VALUES (4); +INSERT INTO ids VALUES (5); +INSERT INTO ids VALUES (8); +INSERT INTO ids VALUES (1); +INSERT INTO ids VALUES (10); +INSERT INTO ids VALUES (3); +INSERT INTO ids VALUES (9); +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; +SELECT id + FROM ids + WHERE id IN (6, 1, 7) + ORDER BY id ASC; + id +---- + 1 + 6 + 7 +(3 rows) + +DROP TABLE ids; Added: sql/compare/integer/single/in/bitmapscan.sql (+27 -0) 100644 =================================================================== --- /dev/null +++ sql/compare/integer/single/in/bitmapscan.sql 2016-09-05 00:15:02 +0900 (78df292) @@ -0,0 +1,27 @@ +CREATE TABLE ids ( + id integer +); + +INSERT INTO ids VALUES (2); +INSERT INTO ids VALUES (7); +INSERT INTO ids VALUES (6); +INSERT INTO ids VALUES (4); +INSERT INTO ids VALUES (5); +INSERT INTO ids VALUES (8); +INSERT INTO ids VALUES (1); +INSERT INTO ids VALUES (10); +INSERT INTO ids VALUES (3); +INSERT INTO ids VALUES (9); + +CREATE INDEX pgroonga_index ON ids USING pgroonga (id); + +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; + +SELECT id + FROM ids + WHERE id IN (6, 1, 7) + ORDER BY id ASC; + +DROP TABLE ids; Added: sql/compare/integer/single/in/indexscan.sql (+27 -0) 100644 =================================================================== --- /dev/null +++ sql/compare/integer/single/in/indexscan.sql 2016-09-05 00:15:02 +0900 (f4dc021) @@ -0,0 +1,27 @@ +CREATE TABLE ids ( + id integer +); + +INSERT INTO ids VALUES (2); +INSERT INTO ids VALUES (7); +INSERT INTO ids VALUES (6); +INSERT INTO ids VALUES (4); +INSERT INTO ids VALUES (5); +INSERT INTO ids VALUES (8); +INSERT INTO ids VALUES (1); +INSERT INTO ids VALUES (10); +INSERT INTO ids VALUES (3); +INSERT INTO ids VALUES (9); + +CREATE INDEX pgroonga_index ON ids USING pgroonga (id); + +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; + +SELECT id + FROM ids + WHERE id IN (6, 1, 7) + ORDER BY id ASC; + +DROP TABLE ids; Added: sql/compare/integer/single/in/seqscan.sql (+25 -0) 100644 =================================================================== --- /dev/null +++ sql/compare/integer/single/in/seqscan.sql 2016-09-05 00:15:02 +0900 (068fe5b) @@ -0,0 +1,25 @@ +CREATE TABLE ids ( + id integer +); + +INSERT INTO ids VALUES (2); +INSERT INTO ids VALUES (7); +INSERT INTO ids VALUES (6); +INSERT INTO ids VALUES (4); +INSERT INTO ids VALUES (5); +INSERT INTO ids VALUES (8); +INSERT INTO ids VALUES (1); +INSERT INTO ids VALUES (10); +INSERT INTO ids VALUES (3); +INSERT INTO ids VALUES (9); + +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; + +SELECT id + FROM ids + WHERE id IN (6, 1, 7) + ORDER BY id ASC; + +DROP TABLE ids; Modified: src/pgroonga.c (+114 -5) =================================================================== --- src/pgroonga.c 2016-08-31 16:36:47 +0900 (a59363f) +++ src/pgroonga.c 2016-09-05 00:15:02 +0900 (d9b99db) @@ -2245,6 +2245,72 @@ pgroonga_beginscan(PG_FUNCTION_ARGS) PG_RETURN_POINTER(scan); } +static bool +PGrnSearchIsInCondition(ScanKey key) +{ + return (key->sk_flags & SK_SEARCHARRAY && + key->sk_strategy == PGrnEqualStrategyNumber); +} + +static bool +PGrnSearchBuildConditionIn(PGrnSearchData *data, + ScanKey key, + grn_obj *targetColumn, + Form_pg_attribute attribute) +{ + grn_id domain; + unsigned char flags = 0; + ArrayType *values; + int i, n; + + domain = PGrnPGTypeToGrnType(attribute->atttypid, &flags); + grn_obj_reinit(ctx, &(buffers->general), domain, flags); + values = DatumGetArrayTypeP(key->sk_argument); + n = ARR_DIMS(values)[0]; + + grn_expr_append_obj(ctx, data->expression, + PGrnLookup("in_values", ERROR), + GRN_OP_PUSH, + 1); + PGrnCheck("pgroonga: IN: failed to push in_values()"); + grn_expr_append_obj(ctx, data->expression, + targetColumn, + GRN_OP_PUSH, + 1); + PGrnCheck("pgroonga: IN: failed to push target column"); + grn_expr_append_op(ctx, data->expression, GRN_OP_GET_VALUE, 1); + PGrnCheck("pgroonga: IN: failed to push GET_VALUE"); + + for (i = 1; i <= n; i++) + { + Datum valueDatum; + bool isNULL; + + valueDatum = array_ref(values, 1, &i, -1, + attribute->attlen, + attribute->attbyval, + attribute->attalign, + &isNULL); + if (isNULL) + return false; + + PGrnConvertFromData(valueDatum, + attribute->atttypid, + &(buffers->general)); + grn_expr_append_const(ctx, + data->expression, + &(buffers->general), + GRN_OP_PUSH, + 1); + PGrnCheck("pgroonga: IN: failed to push a value"); + } + + grn_expr_append_op(ctx, data->expression, GRN_OP_CALL, 2 + (n - 1)); + PGrnCheck("pgroonga: IN: failed to push CALL"); + + return true; +} + static void PGrnSearchBuildConditionLikeMatchFlush(grn_obj *expression, grn_obj *targetColumn, @@ -2570,6 +2636,9 @@ PGrnSearchBuildCondition(Relation index, targetColumn = PGrnLookupColumn(data->sourcesTable, targetColumnName, ERROR); GRN_PTR_PUT(ctx, &(data->targetColumns), targetColumn); + if (PGrnSearchIsInCondition(key)) + return PGrnSearchBuildConditionIn(data, key, targetColumn, attribute); + if (PGrnAttributeIsJSONB(attribute->atttypid)) return PGrnJSONBBuildSearchCondition(data, key, targetColumn); @@ -2845,7 +2914,44 @@ PGrnSearch(IndexScanDesc scan) static void PGrnSort(IndexScanDesc scan) { - /* TODO */ + PGrnScanOpaque so = (PGrnScanOpaque) scan->opaque; + ScanKey key; + TupleDesc desc; + Form_pg_attribute attribute; + const char *targetColumnName; + grn_table_sort_key sort_key; + + if (!so->searched) + return; + + if (scan->numberOfKeys != 1) + return; + + key = &(scan->keyData[0]); + if (!PGrnSearchIsInCondition(key)) + return; + + so->sorted = grn_table_create(ctx, NULL, 0, NULL, + GRN_OBJ_TABLE_NO_KEY, + NULL, so->searched); + + desc = RelationGetDescr(scan->indexRelation); + attribute = desc->attrs[key->sk_attno - 1]; + targetColumnName = attribute->attname.data; + sort_key.key = grn_obj_column(ctx, so->searched, + targetColumnName, + strlen(targetColumnName)); + + sort_key.flags = GRN_TABLE_SORT_ASC; + sort_key.offset = 0; + grn_table_sort(ctx, + so->searched, + 0, + -1, + so->sorted, + &sort_key, + 1); + grn_obj_close(ctx, sort_key.key); } static void @@ -3122,7 +3228,9 @@ PGrnIsRangeSearchable(IndexScanDesc scan) } static void -PGrnEnsureCursorOpened(IndexScanDesc scan, ScanDirection dir) +PGrnEnsureCursorOpened(IndexScanDesc scan, + ScanDirection dir, + bool needSort) { PGrnScanOpaque so = (PGrnScanOpaque) scan->opaque; @@ -3156,7 +3264,8 @@ PGrnEnsureCursorOpened(IndexScanDesc scan, ScanDirection dir) else { PGrnSearch(scan); - PGrnSort(scan); + if (needSort) + PGrnSort(scan); PGrnOpenTableCursor(scan, dir); } } @@ -3221,7 +3330,7 @@ pgroonga_gettuple_raw(IndexScanDesc scan, { PGrnScanOpaque so = (PGrnScanOpaque) scan->opaque; - PGrnEnsureCursorOpened(scan, direction); + PGrnEnsureCursorOpened(scan, direction, true); if (scan->kill_prior_tuple && so->currentID != GRN_ID_NIL) { @@ -3284,7 +3393,7 @@ pgroonga_getbitmap_raw(IndexScanDesc scan, PGrnScanOpaque so = (PGrnScanOpaque) scan->opaque; int64 nRecords = 0; - PGrnEnsureCursorOpened(scan, ForwardScanDirection); + PGrnEnsureCursorOpened(scan, ForwardScanDirection, false); if (so->indexCursor) { -------------- next part -------------- HTML����������������������������... Download