[ZEPPELIN-2297] improvements to jdbc autocompleter ### What is this PR for? PR contains some improvements for completion (JDBC Interpreter): - types of completion - display of long values - refactoring of search of completions - uniqness of completions with type `keyword` - updating data in completer by pressing `Ctrl + .` - setting the schema filter to generate completions - fix highlighting code when used not default data source
### What type of PR is it? Improvement ### What is the Jira issue? https://issues.apache.org/jira/browse/ZEPPELIN-2297 ### How should this be tested? try to work with new completer ### Screenshots (if appropriate) **1. Types of completion** ![1](https://cloud.githubusercontent.com/assets/25951039/24449367/758eeeac-1490-11e7-863f-bf1b313a3f4d.png) **2. Display of long values** before ![2297_before_long_caption](https://cloud.githubusercontent.com/assets/25951039/24449397/8ecd3072-1490-11e7-8fd4-415424ef337e.gif) after ![2297_after_long_caption](https://cloud.githubusercontent.com/assets/25951039/24449413/9c7a36b6-1490-11e7-9d7c-cbbdac71cbe7.gif) **3. Refactoring of search of completions. Updating data in completer by pressing `Ctrl + .`** before ![2297_before_refactoring_search](https://cloud.githubusercontent.com/assets/25951039/24449463/c1801214-1490-11e7-84a8-25c887b68d65.gif) after ![2297_after_refactoring_search](https://cloud.githubusercontent.com/assets/25951039/24449567/1079bdc0-1491-11e7-8409-5187aeceb428.gif) **4. uniqness of completions with type keyword** before ![2297_before_uniq](https://cloud.githubusercontent.com/assets/25951039/24449615/4e20c8d0-1491-11e7-94cc-c86aab886c53.gif) after ![2297_after_uniq](https://cloud.githubusercontent.com/assets/25951039/24449635/5cf59aca-1491-11e7-8ee1-31ea3cdacb3e.gif) **5. fix highlighting code when used not default data source** before ![2297_before_inrpret_name](https://cloud.githubusercontent.com/assets/25951039/24449730/b6c8d62a-1491-11e7-8dc3-39fa6975c8c3.gif) after ![2297_after_inrpret_name](https://cloud.githubusercontent.com/assets/25951039/24449738/baf63e18-1491-11e7-8711-12557a674212.gif) ### Questions: * Does the licenses files need update? no * Is there breaking changes for older versions? no * Does this needs documentation? no Author: Tinkoff DWH <tinkoff....@gmail.com> Closes #2203 from tinkoff-dwh/ZEPPELIN-2297 and squashes the following commits: b86b57a [Tinkoff DWH] [ZEPPELIN-2297] small fix to compute caption 8552049 [Tinkoff DWH] [ZEPPELIN-2297] schema filters 5308f1e [Tinkoff DWH] [ZEPPELIN-2297] updating completions ef6c9cb [Tinkoff DWH] Merge remote-tracking branch 'origin/ZEPPELIN-2297' into ZEPPELIN-2297 1e05a68 [Tinkoff DWH] [ZEPPELIN-2297] fix uniqueness keywords ec3cd3b [Tinkoff DWH] [ZEPPELIN-2297] fix uniqueness keywords 2b58cc5 [Tinkoff DWH] [ZEPPELIN-2297] refactoring search completions 7b5835d [Tinkoff DWH] [ZEPPELIN-2297] compute caption of copletion 1c74384 [Tinkoff DWH] [ZEPPELIN-2297] add type of completion Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/4d398ef2 Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/4d398ef2 Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/4d398ef2 Branch: refs/heads/master Commit: 4d398ef2a6471614cebd6b0177a08333114f5802 Parents: 775607f Author: Tinkoff DWH <tinkoff....@gmail.com> Authored: Mon Apr 3 20:53:02 2017 +0500 Committer: Lee moon soo <m...@apache.org> Committed: Mon Apr 17 14:18:32 2017 +0900 ---------------------------------------------------------------------- .../zeppelin/alluxio/AlluxioInterpreter.java | 7 +- .../alluxio/AlluxioInterpreterTest.java | 38 +-- .../zeppelin/angular/AngularInterpreter.java | 3 +- .../apache/zeppelin/beam/BeamInterpreter.java | 3 +- .../zeppelin/bigquery/BigQueryInterpreter.java | 3 +- .../cassandra/CassandraInterpreter.java | 3 +- docs/interpreter/jdbc.md | 5 + .../elasticsearch/ElasticsearchInterpreter.java | 6 +- .../ElasticsearchInterpreterTest.java | 11 +- .../apache/zeppelin/file/FileInterpreter.java | 3 +- .../zeppelin/file/HDFSFileInterpreter.java | 23 +- .../zeppelin/file/HDFSFileInterpreterTest.java | 10 +- .../apache/zeppelin/flink/FlinkInterpreter.java | 3 +- .../zeppelin/geode/GeodeOqlInterpreter.java | 3 +- .../apache/zeppelin/hbase/HbaseInterpreter.java | 3 +- .../apache/zeppelin/helium/DevInterpreter.java | 3 +- .../zeppelin/ignite/IgniteInterpreter.java | 3 +- .../zeppelin/ignite/IgniteSqlInterpreter.java | 3 +- jdbc/pom.xml | 12 - .../apache/zeppelin/jdbc/JDBCInterpreter.java | 56 ++-- .../org/apache/zeppelin/jdbc/SqlCompleter.java | 257 ++++++++++++------- jdbc/src/main/resources/ansi.sql.keywords | 2 +- .../src/main/resources/interpreter-setting.json | 6 + .../postgresql-native-driver-sql.keywords | 2 +- .../zeppelin/jdbc/JDBCInterpreterTest.java | 5 +- .../apache/zeppelin/jdbc/SqlCompleterTest.java | 167 +++++++----- .../apache/zeppelin/kylin/KylinInterpreter.java | 3 +- .../apache/zeppelin/lens/LensInterpreter.java | 3 +- .../org/apache/zeppelin/markdown/Markdown.java | 3 +- pig/pom.xml | 6 + .../zeppelin/python/PythonInterpreter.java | 3 +- .../org/apache/zeppelin/rinterpreter/KnitR.java | 5 +- .../org/apache/zeppelin/rinterpreter/RRepl.java | 5 +- .../zeppelin/scalding/ScaldingInterpreter.java | 3 +- .../apache/zeppelin/shell/ShellInterpreter.java | 3 +- .../apache/zeppelin/spark/DepInterpreter.java | 7 +- .../zeppelin/spark/PySparkInterpreter.java | 6 +- .../apache/zeppelin/spark/SparkInterpreter.java | 5 +- .../zeppelin/spark/SparkRInterpreter.java | 3 +- .../zeppelin/spark/SparkSqlInterpreter.java | 3 +- .../zeppelin/spark/PySparkInterpreterTest.java | 2 +- .../zeppelin/spark/SparkInterpreterTest.java | 2 +- zeppelin-interpreter/pom.xml | 12 + .../zeppelin/completer/CompletionType.java | 28 ++ .../zeppelin/completer/StringsCompleter.java | 77 ++++++ .../interpreter/ClassloaderInterpreter.java | 5 +- .../zeppelin/interpreter/Interpreter.java | 4 +- .../interpreter/LazyOpenInterpreter.java | 5 +- .../interpreter/remote/RemoteInterpreter.java | 6 +- .../remote/RemoteInterpreterServer.java | 4 +- .../thrift/InterpreterCompletion.java | 115 ++++++++- .../thrift/RemoteApplicationResult.java | 2 +- .../thrift/RemoteInterpreterContext.java | 2 +- .../thrift/RemoteInterpreterEvent.java | 2 +- .../thrift/RemoteInterpreterResult.java | 2 +- .../thrift/RemoteInterpreterResultMessage.java | 2 +- .../thrift/RemoteInterpreterService.java | 144 +++++++++-- .../ZeppelinServerResourceParagraphRunner.java | 2 +- .../main/thrift/RemoteInterpreterService.thrift | 5 +- .../remote/mock/MockInterpreterA.java | 3 +- .../remote/mock/MockInterpreterAngular.java | 3 +- .../remote/mock/MockInterpreterB.java | 3 +- .../remote/mock/MockInterpreterEnv.java | 3 +- .../mock/MockInterpreterOutputStream.java | 3 +- .../mock/MockInterpreterResourcePool.java | 3 +- .../interpreter/mock/MockInterpreter1.java | 3 +- .../notebook/paragraph/paragraph.controller.js | 31 ++- .../org/apache/zeppelin/notebook/Paragraph.java | 14 +- .../interpreter/mock/MockInterpreter1.java | 3 +- .../interpreter/mock/MockInterpreter11.java | 3 +- .../interpreter/mock/MockInterpreter2.java | 3 +- 71 files changed, 875 insertions(+), 319 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/alluxio/src/main/java/org/apache/zeppelin/alluxio/AlluxioInterpreter.java ---------------------------------------------------------------------- diff --git a/alluxio/src/main/java/org/apache/zeppelin/alluxio/AlluxioInterpreter.java b/alluxio/src/main/java/org/apache/zeppelin/alluxio/AlluxioInterpreter.java index 79e10b6..8eb152b 100644 --- a/alluxio/src/main/java/org/apache/zeppelin/alluxio/AlluxioInterpreter.java +++ b/alluxio/src/main/java/org/apache/zeppelin/alluxio/AlluxioInterpreter.java @@ -23,9 +23,9 @@ import java.io.PrintStream; import java.io.ByteArrayOutputStream; import java.util.*; +import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.interpreter.Interpreter; import org.apache.zeppelin.interpreter.InterpreterContext; -import org.apache.zeppelin.interpreter.InterpreterPropertyBuilder; import org.apache.zeppelin.interpreter.InterpreterResult; import org.apache.zeppelin.interpreter.InterpreterResult.Code; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; @@ -166,7 +166,8 @@ public class AlluxioInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { String[] words = splitAndRemoveEmpty(splitAndRemoveEmpty(buf, "\n"), " "); String lastWord = ""; if (words.length > 0) { @@ -176,7 +177,7 @@ public class AlluxioInterpreter extends Interpreter { List<InterpreterCompletion> voices = new LinkedList<>(); for (String command : keywords) { if (command.startsWith(lastWord)) { - voices.add(new InterpreterCompletion(command, command)); + voices.add(new InterpreterCompletion(command, command, CompletionType.command.name())); } } return voices; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/alluxio/src/test/java/org/apache/zeppelin/alluxio/AlluxioInterpreterTest.java ---------------------------------------------------------------------- diff --git a/alluxio/src/test/java/org/apache/zeppelin/alluxio/AlluxioInterpreterTest.java b/alluxio/src/test/java/org/apache/zeppelin/alluxio/AlluxioInterpreterTest.java index 3aff4aa..e272a51 100644 --- a/alluxio/src/test/java/org/apache/zeppelin/alluxio/AlluxioInterpreterTest.java +++ b/alluxio/src/test/java/org/apache/zeppelin/alluxio/AlluxioInterpreterTest.java @@ -29,6 +29,8 @@ import java.util.Properties; import alluxio.client.WriteType; import alluxio.client.file.URIStatus; + +import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.interpreter.InterpreterResult; import org.apache.zeppelin.interpreter.InterpreterResult.Code; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; @@ -78,28 +80,28 @@ public class AlluxioInterpreterTest { @Test public void testCompletion() { List expectedResultOne = Arrays.asList( - new InterpreterCompletion("cat", "cat"), - new InterpreterCompletion("chgrp", "chgrp"), - new InterpreterCompletion("chmod", "chmod"), - new InterpreterCompletion("chown", "chown"), - new InterpreterCompletion("copyFromLocal", "copyFromLocal"), - new InterpreterCompletion("copyToLocal", "copyToLocal"), - new InterpreterCompletion("count", "count"), - new InterpreterCompletion("createLineage", "createLineage")); + new InterpreterCompletion("cat", "cat", CompletionType.command.name()), + new InterpreterCompletion("chgrp", "chgrp", CompletionType.command.name()), + new InterpreterCompletion("chmod", "chmod", CompletionType.command.name()), + new InterpreterCompletion("chown", "chown", CompletionType.command.name()), + new InterpreterCompletion("copyFromLocal", "copyFromLocal", CompletionType.command.name()), + new InterpreterCompletion("copyToLocal", "copyToLocal", CompletionType.command.name()), + new InterpreterCompletion("count", "count", CompletionType.command.name()), + new InterpreterCompletion("createLineage", "createLineage", CompletionType.command.name())); List expectedResultTwo = Arrays.asList( - new InterpreterCompletion("copyFromLocal", "copyFromLocal"), - new InterpreterCompletion("copyToLocal", "copyToLocal"), - new InterpreterCompletion("count", "count")); + new InterpreterCompletion("copyFromLocal", "copyFromLocal", CompletionType.command.name()), + new InterpreterCompletion("copyToLocal", "copyToLocal", CompletionType.command.name()), + new InterpreterCompletion("count", "count", CompletionType.command.name())); List expectedResultThree = Arrays.asList( - new InterpreterCompletion("copyFromLocal", "copyFromLocal"), - new InterpreterCompletion("copyToLocal", "copyToLocal")); + new InterpreterCompletion("copyFromLocal", "copyFromLocal", CompletionType.command.name()), + new InterpreterCompletion("copyToLocal", "copyToLocal", CompletionType.command.name())); List expectedResultNone = new ArrayList<>(); - List<InterpreterCompletion> resultOne = alluxioInterpreter.completion("c", 0); - List<InterpreterCompletion> resultTwo = alluxioInterpreter.completion("co", 0); - List<InterpreterCompletion> resultThree = alluxioInterpreter.completion("copy", 0); - List<InterpreterCompletion> resultNotMatch = alluxioInterpreter.completion("notMatch", 0); - List<InterpreterCompletion> resultAll = alluxioInterpreter.completion("", 0); + List<InterpreterCompletion> resultOne = alluxioInterpreter.completion("c", 0, null); + List<InterpreterCompletion> resultTwo = alluxioInterpreter.completion("co", 0, null); + List<InterpreterCompletion> resultThree = alluxioInterpreter.completion("copy", 0, null); + List<InterpreterCompletion> resultNotMatch = alluxioInterpreter.completion("notMatch", 0, null); + List<InterpreterCompletion> resultAll = alluxioInterpreter.completion("", 0, null); Assert.assertEquals(expectedResultOne, resultOne); Assert.assertEquals(expectedResultTwo, resultTwo); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/angular/src/main/java/org/apache/zeppelin/angular/AngularInterpreter.java ---------------------------------------------------------------------- diff --git a/angular/src/main/java/org/apache/zeppelin/angular/AngularInterpreter.java b/angular/src/main/java/org/apache/zeppelin/angular/AngularInterpreter.java index f8ff350..696e450 100644 --- a/angular/src/main/java/org/apache/zeppelin/angular/AngularInterpreter.java +++ b/angular/src/main/java/org/apache/zeppelin/angular/AngularInterpreter.java @@ -67,7 +67,8 @@ public class AngularInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return new LinkedList<>(); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/beam/src/main/java/org/apache/zeppelin/beam/BeamInterpreter.java ---------------------------------------------------------------------- diff --git a/beam/src/main/java/org/apache/zeppelin/beam/BeamInterpreter.java b/beam/src/main/java/org/apache/zeppelin/beam/BeamInterpreter.java index caa91c3..37ccfae 100644 --- a/beam/src/main/java/org/apache/zeppelin/beam/BeamInterpreter.java +++ b/beam/src/main/java/org/apache/zeppelin/beam/BeamInterpreter.java @@ -92,7 +92,8 @@ public class BeamInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return Collections.emptyList(); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/bigquery/src/main/java/org/apache/zeppelin/bigquery/BigQueryInterpreter.java ---------------------------------------------------------------------- diff --git a/bigquery/src/main/java/org/apache/zeppelin/bigquery/BigQueryInterpreter.java b/bigquery/src/main/java/org/apache/zeppelin/bigquery/BigQueryInterpreter.java index 33e1960..d0c23e5 100644 --- a/bigquery/src/main/java/org/apache/zeppelin/bigquery/BigQueryInterpreter.java +++ b/bigquery/src/main/java/org/apache/zeppelin/bigquery/BigQueryInterpreter.java @@ -332,7 +332,8 @@ public class BigQueryInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return NO_COMPLETION; } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java ---------------------------------------------------------------------- diff --git a/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java b/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java index a4984ad..5eb3a03 100644 --- a/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java +++ b/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java @@ -216,7 +216,8 @@ public class CassandraInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return NO_COMPLETION; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/docs/interpreter/jdbc.md ---------------------------------------------------------------------- diff --git a/docs/interpreter/jdbc.md b/docs/interpreter/jdbc.md index ab31b11..2c1d2f7 100644 --- a/docs/interpreter/jdbc.md +++ b/docs/interpreter/jdbc.md @@ -123,6 +123,11 @@ The JDBC interpreter properties are defined by default like below. <td></td> <td>Some SQL which executes while opening connection</td> </tr> + <tr> + <td>default.completer.schemaFilters</td> + <td></td> + <td>Сomma separated schema (schema = catalog = database) filters to get metadata for completions. Supports '%' symbol is equivalent to any set of characters. (ex. prod_v_%,public%,info)</td> + </tr> </table> If you want to connect other databases such as `Mysql`, `Redshift` and `Hive`, you need to edit the property values. http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java ---------------------------------------------------------------------- diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java index 8c5bc94..33448df 100644 --- a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java +++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java @@ -33,6 +33,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; +import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.elasticsearch.action.ActionResponse; import org.apache.zeppelin.elasticsearch.action.AggWrapper; import org.apache.zeppelin.elasticsearch.action.HitWrapper; @@ -239,12 +240,13 @@ public class ElasticsearchInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String s, int i) { + public List<InterpreterCompletion> completion(String s, int i, + InterpreterContext interpreterContext) { final List suggestions = new ArrayList<>(); for (final String cmd : COMMANDS) { if (cmd.toLowerCase().contains(s)) { - suggestions.add(new InterpreterCompletion(cmd, cmd)); + suggestions.add(new InterpreterCompletion(cmd, cmd, CompletionType.command.name())); } } return suggestions; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java ---------------------------------------------------------------------- diff --git a/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java index aece163..4679f29 100644 --- a/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java +++ b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java @@ -31,6 +31,7 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.lang.math.RandomUtils; +import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.display.AngularObjectRegistry; import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterResult; @@ -305,12 +306,12 @@ public class ElasticsearchInterpreterTest { @Theory public void testCompletion(ElasticsearchInterpreter interpreter) { - final List<InterpreterCompletion> expectedResultOne = Arrays.asList(new InterpreterCompletion("count", "count")); - final List<InterpreterCompletion> expectedResultTwo = Arrays.asList(new InterpreterCompletion("help", "help")); + final List<InterpreterCompletion> expectedResultOne = Arrays.asList(new InterpreterCompletion("count", "count", CompletionType.command.name())); + final List<InterpreterCompletion> expectedResultTwo = Arrays.asList(new InterpreterCompletion("help", "help", CompletionType.command.name())); - final List<InterpreterCompletion> resultOne = interpreter.completion("co", 0); - final List<InterpreterCompletion> resultTwo = interpreter.completion("he", 0); - final List<InterpreterCompletion> resultAll = interpreter.completion("", 0); + final List<InterpreterCompletion> resultOne = interpreter.completion("co", 0, null); + final List<InterpreterCompletion> resultTwo = interpreter.completion("he", 0, null); + final List<InterpreterCompletion> resultAll = interpreter.completion("", 0, null); Assert.assertEquals(expectedResultOne, resultOne); Assert.assertEquals(expectedResultTwo, resultTwo); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java ---------------------------------------------------------------------- diff --git a/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java b/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java index 9aa3605..d7aad19 100644 --- a/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java +++ b/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java @@ -166,7 +166,8 @@ public abstract class FileInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return null; } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java ---------------------------------------------------------------------- diff --git a/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java b/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java index 1b2b01c..c4a1730 100644 --- a/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java +++ b/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java @@ -23,6 +23,8 @@ import java.util.*; import com.google.gson.Gson; import org.apache.commons.lang.StringUtils; +import org.apache.zeppelin.completer.CompletionType; +import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterException; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; @@ -247,21 +249,25 @@ public class HDFSFileInterpreter extends FileInterpreter { @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { logger.info("Completion request at position\t" + cursor + " in string " + buf); final List<InterpreterCompletion> suggestions = new ArrayList<>(); if (StringUtils.isEmpty(buf)) { - suggestions.add(new InterpreterCompletion("ls", "ls")); - suggestions.add(new InterpreterCompletion("cd", "cd")); - suggestions.add(new InterpreterCompletion("pwd", "pwd")); + suggestions.add(new InterpreterCompletion("ls", "ls", CompletionType.command.name())); + suggestions.add(new InterpreterCompletion("cd", "cd", CompletionType.command.name())); + suggestions.add(new InterpreterCompletion("pwd", "pwd", CompletionType.command.name())); return suggestions; } //part of a command == no spaces if (buf.split(" ").length == 1){ - if ("cd".contains(buf)) suggestions.add(new InterpreterCompletion("cd", "cd")); - if ("ls".contains(buf)) suggestions.add(new InterpreterCompletion("ls", "ls")); - if ("pwd".contains(buf)) suggestions.add(new InterpreterCompletion("pwd", "pwd")); + if ("cd".contains(buf)) suggestions.add(new InterpreterCompletion("cd", "cd", + CompletionType.command.name())); + if ("ls".contains(buf)) suggestions.add(new InterpreterCompletion("ls", "ls", + CompletionType.command.name())); + if ("pwd".contains(buf)) suggestions.add(new InterpreterCompletion("pwd", "pwd", + CompletionType.command.name())); return suggestions; } @@ -298,7 +304,8 @@ public class HDFSFileInterpreter extends FileInterpreter { String beforeLastPeriod = unfinished.substring(0, unfinished.lastIndexOf('.') + 1); //beforeLastPeriod should be the start of fs.pathSuffix, so take the end of it. String suggestedFinish = fs.pathSuffix.substring(beforeLastPeriod.length()); - suggestions.add(new InterpreterCompletion(suggestedFinish, suggestedFinish)); + suggestions.add(new InterpreterCompletion(suggestedFinish, suggestedFinish, + CompletionType.path.name())); } } return suggestions; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/file/src/test/java/org/apache/zeppelin/file/HDFSFileInterpreterTest.java ---------------------------------------------------------------------- diff --git a/file/src/test/java/org/apache/zeppelin/file/HDFSFileInterpreterTest.java b/file/src/test/java/org/apache/zeppelin/file/HDFSFileInterpreterTest.java index fe6697d..335693f 100644 --- a/file/src/test/java/org/apache/zeppelin/file/HDFSFileInterpreterTest.java +++ b/file/src/test/java/org/apache/zeppelin/file/HDFSFileInterpreterTest.java @@ -21,6 +21,8 @@ package org.apache.zeppelin.file; import com.google.gson.Gson; import junit.framework.TestCase; import static org.junit.Assert.*; + +import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.interpreter.InterpreterResult; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; import org.junit.Test; @@ -106,11 +108,11 @@ public class HDFSFileInterpreterTest extends TestCase { // auto completion test List expectedResultOne = Arrays.asList( - new InterpreterCompletion("ls", "ls")); + new InterpreterCompletion("ls", "ls", CompletionType.command.name())); List expectedResultTwo = Arrays.asList( - new InterpreterCompletion("pwd", "pwd")); - List<InterpreterCompletion> resultOne = t.completion("l", 0); - List<InterpreterCompletion> resultTwo = t.completion("p", 0); + new InterpreterCompletion("pwd", "pwd", CompletionType.command.name())); + List<InterpreterCompletion> resultOne = t.completion("l", 0, null); + List<InterpreterCompletion> resultTwo = t.completion("p", 0, null); assertEquals(expectedResultOne, resultOne); assertEquals(expectedResultTwo, resultTwo); http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java ---------------------------------------------------------------------- diff --git a/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java b/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java index 8b9b4ec..91ffb9c 100644 --- a/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java +++ b/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java @@ -373,7 +373,8 @@ public class FlinkInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return new LinkedList<>(); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/geode/src/main/java/org/apache/zeppelin/geode/GeodeOqlInterpreter.java ---------------------------------------------------------------------- diff --git a/geode/src/main/java/org/apache/zeppelin/geode/GeodeOqlInterpreter.java b/geode/src/main/java/org/apache/zeppelin/geode/GeodeOqlInterpreter.java index b6c3faa..1825008 100644 --- a/geode/src/main/java/org/apache/zeppelin/geode/GeodeOqlInterpreter.java +++ b/geode/src/main/java/org/apache/zeppelin/geode/GeodeOqlInterpreter.java @@ -282,7 +282,8 @@ public class GeodeOqlInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return null; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java ---------------------------------------------------------------------- diff --git a/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java b/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java index 6c2460d..74d3ed1 100644 --- a/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java +++ b/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java @@ -145,7 +145,8 @@ public class HbaseInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return null; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java ---------------------------------------------------------------------- diff --git a/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java b/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java index 07b6326..7d1c361 100644 --- a/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java +++ b/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java @@ -98,7 +98,8 @@ public class DevInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return new LinkedList<>(); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteInterpreter.java ---------------------------------------------------------------------- diff --git a/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteInterpreter.java b/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteInterpreter.java index 0b022fa..ac385ea 100644 --- a/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteInterpreter.java +++ b/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteInterpreter.java @@ -331,7 +331,8 @@ public class IgniteInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return new LinkedList<>(); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java ---------------------------------------------------------------------- diff --git a/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java b/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java index 03ea4f8..41803bb 100644 --- a/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java +++ b/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java @@ -184,7 +184,8 @@ public class IgniteSqlInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { return new LinkedList<>(); } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/jdbc/pom.xml ---------------------------------------------------------------------- diff --git a/jdbc/pom.xml b/jdbc/pom.xml index e34be89..71d3310 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -35,7 +35,6 @@ <properties> <!--library versions--> <postgresql.version>9.4-1201-jdbc41</postgresql.version> - <jline.version>2.12.1</jline.version> <hadoop.common.version>2.7.2</hadoop.common.version> <h2.version>1.4.190</h2.version> <commons.dbcp2.version>2.0.1</commons.dbcp2.version> @@ -68,17 +67,6 @@ <artifactId>slf4j-log4j12</artifactId> </dependency> - <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - </dependency> - - <dependency> - <groupId>jline</groupId> - <artifactId>jline</artifactId> - <version>${jline.version}</version> - </dependency> - <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java ---------------------------------------------------------------------- diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java index 2e35e81..ff3d3cf 100644 --- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java +++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java @@ -57,9 +57,7 @@ import org.apache.zeppelin.user.UsernamePassword; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Function; import com.google.common.base.Throwables; -import com.google.common.collect.Lists; import static org.apache.commons.lang.StringUtils.containsIgnoreCase; import static org.apache.commons.lang.StringUtils.isEmpty; @@ -103,6 +101,7 @@ public class JDBCInterpreter extends Interpreter { static final String USER_KEY = "user"; static final String PASSWORD_KEY = "password"; static final String PRECODE_KEY = "precode"; + static final String COMPLETER_SCHEMA_FILTERS_KEY = "completer.schemaFilters"; static final String JDBC_JCEKS_FILE = "jceks.file"; static final String JDBC_JCEKS_CREDENTIAL_KEY = "jceks.credentialKey"; static final String PRECODE_KEY_TEMPLATE = "%s.precode"; @@ -130,22 +129,12 @@ public class JDBCInterpreter extends Interpreter { private final HashMap<String, Properties> basePropretiesMap; private final HashMap<String, JDBCUserConfigurations> jdbcUserConfigurationsMap; - private final Map<String, SqlCompleter> propertyKeySqlCompleterMap; - private static final Function<CharSequence, InterpreterCompletion> sequenceToStringTransformer = - new Function<CharSequence, InterpreterCompletion>() { - public InterpreterCompletion apply(CharSequence seq) { - return new InterpreterCompletion(seq.toString(), seq.toString()); - } - }; - - private static final List<InterpreterCompletion> NO_COMPLETION = new ArrayList<>(); private int maxLineResults; public JDBCInterpreter(Properties property) { super(property); jdbcUserConfigurationsMap = new HashMap<>(); - propertyKeySqlCompleterMap = new HashMap<>(); basePropretiesMap = new HashMap<>(); maxLineResults = MAX_LINE_DEFAULT; } @@ -193,9 +182,7 @@ public class JDBCInterpreter extends Interpreter { if (!isEmpty(property.getProperty("zeppelin.jdbc.auth.type"))) { JDBCSecurityImpl.createSecureConfiguration(property); } - for (String propertyKey : basePropretiesMap.keySet()) { - propertyKeySqlCompleterMap.put(propertyKey, createSqlCompleter(null)); - } + setMaxLineResults(); } @@ -206,10 +193,11 @@ public class JDBCInterpreter extends Interpreter { } } - private SqlCompleter createSqlCompleter(Connection jdbcConnection) { - + private SqlCompleter createSqlCompleter(Connection jdbcConnection, String propertyKey) { + String schemaFiltersKey = String.format("%s.%s", propertyKey, COMPLETER_SCHEMA_FILTERS_KEY); + String filters = getProperty(schemaFiltersKey); SqlCompleter completer = new SqlCompleter(); - completer.initFromConnection(jdbcConnection, ""); + completer.initFromConnection(jdbcConnection, filters); return completer; } @@ -425,7 +413,7 @@ public class JDBCInterpreter extends Interpreter { connection = getConnectionFromPool(url, user, propertyKey, properties); } } - propertyKeySqlCompleterMap.put(propertyKey, createSqlCompleter(connection)); + return connection; } @@ -794,18 +782,26 @@ public class JDBCInterpreter extends Interpreter { } @Override - public List<InterpreterCompletion> completion(String buf, int cursor) { - List<CharSequence> candidates = new ArrayList<>(); - SqlCompleter sqlCompleter = propertyKeySqlCompleterMap.get(getPropertyKey(buf)); - // It's strange but here cursor comes with additional +1 (even if buf is "" cursor = 1) - if (sqlCompleter != null && sqlCompleter.complete(buf, cursor - 1, candidates) >= 0) { - List<InterpreterCompletion> completion; - completion = Lists.transform(candidates, sequenceToStringTransformer); - - return completion; - } else { - return NO_COMPLETION; + public List<InterpreterCompletion> completion(String buf, int cursor, + InterpreterContext interpreterContext) { + List<InterpreterCompletion> candidates = new ArrayList<>(); + String propertyKey = getPropertyKey(buf); + Connection connection = null; + try { + if (interpreterContext != null) { + connection = getConnection(propertyKey, interpreterContext); + } + } catch (ClassNotFoundException | SQLException | IOException e) { + logger.warn("SQLCompleter will created without use connection"); } + + SqlCompleter sqlCompleter = createSqlCompleter(connection, propertyKey); + + if (sqlCompleter != null) { + sqlCompleter.complete(buf, cursor - 1, candidates); + } + + return candidates; } public int getMaxResult() { http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java ---------------------------------------------------------------------- diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java index bf2a25e..704ec59 100644 --- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java +++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java @@ -4,15 +4,6 @@ package org.apache.zeppelin.jdbc; * This source file is based on code taken from SQLLine 1.0.2 See SQLLine notice in LICENSE */ -import com.google.common.base.Joiner; -import com.google.common.collect.Sets; -import com.google.common.collect.Sets.SetView; -import jline.console.completer.ArgumentCompleter.ArgumentList; -import jline.console.completer.ArgumentCompleter.WhitespaceArgumentDelimiter; -import jline.console.completer.StringsCompleter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -20,15 +11,34 @@ import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeSet; import java.util.regex.Pattern; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.apache.zeppelin.completer.CompletionType; +import org.apache.zeppelin.completer.StringsCompleter; +import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jline.console.completer.ArgumentCompleter.ArgumentList; +import jline.console.completer.ArgumentCompleter.WhitespaceArgumentDelimiter; + import static org.apache.commons.lang.StringUtils.isBlank; /** * SQL auto complete functionality for the JdbcInterpreter. */ -public class SqlCompleter extends StringsCompleter { +public class SqlCompleter { private static Logger logger = LoggerFactory.getLogger(SqlCompleter.class); @@ -67,8 +77,7 @@ public class SqlCompleter extends StringsCompleter { */ private StringsCompleter keywordCompleter = new StringsCompleter(); - @Override - public int complete(String buffer, int cursor, List<CharSequence> candidates) { + public int complete(String buffer, int cursor, List<InterpreterCompletion> candidates) { logger.debug("Complete with buffer = " + buffer + ", cursor = " + cursor); @@ -76,21 +85,36 @@ public class SqlCompleter extends StringsCompleter { // white spaces. ArgumentList argumentList = sqlDelimiter.delimit(buffer, cursor); - String beforeCursorBuffer = buffer.substring(0, - Math.min(cursor, buffer.length())).toUpperCase(); + Pattern whitespaceEndPatter = Pattern.compile("\\s$"); + String cursorArgument = null; + int argumentPosition; + if (buffer.length() == 0 || whitespaceEndPatter.matcher(buffer).find()) { + argumentPosition = buffer.length() - 1; + } else { + cursorArgument = argumentList.getCursorArgument(); + argumentPosition = argumentList.getArgumentPosition(); + } - // check what sql is and where cursor is to allow column completion or not boolean isColumnAllowed = true; - if (beforeCursorBuffer.contains("SELECT ") && beforeCursorBuffer.contains(" FROM ") - && !beforeCursorBuffer.contains(" WHERE ")) - isColumnAllowed = false; + if (buffer.length() > 0) { + String beforeCursorBuffer = buffer.substring(0, + Math.min(cursor, buffer.length())).toUpperCase(); + // check what sql is and where cursor is to allow column completion or not + if (beforeCursorBuffer.contains("SELECT ") && beforeCursorBuffer.contains(" FROM ") + && !beforeCursorBuffer.contains(" WHERE ")) + isColumnAllowed = false; + } - int complete = completeName(argumentList.getCursorArgument(), - argumentList.getArgumentPosition(), candidates, + int complete = completeName(cursorArgument, argumentPosition, candidates, findAliasesInSQL(argumentList.getArguments()), isColumnAllowed); + if (candidates.size() == 1) { + InterpreterCompletion interpreterCompletion = candidates.get(0); + interpreterCompletion.setName(interpreterCompletion.getName() + " "); + interpreterCompletion.setValue(interpreterCompletion.getValue() + " "); + candidates.set(0, interpreterCompletion); + } logger.debug("complete:" + complete + ", size:" + candidates.size()); - return complete; } @@ -98,24 +122,26 @@ public class SqlCompleter extends StringsCompleter { * Return list of schema names within the database * * @param meta metadata from connection to database - * @param schemaFilter a schema name pattern; must match the schema name + * @param schemaFilters a schema name patterns; must match the schema name * as it is stored in the database; "" retrieves those without a schema; * <code>null</code> means that the schema name should not be used to narrow - * the search; supports '%' and '_' symbols; for example "prod_v_%" + * the search; supports '%'; for example "prod_v_%" * @return set of all schema names in the database */ - private static Set<String> getSchemaNames(DatabaseMetaData meta, String schemaFilter) { + private static Set<String> getSchemaNames(DatabaseMetaData meta, List<String> schemaFilters) { Set<String> res = new HashSet<>(); try { ResultSet schemas = meta.getSchemas(); try { while (schemas.next()) { String schemaName = schemas.getString("TABLE_SCHEM"); - if (schemaName == null) + if (schemaName == null) { schemaName = ""; - if (schemaFilter.equals("") || schemaFilter == null || schemaName.matches( - schemaFilter.replace("_", ".").replace("%", ".*?"))) { - res.add(schemaName); + } + for (String schemaFilter : schemaFilters) { + if (schemaFilter.equals("") || schemaName.matches(schemaFilter.replace("%", ".*?"))) { + res.add(schemaName); + } } } } finally { @@ -131,22 +157,23 @@ public class SqlCompleter extends StringsCompleter { * Return list of catalog names within the database * * @param meta metadata from connection to database - * @param schemaFilter a catalog name pattern; must match the catalog name + * @param schemaFilters a catalog name patterns; must match the catalog name * as it is stored in the database; "" retrieves those without a catalog; * <code>null</code> means that the schema name should not be used to narrow - * the search; supports '%' and '_' symbols; for example "prod_v_%" + * the search; supports '%'; for example "prod_v_%" * @return set of all catalog names in the database */ - private static Set<String> getCatalogNames(DatabaseMetaData meta, String schemaFilter) { + private static Set<String> getCatalogNames(DatabaseMetaData meta, List<String> schemaFilters) { Set<String> res = new HashSet<>(); try { ResultSet schemas = meta.getCatalogs(); try { while (schemas.next()) { String schemaName = schemas.getString("TABLE_CAT"); - if (schemaFilter.equals("") || schemaFilter == null || schemaName.matches( - schemaFilter.replace("_", ".").replace("%", ".*?"))) { - res.add(schemaName); + for (String schemaFilter : schemaFilters) { + if (schemaFilter.equals("") || schemaName.matches(schemaFilter.replace("%", ".*?"))) { + res.add(schemaName); + } } } } finally { @@ -166,7 +193,7 @@ public class SqlCompleter extends StringsCompleter { * @param schemaFilter a schema name pattern; must match the schema name * as it is stored in the database; "" retrieves those without a schema; * <code>null</code> means that the schema name should not be used to narrow - * the search; supports '%' and '_' symbols; for example "prod_v_%" + * the search; supports '%'; for example "prod_v_%" * @param tables function fills this map, for every schema name adds * set of table names within the schema * @param columns function fills this map, for every table name adds set @@ -177,19 +204,27 @@ public class SqlCompleter extends StringsCompleter { Map<String, Set<String>> tables, Map<String, Set<String>> columns) { try { - ResultSet cols = meta.getColumns(catalogName, schemaFilter, "%", - "%"); + ResultSet cols = meta.getColumns(catalogName, StringUtils.EMPTY, "%", "%"); try { while (cols.next()) { String schema = cols.getString("TABLE_SCHEM"); - if (schema == null) schema = cols.getString("TABLE_CAT"); + if (schema == null) { + schema = cols.getString("TABLE_CAT"); + } + if (!schemaFilter.equals("") && !schema.matches(schemaFilter.replace("%", ".*?"))) { + continue; + } String table = cols.getString("TABLE_NAME"); String column = cols.getString("COLUMN_NAME"); if (!isBlank(table)) { String schemaTable = schema + "." + table; - if (!columns.containsKey(schemaTable)) columns.put(schemaTable, new HashSet<String>()); + if (!columns.containsKey(schemaTable)) { + columns.put(schemaTable, new HashSet<String>()); + } columns.get(schemaTable).add(column); - if (!tables.containsKey(schema)) tables.put(schema, new HashSet<String>()); + if (!tables.containsKey(schema)) { + tables.put(schema, new HashSet<String>()); + } tables.get(schema).add(table); } } @@ -327,33 +362,31 @@ public class SqlCompleter extends StringsCompleter { * Initializes all local completers from database connection * * @param connection database connection - * @param schemaFilter a schema name pattern; must match the schema name - * as it is stored in the database; "" retrieves those without a schema; - * <code>null</code> means that the schema name should not be used to narrow - * the search; supports '%' and '_' symbols; for example "prod_v_%" + * @param schemaFiltersString a comma separated schema name patterns; supports '%' symbol; + * for example "prod_v_%,prod_t_%" */ - public void initFromConnection(Connection connection, String schemaFilter) { + public void initFromConnection(Connection connection, String schemaFiltersString) { + if (schemaFiltersString == null) { + schemaFiltersString = StringUtils.EMPTY; + } + List<String> schemaFilters = Arrays.asList(schemaFiltersString.split(",")); - try { + try (Connection c = connection) { Map<String, Set<String>> tables = new HashMap<>(); Map<String, Set<String>> columns = new HashMap<>(); Set<String> schemas = new HashSet<>(); Set<String> catalogs = new HashSet<>(); Set<String> keywords = getSqlKeywordsCompletions(connection); if (connection != null) { - schemas = getSchemaNames(connection.getMetaData(), schemaFilter); - catalogs = getCatalogNames(connection.getMetaData(), schemaFilter); - - if (!"".equals(connection.getCatalog())) { - if (schemas.size() == 0 ) - schemas.add(connection.getCatalog()); - fillTableAndColumnNames(connection.getCatalog(), connection.getMetaData(), schemaFilter, - tables, columns); - } else { - if (schemas.size() == 0) schemas.addAll(catalogs); - for (String catalog : catalogs) { - fillTableAndColumnNames(catalog, connection.getMetaData(), schemaFilter, tables, - columns); + schemas = getSchemaNames(connection.getMetaData(), schemaFilters); + catalogs = getCatalogNames(connection.getMetaData(), schemaFilters); + if (schemas.size() == 0) { + schemas.addAll(catalogs); + } + for (String schema : schemas) { + for (String schemaFilter : schemaFilters) { + fillTableAndColumnNames(schema, connection.getMetaData(), schemaFilter, tables, + columns); } } } @@ -408,8 +441,18 @@ public class SqlCompleter extends StringsCompleter { */ private int completeTable(String schema, String buffer, int cursor, List<CharSequence> candidates) { + if (schema == null) { + int res = -1; + Set<CharSequence> candidatesSet = new HashSet<>(); + for (StringsCompleter stringsCompleter : tablesCompleters.values()) { + int resTable = stringsCompleter.complete(buffer, cursor, candidatesSet); + res = Math.max(res, resTable); + } + candidates.addAll(candidatesSet); + return res; + } // Wrong schema - if (!tablesCompleters.containsKey(schema)) + if (!tablesCompleters.containsKey(schema) && schema != null) return -1; else return tablesCompleters.get(schema).complete(buffer, cursor, candidates); @@ -422,12 +465,23 @@ public class SqlCompleter extends StringsCompleter { */ private int completeColumn(String schema, String table, String buffer, int cursor, List<CharSequence> candidates) { + if (table == null && schema == null) { + int res = -1; + Set<CharSequence> candidatesSet = new HashSet<>(); + for (StringsCompleter stringsCompleter : columnsCompleters.values()) { + int resColumn = stringsCompleter.complete(buffer, cursor, candidatesSet); + res = Math.max(res, resColumn); + } + candidates.addAll(candidatesSet); + return res; + } // Wrong schema or wrong table if (!tablesCompleters.containsKey(schema) || - !columnsCompleters.containsKey(schema + "." + table)) + !columnsCompleters.containsKey(schema + "." + table)) { return -1; - else + } else { return columnsCompleters.get(schema + "." + table).complete(buffer, cursor, candidates); + } } /** @@ -438,32 +492,43 @@ public class SqlCompleter extends StringsCompleter { * @param isColumnAllowed if false the function will not search and complete columns * @return -1 in case of no candidates found, 0 otherwise */ - public int completeName(String buffer, int cursor, List<CharSequence> candidates, + public int completeName(String buffer, int cursor, List<InterpreterCompletion> candidates, Map<String, String> aliases, boolean isColumnAllowed) { - if (buffer == null) buffer = ""; - - // no need to process after first point after cursor - int nextPointPos = buffer.indexOf('.', cursor); - if (nextPointPos != -1) buffer = buffer.substring(0, nextPointPos); - // points divide the name to the schema, table and column - find them - int pointPos1 = buffer.indexOf('.'); - int pointPos2 = buffer.indexOf('.', pointPos1 + 1); + int pointPos1 = -1; + int pointPos2 = -1; + if (StringUtils.isNotEmpty(buffer)) { + if (buffer.length() > cursor) { + buffer = buffer.substring(0, cursor + 1); + } + pointPos1 = buffer.indexOf('.'); + pointPos2 = buffer.indexOf('.', pointPos1 + 1); + } // find schema and table name if they are String schema; String table; String column; - if (pointPos1 == -1) { // process only schema or keyword case - schema = buffer; - int keywordsRes = completeKeyword(buffer, cursor, candidates); + + if (pointPos1 == -1) { // process all + List<CharSequence> keywordsCandidates = new ArrayList(); List<CharSequence> schemaCandidates = new ArrayList<>(); - int schemaRes = completeSchema(schema, cursor, schemaCandidates); - candidates.addAll(schemaCandidates); - return Math.max(keywordsRes, schemaRes); - } - else { + List<CharSequence> tableCandidates = new ArrayList<>(); + List<CharSequence> columnCandidates = new ArrayList<>(); + int keywordsRes = completeKeyword(buffer, cursor, keywordsCandidates); + int schemaRes = completeSchema(buffer, cursor, schemaCandidates); + int tableRes = completeTable(null, buffer, cursor, tableCandidates); + int columnRes = -1; + if (isColumnAllowed) { + columnRes = completeColumn(null, null, buffer, cursor, columnCandidates); + } + addCompletions(candidates, keywordsCandidates, CompletionType.keyword.name()); + addCompletions(candidates, schemaCandidates, CompletionType.schema.name()); + addCompletions(candidates, tableCandidates, CompletionType.table.name()); + addCompletions(candidates, columnCandidates, CompletionType.column.name()); + return NumberUtils.max(new int[]{keywordsRes, schemaRes, tableRes, columnRes}); + } else { schema = buffer.substring(0, pointPos1); if (aliases.containsKey(schema)) { // process alias case String alias = aliases.get(schema); @@ -471,26 +536,40 @@ public class SqlCompleter extends StringsCompleter { schema = alias.substring(0, pointPos); table = alias.substring(pointPos + 1); column = buffer.substring(pointPos1 + 1); - } - else if (pointPos2 == -1) { // process schema.table case + } else if (pointPos2 == -1) { // process schema.table case + List<CharSequence> tableCandidates = new ArrayList(); table = buffer.substring(pointPos1 + 1); - return completeTable(schema, table, cursor - pointPos1 - 1, candidates); - } - else { + int tableRes = completeTable(schema, table, cursor - pointPos1 - 1, tableCandidates); + addCompletions(candidates, tableCandidates, CompletionType.table.name()); + return tableRes; + } else { table = buffer.substring(pointPos1 + 1, pointPos2); column = buffer.substring(pointPos2 + 1); } } // here in case of column - if (isColumnAllowed) - return completeColumn(schema, table, column, cursor - pointPos2 - 1, candidates); - else - return -1; + if (table != null && isColumnAllowed) { + List<CharSequence> columnCandidates = new ArrayList(); + int columnRes = completeColumn(schema, table, column, cursor - pointPos2 - 1, + columnCandidates); + addCompletions(candidates, columnCandidates, CompletionType.column.name()); + return columnRes; + } + + return -1; } // test purpose only WhitespaceArgumentDelimiter getSqlDelimiter() { return this.sqlDelimiter; } + + private void addCompletions(List<InterpreterCompletion> interpreterCompletions, + List<CharSequence> candidates, String meta) { + for (CharSequence candidate : candidates) { + interpreterCompletions.add(new InterpreterCompletion(candidate.toString(), + candidate.toString(), meta)); + } + } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/jdbc/src/main/resources/ansi.sql.keywords ---------------------------------------------------------------------- diff --git a/jdbc/src/main/resources/ansi.sql.keywords b/jdbc/src/main/resources/ansi.sql.keywords index 1f25a81..35b4bcb 100644 --- a/jdbc/src/main/resources/ansi.sql.keywords +++ b/jdbc/src/main/resources/ansi.sql.keywords @@ -1 +1 @@ -ABSOLUTE,ACTION,ADD,ALL,ALLOCATE,ALTER,AND,ANY,ARE,AS,ASC,ASSERTION,AT,AUTHORIZATION,AVG,BEGIN,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,CATALOG,CHAR,CHARACTER,CHAR_LENGTH,CHARACTER_LENGTH,CHECK,CLOSE,CLUSTER,COALESCE,COLLATE,COLLATION,COLUMN,COMMIT,CONNECT,CONNECTION,CONSTRAINT,CONSTRAINTS,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CURRENT,CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,DATE,DAY,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,DEFERRED,DELETE,DESC,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,DISCONNECT,DISTINCT,DOMAIN,DOUBLE,DROP,ELSE,END,END-EXEC,ESCAPE,EXCEPT,EXCEPTION,EXEC,EXECUTE,EXISTS,EXTERNAL,EXTRACT,FALSE,FETCH,FIRST,FLOAT,FOR,FOREIGN,FOUND,FROM,FULL,GET,GLOBAL,GO,GOTO,GRANT,GROUP,HAVING,HOUR,IDENTITY,IMMEDIATE,IN,INDICATOR,INITIALLY,INNER,INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,JOIN,KEY,LANGUAGE,LAST,LEADING,LEFT,LEVEL,LIKE,LOCAL,LOWER,MATCH,MAX,MIN,MINUTE,MODULE,MONTH,NAMES,NATIONAL,NATURAL,NCHA R,NEXT,NO,NOT,NULL,NULLIF,NUMERIC,OCTET_LENGTH,OF,ON,ONLY,OPEN,OPTION,OR,ORDER,OUTER,OUTPUT,OVERLAPS,OVERWRITE,PAD,PARTIAL,PARTITION,POSITION,PRECISION,PREPARE,PRESERVE,PRIMARY,PRIOR,PRIVILEGES,PROCEDURE,PUBLIC,READ,REAL,REFERENCES,RELATIVE,RESTRICT,REVOKE,RIGHT,ROLLBACK,ROWS,SCHEMA,SCROLL,SECOND,SECTION,SELECT,SESSION,SESSION_USER,SET,SIZE,SMALLINT,SOME,SPACE,SQL,SQLCODE,SQLERROR,SQLSTATE,SUBSTRING,SUM,SYSTEM_USER,TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,TO,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,TRUE,UNION,UNIQUE,UNKNOWN,UPDATE,UPPER,USAGE,USER,USING,VALUE,VALUES,VARCHAR,VARYING,VIEW,WHEN,WHENEVER,WHERE,WITH,WORK,WRITE,YEAR,ZONE,ADA,C,CATALOG_NAME,CHARACTER_SET_CATALOG,CHARACTER_SET_NAME,CHARACTER_SET_SCHEMA,CLASS_ORIGIN,COBOL,COLLATION_CATALOG,COLLATION_NAME,COLLATION_SCHEMA,COLUMN_NAME,COMMAND_FUNCTION,COMMITTED,CONDITION_NUMBER,CONNECTION_NAME,CONSTRAINT_CATALOG,CONSTRAINT_NAME,CONSTRAINT_SCHEMA,CURSOR_NAME,DATA,DATETIME_INTERVAL_CODE,DATETIME_I NTERVAL_PRECISION,DYNAMIC_FUNCTION,FORTRAN,LENGTH,MESSAGE_LENGTH,MESSAGE_OCTET_LENGTH,MESSAGE_TEXT,MORE,MUMPS,NAME,NULLABLE,NUMBER,PASCAL,PLI,REPEATABLE,RETURNED_LENGTH,RETURNED_OCTET_LENGTH,RETURNED_SQLSTATE,ROW_COUNT,SCALE,SCHEMA_NAME,SERIALIZABLE,SERVER_NAME,SUBCLASS_ORIGIN,TABLE_NAME,TYPE,UNCOMMITTED,UNNAMED,LIMIT +absolute,action,add,all,allocate,alter,and,any,are,as,asc,assertion,at,authorization,avg,begin,between,bit,bit_length,both,by,cascade,cascaded,case,cast,catalog,char,character,char_length,character_length,check,close,cluster,coalesce,collate,collation,column,commit,connect,connection,constraint,constraints,continue,convert,corresponding,count,create,cross,current,current_date,current_time,current_timestamp,current_user,cursor,date,day,deallocate,dec,decimal,declare,default,deferrable,deferred,delete,desc,describe,descriptor,diagnostics,disconnect,distinct,domain,double,drop,else,end,end-exec,escape,except,exception,exec,execute,exists,external,extract,false,fetch,first,float,for,foreign,found,from,full,get,global,go,goto,grant,group,having,hour,identity,immediate,in,indicator,initially,inner,input,insensitive,insert,int,integer,intersect,interval,into,is,isolation,join,key,language,last,leading,left,level,like,local,lower,match,max,min,minute,module,month,names,national,natural,ncha r,next,no,not,null,nullif,numeric,octet_length,of,on,only,open,option,or,order,outer,output,overlaps,overwrite,pad,partial,partition,position,precision,prepare,preserve,primary,prior,privileges,procedure,public,read,real,references,relative,restrict,revoke,right,rollback,rows,schema,scroll,second,section,select,session,session_user,set,size,smallint,some,space,sql,sqlcode,sqlerror,sqlstate,substring,sum,system_user,table,temporary,then,time,timestamp,timezone_hour,timezone_minute,to,trailing,transaction,translate,translation,trim,true,union,unique,unknown,update,upper,usage,user,using,value,values,varchar,varying,view,when,whenever,where,with,work,write,year,zone,ada,c,catalog_name,character_set_catalog,character_set_name,character_set_schema,class_origin,cobol,collation_catalog,collation_name,collation_schema,column_name,command_function,committed,condition_number,connection_name,constraint_catalog,constraint_name,constraint_schema,cursor_name,data,datetime_interval_code,datetime_i nterval_precision,dynamic_function,fortran,length,message_length,message_octet_length,message_text,more,mumps,name,nullable,number,pascal,pli,repeatable,returned_length,returned_octet_length,returned_sqlstate,row_count,scale,schema_name,serializable,server_name,subclass_origin,table_name,type,uncommitted,unnamed,limit http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/jdbc/src/main/resources/interpreter-setting.json ---------------------------------------------------------------------- diff --git a/jdbc/src/main/resources/interpreter-setting.json b/jdbc/src/main/resources/interpreter-setting.json index 322ea5a..fb8b8b2 100644 --- a/jdbc/src/main/resources/interpreter-setting.json +++ b/jdbc/src/main/resources/interpreter-setting.json @@ -28,6 +28,12 @@ "defaultValue": "org.postgresql.Driver", "description": "JDBC Driver Name" }, + "default.completer.schemaFilters": { + "envName": null, + "propertyName": "default.completer.schemaFilters", + "defaultValue": "", + "description": "Сomma separated schema (schema = catalog = database) filters to get metadata for completions. Supports '%' symbol is equivalent to any set of characters. (ex. prod_v_%,public%,info)" + }, "default.precode": { "envName": null, "propertyName": "zeppelin.jdbc.precode", http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/jdbc/src/main/resources/postgresql-native-driver-sql.keywords ---------------------------------------------------------------------- diff --git a/jdbc/src/main/resources/postgresql-native-driver-sql.keywords b/jdbc/src/main/resources/postgresql-native-driver-sql.keywords index a857cbd..bcd00c8 100644 --- a/jdbc/src/main/resources/postgresql-native-driver-sql.keywords +++ b/jdbc/src/main/resources/postgresql-native-driver-sql.keywords @@ -1 +1 @@ -A,ABORT,ABS,ABSENT,ABSOLUTE,ACCESS,ACCORDING,ACTION,ADA,ADD,ADMIN,AFTER,AGGREGATE,ALL,ALLOCATE,ALSO,ALTER,ALWAYS,ANALYSE,ANALYZE,AND,ANY,ARE,ARRAY,ARRAY_AGG,ARRAY_MAX_CARDINALITY,AS,ASC,ASENSITIVE,ASSERTION,ASSIGNMENT,ASYMMETRIC,AT,ATOMIC,ATTRIBUTE,ATTRIBUTES,AUTHORIZATION,AVG,BACKWARD,BASE64,BEFORE,BEGIN,BEGIN_FRAME,BEGIN_PARTITION,BERNOULLI,BETWEEN,BIGINT,BINARY,BIT,BIT_LENGTH,BLOB,BLOCKED,BOM,BOOLEAN,BOTH,BREADTH,BY,C,CACHE,CALL,CALLED,CARDINALITY,CASCADE,CASCADED,CASE,CAST,CATALOG,CATALOG_NAME,CEIL,CEILING,CHAIN,CHAR,CHARACTER,CHARACTERISTICS,CHARACTERS,CHARACTER_LENGTH,CHARACTER_SET_CATALOG,CHARACTER_SET_NAME,CHARACTER_SET_SCHEMA,CHAR_LENGTH,CHECK,CHECKPOINT,CLASS,CLASS_ORIGIN,CLOB,CLOSE,CLUSTER,COALESCE,COBOL,COLLATE,COLLATION,COLLATION_CATALOG,COLLATION_NAME,COLLATION_SCHEMA,COLLECT,COLUMN,COLUMNS,COLUMN_NAME,COMMAND_FUNCTION,COMMAND_FUNCTION_CODE,COMMENT,COMMENTS,COMMIT,COMMITTED,CONCURRENTLY,CONDITION,CONDITION_NUMBER,CONFIGURATION,CONNECT,CONNECTION,CONNECTION_NAME,CONSTRA INT,CONSTRAINTS,CONSTRAINT_CATALOG,CONSTRAINT_NAME,CONSTRAINT_SCHEMA,CONSTRUCTOR,CONTAINS,CONTENT,CONTINUE,CONTROL,CONVERSION,CONVERT,COPY,CORR,CORRESPONDING,COST,COUNT,COVAR_POP,COVAR_SAMP,CREATE,CROSS,CSV,CUBE,CUME_DIST,CURRENT,CURRENT_CATALOG,CURRENT_DATE,CURRENT_DEFAULT_TRANSFORM_GROUP,CURRENT_PATH,CURRENT_ROLE,CURRENT_ROW,CURRENT_SCHEMA,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_TRANSFORM_GROUP_FOR_TYPE,CURRENT_USER,CURSOR,CURSOR_NAME,CYCLE,DATA,DATABASE,DATALINK,DATE,DATETIME_INTERVAL_CODE,DATETIME_INTERVAL_PRECISION,DAY,DB,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFAULTS,DEFERRABLE,DEFERRED,DEFINED,DEFINER,DEGREE,DELETE,DELIMITER,DELIMITERS,DENSE_RANK,DEPTH,DEREF,DERIVED,DESC,DESCRIBE,DESCRIPTOR,DETERMINISTIC,DIAGNOSTICS,DICTIONARY,DISABLE,DISCARD,DISCONNECT,DISPATCH,DISTINCT,DLNEWCOPY,DLPREVIOUSCOPY,DLURLCOMPLETE,DLURLCOMPLETEONLY,DLURLCOMPLETEWRITE,DLURLPATH,DLURLPATHONLY,DLURLPATHWRITE,DLURLSCHEME,DLURLSERVER,DLVALUE,DO,DOCUMENT,DOMAIN,DOUBLE,DROP,DYNAMIC,DYNAMIC_FUNCTION,DYNAM IC_FUNCTION_CODE,EACH,ELEMENT,ELSE,EMPTY,ENABLE,ENCODING,ENCRYPTED,END,END-EXEC,END_FRAME,END_PARTITION,ENFORCED,ENUM,EQUALS,ESCAPE,EVENT,EVERY,EXCEPT,EXCEPTION,EXCLUDE,EXCLUDING,EXCLUSIVE,EXEC,EXECUTE,EXISTS,EXP,EXPLAIN,EXPRESSION,EXTENSION,EXTERNAL,EXTRACT,FALSE,FAMILY,FETCH,FILE,FILTER,FINAL,FIRST,FIRST_VALUE,FLAG,FLOAT,FLOOR,FOLLOWING,FOR,FORCE,FOREIGN,FORTRAN,FORWARD,FOUND,FRAME_ROW,FREE,FREEZE,FROM,FS,FULL,FUNCTION,FUNCTIONS,FUSION,G,GENERAL,GENERATED,GET,GLOBAL,GO,GOTO,GRANT,GRANTED,GREATEST,GROUP,GROUPING,GROUPS,HANDLER,HAVING,HEADER,HEX,HIERARCHY,HOLD,HOUR,ID,IDENTITY,IF,IGNORE,ILIKE,IMMEDIATE,IMMEDIATELY,IMMUTABLE,IMPLEMENTATION,IMPLICIT,IMPORT,IN,INCLUDING,INCREMENT,INDENT,INDEX,INDEXES,INDICATOR,INHERIT,INHERITS,INITIALLY,INLINE,INNER,INOUT,INPUT,INSENSITIVE,INSERT,INSTANCE,INSTANTIABLE,INSTEAD,INT,INTEGER,INTEGRITY,INTERSECT,INTERSECTION,INTERVAL,INTO,INVOKER,IS,ISNULL,ISOLATION,JOIN,K,KEY,KEY_MEMBER,KEY_TYPE,LABEL,LAG,LANGUAGE,LARGE,LAST,LAST_VALUE,LATERAL,LC_COLLATE,L C_CTYPE,LEAD,LEADING,LEAKPROOF,LEAST,LEFT,LENGTH,LEVEL,LIBRARY,LIKE,LIKE_REGEX,LIMIT,LINK,LISTEN,LN,LOAD,LOCAL,LOCALTIME,LOCALTIMESTAMP,LOCATION,LOCATOR,LOCK,LOWER,M,MAP,MAPPING,MATCH,MATCHED,MATERIALIZED,MAX,MAXVALUE,MAX_CARDINALITY,MEMBER,MERGE,MESSAGE_LENGTH,MESSAGE_OCTET_LENGTH,MESSAGE_TEXT,METHOD,MIN,MINUTE,MINVALUE,MOD,MODE,MODIFIES,MODULE,MONTH,MORE,MOVE,MULTISET,MUMPS,NAME,NAMES,NAMESPACE,NATIONAL,NATURAL,NCHAR,NCLOB,NESTING,NEW,NEXT,NFC,NFD,NFKC,NFKD,NIL,NO,NONE,NORMALIZE,NORMALIZED,NOT,NOTHING,NOTIFY,NOTNULL,NOWAIT,NTH_VALUE,NTILE,NULL,NULLABLE,NULLIF,NULLS,NUMBER,NUMERIC,OBJECT,OCCURRENCES_REGEX,OCTETS,OCTET_LENGTH,OF,OFF,OFFSET,OIDS,OLD,ON,ONLY,OPEN,OPERATOR,OPTION,OPTIONS,OR,ORDER,ORDERING,ORDINALITY,OTHERS,OUT,OUTER,OUTPUT,OVER,OVERLAPS,OVERLAY,OVERRIDING,OWNED,OWNER,P,PAD,PARAMETER,PARAMETER_MODE,PARAMETER_NAME,PARAMETER_ORDINAL_POSITION,PARAMETER_SPECIFIC_CATALOG,PARAMETER_SPECIFIC_NAME,PARAMETER_SPECIFIC_SCHEMA,PARSER,PARTIAL,PARTITION,PASCAL,PASSING,PASSTHROUGH,PAS SWORD,PATH,PERCENT,PERCENTILE_CONT,PERCENTILE_DISC,PERCENT_RANK,PERIOD,PERMISSION,PLACING,PLANS,PLI,PORTION,POSITION,POSITION_REGEX,POWER,PRECEDES,PRECEDING,PRECISION,PREPARE,PREPARED,PRESERVE,PRIMARY,PRIOR,PRIVILEGES,PROCEDURAL,PROCEDURE,PROGRAM,PUBLIC,QUOTE,RANGE,RANK,READ,READS,REAL,REASSIGN,RECHECK,RECOVERY,RECURSIVE,REF,REFERENCES,REFERENCING,REFRESH,REGR_AVGX,REGR_AVGY,REGR_COUNT,REGR_INTERCEPT,REGR_R2,REGR_SLOPE,REGR_SXX,REGR_SXY,REGR_SYY,REINDEX,RELATIVE,RELEASE,RENAME,REPEATABLE,REPLACE,REPLICA,REQUIRING,RESET,RESPECT,RESTART,RESTORE,RESTRICT,RESULT,RETURN,RETURNED_CARDINALITY,RETURNED_LENGTH,RETURNED_OCTET_LENGTH,RETURNED_SQLSTATE,RETURNING,RETURNS,REVOKE,RIGHT,ROLE,ROLLBACK,ROLLUP,ROUTINE,ROUTINE_CATALOG,ROUTINE_NAME,ROUTINE_SCHEMA,ROW,ROWS,ROW_COUNT,ROW_NUMBER,RULE,SAVEPOINT,SCALE,SCHEMA,SCHEMA_NAME,SCOPE,SCOPE_CATALOG,SCOPE_NAME,SCOPE_SCHEMA,SCROLL,SEARCH,SECOND,SECTION,SECURITY,SELECT,SELECTIVE,SELF,SENSITIVE,SEQUENCE,SEQUENCES,SERIALIZABLE,SERVER,SERVER_NAME,SESSION,S ESSION_USER,SET,SETOF,SETS,SHARE,SHOW,SIMILAR,SIMPLE,SIZE,SMALLINT,SNAPSHOT,SOME,SOURCE,SPACE,SPECIFIC,SPECIFICTYPE,SPECIFIC_NAME,SQL,SQLCODE,SQLERROR,SQLEXCEPTION,SQLSTATE,SQLWARNING,SQRT,STABLE,STANDALONE,START,STATE,STATEMENT,STATIC,STATISTICS,STDDEV_POP,STDDEV_SAMP,STDIN,STDOUT,STORAGE,STRICT,STRIP,STRUCTURE,STYLE,SUBCLASS_ORIGIN,SUBMULTISET,SUBSTRING,SUBSTRING_REGEX,SUCCEEDS,SUM,SYMMETRIC,SYSID,SYSTEM,SYSTEM_TIME,SYSTEM_USER,T,TABLE,TABLES,TABLESAMPLE,TABLESPACE,TABLE_NAME,TEMP,TEMPLATE,TEMPORARY,TEXT,THEN,TIES,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,TO,TOKEN,TOP_LEVEL_COUNT,TRAILING,TRANSACTION,TRANSACTIONS_COMMITTED,TRANSACTIONS_ROLLED_BACK,TRANSACTION_ACTIVE,TRANSFORM,TRANSFORMS,TRANSLATE,TRANSLATE_REGEX,TRANSLATION,TREAT,TRIGGER,TRIGGER_CATALOG,TRIGGER_NAME,TRIGGER_SCHEMA,TRIM,TRIM_ARRAY,TRUE,TRUNCATE,TRUSTED,TYPE,TYPES,UESCAPE,UNBOUNDED,UNCOMMITTED,UNDER,UNENCRYPTED,UNION,UNIQUE,UNKNOWN,UNLINK,UNLISTEN,UNLOGGED,UNNAMED,UNNEST,UNTIL,UNTYPED,UPDATE,UPPER,URI,USAGE,USER, USER_DEFINED_TYPE_CATALOG,USER_DEFINED_TYPE_CODE,USER_DEFINED_TYPE_NAME,USER_DEFINED_TYPE_SCHEMA,USING,VACUUM,VALID,VALIDATE,VALIDATOR,VALUE,VALUES,VALUE_OF,VARBINARY,VARCHAR,VARIADIC,VARYING,VAR_POP,VAR_SAMP,VERBOSE,VERSION,VERSIONING,VIEW,VIEWS,VOLATILE,WHEN,WHENEVER,WHERE,WHITESPACE,WIDTH_BUCKET,WINDOW,WITH,WITHIN,WITHOUT,WORK,WRAPPER,WRITE,XML,XMLAGG,XMLATTRIBUTES,XMLBINARY,XMLCAST,XMLCOMMENT,XMLCONCAT,XMLDECLARATION,XMLDOCUMENT,XMLELEMENT,XMLEXISTS,XMLFOREST,XMLITERATE,XMLNAMESPACES,XMLPARSE,XMLPI,XMLQUERY,XMLROOT,XMLSCHEMA,XMLSERIALIZE,XMLTABLE,XMLTEXT,XMLVALIDATE,YEAR,YES,ZONE +a,abort,abs,absent,absolute,access,according,action,ada,add,admin,after,aggregate,all,allocate,also,alter,always,analyse,analyze,and,any,are,array,array_agg,array_max_cardinality,as,asc,asensitive,assertion,assignment,asymmetric,at,atomic,attribute,attributes,authorization,avg,backward,base64,before,begin,begin_frame,begin_partition,bernoulli,between,bigint,binary,bit,bit_length,blob,blocked,bom,boolean,both,breadth,by,c,cache,call,called,cardinality,cascade,cascaded,case,cast,catalog,catalog_name,ceil,ceiling,chain,char,character,characteristics,characters,character_length,character_set_catalog,character_set_name,character_set_schema,char_length,check,checkpoint,class,class_origin,clob,close,cluster,coalesce,cobol,collate,collation,collation_catalog,collation_name,collation_schema,collect,column,columns,column_name,command_function,command_function_code,comment,comments,commit,committed,concurrently,condition,condition_number,configuration,connect,connection,connection_name,constra int,constraints,constraint_catalog,constraint_name,constraint_schema,constructor,contains,content,continue,control,conversion,convert,copy,corr,corresponding,cost,count,covar_pop,covar_samp,create,cross,csv,cube,cume_dist,current,current_catalog,current_date,current_default_transform_group,current_path,current_role,current_row,current_schema,current_time,current_timestamp,current_transform_group_for_type,current_user,cursor,cursor_name,cycle,data,database,datalink,date,datetime_interval_code,datetime_interval_precision,day,db,deallocate,dec,decimal,declare,default,defaults,deferrable,deferred,defined,definer,degree,delete,delimiter,delimiters,dense_rank,depth,deref,derived,desc,describe,descriptor,deterministic,diagnostics,dictionary,disable,discard,disconnect,dispatch,distinct,dlnewcopy,dlpreviouscopy,dlurlcomplete,dlurlcompleteonly,dlurlcompletewrite,dlurlpath,dlurlpathonly,dlurlpathwrite,dlurlscheme,dlurlserver,dlvalue,do,document,domain,double,drop,dynamic,dynamic_function,dynam ic_function_code,each,element,else,empty,enable,encoding,encrypted,end,end-exec,end_frame,end_partition,enforced,enum,equals,escape,event,every,except,exception,exclude,excluding,exclusive,exec,execute,exists,exp,explain,expression,extension,external,extract,false,family,fetch,file,filter,final,first,first_value,flag,float,floor,following,for,force,foreign,fortran,forward,found,frame_row,free,freeze,from,fs,full,function,functions,fusion,g,general,generated,get,global,go,goto,grant,granted,greatest,group,grouping,groups,handler,having,header,hex,hierarchy,hold,hour,id,identity,if,ignore,ilike,immediate,immediately,immutable,implementation,implicit,import,in,including,increment,indent,index,indexes,indicator,inherit,inherits,initially,inline,inner,inout,input,insensitive,insert,instance,instantiable,instead,int,integer,integrity,intersect,intersection,interval,into,invoker,is,isnull,isolation,join,k,key,key_member,key_type,label,lag,language,large,last,last_value,lateral,lc_collate,l c_ctype,lead,leading,leakproof,least,left,length,level,library,like,like_regex,limit,link,listen,ln,load,local,localtime,localtimestamp,location,locator,lock,lower,m,map,mapping,match,matched,materialized,max,maxvalue,max_cardinality,member,merge,message_length,message_octet_length,message_text,method,min,minute,minvalue,mod,mode,modifies,module,month,more,move,multiset,mumps,name,names,namespace,national,natural,nchar,nclob,nesting,new,next,nfc,nfd,nfkc,nfkd,nil,no,none,normalize,normalized,not,nothing,notify,notnull,nowait,nth_value,ntile,null,nullable,nullif,nulls,number,numeric,object,occurrences_regex,octets,octet_length,of,off,offset,oids,old,on,only,open,operator,option,options,or,order,ordering,ordinality,others,out,outer,output,over,overlaps,overlay,overriding,owned,owner,p,pad,parameter,parameter_mode,parameter_name,parameter_ordinal_position,parameter_specific_catalog,parameter_specific_name,parameter_specific_schema,parser,partial,partition,pascal,passing,passthrough,pas sword,path,percent,percentile_cont,percentile_disc,percent_rank,period,permission,placing,plans,pli,portion,position,position_regex,power,precedes,preceding,precision,prepare,prepared,preserve,primary,prior,privileges,procedural,procedure,program,public,quote,range,rank,read,reads,real,reassign,recheck,recovery,recursive,ref,references,referencing,refresh,regr_avgx,regr_avgy,regr_count,regr_intercept,regr_r2,regr_slope,regr_sxx,regr_sxy,regr_syy,reindex,relative,release,rename,repeatable,replace,replica,requiring,reset,respect,restart,restore,restrict,result,return,returned_cardinality,returned_length,returned_octet_length,returned_sqlstate,returning,returns,revoke,right,role,rollback,rollup,routine,routine_catalog,routine_name,routine_schema,row,rows,row_count,row_number,rule,savepoint,scale,schema,schema_name,scope,scope_catalog,scope_name,scope_schema,scroll,search,second,section,security,select,selective,self,sensitive,sequence,sequences,serializable,server,server_name,session,s ession_user,set,setof,sets,share,show,similar,simple,size,smallint,snapshot,some,source,space,specific,specifictype,specific_name,sql,sqlcode,sqlerror,sqlexception,sqlstate,sqlwarning,sqrt,stable,standalone,start,state,statement,static,statistics,stddev_pop,stddev_samp,stdin,stdout,storage,strict,strip,structure,style,subclass_origin,submultiset,substring,substring_regex,succeeds,sum,symmetric,sysid,system,system_time,system_user,t,table,tables,tablesample,tablespace,table_name,temp,template,temporary,text,then,ties,time,timestamp,timezone_hour,timezone_minute,to,token,top_level_count,trailing,transaction,transactions_committed,transactions_rolled_back,transaction_active,transform,transforms,translate,translate_regex,translation,treat,trigger,trigger_catalog,trigger_name,trigger_schema,trim,trim_array,true,truncate,trusted,type,types,uescape,unbounded,uncommitted,under,unencrypted,union,unique,unknown,unlink,unlisten,unlogged,unnamed,unnest,until,untyped,update,upper,uri,usage,user, user_defined_type_catalog,user_defined_type_code,user_defined_type_name,user_defined_type_schema,using,vacuum,valid,validate,validator,value,values,value_of,varbinary,varchar,variadic,varying,var_pop,var_samp,verbose,version,versioning,view,views,volatile,when,whenever,where,whitespace,width_bucket,window,with,within,without,work,wrapper,write,xml,xmlagg,xmlattributes,xmlbinary,xmlcast,xmlcomment,xmlconcat,xmldeclaration,xmldocument,xmlelement,xmlexists,xmlforest,xmliterate,xmlnamespaces,xmlparse,xmlpi,xmlquery,xmlroot,xmlschema,xmlserialize,xmltable,xmltext,xmlvalidate,year,yes,zone http://git-wip-us.apache.org/repos/asf/zeppelin/blob/4d398ef2/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java ---------------------------------------------------------------------- diff --git a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java index 04365cc..ff09503 100644 --- a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java +++ b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; +import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterResult; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; @@ -295,9 +296,9 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter { jdbcInterpreter.interpret("", interpreterContext); - List<InterpreterCompletion> completionList = jdbcInterpreter.completion("sel", 1); + List<InterpreterCompletion> completionList = jdbcInterpreter.completion("sel", 3, null); - InterpreterCompletion correctCompletionKeyword = new InterpreterCompletion("select ", "select "); + InterpreterCompletion correctCompletionKeyword = new InterpreterCompletion("select ", "select ", CompletionType.keyword.name()); assertEquals(1, completionList.size()); assertEquals(true, completionList.contains(correctCompletionKeyword));