diff --git a/bundles/org.jkiss.utils/src/org/jkiss/utils/CommonUtils.java b/bundles/org.jkiss.utils/src/org/jkiss/utils/CommonUtils.java index af0e1346dd4b82f582065f1d0fe87351bbad501f..b07ce7c2a01188979a836ea10139a38317a6ae11 100644 --- a/bundles/org.jkiss.utils/src/org/jkiss/utils/CommonUtils.java +++ b/bundles/org.jkiss.utils/src/org/jkiss/utils/CommonUtils.java @@ -476,6 +476,16 @@ public class CommonUtils { } } + public static boolean isNaN(@Nullable Object value) { + return (value instanceof Float && ((Float) value).isNaN()) + || (value instanceof Double && ((Double) value).isNaN()); + } + + public static boolean isInfinite(@Nullable Object value) { + return (value instanceof Float && ((Float) value).isInfinite()) + || (value instanceof Double && ((Double) value).isInfinite()); + } + @NotNull public static String toHexString(@Nullable byte[] bytes) { return bytes == null ? "" : toHexString(bytes, 0, bytes.length); diff --git a/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2Constants.java b/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2Constants.java index c2ac6574de73ae768d72f8f92bc2f8fbe019b6b5..ec1173e6ef4e5d6f9d86b6c049e63d99bbbd66f4 100644 --- a/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2Constants.java +++ b/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2Constants.java @@ -122,7 +122,8 @@ public class DB2Constants { "RESULT", "RESULT_SET_LOCATOR", "RETURN", "RETURNS", "ROUTINE", "ROW", "RRN", "RUN", "SAVEPOINT", "SCRATCHPAD", "SECOND", "SECONDS", "SECQTY", "SECURITY", "SENSITIVE", "SIGNAL", "SIMPLE", "SOURCE", "SPECIFIC", "SQLID", "STANDARD", "START", "STARTING", "STATIC", "STAY", "STOGROUP", "STORES", "STYLE", "SUBPAGES", "SYNONYM", "SYSTEM", "TABLESPACE", - "TRIGGER", "TYPE", "UNDO", "UNTIL", "VALIDPROC", "VARIABLE", "VARIANT", "VCAT", "VOLATILE", "VOLUMES", "WHILE", "WLM" }; + "TRIGGER", "TYPE", "UNDO", "UNTIL", "VALIDPROC", "VARIABLE", "VARIANT", "VCAT", "VOLATILE", "VOLUMES", "WHILE", "WLM", + "IMPLICITLY", "HIDDEN" }; public static final DBDPseudoAttribute PSEUDO_ATTR_RID_BIT = new DBDPseudoAttribute(DBDPseudoAttributeType.ROWID, "RID_BIT()", "RID_BIT($alias)", "RID_BIT", "Unique physical row identifier", false); diff --git a/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2SQLDialect.java b/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2SQLDialect.java index feaafe62b647af6b7546d251c525bf27fb8f6a16..9043dc2736f978cc50ea9b462e4e265db6943933 100644 --- a/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2SQLDialect.java +++ b/plugins/org.jkiss.dbeaver.ext.db2/src/org/jkiss/dbeaver/ext/db2/DB2SQLDialect.java @@ -22,6 +22,7 @@ import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.ext.db2.model.DB2Routine; +import org.jkiss.dbeaver.model.DBPDataSourceContainer; import org.jkiss.dbeaver.model.DBPEvaluationContext; import org.jkiss.dbeaver.model.data.DBDBinaryFormatter; import org.jkiss.dbeaver.model.exec.jdbc.JDBCDatabaseMetaData; @@ -31,12 +32,18 @@ import org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement; import org.jkiss.dbeaver.model.impl.data.formatters.BinaryFormatterHexString; import org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource; import org.jkiss.dbeaver.model.impl.jdbc.JDBCSQLDialect; +import org.jkiss.dbeaver.model.sql.parser.rules.SQLMultiWordRule; +import org.jkiss.dbeaver.model.sql.parser.tokens.SQLTokenType; import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure; import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureType; +import org.jkiss.dbeaver.model.text.parser.TPRule; +import org.jkiss.dbeaver.model.text.parser.TPRuleProvider; +import org.jkiss.dbeaver.model.text.parser.TPTokenDefault; import org.jkiss.utils.CommonUtils; import java.sql.SQLException; import java.util.Arrays; +import java.util.List; import java.util.Set; /** @@ -45,15 +52,12 @@ import java.util.Set; * @author Denis Forveille * */ -public class DB2SQLDialect extends JDBCSQLDialect { +public class DB2SQLDialect extends JDBCSQLDialect implements TPRuleProvider { private static final Log log = Log.getLog(DB2SQLDialect.class); public static final String[] EXEC_KEYWORDS = new String[]{"CALL"}; - private static final String[][] DB2_BEGIN_END_BLOCK = new String[][]{ - }; - private static final boolean LOAD_ROUTINES_FROM_SYSCAT = false; public DB2SQLDialect() { @@ -146,13 +150,17 @@ public class DB2SQLDialect extends JDBCSQLDialect { return BinaryFormatterHexString.INSTANCE; } - @Override - public String[][] getBlockBoundStrings() { - return DB2_BEGIN_END_BLOCK; - } - @Override public String getScriptDelimiterRedefiner() { return "DELIMITER"; } + + @Override + public void extendRules(@Nullable DBPDataSourceContainer dataSource, @NotNull List rules, @NotNull RulePosition position) { + if (position == RulePosition.KEYWORDS) { + final TPTokenDefault keywordToken = new TPTokenDefault(SQLTokenType.T_KEYWORD); + rules.add(new SQLMultiWordRule(new String[]{"ROW", "BEGIN"}, keywordToken)); + rules.add(new SQLMultiWordRule(new String[]{"ROW", "END"}, keywordToken)); + } + } } diff --git a/plugins/org.jkiss.dbeaver.ext.oracle/src/org/jkiss/dbeaver/ext/oracle/model/OracleSQLDialect.java b/plugins/org.jkiss.dbeaver.ext.oracle/src/org/jkiss/dbeaver/ext/oracle/model/OracleSQLDialect.java index 37fb7757800c25d60e31671bf32d9ff5635fd151..cf0a937118af5c5a44e9743bfead42e2935fe55f 100644 --- a/plugins/org.jkiss.dbeaver.ext.oracle/src/org/jkiss/dbeaver/ext/oracle/model/OracleSQLDialect.java +++ b/plugins/org.jkiss.dbeaver.ext.oracle/src/org/jkiss/dbeaver/ext/oracle/model/OracleSQLDialect.java @@ -33,6 +33,7 @@ import org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect; import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore; import org.jkiss.dbeaver.model.sql.SQLConstants; import org.jkiss.dbeaver.model.sql.SQLExpressionFormatter; +import org.jkiss.dbeaver.model.struct.DBSAttributeBase; import org.jkiss.dbeaver.model.struct.DBSTypedObject; import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure; import org.jkiss.utils.ArrayUtils; @@ -382,6 +383,17 @@ public class OracleSQLDialect extends JDBCSQLDialect { return MultiValueInsertMode.INSERT_ALL; } + @NotNull + @Override + public String escapeScriptValue(DBSAttributeBase attribute, @NotNull Object value, @NotNull String strValue) { + if (CommonUtils.isNaN(value) || CommonUtils.isInfinite(value)) { + // These special values should be quoted, as shown in the example below + // https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions090.htm + return '\'' + String.valueOf(value) + '\''; + } + return super.escapeScriptValue(attribute, value, strValue); + } + @Override public boolean supportsAliasInSelect() { return true; diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/edit/PostgreForeignKeyManager.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/edit/PostgreForeignKeyManager.java index 1864159d2804d3c69fae9ebadb5f40e918917d9f..5d63575bacacec2185a06b4cd5b645133b1af5ae 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/edit/PostgreForeignKeyManager.java +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/edit/PostgreForeignKeyManager.java @@ -28,7 +28,6 @@ import org.jkiss.dbeaver.model.DBUtils; import org.jkiss.dbeaver.model.edit.DBECommandContext; import org.jkiss.dbeaver.model.edit.DBEObjectRenamer; import org.jkiss.dbeaver.model.edit.DBEPersistAction; -import org.jkiss.dbeaver.model.exec.DBCException; import org.jkiss.dbeaver.model.exec.DBCExecutionContext; import org.jkiss.dbeaver.model.impl.edit.DBECommandAbstract; import org.jkiss.dbeaver.model.impl.edit.SQLDatabasePersistAction; @@ -80,7 +79,7 @@ public class PostgreForeignKeyManager extends SQLForeignKeyManager command, Map options) { PostgreTableForeignKey fk = command.getObject(); - if (fk.isPersisted()) { + /*if (fk.isPersisted()) { try { String constrDDL = fk.getObjectDefinitionText( monitor, @@ -91,9 +90,14 @@ public class PostgreForeignKeyManager extends SQLForeignKeyManager newSearchPath = new ArrayList<>(getDefaultSearchPath()); int schemaIndex = newSearchPath.indexOf(defSchemaName); - if (schemaIndex == 0 || (schemaIndex == 1 && isUserFirstInPath(newSearchPath))) { + /*if (schemaIndex == 0 || (schemaIndex == 1 && isUserFirstInPath(newSearchPath))) { // Already default schema return; - } else { + } else*/ + { if (schemaIndex > 0) { // Remove from previous position newSearchPath.remove(schemaIndex); diff --git a/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/edit/VerticaSequenceManager.java b/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/edit/VerticaSequenceManager.java index 12fdeb57b3c77a50a924a333e6912e0e06548d78..40ae7cec00ed1428258a0fa6ed24519fb8d2159c 100644 --- a/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/edit/VerticaSequenceManager.java +++ b/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/edit/VerticaSequenceManager.java @@ -1,18 +1,18 @@ /* * DBeaver - Universal Database Manager - * Copyright (C) 2010-2021 DBeaver Corp + * Copyright (C) 2010-2021 DBeaver Corp and others * - * All Rights Reserved. + * 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 * - * NOTICE: All information contained herein is, and remains - * the property of DBeaver Corp and its suppliers, if any. - * The intellectual and technical concepts contained - * herein are proprietary to DBeaver Corp and its suppliers - * and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material - * is strictly forbidden unless prior written permission is obtained - * from DBeaver Corp. + * 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.ext.vertica.edit; diff --git a/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSQLDialect.java b/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSQLDialect.java index 5dc8c71ce261ec68ddc6ef7eb208d374b011672b..09131da24ddbe0051255f7febe6d27b5b1d6b36f 100644 --- a/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSQLDialect.java +++ b/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSQLDialect.java @@ -33,6 +33,7 @@ public class VerticaSQLDialect extends GenericSQLDialect { private static String[] VERTICA_KEYWORDS = new String[]{ // SELECT * FROM keywords WHERE reserved = 'R' "BIT", + "CACHE", "COMMENT", "CORRELATION", "ENCODED", diff --git a/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSequence.java b/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSequence.java index eba0dd97cd0843b11f36fc66d7f549f270942c53..9d95dea7d362e25e176c7ecacdb85120dc885192 100644 --- a/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSequence.java +++ b/plugins/org.jkiss.dbeaver.ext.vertica/src/org/jkiss/dbeaver/ext/vertica/model/VerticaSequence.java @@ -1,18 +1,18 @@ /* * DBeaver - Universal Database Manager - * Copyright (C) 2010-2021 DBeaver Corp + * Copyright (C) 2010-2021 DBeaver Corp and others * - * All Rights Reserved. + * 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 * - * NOTICE: All information contained herein is, and remains - * the property of DBeaver Corp and its suppliers, if any. - * The intellectual and technical concepts contained - * herein are proprietary to DBeaver Corp and its suppliers - * and may be covered by U.S. and Foreign Patents, - * patents in process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material - * is strictly forbidden unless prior written permission is obtained - * from DBeaver Corp. + * 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.ext.vertica.model; @@ -20,15 +20,20 @@ import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.ext.generic.model.GenericScriptObject; import org.jkiss.dbeaver.ext.generic.model.GenericSequence; import org.jkiss.dbeaver.ext.generic.model.GenericStructContainer; import org.jkiss.dbeaver.ext.generic.model.GenericTableBase; +import org.jkiss.dbeaver.model.DBPEvaluationContext; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.meta.PropertyLength; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.model.sql.SQLUtils; import org.jkiss.utils.CommonUtils; -public class VerticaSequence extends GenericSequence { +import java.util.Map; + +public class VerticaSequence extends GenericSequence implements GenericScriptObject { private static final Log log = Log.getLog(VerticaSequence.class); @@ -38,6 +43,7 @@ public class VerticaSequence extends GenericSequence { private boolean isCycle; private VerticaSchema schema; private String description; + private String source; public VerticaSequence(GenericStructContainer container, String name, String description, Number lastValue, Number minValue, Number maxValue, Number incrementBy, String identityTableName, long cacheCount, boolean isCycle) { super(container, name, description, lastValue, minValue, maxValue, incrementBy); @@ -110,5 +116,30 @@ public class VerticaSequence extends GenericSequence { } - + @Override + public String getObjectDefinitionText(DBRProgressMonitor monitor, Map options) throws DBException { + if (source == null) { + StringBuilder ddl = new StringBuilder(); + ddl.append("CREATE SEQUENCE ") + .append(getFullyQualifiedName(DBPEvaluationContext.DML)) + .append("\n\tINCREMENT BY ").append(getIncrementBy()) + .append("\n\tMINVALUE ").append(getMinValue()) + .append("\n\tMAXVALUE ").append(getMaxValue()) + .append("\n\tSTART WITH ").append(getLastValue()); + + if (cacheCount <= 1) { + ddl.append("\n\tNO CACHE"); + } else { + ddl.append("\n\tCACHE ").append(cacheCount); + } + ddl.append("\n\t").append(isCycle ? "" : "NO ").append("CYCLE;"); + + if (!CommonUtils.isEmpty(description)) { + ddl.append("\n\nCOMMENT ON SEQUENCE ").append(getFullyQualifiedName(DBPEvaluationContext.DML)).append(" IS ") + .append(SQLUtils.quoteString(this, description)).append(";"); + } + source = ddl.toString(); + } + return source; + } } diff --git a/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/rules/SQLMultiWordRule.java b/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/rules/SQLMultiWordRule.java new file mode 100644 index 0000000000000000000000000000000000000000..00d753d17342a6c35b51032d33d866b56af414cb --- /dev/null +++ b/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/rules/SQLMultiWordRule.java @@ -0,0 +1,82 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2021 DBeaver Corp and others + * + * 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.sql.parser.rules; + +import org.eclipse.core.runtime.Assert; +import org.jkiss.dbeaver.model.text.parser.TPCharacterScanner; +import org.jkiss.dbeaver.model.text.parser.TPRule; +import org.jkiss.dbeaver.model.text.parser.TPToken; +import org.jkiss.dbeaver.model.text.parser.TPTokenAbstract; + +/** + * Rule for matching tokens consisting of several words separated by one or more whitespaces. + */ +public class SQLMultiWordRule implements TPRule { + private final String[] parts; + private final TPToken token; + + public SQLMultiWordRule(String[] parts, TPToken token) { + this.parts = parts; + this.token = token; + Assert.isLegal(parts.length > 1, "Multi-word rule should consist of two or more parts"); + } + + @Override + public TPToken evaluate(TPCharacterScanner scanner) { + int ch = scanner.read(); + int read = 1; + + outer: + for (int partIndex = 0; partIndex < parts.length; partIndex++) { + if (ch == TPCharacterScanner.EOF || !Character.isUnicodeIdentifierStart(ch)) { + break; + } + + for (char partCh : parts[partIndex].toCharArray()) { + if (ch == TPCharacterScanner.EOF || !Character.isUnicodeIdentifierPart(ch) || Character.toUpperCase(partCh) != Character.toUpperCase(ch)) { + break outer; + } + + ch = scanner.read(); + read++; + } + + if (partIndex == parts.length - 1 && !Character.isUnicodeIdentifierPart(ch)) { + // Accept rule if last part is preceded by non-identifier character + scanner.unread(); + return token; + } + + if (ch == TPCharacterScanner.EOF || !Character.isWhitespace(ch)) { + // Require at least one whitespace character between parts + break; + } + + while (ch != TPCharacterScanner.EOF && Character.isWhitespace(ch)) { + ch = scanner.read(); + read++; + } + } + + while (read > 0) { + scanner.unread(); + read--; + } + + return TPTokenAbstract.UNDEFINED; + } +} diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCSQLDialect.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCSQLDialect.java index 0716ab623cf925ba9d1e11be210270dbe5a386b4..9b7503f01568d9b7aed2fcb58859cb93118dd934 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCSQLDialect.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/jdbc/JDBCSQLDialect.java @@ -112,7 +112,7 @@ public class JDBCSQLDialect extends BasicSQLDialect { } try { - this.supportsUnquotedMixedCase = !metaData.supportsMixedCaseIdentifiers(); + this.supportsUnquotedMixedCase = metaData.supportsMixedCaseIdentifiers(); } catch (Throwable e) { log.debug("Error getting supportsUnquotedMixedCase:" + e.getMessage()); this.supportsUnquotedMixedCase = false; diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/BlockCanceler.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/BlockCanceler.java index 1ba07f36c091e13d46a77b813586899172c32915..4e22142f14cfba655184b722f5fc7f105f6f13d1 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/BlockCanceler.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/BlockCanceler.java @@ -35,6 +35,9 @@ public class BlockCanceler try { block.cancelBlock(monitor, blockActiveThread); } catch (Throwable e) { + if (e instanceof RuntimeException) { + throw e; + } throw new DBException("Cancel error", e); } finally { thread.setName(threadOldName); diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLUtils.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLUtils.java index 1b34c844c6761e148b583f4efdf1e9bc04a8478a..f20e0363371c3e40fedf37ef1e140481d195b3a5 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLUtils.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLUtils.java @@ -646,9 +646,6 @@ public final class SQLUtils { } else { strValue = valueHandler.getValueDisplayString(attribute, value, displayFormat); } - if (value instanceof Number) { - return strValue; - } SQLDialect sqlDialect = dataSource.getSQLDialect(); DBPDataKind dataKind = attribute.getDataKind(); diff --git a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/lightgrid/GridCellRenderer.java b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/lightgrid/GridCellRenderer.java index 260a239c7b1360587e59163df90e0610c74318dd..ddf60bc9753c664285db99c06ba2b347147339cc 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/lightgrid/GridCellRenderer.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/lightgrid/GridCellRenderer.java @@ -133,7 +133,12 @@ class GridCellRenderer extends AbstractRenderer { case IGridContentProvider.ALIGN_RIGHT: { // Right (numbers, datetimes) Point textSize = gc.textExtent(text); - boolean useClipping = textSize.x + INSIDE_MARGIN > bounds.width; + int valueWidth = textSize.x + INSIDE_MARGIN; + if (imageBounds != null) { + valueWidth += imageBounds.width + INSIDE_MARGIN; + } + valueWidth += RIGHT_MARGIN; + boolean useClipping = valueWidth > bounds.width; int imageMargin = 0; if (image != null) { diff --git a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/ResultSetViewer.java b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/ResultSetViewer.java index 03b68186a4584e2d69f343ac9fa26ff971ea8ce1..e4677c7005d96e40a1444bee0eac235e5e6d6b9f 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/ResultSetViewer.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/ResultSetViewer.java @@ -2681,6 +2681,7 @@ public class ResultSetViewer extends Viewer } if ((getDecorator().getDecoratorFeatures() & IResultSetDecorator.FEATURE_PANELS) != 0) { layoutMenu.add(ActionUtils.makeCommandContribution(site, ResultSetHandlerMain.CMD_TOGGLE_PANELS)); + layoutMenu.add(ActionUtils.makeCommandContribution(site, ResultSetHandlerMain.CMD_ACTIVATE_PANELS)); layoutMenu.add(ActionUtils.makeCommandContribution(site, ResultSetHandlerMain.CMD_TOGGLE_LAYOUT)); } if ((getDecorator().getDecoratorFeatures() & IResultSetDecorator.FEATURE_PRESENTATIONS) != 0) { diff --git a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java index 155b1717fe154a707982a4b52c0ef0c455b2be08..cb8862fc7808aaf96fdfb86603ff333233c2bc21 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java @@ -312,7 +312,7 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa } else { GridCell cell = spreadsheet.posToCell(curPosition); if (cell != null) { - cellText = CommonUtils.toString(spreadsheet.getContentProvider().getCellValue(cell.col, cell.row, true, true)); + cellText = CommonUtils.toString(spreadsheet.getContentProvider().getCellValue(cell.col, cell.row, false, false)); } else { continue; } diff --git a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java index 733b2837af1322557bc2e21aebdc5d89213485eb..d477566b75ba5670efc0d5133e7fb827576c77d5 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java @@ -1986,7 +1986,7 @@ public class SpreadsheetPresentation extends AbstractPresentation implements IRe if (!hasScope || inScope) { java.util.regex.Pattern searchPattern = findReplaceTarget.getSearchPattern(); if (searchPattern != null) { - String cellText = getCellText(colElement, rowElement); + String cellText = CommonUtils.toString(getCellValue(colElement, rowElement, false, false)); if (searchPattern.matcher(cellText).find()) { return backgroundMatched; } diff --git a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/valuefilter/GenericFilterValueEdit.java b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/valuefilter/GenericFilterValueEdit.java index 973698f6a2a61a87b697c37d3d4cbb57baee364c..5f3f214609365fcafa0f0c80c01a6f8eb855ac96 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/valuefilter/GenericFilterValueEdit.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/valuefilter/GenericFilterValueEdit.java @@ -241,7 +241,9 @@ class GenericFilterValueEdit { void loadValues(Runnable onFinish) { KeyLoadJob curLoadJob = this.loadJob; if (curLoadJob != null) { - curLoadJob.cancel(); + if (!curLoadJob.isCanceled()) { + curLoadJob.cancel(); + } curLoadJob.schedule(200); return; } diff --git a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java index 2e9579c4804d5acae106e62235f9ec0d7d235cd2..9a6f2ae6b2c8811dfab5debcda8d64ae5b01f31c 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.sql/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java @@ -4054,6 +4054,11 @@ public class SQLEditor extends SQLEditorBase implements @Override public void run() { getActivePreferenceStore().setValue(SQLPreferenceConstants.OUTPUT_PANEL_AUTO_SHOW, isChecked()); + try { + getActivePreferenceStore().save(); + } catch (IOException e) { + log.error(e); + } } } diff --git a/plugins/org.jkiss.dbeaver.ui.navigator/src/org/jkiss/dbeaver/ui/navigator/itemlist/ItemListControl.java b/plugins/org.jkiss.dbeaver.ui.navigator/src/org/jkiss/dbeaver/ui/navigator/itemlist/ItemListControl.java index 9079bdb57819479e9516a812ff042916c61a0cfc..351138961e3a17d9ff38756ac2dd0672b911e95d 100644 --- a/plugins/org.jkiss.dbeaver.ui.navigator/src/org/jkiss/dbeaver/ui/navigator/itemlist/ItemListControl.java +++ b/plugins/org.jkiss.dbeaver.ui.navigator/src/org/jkiss/dbeaver/ui/navigator/itemlist/ItemListControl.java @@ -383,14 +383,15 @@ public class ItemListControl extends NodeListControl if (property != null) { Object oldValue = getListPropertySource().getPropertyValue(null, objectValue, property, false); getListPropertySource().setPropertyValue(null, objectValue, property, UIUtils.normalizePropertyValue(value)); + Object newValue = getListPropertySource().getPropertyValue(null, objectValue, property, false); if (value instanceof Boolean) { // Redraw control to let it repaint checkbox getItemsViewer().getControl().redraw(); } - if (!CommonUtils.equalObjects(oldValue, value)) { + if (!CommonUtils.equalObjects(oldValue, newValue)) { Map propMap = changedProperties.computeIfAbsent(object, dbnNode -> new HashMap<>()); Object savedValue = propMap.get(property.getId()); - if (CommonUtils.equalObjects(savedValue, value)) { + if (CommonUtils.equalObjects(savedValue, newValue)) { // Reset to original value propMap.remove(property.getId()); } else if (!propMap.containsKey(property.getId())) { diff --git a/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomCheckboxCellEditor.java b/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomCheckboxCellEditor.java index b8bbc730c53cd934775c5ed638f095ed96b46260..6da53bb80a7c6a2a3a17e32e742ebf9c2f6cd1f8 100644 --- a/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomCheckboxCellEditor.java +++ b/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomCheckboxCellEditor.java @@ -20,10 +20,9 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusAdapter; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.*; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; @@ -48,21 +47,59 @@ public class CustomCheckboxCellEditor extends CellEditor { @Override protected Control createControl(Composite parent) { - //Composite ph = UIUtils.createPlaceholder(parent, 1); - checkBox = new Label(parent, SWT.NONE); - //setCheckIcon(); - checkBox.setFont(parent.getFont()); - checkBox.setBackground(null); - - checkBox.addFocusListener(new FocusAdapter() { + Composite ph = new Composite(parent, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + gl.marginWidth = 0; + gl.marginHeight = 0; + ph.setLayout(gl); + + ph.setBackground(parent.getBackground()); + checkBox = new Label(ph, SWT.NONE); + GridData gd = new GridData(SWT.CENTER, SWT.FILL, true, true); + checkBox.setLayoutData(gd); + checkBox.setBackground(ph.getBackground()); + + ph.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { CustomCheckboxCellEditor.this.focusLost(); } }); - addMouseListener(); + ph.addKeyListener(new KeyListener() { + @Override + public void keyPressed(KeyEvent e) { + switch (e.character) { + case SWT.ESC: + dispose(); + break; + case SWT.SPACE: + checked = !checked; + setCheckIcon(); + applyEditorValue(); + break; + case SWT.CR: + applyEditorValue(); + fireApplyEditorValue(); + break; + } + } - return checkBox; + @Override + public void keyReleased(KeyEvent e) { + + } + }); + checkBox.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + checked = !checked; + setCheckIcon(); + applyEditorValue(); + //fireApplyEditorValue(); + } + }); + + return ph; } private void setCheckIcon() { @@ -81,7 +118,7 @@ public class CustomCheckboxCellEditor extends CellEditor { @Override protected void doSetFocus() { - checkBox.setFocus(); + checkBox.getParent().setFocus(); } @Override @@ -98,7 +135,7 @@ public class CustomCheckboxCellEditor extends CellEditor { layoutData.grabHorizontal = true; layoutData.horizontalAlignment = SWT.LEFT; } else { - layoutData.grabHorizontal = false; + layoutData.grabHorizontal = true; layoutData.horizontalAlignment = SWT.CENTER; } return layoutData; @@ -135,21 +172,9 @@ public class CustomCheckboxCellEditor extends CellEditor { } } - private void addMouseListener() { - checkBox.addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - checked = !checked; - setCheckIcon(); - applyEditorValue(); - fireApplyEditorValue(); - } - }); - } - @Override public void activate(ColumnViewerEditorActivationEvent activationEvent) { - if (activationEvent.eventType != ColumnViewerEditorActivationEvent.TRAVERSAL) { + /*if (activationEvent.eventType != ColumnViewerEditorActivationEvent.TRAVERSAL) */{ super.activate(activationEvent); } }