[ZEPPELIN-2297] add type of completion

This commit is contained in:
Tinkoff DWH 2017-03-22 19:06:39 +05:00
parent 29dc3da1e1
commit 1c74384759
29 changed files with 404 additions and 154 deletions

View file

@ -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;
@ -176,7 +176,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;

View file

@ -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,21 +80,21 @@ 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);

View file

@ -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;
@ -244,7 +245,7 @@ public class ElasticsearchInterpreter extends Interpreter {
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;

View file

@ -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,8 +306,8 @@ 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);

View file

@ -23,6 +23,7 @@ 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.InterpreterException;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
@ -251,17 +252,20 @@ public class HDFSFileInterpreter extends FileInterpreter {
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 +302,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;

View file

@ -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,9 +108,9 @@ 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"));
new InterpreterCompletion("pwd", "pwd", CompletionType.command.name()));
List<InterpreterCompletion> resultOne = t.completion("l", 0);
List<InterpreterCompletion> resultTwo = t.completion("p", 0);

View file

@ -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>

View file

@ -56,9 +56,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;
@ -131,13 +129,6 @@ public class JDBCInterpreter extends Interpreter {
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;
@ -756,17 +747,12 @@ public class JDBCInterpreter extends Interpreter {
@Override
public List<InterpreterCompletion> completion(String buf, int cursor) {
List<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> 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;
if (sqlCompleter != null) {
sqlCompleter.complete(buf, cursor - 1, candidates);
}
return candidates;
}
public int getMaxResult() {

View file

@ -4,12 +4,12 @@ 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.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;
@ -28,7 +28,7 @@ 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 +67,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);
@ -177,8 +176,7 @@ 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, schemaFilter, "%", "%");
try {
while (cols.next()) {
String schema = cols.getString("TABLE_SCHEM");
@ -438,15 +436,16 @@ 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);
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);
@ -457,13 +456,14 @@ public class SqlCompleter extends StringsCompleter {
String column;
if (pointPos1 == -1) { // process only schema or keyword case
schema = buffer;
int keywordsRes = completeKeyword(buffer, cursor, candidates);
List<CharSequence> keywordsCandidates = new ArrayList();
int keywordsRes = completeKeyword(buffer, cursor, keywordsCandidates);
List<CharSequence> schemaCandidates = new ArrayList<>();
int schemaRes = completeSchema(schema, cursor, schemaCandidates);
candidates.addAll(schemaCandidates);
addCompletions(candidates, keywordsCandidates, CompletionType.keyword.name());
addCompletions(candidates, schemaCandidates, CompletionType.schema.name());
return Math.max(keywordsRes, schemaRes);
}
else {
} else {
schema = buffer.substring(0, pointPos1);
if (aliases.containsKey(schema)) { // process alias case
String alias = aliases.get(schema);
@ -471,26 +471,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
table = buffer.substring(pointPos1 + 1);
return completeTable(schema, table, cursor - pointPos1 - 1, candidates);
}
else {
List<CharSequence> tableCandidates = new ArrayList();
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
if (isColumnAllowed) {
List<CharSequence> columnCandidates = new ArrayList();
int columnRes = completeColumn(schema, table, column, cursor - pointPos2 - 1,
columnCandidates);
addCompletions(candidates, columnCandidates, CompletionType.column.name());
return columnRes;
} else {
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));
}
}
}

View file

@ -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,7 +296,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
List<InterpreterCompletion> completionList = jdbcInterpreter.completion("sel", 1);
InterpreterCompletion correctCompletionKeyword = new InterpreterCompletion("select ", "select ");
InterpreterCompletion correctCompletionKeyword = new InterpreterCompletion("select ", "select ", CompletionType.keyword.name());
assertEquals(1, completionList.size());
assertEquals(true, completionList.contains(correctCompletionKeyword));

View file

