提交 a93c4f51 编写于 作者: S Serge Rider

Merge remote-tracking branch 'origin/devel' into devel


Former-commit-id: d7e889aa
......@@ -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);
......
......@@ -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);
......
......@@ -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<TPRule> 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));
}
}
}
......@@ -97,7 +97,7 @@ public class GreenplumTable extends PostgreTableRegular {
private List<PostgreTableColumn> getDistributionTableColumns(DBRProgressMonitor monitor, List<PostgreTableColumn> distributionColumns) throws DBException {
// Get primary key
PostgreTableConstraint pk = null;
for (PostgreTableConstraint tc : getConstraints(monitor)) {
for (PostgreTableConstraint tc : CommonUtils.safeCollection(getConstraints(monitor))) {
if (tc.getConstraintType() == DBSEntityConstraintType.PRIMARY_KEY) {
pk = tc;
break;
......@@ -167,15 +167,17 @@ public class GreenplumTable extends PostgreTableRegular {
}
ddl.append("\nDISTRIBUTED ");
if (CommonUtils.isEmpty(distributionColumns)) {
ddl.append((supportsReplicatedDistribution && isPersisted() && isDistributedByReplicated(monitor)) ? "REPLICATED" : "RANDOMLY");
} else {
if (supportsReplicatedDistribution && isPersisted() && isDistributedByReplicated(monitor)) {
ddl.append("REPLICATED");
} else if (!CommonUtils.isEmpty(distributionColumns)) {
ddl.append("BY (");
for (int i = 0; i < distributionColumns.size(); i++) {
if (i > 0) ddl.append(", ");
ddl.append(DBUtils.getQuotedIdentifier(distributionColumns.get(i)));
}
ddl.append(")");
} else {
ddl.append("RANDOMLY");
}
String partitionData = isPersisted() ? getPartitionData(monitor) : null;
......
......@@ -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;
......
......@@ -80,7 +80,7 @@ public class PostgreForeignKeyManager extends SQLForeignKeyManager<PostgreTableF
@Override
public StringBuilder getNestedDeclaration(DBRProgressMonitor monitor, PostgreTableBase owner, DBECommandAbstract<PostgreTableForeignKey> command, Map<String, Object> options) {
PostgreTableForeignKey fk = command.getObject();
if (fk.isPersisted()) {
/*if (fk.isPersisted()) {
try {
String constrDDL = fk.getObjectDefinitionText(
monitor,
......@@ -91,9 +91,14 @@ public class PostgreForeignKeyManager extends SQLForeignKeyManager<PostgreTableF
} catch (DBException e) {
log.warn("Can't extract FK DDL", e);
}
}
}*/
StringBuilder sql = super.getNestedDeclaration(monitor, owner, command, options);
if (fk.getMatchType().equals(PostgreTableForeignKey.MatchType.f)) {
//Foreign key match types: f = full, p = partial (not implemented yet), s = simple (u == s in old PG versions - default value)
sql.append(" MATCH FULL");
}
if (fk.isDeferrable()) {
sql.append(" DEFERRABLE");
}
......
......@@ -42,6 +42,7 @@ import org.jkiss.dbeaver.model.struct.DBSTypedObject;
import org.jkiss.dbeaver.model.text.parser.TPRule;
import org.jkiss.dbeaver.model.text.parser.TPRuleProvider;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import java.sql.Types;
import java.util.Arrays;
......@@ -816,6 +817,11 @@ public class PostgreDialect extends JDBCSQLDialect implements TPRuleProvider {
// For now we use workaround: represent objects as strings
return '\'' + escapeString(strValue) + '\'';
}
if (CommonUtils.isNaN(value) || CommonUtils.isInfinite(value)) {
// These special values should be quoted
// https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL
return '\'' + String.valueOf(value) + '\'';
}
return super.escapeScriptValue(attribute, value, strValue);
}
......
/*
* 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;
}
}
......@@ -636,9 +636,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();
......
......@@ -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;
}
......
......@@ -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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册