This is an automated email from the ASF dual-hosted git repository.

kunal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git


The following commit(s) were added to refs/heads/master by this push:
     new a26d848  DRILL-6084: Show Drill functions in WebUI for autocomplete
a26d848 is described below

commit a26d848643e8d7851d8651a4d6c1f366624c3a70
Author: Kunal Khatua <[email protected]>
AuthorDate: Wed Oct 17 17:30:03 2018 -0700

    DRILL-6084: Show Drill functions in WebUI for autocomplete
    
    Building on top of DRILL-3988 and leveraging DRILL-5868, this allows 
support for Drill functions to be now available in the WebUI.
    If users wants UDFs to show up, they should place the UDF jars in the 
`$DRILL_HOME/jars/3rdparty` directory so that this can be loaded during the 
Drillbit's startup.
    Concept of internal Drill functions are introduced. With this, internal 
Drill functions like `ConvertToNullableXYZ` has been marked as internal.
    The WebUI will not show these functions. However, they are still visible in 
`sys.functions` table with an additional column indicating that it  is an 
internal function.
    Tests have been added as a part of this commit to verify the internal 
functions concept.
---
 .../CastEmptyStringVarTypesToNullableNumeric.java  |  2 +-
 .../codegen/templates/ConvertToNullableHolder.java |  3 +-
 .../exec/expr/annotations/FunctionTemplate.java    |  5 ++
 .../apache/drill/exec/expr/fn/DrillFuncHolder.java |  4 +
 .../drill/exec/expr/fn/FunctionAttributes.java     |  4 +
 .../expr/fn/FunctionImplementationRegistry.java    |  4 +
 .../apache/drill/exec/expr/fn/ValueReference.java  |  9 +++
 .../apache/drill/exec/server/rest/WebServer.java   | 86 +++++++++++++++++++---
 .../drill/exec/store/sys/FunctionsIterator.java    | 10 ++-
 .../mode-sql.js => ace.mode-sql.template.js}       | 17 +----
 .../src/main/resources/rest/query/query.ftl        |  3 +-
 .../drill/exec/store/sys/TestSystemTable.java      |  7 ++
 .../exec/work/metadata/TestMetadataProvider.java   |  2 +-
 13 files changed, 125 insertions(+), 31 deletions(-)

diff --git 
a/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java
 
b/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java
index e0942e9..6512771 100644
--- 
a/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java
+++ 
b/exec/java-exec/src/main/codegen/templates/CastEmptyStringVarTypesToNullableNumeric.java
@@ -48,7 +48,7 @@
  */
 
 @SuppressWarnings("unused")
-@FunctionTemplate(name = "castEmptyString${type.from}To${type.to?upper_case}", 
scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.INTERNAL)
+@FunctionTemplate(name = "castEmptyString${type.from}To${type.to?upper_case}", 
scope = FunctionTemplate.FunctionScope.SIMPLE, nulls=NullHandling.INTERNAL, 
isInternal=true)
 public class CastEmptyString${type.from}To${type.to} implements 
