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

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 8c7c73f  support special characters. (#1253)
8c7c73f is described below

commit 8c7c73f61ad43bfa6091785f41ee354c4ebd61ad
Author: Boris <[email protected]>
AuthorDate: Sun May 24 22:50:14 2020 +0800

    support special characters. (#1253)
    
    * support special characters in path
---
 .../org/apache/iotdb/db/qp/strategy/SqlBase.g4     | 69 ++++++++++++++++------
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  9 ++-
 .../iotdb/db/qp/logical/sys/LoadFilesOperator.java | 16 -----
 .../iotdb/db/qp/strategy/LogicalGenerator.java     | 35 +++++------
 .../iotdb/db/qp/strategy/PhysicalGenerator.java    |  3 -
 .../db/integration/IoTDBLoadExternalTsfileIT.java  | 13 +---
 .../apache/iotdb/db/qp/plan/PhysicalPlanTest.java  |  7 +++
 .../apache/iotdb/db/sql/CheckPathValidityTest.java |  7 ++-
 .../org/apache/iotdb/session/IoTDBSessionIT.java   | 10 ++--
 9 files changed, 93 insertions(+), 76 deletions(-)

diff --git a/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4 
b/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4
index 4c56b68..d119c41 100644
--- a/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4
+++ b/server/src/main/antlr4/org/apache/iotdb/db/qp/strategy/SqlBase.g4
@@ -37,7 +37,7 @@ statement
     | CREATE INDEX ON fullPath USING function=ID indexWithClause? whereClause? 
#createIndex //not support yet
     | DROP INDEX function=ID ON fullPath #dropIndex //not support yet
     | MERGE #merge
-    | FLUSH prefixPath? (COMMA prefixPath)* (ID)?#flush //ID is true or false
+    | FLUSH prefixPath? (COMMA prefixPath)* (booleanClause)?#flush
     | FULL MERGE #fullMerge
     | CLEAR CACHE #clearcache
     | CREATE USER userName=ID password=STRING_LITERAL #createUser
@@ -322,14 +322,10 @@ timeValue
     ;
 
 propertyValue
-    : ID
-    | MINUS? INT
-    | MINUS? realLiteral
+    : INT
+    | ID
     | STRING_LITERAL
-    ;
-
-propertyLabelPair
-    : propertyName=ID DOT labelName=ID
+    | constant
     ;
 
 fullPath
@@ -346,18 +342,21 @@ suffixPath
 
 nodeName
     : ID
-    | INT
     | STAR
     | ID STAR
-    | STRING_LITERAL
     | DURATION
+    | encoding
+    | dataType
+    | constant
     ;
 
 nodeNameWithoutStar
-    : INT
-    | ID
+    : ID
     | STRING_LITERAL
     | DURATION
+    | encoding
+    | dataType
+    | constant
     ;
 
 dataType
@@ -371,10 +370,16 @@ dateFormat
 
 constant
     : dateExpression
-    | ID
     | MINUS? realLiteral
     | MINUS? INT
     | STRING_LITERAL
+    | TRUE
+    | FALSE
+    ;
+
+booleanClause
+    : TRUE
+    | FALSE
     ;
 
 dateExpression
@@ -396,8 +401,8 @@ property
     ;
 
 autoCreateSchema
-    : ID
-    | ID INT
+    : booleanClause
+    | booleanClause INT
     ;
 
 //============================
@@ -831,6 +836,14 @@ CLEAR
 CACHE
     : C A C H E
     ;
+
+TRUE
+    : T R U E
+    ;
+
+FALSE
+    : F A L S E
+    ;
 //============================
 // End of the keywords list
 //============================
@@ -912,12 +925,12 @@ DATETIME
       INT ':' INT ':' INT (DOT INT)?
       (('+' | '-') INT ':' INT)?)?
     ;
-/** Allow unicode rule/token names */
-ID : NAME_CHAR NAME_CHAR*;
 
 FILE
     :  (('a'..'z'| 'A'..'Z')(':')?)* (('\\' | '/')+ PATH_FRAGMENT) +
     ;
+/** Allow unicode rule/token names */
+ID : FIRST_NAME_CHAR NAME_CHAR*;
 
 fragment
 NAME_CHAR
@@ -925,6 +938,28 @@ NAME_CHAR
     |   'a'..'z'
     |   '0'..'9'
     |   '_'
+    |   '-'
+    |   '/'
+    |   '@'
+    |   '#'
+    |   '$'
+    |   '%'
+    |   '&'
+    |   CN_CHAR
+    ;
+
+fragment
+FIRST_NAME_CHAR
+    :   'A'..'Z'
+    |   'a'..'z'
+    |   '0'..'9'
+    |   '_'
+    |   '/'
+    |   '@'
+    |   '#'
+    |   '$'
+    |   '%'
+    |   '&'
     |   CN_CHAR
     ;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java 
b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index 8547960..1c40347 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -47,12 +47,15 @@ public class IoTDBConfig {
       "org.apache.iotdb.db.conf.directories.strategy.";
   private static final String DEFAULT_MULTI_DIR_STRATEGY = 
"MaxDiskUsableSpaceFirstStrategy";
 
-  private static final String NODE_MATCHER =
-      "[" + PATH_SEPARATOR + "]" + "([a-zA-Z0-9\u2E80-\u9FFF_]+)";
+  // e.g., a31+/$%#&[]{}3e4
+  private static final String ID_MATCHER = 
"([a-zA-Z0-9/@#$%&{}\\[\\]\\-+\\u2E80-\\u9FFF_]+)";
+
+  // e.g.,  .s1
+  private static final String NODE_MATCHER = "[" + PATH_SEPARATOR + "]" + 
ID_MATCHER;
 
   // for path like: root.sg1.d1."1.2.3" or root.sg1.d1.'1.2.3', only occurs in 
the end of the path and only occurs once
   private static final String NODE_WITH_QUOTATION_MARK_MATCHER =
-      "[" + PATH_SEPARATOR + "][\"|\']([a-zA-Z0-9\u2E80-\u9FFF_]+)(" + 
NODE_MATCHER + ")+[\"|\']";
+      "[" + PATH_SEPARATOR + "][\"|\']" + ID_MATCHER +"(" + NODE_MATCHER+ 
")*[\"|\']";
   public static final Pattern PATH_PATTERN = Pattern
       .compile(PATH_ROOT + "(" + NODE_MATCHER + ")+(" + 
NODE_WITH_QUOTATION_MARK_MATCHER + ")?");
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/LoadFilesOperator.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/LoadFilesOperator.java
index f60262a..90a2c1a 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/LoadFilesOperator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/LoadFilesOperator.java
@@ -27,8 +27,6 @@ public class LoadFilesOperator extends RootOperator {
   private File file;
   private boolean autoCreateSchema;
   private int sgLevel;
-  private boolean invalid;
-  private String errMsg;
 
   public LoadFilesOperator(File file, boolean autoCreateSchema, int sgLevel) {
     super(SQLConstant.TOK_LOAD_FILES);
@@ -38,12 +36,6 @@ public class LoadFilesOperator extends RootOperator {
     this.operatorType = OperatorType.LOAD_FILES;
   }
 
-  public LoadFilesOperator(boolean invalid, String errMsg) {
-    super(SQLConstant.TOK_LOAD_FILES);
-    this.invalid = invalid;
-    this.errMsg = errMsg;
-    this.operatorType = OperatorType.LOAD_FILES;
-  }
 
   public File getFile() {
     return file;
@@ -56,12 +48,4 @@ public class LoadFilesOperator extends RootOperator {
   public int getSgLevel() {
     return sgLevel;
   }
-
-  public boolean isInvalid() {
-    return invalid;
-  }
-
-  public String getErrMsg() {
-    return errMsg;
-  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
index c84c654..4da9f2d 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/strategy/LogicalGenerator.java
@@ -90,13 +90,8 @@ public class LogicalGenerator extends SqlBaseBaseListener {
   public void enterFlush(FlushContext ctx) {
     super.enterFlush(ctx);
     FlushOperator flushOperator = new FlushOperator(SQLConstant.TOK_FLUSH);
-    if(ctx.ID() != null) {
-      if(ctx.ID().getText().equalsIgnoreCase("true")
-          || ctx.ID().getText().equalsIgnoreCase("false")) {
-        flushOperator.setSeq(Boolean.parseBoolean(ctx.ID().getText()));
-      } else {
-        throw new ParseCancellationException("Should be true or false");
-      }
+    if(ctx.booleanClause() != null) {
+        
flushOperator.setSeq(Boolean.parseBoolean(ctx.booleanClause().getText()));
     }
     if(ctx.prefixPath(0) != null) {
       List<Path> storageGroups = new ArrayList<>();
@@ -167,21 +162,23 @@ public class LogicalGenerator extends SqlBaseBaseListener 
{
   @Override
   public void enterLoadFiles(LoadFilesContext ctx) {
     super.enterLoadFiles(ctx);
-    AutoCreateSchemaContext acsc = ctx.autoCreateSchema();
-    if (acsc != null) {
-      if (!acsc.ID().getText().equalsIgnoreCase("true") && !acsc.ID().getText()
-          .equalsIgnoreCase("false")) {
-        initializedOperator = new LoadFilesOperator(true,
-            "Please check the statement: load [FILE] true/false [storage group 
level]");
+    if(ctx.autoCreateSchema() != null) {
+      if(ctx.autoCreateSchema().INT() != null) {
+        initializedOperator = new LoadFilesOperator(new 
File(ctx.FILE().getText()),
+            
Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()),
+            Integer.parseInt(ctx.autoCreateSchema().INT().getText())
+        );
       } else {
-        int sgLevel = acsc.INT() == null ? 
IoTDBDescriptor.getInstance().getConfig()
-            .getDefaultStorageGroupLevel() : 
Integer.parseInt(acsc.INT().getText());
-        initializedOperator = new LoadFilesOperator(new 
File(ctx.FILE().getText()), Boolean
-            .parseBoolean(acsc.ID().getText()), sgLevel);
+        initializedOperator = new LoadFilesOperator(new 
File(ctx.FILE().getText()),
+            
Boolean.parseBoolean(ctx.autoCreateSchema().booleanClause().getText()),
+            
IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel()
+        );
       }
     } else {
-      initializedOperator = new LoadFilesOperator(new 
File(ctx.getChild(1).getText()), true,
-          
IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel());
+      initializedOperator = new LoadFilesOperator(new 
File(ctx.FILE().getText()),
+          true,
+          
IoTDBDescriptor.getInstance().getConfig().getDefaultStorageGroupLevel()
+      );
     }
   }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
index 0dfa0b3..a083856 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/strategy/PhysicalGenerator.java
@@ -254,9 +254,6 @@ public class PhysicalGenerator {
                     "not supported operator type %s in show operation.", 
operator.getType()));
         }
       case LOAD_FILES:
-        if (((LoadFilesOperator) operator).isInvalid()) {
-          throw new LogicalOperatorException(((LoadFilesOperator) 
operator).getErrMsg());
-        }
         return new OperateFilePlan(
             ((LoadFilesOperator) operator).getFile(),
             OperatorType.LOAD_FILES,
diff --git 
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsfileIT.java
 
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsfileIT.java
index dff350c..4b013fc 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsfileIT.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsfileIT.java
@@ -405,20 +405,9 @@ public class IoTDBLoadExternalTsfileIT {
         statement.execute(sql);
       }
 
-      // test wrong statement
-      boolean hasError = false;
-      try {
-        statement.execute(String.format("load %s true1 1", 
tmpDir.getAbsolutePath()));
-      } catch (Exception e) {
-        hasError = true;
-        Assert.assertEquals(
-            "411: Meet error in query process: Please check the statement: 
load [FILE] true/false [storage group level]",
-            e.getMessage());
-      }
-      Assert.assertTrue(hasError);
 
       // test not load metadata automatically, it will occur errors.
-      hasError = false;
+      boolean hasError = false;
       try {
         statement.execute(String.format("load %s false 1", 
tmpDir.getAbsolutePath()));
       } catch (Exception e) {
diff --git 
a/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java 
b/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
index 7fe7250..ce47702 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/plan/PhysicalPlanTest.java
@@ -796,4 +796,11 @@ public class PhysicalPlanTest {
       assertEquals(TSDataType.FLOAT, dt);
     }
   }
+
+  @Test
+  public void testSpecialCharacters() throws QueryProcessException {
+    String sqlStr1 = "create timeseries root.3e-3.-1.1/2.SNAPPY.RLE with 
datatype=FLOAT, encoding=RLE, compression=SNAPPY tags(tag1=v1, tag2=v2) 
attributes(attr1=v1, attr2=v2)";
+    PhysicalPlan plan1 = processor.parseSQLToPhysicalPlan(sqlStr1);
+    Assert.assertEquals(OperatorType.CREATE_TIMESERIES, 
plan1.getOperatorType());
+  }
 }
diff --git 
a/server/src/test/java/org/apache/iotdb/db/sql/CheckPathValidityTest.java 
b/server/src/test/java/org/apache/iotdb/db/sql/CheckPathValidityTest.java
index 2204c3b..2a0f57e 100644
--- a/server/src/test/java/org/apache/iotdb/db/sql/CheckPathValidityTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/sql/CheckPathValidityTest.java
@@ -43,7 +43,10 @@ public class CheckPathValidityTest {
     assertFalse(IoTDBConfig.PATH_PATTERN.matcher("root.\tvehicle").matches());
     assertFalse(IoTDBConfig.PATH_PATTERN.matcher("root.\nvehicle").matches());
     assertFalse(IoTDBConfig.PATH_PATTERN.matcher("root..vehicle").matches());
-    assertFalse(IoTDBConfig.PATH_PATTERN.matcher("root.%12345").matches());
-    assertFalse(IoTDBConfig.PATH_PATTERN.matcher("root.a{12345}").matches());
+    assertTrue(IoTDBConfig.PATH_PATTERN.matcher("root.%12345").matches());
+    assertTrue(IoTDBConfig.PATH_PATTERN.matcher("root.a{12345}").matches());
+    assertTrue(IoTDBConfig.PATH_PATTERN.matcher("root.a[12345]").matches());
+    
assertTrue(IoTDBConfig.PATH_PATTERN.matcher("root.2e3.2-2.-1.%$#/&@.a[12345]{}").matches());
+    assertTrue(IoTDBConfig.PATH_PATTERN.matcher("root.a.b.\"c.a\"").matches());
   }
 }
diff --git a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java 
b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java
index cbfe569..4c4b1e2 100644
--- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java
+++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java
@@ -758,8 +758,10 @@ public class IoTDBSessionIT {
     checkSetSG(session, "root..vehicle", false);
     checkSetSG(session, "root.1234a4", true);
     checkSetSG(session, "root.1_2", true);
-    checkSetSG(session, "root.%12345", false);
-    checkSetSG(session, "root.a{12345}", false);
+    checkSetSG(session, "root.%12345", true);
+    checkSetSG(session, "root.+12345", true);
+    checkSetSG(session, "root.-12345", true);
+    checkSetSG(session, "root.a{12345}", true);
 
     //test create timeseries
     checkCreateTimeseries(session, "root.vehicle.d0.s0", true);
@@ -768,10 +770,10 @@ public class IoTDBSessionIT {
     checkCreateTimeseries(session, "root.vehicle._1234.s0", true);
     checkCreateTimeseries(session, "root.vehicle.1245.\"1.2.3\"", true);
     checkCreateTimeseries(session, "root.vehicle.1245.\'1.2.4\'", true);
-    checkCreateTimeseries(session, "root.vehicle./d0.s0", false);
+    checkCreateTimeseries(session, "root.vehicle./d0.s0", true);
     checkCreateTimeseries(session, "root.vehicle.d\t0.s0", false);
     checkCreateTimeseries(session, "root.vehicle.!d\t0.s0", false);
-    checkCreateTimeseries(session, "root.vehicle.d{dfewrew0}.s0", false);
+    checkCreateTimeseries(session, "root.vehicle.d{dfewrew0}.s0", true);
 
     session.close();
   }

Reply via email to