Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
76f7e8b
dbeaver/pro#5630 Add cache for queries
HocKu7 Jul 14, 2025
db21031
dbeaver/pro#5830 cache
HocKu7 Jul 14, 2025
298a4e3
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 15, 2025
6dee34b
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 15, 2025
2e273e0
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 15, 2025
4068c55
feat: use cache for data queries
Wroud Jul 15, 2025
8c7c3a5
fix: don't cache refresh requests
Wroud Jul 15, 2025
3dddd20
fix: grouping
Wroud Jul 15, 2025
9ba77d4
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 15, 2025
964cd76
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
Wroud Jul 15, 2025
18bc462
Merge remote-tracking branch 'origin/dbeaver/pro#5630-add-cache-for-q…
HocKu7 Jul 15, 2025
14de429
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 15, 2025
6367256
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
HocKu7 Jul 16, 2025
550373f
fix: check added constraints
Wroud Jul 16, 2025
d90a765
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 16, 2025
aa489cc
Merge remote-tracking branch 'origin/dbeaver/pro#5630-add-cache-for-q…
HocKu7 Jul 16, 2025
65a9947
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 16, 2025
93972f8
dbeaver/pro#5630 cache sql queries
HocKu7 Jul 16, 2025
52e2ee4
dbeaver/pro#5630 add soft reference
HocKu7 Jul 21, 2025
3c34ce5
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
dariamarutkina Jul 23, 2025
f0004d1
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
dariamarutkina Jul 25, 2025
a1d3edc
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
dariamarutkina Jul 25, 2025
c200d57
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
mr-anton-t Jul 28, 2025
d03b00e
dbeaver/pro#6401 fix: async task update after finish
Wroud Jul 28, 2025
97cee01
dbeaver/pro#5630 fix npe
HocKu7 Jul 28, 2025
08f4e46
dbeaver/pro#5630 fix npe
HocKu7 Jul 28, 2025
c7b2980
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
mr-anton-t Jul 28, 2025
9a9445c
Merge branch 'devel' into dbeaver/pro#6401/fix/async-task-update-afte…
EvgeniaBzzz Jul 29, 2025
74bea16
Merge branch 'dbeaver/pro#6401/fix/async-task-update-after-finish' in…
Wroud Jul 29, 2025
945802c
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
EvgeniaBzzz Jul 29, 2025
6156675
fix: do not use cache if result dataFormat changed
Wroud Jul 29, 2025
885e2c1
Merge branch 'devel' into dbeaver/pro#5630-add-cache-for-queries
EvgeniaBzzz Jul 29, 2025
90ae597
dbeaver/pro#5630 fix images
HocKu7 Jul 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ extend type Mutation {
resultId: ID,
filter: SQLDataFilter,
dataFormat: ResultDataFormat, # requested data format. May be ignored by server
readLogs: Boolean # added 23.2.1
readLogs: Boolean, # added 23.2.1
useCache: Boolean @since(version: "25.1.3")
): AsyncTaskInfo!

"Creates async task for reading data from the container node"
Expand All @@ -372,7 +373,8 @@ extend type Mutation {
containerNodePath: ID!,
resultId: ID,
filter: SQLDataFilter,
dataFormat: ResultDataFormat
dataFormat: ResultDataFormat,
useCache: Boolean @since(version: "25.1.3")
): AsyncTaskInfo!

"Returns transaction log info for the specified project, connection and context"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,19 @@ WebAsyncTaskInfo asyncExecuteQuery(
@Nullable WebSQLDataFilter filter,
@Nullable WebDataFormat dataFormat,
boolean readLogs,
@NotNull WebSession webSession) throws DBException;
@NotNull WebSession webSession,
@Nullable Boolean useCache
) throws DBException;

@WebAction
WebAsyncTaskInfo asyncReadDataFromContainer(
@NotNull WebSQLContextInfo contextInfo,
@NotNull String nodePath,
@Nullable String resultId,
@Nullable WebSQLDataFilter filter,
@Nullable WebDataFormat dataFormat) throws DBWebException;
@Nullable WebDataFormat dataFormat,
@Nullable Boolean useCache
) throws DBWebException;

