Skip to content

Commit

Permalink
Added CLI enhancement for better maintainability
Browse files Browse the repository at this point in the history
  • Loading branch information
akashrn5 committed Oct 25, 2018
1 parent d86fd5e commit 6b09d2f
Show file tree
Hide file tree
Showing 13 changed files with 385 additions and 137 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,10 @@ class TestNonTransactionalCarbonTable extends QueryTest with BeforeAndAfterAll {
|'carbondata' LOCATION
|'$writerPath' """.stripMargin)

val output = sql("show summary for table sdkOutputTable options('command'='-cmd,summary,-p,-a,-v,-c,age')").collect()

assert(output.toList.contains(Row("written_by Version ")))

checkExistence(sql("describe formatted sdkOutputTable"), true, "age,name")

checkExistence(sql("describe formatted sdkOutputTable"), true, writerPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ abstract class CarbonDDLSqlParser extends AbstractCarbonSparkSQLParser {
protected val STREAM = carbonKeyWord("STREAM")
protected val STREAMS = carbonKeyWord("STREAMS")
protected val STMPROPERTIES = carbonKeyWord("STMPROPERTIES")
protected val SUMMARY = carbonKeyWord("SUMMARY")

protected val doubleQuotedString = "\"([^\"]+)\"".r
protected val singleQuotedString = "'([^']+)'".r
Expand Down Expand Up @@ -1141,6 +1142,13 @@ abstract class CarbonDDLSqlParser extends AbstractCarbonSparkSQLParser {
case _ => ("", "")
}

protected lazy val summaryOptions: Parser[(String, String)] =
(stringLit <~ "=") ~ stringLit ^^ {
case opt ~ optvalue => (opt.trim.toLowerCase(), optvalue)
case _ => ("", "")
}


protected lazy val partitions: Parser[(String, Option[String])] =
(ident <~ "=".?) ~ stringLit.? ^^ {
case opt ~ optvalue => (opt.trim, optvalue)
Expand Down
5 changes: 5 additions & 0 deletions integration/spark2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
<artifactId>carbondata-spark-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.carbondata</groupId>
<artifactId>carbondata-cli</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.carbondata</groupId>
<artifactId>carbondata-store-sdk</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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.spark.sql.execution.command.management

import java.util

import scala.collection.JavaConverters._

import org.apache.spark.sql.{CarbonEnv, Row, SparkSession}
import org.apache.spark.sql.catalyst.expressions.{Attribute, AttributeReference}
import org.apache.spark.sql.execution.command.{Checker, DataCommand}
import org.apache.spark.sql.types.StringType

import org.apache.carbondata.tool.CarbonCli

/**
* Show summary command class which is integrated to cli and sql support is provided via this class
* @param databaseNameOp
* @param tableName
* @param commandOptions
*/
case class CarbonShowSummaryCommand(
databaseNameOp: Option[String],
tableName: String,
commandOptions: Map[String, String])
extends DataCommand {

override def output: Seq[Attribute] = {
Seq(AttributeReference("Table Summary", StringType, nullable = false)())
}

override def processData(sparkSession: SparkSession): Seq[Row] = {
Checker.validateTableExists(databaseNameOp, tableName, sparkSession)
val carbonTable = CarbonEnv.getCarbonTable(databaseNameOp, tableName)(sparkSession)
val commandArgs: Seq[String] = commandOptions("command").split(",")
val finalCommands = commandArgs.collect {
case a if a.trim.equalsIgnoreCase("-p") =>
Seq(a, carbonTable.getTablePath)
case x => Seq(x.trim)
}.flatten
val summaryOutput = new util.ArrayList[String]()
CarbonCli.run(finalCommands.toArray, summaryOutput)
summaryOutput.asScala.map(x =>
Row(x)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class CarbonSpark2SqlParser extends CarbonDDLSqlParser {

protected lazy val startCommand: Parser[LogicalPlan] =
loadManagement | showLoads | alterTable | restructure | updateTable | deleteRecords |
alterPartition | datamapManagement | alterTableFinishStreaming | stream
alterPartition | datamapManagement | alterTableFinishStreaming | stream | cli

protected lazy val loadManagement: Parser[LogicalPlan] =
deleteLoadsByID | deleteLoadsByLoadDate | cleanFiles | loadDataNew
Expand Down Expand Up @@ -495,6 +495,23 @@ class CarbonSpark2SqlParser extends CarbonDDLSqlParser {
showHistory.isDefined)
}


protected lazy val cli: Parser[LogicalPlan] =
(SHOW ~> SUMMARY ~> FOR ~> TABLE) ~> (ident <~ ".").? ~ ident ~
(OPTIONS ~> "(" ~> repsep(summaryOptions, ",") <~ ")").? <~
opt(";") ^^ {
case databaseName ~ tableName ~ commandList =>
var commandOptions: Map[String, String] = null
if (commandList.isDefined) {
commandOptions = commandList.getOrElse(List.empty[(String, String)]).toMap
}
CarbonShowSummaryCommand(
convertDbNameToLowerCase(databaseName),
tableName.toLowerCase(),
commandOptions.map { case (key, value) => key.toLowerCase -> value })
}


protected lazy val alterTableModifyDataType: Parser[LogicalPlan] =
ALTER ~> TABLE ~> (ident <~ ".").? ~ ident ~ CHANGE ~ ident ~ ident ~
ident ~ opt("(" ~> rep1sep(valueOptions, ",") <~ ")") <~ opt(";") ^^ {
Expand Down
61 changes: 55 additions & 6 deletions tools/cli/src/main/java/org/apache/carbondata/tool/CarbonCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.carbondata.common.annotations.InterfaceAudience;
import org.apache.carbondata.common.annotations.InterfaceStability;
Expand All @@ -40,6 +42,13 @@
@InterfaceStability.Unstable
public class CarbonCli {

// List to collect all the outputs of option details
private static List<String> outPuts;

// a boolean variable to decide whether to print the output in console or return the list,
// by default true, and it will be set to false if the cli is trigerred via sql command
private static boolean isPrintInConsole = true;

private static Options buildOptions() {
Option help = new Option("h", "help", false,"print this message");
Option path = OptionBuilder.withArgName("path")
Expand All @@ -64,7 +73,6 @@ private static Options buildOptions() {
Option schema = new Option("s", "schema",false, "print the schema");
Option segment = new Option("m", "showSegment", false, "print segment information");
Option tblProperties = new Option("t", "tblProperties", false, "print table properties");
Option detail = new Option("b", "blocklet", false, "print blocklet size detail");
Option columnMeta = new Option("k", "columnChunkMeta", false, "print column chunk meta");
Option columnName = OptionBuilder
.withArgName("column name")
Expand All @@ -73,6 +81,15 @@ private static Options buildOptions() {
.withLongOpt("column")
.create("c");

Option blockletDetail = OptionBuilder.withArgName("limitSize").hasOptionalArg()
.withDescription("print blocklet size detail").withLongOpt("limitSize")
.create("b");

Option blockLevelDetail = OptionBuilder.withArgName("blockDetail").hasArg()
.withDescription("print block details").withLongOpt("blockDetail")
.create("B");

Option version = new Option("v", "version", false, "print version details of carbondata file");
Options options = new Options();
options.addOption(help);
options.addOption(path);
Expand All @@ -82,17 +99,36 @@ private static Options buildOptions() {
options.addOption(schema);
options.addOption(segment);
options.addOption(tblProperties);
options.addOption(detail);
options.addOption(blockletDetail);
options.addOption(columnMeta);
options.addOption(columnName);
options.addOption(version);
options.addOption(blockLevelDetail);
return options;
}

public static void main(String[] args) {
run(args, System.out);
}

static void run(String[] args, PrintStream out) {
public static void run(String[] args, ArrayList<String> e) {
// this boolean to check whether to print in console or not
isPrintInConsole = false;
outPuts = e;
Options options = buildOptions();
CommandLineParser parser = new PosixParser();

CommandLine line;
try {
line = parser.parse(options, args);
} catch (ParseException exp) {
throw new RuntimeException("Parsing failed. Reason: " + exp.getMessage());
}

runCli(System.out, options, line);
}

public static void run(String[] args, PrintStream out) {
Options options = buildOptions();
CommandLineParser parser = new PosixParser();

Expand All @@ -104,6 +140,13 @@ static void run(String[] args, PrintStream out) {
return;
}

runCli(out, options, line);
}

private static void runCli(PrintStream out, Options options, CommandLine line) {
if (outPuts == null) {
outPuts = new ArrayList<>();
}
if (line.hasOption("h")) {
printHelp(options);
return;
Expand All @@ -113,22 +156,28 @@ static void run(String[] args, PrintStream out) {
if (line.hasOption("p")) {
path = line.getOptionValue("path");
}
out.println("Input Folder: " + path);
outPuts.add("Input Folder: " + path);

String cmd = line.getOptionValue("cmd");
Command command;
if (cmd.equalsIgnoreCase("summary")) {
command = new DataSummary(path, out);
command = new DataSummary(path, outPuts);
} else if (cmd.equalsIgnoreCase("benchmark")) {
command = new ScanBenchmark(path, out);
command = new ScanBenchmark(path, outPuts);
} else {
out.println("command " + cmd + " is not supported");
outPuts.add("command " + cmd + " is not supported");
printHelp(options);
return;
}

try {
command.run(line);
if (isPrintInConsole) {
for (String output : outPuts) {
out.println(output);
}
}
out.flush();
} catch (IOException | MemoryException e) {
e.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ class ColumnChunk {
// min/max stats of this column chunk
byte[] min, max;

// to set whether min max is present for the column chunck, as we may not right min max after
// specific size
boolean isMinMaxPresent;

// percentage of min/max comparing to min/max scope collected in all blocklets
// they are set after calculation in DataSummary
double minPercentage, maxPercentage;
Expand All @@ -335,6 +339,7 @@ class ColumnChunk {
this.column = column;
min = index.min_max_index.min_values.get(columnIndex).array();
max = index.min_max_index.max_values.get(columnIndex).array();
isMinMaxPresent = index.min_max_index.min_max_presence.get(columnIndex);

// read the column chunk metadata: DataChunk3
ByteBuffer buffer = fileReader.readByteBuffer(
Expand Down
Loading

0 comments on commit 6b09d2f

Please sign in to comment.