calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jh...@apache.org
Subject [04/10] calcite git commit: [CALCITE-1667] Forbid calls to JDK APIs that use the default locale, time zone or character set
Date Sat, 04 Mar 2017 21:03:23 GMT
http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/DiffTestCase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/DiffTestCase.java b/core/src/test/java/org/apache/calcite/test/DiffTestCase.java
index 7e3adee..c8a9a89 100644
--- a/core/src/test/java/org/apache/calcite/test/DiffTestCase.java
+++ b/core/src/test/java/org/apache/calcite/test/DiffTestCase.java
@@ -17,6 +17,7 @@
 package org.apache.calcite.test;
 
 import org.apache.calcite.util.ReflectUtil;
+import org.apache.calcite.util.Util;
 
 import org.incava.util.diff.Diff;
 import org.incava.util.diff.Difference;
@@ -24,15 +25,18 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.LineNumberReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -71,8 +75,6 @@ public abstract class DiffTestCase {
   private String ignorePatterns;
   Matcher compiledIgnoreMatcher;
 
-  int gcInterval;
-
   /**
    * Whether to give verbose message if diff fails.
    */
@@ -92,7 +94,6 @@ public abstract class DiffTestCase {
     ignorePatterns = "";
     compiledIgnoreMatcher = null;
     compiledDiffMatcher = null;
-    gcInterval = 0;
     String verboseVal =
         System.getProperty(DiffTestCase.class.getName() + ".verbose");
     if (verboseVal != null) {
@@ -109,7 +110,6 @@ public abstract class DiffTestCase {
     ignorePatterns = "";
     compiledIgnoreMatcher = null;
     compiledDiffMatcher = null;
-    gcInterval = 0;
   }
 
   @After
@@ -142,7 +142,8 @@ public abstract class DiffTestCase {
         new File(
             testClassDir,
             testCaseName);
-    return new OutputStreamWriter(openTestLogOutputStream(testLogFile));
+    return new OutputStreamWriter(
+        openTestLogOutputStream(testLogFile), StandardCharsets.UTF_8);
   }
 
   /**
@@ -206,19 +207,9 @@ public abstract class DiffTestCase {
    */
   protected void diffFile(File logFile, File refFile) throws IOException {
     int n = 0;
-    FileReader logReader = null;
-    FileReader refReader = null;
+    BufferedReader logReader = null;
+    BufferedReader refReader = null;
     try {
-      if (compiledIgnoreMatcher != null) {
-        if (gcInterval != 0) {
-          n++;
-          if (n == gcInterval) {
-            n = 0;
-            System.gc();
-          }
-        }
-      }
-
       // NOTE: Use of diff.mask is deprecated, use diff_mask.
       String diffMask = System.getProperty("diff.mask", null);
       if (diffMask != null) {
@@ -230,8 +221,8 @@ public abstract class DiffTestCase {
         addDiffMask(diffMask);
       }
 
-      logReader = new FileReader(logFile);
-      refReader = new FileReader(refFile);
+      logReader = Util.reader(logFile);
+      refReader = Util.reader(refFile);
       LineNumberReader logLineReader = new LineNumberReader(logReader);
       LineNumberReader refLineReader = new LineNumberReader(refReader);
       for (;;) {
@@ -280,16 +271,6 @@ public abstract class DiffTestCase {
   }
 
   /**
-   * set the number of lines for garbage collection.
-   *
-   * @param n an integer, the number of line for garbage collection, 0 means
-   *          no garbage collection.
-   */
-  protected void setGC(int n) {
-    gcInterval = n;
-  }
-
-  /**
    * Adds a diff mask. Strings matching the given regular expression will be
    * masked before diffing. This can be used to suppress spurious diffs on a
    * case-by-case basis.
@@ -471,9 +452,8 @@ public abstract class DiffTestCase {
    * @return List of lines
    */
   private static List<String> fileLines(File file) {
-    List<String> lines = new ArrayList<String>();
-    try {
-      LineNumberReader r = new LineNumberReader(new FileReader(file));
+    List<String> lines = new ArrayList<>();
+    try (LineNumberReader r = new LineNumberReader(Util.reader(file))) {
       String line;
       while ((line = r.readLine()) != null) {
         lines.add(line);
@@ -492,15 +472,14 @@ public abstract class DiffTestCase {
    * @return Contents of the file
    */
   protected static String fileContents(File file) {
-    try {
-      char[] buf = new char[2048];
-      final FileReader reader = new FileReader(file);
+    byte[] buf = new byte[2048];
+    try (final FileInputStream reader = new FileInputStream(file)) {
       int readCount;
-      final StringWriter writer = new StringWriter();
+      final ByteArrayOutputStream writer = new ByteArrayOutputStream();
       while ((readCount = reader.read(buf)) >= 0) {
         writer.write(buf, 0, readCount);
       }
-      return writer.toString();
+      return writer.toString(StandardCharsets.UTF_8.name());
     } catch (IOException e) {
       throw new RuntimeException(e);
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 5196732..2fcbb0a 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -108,7 +108,6 @@ import org.junit.Ignore;
 import org.junit.Test;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.Reader;
@@ -132,6 +131,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
@@ -5233,8 +5233,7 @@ public class JdbcTest {
   private void checkCustomSchemaInFileInPwd(String fileName)
       throws SQLException {
     final File file = new File(fileName);
-    try (final FileWriter fw = new FileWriter(file);
-         final PrintWriter pw = new PrintWriter(fw)) {
+    try (final PrintWriter pw = Util.printWriter(file)) {
       file.deleteOnExit();
       pw.println("{\n"
           + "  version: '1.0',\n"
@@ -5673,6 +5672,8 @@ public class JdbcTest {
   @Test public void testGetTimestamp() throws Exception {
     CalciteAssert.that()
         .with("timezone", "GMT+1:00")
+        // Workaround, until [CALCITE-1667] is fixed in Avatica
+        .with("TIME_ZONE", "GMT+1:00")
         .doWithConnection(
             new Function<CalciteConnection, Void>() {
               public Void apply(CalciteConnection connection) {
@@ -5707,10 +5708,10 @@ public class JdbcTest {
     TimeZone tzGmt05 = TimeZone.getTimeZone("GMT-05"); // -0500 always
     TimeZone tzGmt13 = TimeZone.getTimeZone("GMT+13"); // +1000 always
 
-    Calendar cUtc   = Calendar.getInstance(tzUtc);
-    Calendar cGmt03 = Calendar.getInstance(tzGmt03);
-    Calendar cGmt05 = Calendar.getInstance(tzGmt05);
-    Calendar cGmt13 = Calendar.getInstance(tzGmt13);
+    Calendar cUtc   = Calendar.getInstance(tzUtc, Locale.ROOT);
+    Calendar cGmt03 = Calendar.getInstance(tzGmt03, Locale.ROOT);
+    Calendar cGmt05 = Calendar.getInstance(tzGmt05, Locale.ROOT);
+    Calendar cGmt13 = Calendar.getInstance(tzGmt13, Locale.ROOT);
 
     Timestamp ts;
     String s;

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/QuidemTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/QuidemTest.java b/core/src/test/java/org/apache/calcite/test/QuidemTest.java
index f15fe13..40a3266 100644
--- a/core/src/test/java/org/apache/calcite/test/QuidemTest.java
+++ b/core/src/test/java/org/apache/calcite/test/QuidemTest.java
@@ -42,11 +42,10 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
 import java.io.FilenameFilter;
+import java.io.Reader;
+import java.io.Writer;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.sql.Connection;
@@ -148,11 +147,10 @@ public class QuidemTest {
       outFile = new File(base, u2n("/surefire/") + path);
     }
     Util.discard(outFile.getParentFile().mkdirs());
-    try (final FileReader fileReader = new FileReader(inFile);
-         final BufferedReader bufferedReader = new BufferedReader(fileReader);
-         final FileWriter writer = new FileWriter(outFile);
+    try (final Reader reader = Util.reader(inFile);
+         final Writer writer = Util.printWriter(outFile);
          final Closer closer = new Closer()) {
-      new Quidem(bufferedReader, writer, env(), new QuidemConnectionFactory())
+      new Quidem(reader, writer, env(), new QuidemConnectionFactory())
           .withPropertyHandler(new Quidem.PropertyHandler() {
             public void onSet(String propertyName, Object value) {
               if (propertyName.equals("bindable")) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java b/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
index 69cccd0..84deb87 100644
--- a/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
@@ -37,6 +37,7 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.tools.Frameworks;
 import org.apache.calcite.util.Holder;
 import org.apache.calcite.util.NlsString;
+import org.apache.calcite.util.Util;
 
 import org.junit.Ignore;
 import org.junit.Test;
@@ -177,7 +178,7 @@ public class RexImplicationCheckerTest {
   @Ignore("work in progress")
   @Test public void testSimpleDate() {
     final Fixture f = new Fixture();
-    final Calendar instance = Calendar.getInstance();
+    final Calendar instance = Util.calendar();
     final RexNode node1 = f.ge(f.dt, f.rexBuilder.makeDateLiteral(instance));
     final RexNode node2 = f.eq(f.dt, f.rexBuilder.makeDateLiteral(instance));
 
@@ -188,7 +189,7 @@ public class RexImplicationCheckerTest {
   @Ignore("work in progress")
   @Test public void testSimpleTimeStamp() {
     final Fixture f = new Fixture();
-    final Calendar calendar = Calendar.getInstance();
+    final Calendar calendar = Util.calendar();
     final RexNode node1 = f.le(f.ts, f.timestampLiteral(calendar));
     final RexNode node2 = f.le(f.ts, f.timestampLiteral(calendar));
 
@@ -199,7 +200,7 @@ public class RexImplicationCheckerTest {
   @Ignore("work in progress")
   @Test public void testSimpleTime() {
     final Fixture f = new Fixture();
-    final Calendar calendar = Calendar.getInstance();
+    final Calendar calendar = Util.calendar();
     final RexNode node1 = f.le(f.ts, f.timeLiteral(calendar));
     final RexNode node2 = f.le(f.ts, f.timeLiteral(calendar));
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
index 090f3ba..9ce8017 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -18,7 +18,6 @@ package org.apache.calcite.test;
 
 import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.avatica.util.ByteString;
-import org.apache.calcite.avatica.util.DateTimeUtils;
 import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
 import org.apache.calcite.plan.Strong;
 import org.apache.calcite.rel.type.RelDataType;
@@ -1310,7 +1309,7 @@ public class RexProgramTest {
   }
 
   private Calendar cal(int y, int m, int d, int h, int mm, int s) {
-    final Calendar c = Calendar.getInstance(DateTimeUtils.GMT_ZONE);
+    final Calendar c = Util.calendar();
     c.set(Calendar.YEAR, y);
     c.set(Calendar.MONTH, m);
     c.set(Calendar.DAY_OF_MONTH, d);

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
index 00e789d..12ef35b 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
@@ -88,11 +88,11 @@ public class SqlFunctionsTest {
   }
 
   @Test public void testLower() {
-    assertEquals("a bcd", lower("A bCd"));
+    assertEquals("a bcd iijk", lower("A bCd Iijk"));
   }
 
   @Test public void testUpper() {
-    assertEquals("A BCD", upper("A bCd"));
+    assertEquals("A BCD IIJK", upper("A bCd iIjk"));
   }
 
   @Test public void testInitcap() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/SqlLimitsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlLimitsTest.java b/core/src/test/java/org/apache/calcite/test/SqlLimitsTest.java
index c8d44ce..298830b 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlLimitsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlLimitsTest.java
@@ -211,11 +211,11 @@ public class SqlLimitsTest {
   private DateFormat getDateFormat(SqlTypeName typeName) {
     switch (typeName) {
     case DATE:
-      return new SimpleDateFormat("MMM d, yyyy");
+      return new SimpleDateFormat("MMM d, yyyy", Locale.ROOT);
     case TIME:
-      return new SimpleDateFormat("hh:mm:ss a");
+      return new SimpleDateFormat("hh:mm:ss a", Locale.ROOT);
     default:
-      return new SimpleDateFormat("MMM d, yyyy hh:mm:ss a");
+      return new SimpleDateFormat("MMM d, yyyy hh:mm:ss a", Locale.ROOT);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/SqlLineTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlLineTest.java b/core/src/test/java/org/apache/calcite/test/SqlLineTest.java
index 241df75..9530e06 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlLineTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlLineTest.java
@@ -18,6 +18,7 @@ package org.apache.calcite.test;
 
 import org.apache.calcite.util.Bug;
 import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.Util;
 
 import org.hamcrest.Matcher;
 
@@ -25,8 +26,9 @@ import org.junit.Test;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -52,7 +54,8 @@ public class SqlLineTest {
       throws Throwable {
     SqlLine sqlline = new SqlLine();
     ByteArrayOutputStream os = new ByteArrayOutputStream();
-    PrintStream sqllineOutputStream = new PrintStream(os);
+    PrintStream sqllineOutputStream =
+        new PrintStream(os, false, StandardCharsets.UTF_8.name());
     sqlline.setOutputStream(sqllineOutputStream);
     sqlline.setErrorStream(sqllineOutputStream);
     SqlLine.Status status = SqlLine.Status.OK;
@@ -92,9 +95,9 @@ public class SqlLineTest {
     // Put the script content in a temp file
     File scriptFile = File.createTempFile("foo", "temp");
     scriptFile.deleteOnExit();
-    PrintStream os = new PrintStream(new FileOutputStream(scriptFile));
-    os.print(scriptText);
-    os.close();
+    try (PrintWriter w = Util.printWriter(scriptFile)) {
+      w.print(scriptText);
+    }
 
     Pair<SqlLine.Status, String> pair = runScript(scriptFile, flag);
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/SqlTestGen.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlTestGen.java b/core/src/test/java/org/apache/calcite/test/SqlTestGen.java
index e330efc..95ab005 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlTestGen.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlTestGen.java
@@ -24,9 +24,9 @@ import org.apache.calcite.sql.test.SqlTester;
 import org.apache.calcite.sql.test.SqlTesterImpl;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.util.BarfingInvocationHandler;
+import org.apache.calcite.util.Util;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.reflect.InvocationTargetException;
@@ -51,8 +51,7 @@ public class SqlTestGen {
 
   private void genValidatorTest() {
     final File file = new File("validatorTest.sql");
-    try (FileOutputStream fos = new FileOutputStream(file);
-         PrintWriter pw = new PrintWriter(fos)) {
+    try (PrintWriter pw = Util.printWriter(file)) {
       Method[] methods = getJunitMethods(SqlValidatorSpooler.class);
       for (Method method : methods) {
         final SqlValidatorSpooler test = new SqlValidatorSpooler(pw);

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index 8c0f268..938d4c7 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -3637,7 +3637,7 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
 
     for (String interval : tsi) {
       for (String function : functions) {
-        checkExp(String.format(function, interval));
+        checkExp(String.format(Locale.ROOT, function, interval));
       }
     }
 
@@ -7844,7 +7844,7 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
       case INTERNAL:
         break;
       default:
-        assertThat(name.toUpperCase(), equalTo(name));
+        assertThat(name.toUpperCase(Locale.ROOT), equalTo(name));
         break;
       }
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandExecutor.java b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandExecutor.java
index 25d89eb..62e2b1c 100644
--- a/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandExecutor.java
+++ b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandExecutor.java
@@ -16,6 +16,8 @@
  */
 package org.apache.calcite.test.concurrent;
 
+import org.apache.calcite.util.Unsafe;
+
 import java.io.PrintStream;
 import java.sql.Connection;
 import java.sql.DriverManager;
@@ -288,13 +290,13 @@ class ConcurrentTestCommandExecutor extends Thread {
     synchronized void waitForOthers() throws InterruptedException {
       if (++numWaiting == numThreads) {
         numWaiting = 0;
-        notifyAll();
+        Unsafe.notifyAll(this);
       } else {
         // REVIEW: SZ 6/17/2004: Need a timeout here --
         // otherwise a test case will hang forever if there's
         // a deadlock.  The question is, how long should the
         // timeout be to avoid falsely detecting deadlocks?
-        wait();
+        Unsafe.wait(this);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandScript.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandScript.java b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandScript.java
index eebb79c..ab3f7b1 100644
--- a/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandScript.java
+++ b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestCommandScript.java
@@ -17,14 +17,13 @@
 package org.apache.calcite.test.concurrent;
 
 import org.apache.calcite.jdbc.SqlTimeoutException;
+import org.apache.calcite.util.Unsafe;
 import org.apache.calcite.util.Util;
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.StringWriter;
@@ -43,6 +42,7 @@ import java.util.Arrays;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 import java.util.StringTokenizer;
@@ -440,12 +440,13 @@ public class ConcurrentTestCommandScript
    * translates argument of !set force etc.
    */
   private boolean asBoolValue(String s) {
-    s = s.toLowerCase();
-    return s.equals("true") || s.equals("yes") || s.equals("on");
+    return s.equalsIgnoreCase("true")
+        || s.equalsIgnoreCase("yes")
+        || s.equalsIgnoreCase("on");
   }
 
   /**
-   * Determines if a block of SQL is a select statment or not.
+   * Determines whether a block of SQL is a SELECT statement.
    */
   private boolean isSelect(String sql) {
     BufferedReader rdr = new BufferedReader(new StringReader(sql));
@@ -453,7 +454,7 @@ public class ConcurrentTestCommandScript
     try {
       String line;
       while ((line = rdr.readLine()) != null) {
-        line = line.trim().toLowerCase();
+        line = line.trim().toLowerCase(Locale.ROOT);
         if (isComment(line)) {
           continue;
         }
@@ -520,11 +521,11 @@ public class ConcurrentTestCommandScript
     }
   }
 
-  public void printResults(BufferedWriter out) throws IOException {
+  public void printResults(PrintWriter out) throws IOException {
     final Map<Integer, String[]> results = collectResults();
     if (verbose) {
       out.write(
-          String.format(
+          String.format(Locale.ROOT,
               "script execution started at %tc (%d)%n",
               new Timestamp(scriptStartTime), scriptStartTime));
     }
@@ -538,18 +539,18 @@ public class ConcurrentTestCommandScript
     printThreadResults(out, results.get(CLEANUP_THREAD_ID));
   }
 
-  private void printThreadResults(BufferedWriter out, String[] threadResult)
+  private void printThreadResults(PrintWriter out, String[] threadResult)
       throws IOException {
     if (threadResult == null) {
       return;
     }
     String threadName = threadResult[0];
     out.write("-- " + threadName);
-    out.newLine();
+    out.println();
     out.write(threadResult[1]);
     out.write("-- end of " + threadName);
-    out.newLine();
-    out.newLine();
+    out.println();
+    out.println();
     out.flush();
   }
 
@@ -848,7 +849,7 @@ public class ConcurrentTestCommandScript
     private void load(String scriptFileName) throws IOException {
       File scriptFile = new File(currentDirectory.peek(), scriptFileName);
       currentDirectory.push(scriptDirectory = scriptFile.getParentFile());
-      try (BufferedReader in = new BufferedReader(new FileReader(scriptFile))) {
+      try (BufferedReader in = Util.reader(scriptFile)) {
         String line;
         while ((line = in.readLine()) != null) {
           line = line.trim();
@@ -1891,8 +1892,7 @@ public class ConcurrentTestCommandScript
           out.println();
         }
         if (verbose) {
-          out.printf(
-              "fetch started at %tc %d, %s at %tc %d%n",
+          out.printf(Locale.ROOT, "fetch started at %tc %d, %s at %tc %d%n",
               startTime, startTime,
               timedOut ? "timeout" : "eos",
               endTime, endTime);
@@ -1903,20 +1903,19 @@ public class ConcurrentTestCommandScript
             dt -= timeout;
           }
           assert dt >= 0;
-          out.printf(
-              "fetched %d rows in %d msecs %s%n",
+          out.printf(Locale.ROOT, "fetched %d rows in %d msecs %s%n",
               rowCount, dt, timedOut ? "(timeout)" : "(end)");
         }
       }
     }
 
     private void printRowCount(int count) {
-      out.printf("(%06d) ", count);
+      out.printf(Locale.ROOT, "(%06d) ", count);
     }
 
     private void printTimestamp(long time) {
       time -= baseTime;
-      out.printf("(% 4d.%03d) ", time / 1000, time % 1000);
+      out.printf(Locale.ROOT, "(% 4d.%03d) ", time / 1000, time % 1000);
     }
 
     // indent a heading or separator line to match a row-values line
@@ -2003,7 +2002,7 @@ public class ConcurrentTestCommandScript
 
     // returns 0 on success, 1 on error, 2 on bad invocation.
     public int run(String[] args) {
-      try {
+      try (final PrintWriter w = Util.printWriter(System.out)) {
         if (!parseCommand(args)) {
           usage();
           return 2;
@@ -2018,8 +2017,6 @@ public class ConcurrentTestCommandScript
           jdbcProps.setProperty("password", password);
         }
 
-        BufferedWriter cout =
-            new BufferedWriter(new OutputStreamWriter(System.out));
         for (String file : files) {
           ConcurrentTestCommandScript script =
               new ConcurrentTestCommandScript();
@@ -2032,7 +2029,7 @@ public class ConcurrentTestCommandScript
             script.execute();
           } finally {
             if (!quiet) {
-              script.printResults(cout);
+              script.printResults(w);
             }
           }
         }
@@ -2109,7 +2106,7 @@ public class ConcurrentTestCommandScript
    */
   public static void main(String[] args) {
     int status = new Tool().run(args);
-    System.exit(status);
+    Unsafe.systemExit(status);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/util/Smalls.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/util/Smalls.java b/core/src/test/java/org/apache/calcite/util/Smalls.java
index c37f320..a2ac470 100644
--- a/core/src/test/java/org/apache/calcite/util/Smalls.java
+++ b/core/src/test/java/org/apache/calcite/util/Smalls.java
@@ -49,6 +49,7 @@ import java.lang.reflect.Method;
 import java.util.AbstractList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.hamcrest.CoreMatchers.is;
@@ -427,7 +428,7 @@ public class Smalls {
     private MultipleFunction() {}
 
     // Three overloads
-    public static String fun1(String x) { return x.toLowerCase(); }
+    public static String fun1(String x) { return x.toLowerCase(Locale.ROOT); }
     public static int fun1(int x) { return x * 2; }
     public static int fun1(int x, int y) { return x + y; }
 
@@ -615,19 +616,24 @@ public class Smalls {
     }
 
     public static ScannableTable generate(int width, int height, int seed) {
-      return new MazeTable(String.format("generate(w=%d, h=%d, s=%d)", width, height, seed));
+      return new MazeTable(
+          String.format(Locale.ROOT, "generate(w=%d, h=%d, s=%d)", width,
+              height, seed));
     }
 
     public static ScannableTable generate2(
         @Parameter(name = "WIDTH") int width,
         @Parameter(name = "HEIGHT") int height,
         @Parameter(name = "SEED", optional = true) Integer seed) {
-      return new MazeTable(String.format("generate2(w=%d, h=%d, s=%d)", width, height, seed));
+      return new MazeTable(
+          String.format(Locale.ROOT, "generate2(w=%d, h=%d, s=%d)", width,
+              height, seed));
     }
 
     public static ScannableTable generate3(
         @Parameter(name = "FOO") String foo) {
-      return new MazeTable(String.format("generate3(foo=%s)", foo));
+      return new MazeTable(
+          String.format(Locale.ROOT, "generate3(foo=%s)", foo));
     }
 
     public RelDataType getRowType(RelDataTypeFactory typeFactory) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/core/src/test/java/org/apache/calcite/util/UtilTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/util/UtilTest.java b/core/src/test/java/org/apache/calcite/util/UtilTest.java
index 8afc09b..2f48d64 100644
--- a/core/src/test/java/org/apache/calcite/util/UtilTest.java
+++ b/core/src/test/java/org/apache/calcite/util/UtilTest.java
@@ -762,10 +762,10 @@ public class UtilTest {
    */
   @Test public void testTemplate() {
     // Regular java message format.
-    assertEquals(
-        "Hello, world, what a nice day.",
-        MessageFormat.format(
-            "Hello, {0}, what a nice {1}.", "world", "day"));
+    assertThat(
+        new MessageFormat("Hello, {0}, what a nice {1}.", Locale.ROOT)
+            .format(new Object[]{"world", "day"}),
+        is("Hello, world, what a nice day."));
 
     // Our extended message format. First, just strings.
     final HashMap<Object, Object> map = new HashMap<>();
@@ -1513,8 +1513,8 @@ public class UtilTest {
 
     final Comparator<String> comparator = new Comparator<String>() {
       public int compare(String o1, String o2) {
-        String u1 = o1.toUpperCase();
-        String u2 = o2.toUpperCase();
+        String u1 = o1.toUpperCase(Locale.ROOT);
+        String u2 = o2.toUpperCase(Locale.ROOT);
         int c = u1.compareTo(u2);
         if (c == 0) {
           c = o1.compareTo(o2);
@@ -1545,7 +1545,8 @@ public class UtilTest {
   }
 
   private NavigableSet<String> checkNav(NavigableSet<String> set, String s) {
-    return set.subSet(s.toUpperCase(), true, s.toLowerCase(), true);
+    return set.subSet(s.toUpperCase(Locale.ROOT), true,
+        s.toLowerCase(Locale.ROOT), true);
   }
 
   /** Test for {@link org.apache.calcite.util.ImmutableNullableList}. */
@@ -1741,7 +1742,7 @@ public class UtilTest {
     final Map<String, String> map = Util.asIndexMap(values,
         new Function<String, String>() {
           public String apply(@Nullable String input) {
-            return input.toUpperCase();
+            return input.toUpperCase(Locale.ROOT);
           }
         });
     assertThat(map.size(), equalTo(values.size()));

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
----------------------------------------------------------------------
diff --git a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
index d7f54fa..036a2e1 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidConnectionImpl.java
@@ -45,11 +45,13 @@ import com.google.common.collect.ImmutableSet;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
@@ -71,7 +73,8 @@ class DruidConnectionImpl implements DruidConnection {
 
   static {
     final TimeZone utc = DateTimeUtils.GMT_ZONE;
-    UTC_TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+    UTC_TIMESTAMP_FORMAT =
+        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ROOT);
     UTC_TIMESTAMP_FORMAT.setTimeZone(utc);
   }
 
@@ -117,7 +120,8 @@ class DruidConnectionImpl implements DruidConnection {
     if (CalcitePrepareImpl.DEBUG) {
       try {
         final byte[] bytes = AvaticaUtils.readFullyToBytes(in);
-        System.out.println("Response: " + new String(bytes));
+        System.out.println("Response: "
+            + new String(bytes, StandardCharsets.UTF_8));
         in = new ByteArrayInputStream(bytes);
       } catch (IOException e) {
         throw new RuntimeException(e);
@@ -516,7 +520,8 @@ class DruidConnectionImpl implements DruidConnection {
       try {
         final byte[] bytes = AvaticaUtils.readFullyToBytes(in);
         in.close();
-        System.out.println("Response: " + new String(bytes));
+        System.out.println("Response: "
+            + new String(bytes, StandardCharsets.UTF_8));
         in = new ByteArrayInputStream(bytes);
       } catch (IOException e) {
         throw new RuntimeException(e);

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
----------------------------------------------------------------------
diff --git a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
index 17ddd05..694f9c7 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
@@ -962,7 +962,7 @@ public class DruidQuery extends AbstractRelNode implements BindableRel {
       case OR:
       case NOT:
         call = (RexCall) e;
-        return new JsonCompositeFilter(e.getKind().toString().toLowerCase(),
+        return new JsonCompositeFilter(e.getKind().lowerName,
             translateFilters(call.getOperands()));
       }
       throw new AssertionError("cannot translate filter: " + e);

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/druid/src/main/java/org/apache/calcite/adapter/druid/Granularity.java
----------------------------------------------------------------------
diff --git a/druid/src/main/java/org/apache/calcite/adapter/druid/Granularity.java b/druid/src/main/java/org/apache/calcite/adapter/druid/Granularity.java
index b3f1e85..0ee2e20 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/Granularity.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/Granularity.java
@@ -16,6 +16,8 @@
  */
 package org.apache.calcite.adapter.druid;
 
+import java.util.Locale;
+
 /** Granularity of a Druid query. */
 public enum Granularity {
   ALL,
@@ -30,7 +32,7 @@ public enum Granularity {
   NONE;
 
   /** JSON attribute value in a Druid query. */
-  public final String value = name().toLowerCase();
+  public final String value = name().toLowerCase(Locale.ROOT);
 }
 
 // End Granularity.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchFilter.java
----------------------------------------------------------------------
diff --git a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchFilter.java b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchFilter.java
index f11a7b5..ef22fa2 100644
--- a/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchFilter.java
+++ b/elasticsearch/src/main/java/org/apache/calcite/adapter/elasticsearch/ElasticsearchFilter.java
@@ -39,6 +39,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 
@@ -93,7 +94,8 @@ public class ElasticsearchFilter extends Filter implements ElasticsearchRel {
       final Map<String, Object> map = builder.map();
       map.put("constant_score", filterMap);
 
-      return "\"query\" : " + builder.toJsonString(map).replaceAll("\\s+", "").toLowerCase();
+      return "\"query\" : " + builder.toJsonString(map).replaceAll("\\s+", "")
+          .toLowerCase(Locale.ROOT);
     }
 
     private Object translateOr(RexNode condition) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java
----------------------------------------------------------------------
diff --git a/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java b/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java
index 44520c1..b544b16 100644
--- a/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java
+++ b/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java
@@ -22,6 +22,7 @@ import org.apache.calcite.schema.SchemaFactory;
 import org.apache.calcite.schema.SchemaPlus;
 
 import java.io.File;
+import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -56,7 +57,7 @@ public class CsvSchemaFactory implements SchemaFactory {
     if (flavorName == null) {
       flavor = CsvTable.Flavor.SCANNABLE;
     } else {
-      flavor = CsvTable.Flavor.valueOf(flavorName.toUpperCase());
+      flavor = CsvTable.Flavor.valueOf(flavorName.toUpperCase(Locale.ROOT));
     }
     return new CsvSchema(directoryFile, flavor);
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java
----------------------------------------------------------------------
diff --git a/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java b/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java
index 38693ce..47c9213 100644
--- a/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java
+++ b/example/csv/src/test/java/org/apache/calcite/test/CsvTest.java
@@ -31,7 +31,6 @@ import org.junit.Ignore;
 import org.junit.Test;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.net.URL;
@@ -582,7 +581,7 @@ public class CsvTest {
 
     try (final Connection connection =
              DriverManager.getConnection("jdbc:calcite:model=inline:" + model);
-         final PrintWriter pw = new PrintWriter(new FileWriter(file));
+         final PrintWriter pw = Util.printWriter(file);
          final Worker<Void> worker = new Worker<>()) {
       final Thread thread = new Thread(worker);
       thread.start();

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/example/function/src/main/java/org/apache/calcite/example/maze/MazeTable.java
----------------------------------------------------------------------
diff --git a/example/function/src/main/java/org/apache/calcite/example/maze/MazeTable.java b/example/function/src/main/java/org/apache/calcite/example/maze/MazeTable.java
index 3a2dc02..a08b366 100644
--- a/example/function/src/main/java/org/apache/calcite/example/maze/MazeTable.java
+++ b/example/function/src/main/java/org/apache/calcite/example/maze/MazeTable.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.schema.ScannableTable;
 import org.apache.calcite.schema.impl.AbstractTable;
 import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.util.Util;
 
 import java.io.PrintWriter;
 import java.util.Random;
@@ -88,7 +89,7 @@ public class MazeTable extends AbstractTable implements ScannableTable {
   public Enumerable<Object[]> scan(DataContext root) {
     final Random random = seed >= 0 ? new Random(seed) : new Random();
     final Maze maze = new Maze(width, height);
-    final PrintWriter pw = new PrintWriter(System.out);
+    final PrintWriter pw = Util.printWriter(System.out);
     maze.layout(random, pw);
     if (Maze.DEBUG) {
       maze.print(pw, true);

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/file/src/main/java/org/apache/calcite/adapter/file/FileReader.java
----------------------------------------------------------------------
diff --git a/file/src/main/java/org/apache/calcite/adapter/file/FileReader.java b/file/src/main/java/org/apache/calcite/adapter/file/FileReader.java
index fc6904b..6eecce4 100644
--- a/file/src/main/java/org/apache/calcite/adapter/file/FileReader.java
+++ b/file/src/main/java/org/apache/calcite/adapter/file/FileReader.java
@@ -24,6 +24,8 @@ import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
 import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.Iterator;
 
 /**
@@ -31,12 +33,10 @@ import java.util.Iterator;
  */
 public class FileReader implements Iterable<Elements> {
 
-  private static final String DEFAULT_CHARSET = "UTF-8";
-
   private final Source source;
   private final String selector;
   private final Integer index;
-  private final String charset = DEFAULT_CHARSET;
+  private final Charset charset = StandardCharsets.UTF_8;
   private Element tableElement;
   private Elements headings;
 
@@ -63,7 +63,7 @@ public class FileReader implements Iterable<Elements> {
     try {
       String proto = source.protocol();
       if (proto.equals("file")) {
-        doc = Jsoup.parse(source.file(), this.charset);
+        doc = Jsoup.parse(source.file(), this.charset.name());
       } else {
         doc = Jsoup.connect(source.path()).get();
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/file/src/main/java/org/apache/calcite/adapter/file/FileRowConverter.java
----------------------------------------------------------------------
diff --git a/file/src/main/java/org/apache/calcite/adapter/file/FileRowConverter.java b/file/src/main/java/org/apache/calcite/adapter/file/FileRowConverter.java
index a6c1bcc..827bf59 100644
--- a/file/src/main/java/org/apache/calcite/adapter/file/FileRowConverter.java
+++ b/file/src/main/java/org/apache/calcite/adapter/file/FileRowConverter.java
@@ -36,6 +36,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -55,6 +56,16 @@ class FileRowConverter {
   // row parser configuration
   private final List<FieldDef> fields = new ArrayList<>();
 
+  /** Format for parsing numbers. Not thread-safe, but we assume that only
+   * one thread uses this converter at a time. */
+  private final NumberFormat numberFormat =
+      NumberFormat.getInstance(Locale.ROOT);
+
+  /** Format for parsing integers. Not thread-safe, but we assume that only
+   * one thread uses this converter at a time. */
+  private final NumberFormat integerFormat =
+      NumberFormat.getIntegerInstance(Locale.ROOT);
+
   /** Creates a FileRowConverter. */
   FileRowConverter(FileReader fileReader,
       List<Map<String, Object>> fieldConfigs) {
@@ -340,43 +351,36 @@ class FileRowConverter {
         return Byte.parseByte(string);
 
       case SHORT:
-
         try {
-          return NumberFormat.getIntegerInstance().parse(string)
-              .shortValue();
+          return integerFormat.parse(string).shortValue();
         } catch (ParseException e) {
           return null;
         }
 
       case INT:
-
         try {
-          return NumberFormat.getIntegerInstance().parse(string)
-              .intValue();
+          return integerFormat.parse(string).intValue();
         } catch (ParseException e) {
           return null;
         }
 
       case LONG:
-
         try {
-          return NumberFormat.getInstance().parse(string).longValue();
+          return numberFormat.parse(string).longValue();
         } catch (ParseException e) {
           return null;
         }
 
       case FLOAT:
-
         try {
-          return NumberFormat.getInstance().parse(string).floatValue();
+          return numberFormat.parse(string).floatValue();
         } catch (ParseException e) {
           return null;
         }
 
       case DOUBLE:
-
         try {
-          return NumberFormat.getInstance().parse(string).doubleValue();
+          return numberFormat.parse(string).doubleValue();
         } catch (ParseException e) {
           return null;
         }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/linq4j/src/test/java/org/apache/calcite/linq4j/test/Linq4jTest.java
----------------------------------------------------------------------
diff --git a/linq4j/src/test/java/org/apache/calcite/linq4j/test/Linq4jTest.java b/linq4j/src/test/java/org/apache/calcite/linq4j/test/Linq4jTest.java
index f19bdd0..e55a025 100644
--- a/linq4j/src/test/java/org/apache/calcite/linq4j/test/Linq4jTest.java
+++ b/linq4j/src/test/java/org/apache/calcite/linq4j/test/Linq4jTest.java
@@ -52,6 +52,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
@@ -338,7 +339,8 @@ public class Linq4jTest {
                 return String.CASE_INSENSITIVE_ORDER.compare(v1, v2) == 0;
               }
               public int hashCode(String s) {
-                return s == null ? Objects.hashCode(null) : s.toLowerCase().hashCode();
+                return s == null ? Objects.hashCode(null)
+                    : s.toLowerCase(Locale.ROOT).hashCode();
               }
             });
     assertEquals(3, map.size());
@@ -361,7 +363,7 @@ public class Linq4jTest {
             .toMap(Functions.<String>identitySelector(),
                 new Function1<String, String>() {
                   public String apply(String x) {
-                    return x == null ? null : x.toUpperCase();
+                    return x == null ? null : x.toUpperCase(Locale.ROOT);
                   }
                 },
                 new EqualityComparer<String>() {
@@ -369,7 +371,8 @@ public class Linq4jTest {
                     return String.CASE_INSENSITIVE_ORDER.compare(v1, v2) == 0;
                   }
                   public int hashCode(String s) {
-                    return s == null ? Objects.hashCode(null) : s.toLowerCase().hashCode();
+                    return s == null ? Objects.hashCode(null)
+                        : s.toLowerCase(Locale.ROOT).hashCode();
                   }
                 });
     assertEquals(3, map.size());
@@ -2161,8 +2164,7 @@ public class Linq4jTest {
             .groupBy(EMP_DEPTNO_SELECTOR)
             .select(new Function1<Grouping<Integer, Employee>, String>() {
               public String apply(Grouping<Integer, Employee> group) {
-                return String.format("%s: %s",
-                    group.getKey(),
+                return String.format(Locale.ROOT, "%s: %s", group.getKey(),
                     stringJoin("+", group.select(new Function1<Employee, String>() {
                       public String apply(Employee element) {
                         return element.name;
@@ -2190,8 +2192,7 @@ public class Linq4jTest {
             })
             .select(new Function1<Grouping<Integer, Employee>, String>() {
               public String apply(Grouping<Integer, Employee> group) {
-                return String.format("%s: %s",
-                    group.getKey(),
+                return String.format(Locale.ROOT, "%s: %s", group.getKey(),
                     stringJoin("+", group.select(new Function1<Employee, String>() {
                       public String apply(Employee element) {
                         return element.name;
@@ -2212,7 +2213,8 @@ public class Linq4jTest {
             .groupBy(EMP_DEPTNO_SELECTOR, EMP_NAME_SELECTOR)
             .select(new Function1<Grouping<Integer, String>, String>() {
               public String apply(Grouping<Integer, String> group) {
-                return String.format("%s: %s", group.getKey(), stringJoin("+", group));
+                return String.format(Locale.ROOT, "%s: %s", group.getKey(),
+                    stringJoin("+", group));
               }
             })
             .toList()
@@ -2249,7 +2251,8 @@ public class Linq4jTest {
             })
             .select(new Function1<Grouping<Integer, String>, String>() {
               public String apply(Grouping<Integer, String> group) {
-                return String.format("%s: %s", group.getKey(), stringJoin("+", group));
+                return String.format(Locale.ROOT, "%s: %s", group.getKey(),
+                    stringJoin("+", group));
               }
             })
             .toList()
@@ -2264,8 +2267,7 @@ public class Linq4jTest {
         Linq4j.asEnumerable(emps)
             .groupBy(EMP_DEPTNO_SELECTOR, new Function2<Integer, Enumerable<Employee>, String>() {
               public String apply(Integer key, Enumerable<Employee> group) {
-                return String.format("%s: %s",
-                    key,
+                return String.format(Locale.ROOT, "%s: %s", key,
                     stringJoin("+", group.select(new Function1<Employee, String>() {
                       public String apply(Employee element) {
                         return element.name;
@@ -2285,8 +2287,7 @@ public class Linq4jTest {
         Linq4j.asEnumerable(emps)
             .groupBy(EMP_DEPTNO_SELECTOR, new Function2<Integer, Enumerable<Employee>, String>() {
               public String apply(Integer key, Enumerable<Employee> group) {
-                return String.format("%s: %s",
-                    key,
+                return String.format(Locale.ROOT, "%s: %s", key,
                     stringJoin("+", group.select(new Function1<Employee, String>() {
                       public String apply(Employee element) {
                         return element.name;
@@ -2314,7 +2315,8 @@ public class Linq4jTest {
             .groupBy(EMP_DEPTNO_SELECTOR, EMP_NAME_SELECTOR,
                 new Function2<Integer, Enumerable<String>, String>() {
                   public String apply(Integer key, Enumerable<String> group) {
-                    return String.format("%s: %s", key, stringJoin("+", group));
+                    return String.format(Locale.ROOT, "%s: %s", key,
+                        stringJoin("+", group));
                   }
                 })
             .toList()
@@ -2330,7 +2332,8 @@ public class Linq4jTest {
             .groupBy(EMP_DEPTNO_SELECTOR, EMP_NAME_SELECTOR,
                 new Function2<Integer, Enumerable<String>, String>() {
                   public String apply(Integer key, Enumerable<String> group) {
-                    return String.format("%s: %s", key, stringJoin("+", group));
+                    return String.format(Locale.ROOT, "%s: %s", key,
+                        stringJoin("+", group));
                   }
                 },
                 new EqualityComparer<Integer>() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/plus/src/main/java/org/apache/calcite/adapter/tpcds/TpcdsSchema.java
----------------------------------------------------------------------
diff --git a/plus/src/main/java/org/apache/calcite/adapter/tpcds/TpcdsSchema.java b/plus/src/main/java/org/apache/calcite/adapter/tpcds/TpcdsSchema.java
index 5f240e3..9a430b2 100644
--- a/plus/src/main/java/org/apache/calcite/adapter/tpcds/TpcdsSchema.java
+++ b/plus/src/main/java/org/apache/calcite/adapter/tpcds/TpcdsSchema.java
@@ -41,6 +41,7 @@ import net.hydromatic.tpcds.TpcdsTable;
 import java.sql.Date;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 /** Schema that provides TPC-DS tables, populated according to a
@@ -88,7 +89,7 @@ public class TpcdsSchema extends AbstractSchema {
     final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();
     for (TpcdsTable<?> tpcdsTable : TpcdsTable.getTables()) {
       //noinspection unchecked
-      builder.put(tpcdsTable.getTableName().toUpperCase(),
+      builder.put(tpcdsTable.getTableName().toUpperCase(Locale.ROOT),
           new TpcdsQueryableTable(tpcdsTable));
     }
     this.tableMap = builder.build();
@@ -166,7 +167,7 @@ public class TpcdsSchema extends AbstractSchema {
     public RelDataType getRowType(RelDataTypeFactory typeFactory) {
       final RelDataTypeFactory.FieldInfoBuilder builder = typeFactory.builder();
       for (TpcdsColumn<E> column : tpcdsTable.getColumns()) {
-        builder.add(column.getColumnName().toUpperCase(),
+        builder.add(column.getColumnName().toUpperCase(Locale.ROOT),
             typeFactory.createJavaType(realType(column)));
       }
       return builder.build();

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/plus/src/main/java/org/apache/calcite/adapter/tpch/TpchSchema.java
----------------------------------------------------------------------
diff --git a/plus/src/main/java/org/apache/calcite/adapter/tpch/TpchSchema.java b/plus/src/main/java/org/apache/calcite/adapter/tpch/TpchSchema.java
index 68e1c31..451c344 100644
--- a/plus/src/main/java/org/apache/calcite/adapter/tpch/TpchSchema.java
+++ b/plus/src/main/java/org/apache/calcite/adapter/tpch/TpchSchema.java
@@ -36,6 +36,7 @@ import io.airlift.tpch.TpchTable;
 
 import java.sql.Date;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 /** Schema that provides TPC-H tables, populated according to a
@@ -57,7 +58,7 @@ public class TpchSchema extends AbstractSchema {
 
     final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();
     for (TpchTable<?> tpchTable : TpchTable.getTables()) {
-      builder.put(tpchTable.getTableName().toUpperCase(),
+      builder.put(tpchTable.getTableName().toUpperCase(Locale.ROOT),
           new TpchQueryableTable(tpchTable));
     }
     this.tableMap = builder.build();
@@ -140,12 +141,14 @@ public class TpchSchema extends AbstractSchema {
       final RelDataTypeFactory.FieldInfoBuilder builder = typeFactory.builder();
       String prefix = "";
       if (columnPrefix) {
-        prefix = columnPrefixes.get(tpchTable.getTableName().toUpperCase());
-        assert prefix != null : tpchTable.getTableName().toUpperCase();
+        final String t = tpchTable.getTableName().toUpperCase(Locale.ROOT);
+        prefix = columnPrefixes.get(t);
+        assert prefix != null : t;
       }
       for (TpchColumn<E> column : tpchTable.getColumns()) {
-        builder.add((prefix + column.getColumnName()).toUpperCase(),
-            typeFactory.createJavaType(realType(column)));
+        final String c = (prefix + column.getColumnName())
+            .toUpperCase(Locale.ROOT);
+        builder.add(c, typeFactory.createJavaType(realType(column)));
       }
       return builder.build();
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6cda20f..2340596 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,7 @@ limitations under the License.
     <fmpp-maven-plugin.version>1.0</fmpp-maven-plugin.version>
     <foodmart-data-hsqldb.version>0.3</foodmart-data-hsqldb.version>
     <foodmart-queries.version>0.4.1</foodmart-queries.version>
+    <forbiddenapis.version>2.3</forbiddenapis.version>
     <freemarker.version>2.3.25-incubating</freemarker.version>
     <git-commit-id-plugin.version>2.1.9</git-commit-id-plugin.version>
 
@@ -461,6 +462,43 @@ limitations under the License.
   <build>
     <plugins>
       <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <configuration>
+          <!-- if the used Java version is too new, don't fail, just do nothing: -->
+          <failOnUnsupportedJava>false</failOnUnsupportedJava>
+          <bundledSignatures>
+            <!--
+              This will automatically choose the right
+              signatures based on 'maven.compiler.target':
+            -->
+            <bundledSignature>jdk-unsafe</bundledSignature>
+            <bundledSignature>jdk-deprecated</bundledSignature>
+            <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+            <bundledSignature>jdk-non-portable</bundledSignature>
+          </bundledSignatures>
+          <signaturesFiles>
+            <signaturesFile>${top.dir}/src/main/config/forbidden-apis/signatures.txt</signaturesFile>
+          </signaturesFiles>
+          <excludes>
+            <exclude>**/ParseException.class</exclude>
+            <exclude>**/SimpleCharStream.class</exclude>
+            <exclude>**/*TokenManager.class</exclude>
+            <exclude>**/TokenMgrError.class</exclude>
+            <exclude>**/org/apache/calcite/runtime/Resources$Inst.class</exclude>
+            <exclude>**/org/apache/calcite/util/Unsafe.class</exclude>
+          </excludes>
+        </configuration>
+        <executions>
+          <execution>
+            <goals>
+              <goal>check</goal>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
         <groupId>org.apache.rat</groupId>
         <artifactId>apache-rat-plugin</artifactId>
         <configuration>
@@ -674,6 +712,11 @@ limitations under the License.
           </dependencies>
         </plugin>
         <plugin>
+          <groupId>de.thetaphi</groupId>
+          <artifactId>forbiddenapis</artifactId>
+          <version>${forbiddenapis.version}</version>
+        </plugin>
+        <plugin>
           <groupId>net.hydromatic</groupId>
           <artifactId>hydromatic-resource-maven-plugin</artifactId>
           <version>${hydromatic-resource.version}</version>
@@ -749,7 +792,19 @@ limitations under the License.
             <threadCount>1</threadCount>
             <perCoreThreadCount>true</perCoreThreadCount>
             <parallel>both</parallel>
-            <argLine>-Xmx1536m -XX:MaxPermSize=256m -Duser.timezone=${user.timezone}</argLine>
+            <forkMode>once</forkMode>
+            <systemProperties>
+              <systemProperty>
+                <name>user.language</name>
+                <value>TR</value>
+              </systemProperty>
+              <systemProperty>
+                <name>user.country</name>
+                <value>tr</value>
+              </systemProperty>
+            </systemProperties>
+            <!--<argLine>-Xmx1536m -XX:MaxPermSize=256m -Duser.timezone=${user.timezone} -Duser.country=${user.country} -Duser.language=${user.language}</argLine>-->
+            <argLine>-Xmx1536m -XX:MaxPermSize=256m</argLine>
           </configuration>
         </plugin>
         <plugin>

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/spark/src/main/java/org/apache/calcite/adapter/spark/SparkHandlerImpl.java
----------------------------------------------------------------------
diff --git a/spark/src/main/java/org/apache/calcite/adapter/spark/SparkHandlerImpl.java b/spark/src/main/java/org/apache/calcite/adapter/spark/SparkHandlerImpl.java
index b67f096..a580912 100644
--- a/spark/src/main/java/org/apache/calcite/adapter/spark/SparkHandlerImpl.java
+++ b/spark/src/main/java/org/apache/calcite/adapter/spark/SparkHandlerImpl.java
@@ -23,14 +23,15 @@ import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.runtime.ArrayBindable;
+import org.apache.calcite.util.Util;
 import org.apache.calcite.util.javac.JaninoCompiler;
 
 import org.apache.spark.api.java.JavaSparkContext;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.Serializable;
+import java.io.Writer;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Calendar;
@@ -63,7 +64,7 @@ public class SparkHandlerImpl implements CalcitePrepare.SparkHandler {
     // Generate a starting point for class names that is unlikely to clash with
     // previous classes. A better solution would be to clear the class directory
     // on startup.
-    final Calendar calendar = Calendar.getInstance();
+    final Calendar calendar = Util.calendar();
     classId = new AtomicInteger(
         calendar.get(Calendar.HOUR_OF_DAY) * 10000
         + calendar.get(Calendar.MINUTE) * 100
@@ -104,10 +105,9 @@ public class SparkHandlerImpl implements CalcitePrepare.SparkHandler {
   }
 
   public ArrayBindable compile(ClassDeclaration expr, String s) {
-    try {
-      String className = "CalciteProgram" + classId.getAndIncrement();
-      File file = new File(SRC_DIR, className + ".java");
-      FileWriter fileWriter = new FileWriter(file, false);
+    final String className = "CalciteProgram" + classId.getAndIncrement();
+    final File file = new File(SRC_DIR, className + ".java");
+    try (Writer w = Util.printWriter(file)) {
       String source = "public class " + className + "\n"
           + "    implements " + ArrayBindable.class.getName()
           + ", " + Serializable.class.getName()
@@ -119,8 +119,8 @@ public class SparkHandlerImpl implements CalcitePrepare.SparkHandler {
       System.out.println(source);
       System.out.println("======================");
 
-      fileWriter.write(source);
-      fileWriter.close();
+      w.write(source);
+      w.close();
       JaninoCompiler compiler = new JaninoCompiler();
       compiler.getArgs().setDestdir(CLASS_DIR.getAbsolutePath());
       compiler.getArgs().setSource(source, file.getAbsolutePath());

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/spark/src/main/java/org/apache/calcite/adapter/spark/SparkRules.java
----------------------------------------------------------------------
diff --git a/spark/src/main/java/org/apache/calcite/adapter/spark/SparkRules.java b/spark/src/main/java/org/apache/calcite/adapter/spark/SparkRules.java
index 3adfcd9..8b355a2 100644
--- a/spark/src/main/java/org/apache/calcite/adapter/spark/SparkRules.java
+++ b/spark/src/main/java/org/apache/calcite/adapter/spark/SparkRules.java
@@ -72,6 +72,7 @@ import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
 import java.util.Random;
 
 /**
@@ -445,7 +446,7 @@ public abstract class SparkRules {
                   return Collections.emptyList();
                 }
                 return Collections.singletonList(
-                    Pair.of(x.toUpperCase(), x.length()));
+                    Pair.of(x.toUpperCase(Locale.ROOT), x.length()));
               }
             })
             .take(5)

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/splunk/src/main/java/org/apache/calcite/adapter/splunk/search/SplunkConnectionImpl.java
----------------------------------------------------------------------
diff --git a/splunk/src/main/java/org/apache/calcite/adapter/splunk/search/SplunkConnectionImpl.java b/splunk/src/main/java/org/apache/calcite/adapter/splunk/search/SplunkConnectionImpl.java
index aeb4a91..8f08e23 100644
--- a/splunk/src/main/java/org/apache/calcite/adapter/splunk/search/SplunkConnectionImpl.java
+++ b/splunk/src/main/java/org/apache/calcite/adapter/splunk/search/SplunkConnectionImpl.java
@@ -19,6 +19,8 @@ package org.apache.calcite.adapter.splunk.search;
 import org.apache.calcite.adapter.splunk.util.StringUtils;
 import org.apache.calcite.linq4j.Enumerator;
 import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.util.Unsafe;
+import org.apache.calcite.util.Util;
 
 import au.com.bytecode.opencsv.CSVReader;
 
@@ -34,10 +36,12 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -87,7 +91,7 @@ public class SplunkConnectionImpl implements SplunkConnection {
 
     try {
       String loginUrl =
-          String.format(
+          String.format(Locale.ROOT,
               "%s://%s:%d/services/auth/login",
               url.getProtocol(),
               url.getHost(),
@@ -97,12 +101,7 @@ public class SplunkConnectionImpl implements SplunkConnection {
       appendURLEncodedArgs(
           data, "username", username, "password", password);
 
-      rd = new BufferedReader(
-          new InputStreamReader(
-              post(
-                  loginUrl,
-                  data,
-                  requestHeaders)));
+      rd = Util.reader(post(loginUrl, data, requestHeaders));
 
       String line;
       StringBuilder reply = new StringBuilder();
@@ -141,7 +140,7 @@ public class SplunkConnectionImpl implements SplunkConnection {
       List<String> wantedFields,
       SearchResultListener srl) {
     String searchUrl =
-        String.format(
+        String.format(Locale.ROOT,
             "%s://%s:%d/services/search/jobs/export",
             url.getProtocol(),
             url.getHost(),
@@ -182,7 +181,9 @@ public class SplunkConnectionImpl implements SplunkConnection {
   }
 
   private static void parseResults(InputStream in, SearchResultListener srl) {
-    try (CSVReader r = new CSVReader(new InputStreamReader(in))) {
+    try (CSVReader r = new CSVReader(
+        new BufferedReader(
+            new InputStreamReader(in, StandardCharsets.UTF_8)))) {
       String[] header = r.readNext();
       if (header != null
           && header.length > 0
@@ -237,7 +238,7 @@ public class SplunkConnectionImpl implements SplunkConnection {
     for (String s : strings) {
       System.err.println(s);
     }
-    System.exit(1);
+    Unsafe.systemExit(1);
   }
 
   public static void main(String[] args) throws MalformedURLException {
@@ -283,8 +284,7 @@ public class SplunkConnectionImpl implements SplunkConnection {
     long start = System.currentTimeMillis();
     c.getSearchResults(search, searchArgs, null, dummy);
 
-    System.out.printf(
-        "received %d results in %dms\n",
+    System.out.printf(Locale.ROOT, "received %d results in %dms\n",
         dummy.getResultCount(),
         System.currentTimeMillis() - start);
   }
@@ -310,7 +310,8 @@ public class SplunkConnectionImpl implements SplunkConnection {
       resultCount++;
       if (print) {
         for (int i = 0; i < this.fieldNames.length; ++i) {
-          System.out.printf("%s=%s\n", this.fieldNames[i], values[i]);
+          System.out.printf(Locale.ROOT, "%s=%s\n", this.fieldNames[i],
+              values[i]);
         }
         System.out.println();
       }
@@ -346,7 +347,10 @@ public class SplunkConnectionImpl implements SplunkConnection {
     private int source;
 
     public SplunkResultEnumerator(InputStream in, List<String> wantedFields) {
-      csvReader = new CSVReader(new InputStreamReader(in));
+      csvReader =
+          new CSVReader(
+              new BufferedReader(
+                  new InputStreamReader(in, StandardCharsets.UTF_8)));
       try {
         fieldNames = csvReader.readNext();
         if (fieldNames == null

http://git-wip-us.apache.org/repos/asf/calcite/blob/75152c5b/src/main/config/forbidden-apis/signatures.txt
----------------------------------------------------------------------
diff --git a/src/main/config/forbidden-apis/signatures.txt b/src/main/config/forbidden-apis/signatures.txt
new file mode 100644
index 0000000..a0eb429
--- /dev/null
+++ b/src/main/config/forbidden-apis/signatures.txt
@@ -0,0 +1,42 @@
+# 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.
+#
+# Signatures of APIs to avoid.
+# Cribbed from Elasticsearch
+
+java.lang.Character#codePointBefore(char[],int) @ Implicit start offset is error-prone when the char[] is a buffer and the first chars are random chars
+java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone when the char[] is a buffer and the last chars are random chars
+
+@defaultMessage Only use wait / notify when really needed try to use concurrency primitives, latches or callbacks instead.
+java.lang.Object#wait()
+java.lang.Object#wait(long)
+java.lang.Object#wait(long,int)
+java.lang.Object#notify()
+java.lang.Object#notifyAll()
+
+@defaultMessage Use StringBuilder; it is more efficient
+java.lang.StringBuffer
+
+@defaultMessage Please do not try to stop the world
+java.lang.System#gc()
+
+@defaultMessage Please do not try to kill the world
+java.lang.System#exit(int)
+java.lang.Runtime#exit(int)
+
+@defaultMessage Don't interrupt threads use FutureUtils#cancel(Future<T>) instead
+java.util.concurrent.Future#cancel(boolean)
+
+# End signatures.txt


Mime
View raw message