@ -14,18 +14,25 @@
*/
package org.apache.zeppelin.jdbc;
import com.google.common.base.Joiner;
import com.mockrunner.jdbc.BasicJDBCTestCaseAdapter;
import jline.console.completer.ArgumentCompleter;
import jline.console.completer.Completer;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.zeppelin.completer.CompletionType;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.sql.SQLException;
import java.util.*;
import com.google.common.base.Joiner;
import jline.console.completer.ArgumentCompleter;
import static com.google.common.collect.Sets.newHashSet;
import static org.junit.Assert.assertEquals;
@ -34,18 +41,18 @@ import static org.junit.Assert.assertTrue;
/**
* SQL completer unit tests
*/
public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
public class SqlCompleterTest {
public class CompleterTester {
private Completer completer;
private SqlCompleter completer;
private String buffer;
private int fromCursor;
private int toCursor;
private Set<String> expectedCompletions;
private Set<InterpreterCompletion> expectedCompletions;
public CompleterTester(Completer completer) {
public CompleterTester(SqlCompleter completer) {
this.completer = completer;
}
@ -64,7 +71,7 @@ public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
return this;
}
public CompleterTester expect(Set<String> expectedCompletions) {
public CompleterTester expect(Set<InterpreterCompletion> expectedCompletions) {
this.expectedCompletions = expectedCompletions;
return this;
}
@ -75,9 +82,9 @@ public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
}
}
private void expectedCompletions(String buffer, int cursor, Set<String> expected) {
private void expectedCompletions(String buffer, int cursor, Set<InterpreterCompletion> expected) {
ArrayList<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> candidates = new ArrayList<>();
completer.complete(buffer, cursor, candidates);
@ -85,11 +92,15 @@ public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
logger.info(explain);
assertEquals("Buffer [" + buffer.replace(" ", ".") + "] and Cursor[" + cursor + "] "
Assert.assertEquals("Buffer [" + buffer.replace(" ", ".") + "] and Cursor[" + cursor + "] "
+ explain, expected, newHashSet(candidates));
}
private String explain(String buffer, int cursor, ArrayList<CharSequence> candidates) {
private String explain(String buffer, int cursor, List<InterpreterCompletion> candidates) {
List<String> cndidateStrings = new ArrayList<>();
for (InterpreterCompletion candidate : candidates) {
cndidateStrings.add(candidate.getValue());
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i <= Math.max(cursor, buffer.length()); i++) {
@ -109,7 +120,7 @@ public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
sb.append(")");
}
}
sb.append(" >> [").append(Joiner.on(",").join(candidates)).append("]");
sb.append(" >> [").append(Joiner.on(",").join(cndidateStrings)).append("]");
return sb.toString();
}
@ -205,116 +216,129 @@ public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
public void testCompleteName_Empty() {
String buffer = "";
int cursor = 0;
List<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> candidates = new ArrayList<>();
Map<String, String> aliases = new HashMap<>();
sqlCompleter.completeName(buffer, cursor, candidates, aliases, false);
assertEquals(9, candidates.size());
assertTrue(candidates.contains("prod_dds"));
assertTrue(candidates.contains("prod_emart"));
assertTrue(candidates.contains("SUM"));
assertTrue(candidates.contains("SUBSTRING"));
assertTrue(candidates.contains("SUBCLASS_ORIGIN"));
assertTrue(candidates.contains("SELECT"));
assertTrue(candidates.contains("ORDER"));
assertTrue(candidates.contains("LIMIT"));
assertTrue(candidates.contains("FROM"));
assertTrue(candidates.contains(new InterpreterCompletion("prod_dds", "prod_dds", CompletionType.schema.name())));
assertTrue(candidates.contains(new InterpreterCompletion("prod_emart", "prod_emart", CompletionType.schema.name())));
assertTrue(candidates.contains(new InterpreterCompletion("SUM", "SUM", CompletionType.keyword.name())));
assertTrue(candidates.contains(new InterpreterCompletion("SUBSTRING", "SUBSTRING", CompletionType.keyword.name())));
assertTrue(candidates.contains(new InterpreterCompletion("SUBCLASS_ORIGIN", "SUBCLASS_ORIGIN", CompletionType.keyword.name())));
assertTrue(candidates.contains(new InterpreterCompletion("SELECT", "SELECT", CompletionType.keyword.name())));
assertTrue(candidates.contains(new InterpreterCompletion("ORDER", "ORDER", CompletionType.keyword.name())));
assertTrue(candidates.contains(new InterpreterCompletion("LIMIT", "LIMIT", CompletionType.keyword.name())));
assertTrue(candidates.contains(new InterpreterCompletion("FROM", "FROM", CompletionType.keyword.name())));
}
@Test
public void testCompleteName_SimpleSchema() {
String buffer = "prod_";
int cursor = 3;
List<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> candidates = new ArrayList<>();
Map<String, String> aliases = new HashMap<>();
sqlCompleter.completeName(buffer, cursor, candidates, aliases, false);
assertEquals(2, candidates.size());
assertTrue(candidates.contains("prod_dds"));
assertTrue(candidates.contains("prod_emart"));
assertTrue(candidates.contains(new InterpreterCompletion("prod_dds", "prod_dds", CompletionType.schema.name())));
assertTrue(candidates.contains(new InterpreterCompletion("prod_emart", "prod_emart", CompletionType.schema.name())));
}
@Test
public void testCompleteName_SimpleTable() {
String buffer = "prod_dds.fin";
int cursor = 11;
List<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> candidates = new ArrayList<>();
Map<String, String> aliases = new HashMap<>();
sqlCompleter.completeName(buffer, cursor, candidates, aliases, false);
assertEquals(1, candidates.size());
assertTrue(candidates.contains("financial_account "));
assertTrue(candidates.contains(new InterpreterCompletion("financial_account ", "financial_account ", CompletionType.table.name())));
}
@Test
public void testCompleteName_SimpleColumn() {
String buffer = "prod_dds.financial_account.acc";
int cursor = 30;
List<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> candidates = new ArrayList<>();
Map<String, String> aliases = new HashMap<>();
sqlCompleter.completeName(buffer, cursor, candidates, aliases, true);
assertEquals(2, candidates.size());
assertTrue(candidates.contains("account_rk"));
assertTrue(candidates.contains("account_id"));
assertTrue(candidates.contains(new InterpreterCompletion("account_rk", "account_rk", CompletionType.column.name())));
assertTrue(candidates.contains(new InterpreterCompletion("account_id", "account_id", CompletionType.column.name())));
}
@Test
public void testCompleteName_WithAlias() {
String buffer = "a.acc";
int cursor = 4;
List<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> candidates = new ArrayList<>();
Map<String, String> aliases = new HashMap<>();
aliases.put("a", "prod_dds.financial_account");
sqlCompleter.completeName(buffer, cursor, candidates, aliases, true);
assertEquals(2, candidates.size());
assertTrue(candidates.contains("account_rk"));
assertTrue(candidates.contains("account_id"));
assertTrue(candidates.contains(new InterpreterCompletion("account_rk", "account_rk", CompletionType.column.name())));
assertTrue(candidates.contains(new InterpreterCompletion("account_id", "account_id", CompletionType.column.name())));
}
@Test
public void testCompleteName_WithAliasAndPoint() {
String buffer = "a.";
int cursor = 2;
List<CharSequence> candidates = new ArrayList<>();
List<InterpreterCompletion> candidates = new ArrayList<>();
Map<String, String> aliases = new HashMap<>();
aliases.put("a", "prod_dds.financial_account");
sqlCompleter.completeName(buffer, cursor, candidates, aliases, true);
assertEquals(2, candidates.size());
assertTrue(candidates.contains("account_rk"));
assertTrue(candidates.contains("account_id"));
assertTrue(candidates.contains(new InterpreterCompletion("account_rk", "account_rk", CompletionType.column.name())));
assertTrue(candidates.contains(new InterpreterCompletion("account_id", "account_id", CompletionType.column.name())));
}
@Test
public void testSchemaAndTable() {
String buffer = "select * from prod_v_emart.fi";
tester.buffer(buffer).from(15).to(26).expect(newHashSet("prod_v_emart ")).test();
tester.buffer(buffer).from(27).to(29).expect(newHashSet("financial_account ")).test();
String buffer = "select * from prod_emart.fi";
tester.buffer(buffer).from(15).to(24).expect(newHashSet(new InterpreterCompletion("prod_emart ", "prod_emart ", CompletionType.schema.name()))).test();
tester.buffer(buffer).from(25).to(27).expect(newHashSet(new InterpreterCompletion("financial_account ", "financial_account ", CompletionType.table.name()))).test();
}
@Test
public void testEdges() {
String buffer = " ORDER ";
tester.buffer(buffer).from(0).to(7).expect(newHashSet("ORDER ")).test();
tester.buffer(buffer).from(8).to(15).expect(newHashSet("ORDER", "SUBCLASS_ORIGIN", "SUBSTRING",
"prod_emart", "LIMIT", "SUM", "prod_dds", "SELECT", "FROM")).test();
tester.buffer(buffer).from(0).to(7).expect(newHashSet(new InterpreterCompletion("ORDER ", "ORDER ", CompletionType.keyword.name()))).test();
tester.buffer(buffer).from(8).to(15).expect(newHashSet(
new InterpreterCompletion("ORDER", "ORDER", CompletionType.keyword.name()),
new InterpreterCompletion("SUBCLASS_ORIGIN", "SUBCLASS_ORIGIN", CompletionType.keyword.name()),
new InterpreterCompletion("SUBSTRING", "SUBSTRING", CompletionType.keyword.name()),
new InterpreterCompletion("prod_emart", "prod_emart", CompletionType.schema.name()),
new InterpreterCompletion("LIMIT", "LIMIT", CompletionType.keyword.name()),
new InterpreterCompletion("SUM", "SUM", CompletionType.keyword.name()),
new InterpreterCompletion("prod_dds", "prod_dds", CompletionType.schema.name()),
new InterpreterCompletion("SELECT", "SELECT", CompletionType.keyword.name()),
new InterpreterCompletion("FROM", "FROM", CompletionType.keyword.name())
)).test();
}
@Test
public void testMultipleWords() {
String buffer = "SELE FRO LIM";
tester.buffer(buffer).from(0).to(4).expect(newHashSet("SELECT ")).test();
tester.buffer(buffer).from(5).to(8).expect(newHashSet("FROM ")).test();
tester.buffer(buffer).from(9).to(12).expect(newHashSet("LIMIT ")).test();
tester.buffer(buffer).from(0).to(4).expect(newHashSet(new InterpreterCompletion("SELECT ", "SELECT ", CompletionType.keyword.name()))).test();
tester.buffer(buffer).from(5).to(8).expect(newHashSet(new InterpreterCompletion("FROM ", "FROM ", CompletionType.keyword.name()))).test();
tester.buffer(buffer).from(9).to(12).expect(newHashSet(new InterpreterCompletion("LIMIT ", "LIMIT ", CompletionType.keyword.name()))).test();
}
@Test
public void testMultiLineBuffer() {
String buffer = " \n SELE\nFRO";
tester.buffer(buffer).from(0).to(7).expect(newHashSet("SELECT ")).test();
tester.buffer(buffer).from(8).to(11).expect(newHashSet("FROM ")).test();
tester.buffer(buffer).from(0).to(7).expect(newHashSet(new InterpreterCompletion("SELECT ", "SELECT ", CompletionType.keyword.name()))).test();
tester.buffer(buffer).from(8).to(11).expect(newHashSet(new InterpreterCompletion("FROM ", "FROM ", CompletionType.keyword.name()))).test();
}
@Test
public void testMultipleCompletionSuggestions() {
String buffer = "SU";
tester.buffer(buffer).from(0).to(2).expect(newHashSet("SUBCLASS_ORIGIN", "SUM", "SUBSTRING"))
.test();
tester.buffer(buffer).from(0).to(2).expect(newHashSet(
new InterpreterCompletion("SUBCLASS_ORIGIN", "SUBCLASS_ORIGIN", CompletionType.keyword.name()),
new InterpreterCompletion("SUM", "SUM", CompletionType.keyword.name()),
new InterpreterCompletion("SUBSTRING", "SUBSTRING", CompletionType.keyword.name()))
).test();
}
@Test

View file

@ -47,6 +47,12 @@
<artifactId>zeppelin-interpreter</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

View file

@ -33,6 +33,8 @@ import java.util.Properties;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.apache.spark.repl.SparkILoop;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
@ -293,7 +295,7 @@ public class DepInterpreter extends Interpreter {
List<InterpreterCompletion> completions = new LinkedList<>();
for (String candidate : candidates) {
completions.add(new InterpreterCompletion(candidate, candidate));
completions.add(new InterpreterCompletion(candidate, candidate, StringUtils.EMPTY));
}
return completions;

View file

@ -42,6 +42,7 @@ import org.apache.commons.exec.ExecuteResultHandler;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.exec.environment.EnvironmentUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.SQLContext;
@ -509,7 +510,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
List<InterpreterCompletion> results = new LinkedList<>();
for (String name: completionList) {
results.add(new InterpreterCompletion(name, name));
results.add(new InterpreterCompletion(name, name, StringUtils.EMPTY));
}
return results;
}

View file

@ -1079,7 +1079,7 @@ public class SparkInterpreter extends Interpreter {
List<InterpreterCompletion> completions = new LinkedList<>();
for (String candidate : candidates) {
completions.add(new InterpreterCompletion(candidate, candidate));
completions.add(new InterpreterCompletion(candidate, candidate, StringUtils.EMPTY));
}
return completions;

View file

@ -43,6 +43,7 @@
<aether.version>1.12</aether.version>
<maven.aeither.provider.version>3.0.3</maven.aeither.provider.version>
<wagon.version>1.0</wagon.version>
<jline.version>2.12.1</jline.version>
<!--plugin versions-->
<plugin.shade.version>2.3</plugin.shade.version>
@ -202,6 +203,17 @@
<version>${wagon.version}</version>
</dependency>
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
<version>${jline.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View file

@ -0,0 +1,28 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you 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.apache.zeppelin.completer;
/**
* Types of completion
*/
public enum CompletionType {
schema,
table,
column,
setting,
command,
keyword,
path
}

View file

@ -0,0 +1,68 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you 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.apache.zeppelin.completer;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import jline.console.completer.Completer;
import jline.internal.Preconditions;
/**
* Case-insensitive completer for a set of strings.
*/
public class StringsCompleter implements Completer {
private final SortedSet<String> strings = new TreeSet<String>();
public StringsCompleter() {
}
public StringsCompleter(final Collection<String> strings) {
Preconditions.checkNotNull(strings);
getStrings().addAll(strings);
}
public Collection<String> getStrings() {
return strings;
}
public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
Preconditions.checkNotNull(candidates);
if (buffer == null) {
candidates.addAll(strings);
}
else {
String bufferTmp = buffer.toUpperCase();
for (String match : strings.tailSet(buffer)) {
String matchTmp = match.toUpperCase();
if (!matchTmp.startsWith(bufferTmp)) {
break;
}
candidates.add(match);
}
}
if (candidates.size() == 1) {
candidates.set(0, candidates.get(0) + " ");
}
return candidates.isEmpty() ? -1 : 0;
}
}

View file

@ -51,12 +51,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class InterpreterCompletion implements org.apache.thrift.TBase<InterpreterCompletion, InterpreterCompletion._Fields>, java.io.Serializable, Cloneable, Comparable<InterpreterCompletion> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("InterpreterCompletion");
private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1);
private static final org.apache.thrift.protocol.TField VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("value", org.apache.thrift.protocol.TType.STRING, (short)2);
private static final org.apache.thrift.protocol.TField META_FIELD_DESC = new org.apache.thrift.protocol.TField("meta", org.apache.thrift.protocol.TType.STRING, (short)3);
private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
static {
@ -66,11 +67,13 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
public String name; // required
public String value; // required
public String meta; // required
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements org.apache.thrift.TFieldIdEnum {
NAME((short)1, "name"),
VALUE((short)2, "value");
VALUE((short)2, "value"),
META((short)3, "meta");
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
@ -89,6 +92,8 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
return NAME;
case 2: // VALUE
return VALUE;
case 3: // META
return META;
default:
return null;
}
@ -136,6 +141,8 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
tmpMap.put(_Fields.VALUE, new org.apache.thrift.meta_data.FieldMetaData("value", org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
tmpMap.put(_Fields.META, new org.apache.thrift.meta_data.FieldMetaData("meta", org.apache.thrift.TFieldRequirementType.DEFAULT,
new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
metaDataMap = Collections.unmodifiableMap(tmpMap);
org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(InterpreterCompletion.class, metaDataMap);
}
@ -145,11 +152,13 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
public InterpreterCompletion(
String name,
String value)
String value,
String meta)
{
this();
this.name = name;
this.value = value;
this.meta = meta;
}
/**
@ -162,6 +171,9 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
if (other.isSetValue()) {
this.value = other.value;
}
if (other.isSetMeta()) {
this.meta = other.meta;
}
}
public InterpreterCompletion deepCopy() {
@ -172,6 +184,7 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
public void clear() {
this.name = null;
this.value = null;
this.meta = null;
}
public String getName() {
@ -222,6 +235,30 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
}
}
public String getMeta() {
return this.meta;
}
public InterpreterCompletion setMeta(String meta) {
this.meta = meta;
return this;
}
public void unsetMeta() {
this.meta = null;
}
/** Returns true if field meta is set (has been assigned a value) and false otherwise */
public boolean isSetMeta() {
return this.meta != null;
}
public void setMetaIsSet(boolean value) {
if (!value) {
this.meta = null;
}
}
public void setFieldValue(_Fields field, Object value) {
switch (field) {
case NAME:
@ -240,6 +277,14 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
}
break;
case META:
if (value == null) {
unsetMeta();
} else {
setMeta((String)value);
}
break;
}
}
@ -251,6 +296,9 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
case VALUE:
return getValue();
case META:
return getMeta();
}
throw new IllegalStateException();
}
@ -266,6 +314,8 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
return isSetName();
case VALUE:
return isSetValue();
case META:
return isSetMeta();
}
throw new IllegalStateException();
}
@ -301,6 +351,15 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
return false;
}
boolean this_present_meta = true && this.isSetMeta();
boolean that_present_meta = true && that.isSetMeta();
if (this_present_meta || that_present_meta) {
if (!(this_present_meta && that_present_meta))
return false;
if (!this.meta.equals(that.meta))
return false;
}
return true;
}
@ -318,6 +377,11 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
if (present_value)
list.add(value);
boolean present_meta = true && (isSetMeta());
list.add(present_meta);
if (present_meta)
list.add(meta);
return list.hashCode();
}
@ -349,6 +413,16 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
return lastComparison;
}
}
lastComparison = Boolean.valueOf(isSetMeta()).compareTo(other.isSetMeta());
if (lastComparison != 0) {
return lastComparison;
}
if (isSetMeta()) {
lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.meta, other.meta);
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
@ -384,6 +458,14 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
sb.append(this.value);
}
first = false;
if (!first) sb.append(", ");
sb.append("meta:");
if (this.meta == null) {
sb.append("null");
} else {
sb.append(this.meta);
}
first = false;
sb.append(")");
return sb.toString();
}
@ -443,6 +525,14 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
case 3: // META
if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
struct.meta = iprot.readString();
struct.setMetaIsSet(true);
} else {
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
break;
default:
org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
}
@ -468,6 +558,11 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
oprot.writeString(struct.value);
oprot.writeFieldEnd();
}
if (struct.meta != null) {
oprot.writeFieldBegin(META_FIELD_DESC);
oprot.writeString(struct.meta);
oprot.writeFieldEnd();
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
@ -492,19 +587,25 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
if (struct.isSetValue()) {
optionals.set(1);
}
oprot.writeBitSet(optionals, 2);
if (struct.isSetMeta()) {
optionals.set(2);
}
oprot.writeBitSet(optionals, 3);
if (struct.isSetName()) {
oprot.writeString(struct.name);
}
if (struct.isSetValue()) {
oprot.writeString(struct.value);
}
if (struct.isSetMeta()) {
oprot.writeString(struct.meta);
}
}
@Override
public void read(org.apache.thrift.protocol.TProtocol prot, InterpreterCompletion struct) throws org.apache.thrift.TException {
TTupleProtocol iprot = (TTupleProtocol) prot;
BitSet incoming = iprot.readBitSet(2);
BitSet incoming = iprot.readBitSet(3);
if (incoming.get(0)) {
struct.name = iprot.readString();
struct.setNameIsSet(true);
@ -513,6 +614,10 @@ public class InterpreterCompletion implements org.apache.thrift.TBase<Interprete
struct.value = iprot.readString();
struct.setValueIsSet(true);
}
if (incoming.get(2)) {
struct.meta = iprot.readString();
struct.setMetaIsSet(true);
}
}
}

