@@ -13,6 +13,7 @@ use crate::dsl::{
1313use async_trait:: async_trait;
1414use chrono:: { DateTime , Utc } ;
1515use sqlx:: { Execute , PgPool , Postgres , QueryBuilder , Transaction , types:: Json } ;
16+ use sqlx:: postgres:: PgArguments ;
1617use std:: {
1718 collections:: { BTreeMap , HashMap , HashSet } ,
1819 io:: Read ,
@@ -1942,18 +1943,46 @@ ORDER BY idx
19421943 ) -> Result < Vec < String > , DbError > {
19431944 let escaped = escape_sql_like_literal ( term) ;
19441945 let pattern = format ! ( "%{}%" , escaped) ;
1945- let rows : Vec < String > = sqlx:: query_scalar (
1946+ let mut query = sqlx:: query_scalar (
19461947 "SELECT DISTINCT repository \
19471948 FROM files \
19481949 WHERE repository ILIKE $1 ESCAPE '\\ ' \
19491950 ORDER BY repository \
19501951 LIMIT $2",
19511952 )
19521953 . bind ( pattern)
1953- . bind ( limit)
1954- . fetch_all ( & self . pool )
1955- . await
1956- . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
1954+ . bind ( limit) ;
1955+
1956+ if std:: env:: var ( "POINTER_EXPLAIN_SEARCH_SQL" ) . is_ok ( ) {
1957+ let sql = format ! ( "EXPLAIN (ANALYZE, VERBOSE, BUFFERS) {}" , query. sql( ) ) ;
1958+ if let Ok ( Some ( args) ) = query. take_arguments ( ) {
1959+ let args: PgArguments = args;
1960+ let explain_args = args. clone ( ) ;
1961+ match sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( & sql, explain_args)
1962+ . fetch_all ( & self . pool )
1963+ . await
1964+ {
1965+ Ok ( rows) => {
1966+ for line in rows {
1967+ tracing:: info!( target: "pointer::autocomplete_sql" , "{}" , line) ;
1968+ }
1969+ }
1970+ Err ( err) => {
1971+ tracing:: warn!(
1972+ target: "pointer::autocomplete_sql" ,
1973+ "failed to run EXPLAIN: {}" ,
1974+ err
1975+ ) ;
1976+ }
1977+ }
1978+ query = sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( query. sql ( ) , args) ;
1979+ }
1980+ }
1981+
1982+ let rows: Vec < String > = query
1983+ . fetch_all ( & self . pool )
1984+ . await
1985+ . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
19571986
19581987 Ok ( rows)
19591988 }
@@ -1994,8 +2023,34 @@ ORDER BY idx
19942023 qb. push ( " ESCAPE '\\ ' ORDER BY dir LIMIT " ) ;
19952024 qb. push_bind ( limit) ;
19962025
1997- let rows: Vec < String > = qb
1998- . build_query_scalar ( )
2026+ let mut query = qb. build_query_scalar :: < String > ( ) ;
2027+ if std:: env:: var ( "POINTER_EXPLAIN_SEARCH_SQL" ) . is_ok ( ) {
2028+ let sql = format ! ( "EXPLAIN (ANALYZE, VERBOSE, BUFFERS) {}" , query. sql( ) ) ;
2029+ if let Ok ( Some ( args) ) = query. take_arguments ( ) {
2030+ let args: PgArguments = args;
2031+ let explain_args = args. clone ( ) ;
2032+ match sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( & sql, explain_args)
2033+ . fetch_all ( & self . pool )
2034+ . await
2035+ {
2036+ Ok ( rows) => {
2037+ for line in rows {
2038+ tracing:: info!( target: "pointer::autocomplete_sql" , "{}" , line) ;
2039+ }
2040+ }
2041+ Err ( err) => {
2042+ tracing:: warn!(
2043+ target: "pointer::autocomplete_sql" ,
2044+ "failed to run EXPLAIN: {}" ,
2045+ err
2046+ ) ;
2047+ }
2048+ }
2049+ query = sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( query. sql ( ) , args) ;
2050+ }
2051+ }
2052+
2053+ let rows: Vec < String > = query
19992054 . fetch_all ( & self . pool )
20002055 . await
20012056 . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
@@ -2027,8 +2082,34 @@ ORDER BY idx
20272082 qb. push ( " ESCAPE '\\ ' ORDER BY file_path LIMIT " ) ;
20282083 qb. push_bind ( limit) ;
20292084
2030- let rows: Vec < String > = qb
2031- . build_query_scalar ( )
2085+ let mut query = qb. build_query_scalar :: < String > ( ) ;
2086+ if std:: env:: var ( "POINTER_EXPLAIN_SEARCH_SQL" ) . is_ok ( ) {
2087+ let sql = format ! ( "EXPLAIN (ANALYZE, VERBOSE, BUFFERS) {}" , query. sql( ) ) ;
2088+ if let Ok ( Some ( args) ) = query. take_arguments ( ) {
2089+ let args: PgArguments = args;
2090+ let explain_args = args. clone ( ) ;
2091+ match sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( & sql, explain_args)
2092+ . fetch_all ( & self . pool )
2093+ . await
2094+ {
2095+ Ok ( rows) => {
2096+ for line in rows {
2097+ tracing:: info!( target: "pointer::autocomplete_sql" , "{}" , line) ;
2098+ }
2099+ }
2100+ Err ( err) => {
2101+ tracing:: warn!(
2102+ target: "pointer::autocomplete_sql" ,
2103+ "failed to run EXPLAIN: {}" ,
2104+ err
2105+ ) ;
2106+ }
2107+ }
2108+ query = sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( query. sql ( ) , args) ;
2109+ }
2110+ }
2111+
2112+ let rows: Vec < String > = query
20322113 . fetch_all ( & self . pool )
20332114 . await
20342115 . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
@@ -2061,8 +2142,37 @@ ORDER BY idx
20612142 qb. push ( " ESCAPE '\\ ' ORDER BY cb.language LIMIT " ) ;
20622143 qb. push_bind ( limit) ;
20632144
2064- let rows: Vec < Option < String > > = qb
2065- . build_query_scalar ( )
2145+ let mut query = qb. build_query_scalar :: < Option < String > > ( ) ;
2146+ if std:: env:: var ( "POINTER_EXPLAIN_SEARCH_SQL" ) . is_ok ( ) {
2147+ let sql = format ! ( "EXPLAIN (ANALYZE, VERBOSE, BUFFERS) {}" , query. sql( ) ) ;
2148+ if let Ok ( Some ( args) ) = query. take_arguments ( ) {
2149+ let args: PgArguments = args;
2150+ let explain_args = args. clone ( ) ;
2151+ match sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( & sql, explain_args)
2152+ . fetch_all ( & self . pool )
2153+ . await
2154+ {
2155+ Ok ( rows) => {
2156+ for line in rows {
2157+ tracing:: info!( target: "pointer::autocomplete_sql" , "{}" , line) ;
2158+ }
2159+ }
2160+ Err ( err) => {
2161+ tracing:: warn!(
2162+ target: "pointer::autocomplete_sql" ,
2163+ "failed to run EXPLAIN: {}" ,
2164+ err
2165+ ) ;
2166+ }
2167+ }
2168+ query = sqlx:: query_scalar_with :: < Postgres , Option < String > , PgArguments > (
2169+ query. sql ( ) ,
2170+ args,
2171+ ) ;
2172+ }
2173+ }
2174+
2175+ let rows: Vec < Option < String > > = query
20662176 . fetch_all ( & self . pool )
20672177 . await
20682178 . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
@@ -2094,8 +2204,34 @@ ORDER BY idx
20942204 qb. push ( " ESCAPE '\\ ' ORDER BY branch LIMIT " ) ;
20952205 qb. push_bind ( limit) ;
20962206
2097- let rows: Vec < String > = qb
2098- . build_query_scalar ( )
2207+ let mut query = qb. build_query_scalar :: < String > ( ) ;
2208+ if std:: env:: var ( "POINTER_EXPLAIN_SEARCH_SQL" ) . is_ok ( ) {
2209+ let sql = format ! ( "EXPLAIN (ANALYZE, VERBOSE, BUFFERS) {}" , query. sql( ) ) ;
2210+ if let Ok ( Some ( args) ) = query. take_arguments ( ) {
2211+ let args: PgArguments = args;
2212+ let explain_args = args. clone ( ) ;
2213+ match sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( & sql, explain_args)
2214+ . fetch_all ( & self . pool )
2215+ . await
2216+ {
2217+ Ok ( rows) => {
2218+ for line in rows {
2219+ tracing:: info!( target: "pointer::autocomplete_sql" , "{}" , line) ;
2220+ }
2221+ }
2222+ Err ( err) => {
2223+ tracing:: warn!(
2224+ target: "pointer::autocomplete_sql" ,
2225+ "failed to run EXPLAIN: {}" ,
2226+ err
2227+ ) ;
2228+ }
2229+ }
2230+ query = sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( query. sql ( ) , args) ;
2231+ }
2232+ }
2233+
2234+ let rows: Vec < String > = query
20992235 . fetch_all ( & self . pool )
21002236 . await
21012237 . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
@@ -2110,23 +2246,59 @@ ORDER BY idx
21102246 ) -> Result < Vec < SymbolSuggestion > , DbError > {
21112247 let escaped = escape_sql_like_literal ( term) ;
21122248 let pattern = format ! ( "%{}%" , escaped) ;
2113- let rows: Vec < ( String , String , String ) > = sqlx:: query_as (
2114- "SELECT
2115- s.name_lc,
2249+ let mut query = sqlx:: query_as (
2250+ "WITH matches AS (
2251+ SELECT us.name_lc
2252+ FROM unique_symbols us
2253+ WHERE us.name_lc ILIKE $1 ESCAPE '\\ '
2254+ LIMIT $2
2255+ )
2256+ SELECT
2257+ m.name_lc,
21162258 MIN(f.repository) AS repository,
21172259 MIN(f.file_path) AS file_path
2118- FROM symbols s
2260+ FROM matches m
2261+ JOIN symbols s ON s.name_lc = m.name_lc
21192262 JOIN files f ON f.content_hash = s.content_hash
2120- WHERE s.name_lc ILIKE $1 ESCAPE '\\ '
2121- GROUP BY s.name_lc
2122- ORDER BY s.name_lc
2123- LIMIT $2" ,
2263+ GROUP BY m.name_lc
2264+ ORDER BY m.name_lc" ,
21242265 )
21252266 . bind ( pattern)
2126- . bind ( limit)
2127- . fetch_all ( & self . pool )
2128- . await
2129- . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
2267+ . bind ( limit) ;
2268+
2269+ if std:: env:: var ( "POINTER_EXPLAIN_SEARCH_SQL" ) . is_ok ( ) {
2270+ let sql = format ! ( "EXPLAIN (ANALYZE, VERBOSE, BUFFERS) {}" , query. sql( ) ) ;
2271+ if let Ok ( Some ( args) ) = query. take_arguments ( ) {
2272+ let args: PgArguments = args;
2273+ let explain_args = args. clone ( ) ;
2274+ match sqlx:: query_scalar_with :: < Postgres , String , PgArguments > ( & sql, explain_args)
2275+ . fetch_all ( & self . pool )
2276+ . await
2277+ {
2278+ Ok ( rows) => {
2279+ for line in rows {
2280+ tracing:: info!( target: "pointer::autocomplete_sql" , "{}" , line) ;
2281+ }
2282+ }
2283+ Err ( err) => {
2284+ tracing:: warn!(
2285+ target: "pointer::autocomplete_sql" ,
2286+ "failed to run EXPLAIN: {}" ,
2287+ err
2288+ ) ;
2289+ }
2290+ }
2291+ query = sqlx:: query_as_with :: < Postgres , ( String , String , String ) , PgArguments > (
2292+ query. sql ( ) ,
2293+ args,
2294+ ) ;
2295+ }
2296+ }
2297+
2298+ let rows: Vec < ( String , String , String ) > = query
2299+ . fetch_all ( & self . pool )
2300+ . await
2301+ . map_err ( |e| DbError :: Database ( e. to_string ( ) ) ) ?;
21302302
21312303 Ok ( rows
21322304 . into_iter ( )
0 commit comments