Kouhei Sutou
null+****@clear*****
Tue Nov 29 23:49:37 JST 2016
Kouhei Sutou 2016-11-29 23:49:37 +0900 (Tue, 29 Nov 2016) New Revision: 10b7106906ff875475c85e582165e2b80e8fe75e https://github.com/pgroonga/pgroonga/commit/10b7106906ff875475c85e582165e2b80e8fe75e Message: pgroonga.command: support arguments style The style escape command values automatically. Added files: expected/function/command/arguments.out sql/function/command/arguments.sql src/pgrn_command_escape_value.h Modified files: pgroonga--1.1.8--1.1.9.sql pgroonga.sql src/pgrn_command_escape_value.c src/pgroonga.c Added: expected/function/command/arguments.out (+21 -0) 100644 =================================================================== --- /dev/null +++ expected/function/command/arguments.out 2016-11-29 23:49:37 +0900 (050be82) @@ -0,0 +1,21 @@ +CREATE TABLE memos ( + content text +); +INSERT INTO memos VALUES ('PostgreSQL is a RDBMS.'); +INSERT INTO memos VALUES ('Groonga is fast full text search engine.'); +INSERT INTO memos VALUES ('PGroonga is a PostgreSQL extension that uses Groonga.'); +CREATE INDEX pgroonga_index ON memos USING pgroonga (content); +SELECT pgroonga.command('select', + ARRAY[ + 'table', + pgroonga.table_name('pgroonga_index'), + 'output_columns', + '_id, content' + ])::json->>1 + AS body; + body +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + [[[3],[["_id","UInt32"],["content","LongText"]],[1,"PostgreSQL is a RDBMS."],[2,"Groonga is fast full text search engine."],[3,"PGroonga is a PostgreSQL extension that uses Groonga."]]] +(1 row) + +DROP TABLE memos; Modified: pgroonga--1.1.8--1.1.9.sql (+7 -0) =================================================================== --- pgroonga--1.1.8--1.1.9.sql 2016-11-29 23:46:56 +0900 (838d0d2) +++ pgroonga--1.1.8--1.1.9.sql 2016-11-29 23:49:37 +0900 (2bef297) @@ -6,6 +6,13 @@ CREATE FUNCTION pgroonga.table_name(indexName cstring) STABLE STRICT; +CREATE FUNCTION pgroonga.command(groongaCommand text, arguments text[]) + RETURNS text + AS 'MODULE_PATHNAME', 'pgroonga_command' + LANGUAGE C + VOLATILE + STRICT; + CREATE FUNCTION pgroonga.command_escape_value(value text) RETURNS text AS 'MODULE_PATHNAME', 'pgroonga_command_escape_value' Modified: pgroonga.sql (+7 -0) =================================================================== --- pgroonga.sql 2016-11-29 23:46:56 +0900 (acb3aa9) +++ pgroonga.sql 2016-11-29 23:49:37 +0900 (ecda7b4) @@ -23,6 +23,13 @@ CREATE FUNCTION pgroonga.command(groongaCommand text) VOLATILE STRICT; +CREATE FUNCTION pgroonga.command(groongaCommand text, arguments text[]) + RETURNS text + AS 'MODULE_PATHNAME', 'pgroonga_command' + LANGUAGE C + VOLATILE + STRICT; + CREATE FUNCTION pgroonga.snippet_html(target text, keywords text[]) RETURNS text[] AS 'MODULE_PATHNAME', 'pgroonga_snippet_html' Added: sql/function/command/arguments.sql (+20 -0) 100644 =================================================================== --- /dev/null +++ sql/function/command/arguments.sql 2016-11-29 23:49:37 +0900 (226f92b) @@ -0,0 +1,20 @@ +CREATE TABLE memos ( + content text +); + +INSERT INTO memos VALUES ('PostgreSQL is a RDBMS.'); +INSERT INTO memos VALUES ('Groonga is fast full text search engine.'); +INSERT INTO memos VALUES ('PGroonga is a PostgreSQL extension that uses Groonga.'); + +CREATE INDEX pgroonga_index ON memos USING pgroonga (content); + +SELECT pgroonga.command('select', + ARRAY[ + 'table', + pgroonga.table_name('pgroonga_index'), + 'output_columns', + '_id, content' + ])::json->>1 + AS body; + +DROP TABLE memos; Modified: src/pgrn_command_escape_value.c (+30 -21) =================================================================== --- src/pgrn_command_escape_value.c 2016-11-29 23:46:56 +0900 (a2ae21c) +++ src/pgrn_command_escape_value.c 2016-11-29 23:49:37 +0900 (9d40808) @@ -1,7 +1,7 @@ #include "pgroonga.h" +#include "pgrn_command_escape_value.h" #include "pgrn_global.h" -#include "pgrn_groonga.h" #include <utils/builtins.h> @@ -10,24 +10,17 @@ static struct PGrnBuffers *buffers = &PGrnBuffers; PG_FUNCTION_INFO_V1(pgroonga_command_escape_value); -/** - * pgroonga.command_escape_value(value text : text - */ -Datum -pgroonga_command_escape_value(PG_FUNCTION_ARGS) +void +PGrnCommandEscapeValue(const char *value, + size_t valueSize, + grn_obj *escapedValue) { - text *value = PG_GETARG_TEXT_PP(0); - text *escapedValue; - grn_obj *escapedValueBuffer; const char *valueCurrent; const char *valueEnd; - escapedValueBuffer = &(buffers->escape.escapedValue); - - GRN_BULK_REWIND(escapedValueBuffer); - GRN_TEXT_PUTC(ctx, escapedValueBuffer, '"'); - valueCurrent = VARDATA_ANY(value); - valueEnd = valueCurrent + VARSIZE_ANY_EXHDR(value); + GRN_TEXT_PUTC(ctx, escapedValue, '"'); + valueCurrent = value; + valueEnd = valueCurrent + valueSize; while (valueCurrent < valueEnd) { int charLength = grn_charlen(ctx, valueCurrent, valueEnd); @@ -41,26 +34,42 @@ pgroonga_command_escape_value(PG_FUNCTION_ARGS) { case '\\': case '"': - GRN_TEXT_PUTC(ctx, escapedValueBuffer, '\\'); - GRN_TEXT_PUTC(ctx, escapedValueBuffer, *valueCurrent); + GRN_TEXT_PUTC(ctx, escapedValue, '\\'); + GRN_TEXT_PUTC(ctx, escapedValue, *valueCurrent); break; case '\n': - GRN_TEXT_PUTS(ctx, escapedValueBuffer, "\\n"); + GRN_TEXT_PUTS(ctx, escapedValue, "\\n"); break; default: - GRN_TEXT_PUTC(ctx, escapedValueBuffer, *valueCurrent); + GRN_TEXT_PUTC(ctx, escapedValue, *valueCurrent); break; } } else { - GRN_TEXT_PUT(ctx, escapedValueBuffer, valueCurrent, charLength); + GRN_TEXT_PUT(ctx, escapedValue, valueCurrent, charLength); } valueCurrent += charLength; } - GRN_TEXT_PUTC(ctx, escapedValueBuffer, '"'); + GRN_TEXT_PUTC(ctx, escapedValue, '"'); +} +/** + * pgroonga.command_escape_value(value text) : text + */ +Datum +pgroonga_command_escape_value(PG_FUNCTION_ARGS) +{ + text *value = PG_GETARG_TEXT_PP(0); + text *escapedValue; + grn_obj *escapedValueBuffer; + + escapedValueBuffer = &(buffers->escape.escapedValue); + GRN_BULK_REWIND(escapedValueBuffer); + PGrnCommandEscapeValue(VARDATA_ANY(value), + VARSIZE_ANY_EXHDR(value), + escapedValueBuffer); escapedValue = cstring_to_text_with_len(GRN_TEXT_VALUE(escapedValueBuffer), GRN_TEXT_LEN(escapedValueBuffer)); PG_RETURN_TEXT_P(escapedValue); Added: src/pgrn_command_escape_value.h (+7 -0) 100644 =================================================================== --- /dev/null +++ src/pgrn_command_escape_value.h 2016-11-29 23:49:37 +0900 (0b78257) @@ -0,0 +1,7 @@ +#pragma once + +#include <groonga.h> + +void PGrnCommandEscapeValue(const char *value, + size_t valueSize, + grn_obj *escapedValue); Modified: src/pgroonga.c (+62 -3) =================================================================== --- src/pgroonga.c 2016-11-29 23:46:56 +0900 (943c59e) +++ src/pgroonga.c 2016-11-29 23:49:37 +0900 (7682353) @@ -2,6 +2,7 @@ #include "pgrn_compatible.h" +#include "pgrn_command_escape_value.h" #include "pgrn_convert.h" #include "pgrn_create.h" #include "pgrn_ctid.h" @@ -1122,6 +1123,7 @@ pgroonga_table_name(PG_FUNCTION_ARGS) /** * pgroonga.command(groongaCommand text) : text + * pgroonga.command(groongaCommandName text, arguments text[]) : text */ Datum pgroonga_command(PG_FUNCTION_ARGS) @@ -1131,9 +1133,66 @@ pgroonga_command(PG_FUNCTION_ARGS) int flags = 0; text *result; - grn_ctx_send(ctx, - VARDATA_ANY(groongaCommand), - VARSIZE_ANY_EXHDR(groongaCommand), 0); + if (PG_NARGS() == 2) + { + grn_obj *command = &(buffers->general); + ArrayType *arguments = PG_GETARG_ARRAYTYPE_P(1); + int i, n; + + n = ARR_DIMS(arguments)[0]; + if ((n % 2) != 0) + { + } + + grn_obj_reinit(ctx, command, GRN_DB_TEXT, 0); + GRN_TEXT_PUT(ctx, + command, + VARDATA_ANY(groongaCommand), + VARSIZE_ANY_EXHDR(groongaCommand)); + for (i = 1; i <= n; i += 2) + { + int nameIndex = i; + Datum nameDatum; + text *name; + int valueIndex = i + 1; + Datum valueDatum; + text *value; + bool isNULL; + + nameDatum = array_ref(arguments, 1, &nameIndex, -1, -1, false, + 'i', &isNULL); + if (isNULL) + continue; + valueDatum = array_ref(arguments, 1, &valueIndex, -1, -1, false, + 'i', &isNULL); + if (isNULL) + continue; + + name = DatumGetTextPP(nameDatum); + value = DatumGetTextPP(valueDatum); + + GRN_TEXT_PUTS(ctx, command, " --"); + GRN_TEXT_PUT(ctx, + command, + VARDATA_ANY(name), + VARSIZE_ANY_EXHDR(name)); + GRN_TEXT_PUTC(ctx, command, ' '); + PGrnCommandEscapeValue(VARDATA_ANY(value), + VARSIZE_ANY_EXHDR(value), + command); + } + grn_ctx_send(ctx, + GRN_TEXT_VALUE(command), + GRN_TEXT_LEN(command), + 0); + } + else + { + grn_ctx_send(ctx, + VARDATA_ANY(groongaCommand), + VARSIZE_ANY_EXHDR(groongaCommand), + 0); + } rc = ctx->rc; GRN_BULK_REWIND(&(buffers->body)); -------------- next part -------------- HTML����������������������������...Download