diff --git a/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java b/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java index b65dab4..184372d 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/YdbConnection.java @@ -8,8 +8,8 @@ import tech.ydb.jdbc.context.YdbContext; import tech.ydb.jdbc.context.YdbValidator; +import tech.ydb.jdbc.query.ExplainedQuery; import tech.ydb.jdbc.query.YdbQuery; -import tech.ydb.table.query.ExplainDataQueryResult; import tech.ydb.table.query.Params; import tech.ydb.table.result.ResultSetReader; @@ -76,7 +76,7 @@ List executeDataQuery(YdbQuery query, YdbValidator validator, * and {@link YdbConst#EXPLAIN_COLUMN_PLAN} * @throws SQLException if query cannot be explained */ - ExplainDataQueryResult executeExplainQuery(YdbQuery query, YdbValidator validator) throws SQLException; + ExplainedQuery executeExplainQuery(YdbQuery query, YdbValidator validator) throws SQLException; @Override YdbDatabaseMetaData getMetaData() throws SQLException; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/BaseYdbExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/BaseYdbExecutor.java index 678414d..72077a3 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/BaseYdbExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/BaseYdbExecutor.java @@ -12,13 +12,11 @@ import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.table.Session; import tech.ydb.table.TableClient; -import tech.ydb.table.query.ExplainDataQueryResult; import tech.ydb.table.query.Params; import tech.ydb.table.result.ResultSetReader; import tech.ydb.table.result.impl.ProtoValueReaders; import tech.ydb.table.settings.ExecuteScanQuerySettings; import tech.ydb.table.settings.ExecuteSchemeQuerySettings; -import tech.ydb.table.settings.ExplainDataQuerySettings; /** * @@ -54,19 +52,6 @@ public void executeSchemeQuery(YdbContext ctx, YdbValidator validator, YdbQuery } } - @Override - public ExplainDataQueryResult executeExplainQuery(YdbContext ctx, YdbValidator validator, YdbQuery query) - throws SQLException { - ensureOpened(); - - String yql = query.getYqlQuery(null); - ExplainDataQuerySettings settings = ctx.withDefaultTimeout(new ExplainDataQuerySettings()); - try (Session session = createNewTableSession(validator)) { - String msg = QueryType.EXPLAIN_QUERY + " >>\n" + yql; - return validator.call(msg, () -> session.explainDataQuery(yql, settings)); - } - } - @Override public ResultSetReader executeScanQuery(YdbContext ctx, YdbValidator validator, YdbQuery query, Params params) throws SQLException { diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/QueryServiceExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/QueryServiceExecutor.java index c2d6338..17404c8 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/QueryServiceExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/QueryServiceExecutor.java @@ -15,15 +15,18 @@ import tech.ydb.core.UnexpectedResultException; import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.exception.ExceptionFactory; +import tech.ydb.jdbc.query.ExplainedQuery; import tech.ydb.jdbc.query.QueryType; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.query.QueryClient; import tech.ydb.query.QuerySession; import tech.ydb.query.QueryStream; import tech.ydb.query.QueryTransaction; +import tech.ydb.query.result.QueryInfo; import tech.ydb.query.result.QueryResultPart; import tech.ydb.query.settings.CommitTransactionSettings; import tech.ydb.query.settings.ExecuteQuerySettings; +import tech.ydb.query.settings.QueryExecMode; import tech.ydb.query.settings.RollbackTransactionSettings; import tech.ydb.query.tools.QueryReader; import tech.ydb.table.query.Params; @@ -227,6 +230,8 @@ public List executeDataQuery( @Override public void executeSchemeQuery(YdbContext ctx, YdbValidator validator, YdbQuery query) throws SQLException { + ensureOpened(); + // Scheme query does not affect transactions or result sets ExecuteQuerySettings settings = ctx.withRequestTimeout(ExecuteQuerySettings.newBuilder()).build(); final String yql = query.getYqlQuery(null); @@ -239,6 +244,30 @@ public void executeSchemeQuery(YdbContext ctx, YdbValidator validator, YdbQuery } } + @Override + public ExplainedQuery executeExplainQuery(YdbContext ctx, YdbValidator validator, YdbQuery query) + throws SQLException { + ensureOpened(); + + // Scheme query does not affect transactions or result sets + ExecuteQuerySettings settings = ctx.withRequestTimeout(ExecuteQuerySettings.newBuilder()) + .withExecMode(QueryExecMode.EXPLAIN) + .build(); + final String yql = query.getYqlQuery(null); + + try (QuerySession session = createNewQuerySession(validator)) { + QueryInfo res = validator.call(QueryType.EXPLAIN_QUERY + " >>\n" + yql, () -> session + .createQuery(yql, TxMode.NONE, Params.empty(), settings) + .execute(new IssueHandler(validator)) + ); + + if (!res.hasStats()) { + throw new SQLException("No explain data"); + } + return new ExplainedQuery(res.getStats().getQueryAst(), res.getStats().getQueryPlan()); + } + } + private class IssueHandler implements QueryStream.PartsHandler { private final YdbValidator validator; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/TableServiceExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/TableServiceExecutor.java index 6638362..9dbdc44 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/TableServiceExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/TableServiceExecutor.java @@ -8,14 +8,17 @@ import java.util.List; import tech.ydb.jdbc.YdbConst; +import tech.ydb.jdbc.query.ExplainedQuery; import tech.ydb.jdbc.query.QueryType; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.table.Session; import tech.ydb.table.query.DataQueryResult; +import tech.ydb.table.query.ExplainDataQueryResult; import tech.ydb.table.query.Params; import tech.ydb.table.result.ResultSetReader; import tech.ydb.table.settings.CommitTxSettings; import tech.ydb.table.settings.ExecuteDataQuerySettings; +import tech.ydb.table.settings.ExplainDataQuerySettings; import tech.ydb.table.settings.KeepAliveSessionSettings; import tech.ydb.table.settings.RollbackTxSettings; import tech.ydb.table.transaction.TxControl; @@ -151,6 +154,20 @@ private ExecuteDataQuerySettings dataQuerySettings(long timeout, boolean keepInC return settings; } + @Override + public ExplainedQuery executeExplainQuery(YdbContext ctx, YdbValidator validator, YdbQuery query) + throws SQLException { + ensureOpened(); + + String yql = query.getYqlQuery(null); + ExplainDataQuerySettings settings = ctx.withDefaultTimeout(new ExplainDataQuerySettings()); + try (Session session = createNewTableSession(validator)) { + String msg = QueryType.EXPLAIN_QUERY + " >>\n" + yql; + ExplainDataQueryResult res = validator.call(msg, () -> session.explainDataQuery(yql, settings)); + return new ExplainedQuery(res.getQueryAst(), res.getQueryPlan()); + } + } + @Override public List executeDataQuery( YdbContext ctx, YdbValidator validator, YdbQuery query, long timeout, boolean keepInCache, Params params diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java index 44d6776..ad49e87 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java @@ -4,8 +4,8 @@ import java.util.List; import tech.ydb.jdbc.YdbConst; +import tech.ydb.jdbc.query.ExplainedQuery; import tech.ydb.jdbc.query.YdbQuery; -import tech.ydb.table.query.ExplainDataQueryResult; import tech.ydb.table.query.Params; import tech.ydb.table.result.ResultSetReader; @@ -41,7 +41,7 @@ List executeDataQuery(YdbContext ctx, YdbValidator validator, Y ResultSetReader executeScanQuery(YdbContext ctx, YdbValidator validator, YdbQuery query, Params params) throws SQLException; - ExplainDataQueryResult executeExplainQuery(YdbContext ctx, YdbValidator validator, YdbQuery query) + ExplainedQuery executeExplainQuery(YdbContext ctx, YdbValidator validator, YdbQuery query) throws SQLException; void commit(YdbContext ctx, YdbValidator validator) throws SQLException; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java index 53ad958..28f67ce 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java @@ -17,10 +17,10 @@ import tech.ydb.jdbc.YdbStatement; import tech.ydb.jdbc.common.FixedResultSetFactory; import tech.ydb.jdbc.context.YdbValidator; +import tech.ydb.jdbc.query.ExplainedQuery; import tech.ydb.jdbc.query.YdbExpression; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.jdbc.settings.YdbOperationProperties; -import tech.ydb.table.query.ExplainDataQueryResult; import tech.ydb.table.query.Params; import tech.ydb.table.result.ResultSetReader; @@ -177,12 +177,12 @@ protected List executeSchemeQuery(YdbQuery query) throws SQLException } protected List executeExplainQuery(YdbQuery query) throws SQLException { - ExplainDataQueryResult explainDataQuery = connection.executeExplainQuery(query, validator); + ExplainedQuery explainedQuery = connection.executeExplainQuery(query, validator); ResultSetReader result = EXPLAIN_RS_FACTORY.createResultSet() .newRow() - .withTextValue(YdbConst.EXPLAIN_COLUMN_AST, explainDataQuery.getQueryAst()) - .withTextValue(YdbConst.EXPLAIN_COLUMN_PLAN, explainDataQuery.getQueryPlan()) + .withTextValue(YdbConst.EXPLAIN_COLUMN_AST, explainedQuery.getAst()) + .withTextValue(YdbConst.EXPLAIN_COLUMN_PLAN, explainedQuery.getPlan()) .build() .build(); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java index 477146e..d66e34a 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java @@ -31,12 +31,12 @@ import tech.ydb.jdbc.context.YdbContext; import tech.ydb.jdbc.context.YdbExecutor; import tech.ydb.jdbc.context.YdbValidator; +import tech.ydb.jdbc.query.ExplainedQuery; import tech.ydb.jdbc.query.JdbcParams; import tech.ydb.jdbc.query.QueryType; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.jdbc.settings.FakeTxMode; import tech.ydb.jdbc.settings.YdbOperationProperties; -import tech.ydb.table.query.ExplainDataQueryResult; import tech.ydb.table.query.Params; import tech.ydb.table.result.ResultSetReader; @@ -232,7 +232,7 @@ public ResultSetReader executeScanQuery(YdbQuery query, YdbValidator validator, } @Override - public ExplainDataQueryResult executeExplainQuery(YdbQuery query, YdbValidator validator) throws SQLException { + public ExplainedQuery executeExplainQuery(YdbQuery query, YdbValidator validator) throws SQLException { return executor.executeExplainQuery(ctx, validator, query); } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/ExplainedQuery.java b/jdbc/src/main/java/tech/ydb/jdbc/query/ExplainedQuery.java new file mode 100644 index 0000000..3405ed5 --- /dev/null +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/ExplainedQuery.java @@ -0,0 +1,23 @@ +package tech.ydb.jdbc.query; + +/** + * + * @author Aleksandr Gorshenin + */ +public class ExplainedQuery { + private final String ast; + private final String plan; + + public ExplainedQuery(String ast, String plan) { + this.ast = ast; + this.plan = plan; + } + + public String getAst() { + return this.ast; + } + + public String getPlan() { + return this.plan; + } +}