diff --git beeline/pom.xml beeline/pom.xml index 6ec1d1a..fbe0ed0 100644 --- beeline/pom.xml +++ beeline/pom.xml @@ -81,6 +81,11 @@ libthrift ${libthrift.version} + + net.sf.supercsv + super-csv + ${super-csv.version} + org.apache.hive diff --git beeline/src/java/org/apache/hive/beeline/BeeLineOpts.java beeline/src/java/org/apache/hive/beeline/BeeLineOpts.java index 75f7d38..0d529d1 100644 --- beeline/src/java/org/apache/hive/beeline/BeeLineOpts.java +++ beeline/src/java/org/apache/hive/beeline/BeeLineOpts.java @@ -88,7 +88,7 @@ private String scriptFile = null; private String initFile = null; private String authType = null; - + private boolean outputAsCLICSVFormat = false; private Map hiveVariables = new HashMap(); private Map hiveConfVariables = new HashMap(); @@ -490,5 +490,13 @@ public String getNullString(){ public void setHiveConfVariables(Map hiveConfVariables) { this.hiveConfVariables = hiveConfVariables; } + + public boolean getOutputAsCLICSVFormat() { + return outputAsCLICSVFormat; + } + + public void setOutputAsCLICSVFormat(boolean outputAsCLICSVFormat) { + this.outputAsCLICSVFormat = outputAsCLICSVFormat; + } } diff --git beeline/src/java/org/apache/hive/beeline/SeparatedValuesOutputFormat.java beeline/src/java/org/apache/hive/beeline/SeparatedValuesOutputFormat.java index 7853c3f..4edbf0c 100644 --- beeline/src/java/org/apache/hive/beeline/SeparatedValuesOutputFormat.java +++ beeline/src/java/org/apache/hive/beeline/SeparatedValuesOutputFormat.java @@ -22,6 +22,12 @@ */ package org.apache.hive.beeline; +import java.io.IOException; +import java.io.StringWriter; + +import org.apache.zookeeper.common.IOUtils; +import org.supercsv.io.CsvListWriter; +import org.supercsv.prefs.CsvPreference; /** * OutputFormat for values separated by a delimiter. * @@ -34,10 +40,14 @@ */ private final BeeLine beeLine; private char separator; + private CsvPreference csvPreference; public SeparatedValuesOutputFormat(BeeLine beeLine, char separator) { this.beeLine = beeLine; setSeparator(separator); + csvPreference = + new CsvPreference.Builder('"', this.getSeparator(), "") + .surroundingSpacesNeedQuotes(true).build(); } public int print(Rows rows) { @@ -49,16 +59,42 @@ public int print(Rows rows) { return count - 1; // sans header row } - public void printRow(Rows rows, Rows.Row row) { - String[] vals = row.values; + private String getStrInRFCFormat(String[] vals) { + StringWriter strWriter = new StringWriter(); + CsvListWriter write = new CsvListWriter(strWriter, csvPreference); + if (vals.length > 0) { + try { + write.write(vals); + } catch (IOException e) { + beeLine.error(e); + } finally { + IOUtils.closeStream(write); + } + } + return strWriter.toString(); + } + + private String getStrInHiveCliFormat(String[] vals) { StringBuilder buf = new StringBuilder(); for (int i = 0; i < vals.length; i++) { - buf.append(buf.length() == 0 ? "" : "" + getSeparator()) - .append('\'') - .append(vals[i] == null ? "" : vals[i]) - .append('\''); + buf.append(buf.length() == 0 ? "" : "" + getSeparator()).append( + vals[i] == null ? "" : vals[i]); + } + return buf.toString(); + } + + private String getFormatStr(String[] vals) { + if (beeLine.getOpts().getOutputAsCLICSVFormat()) { + return getStrInHiveCliFormat(vals); + }else{ + return getStrInRFCFormat(vals); } - beeLine.output(buf.toString()); + } + + public void printRow(Rows rows, Rows.Row row) { + String[] vals = row.values; + String formattedStr = getFormatStr(vals); + beeLine.output(formattedStr); } public void setSeparator(char separator) { @@ -68,4 +104,12 @@ public void setSeparator(char separator) { public char getSeparator() { return this.separator; } + + public CsvPreference getCsvPreference() { + return this.csvPreference; + } + + public void setCsvPreference(CsvPreference csvPreference) { + this.csvPreference = csvPreference; + } } diff --git beeline/src/main/resources/BeeLine.properties beeline/src/main/resources/BeeLine.properties index 390d062..314fa4a 100644 --- beeline/src/main/resources/BeeLine.properties +++ beeline/src/main/resources/BeeLine.properties @@ -167,6 +167,7 @@ cmd-usage: Usage: java org.apache.hive.cli.beeline.BeeLine \n \ \ --silent=[true/false] be more silent\n \ \ --autosave=[true/false] automatically save preferences\n \ \ --outputformat=[table/vertical/csv/tsv] format mode for result display\n \ +\ --outputAsCLICSVFormat=[true/false] display the output in the csv format as Hive command line\n \ \ --isolation=LEVEL set the transaction isolation level\n \ \ --nullemptystring=[true/false] set to true to get historic behavior of printing null as empty string\n \ \ --help display this message diff --git itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java index 8888bd9..e1d44ec 100644 --- itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java +++ itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java @@ -362,7 +362,7 @@ public void testNullEmpty() throws Throwable { final String TEST_NAME = "testNullNonDefault"; final String SCRIPT_TEXT = "set hive.support.concurrency = false;\n" + "!set nullemptystring true\n select 'abc',null,'def' from " + tableName + " limit 1 ;\n"; - final String EXPECTED_PATTERN = "'abc','','def'"; + final String EXPECTED_PATTERN = "abc,,def"; List argList = getBaseArgs(JDBC_URL); argList.add("--outputformat=csv"); @@ -382,7 +382,7 @@ public void testNullEmptyCmdArg() throws Throwable { final String SCRIPT_TEXT = "set hive.support.concurrency = false;\n" + "select 'abc',null,'def' from " + tableName + " limit 1 ;\n"; //final String EXPECTED_PATTERN = "| abc | | def |"; - final String EXPECTED_PATTERN = "'abc','','def'"; + final String EXPECTED_PATTERN = "abc,,def"; List argList = getBaseArgs(JDBC_URL); argList.add("--nullemptystring=true"); diff --git pom.xml pom.xml index b5a5697..57c1c12 100644 --- pom.xml +++ pom.xml @@ -144,6 +144,7 @@ 1.0.1 1.7.5 4.0.4 + 2.2.0 0.4.0-incubating 1.1 0.2