3939import tech .ydb .table .description .TableColumn ;
4040import tech .ydb .table .description .TableDescription ;
4141import tech .ydb .table .impl .PooledTableClient ;
42+ import tech .ydb .table .query .ExplainDataQueryResult ;
4243import tech .ydb .table .rpc .grpc .GrpcTableRpc ;
4344import tech .ydb .table .settings .DescribeTableSettings ;
45+ import tech .ydb .table .settings .ExplainDataQuerySettings ;
4446import tech .ydb .table .settings .PrepareDataQuerySettings ;
4547import tech .ydb .table .settings .RequestSettings ;
4648import tech .ydb .table .values .Type ;
@@ -68,6 +70,7 @@ public class YdbContext implements AutoCloseable {
6870 private final SessionRetryContext retryCtx ;
6971
7072 private final Cache <String , YdbQuery > queriesCache ;
73+ private final Cache <String , QueryStat > queryStatesCache ;
7174 private final Cache <String , Map <String , Type >> queryParamsCache ;
7275
7376 private final boolean autoResizeSessionPool ;
@@ -98,8 +101,14 @@ private YdbContext(
98101 if (cacheSize > 0 ) {
99102 queriesCache = CacheBuilder .newBuilder ().maximumSize (cacheSize ).build ();
100103 queryParamsCache = CacheBuilder .newBuilder ().maximumSize (cacheSize ).build ();
104+ if (config .isFullScanDetectorEnabled ()) {
105+ queryStatesCache = CacheBuilder .newBuilder ().maximumSize (cacheSize ).build ();
106+ } else {
107+ queryStatesCache = null ;
108+ }
101109 } else {
102110 queriesCache = null ;
111+ queryStatesCache = null ;
103112 queryParamsCache = null ;
104113 }
105114 }
@@ -270,6 +279,27 @@ public YdbQuery findOrParseYdbQuery(String sql) throws SQLException {
270279 if (cached == null ) {
271280 cached = parseYdbQuery (sql );
272281 queriesCache .put (sql , cached );
282+
283+ if (queryStatesCache != null ) {
284+ QueryStat stat = queryStatesCache .getIfPresent (sql );
285+ if (stat == null ) {
286+ final String preparedYQL = cached .getPreparedYql ();
287+ final ExplainDataQuerySettings settings = withDefaultTimeout (new ExplainDataQuerySettings ());
288+ Result <ExplainDataQueryResult > res = retryCtx .supplyResult (
289+ session -> session .explainDataQuery (preparedYQL , settings )
290+ ).join ();
291+
292+ if (res .isSuccess ()) {
293+ ExplainDataQueryResult exp = res .getValue ();
294+ stat = new QueryStat (cached , exp .getQueryAst (), exp .getQueryPlan ());
295+ } else {
296+ stat = new QueryStat (cached , res .getStatus ());
297+ }
298+ queryStatesCache .put (sql , stat );
299+ }
300+
301+ stat .incrementUsage ();
302+ }
273303 }
274304
275305 return cached ;
@@ -288,8 +318,8 @@ public YdbPreparedQuery findOrPrepareParams(YdbQuery query, YdbPrepareMode mode)
288318 ).join ();
289319
290320 if (result .isSuccess ()) {
291- TableDescription d = result .getValue ();
292- types = result . getValue () .getColumns ().stream ()
321+ TableDescription descrtiption = result .getValue ();
322+ types = descrtiption .getColumns ().stream ()
293323 .collect (Collectors .toMap (TableColumn ::getName , TableColumn ::getType ));
294324 queryParamsCache .put (query .getOriginQuery (), types );
295325 }
0 commit comments