Kouhei Sutou
null+****@clear*****
Tue Nov 29 11:01:10 JST 2016
Kouhei Sutou 2016-11-29 11:01:10 +0900 (Tue, 29 Nov 2016) New Revision: e99abd2acd2f6eafd6e4f23e48d9e72fba252ef6 https://github.com/pgroonga/pgroonga/commit/e99abd2acd2f6eafd6e4f23e48d9e72fba252ef6 Message: Add pgroonga.escape() It's useful for avoiding syntax error in `@@` by user input. Added files: expected/function/escape/with-special-characters.out expected/function/escape/without-special-characters.out sql/function/escape/with-special-characters.sql sql/function/escape/without-special-characters.sql src/pgrn_escape.c Modified files: pgroonga--1.1.8--1.1.9.sql pgroonga.sql sources.am src/pgrn_global.c src/pgrn_global.h src/pgroonga.h Added: expected/function/escape/with-special-characters.out (+6 -0) 100644 =================================================================== --- /dev/null +++ expected/function/escape/with-special-characters.out 2016-11-29 11:01:10 +0900 (85f94df) @@ -0,0 +1,6 @@ +SELECT pgroonga.escape('a+O-R< >あいう~*()"'':', '()OR:'); + escape +---------------------------- + a+\O-\R< >あいう~*\(\)"'\: +(1 row) + Added: expected/function/escape/without-special-characters.out (+6 -0) 100644 =================================================================== --- /dev/null +++ expected/function/escape/without-special-characters.out 2016-11-29 11:01:10 +0900 (af9ef13) @@ -0,0 +1,6 @@ +SELECT pgroonga.escape('a+B-c< >あいう~*()"'':'); + escape +--------------------------------- + a\+B\-c\< \>あいう\~\*\(\)\"'\: +(1 row) + Modified: pgroonga--1.1.8--1.1.9.sql (+13 -0) =================================================================== --- pgroonga--1.1.8--1.1.9.sql 2016-11-29 10:53:07 +0900 (e69de29) +++ pgroonga--1.1.8--1.1.9.sql 2016-11-29 11:01:10 +0900 (484b1fd) @@ -0,0 +1,13 @@ +CREATE FUNCTION pgroonga.escape(target text) + RETURNS text + AS 'MODULE_PATHNAME', 'pgroonga_escape' + LANGUAGE C + IMMUTABLE + STRICT; + +CREATE FUNCTION pgroonga.escape(target text, special_characters text) + RETURNS text + AS 'MODULE_PATHNAME', 'pgroonga_escape' + LANGUAGE C + IMMUTABLE + STRICT; Modified: pgroonga.sql (+14 -0) =================================================================== --- pgroonga.sql 2016-11-29 10:53:07 +0900 (27729bb) +++ pgroonga.sql 2016-11-29 11:01:10 +0900 (9c356b1) @@ -65,6 +65,20 @@ CREATE FUNCTION pgroonga.flush(indexName cstring) VOLATILE STRICT; +CREATE FUNCTION pgroonga.escape(target text) + RETURNS text + AS 'MODULE_PATHNAME', 'pgroonga_escape' + LANGUAGE C + IMMUTABLE + STRICT; + +CREATE FUNCTION pgroonga.escape(target text, special_characters text) + RETURNS text + AS 'MODULE_PATHNAME', 'pgroonga_escape' + LANGUAGE C + IMMUTABLE + STRICT; + CREATE FUNCTION pgroonga.match_term(target text, term text) RETURNS bool AS 'MODULE_PATHNAME', 'pgroonga_match_term_text' Modified: sources.am (+1 -0) =================================================================== --- sources.am 2016-11-29 10:53:07 +0900 (3602d50) +++ sources.am 2016-11-29 11:01:10 +0900 (a7d944f) @@ -4,6 +4,7 @@ SRCS = \ src/pgrn_convert.c \ src/pgrn_create.c \ src/pgrn_ctid.c \ + src/pgrn_escape.c \ src/pgrn_flush.c \ src/pgrn_global.c \ src/pgrn_groonga.c \ Added: sql/function/escape/with-special-characters.sql (+1 -0) 100644 =================================================================== --- /dev/null +++ sql/function/escape/with-special-characters.sql 2016-11-29 11:01:10 +0900 (0ce081f) @@ -0,0 +1 @@ +SELECT pgroonga.escape('a+O-R< >あいう~*()"'':', '()OR:'); Added: sql/function/escape/without-special-characters.sql (+1 -0) 100644 =================================================================== --- /dev/null +++ sql/function/escape/without-special-characters.sql 2016-11-29 11:01:10 +0900 (f256ddf) @@ -0,0 +1 @@ +SELECT pgroonga.escape('a+B-c< >あいう~*()"'':'); Added: src/pgrn_escape.c (+61 -0) 100644 =================================================================== --- /dev/null +++ src/pgrn_escape.c 2016-11-29 11:01:10 +0900 (88e875e) @@ -0,0 +1,61 @@ +#include "pgroonga.h" + +#include "pgrn_global.h" +#include "pgrn_groonga.h" + +#include <utils/builtins.h> + +static grn_ctx *ctx = &PGrnContext; +static struct PGrnBuffers *buffers = &PGrnBuffers; + +PG_FUNCTION_INFO_V1(pgroonga_escape); + +/** + * pgroonga.escape(target text, special_characters text = '+-<>~*()":') : text + */ +Datum +pgroonga_escape(PG_FUNCTION_ARGS) +{ + grn_rc rc = GRN_SUCCESS; + text *target = PG_GETARG_TEXT_PP(0); + text *escapedTarget; + grn_obj *escapedTargetBuffer; + + escapedTargetBuffer = &(buffers->escape.escapedTarget); + GRN_BULK_REWIND(escapedTargetBuffer); + if (PG_NARGS() == 1) + { + rc = grn_expr_syntax_escape_query(ctx, + VARDATA_ANY(target), + VARSIZE_ANY_EXHDR(target), + escapedTargetBuffer); + } + else + { + text *specialCharacters = PG_GETARG_TEXT_PP(1); + grn_obj *specialCharactersBuffer; + + specialCharactersBuffer = &(buffers->escape.specialCharacters); + GRN_TEXT_SET(ctx, + specialCharactersBuffer, + VARDATA_ANY(specialCharacters), + VARSIZE_ANY_EXHDR(specialCharacters)); + GRN_TEXT_PUTC(ctx, specialCharactersBuffer, '\0'); + rc = grn_expr_syntax_escape(ctx, + VARDATA_ANY(target), + VARSIZE_ANY_EXHDR(target), + GRN_TEXT_VALUE(specialCharactersBuffer), + GRN_QUERY_ESCAPE, + escapedTargetBuffer); + } + + if (rc != GRN_SUCCESS) { + ereport(ERROR, + (errcode(PGrnRCToPgErrorCode(rc)), + errmsg("pgroonga: escape: failed to escape"))); + } + + escapedTarget = cstring_to_text_with_len(GRN_TEXT_VALUE(escapedTargetBuffer), + GRN_TEXT_LEN(escapedTargetBuffer)); + PG_RETURN_TEXT_P(escapedTarget); +} Modified: src/pgrn_global.c (+4 -0) =================================================================== --- src/pgrn_global.c 2016-11-29 10:53:07 +0900 (b83b7f8) +++ src/pgrn_global.c 2016-11-29 11:01:10 +0900 (2dec706) @@ -22,6 +22,8 @@ PGrnInitializeBuffers(void) GRN_VOID_INIT(&(PGrnBuffers.walValue)); GRN_UINT32_INIT(&(PGrnBuffers.maxRecordSize), 0); GRN_UINT64_INIT(&(PGrnBuffers.walAppliedPosition), 0); + GRN_TEXT_INIT(&(PGrnBuffers.escape.escapedTarget), 0); + GRN_TEXT_INIT(&(PGrnBuffers.escape.specialCharacters), 0); GRN_TEXT_INIT(&(PGrnBuffers.head), 0); GRN_TEXT_INIT(&(PGrnBuffers.body), 0); GRN_TEXT_INIT(&(PGrnBuffers.foot), 0); @@ -43,6 +45,8 @@ PGrnFinalizeBuffers(void) GRN_OBJ_FIN(ctx, &(PGrnBuffers.walValue)); GRN_OBJ_FIN(ctx, &(PGrnBuffers.maxRecordSize)); GRN_OBJ_FIN(ctx, &(PGrnBuffers.walAppliedPosition)); + GRN_OBJ_FIN(ctx, &(PGrnBuffers.escape.escapedTarget)); + GRN_OBJ_FIN(ctx, &(PGrnBuffers.escape.specialCharacters)); GRN_OBJ_FIN(ctx, &(PGrnBuffers.head)); GRN_OBJ_FIN(ctx, &(PGrnBuffers.body)); GRN_OBJ_FIN(ctx, &(PGrnBuffers.foot)); Modified: src/pgrn_global.h (+5 -0) =================================================================== --- src/pgrn_global.h 2016-11-29 10:53:07 +0900 (96078cd) +++ src/pgrn_global.h 2016-11-29 11:01:10 +0900 (dcc22b3) @@ -16,6 +16,11 @@ struct PGrnBuffers grn_obj walValue; grn_obj maxRecordSize; grn_obj walAppliedPosition; + struct + { + grn_obj escapedTarget; + grn_obj specialCharacters; + } escape; grn_obj head; grn_obj body; grn_obj foot; Modified: src/pgroonga.h (+1 -0) =================================================================== --- src/pgroonga.h 2016-11-29 10:53:07 +0900 (7335e7a) +++ src/pgroonga.h 2016-11-29 11:01:10 +0900 (16808d3) @@ -67,6 +67,7 @@ extern Datum PGDLLEXPORT pgroonga_match_positions_byte(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_match_positions_character(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_query_extract_keywords(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_flush(PG_FUNCTION_ARGS); +extern Datum PGDLLEXPORT pgroonga_escape(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_match_term_text(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_match_term_text_array(PG_FUNCTION_ARGS); -------------- next part -------------- HTML����������������������������...Download