提交 c10fa631 编写于 作者: S serge-rider

SQL Completion: process quoted identifiers

上级 207c4d41
......@@ -24,6 +24,7 @@ import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.utils.ArrayUtils;
/**
* Determines whether a given character is valid as part of an SQL identifier.
......@@ -85,9 +86,16 @@ public class SQLIdentifierDetector extends SQLWordDetector {
}
public String removeQuotes(String name) {
// Remove leading (and trailing) quotes if any
for (int i = 0; i < quoteStrings.length; i++) {
name = DBUtils.getUnQuotedIdentifier(name, quoteStrings[i][0], quoteStrings[i][1]);
if (name.startsWith(quoteStrings[i][0])) {
name = name.substring(quoteStrings[i][0].length());
}
if (name.endsWith(quoteStrings[i][1])) {
name = name.substring(0, name.length() - quoteStrings[i][0].length());
}
}
return name;
}
......
/*
* 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.sql.parser;
import org.eclipse.jface.text.IDocument;
/**
* Partitions and other
*/
public class SQLParserPartitions {
public final static String SQL_PARTITIONING = "___sql_partitioning";
public final static String CONTENT_TYPE_SQL_COMMENT = "sql_comment";
public final static String CONTENT_TYPE_SQL_MULTILINE_COMMENT = "sql_multiline_comment";
public final static String CONTENT_TYPE_SQL_STRING = "sql_character";
public final static String CONTENT_TYPE_SQL_QUOTED = "sql_quoted";
public final static String[] SQL_CONTENT_TYPES = new String[]{
IDocument.DEFAULT_CONTENT_TYPE,
CONTENT_TYPE_SQL_COMMENT,
CONTENT_TYPE_SQL_MULTILINE_COMMENT,
CONTENT_TYPE_SQL_STRING,
CONTENT_TYPE_SQL_QUOTED,
};
}
\ No newline at end of file
......@@ -19,6 +19,7 @@ package org.jkiss.dbeaver.model.sql.parser;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextUtilities;
import org.jkiss.dbeaver.model.sql.SQLSyntaxManager;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.utils.CommonUtils;
......@@ -62,7 +63,8 @@ public class SQLWordPartDetector extends SQLIdentifierDetector
endOffset = documentOffset;
int topIndex = 0, documentLength = document.getLength();
try {
boolean inQuote = false;
String contentType = TextUtilities.getContentType(document, SQLParserPartitions.SQL_PARTITIONING, documentOffset, true);
boolean inQuote = SQLParserPartitions.CONTENT_TYPE_SQL_QUOTED.equals(contentType);
while (startOffset >= topIndex && startOffset < documentLength) {
char c = document.getChar(startOffset);
if (inQuote) {
......
......@@ -53,6 +53,7 @@ import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.*;
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionContext;
import org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.model.text.TextUtils;
import org.jkiss.dbeaver.ui.*;
......@@ -403,11 +404,11 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext
char[] matchChars = BRACKETS; //which brackets to match
try {
characterPairMatcher = new SQLCharacterPairMatcher(this, matchChars,
SQLPartitionScanner.SQL_PARTITIONING,
SQLParserPartitions.SQL_PARTITIONING,
true);
} catch (Throwable e) {
// If we below Eclipse 4.2.1
characterPairMatcher = new SQLCharacterPairMatcher(this, matchChars, SQLPartitionScanner.SQL_PARTITIONING);
characterPairMatcher = new SQLCharacterPairMatcher(this, matchChars, SQLParserPartitions.SQL_PARTITIONING);
}
support.setCharacterPairMatcher(characterPairMatcher);
support.setMatchingCharacterPainterPreferenceKeys(SQLPreferenceConstants.MATCHING_BRACKETS, SQLPreferenceConstants.MATCHING_BRACKETS_COLOR);
......@@ -587,10 +588,10 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext
if (document instanceof IDocumentExtension3) {
IDocumentPartitioner partitioner = new FastPartitioner(
new SQLPartitionScanner(dialect),
SQLPartitionScanner.SQL_CONTENT_TYPES);
SQLParserPartitions.SQL_CONTENT_TYPES);
partitioner.connect(document);
try {
((IDocumentExtension3)document).setDocumentPartitioner(SQLPartitionScanner.SQL_PARTITIONING, partitioner);
((IDocumentExtension3)document).setDocumentPartitioner(SQLParserPartitions.SQL_PARTITIONING, partitioner);
} catch (Throwable e) {
log.warn("Error setting SQL partitioner", e); //$NON-NLS-1$
}
......@@ -695,7 +696,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext
return null;
}
final int docLength = document.getLength();
IDocumentPartitioner partitioner = document instanceof IDocumentExtension3 ? ((IDocumentExtension3)document).getDocumentPartitioner(SQLPartitionScanner.SQL_PARTITIONING) : null;
IDocumentPartitioner partitioner = document instanceof IDocumentExtension3 ? ((IDocumentExtension3)document).getDocumentPartitioner(SQLParserPartitions.SQL_PARTITIONING) : null;
if (partitioner != null) {
// Move to default partition. We don't want to be in the middle of multi-line comment or string
while (currentPos < docLength && isMultiCommentPartition(partitioner, currentPos)) {
......@@ -829,7 +830,7 @@ public abstract class SQLEditorBase extends BaseTextEditor implements DBPContext
}
private static boolean isMultiCommentPartition(IDocumentPartitioner partitioner, int currentPos) {
return partitioner != null && SQLPartitionScanner.CONTENT_TYPE_SQL_MULTILINE_COMMENT.equals(partitioner.getContentType(currentPos));
return partitioner != null && SQLParserPartitions.CONTENT_TYPE_SQL_MULTILINE_COMMENT.equals(partitioner.getContentType(currentPos));
}
private void startScriptEvaluation() {
......
......@@ -44,6 +44,7 @@ import org.jkiss.dbeaver.model.preferences.DBPPreferenceListener;
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.editors.sql.indent.SQLAutoIndentStrategy;
import org.jkiss.dbeaver.ui.editors.sql.indent.SQLCommentAutoIndentStrategy;
......@@ -116,11 +117,11 @@ public class SQLEditorSourceViewerConfiguration extends TextSourceViewerConfigur
public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType)
{
if (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
return new IAutoEditStrategy[] { new SQLAutoIndentStrategy(SQLPartitionScanner.SQL_PARTITIONING, editor.getSyntaxManager()) } ;
} else if (SQLPartitionScanner.CONTENT_TYPE_SQL_COMMENT.equals(contentType) || SQLPartitionScanner.CONTENT_TYPE_SQL_MULTILINE_COMMENT.equals(contentType)) {
return new IAutoEditStrategy[] { new SQLCommentAutoIndentStrategy(SQLPartitionScanner.SQL_PARTITIONING) } ;
} else if (SQLPartitionScanner.CONTENT_TYPE_SQL_STRING.equals(contentType)) {
return new IAutoEditStrategy[] { new SQLStringAutoIndentStrategy(SQLPartitionScanner.CONTENT_TYPE_SQL_STRING) };
return new IAutoEditStrategy[] { new SQLAutoIndentStrategy(SQLParserPartitions.SQL_PARTITIONING, editor.getSyntaxManager()) } ;
} else if (SQLParserPartitions.CONTENT_TYPE_SQL_COMMENT.equals(contentType) || SQLParserPartitions.CONTENT_TYPE_SQL_MULTILINE_COMMENT.equals(contentType)) {
return new IAutoEditStrategy[] { new SQLCommentAutoIndentStrategy(SQLParserPartitions.SQL_PARTITIONING) } ;
} else if (SQLParserPartitions.CONTENT_TYPE_SQL_STRING.equals(contentType)) {
return new IAutoEditStrategy[] { new SQLStringAutoIndentStrategy(SQLParserPartitions.CONTENT_TYPE_SQL_STRING) };
}
return new IAutoEditStrategy[0];
}
......@@ -134,7 +135,7 @@ public class SQLEditorSourceViewerConfiguration extends TextSourceViewerConfigur
@Override
public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer)
{
return SQLPartitionScanner.SQL_PARTITIONING;
return SQLParserPartitions.SQL_PARTITIONING;
}
/**
......@@ -153,7 +154,8 @@ public class SQLEditorSourceViewerConfiguration extends TextSourceViewerConfigur
// Set content assist processors for various content types.
if (completionProcessor != null) {
assistant.setContentAssistProcessor(completionProcessor, IDocument.DEFAULT_CONTENT_TYPE);
assistant.addContentAssistProcessor(completionProcessor, IDocument.DEFAULT_CONTENT_TYPE);
assistant.addContentAssistProcessor(completionProcessor, SQLParserPartitions.CONTENT_TYPE_SQL_QUOTED);
}
// Configure how content assist information will appear.
......@@ -210,10 +212,10 @@ public class SQLEditorSourceViewerConfiguration extends TextSourceViewerConfigur
public IContentFormatter getContentFormatter(ISourceViewer sourceViewer)
{
ContentFormatter formatter = new ContentFormatter();
formatter.setDocumentPartitioning(SQLPartitionScanner.SQL_PARTITIONING);
formatter.setDocumentPartitioning(SQLParserPartitions.SQL_PARTITIONING);
IFormattingStrategy formattingStrategy = new SQLFormattingStrategy(sourceViewer, this, editor.getSyntaxManager());
for (String ct : SQLPartitionScanner.SQL_CONTENT_TYPES) {
for (String ct : SQLParserPartitions.SQL_CONTENT_TYPES) {
formatter.setFormattingStrategy(formattingStrategy, ct);
}
......@@ -258,13 +260,13 @@ public class SQLEditorSourceViewerConfiguration extends TextSourceViewerConfigur
// rule for multiline comments
// We just need a scanner that does nothing but returns a token with
// the corresponding text attributes
addContentTypeDamageRepairer(reconciler, SQLPartitionScanner.CONTENT_TYPE_SQL_MULTILINE_COMMENT, SQLConstants.CONFIG_COLOR_COMMENT);
addContentTypeDamageRepairer(reconciler, SQLParserPartitions.CONTENT_TYPE_SQL_MULTILINE_COMMENT, SQLConstants.CONFIG_COLOR_COMMENT);
// Add a "damager-repairer" for changes within one-line SQL comments.
addContentTypeDamageRepairer(reconciler, SQLPartitionScanner.CONTENT_TYPE_SQL_COMMENT, SQLConstants.CONFIG_COLOR_COMMENT);
addContentTypeDamageRepairer(reconciler, SQLParserPartitions.CONTENT_TYPE_SQL_COMMENT, SQLConstants.CONFIG_COLOR_COMMENT);
// Add a "damager-repairer" for changes within quoted literals.
addContentTypeDamageRepairer(reconciler, SQLPartitionScanner.CONTENT_TYPE_SQL_STRING, SQLConstants.CONFIG_COLOR_STRING);
addContentTypeDamageRepairer(reconciler, SQLParserPartitions.CONTENT_TYPE_SQL_STRING, SQLConstants.CONFIG_COLOR_STRING);
// Add a "damager-repairer" for changes within quoted literals.
addContentTypeDamageRepairer(reconciler, SQLPartitionScanner.CONTENT_TYPE_SQL_QUOTED, SQLConstants.CONFIG_COLOR_DATATYPE);
addContentTypeDamageRepairer(reconciler, SQLParserPartitions.CONTENT_TYPE_SQL_QUOTED, SQLConstants.CONFIG_COLOR_DATATYPE);
return reconciler;
}
......@@ -306,7 +308,7 @@ public class SQLEditorSourceViewerConfiguration extends TextSourceViewerConfigur
@Override
public String[] getConfiguredContentTypes(ISourceViewer sourceViewer)
{
return SQLPartitionScanner.SQL_CONTENT_TYPES;
return SQLParserPartitions.SQL_CONTENT_TYPES;
}
@Override
......
......@@ -22,9 +22,9 @@ import org.jkiss.dbeaver.model.DBPKeywordType;
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLSyntaxManager;
import org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.ui.editors.sql.SQLPreferenceConstants;
import org.jkiss.dbeaver.ui.editors.sql.syntax.SQLPartitionScanner;
import org.jkiss.dbeaver.utils.GeneralUtils;
import java.util.HashMap;
......@@ -365,7 +365,7 @@ public class SQLAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
int start = reg.getOffset();
ITypedRegion region = TextUtilities.getPartition(document, partitioning, start, true);
if (SQLPartitionScanner.CONTENT_TYPE_SQL_MULTILINE_COMMENT.equals(region.getType())) {
if (SQLParserPartitions.CONTENT_TYPE_SQL_MULTILINE_COMMENT.equals(region.getType())) {
start = document.getLineInformationOfOffset(region.getOffset()).getOffset();
}
......
......@@ -22,7 +22,7 @@ import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextUtilities;
import org.jkiss.dbeaver.model.DBPKeywordType;
import org.jkiss.dbeaver.model.sql.SQLSyntaxManager;
import org.jkiss.dbeaver.ui.editors.sql.syntax.SQLPartitionScanner;
import org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions;
/**
......@@ -154,7 +154,7 @@ public class SQLHeuristicScanner implements SQLIndentSymbols {
}
public SQLHeuristicScanner(IDocument document, SQLSyntaxManager syntaxManager) {
this(document, SQLPartitionScanner.SQL_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE, syntaxManager);
this(document, SQLParserPartitions.SQL_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE, syntaxManager);
}
public int getPosition() {
......
......@@ -33,6 +33,7 @@ import org.jkiss.dbeaver.model.sql.SQLScriptElement;
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionAnalyzer;
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionProposalBase;
import org.jkiss.dbeaver.model.sql.completion.SQLCompletionRequest;
import org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions;
import org.jkiss.dbeaver.model.sql.parser.SQLWordPartDetector;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.editors.sql.SQLEditorBase;
......@@ -100,8 +101,8 @@ public class SQLCompletionProcessor implements IContentAssistProcessor
try {
// Check that word start position is in default partition (#5994)
String contentType = TextUtilities.getContentType(document, SQLPartitionScanner.SQL_PARTITIONING, wordDetector.getStartOffset(), true);
if (contentType == null || !IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
String contentType = TextUtilities.getContentType(document, SQLParserPartitions.SQL_PARTITIONING, wordDetector.getStartOffset(), true);
if (contentType == null || (!IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) && !SQLParserPartitions.CONTENT_TYPE_SQL_QUOTED.equals(contentType))) {
return new ICompletionProposal[0];
}
} catch (BadLocationException e) {
......
......@@ -23,6 +23,7 @@ import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.rules.*;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions;
import org.jkiss.utils.Pair;
import java.util.ArrayList;
......@@ -36,27 +37,13 @@ import java.util.List;
* and SQL code sections.
*/
public class SQLPartitionScanner extends RuleBasedPartitionScanner {
public final static String SQL_PARTITIONING = "___sql_partitioning";
public final static String CONTENT_TYPE_SQL_COMMENT = "sql_comment";
public final static String CONTENT_TYPE_SQL_MULTILINE_COMMENT = "sql_multiline_comment";
public final static String CONTENT_TYPE_SQL_STRING = "sql_character";
public final static String CONTENT_TYPE_SQL_QUOTED = "sql_quoted";
public final static String[] SQL_CONTENT_TYPES = new String[]{
IDocument.DEFAULT_CONTENT_TYPE,
CONTENT_TYPE_SQL_COMMENT,
CONTENT_TYPE_SQL_MULTILINE_COMMENT,
CONTENT_TYPE_SQL_STRING,
CONTENT_TYPE_SQL_QUOTED,
};
// Syntax higlight
private final List<IPredicateRule> rules = new ArrayList<>();
private final IToken commentToken = new Token(CONTENT_TYPE_SQL_COMMENT);
private final IToken multilineCommentToken = new Token(CONTENT_TYPE_SQL_MULTILINE_COMMENT);
private final IToken sqlStringToken = new Token(CONTENT_TYPE_SQL_STRING);
private final IToken sqlQuotedToken = new Token(CONTENT_TYPE_SQL_QUOTED);
private final IToken commentToken = new Token(SQLParserPartitions.CONTENT_TYPE_SQL_COMMENT);
private final IToken multilineCommentToken = new Token(SQLParserPartitions.CONTENT_TYPE_SQL_MULTILINE_COMMENT);
private final IToken sqlStringToken = new Token(SQLParserPartitions.CONTENT_TYPE_SQL_STRING);
private final IToken sqlQuotedToken = new Token(SQLParserPartitions.CONTENT_TYPE_SQL_QUOTED);
/**
* Detector for empty comments.
......@@ -188,7 +175,7 @@ public class SQLPartitionScanner extends RuleBasedPartitionScanner {
{
ITypedRegion[] regions = null;
try {
regions = TextUtilities.computePartitioning(doc, SQLPartitionScanner.SQL_PARTITIONING, 0, doc.getLength(), false);
regions = TextUtilities.computePartitioning(doc, SQLParserPartitions.SQL_PARTITIONING, 0, doc.getLength(), false);
}
catch (BadLocationException e) {
// ignore
......
......@@ -31,8 +31,8 @@ import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions;
import org.jkiss.dbeaver.ui.editors.sql.SQLEditorBase;
import org.jkiss.dbeaver.ui.editors.sql.syntax.SQLPartitionScanner;
import org.jkiss.dbeaver.ui.editors.sql.templates.SQLTemplatesPage;
import java.util.ArrayList;
......@@ -190,7 +190,7 @@ public class SQLSymbolInserter implements VerifyKeyListener, ILinkedModeListener
try {
ITypedRegion partition = TextUtilities.getPartition(
document,
SQLPartitionScanner.SQL_PARTITIONING,
SQLParserPartitions.SQL_PARTITIONING,
offset,
true);
if (!IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册