View file

@ -51,7 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class RemoteApplicationResult implements org.apache.thrift.TBase<RemoteApplicationResult, RemoteApplicationResult._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteApplicationResult> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteApplicationResult");

View file

@ -51,7 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteInterpreterContext, RemoteInterpreterContext._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterContext> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterContext");

View file

@ -51,7 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class RemoteInterpreterEvent implements org.apache.thrift.TBase<RemoteInterpreterEvent, RemoteInterpreterEvent._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterEvent> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterEvent");

View file

@ -51,7 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteInterpreterResult, RemoteInterpreterResult._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResult> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResult");

View file

@ -51,7 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class RemoteInterpreterResultMessage implements org.apache.thrift.TBase<RemoteInterpreterResultMessage, RemoteInterpreterResultMessage._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResultMessage> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResultMessage");

View file

@ -51,7 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class RemoteInterpreterService {
public interface Iface {

View file

@ -51,7 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-25")
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-3-22")
public class ZeppelinServerResourceParagraphRunner implements org.apache.thrift.TBase<ZeppelinServerResourceParagraphRunner, ZeppelinServerResourceParagraphRunner._Fields>, java.io.Serializable, Cloneable, Comparable<ZeppelinServerResourceParagraphRunner> {
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ZeppelinServerResourceParagraphRunner");

View file

@ -84,7 +84,8 @@ struct ZeppelinServerResourceParagraphRunner {
*/
struct InterpreterCompletion {
1: string name,
2: string value
2: string value,
3: string meta
}
service RemoteInterpreterService {

View file

@ -657,6 +657,7 @@ function ParagraphCtrl($scope, $rootScope, $route, $window, $routeParams, $locat
completions.push({
name: v.name,
value: v.value,
meta: v.meta,
score: 300
});
}

View file

@ -20,6 +20,7 @@ package org.apache.zeppelin.notebook;
import com.google.common.collect.Maps;
import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
import org.apache.zeppelin.completer.CompletionType;
import org.apache.zeppelin.display.AngularObject;
import org.apache.zeppelin.display.AngularObjectRegistry;
import org.apache.zeppelin.helium.HeliumPackage;
@ -267,10 +268,11 @@ public class Paragraph extends Job implements Serializable, Cloneable {
if (intInfo.size() > 1) {
for (InterpreterInfo info : intInfo) {
String name = intp.getName() + "." + info.getName();
completion.add(new InterpreterCompletion(name, name));
completion.add(new InterpreterCompletion(name, name, CompletionType.setting.name()));
}
} else {
completion.add(new InterpreterCompletion(intp.getName(), intp.getName()));
completion.add(new InterpreterCompletion(intp.getName(), intp.getName(),
CompletionType.setting.name()));
}
}
return completion;