You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by jm...@apache.org on 2021/09/16 13:39:10 UTC

[accumulo] branch main updated: Added ColFam and ColQual opts to scan command (#2255)

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

jmanno pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new 9dd6580  Added ColFam and ColQual opts to scan command (#2255)
9dd6580 is described below

commit 9dd65807008d3d3ed313d7cfd10bfb68c4ccc597
Author: harjitdotsingh <75...@users.noreply.github.com>
AuthorDate: Thu Sep 16 09:39:03 2021 -0400

    Added ColFam and ColQual opts to scan command (#2255)
    
    * This will enable users to have scan for column families with characters such as colons in them.
    * Added tests to verify this functionality.
    
    Co-authored-by: Hsingh <ha...@Hsinghs-MacBook-Pro.local>
    Co-authored-by: Jeffrey Manno <je...@gmail.com>
---
 .../accumulo/shell/commands/ScanCommand.java       | 49 +++++++++++++++++++++-
 .../accumulo/shell/commands/ScanCommandTest.java   | 12 ++++++
 .../org/apache/accumulo/test/ShellServerIT.java    | 11 +++++
 3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
index 8f5fe5f..d1c0b8d 100644
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/ScanCommand.java
@@ -59,7 +59,7 @@ import org.apache.hadoop.io.Text;
 public class ScanCommand extends Command {
 
   private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt,
-      formatterOpt, interpreterOpt, formatterInterpeterOpt, outputFileOpt;
+      formatterOpt, interpreterOpt, formatterInterpeterOpt, outputFileOpt, scanOptCf, scanOptCq;
 
   protected Option timestampOpt;
   protected Option profileOpt;
@@ -114,6 +114,7 @@ public class ScanCommand extends Command {
 
       // handle columns
       fetchColumns(cl, scanner, interpeter);
+      fetchColumsWithCFAndCQ(cl, scanner, interpeter);
 
       // set timeout
       scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
@@ -270,6 +271,16 @@ public class ScanCommand extends Command {
 
   protected void fetchColumns(final CommandLine cl, final ScannerBase scanner,
       final ScanInterpreter formatter) throws UnsupportedEncodingException {
+
+    if ((cl.hasOption(scanOptCf.getOpt()) || cl.hasOption(scanOptCq.getOpt()))
+        && cl.hasOption(scanOptColumns.getOpt())) {
+
+      String formattedString =
+          String.format("Option -%s is mutually exclusive with options -%s and -%s.",
+              scanOptColumns.getOpt(), scanOptCf.getOpt(), scanOptCq.getOpt());
+      throw new IllegalArgumentException(formattedString);
+    }
+
     if (cl.hasOption(scanOptColumns.getOpt())) {
       for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
         final String[] sa = a.split(":", 2);
@@ -285,6 +296,32 @@ public class ScanCommand extends Command {
     }
   }
 
+  private void fetchColumsWithCFAndCQ(CommandLine cl, Scanner scanner, ScanInterpreter interpeter) {
+    String cf = "";
+    String cq = "";
+    if (cl.hasOption(scanOptCf.getOpt())) {
+      cf = cl.getOptionValue(scanOptCf.getOpt());
+    }
+    if (cl.hasOption(scanOptCq.getOpt())) {
+      cq = cl.getOptionValue(scanOptCq.getOpt());
+    }
+
+    if (cf.isEmpty() && !cq.isEmpty()) {
+      String formattedString = String.format("Option -%s is required when using -%s.",
+          scanOptCf.getOpt(), scanOptCq.getOpt());
+      throw new IllegalArgumentException(formattedString);
+    } else if (!cf.isEmpty() && cq.isEmpty()) {
+      scanner.fetchColumnFamily(
+          interpeter.interpretColumnFamily(new Text(cf.getBytes(Shell.CHARSET))));
+
+    } else if (!cf.isEmpty() && !cq.isEmpty()) {
+      scanner.fetchColumn(interpeter.interpretColumnFamily(new Text(cf.getBytes(Shell.CHARSET))),
+          interpeter.interpretColumnQualifier(new Text(cq.getBytes(Shell.CHARSET))));
+
+    }
+
+  }
+
   protected Range getRange(final CommandLine cl, final ScanInterpreter formatter)
       throws UnsupportedEncodingException {
     if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT))
@@ -347,7 +384,11 @@ public class ScanCommand extends Command {
         "make end row exclusive (by default it's inclusive)");
     optEndRowExclusive.setArgName("end-exclusive");
     scanOptRow = new Option("r", "row", true, "row to scan");
-    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
+    scanOptColumns = new Option("c", "columns", true,
+        "comma-separated columns.This" + " option is mutually exclusive with cf and cq");
+    scanOptCf = new Option("cf", "column-family", true, "column family to scan.");
+    scanOptCq = new Option("cq", "column-qualifier", true, "column qualifier to scan");
+
     timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
     disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
     showFewOpt = new Option("f", "show-few", true, "show only a specified number of characters");
@@ -369,6 +410,8 @@ public class ScanCommand extends Command {
     scanOptRow.setArgName("row");
     scanOptColumns
         .setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
+    scanOptCf.setArgName("column-family");
+    scanOptCq.setArgName("column-qualifier");
     showFewOpt.setRequired(false);
     showFewOpt.setArgName("int");
     formatterOpt.setArgName("className");
@@ -390,6 +433,8 @@ public class ScanCommand extends Command {
     o.addOption(optStartRowExclusive);
     o.addOption(optEndRowExclusive);
     o.addOption(scanOptColumns);
+    o.addOption(scanOptCf);
+    o.addOption(scanOptCq);
     o.addOption(timestampOpt);
     o.addOption(disablePaginationOpt);
     o.addOption(OptUtil.tableOpt("table to be scanned"));
diff --git a/shell/src/test/java/org/apache/accumulo/shell/commands/ScanCommandTest.java b/shell/src/test/java/org/apache/accumulo/shell/commands/ScanCommandTest.java
index 66b26d9..a41c062 100644
--- a/shell/src/test/java/org/apache/accumulo/shell/commands/ScanCommandTest.java
+++ b/shell/src/test/java/org/apache/accumulo/shell/commands/ScanCommandTest.java
@@ -30,4 +30,16 @@ public class ScanCommandTest {
         new ScanCommand().getOptions().getOption("b").getDescription().contains("row (inclusive)"));
   }
 
+  @Test
+  public void testCFRowHelp() {
+    assertTrue("Column Family",
+        new ScanCommand().getOptions().getOption("cf").getDescription().contains("family"));
+  }
+
+  @Test
+  public void testCQHelp() {
+    assertTrue("Column Qualifier",
+        new ScanCommand().getOptions().getOption("cq").getDescription().contains("qualifier"));
+  }
+
 }
diff --git a/test/src/main/java/org/apache/accumulo/test/ShellServerIT.java b/test/src/main/java/org/apache/accumulo/test/ShellServerIT.java
index 012dc4b..a5c8cfe 100644
--- a/test/src/main/java/org/apache/accumulo/test/ShellServerIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/ShellServerIT.java
@@ -1940,6 +1940,17 @@ public class ShellServerIT extends SharedMiniClusterBase {
   }
 
   @Test
+  public void scansWithColon() throws Exception {
+    ts.exec("createtable twithcolontest");
+    ts.exec("insert row c:f cq value");
+    ts.exec("scan -r row -cf c:f", true, "value");
+    ts.exec("scan -b row -cf c:f  -cq cq -e row", true, "value");
+    ts.exec("scan -b row -c cf -cf c:f  -cq cq -e row", false, "mutually exclusive");
+    ts.exec("scan -b row -cq col1 -e row", false, "Option -cf is required when using -cq");
+    ts.exec("deletetable -f twithcolontest");
+  }
+
+  @Test
   public void scansWithClassLoaderContext() throws IOException {
 
     try {