Repository: zeppelin
Updated Branches:
  refs/heads/master c9e3a6a43 -> ccd8a49ac


ZEPPELIN-614 Part 1. Merge PostgresqlInterpreter's sql completer into JDBC 
Interpreter

### What is this PR for?
Supporting Sql completer into JDBC Interpreter which is merged by the function 
of Postgresql Interpreter. And this is the first step to merge Postgresql into 
generic JDBC Interpreter

### What type of PR is it?
[Improvement]

### Todos
* [x] - Adopted the function of auto completion

### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-614

### How should this be tested?

### Screenshots (if appropriate)
<img width="1054" alt="screen shot 2016-06-08 at 3 00 54 pm" 
src="https://cloud.githubusercontent.com/assets/3612566/15884224/e241f6b4-2d89-11e6-9746-8c8951ef6708.png";>
<img width="474" alt="screen shot 2016-06-08 at 2 45 50 pm" 
src="https://cloud.githubusercontent.com/assets/3612566/15884229/e7993e24-2d89-11e6-9f5b-018e6eac7f6a.png";>

### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No

Author: Jongyoul Lee <[email protected]>

Closes #974 from jongyoul/ZEPPELIN-614 and squashes the following commits:

998352c [Jongyoul Lee] Fixed old styles
99ce452 [Jongyoul Lee] Updated license document
d482395 [Jongyoul Lee] Fixed typo and coding style
e49f73c [Jongyoul Lee] Updated original documentation
6491cba [Jongyoul Lee] Added auto completion from PostgresqlInterpreter


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/ccd8a49a
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/ccd8a49a
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/ccd8a49a

Branch: refs/heads/master
Commit: ccd8a49acc90cf9134cca23ade8cc73e20e459e3
Parents: c9e3a6a
Author: Jongyoul Lee <[email protected]>
Authored: Thu Jun 9 23:17:24 2016 +0900
Committer: Jongyoul Lee <[email protected]>
Committed: Mon Jun 13 12:43:31 2016 +0900

----------------------------------------------------------------------
 LICENSE                                         |  10 +-
 docs/interpreter/postgresql.md                  |  42 ++++
 .../apache/zeppelin/jdbc/JDBCInterpreter.java   |  90 +++++--
 .../org/apache/zeppelin/jdbc/SqlCompleter.java  | 250 +++++++++++++++++++
 jdbc/src/main/resources/ansi.sql.keywords       |   1 +
 .../postgresql-native-driver-sql.keywords       |   1 +
 licenses/LICENSE-sqlline-1.0.2                  |  10 +
 7 files changed, 380 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ccd8a49a/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index db076c6..67a5b79 100644
