aboutsummaryrefslogtreecommitdiff
path: root/internal/postgres
diff options
context:
space:
mode:
authorJulie Qiu <julie@golang.org>2021-07-17 17:11:28 -0400
committerJulie Qiu <julie@golang.org>2021-07-20 13:22:05 +0000
commit88d596252dbac48b59ded3a5003f55fd1fc5df4d (patch)
treed3d2b730e340fc7d2889239162d1f0369c8801c4 /internal/postgres
parent685af85aeb4e043f458dfed28947e8ef2dbb285e (diff)
downloadgo-x-pkgsite-88d596252dbac48b59ded3a5003f55fd1fc5df4d.tar.xz
internal/postgres/{symbolsearch}: add QueryOneDot
QueryOneDot is added, which can search for anything with the structure <package>.<symbol> or <type>.<methodOrField>. For golang/go#44142 Change-Id: I2d1f0636849854cf3a95b784ed456c614d5f7b4f Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/335263 Trust: Julie Qiu <julie@golang.org> Run-TryBot: Julie Qiu <julie@golang.org> TryBot-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: Jonathan Amsterdam <jba@google.com>
Diffstat (limited to 'internal/postgres')
-rw-r--r--internal/postgres/symbolsearch.go2
-rw-r--r--internal/postgres/symbolsearch/gen_query.go8
-rw-r--r--internal/postgres/symbolsearch/query.gen.go52
-rw-r--r--internal/postgres/symbolsearch/symbolsearch.go5
-rw-r--r--internal/postgres/symbolsearch_test.go20
5 files changed, 80 insertions, 7 deletions
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 <package>.<symbol> or <type>.<methodOrFieldName>.
- // TODO: implement
+ query = symbolsearch.QueryOneDot
case 3:
// There is only 1 element, split by 2 dots, so the search must
// be for <package>.<type>.<methodOrFieldName>.
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 <package>.<symbol> or
+// <type>.<methodOrField>.
%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 <package>.<symbol> or
+// <type>.<methodOrField>.
+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 <package>.<symbol> or <type>.<methodOrField>.
+ 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,13 +66,23 @@ func TestSymbolSearch(t *testing.T) {
q: "foo.Type.Method",
want: checkResult(sample.Method),
},
+ {
+ name: "test search by <package>.<identifier>",
+ q: "foo.Variable",
+ want: checkResult(sample.Variable.SymbolMeta),
+ },
+ {
+ name: "test search by <type>.<field>",
+ q: "Type.Field",
+ want: checkResult(sample.Field),
+ },
+ {
+ name: "test search by <type>.<method>",
+ q: "Type.Method",
+ want: checkResult(sample.Method),
+ },
/*
{
- name: "test search by <package>.<identifier>",
- q: fmt.Sprintf("%s.%s", sample.PackageName, sample.Variable.Name),
- want: checkResult(sample.Variable.SymbolMeta),
- },
- {
name: "test search by <package> <identifier>",
q: sample.PackageName + " function",
want: checkResult(sample.Function.SymbolMeta),