From e1389b248cb3ee7a851c7da45fa6e86dbdb655bb Mon Sep 17 00:00:00 2001 From: serge-rider Date: Tue, 12 Feb 2019 22:45:06 +0300 Subject: [PATCH] #5233 SQL Server: error handle fix (for multi-results queries) Former-commit-id: 955eedb6ff858b6d2f9cacb863da97167ae40c06 --- .../mssql/model/SQLServerDataSourceInfo.java | 9 ++ .../ext/wmi/model/WMIDataSourceInfo.java | 17 +-- .../dbeaver/model/DBPDataSourceInfo.java | 5 + .../model/impl/BaseDataSourceInfo.java | 102 ++++++++++++++++++ .../model/impl/jdbc/JDBCDataSourceInfo.java | 5 + .../dbeaver/ui/editors/sql/SQLEditorBase.java | 5 + .../ui/editors/sql/execute/SQLQueryJob.java | 12 ++- 7 files changed, 136 insertions(+), 19 deletions(-) create mode 100644 plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/BaseDataSourceInfo.java diff --git a/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDataSourceInfo.java b/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDataSourceInfo.java index 12bd8464b4..f4a20e95bc 100644 --- a/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDataSourceInfo.java +++ b/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDataSourceInfo.java @@ -16,6 +16,7 @@ */ package org.jkiss.dbeaver.ext.mssql.model; +import org.jkiss.dbeaver.ext.mssql.SQLServerUtils; import org.jkiss.dbeaver.model.exec.jdbc.JDBCDatabaseMetaData; import org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSourceInfo; @@ -24,8 +25,11 @@ import org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSourceInfo; */ class SQLServerDataSourceInfo extends JDBCDataSourceInfo { + private boolean isSybase; + public SQLServerDataSourceInfo(SQLServerDataSource dataSource, JDBCDatabaseMetaData metaData) { super(metaData); + this.isSybase = !SQLServerUtils.isDriverSqlServer(dataSource.getContainer().getDriver()); } @Override @@ -38,4 +42,9 @@ class SQLServerDataSourceInfo extends JDBCDataSourceInfo { return true; } + @Override + public boolean isMultipleResultsFetchBroken() { + return isSybase; + } + } diff --git a/plugins/org.jkiss.dbeaver.ext.wmi/src/org/jkiss/dbeaver/ext/wmi/model/WMIDataSourceInfo.java b/plugins/org.jkiss.dbeaver.ext.wmi/src/org/jkiss/dbeaver/ext/wmi/model/WMIDataSourceInfo.java index bfe0f26e57..6fac0c37ba 100644 --- a/plugins/org.jkiss.dbeaver.ext.wmi/src/org/jkiss/dbeaver/ext/wmi/model/WMIDataSourceInfo.java +++ b/plugins/org.jkiss.dbeaver.ext.wmi/src/org/jkiss/dbeaver/ext/wmi/model/WMIDataSourceInfo.java @@ -18,6 +18,7 @@ package org.jkiss.dbeaver.ext.wmi.model; import org.jkiss.dbeaver.model.DBPDataSourceInfo; import org.jkiss.dbeaver.model.DBPTransactionIsolation; +import org.jkiss.dbeaver.model.impl.BaseDataSourceInfo; import org.osgi.framework.Version; import java.util.Collection; @@ -25,7 +26,7 @@ import java.util.Collection; /** * Info */ -public class WMIDataSourceInfo implements DBPDataSourceInfo { +public class WMIDataSourceInfo extends BaseDataSourceInfo { public WMIDataSourceInfo() { @@ -136,18 +137,4 @@ public class WMIDataSourceInfo implements DBPDataSourceInfo { return true; } - @Override - public boolean supportsResultSetScroll() { - return false; - } - - @Override - public boolean isDynamicMetadata() { - return false; - } - - @Override - public boolean supportsMultipleResults() { - return false; - } } diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPDataSourceInfo.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPDataSourceInfo.java index 49efe5f776..d82c481076 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPDataSourceInfo.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPDataSourceInfo.java @@ -152,4 +152,9 @@ public interface DBPDataSourceInfo * Checks whether this data source supports multiple results for a single statement */ boolean supportsMultipleResults(); + + /** + * Workaround for broken drivers (#2792) + */ + boolean isMultipleResultsFetchBroken(); } diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/BaseDataSourceInfo.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/BaseDataSourceInfo.java new file mode 100644 index 0000000000..db843b4b11 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/BaseDataSourceInfo.java @@ -0,0 +1,102 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jkiss.dbeaver.model.impl; + +import org.jkiss.dbeaver.model.DBPDataSourceInfo; +import org.jkiss.dbeaver.model.DBPTransactionIsolation; + +import java.util.Collection; + +/** + * BaseDataSourceInfo + */ +public abstract class BaseDataSourceInfo implements DBPDataSourceInfo +{ + @Override + public boolean supportsTransactions() { + return false; + } + + @Override + public boolean supportsSavepoints() { + return false; + } + + @Override + public boolean supportsReferentialIntegrity() { + return false; + } + + @Override + public boolean supportsIndexes() { + return false; + } + + @Override + public boolean supportsStoredCode() { + return false; + } + + @Override + public Collection getSupportedTransactionsIsolation() { + return null; + } + + @Override + public boolean supportsResultSetLimit() { + return false; + } + + @Override + public boolean supportsResultSetScroll() { + return false; + } + + @Override + public boolean isDynamicMetadata() { + return false; + } + + @Override + public boolean supportsMultipleResults() { + return false; + } + + @Override + public boolean isReadOnlyData() + { + return false; + } + + @Override + public boolean isReadOnlyMetaData() + { + return false; + } + + @Override + public boolean isMultipleResultsFetchBroken() { + return false; + } + + @Override + public boolean supportsBatchUpdates() + { + return false; + } + +} diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCDataSourceInfo.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCDataSourceInfo.java index 4f414dd56f..1454d87206 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCDataSourceInfo.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCDataSourceInfo.java @@ -320,6 +320,11 @@ public class JDBCDataSourceInfo implements DBPDataSourceInfo return false; } + @Override + public boolean isMultipleResultsFetchBroken() { + return false; + } + public void setSupportsResultSetScroll(boolean supportsScroll) { this.supportsScroll = supportsScroll; diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java index 95d5fd5042..30b4d481eb 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditorBase.java @@ -1330,6 +1330,11 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext } if (errorOffset < queryStartOffset) errorOffset = queryStartOffset; if (errorLength > queryLength) errorLength = queryLength; + if (errorOffset >= queryStartOffset + queryLength) { + // This may happen if error position was incorrectly detected. + // E.g. in SQL Server when actual error happened in some stored procedure. + errorOffset = queryStartOffset + queryLength - 1; + } getSelectionProvider().setSelection(new TextSelection(errorOffset, errorLength)); scrolled = true; } diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/execute/SQLQueryJob.java b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/execute/SQLQueryJob.java index 71559354d4..20cb3d7911 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/execute/SQLQueryJob.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/execute/SQLQueryJob.java @@ -504,10 +504,14 @@ public class SQLQueryJob extends DataSourceJob try { hasResultSet = dbcStatement.nextResults(); } catch (DBCException e) { - log.error(e); - // #2792: Check this twice. Some drivers (e.g. Sybase jConnect) - // throw error on n'th result fetch - but it still can keep fetching next results - hasResultSet = dbcStatement.nextResults(); + if (session.getDataSource().getInfo().isMultipleResultsFetchBroken()) { + log.error(e); + // #2792: Check this twice. Some drivers (e.g. Sybase jConnect) + // throw error on n'th result fetch - but it still can keep fetching next results + hasResultSet = dbcStatement.nextResults(); + } else { + throw e; + } } updateCount = hasResultSet ? -1 : 0; } else { -- GitLab