--- a/LICENSE
+++ b/LICENSE
@@ -256,4 +256,12 @@ The following components are provided under the BSD 
3-Clause license.  See file
    r/src/main/scala/org/apache/zeppelin/rinterpreter/rscala/{Package.scala, 
RClient.scala}
 
   (BSD 3 Clause) portions of Scala (http://www.scala-lang.org/download) - 
http://www.scala-lang.org/download/#License
-   r/src/main/scala/scala/Console.scala
\ No newline at end of file
+   r/src/main/scala/scala/Console.scala
+
+========================================================================
+BSD 2-Clause licenses
+========================================================================
+The following components are provided under the BSD 3-Clause license.  See 
file headers and project links for details.
+
+  (BSD 2 Clause) portions of SQLLine (http://sqlline.sourceforge.net/) - 
http://sqlline.sourceforge.net/#license
+   jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ccd8a49a/docs/interpreter/postgresql.md
----------------------------------------------------------------------
diff --git a/docs/interpreter/postgresql.md b/docs/interpreter/postgresql.md
index 54def09..5985b18 100644
--- a/docs/interpreter/postgresql.md
+++ b/docs/interpreter/postgresql.md
@@ -6,7 +6,49 @@ group: manual
 ---
 {% include JB/setup %}
 
+## Important Notice
+Postgresql Interpreter will be deprecated and merged into JDBC Interpreter. 
You can use Postgresql by using JDBC Interpreter with same functionality. See 
the example below of settings and dependencies.
+
+### Properties
+<table class="table-configuration">
+  <tr>
+    <th>Property</th>
+    <th>Value</th>
+  </tr>
+  <tr>
+    <td>psql.driver</td>
+    <td>org.postgresql.Driver</td>
+  </tr>
+  <tr>
+    <td>psql.url</td>
+    <td>jdbc:postgresql://localhost:5432/</td>
+  </tr>
+  <tr>
+    <td>psql.user</td>
+    <td>psqlUser</td>
+  </tr>
+  <tr>
+    <td>psql.password</td>
+    <td>psqlPassword</td>
+  </tr>
+</table>
+
+### Dependencies
+<table class="table-configuration">
+  <tr>
+    <th>Artifact</th>
+    <th>Exclude</th>
+  </tr>
+  <tr>
+    <td>org.postgresql:postgresql:9.4-1201-jdbc41</td>
+    <td></td>
+  </tr>
+</table>
+
+----
+
 ## PostgreSQL, HAWQ  Interpreter for Apache Zeppelin
+
 <table class="table-configuration">
   <tr>
     <th>Name</th>

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ccd8a49a/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 6495264..610618a 100644
--- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
+++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
@@ -33,8 +33,6 @@ import java.util.Set;
 
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterContext;
-import org.apache.zeppelin.interpreter.InterpreterException;
-import org.apache.zeppelin.interpreter.InterpreterPropertyBuilder;
 import org.apache.zeppelin.interpreter.InterpreterResult;
 import org.apache.zeppelin.interpreter.InterpreterResult.Code;
 import org.apache.zeppelin.scheduler.Scheduler;
@@ -50,7 +48,7 @@ import com.google.common.collect.Sets.SetView;
 /**
  * JDBC interpreter for Zeppelin. This interpreter can also be used for 
accessing HAWQ,
  * GreenplumDB, MariaDB, MySQL, Postgres and Redshit.
- * 
+ *
  * <ul>
  * <li>{@code default.url} - JDBC URL to connect to.</li>
  * <li>{@code default.user} - JDBC user name..</li>
@@ -58,22 +56,21 @@ import com.google.common.collect.Sets.SetView;
  * <li>{@code default.driver.name} - JDBC driver name.</li>
  * <li>{@code common.max.result} - Max number of SQL result to display.</li>
  * </ul>
- * 
+ *
  * <p>
  * How to use: <br/>
  * {@code %jdbc.sql} <br/>
- * {@code 
- *  SELECT store_id, count(*) 
- *  FROM retail_demo.order_lineitems_pxf 
- *  GROUP BY store_id;
+ * {@code
+ * SELECT store_id, count(*)
+ * FROM retail_demo.order_lineitems_pxf
+ * GROUP BY store_id;
  * }
  * </p>
- * 
  */
 public class JDBCInterpreter extends Interpreter {
 
   private Logger logger = LoggerFactory.getLogger(JDBCInterpreter.class);
- 
+
   static final String COMMON_KEY = "common";
   static final String MAX_LINE_KEY = "max_count";
   static final String MAX_LINE_DEFAULT = "1000";
@@ -84,7 +81,7 @@ public class JDBCInterpreter extends Interpreter {
   static final String USER_KEY = "user";
   static final String PASSWORD_KEY = "password";
   static final String DOT = ".";
-  
+
   private static final char WHITESPACE = ' ';
   private static final char NEWLINE = '\n';
   private static final char TAB = '\t';
@@ -100,21 +97,33 @@ public class JDBCInterpreter extends Interpreter {
   static final String DEFAULT_PASSWORD = DEFAULT_KEY + DOT + PASSWORD_KEY;
 
   static final String EMPTY_COLUMN_VALUE = "";
-  
+
   private final HashMap<String, Properties> propertiesMap;
   private final Map<String, Statement> paragraphIdStatementMap;
 
   private final Map<String, ArrayList<Connection>> 
propertyKeyUnusedConnectionListMap;
   private final Map<String, Connection> paragraphIdConnectionMap;
 
+  private final Map<String, SqlCompleter> propertyKeySqlCompleterMap;
+
+  private static final Function<CharSequence, String> 
sequenceToStringTransformer =
+      new Function<CharSequence, String>() {
+        public String apply(CharSequence seq) {
+          return seq.toString();
+        }
+      };
+
+  private static final List<String> NO_COMPLETION = new ArrayList<>();
+
   public JDBCInterpreter(Properties property) {
     super(property);
     propertiesMap = new HashMap<>();
     propertyKeyUnusedConnectionListMap = new HashMap<>();
     paragraphIdStatementMap = new HashMap<>();
     paragraphIdConnectionMap = new HashMap<>();
+    propertyKeySqlCompleterMap = new HashMap<>();
   }
-  
+
   public HashMap<String, Properties> getPropertiesMap() {
     return propertiesMap;
   }
@@ -154,9 +163,38 @@ public class JDBCInterpreter extends Interpreter {
     }
 
     logger.debug("propertiesMap: {}", propertiesMap);
+
+    Connection connection = null;
+    SqlCompleter sqlCompleter = null;
+    for (String propertyKey : propertiesMap.keySet()) {
+      try {
+        connection = getConnection(propertyKey);
+        sqlCompleter = createSqlCompleter(connection);
+      } catch (Exception e) {
+        sqlCompleter = createSqlCompleter(null);
+      }
+      propertyKeySqlCompleterMap.put(propertyKey, sqlCompleter);
+    }
   }
-  
-  public Connection getConnection(String propertyKey)  throws 
ClassNotFoundException, SQLException {
+
+  private SqlCompleter createSqlCompleter(Connection jdbcConnection) {
+
+    SqlCompleter completer = null;
+    try {
+      Set<String> keywordsCompletions = 
SqlCompleter.getSqlKeywordsCompletions(jdbcConnection);
+      Set<String> dataModelCompletions =
+          SqlCompleter.getDataModelMetadataCompletions(jdbcConnection);
+      SetView<String> allCompletions = Sets.union(keywordsCompletions, 
dataModelCompletions);
+      completer = new SqlCompleter(allCompletions, dataModelCompletions);
+
+    } catch (IOException | SQLException e) {
+      logger.error("Cannot create SQL completer", e);
+    }
+
+    return completer;
+  }
+
+  public Connection getConnection(String propertyKey) throws 
ClassNotFoundException, SQLException {
     Connection connection = null;
     if (propertyKey == null || propertiesMap.get(propertyKey) == null) {
       return null;
@@ -180,7 +218,7 @@ public class JDBCInterpreter extends Interpreter {
     }
     return connection;
   }
-  
+
   public Statement getStatement(String propertyKey, String paragraphId)
       throws SQLException, ClassNotFoundException {
     Connection connection;
@@ -189,7 +227,7 @@ public class JDBCInterpreter extends Interpreter {
     } else {
       connection = getConnection(propertyKey);
     }
-    
+
     if (connection == null) {
       return null;
     }
@@ -213,7 +251,7 @@ public class JDBCInterpreter extends Interpreter {
       return false;
     }
   }
-  
+
   @Override
   public void close() {
 
@@ -241,13 +279,13 @@ public class JDBCInterpreter extends Interpreter {
 
   private InterpreterResult executeSql(String propertyKey, String sql,
       InterpreterContext interpreterContext) {
-    
+
     String paragraphId = interpreterContext.getParagraphId();
 
     try {
 
       Statement statement = getStatement(propertyKey, paragraphId);
-      
+
       if (statement == null) {
         return new InterpreterResult(Code.ERROR, "Prefix not found.");
       }
@@ -346,7 +384,7 @@ public class JDBCInterpreter extends Interpreter {
     if (null != propertyKey && !propertyKey.equals(DEFAULT_KEY)) {
       cmd = cmd.substring(propertyKey.length() + 2);
     }
-    
+
     cmd = cmd.trim();
 
     logger.info("PropertyKey: {}, SQL command: '{}'", propertyKey, cmd);
@@ -382,7 +420,7 @@ public class JDBCInterpreter extends Interpreter {
       return DEFAULT_KEY;
     }
   }
-  
+
   @Override
   public FormType getFormType() {
     return FormType.SIMPLE;
@@ -401,7 +439,13 @@ public class JDBCInterpreter extends Interpreter {
 
   @Override
   public List<String> completion(String buf, int cursor) {
-    return null;
+    List<CharSequence> candidates = new ArrayList<>();
+    SqlCompleter sqlCompleter = 
propertyKeySqlCompleterMap.get(getPropertyKey(buf));
+    if (sqlCompleter != null && sqlCompleter.complete(buf, cursor, candidates) 
>= 0) {
+      return Lists.transform(candidates, sequenceToStringTransformer);
+    } else {
+      return NO_COMPLETION;
+    }
   }
 
   public int getMaxResult() {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ccd8a49a/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
new file mode 100644
index 0000000..41dcaab
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java
@@ -0,0 +1,250 @@
+/**
+ * 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.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;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.*;
+import java.util.regex.Pattern;
+
+import static org.apache.commons.lang.StringUtils.isBlank;
+
+/**
+ * SQL auto complete functionality for the JdbcInterpreter.
+ */
+public class SqlCompleter extends StringsCompleter {
+
+  private static Logger logger = LoggerFactory.getLogger(SqlCompleter.class);
+
+  /**
+   * Delimiter that can split SQL statement in keyword list
+   */
+  private WhitespaceArgumentDelimiter sqlDelimiter = new 
WhitespaceArgumentDelimiter() {
+
+    private Pattern pattern = Pattern.compile("[\\.:;,]");
+
+    @Override
+    public boolean isDelimiterChar(CharSequence buffer, int pos) {
+      return pattern.matcher("" + buffer.charAt(pos)).matches()
+          || super.isDelimiterChar(buffer, pos);
+    }
+  };
+
+  private Set<String> modelCompletions = new HashSet<>();
+
+  public SqlCompleter(Set<String> allCompletions, Set<String> 
dataModelCompletions) {
+    super(allCompletions);
+    this.modelCompletions = dataModelCompletions;
+  }
+
+  @Override
+  public int complete(String buffer, int cursor, List<CharSequence> 
candidates) {
+
+    if (isBlank(buffer) || (cursor > buffer.length() + 1)) {
+      return -1;
+    }
+
+    // The delimiter breaks the buffer into separate words (arguments), 
separated by the
+    // white spaces.
+    ArgumentList argumentList = sqlDelimiter.delimit(buffer, cursor);
+    String argument = argumentList.getCursorArgument();
+    // cursor in the selected argument
+    int argumentPosition = argumentList.getArgumentPosition();
+
+    if (isBlank(argument)) {
+      int argumentsCount = argumentList.getArguments().length;
+      if (argumentsCount <= 0 || ((buffer.length() + 2) < cursor)
+          || sqlDelimiter.isDelimiterChar(buffer, cursor - 2)) {
+        return -1;
+      }
+      argument = argumentList.getArguments()[argumentsCount - 1];
+      argumentPosition = argument.length();
+    }
+
+    int complete = super.complete(argument, argumentPosition, candidates);
+
+    logger.debug("complete:" + complete + ", size:" + candidates.size());
+
+    return complete;
+  }
+
+  public void updateDataModelMetaData(Connection connection) {
+
+    try {
+      Set<String> newModelCompletions = 
getDataModelMetadataCompletions(connection);
+      logger.debug("New model metadata is:" + 
Joiner.on(',').join(newModelCompletions));
+
+      // Sets.difference(set1, set2) - returned set contains all elements that 
are contained by set1
+      // and not contained by set2. set2 may also contain elements not present 
in set1; these are
+      // simply ignored.
+      SetView<String> removedCompletions = Sets.difference(modelCompletions, 
newModelCompletions);
+      logger.debug("Removed Model Completions: " + 
Joiner.on(',').join(removedCompletions));
+      this.getStrings().removeAll(removedCompletions);
+
+      SetView<String> newCompletions = Sets.difference(newModelCompletions, 
modelCompletions);
+      logger.debug("New Completions: " + Joiner.on(',').join(newCompletions));
+      this.getStrings().addAll(newCompletions);
+
+      modelCompletions = newModelCompletions;
+
+    } catch (SQLException e) {
+      logger.error("Failed to update the metadata conmpletions", e);
+    }
+  }
+
+  public static Set<String> getSqlKeywordsCompletions(Connection connection) 
throws IOException,
+      SQLException {
+
+    // Add the default SQL completions
+    String keywords =
+        new BufferedReader(new InputStreamReader(
+            
SqlCompleter.class.getResourceAsStream("/ansi.sql.keywords"))).readLine();
+
+    Set<String> completions = new TreeSet<>();
+
+    if (null != connection) {
+      DatabaseMetaData metaData = connection.getMetaData();
+
+      // Add the driver specific SQL completions
+      String driverSpecificKeywords =
+          "/" + metaData.getDriverName().replace(" ", "-").toLowerCase() + 
"-sql.keywords";
+
+      logger.info("JDBC DriverName:" + driverSpecificKeywords);
+
+      if (SqlCompleter.class.getResource(driverSpecificKeywords) != null) {
+        String driverKeywords =
+            new BufferedReader(new InputStreamReader(
+                
SqlCompleter.class.getResourceAsStream(driverSpecificKeywords))).readLine();
+        keywords += "," + driverKeywords.toUpperCase();
+      }
+
+
+      // Add the keywords from the current JDBC connection
+      try {
+        keywords += "," + metaData.getSQLKeywords();
+      } catch (Exception e) {
+        logger.debug("fail to get SQL key words from database metadata: " + e, 
e);
+      }
+      try {
+        keywords += "," + metaData.getStringFunctions();
+      } catch (Exception e) {
+        logger.debug("fail to get string function names from database 
metadata: " + e, e);
+      }
+      try {
+        keywords += "," + metaData.getNumericFunctions();
+      } catch (Exception e) {
+        logger.debug("fail to get numeric function names from database 
metadata: " + e, e);
+      }
+      try {
+        keywords += "," + metaData.getSystemFunctions();
+      } catch (Exception e) {
+        logger.debug("fail to get system function names from database 
metadata: " + e, e);
+      }
+      try {
+        keywords += "," + metaData.getTimeDateFunctions();
+      } catch (Exception e) {
+        logger.debug("fail to get time date function names from database 
metadata: " + e, e);
+      }
+
+      // Also allow lower-case versions of all the keywords
+      keywords += "," + keywords.toLowerCase();
+
+    }
+
+    StringTokenizer tok = new StringTokenizer(keywords, ", ");
+    while (tok.hasMoreTokens()) {
+      completions.add(tok.nextToken());
+    }
+
+    return completions;
+  }
+
+  public static Set<String> getDataModelMetadataCompletions(Connection 
connection)
+      throws SQLException {
+    Set<String> completions = new TreeSet<>();
+    if (null != connection) {
+      getColumnNames(connection.getMetaData(), completions);
+      getSchemaNames(connection.getMetaData(), completions);
+    }
+    return completions;
+  }
+
+  private static void getColumnNames(DatabaseMetaData meta, Set<String> names) 
throws SQLException {
+
+    try {
+      ResultSet columns = meta.getColumns(meta.getConnection().getCatalog(), 
null, "%", "%");
+      try {
+
+        while (columns.next()) {
+          // Add the following strings: (1) column name, (2) table name
+          String name = columns.getString("TABLE_NAME");
+          if (!isBlank(name)) {
+            names.add(name);
+            names.add(columns.getString("COLUMN_NAME"));
+            // names.add(columns.getString("TABLE_NAME") + "." + 
columns.getString("COLUMN_NAME"));
+          }
+        }
+      } finally {
+        columns.close();
+      }
+
+      logger.debug(Joiner.on(',').join(names));
+    } catch (Exception e) {
+      logger.error("Failed to retrieve the column name", e);
+    }
+  }
+
+  private static void getSchemaNames(DatabaseMetaData meta, Set<String> names) 
throws SQLException {
+
+    try {
+      ResultSet schemas = meta.getSchemas();
+      try {
+        while (schemas.next()) {
+          String schemaName = schemas.getString("TABLE_SCHEM");
+          if (!isBlank(schemaName)) {
+            names.add(schemaName + ".");
+          }
+        }
+      } finally {
+        schemas.close();
+      }
+    } catch (Exception e) {
+      logger.error("Failed to retrieve the column name", e);
+    }
+  }
+
+  // test purpose only
+  WhitespaceArgumentDelimiter getSqlDelimiter() {
+    return this.sqlDelimiter;
+  }
+}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ccd8a49a/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
new file mode 100644
index 0000000..1f25a81
--- /dev/null
+++ b/jdbc/src/main/resources/ansi.sql.keywords
@@ -0,0 +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

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ccd8a49a/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
new file mode 100644
index 0000000..a857cbd
--- /dev/null
+++ b/jdbc/src/main/resources/postgresql-native-driver-sql.keywords
@@ -0,0 +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

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ccd8a49a/licenses/LICENSE-sqlline-1.0.2
----------------------------------------------------------------------
diff --git a/licenses/LICENSE-sqlline-1.0.2 b/licenses/LICENSE-sqlline-1.0.2
new file mode 100644
index 0000000..970974c
--- /dev/null
+++ b/licenses/LICENSE-sqlline-1.0.2
@@ -0,0 +1,10 @@
+Copyright (c)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this 
list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, 
this list of conditions and the following disclaimer in the documentation 
and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file

Reply via email to