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

cgivre 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 d44aa986ae DRILL-8501: Json Conversion UDF Not Respecting System JSON 
Options (#2921)
d44aa986ae is described below

commit d44aa986aea8c6f893edb2fa5525b2ca8bdef3b4
Author: Charles S. Givre <cgi...@apache.org>
AuthorDate: Tue Jul 9 11:01:04 2024 -0400

    DRILL-8501: Json Conversion UDF Not Respecting System JSON Options (#2921)
---
 .../exec/expr/fn/impl/conv/JsonConvertFrom.java    | 291 +++++++++++++++++++--
 .../exec/store/json/TestJsonConversionUDF.java     | 223 ++++++++++++++++
 .../drill/exec/store/json/TestJsonNanInf.java      | 101 ++-----
 .../src/test/resources/jsoninput/allTypes.csvh     |   2 +
 4 files changed, 516 insertions(+), 101 deletions(-)

diff --git 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/JsonConvertFrom.java
 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/JsonConvertFrom.java
index bbfc282914..61e64a55dc 100644
--- 
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/JsonConvertFrom.java
+++ 
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/conv/JsonConvertFrom.java
@@ -19,24 +19,23 @@ package org.apache.drill.exec.expr.fn.impl.conv;
 
 
 import io.netty.buffer.DrillBuf;
-
-import javax.inject.Inject;
-
 import org.apache.drill.exec.expr.DrillSimpleFunc;
 import org.apache.drill.exec.expr.annotations.FunctionTemplate;
 import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
 import org.apache.drill.exec.expr.annotations.Output;
 import org.apache.drill.exec.expr.annotations.Param;
 import org.apache.drill.exec.expr.annotations.Workspace;
+import org.apache.drill.exec.expr.holders.BitHolder;
 import org.apache.drill.exec.expr.holders.NullableVarBinaryHolder;
 import org.apache.drill.exec.expr.holders.NullableVarCharHolder;
 import org.apache.drill.exec.expr.holders.VarBinaryHolder;
 import org.apache.drill.exec.expr.holders.VarCharHolder;
+import org.apache.drill.exec.server.options.OptionManager;
 import org.apache.drill.exec.vector.complex.writer.BaseWriter.ComplexWriter;
 
-public class JsonConvertFrom {
+import javax.inject.Inject;
 
- static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(JsonConvertFrom.class);
+public class JsonConvertFrom {
 
   private JsonConvertFrom() {
   }
@@ -44,16 +43,75 @@ public class JsonConvertFrom {
   @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
   public static class ConvertFromJson implements DrillSimpleFunc {
 
-    @Param VarBinaryHolder in;
-    @Inject DrillBuf buffer;
-    @Workspace org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+    @Param
+    VarBinaryHolder in;
 
-    @Output ComplexWriter writer;
+    @Inject
+    DrillBuf buffer;
+
+    @Inject
+    OptionManager options;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+
+    @Output
+    ComplexWriter writer;
 
     @Override
     public void setup() {
+      boolean allTextMode = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_ALL_TEXT_MODE);
+      boolean readNumbersAsDouble = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+
+      jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
+          .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
+          .build();
+    }
+
+    @Override
+    public void eval() {
+      try {
+        jsonReader.setSource(in.start, in.end, in.buffer);
+        jsonReader.write(writer);
+        buffer = jsonReader.getWorkBuf();
+      } catch (Exception e) {
+        throw new 
org.apache.drill.common.exceptions.DrillRuntimeException("Error while 
converting from JSON. ", e);
+      }
+    }
+  }
+
+  @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
+  public static class ConvertFromJsonWithArgs implements DrillSimpleFunc {
+
+    @Param
+    VarBinaryHolder in;
+
+    @Param
+    BitHolder allTextModeHolder;
+
+    @Param
+    BitHolder readNumbersAsDoubleHolder;
+
+    @Inject
+    DrillBuf buffer;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+
+    @Output
+    ComplexWriter writer;
+
+    @Override
+    public void setup() {
+      boolean allTextMode = allTextModeHolder.value == 1;
+      boolean readNumbersAsDouble = readNumbersAsDoubleHolder.value == 1;
+
       jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
           .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
           .build();
     }
 
@@ -69,19 +127,79 @@ public class JsonConvertFrom {
     }
   }
 
+
   @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
   public static class ConvertFromJsonVarchar implements DrillSimpleFunc {
 
-    @Param VarCharHolder in;
-    @Inject DrillBuf buffer;
-    @Workspace org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+    @Param
+    VarCharHolder in;
 
-    @Output ComplexWriter writer;
+    @Inject
+    DrillBuf buffer;
+
+    @Inject
+    OptionManager options;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+
+    @Output
+    ComplexWriter writer;
 
     @Override
     public void setup() {
+      boolean allTextMode = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_ALL_TEXT_MODE);
+      boolean readNumbersAsDouble = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+
       jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
           .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
+          .build();
+    }
+
+    @Override
+    public void eval() {
+      try {
+        jsonReader.setSource(in.start, in.end, in.buffer);
+        jsonReader.write(writer);
+        buffer = jsonReader.getWorkBuf();
+      } catch (Exception e) {
+        throw new 
org.apache.drill.common.exceptions.DrillRuntimeException("Error while 
converting from JSON. ", e);
+      }
+    }
+  }
+
+  @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
+  public static class ConvertFromJsonVarcharWithConfig implements 
DrillSimpleFunc {
+
+    @Param
+    VarCharHolder in;
+
+    @Param
+    BitHolder allTextModeHolder;
+
+    @Param
+    BitHolder readNumbersAsDoubleHolder;
+
+    @Inject
+    DrillBuf buffer;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+
+    @Output
+    ComplexWriter writer;
+
+    @Override
+    public void setup() {
+      boolean allTextMode = allTextModeHolder.value == 1;
+      boolean readNumbersAsDouble = readNumbersAsDoubleHolder.value == 1;
+
+      jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
+          .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
           .build();
     }
 
@@ -100,16 +218,83 @@ public class JsonConvertFrom {
   @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
   public static class ConvertFromJsonNullableInput implements DrillSimpleFunc {
 
-    @Param NullableVarBinaryHolder in;
-    @Inject DrillBuf buffer;
-    @Workspace org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+    @Param
+    NullableVarBinaryHolder in;
 
-    @Output ComplexWriter writer;
+    @Inject
+    DrillBuf buffer;
+
+    @Inject
+    OptionManager options;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+
+    @Output
+    ComplexWriter writer;
+
+    @Override
+    public void setup() {
+      boolean allTextMode = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_ALL_TEXT_MODE);
+      boolean readNumbersAsDouble = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+
+      jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
+          .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
+          .build();
+    }
+
+    @Override
+    public void eval() {
+      if (in.isSet == 0) {
+        // Return empty map
+        org.apache.drill.exec.vector.complex.writer.BaseWriter.MapWriter 
mapWriter = writer.rootAsMap();
+        mapWriter.start();
+        mapWriter.end();
+        return;
+      }
+
+      try {
+        jsonReader.setSource(in.start, in.end, in.buffer);
+        jsonReader.write(writer);
+        buffer = jsonReader.getWorkBuf();
+      } catch (Exception e) {
+        throw new 
org.apache.drill.common.exceptions.DrillRuntimeException("Error while 
converting from JSON. ", e);
+      }
+    }
+  }
+
+  @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
+  public static class ConvertFromJsonNullableInputWithArgs implements 
DrillSimpleFunc {
+
+    @Param
+    NullableVarBinaryHolder in;
+
+    @Param
+    BitHolder allTextModeHolder;
+
+    @Param
+    BitHolder readNumbersAsDoubleHolder;
+
+    @Inject
+    DrillBuf buffer;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+
+    @Output
+    ComplexWriter writer;
 
     @Override
     public void setup() {
+      boolean allTextMode = allTextModeHolder.value == 1;
+      boolean readNumbersAsDouble = readNumbersAsDoubleHolder.value == 1;
+
       jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
           .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
           .build();
     }
 
@@ -136,16 +321,29 @@ public class JsonConvertFrom {
   @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
   public static class ConvertFromJsonVarcharNullableInput implements 
DrillSimpleFunc {
 
-    @Param NullableVarCharHolder in;
-    @Inject DrillBuf buffer;
-    @Workspace org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+    @Param
+    NullableVarCharHolder in;
+
+    @Inject
+    DrillBuf buffer;
+
+    @Inject
+    OptionManager options;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
 
     @Output ComplexWriter writer;
 
     @Override
     public void setup() {
+      boolean allTextMode = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_ALL_TEXT_MODE);
+      boolean readNumbersAsDouble = 
options.getBoolean(org.apache.drill.exec.ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+
       jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
           .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
           .build();
     }
 
@@ -168,4 +366,57 @@ public class JsonConvertFrom {
       }
     }
   }
+
+  @FunctionTemplate(name = "convert_fromJSON", scope = FunctionScope.SIMPLE, 
isRandom = true)
+  public static class ConvertFromJsonVarcharNullableInputWithConfigs 
implements DrillSimpleFunc {
+
+    @Param
+    NullableVarCharHolder in;
+
+    @Param
+    BitHolder allTextModeHolder;
+
+    @Param
+    BitHolder readNumbersAsDoubleHolder;
+
+    @Inject
+    DrillBuf buffer;
+
+    @Workspace
+    org.apache.drill.exec.vector.complex.fn.JsonReader jsonReader;
+
+    @Output ComplexWriter writer;
+
+    @Override
+    public void setup() {
+      boolean allTextMode = allTextModeHolder.value == 1;
+      boolean readNumbersAsDouble = readNumbersAsDoubleHolder.value == 1;
+
+      jsonReader = new 
org.apache.drill.exec.vector.complex.fn.JsonReader.Builder(buffer)
+          .defaultSchemaPathColumns()
+          .allTextMode(allTextMode)
+          .readNumbersAsDouble(readNumbersAsDouble)
+          .build();
+    }
+
+    @Override
+    public void eval() {
+      if (in.isSet == 0) {
+        // Return empty map
+        org.apache.drill.exec.vector.complex.writer.BaseWriter.MapWriter 
mapWriter = writer.rootAsMap();
+        mapWriter.start();
+        mapWriter.end();
+        return;
+      }
+
+      try {
+        jsonReader.setSource(in.start, in.end, in.buffer);
+        jsonReader.write(writer);
+        buffer = jsonReader.getWorkBuf();
+      } catch (Exception e) {
+        throw new 
org.apache.drill.common.exceptions.DrillRuntimeException("Error while 
converting from JSON. ", e);
+      }
+    }
+  }
+
 }
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/store/json/TestJsonConversionUDF.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/store/json/TestJsonConversionUDF.java
new file mode 100644
index 0000000000..d6fa857a39
--- /dev/null
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/store/json/TestJsonConversionUDF.java
@@ -0,0 +1,223 @@
+/*
+ * 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.drill.exec.store.json;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.exec.ExecConstants;
+import org.apache.drill.exec.record.RecordBatchLoader;
+import org.apache.drill.exec.record.VectorWrapper;
+import org.apache.drill.exec.rpc.user.QueryDataBatch;
+import org.apache.drill.exec.vector.VarCharVector;
+import org.apache.drill.test.BaseTestQuery;
+import org.junit.Test;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.List;
+
+import static org.apache.drill.test.TestBuilder.mapOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class TestJsonConversionUDF extends BaseTestQuery {
+
+  @Test
+  public void doTestConvertFromJsonFunction() throws Exception {
+    String table = "nan_test.csv";
+    File file = new File(dirTestWatcher.getRootDir(), table);
+    String csv = "col_0, {\"nan_col\":NaN}";
+    try {
+      FileUtils.writeStringToFile(file, csv, Charset.defaultCharset());
+      testBuilder()
+          .sqlQuery(String.format("select convert_fromJSON(columns[1]) as col 
from dfs.`%s`", table))
+          .unOrdered()
+          .baselineColumns("col")
+          .baselineValues(mapOf("nan_col", Double.NaN))
+          .go();
+    } finally {
+      FileUtils.deleteQuietly(file);
+    }
+  }
+
+  @Test
+  public void doTestConvertToJsonFunction() throws Exception {
+    String table = "nan_test.csv";
+    File file = new File(dirTestWatcher.getRootDir(), table);
+    String csv = "col_0, {\"nan_col\":NaN}";
+    String query = String.format("select 
string_binary(convert_toJSON(convert_fromJSON(columns[1]))) as col " +
+        "from dfs.`%s` where columns[0]='col_0'", table);
+    try {
+      FileUtils.writeStringToFile(file, csv, Charset.defaultCharset());
+      List<QueryDataBatch> results = testSqlWithResults(query);
+      RecordBatchLoader batchLoader = new RecordBatchLoader(getAllocator());
+      assertEquals("Query result must contain 1 row", 1, results.size());
+      QueryDataBatch batch = results.get(0);
+
+      batchLoader.load(batch.getHeader().getDef(), batch.getData());
+      VectorWrapper<?> vw = 
batchLoader.getValueAccessorById(VarCharVector.class, 
batchLoader.getValueVectorId(SchemaPath.getCompoundPath("col")).getFieldIds());
+      // ensuring that `NaN` token ARE NOT enclosed with double quotes
+      String resultJson = 
vw.getValueVector().getAccessor().getObject(0).toString();
+      int nanIndex = resultJson.indexOf("NaN");
+      assertNotEquals("`NaN` must not be enclosed with \"\" ", '"', 
resultJson.charAt(nanIndex - 1));
+      assertNotEquals("`NaN` must not be enclosed with \"\" ", '"', 
resultJson.charAt(nanIndex + "NaN".length()));
+      batch.release();
+      batchLoader.clear();
+    } finally {
+      FileUtils.deleteQuietly(file);
+    }
+  }
+
+  @Test
+  public void testAllTextMode() throws Exception {
+    alterSession(ExecConstants.JSON_ALL_TEXT_MODE, true);
+    alterSession(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE, false);
+
+    String sql = "SELECT \n" +
+        "typeof(jsonMap['bi']) AS bi, \n" +
+        "typeof(jsonMap['fl']) AS fl, \n" +
+        "typeof(jsonMap['st']) AS st, \n" +
+        "typeof(jsonMap['mp']) AS mp, \n" +
+        "typeof(jsonMap['ar']) AS ar, \n" +
+        "typeof(jsonMap['nu']) AS nu\n" +
+        "FROM(\n" +
+        "SELECT convert_fromJSON(col1) AS jsonMap, \n" +
+        "col2 \n" +
+        "FROM cp.`jsoninput/allTypes.csvh`\n" +
+        ")";
+
+    testBuilder()
+        .sqlQuery(sql)
+        .unOrdered()
+        .baselineColumns("bi", "fl", "st", "mp", "ar", "nu")
+        .baselineValues("VARCHAR", "VARCHAR", "VARCHAR", "MAP", "VARCHAR", 
"NULL")
+        .go();
+
+    alterSession(ExecConstants.JSON_ALL_TEXT_MODE, false);
+
+    testBuilder()
+        .sqlQuery(sql)
+        .unOrdered()
+        .baselineColumns("bi", "fl", "st", "mp", "ar", "nu")
+        .baselineValues("BIGINT", "FLOAT8", "VARCHAR", "MAP", "BIGINT", "NULL")
+        .go();
+
+    resetSessionOption(ExecConstants.JSON_ALL_TEXT_MODE);
+    resetSessionOption(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+  }
+
+  @Test
+  public void testAllTextModeFromArgs() throws Exception {
+    // Set the system options to make sure that the UDF is using the provided 
options rather than
+    // the system options.
+    alterSession(ExecConstants.JSON_ALL_TEXT_MODE, false);
+    alterSession(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE, true);
+
+    String sql = "SELECT \n" +
+        "typeof(jsonMap['bi']) AS bi, \n" +
+        "typeof(jsonMap['fl']) AS fl, \n" +
+        "typeof(jsonMap['st']) AS st, \n" +
+        "typeof(jsonMap['mp']) AS mp, \n" +
+        "typeof(jsonMap['ar']) AS ar, \n" +
+        "typeof(jsonMap['nu']) AS nu\n" +
+        "FROM(\n" +
+        "SELECT convert_fromJSON(col1, true, false) AS jsonMap, \n" +
+        "col2 \n" +
+        "FROM cp.`jsoninput/allTypes.csvh`\n" +
+        ")";
+
+    testBuilder()
+        .sqlQuery(sql)
+        .unOrdered()
+        .baselineColumns("bi", "fl", "st", "mp", "ar", "nu")
+        .baselineValues("VARCHAR", "VARCHAR", "VARCHAR", "MAP", "VARCHAR", 
"NULL")
+        .go();
+
+    resetSessionOption(ExecConstants.JSON_ALL_TEXT_MODE);
+    resetSessionOption(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+  }
+
+
+  @Test
+  public void testReadNumbersAsDouble() throws Exception {
+    alterSession(ExecConstants.JSON_ALL_TEXT_MODE, false);
+    alterSession(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE, true);
+
+    String sql = "SELECT \n" +
+        "typeof(jsonMap['bi']) AS bi, \n" +
+        "typeof(jsonMap['fl']) AS fl, \n" +
+        "typeof(jsonMap['st']) AS st, \n" +
+        "typeof(jsonMap['mp']) AS mp, \n" +
+        "typeof(jsonMap['ar']) AS ar, \n" +
+        "typeof(jsonMap['nu']) AS nu\n" +
+        "FROM(\n" +
+        "SELECT convert_fromJSON(col1) AS jsonMap, \n" +
+        "col2 \n" +
+        "FROM cp.`jsoninput/allTypes.csvh`\n" +
+        ")";
+
+    testBuilder()
+        .sqlQuery(sql)
+        .unOrdered()
+        .baselineColumns("bi", "fl", "st", "mp", "ar", "nu")
+        .baselineValues("FLOAT8", "FLOAT8", "VARCHAR", "MAP", "FLOAT8", "NULL")
+        .go();
+
+    alterSession(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE, true);
+    testBuilder()
+        .sqlQuery(sql)
+        .unOrdered()
+        .baselineColumns("bi", "fl", "st", "mp", "ar", "nu")
+        .baselineValues("FLOAT8", "FLOAT8", "VARCHAR", "MAP", "FLOAT8", "NULL")
+        .go();
+
+    resetSessionOption(ExecConstants.JSON_ALL_TEXT_MODE);
+    resetSessionOption(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+  }
+
+  @Test
+  public void testReadNumbersAsDoubleFromArgs() throws Exception {
+    // Set the system options to make sure that the UDF is using the provided 
options rather than
+    // the system options.
+    alterSession(ExecConstants.JSON_ALL_TEXT_MODE, true);
+    alterSession(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE, true);
+    String sql = "SELECT \n" +
+        "typeof(jsonMap['bi']) AS bi, \n" +
+        "typeof(jsonMap['fl']) AS fl, \n" +
+        "typeof(jsonMap['st']) AS st, \n" +
+        "typeof(jsonMap['mp']) AS mp, \n" +
+        "typeof(jsonMap['ar']) AS ar, \n" +
+        "typeof(jsonMap['nu']) AS nu\n" +
+        "FROM(\n" +
+        "SELECT convert_fromJSON(col1, false, true) AS jsonMap, \n" +
+        "col2 \n" +
+        "FROM cp.`jsoninput/allTypes.csvh`\n" +
+        ")";
+
+    testBuilder()
+        .sqlQuery(sql)
+        .unOrdered()
+        .baselineColumns("bi", "fl", "st", "mp", "ar", "nu")
+        .baselineValues("FLOAT8", "FLOAT8", "VARCHAR", "MAP", "FLOAT8", "NULL")
+        .go();
+
+    resetSessionOption(ExecConstants.JSON_ALL_TEXT_MODE);
+    resetSessionOption(ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
+  }
+}
diff --git 
a/exec/java-exec/src/test/java/org/apache/drill/exec/store/json/TestJsonNanInf.java
 
b/exec/java-exec/src/test/java/org/apache/drill/exec/store/json/TestJsonNanInf.java
index e556ec16ea..ae4e2f8be7 100644
--- 
a/exec/java-exec/src/test/java/org/apache/drill/exec/store/json/TestJsonNanInf.java
+++ 
b/exec/java-exec/src/test/java/org/apache/drill/exec/store/json/TestJsonNanInf.java
@@ -17,31 +17,23 @@
  */
 package org.apache.drill.exec.store.json;
 
-import static org.apache.drill.test.TestBuilder.mapOf;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.util.List;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.drill.common.exceptions.UserRemoteException;
-import org.apache.drill.common.expression.SchemaPath;
 import org.apache.drill.exec.ExecConstants;
 import org.apache.drill.exec.physical.impl.join.JoinTestBase;
-import org.apache.drill.exec.record.RecordBatchLoader;
-import org.apache.drill.exec.record.VectorWrapper;
-import org.apache.drill.exec.rpc.user.QueryDataBatch;
-import org.apache.drill.exec.vector.VarCharVector;
 import org.apache.drill.exec.store.json.TestJsonReader.TestWrapper;
 import org.apache.drill.test.BaseTestQuery;
 import org.junit.Ignore;
 import org.junit.Test;
 
-// TODO: Split or rename: this tests mor than NanInf
+import java.io.File;
+import java.nio.charset.Charset;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
+
 public class TestJsonNanInf extends BaseTestQuery {
 
   public void runBoth(TestWrapper wrapper) throws Exception {
@@ -66,7 +58,7 @@ public class TestJsonNanInf extends BaseTestQuery {
     String json = "{\"nan_col\":NaN, \"inf_col\":Infinity}";
     String query = String.format("select * from dfs.`%s`",table);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       testBuilder()
         .sqlQuery(query)
         .unOrdered()
@@ -91,7 +83,7 @@ public class TestJsonNanInf extends BaseTestQuery {
         "{\"nan_col\":5.0, \"inf_col\":5.0}]";
     String query = String.format("select inf_col from dfs.`%s` where inf_col 
<> cast('Infinity' as double)",table);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       testBuilder()
         .sqlQuery(query)
         .unOrdered()
@@ -116,7 +108,7 @@ public class TestJsonNanInf extends BaseTestQuery {
         "{\"nan_col\":5.0, \"inf_col\":5.0}]";
     String query = String.format("select inf_col from dfs.`%s` where inf_col 
<> cast('-Infinity' as double)",table);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       testBuilder()
         .sqlQuery(query)
         .unOrdered()
@@ -141,7 +133,7 @@ public class TestJsonNanInf extends BaseTestQuery {
         "{\"nan_col\":5.0, \"inf_col\":5.0}]";
     String query = String.format("select inf_col from dfs.`%s` where inf_col = 
cast('Infinity' as double)",table);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       testBuilder()
           .sqlQuery(query)
           .unOrdered()
@@ -166,7 +158,7 @@ public class TestJsonNanInf extends BaseTestQuery {
         "{\"nan_col\":5.0, \"inf_col\":5.0}]";
     String query = String.format("select nan_col from dfs.`%s` where 
cast(nan_col as varchar) <> 'NaN'",table);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       testBuilder()
           .sqlQuery(query)
           .unOrdered()
@@ -190,7 +182,7 @@ public class TestJsonNanInf extends BaseTestQuery {
         "{\"nan_col\":5.0, \"inf_col\":5.0}]";
     String query = String.format("select nan_col from dfs.`%s` where 
cast(nan_col as varchar) = 'NaN'",table);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       testBuilder()
           .sqlQuery(query)
           .unOrdered()
@@ -213,7 +205,7 @@ public class TestJsonNanInf extends BaseTestQuery {
     test("alter session set `%s` = false", 
ExecConstants.JSON_READER_NAN_INF_NUMBERS);
     String json = "{\"nan_col\":NaN, \"inf_col\":Infinity}";
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       test("select * from dfs.`%s`;", table);
       fail();
     } catch (UserRemoteException e) {
@@ -235,7 +227,7 @@ public class TestJsonNanInf extends BaseTestQuery {
     String json = "{\"nan_col\":NaN, \"inf_col\":Infinity}";
     String newTable = "ctas_test";
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       test("alter session set `store.format`='json'");
       test("create table dfs.`%s` as select * from dfs.`%s`;", newTable, 
table);
 
@@ -254,28 +246,6 @@ public class TestJsonNanInf extends BaseTestQuery {
     }
   }
 
-  @Test
-  public void testConvertFromJsonFunction() throws Exception {
-    runBoth(this::doTestConvertFromJsonFunction);
-  }
-
-  private void doTestConvertFromJsonFunction() throws Exception {
-    String table = "nan_test.csv";
-    File file = new File(dirTestWatcher.getRootDir(), table);
-    String csv = "col_0, {\"nan_col\":NaN}";
-    try {
-      FileUtils.writeStringToFile(file, csv);
-      testBuilder()
-          .sqlQuery(String.format("select convert_fromJSON(columns[1]) as col 
from dfs.`%s`", table))
-          .unOrdered()
-          .baselineColumns("col")
-          .baselineValues(mapOf("nan_col", Double.NaN))
-          .go();
-    } finally {
-      FileUtils.deleteQuietly(file);
-    }
-  }
-
   @Test
   public void testLargeStringBinary() throws Exception {
     runBoth(() -> doTestLargeStringBinary());
@@ -291,37 +261,6 @@ public class TestJsonNanInf extends BaseTestQuery {
     test("select string_binary(binary_string('%s')) from (values(1))", data);
  }
 
-  @Test
-  public void testConvertToJsonFunction() throws Exception {
-    runBoth(() -> doTestConvertToJsonFunction());
-  }
-
-  private void doTestConvertToJsonFunction() throws Exception {
-    String table = "nan_test.csv";
-    File file = new File(dirTestWatcher.getRootDir(), table);
-    String csv = "col_0, {\"nan_col\":NaN}";
-    String query = String.format("select 
string_binary(convert_toJSON(convert_fromJSON(columns[1]))) as col " +
-        "from dfs.`%s` where columns[0]='col_0'", table);
-    try {
-      FileUtils.writeStringToFile(file, csv);
-      List<QueryDataBatch> results = testSqlWithResults(query);
-      RecordBatchLoader batchLoader = new RecordBatchLoader(getAllocator());
-      assertEquals("Query result must contain 1 row", 1, results.size());
-      QueryDataBatch batch = results.get(0);
-
-      batchLoader.load(batch.getHeader().getDef(), batch.getData());
-      VectorWrapper<?> vw = 
batchLoader.getValueAccessorById(VarCharVector.class, 
batchLoader.getValueVectorId(SchemaPath.getCompoundPath("col")).getFieldIds());
-      // ensuring that `NaN` token ARE NOT enclosed with double quotes
-      String resultJson = 
vw.getValueVector().getAccessor().getObject(0).toString();
-      int nanIndex = resultJson.indexOf("NaN");
-      assertNotEquals("`NaN` must not be enclosed with \"\" ", '"', 
resultJson.charAt(nanIndex - 1));
-      assertNotEquals("`NaN` must not be enclosed with \"\" ", '"', 
resultJson.charAt(nanIndex + "NaN".length()));
-      batch.release();
-      batchLoader.clear();
-    } finally {
-      FileUtils.deleteQuietly(file);
-    }
-  }
 
   @Test
   @Ignore("DRILL-6018")
@@ -350,7 +289,7 @@ public class TestJsonNanInf extends BaseTestQuery {
 
     File file = new File(dirTestWatcher.getRootDir(), table_name);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       test("alter session set `%s` = true", 
ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
       testBuilder()
           .sqlQuery(query)
@@ -391,7 +330,7 @@ public class TestJsonNanInf extends BaseTestQuery {
 
     File file = new File(dirTestWatcher.getRootDir(), table_name);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       test("alter session set `%s` = true", 
ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
       testBuilder()
           .sqlQuery(query)
@@ -426,7 +365,7 @@ public class TestJsonNanInf extends BaseTestQuery {
 
     File file = new File(dirTestWatcher.getRootDir(), table_name);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       test("alter session set `%s` = true", 
ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
       testBuilder()
           .sqlQuery(query)
@@ -459,7 +398,7 @@ public class TestJsonNanInf extends BaseTestQuery {
 
     File file = new File(dirTestWatcher.getRootDir(), table_name);
     try {
-      FileUtils.writeStringToFile(file, json);
+      FileUtils.writeStringToFile(file, json, Charset.defaultCharset());
       test("alter session set `%s` = true", 
ExecConstants.JSON_READ_NUMBERS_AS_DOUBLE);
       testBuilder()
           .sqlQuery(query)
diff --git a/exec/java-exec/src/test/resources/jsoninput/allTypes.csvh 
b/exec/java-exec/src/test/resources/jsoninput/allTypes.csvh
new file mode 100644
index 0000000000..99a6731b18
--- /dev/null
+++ b/exec/java-exec/src/test/resources/jsoninput/allTypes.csvh
@@ -0,0 +1,2 @@
+col1,col2
+"{bi: 123,fl: 123.4,st: ""foo"",mp: { a: 10, b: ""bar"" },ar: [ 10, 20 ],nu: 
null}", 2

Reply via email to