/**
* Reads dynamic trace from provided database results.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.model.session.WebSessionProvider;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
Expand All @@ -49,6 +50,7 @@
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;

import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.time.Instant;
import java.time.ZoneId;
Expand All @@ -65,11 +67,13 @@
public class WebSQLContextInfo implements WebSessionProvider {

private static final Log log = Log.getLog(WebSQLContextInfo.class);
private static final int MAX_RESULT_SET_SIZE = 300;

private final transient WebSQLProcessor processor;
private final String id;
private final String projectId;
private final Map<String, WebSQLResultsInfo> resultInfoMap = new HashMap<>();
private final Map<String, SoftReference<WebSQLQueryResults>> queryResultsMap = new HashMap<>();

private final AtomicInteger resultId = new AtomicInteger();

Expand Down Expand Up @@ -190,7 +194,26 @@ public WebSQLResultsInfo getResults(@NotNull String resultId) throws DBWebExcept
return resultsInfo;
}

@Nullable
public WebSQLQueryResults getQueryResults(@NotNull String resultId) throws DBWebException {
SoftReference<WebSQLQueryResults> reference = queryResultsMap.get(resultId);
return reference == null ? null : reference.get();
}

public void trySaveQueryResults(@NotNull WebSQLQueryResults[] resultsArray, int requestedLimit) {

if (resultsArray[0].getResultSet() == null) {
return;
}
boolean isSingleResult = resultsArray.length == 1;
int actualRowCount = isSingleResult ? resultsArray[0].getResultSet().getRows().length : 0;
if (isSingleResult && actualRowCount < Math.min(requestedLimit, MAX_RESULT_SET_SIZE)) {
queryResultsMap.put(resultsArray[0].getResultSet().getId(), new SoftReference<>(resultsArray[0]));
}
}

public boolean closeResult(@NotNull String resultId) {
queryResultsMap.remove(resultId);
return resultInfoMap.remove(resultId) != null;
}

Expand All @@ -199,6 +222,7 @@ public boolean closeResult(@NotNull String resultId) {

void dispose() {
resultInfoMap.clear();
queryResultsMap.clear();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@

private static final String FILE_ID = "fileId";
private static final String TEMP_FILE_FOLDER = "temp-sql-upload-files";

private final WebSession webSession;
private final WebConnectionInfo connection;
private final SQLSyntaxManager syntaxManager;
Expand Down Expand Up @@ -166,20 +165,25 @@
@Nullable WebSQLDataFilter filter,
@Nullable WebDataFormat dataFormat,
@NotNull WebSession webSession,
boolean readLogs) throws DBWebException, DBCException {
boolean readLogs,
@Nullable Boolean useCache
) throws DBWebException, DBCException {
if (filter == null) {
// Use default filter
filter = new WebSQLDataFilter();
}
long startTime = System.currentTimeMillis();
WebSQLExecuteInfo executeInfo = new WebSQLExecuteInfo();

var dataContainer = new WebSQLQueryDataContainer(connection.getDataSource(), syntaxManager, sql);

DBCExecutionContext context = getExecutionContext(dataContainer);

try {
final DBDDataFilter dataFilter = filter.makeDataFilter((resultId == null ? null : contextInfo.getResults(resultId)));

if (trySetCachedResults(useCache, resultId, contextInfo, filter, executeInfo)) {
return executeInfo;
}

if (dataFilter.hasFilters()) {
sql = context.getDataSource().getSQLDialect().addFiltersToQuery(
monitor,
Expand Down Expand Up @@ -281,6 +285,7 @@
if (executeInfo.getResults().length == 0) {
executeInfo.setStatusMessage("No Data");
} else {
contextInfo.trySaveQueryResults(executeInfo.getResults(), filter.getLimit());
executeInfo.setStatusMessage("Executed");
}

Expand All @@ -294,15 +299,22 @@
@NotNull DBSDataContainer dataContainer,
@Nullable String resultId,
@NotNull WebSQLDataFilter filter,
@Nullable WebDataFormat dataFormat) throws DBException {
@Nullable WebDataFormat dataFormat,
@Nullable Boolean useCache
) throws DBException {

WebSQLExecuteInfo executeInfo = new WebSQLExecuteInfo();

DBCExecutionContext executionContext = getExecutionContext(dataContainer);
DBDDataFilter dataFilter = filter.makeDataFilter((resultId == null ? null : contextInfo.getResults(resultId)));
DBExecUtils.tryExecuteRecover(monitor, connection.getDataSource(), param -> {

if (trySetCachedResults(useCache, resultId, contextInfo, filter, executeInfo)) {
return;
}

try (DBCSession session = executionContext.openSession(monitor, resolveQueryPurpose(dataFilter), "Read data from container")) {
try (WebSQLQueryDataReceiver dataReceiver = new WebSQLQueryDataReceiver(contextInfo, dataContainer, dataFormat)) {
try (WebSQLQueryDataReceiver dataReceiver = new WebSQLQueryDataReceiver(contextInfo, dataContainer, dataFormat, webSession)) {

Check warning on line 317 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java

View workflow job for this annotation

GitHub Actions / Server / Lint

[checkstyle] reported by reviewdog 🐶 Line is longer than 140 characters (found 142). Raw Output: /github/workspace/./server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java:317:0: warning: Line is longer than 140 characters (found 142). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
DBCStatistics statistics = dataContainer.readData(
new WebExecutionSource(dataContainer, executionContext, this),
session,
Expand All @@ -324,6 +336,7 @@
if (resultSet != null && resultSet.getRows() != null && resultSet.getResultsInfo() != null) {
resultSet.getResultsInfo().setQueryText(statistics.getQueryText());
executeInfo.setStatusMessage(resultSet.getRows().length + " row(s) fetched");
contextInfo.trySaveQueryResults(executeInfo.getResults(), filter.getLimit());
}
} catch (DBException e) {
throw new InvocationTargetException(e);
Expand Down Expand Up @@ -432,7 +445,7 @@
sendTransactionalEvent(contextInfo);
}

WebSQLQueryResultSet updatedResultSet = new WebSQLQueryResultSet();
WebSQLQueryResultSet updatedResultSet = new WebSQLQueryResultSet(webSession);
updatedResultSet.setResultsInfo(resultsInfo);
updatedResultSet.setColumns(resultsInfo.getAttributes());

Expand All @@ -448,6 +461,34 @@
return result;
}

/**
* Checks cache and sets executeInfo if cached results are found.
* @return true if cached results were used, false otherwise

Check warning on line 466 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java

View workflow job for this annotation

GitHub Actions / Server / Lint

[checkstyle] reported by reviewdog 🐶 Javadoc tag '@return' should be preceded with an empty line. Raw Output: /github/workspace/./server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java:466:0: warning: Javadoc tag '@return' should be preceded with an empty line. (com.puppycrawl.tools.checkstyle.checks.javadoc.RequireEmptyLineBeforeBlockTagGroupCheck)
*/
private boolean trySetCachedResults(
@Nullable Boolean useCache,
@Nullable String resultId,
@NotNull WebSQLContextInfo contextInfo,
@NotNull WebSQLDataFilter filter,
@NotNull WebSQLExecuteInfo executeInfo
) {
if (CommonUtils.toBoolean(useCache)) {
WebSQLResultCacheService webSQLResultCacheService = new WebSQLResultCacheService();
WebSQLQueryResults filterCachedResults = webSQLResultCacheService.getCachedSQLQueryResults(
resultId,
contextInfo,
filter
);
if (filterCachedResults != null) {
executeInfo.setResults(new WebSQLQueryResults[] {filterCachedResults});
executeInfo.setDuration(0);
executeInfo.setStatusMessage("Cached result set");
return true;
}
}
return false;
}

