From 88d596252dbac48b59ded3a5003f55fd1fc5df4d Mon Sep 17 00:00:00 2001 From: Julie Qiu Date: Sat, 17 Jul 2021 17:11:28 -0400 Subject: internal/postgres/{symbolsearch}: add QueryOneDot QueryOneDot is added, which can search for anything with the structure . or .. For golang/go#44142 Change-Id: I2d1f0636849854cf3a95b784ed456c614d5f7b4f Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/335263 Trust: Julie Qiu Run-TryBot: Julie Qiu TryBot-Result: kokoro Reviewed-by: Jonathan Amsterdam --- internal/postgres/symbolsearch.go | 2 +- internal/postgres/symbolsearch/gen_query.go | 8 +++- internal/postgres/symbolsearch/query.gen.go | 52 ++++++++++++++++++++++++++ internal/postgres/symbolsearch/symbolsearch.go | 5 +++ internal/postgres/symbolsearch_test.go | 20 +++++++--- 5 files changed, 80 insertions(+), 7 deletions(-) (limited to 'internal/postgres') diff --git a/internal/postgres/symbolsearch.go b/internal/postgres/symbolsearch.go index 48b72afc..8ddf3270 100644 --- a/internal/postgres/symbolsearch.go +++ b/internal/postgres/symbolsearch.go @@ -125,7 +125,7 @@ func (db *DB) symbolSearch(ctx context.Context, q string, limit, offset, maxResu case 2: // There is only 1 element, split by 1 dot, so the search must // either be for . or .. - // TODO: implement + query = symbolsearch.QueryOneDot case 3: // There is only 1 element, split by 2 dots, so the search must // be for ... diff --git a/internal/postgres/symbolsearch/gen_query.go b/internal/postgres/symbolsearch/gen_query.go index 9c5b58aa..6a97153f 100644 --- a/internal/postgres/symbolsearch/gen_query.go +++ b/internal/postgres/symbolsearch/gen_query.go @@ -50,9 +50,15 @@ package symbolsearch // QueryPackageDotSymbol is used when the search query is one element // containing a dot, where the first part is assumed to be the package name and // the second the symbol name. For example, "sql.DB" or "sql.DB.Begin". +%s + +// QueryOneDot is used when the search query is one element +// containing a dot. This means it can either be . or +// .. %s`, formatQuery("QuerySymbol", symbolsearch.RawQuerySymbol), - formatQuery("QueryPackageDotSymbol", symbolsearch.RawQueryPackageDotSymbol)) + formatQuery("QueryPackageDotSymbol", symbolsearch.RawQueryPackageDotSymbol), + formatQuery("QueryOneDot", symbolsearch.RawQueryOneDot)) func formatQuery(name, query string) string { return fmt.Sprintf("const %s = `%s`", name, query) diff --git a/internal/postgres/symbolsearch/query.gen.go b/internal/postgres/symbolsearch/query.gen.go index 6cf98fb4..1c51d97c 100644 --- a/internal/postgres/symbolsearch/query.gen.go +++ b/internal/postgres/symbolsearch/query.gen.go @@ -109,3 +109,55 @@ ORDER BY package_path LIMIT $2 OFFSET $3;` + +// QueryOneDot is used when the search query is one element +// containing a dot. This means it can either be . or +// .. +const QueryOneDot = ` +WITH results AS ( + SELECT + s.name AS symbol_name, + sd.package_path, + sd.module_path, + sd.version, + sd.name AS package_name, + sd.synopsis, + sd.license_types, + sd.commit_time, + sd.imported_by_count, + ssd.package_symbol_id, + ssd.goos, + ssd.goarch, + (ln(exp(1)+imported_by_count) + * CASE WHEN sd.redistributable THEN 1 ELSE 0.500000 END + * CASE WHEN COALESCE(has_go_mod, true) THEN 1 ELSE 0.800000 END) AS score + FROM symbol_search_documents ssd + INNER JOIN search_documents sd ON sd.unit_id = ssd.unit_id + INNER JOIN symbol_names s ON s.id = ssd.symbol_name_id + WHERE (sd.name = split_part($1, '.', 1) AND s.tsv_name_tokens @@ to_tsquery('symbols', substring(replace($1, '_', '-') from E'[^.]*\.(.+)$'))) OR (s.tsv_name_tokens @@ to_tsquery('symbols', replace($1, '_', '-'))) +) +SELECT + r.package_path, + r.module_path, + r.version, + r.package_name, + r.synopsis, + r.license_types, + r.commit_time, + r.imported_by_count, + r.symbol_name, + r.goos, + r.goarch, + ps.type AS symbol_type, + ps.synopsis AS symbol_synopsis, + COUNT(*) OVER() AS total +FROM results r +INNER JOIN package_symbols ps ON r.package_symbol_id = ps.id +WHERE r.score > 0.1 +ORDER BY + score DESC, + commit_time DESC, + symbol_name, + package_path +LIMIT $2 +OFFSET $3;` diff --git a/internal/postgres/symbolsearch/symbolsearch.go b/internal/postgres/symbolsearch/symbolsearch.go index 0229a385..5e9df1b3 100644 --- a/internal/postgres/symbolsearch/symbolsearch.go +++ b/internal/postgres/symbolsearch/symbolsearch.go @@ -22,6 +22,7 @@ const SymbolTextSearchConfiguration = "symbols" var ( RawQuerySymbol = fmt.Sprintf(symbolSearchBaseQuery, scoreMultipliers, filterSymbol) RawQueryPackageDotSymbol = fmt.Sprintf(symbolSearchBaseQuery, scoreMultipliers, filterPackageDotSymbol) + RawQueryOneDot = fmt.Sprintf(symbolSearchBaseQuery, scoreMultipliers, filterOneDot) ) var ( @@ -38,6 +39,10 @@ var ( // Split the symbol name from $1, which can be assumed to be everything // following the first dot. toTSQuery("substring($1 from E'[^.]*\\.(.+)$')")) + + // filterOneDot is used when $1 is one word containing a single dot, which + // means it is either . or .. + filterOneDot = fmt.Sprintf("(%s) OR (%s)", filterPackageDotSymbol, filterSymbol) ) var ( diff --git a/internal/postgres/symbolsearch_test.go b/internal/postgres/symbolsearch_test.go index b82e37f6..be9bc90b 100644 --- a/internal/postgres/symbolsearch_test.go +++ b/internal/postgres/symbolsearch_test.go @@ -66,12 +66,22 @@ func TestSymbolSearch(t *testing.T) { q: "foo.Type.Method", want: checkResult(sample.Method), }, + { + name: "test search by .", + q: "foo.Variable", + want: checkResult(sample.Variable.SymbolMeta), + }, + { + name: "test search by .", + q: "Type.Field", + want: checkResult(sample.Field), + }, + { + name: "test search by .", + q: "Type.Method", + want: checkResult(sample.Method), + }, /* - { - name: "test search by .", - q: fmt.Sprintf("%s.%s", sample.PackageName, sample.Variable.Name), - want: checkResult(sample.Variable.SymbolMeta), - }, { name: "test search by ", q: sample.PackageName + " function", -- cgit v1.3-5-g9baa