DrillSimpleFunc{
 
     @Param ${type.from}Holder in;
diff --git 
a/exec/java-exec/src/main/codegen/templates/ConvertToNullableHolder.java 
b/exec/java-exec/src/main/codegen/templates/ConvertToNullableHolder.java
index 7615bc5..875038c 100644
--- a/exec/java-exec/src/main/codegen/templates/ConvertToNullableHolder.java
+++ b/exec/java-exec/src/main/codegen/templates/ConvertToNullableHolder.java
@@ -42,7 +42,8 @@ import org.apache.drill.exec.record.RecordBatch;
     <#elseif minor.class.startsWith("Var")>
     returnType = FunctionTemplate.ReturnType.SAME_IN_OUT_LENGTH,
     </#if>
-    nulls = FunctionTemplate.NullHandling.INTERNAL)
+    nulls = FunctionTemplate.NullHandling.INTERNAL,
+    isInternal = true)
 public class ${className} implements DrillSimpleFunc {
 
   @Param ${minor.class}Holder input;
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
index 11914ea..3aa7365 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/annotations/FunctionTemplate.java
@@ -91,6 +91,11 @@ public @interface FunctionTemplate {
   boolean checkPrecisionRange() default false;
 
   /**
+   * Defines if a function is internal and not intended for public use [e.g. 
castEmptyStringNullableVarBinaryToNullableVarDecimal(..) ]
+   */
+  boolean isInternal() default false;
+
+  /**
    * This enum will be used to estimate the average size of the output
    * produced by a function that produces variable length output
    */
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
index d6f6ea2..fc021c9 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFuncHolder.java
@@ -107,6 +107,10 @@ public abstract class DrillFuncHolder extends 
AbstractFuncHolder {
   }
 
 
+  public boolean isInternal() {
+    return attributes.isInternal();
+  }
+
   /**
    * Generates string representation of function input parameters:
    * PARAMETER_TYPE_1-PARAMETER_MODE_1,PARAMETER_TYPE_2-PARAMETER_MODE_2
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionAttributes.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionAttributes.java
index 6d1b767..5f744e5 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionAttributes.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionAttributes.java
@@ -103,5 +103,9 @@ public class FunctionAttributes {
     return template.isNiladic();
   }
 
+  public boolean isInternal() {
+    return template.isInternal();
+  }
+
   public boolean checkPrecisionRange() { return 
template.checkPrecisionRange(); }
 }
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java
index a6f9a7f..5621c44 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/FunctionImplementationRegistry.java
@@ -293,6 +293,10 @@ public class FunctionImplementationRegistry implements 
FunctionLookupContext, Au
     return false;
   }
 
+  public LocalFunctionRegistry getLocalFunctionRegistry() {
+    return localFunctionRegistry;
+  }
+
   public RemoteFunctionRegistry getRemoteFunctionRegistry() {
     return remoteFunctionRegistry;
   }
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/ValueReference.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/ValueReference.java
index 42d3967..1ee39ff 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/ValueReference.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/ValueReference.java
@@ -28,6 +28,7 @@ public class ValueReference {
   private boolean isConstant = false;
   private boolean isFieldReader = false;
   private boolean isComplexWriter = false;
+  private boolean isInternal = false;
 
   public ValueReference(MajorType type, String name) {
     Preconditions.checkNotNull(type);
@@ -52,6 +53,14 @@ public class ValueReference {
     return isConstant;
   }
 
+  public void setInternal(boolean isInternal) {
+    this.isInternal = isInternal;
+  }
+
+  public boolean isInternal() {
+    return isInternal;
+  }
+
   public boolean isFieldReader() {
     return isFieldReader;
   }
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java
index fd9950e..8cab4dd 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/WebServer.java
@@ -20,8 +20,6 @@ package org.apache.drill.exec.server.rest;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.servlets.MetricsServlet;
 import com.codahale.metrics.servlets.ThreadDumpServlet;
-import org.apache.drill.shaded.guava.com.google.common.collect.Lists;
-import org.apache.drill.shaded.guava.com.google.common.io.Files;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.RandomStringUtils;
@@ -32,6 +30,8 @@ import org.apache.drill.common.exceptions.DrillException;
 import org.apache.drill.exec.ExecConstants;
 import org.apache.drill.exec.ssl.SSLConfig;
 import org.apache.drill.exec.exception.DrillbitStartupException;
+import org.apache.drill.exec.expr.fn.registry.FunctionHolder;
+import org.apache.drill.exec.expr.fn.registry.LocalFunctionRegistry;
 import org.apache.drill.exec.server.BootStrapContext;
 import org.apache.drill.exec.server.Drillbit;
 import org.apache.drill.exec.server.options.OptionList;
@@ -84,20 +84,34 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigInteger;
 import java.net.BindException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.SecureRandom;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.EnumSet;
 import java.util.List;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Wrapper class around jetty based webserver.
  */
 public class WebServer implements AutoCloseable {
+  private static final String ACE_MODE_SQL_TEMPLATE_JS = 
"ace.mode-sql.template.js";
+  private static final String ACE_MODE_SQL_JS = "mode-sql.js";
+  private static final String DRILL_FUNCTIONS_PLACEHOLDER = 
"__DRILL_FUNCTIONS__";
+
+  private static final String STATUS_THREADS_PATH = "/status/threads";
+  private static final String STATUS_METRICS_PATH = "/status/metrics";
+
   private static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(WebServer.class);
   private static final String OPTIONS_DESCRIBE_JS = "options.describe.js";
   private static final String OPTIONS_DESCRIBE_TEMPLATE_JS = 
"options.describe.template.js";
@@ -117,11 +131,12 @@ public class WebServer implements AutoCloseable {
 
   public File getTmpJavaScriptDir() {
     if (tmpJavaScriptDir == null) {
-      tmpJavaScriptDir = Files.createTempDir();
+      tmpJavaScriptDir = 
org.apache.drill.shaded.guava.com.google.common.io.Files.createTempDir();
       tmpJavaScriptDir.deleteOnExit();
       //Perform All auto generated files at this point
       try {
         generateOptionsDescriptionJSFile();
+        generateFunctionJS();
       } catch (IOException e) {
         logger.error("Unable to create temp dir for JavaScripts. {}", e);
       }
@@ -177,7 +192,7 @@ public class WebServer implements AutoCloseable {
     FilterHolder filterHolder = new FilterHolder(CrossOriginFilter.class);
     filterHolder.setInitParameter("allowedOrigins", "*");
     //Allowing CORS for metrics only
-    webServerContext.addFilter(filterHolder, "/status/metrics", null);
+    webServerContext.addFilter(filterHolder, STATUS_METRICS_PATH, null);
     embeddedJetty.setHandler(webServerContext);
 
     ServerConnector connector = createConnector(port, acceptors, selectors);
@@ -215,8 +230,8 @@ public class WebServer implements AutoCloseable {
     servletHolder.setInitOrder(1);
     servletContextHandler.addServlet(servletHolder, "/*");
 
-    servletContextHandler.addServlet(new ServletHolder(new 
MetricsServlet(metrics)), "/status/metrics");
-    servletContextHandler.addServlet(new ServletHolder(new 
ThreadDumpServlet()), "/status/threads");
+    servletContextHandler.addServlet(new ServletHolder(new 
MetricsServlet(metrics)), STATUS_METRICS_PATH);
+    servletContextHandler.addServlet(new ServletHolder(new 
ThreadDumpServlet()), STATUS_THREADS_PATH);
 
     final ServletHolder staticHolder = new ServletHolder("static", 
DefaultServlet.class);
     // Get resource URL for Drill static assets, based on where Drill icon is 
located
@@ -456,14 +471,15 @@ public class WebServer implements AutoCloseable {
     FileUtils.deleteDirectory(getTmpJavaScriptDir());
   }
 
-  private static final String FILE_CONTENT_FOOTER = "};";
-
-  //Generate Options Description JavaScript
+  /**
+   * Generate Options Description JavaScript to serve http://drillhost/options 
ACE library search features
+   * @throws IOException
+   */
   private void generateOptionsDescriptionJSFile() throws IOException {
     //Obtain list of Options & their descriptions
     OptionManager optionManager = 
this.drillbit.getContext().getOptionManager();
     OptionList publicOptions = optionManager.getPublicOptionList();
-    List<OptionValue> options = Lists.newArrayList(publicOptions);
+    List<OptionValue> options = new ArrayList<>(publicOptions);
     Collections.sort(options);
     int numLeftToWrite = options.size();
 
@@ -471,6 +487,7 @@ public class WebServer implements AutoCloseable {
     InputStream optionsDescripTemplateStream = 
Resource.newClassPathResource(OPTIONS_DESCRIBE_TEMPLATE_JS).getInputStream();
     //Generated file
     File optionsDescriptionFile = new File(getTmpJavaScriptDir(), 
OPTIONS_DESCRIBE_JS);
+    final String file_content_footer = "};";
     optionsDescriptionFile.deleteOnExit();
     //Create a copy of a template and write with that!
     java.nio.file.Files.copy(optionsDescripTemplateStream, 
optionsDescriptionFile.toPath());
@@ -490,9 +507,56 @@ public class WebServer implements AutoCloseable {
           writer.newLine();
         }
       }
-      writer.append(FILE_CONTENT_FOOTER);
+      writer.append(file_content_footer);
       writer.newLine();
       writer.flush();
     }
   }
+
+  /**
+   * Generates ACE library javascript populated with list of available SQL 
functions
+   * @throws IOException
+   */
+  private void generateFunctionJS() throws IOException {
+    //Naturally ordered set of function names
+    TreeSet<String> functionSet = new TreeSet<>();
+    //Extracting ONLY builtIn functions (i.e those already available)
+    List<FunctionHolder> builtInFuncHolderList = 
this.drillbit.getContext().getFunctionImplementationRegistry().getLocalFunctionRegistry()
+        .getAllJarsWithFunctionsHolders().get(LocalFunctionRegistry.BUILT_IN);
+
+    //Build List of 'usable' functions (i.e. functions that start with an 
alphabet and can be autocompleted by the ACE library)
+    //Example of 'unusable' functions would be operators like '<', '!'
+    int skipCount = 0;
+    for (FunctionHolder builtInFunctionHolder : builtInFuncHolderList) {
+      String name = builtInFunctionHolder.getName();
+      if (!name.contains(" ") && name.matches("([a-z]|[A-Z])\\w+") && 
!builtInFunctionHolder.getHolder().isInternal()) {
+        functionSet.add(name);
+      } else {
+        logger.debug("Non-alphabetic leading character. Function skipped : {} 
", name);
+        skipCount++;
+      }
+    }
+    logger.debug("{} functions will not be available in WebUI", skipCount);
+
+    //Generated file
+    File functionsListFile = new File(getTmpJavaScriptDir(), ACE_MODE_SQL_JS);
+    functionsListFile.deleteOnExit();
+    //Template source Javascript file
+    try (InputStream aceModeSqlTemplateStream = 
Resource.newClassPathResource(ACE_MODE_SQL_TEMPLATE_JS).getInputStream()) {
+      //Create a copy of a template and write with that!
+      java.nio.file.Files.copy(aceModeSqlTemplateStream, 
functionsListFile.toPath());
+    }
+
+    //Construct String
+    String funcListString = String.join("|", functionSet);
+
+    Path path = Paths.get(functionsListFile.getPath());
+    try (Stream<String> lines = Files.lines(path)) {
+      List <String> replaced =
+          lines //Replacing first occurrence
+            .map(line -> line.replaceFirst(DRILL_FUNCTIONS_PLACEHOLDER, 
funcListString))
+            .collect(Collectors.toList());
+      Files.write(path, replaced);
+    }
+  }
 }
diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/FunctionsIterator.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/FunctionsIterator.java
index 86e8817..63798a2 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/FunctionsIterator.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/FunctionsIterator.java
@@ -87,11 +87,12 @@ public class FunctionsIterator implements Iterator<Object> {
     String registeredNames[] = dfh.getRegisteredNames();
     String signature = dfh.getInputParameters();
     String returnType = dfh.getReturnType().getMinorType().toString();
+    boolean isInternal = dfh.isInternal();
     for (String name : registeredNames) {
       //Generate a unique key for a function holder as 
'functionName#functionSignature'
       //Bumping capacity from default 16 to 64 (since key is expected to be 
bigger, and reduce probability of resizing)
       String funcSignatureKey = new 
StringBuilder(64).append(name).append('#').append(signature).toString();
-      functionMap.put(funcSignatureKey, new FunctionInfo(name, signature, 
returnType, jarName));
+      functionMap.put(funcSignatureKey, new FunctionInfo(name, signature, 
returnType, jarName, isInternal));
     }
   }
 
@@ -117,12 +118,19 @@ public class FunctionsIterator implements 
Iterator<Object> {
     public final String returnType;
     @NonNullable
     public final String source;
+    @NonNullable
+    public final boolean internal;
 
     public FunctionInfo(String funcName, String funcSignature, String 
funcReturnType, String jarName) {
+      this(funcName, funcSignature, funcReturnType, jarName, false);
+    }
+
+    public FunctionInfo(String funcName, String funcSignature, String 
funcReturnType, String jarName, boolean isInternal) {
       this.name = funcName;
       this.signature = funcSignature;
       this.returnType = funcReturnType;
       this.source = jarName;
+      this.internal = isInternal;
     }
   }
 }
diff --git 
a/exec/java-exec/src/main/resources/rest/static/js/ace-code-editor/mode-sql.js 
b/exec/java-exec/src/main/resources/ace.mode-sql.template.js
similarity index 80%
rename from 
exec/java-exec/src/main/resources/rest/static/js/ace-code-editor/mode-sql.js
rename to exec/java-exec/src/main/resources/ace.mode-sql.template.js
index ceb47c8..057d8df 100644
--- 
a/exec/java-exec/src/main/resources/rest/static/js/ace-code-editor/mode-sql.js
+++ b/exec/java-exec/src/main/resources/ace.mode-sql.template.js
@@ -31,22 +31,9 @@ var SqlHighlightRules = function() {
         "true|false"
     );
 
-    //Drill-specific
+    //Drill-specific (auto-generated: See DRILL-6084)
     var builtinFunctions = (
-        //Math and Trignometric
-        
"abs|cbrt|ceil|ceiling|degrees|e|exp|floor|log|log|log10|lshift|mod|negative|pi|pow|radians|rand|round|round|rshift|sign|sqrt|trunc|trunc|"
 +
-        "sin|cos|tan|asin|acos|atan|sinh|cosh|tanh|" +
-        //datatype conversion
-        "cast|convert_to|convert_from|string_binary|binary_string|" +
-        //time-conversion
-        "to_char|to_date|to_number|to_timestamp|to_timestamp|" +
-        
"age|extract|current_date|current_time|current_timestamp|date_add|date_part|date_sub|localtime|localtimestamp|now|timeofday|unix_timestamp|"
 +
-        //string manipulation
-        
"byte_substr|char_length|concat|ilike|initcap|length|lower|lpad|ltrim|position|regexp_replace|rpad|rtrim|strpos|substr|trim|upper|"
 +
-        //statistical
-        
"avg|count|max|min|sum|stddev|stddev_pop|stddev_samp|variance|var_pop|var_samp|"
 +
-        //null-handling
-        "coalesce|nullif"
+        "__DRILL_FUNCTIONS__"
     );
 
     //Drill-specific
diff --git a/exec/java-exec/src/main/resources/rest/query/query.ftl 
b/exec/java-exec/src/main/resources/rest/query/query.ftl
index 936b1a5..078333e 100644
--- a/exec/java-exec/src/main/resources/rest/query/query.ftl
+++ b/exec/java-exec/src/main/resources/rest/query/query.ftl
@@ -25,7 +25,8 @@
     </#if>
   <!-- Ace Libraries for Syntax Formatting -->
   <script src="/static/js/ace-code-editor/ace.js" type="text/javascript" 
charset="utf-8"></script>
-  <script src="/static/js/ace-code-editor/mode-sql.js" type="text/javascript" 
charset="utf-8"></script>
+  <!-- Disabled in favour of dynamic: script 
src="/static/js/ace-code-editor/mode-sql.js" type="text/javascript" 
charset="utf-8" -->
+  <script src="/dynamic/mode-sql.js" type="text/javascript" 
charset="utf-8"></script>
   <script src="/static/js/ace-code-editor/ext-language_tools.js" 
type="text/javascript" charset="utf-8"></script>
   <script src="/static/js/ace-code-editor/theme-sqlserver.js" 
type="text/javascript" charset="utf-8"></script>
   <script src="/static/js/ace-code-editor/snippets/sql.js" 
type="text/javascript" charset="utf-8"></script>
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/store/sys/TestSystemTable.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/store/sys/TestSystemTable.java
index 5c9990a..2ed5f6e 100644
--- 
a/exec/java-exec/src/test/java/org/apache/drill/exec/store/sys/TestSystemTable.java
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/store/sys/TestSystemTable.java
@@ -82,6 +82,13 @@ public class TestSystemTable extends PlanTestBase {
   }
 
   @Test
+  public void testInternalFunctionsTable() throws Exception {
+    String query = "select internal, count(*) from sys.functions group by 
internal";
+    //Testing a mix of public and internal functions defined in 
FunctionTemplate
+    assertEquals(2, testSql(query));
+  }
+
+  @Test
   public void profilesTable() throws Exception {
     test("select * from sys.profiles");
   }
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/work/metadata/TestMetadataProvider.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/work/metadata/TestMetadataProvider.java
index ce58cb0..2e785b7 100644
--- 
a/exec/java-exec/src/test/java/org/apache/drill/exec/work/metadata/TestMetadataProvider.java
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/work/metadata/TestMetadataProvider.java
@@ -240,7 +240,7 @@ public class TestMetadataProvider extends BaseTestQuery {
 
     assertEquals(RequestStatus.OK, resp.getStatus());
     List<ColumnMetadata> columns = resp.getColumnsList();
-    assertEquals(139, columns.size());
+    assertEquals(140, columns.size());
     // too many records to verify the output.
   }
 

Reply via email to