private void sendTransactionalEvent(WebSQLContextInfo contextInfo) {
int count = QMUtils.getTransactionState(getExecutionContext()).getUpdateCount();
webSession.addSessionEvent(
Expand Down Expand Up @@ -509,7 +550,7 @@
}
DBDDataFilter filter = new DBDDataFilter(constraints);
DBSDataContainer dataContainer = resultsInfo.getDataContainer();
WebRowDataReceiver dataReceiver = new WebRowDataReceiver(resultsInfo.getAttributes(), row.getData(), dataFormat);
RowDataReceiver dataReceiver = new RowDataReceiver(resultsInfo.getAttributes());
dataContainer.readData(
new AbstractExecutionSource(dataContainer, getExecutionContext(dataContainer), this),
session,
Expand Down Expand Up @@ -606,7 +647,7 @@
DBDAttributeBinding[] allAttributes = resultsInfo.getAttributes();
DBDAttributeBinding[] keyAttributes = rowIdentifier.getAttributes().toArray(new DBDAttributeBinding[0]);

WebSQLQueryResultSet updatedResultSet = new WebSQLQueryResultSet();
WebSQLQueryResultSet updatedResultSet = new WebSQLQueryResultSet(webSession);
updatedResultSet.setResultsInfo(resultsInfo);
updatedResultSet.setColumns(resultsInfo.getAttributes());

Expand Down Expand Up @@ -813,7 +854,7 @@
}

@Nullable
public Object convertInputCellValue(DBCSession session, DBDAttributeBinding updateAttribute, Object cellRawValue, boolean justGenerateScript) throws DBCException {
public Object convertInputCellValue(DBCSession session, DBDAttributeBinding updateAttribute, Object cellRawValue, boolean justGenerateScript) throws DBException {

Check warning on line 857 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java

View workflow job for this annotation

GitHub Actions / Server / Lint

[checkstyle] reported by reviewdog 🐶 Line is longer than 140 characters (found 166). Raw Output: /github/workspace/./server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java:857:0: warning: Line is longer than 140 characters (found 166). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
cellRawValue = WebSQLUtils.makePlainCellValue(session, updateAttribute, cellRawValue);
Object realCellValue = cellRawValue;
// In some cases we already have final value here
Expand Down Expand Up @@ -1028,7 +1069,8 @@
@NotNull WebSQLExecuteInfo executeInfo,
@NotNull WebSQLDataFilter webDataFilter,
@NotNull DBDDataFilter dataFilter,
@Nullable WebDataFormat dataFormat) throws DBException {
@Nullable WebDataFormat dataFormat
) throws DBException {

List<WebSQLQueryResults> resultList = new ArrayList<>();
int maxResultsCount = resolveMaxResultsCount(dataContainer.getDataSource());
Expand All @@ -1041,7 +1083,7 @@
if (resultSet == null) {
break;
}
try (WebSQLQueryDataReceiver dataReceiver = new WebSQLQueryDataReceiver(contextInfo, dataContainer, dataFormat)) {
try (WebSQLQueryDataReceiver dataReceiver = new WebSQLQueryDataReceiver(contextInfo, dataContainer, dataFormat, webSession)) {

Check warning on line 1086 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java

View workflow job for this annotation

GitHub Actions / Server / Lint

[checkstyle] reported by reviewdog 🐶 Line is longer than 140 characters (found 146). Raw Output: /github/workspace/./server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java:1086:0: warning: Line is longer than 140 characters (found 146). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
readResultSet(dbStat.getSession(), resultSet, webDataFilter, dataReceiver);
results.setResultSet(dataReceiver.getResultSet());
dataReceiver.getResultSet().getResultsInfo().setQueryText(resultSet.getSourceStatement().getQueryString());
Expand Down Expand Up @@ -1162,30 +1204,6 @@
}
}

public class WebRowDataReceiver extends RowDataReceiver {
private final WebDataFormat dataFormat;

public WebRowDataReceiver(DBDAttributeBinding[] curAttributes, Object[] rowValues, WebDataFormat dataFormat) {
super(curAttributes);
this.rowValues = rowValues;
this.dataFormat = dataFormat;
}

@Override
protected void fetchRowValues(DBCSession session, DBCResultSet resultSet) throws DBCException {
for (int i = 0; i < curAttributes.length; i++) {
final DBDAttributeBinding attr = curAttributes[i];
DBDValueHandler valueHandler = attr.getValueHandler();
Object attrValue = valueHandler.fetchValueObject(session, resultSet, attr, i);

// Patch result rows (adapt to web format)
rowValues[i] = WebSQLUtils.makeWebCellValue(webSession, attr, attrValue, dataFormat);
}
}

}


///////////////////////////////////////////////////////
// Utils
private static int resolveMaxResultsCount(@Nullable DBPDataSource dataSource) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,18 @@
private final WebSQLContextInfo contextInfo;
private final DBSDataContainer dataContainer;
private final WebDataFormat dataFormat;
private final WebSQLQueryResultSet webResultSet = new WebSQLQueryResultSet();
private final WebSQLQueryResultSet webResultSet;

private DBDAttributeBinding[] bindings;
private DBCTrace trace;
private List<WebSQLQueryResultSetRow> rows = new ArrayList<>();
private final Number rowLimit;

WebSQLQueryDataReceiver(WebSQLContextInfo contextInfo, DBSDataContainer dataContainer, WebDataFormat dataFormat) {
WebSQLQueryDataReceiver(WebSQLContextInfo contextInfo, DBSDataContainer dataContainer, WebDataFormat dataFormat, WebSession webSession) {

Check warning on line 54 in server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLQueryDataReceiver.java

View workflow job for this annotation

GitHub Actions / Server / Lint

[checkstyle] reported by reviewdog 🐶 Line is longer than 140 characters (found 141). Raw Output: /github/workspace/./server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLQueryDataReceiver.java:54:0: warning: Line is longer than 140 characters (found 141). (com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck)
this.contextInfo = contextInfo;
this.dataContainer = dataContainer;
this.dataFormat = dataFormat;
this.webResultSet = new WebSQLQueryResultSet(webSession);
rowLimit = ServletAppUtils.getServletApplication()
.getAppConfiguration()
.getResourceQuota(WebSQLConstants.QUOTA_PROP_ROW_LIMIT);
Expand Down Expand Up @@ -146,14 +147,6 @@
}
}

// Convert row values
for (WebSQLQueryResultSetRow row : rows) {
for (int i = 0; i < bindings.length; i++) {
DBDAttributeBinding binding = bindings[i];
row.getData()[i] = WebSQLUtils.makeWebCellValue(webSession, binding, row.getData()[i], dataFormat);
}
}

webResultSet.setColumns(bindings);
webResultSet.setRows(List.of(rows.toArray(new WebSQLQueryResultSetRow[0])));
webResultSet.setHasChildrenCollection(resultSet instanceof DBDSubCollectionResultSet);
Expand Down
Loading
Loading