From 6f29c17d1f70eeaacfea10c56cad5c05c3d662f4 Mon Sep 17 00:00:00 2001 From: gmc Date: Fri, 29 Oct 2010 01:25:01 +0000 Subject: [PATCH] adjust quoting of phrase searches This has three main effects: * This formalizes the current behavior where a phrase search like title:"^Harry Potter" acts as a left-anchored search and title:"Harry Potter$" acts as a right-anchored search. In particular, this can be useful for constructing searches of bibliographic call numbers. * Other regex metacharacters in phrase searches are now escaped. * Phrase searches like "C++" will no longer crash; in fact, this makes a phrase search currently the only way to accurately retrieve all C++ titles with the usual normalization rules Signed-off-by: Galen Charlton git-svn-id: svn://svn.open-ils.org/ILS/trunk@18540 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../OpenILS/Application/Storage/Driver/Pg/QueryParser.pm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm index 94db0a4780..a27081e1d0 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm @@ -17,6 +17,20 @@ sub quote_value { return "\$_$$\$$value\$_$$\$"; } +sub quote_phrase_value { + my $self = shift; + my $value = shift; + + my $left_anchored = $value =~ m/^\^/; + my $right_anchored = $value =~ m/\$$/; + $value =~ s/\^// if $left_anchored; + $value =~ s/\$$// if $right_anchored; + $value =~ quotemeta($value); + $value = '^' . $value if $left_anchored; + $value = "$value\$" if $right_anchored; + return $self->quote_value($value); +} + sub init { my $class = shift; @@ -619,7 +633,7 @@ sub flatten { } $where .= '(' . $talias . ".id IS NOT NULL"; - $where .= ' AND ' . join(' AND ', map {"${talias}.value ~* ".$self->QueryParser->quote_value($_)} @{$node->phrases}) if (@{$node->phrases}); + $where .= ' AND ' . join(' AND ', map {"${talias}.value ~* ".$self->QueryParser->quote_phrase_value($_)} @{$node->phrases}) if (@{$node->phrases}); $where .= ')'; push @rank_list, $node_rank; -- 2.11.0