You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by hu...@apache.org on 2022/12/07 13:55:36 UTC
[iotdb] branch master updated: Update nodenames if necessary in ClientRpcServiceImpl (#8359)
This is an automated email from the ASF dual-hosted git repository.
hui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new a971a8d04f Update nodenames if necessary in ClientRpcServiceImpl (#8359)
a971a8d04f is described below
commit a971a8d04fb0c5c992582d01ee7ef5e17ebbb4e2
Author: Liao Lanyu <14...@qq.com>
AuthorDate: Wed Dec 7 21:55:31 2022 +0800
Update nodenames if necessary in ClientRpcServiceImpl (#8359)
---
.../session/it/IoTDBSessionSyntaxConventionIT.java | 2 +
.../org/apache/iotdb/commons/utils/PathUtils.java | 135 ++++++++++++---------
.../iotdb/db/mpp/plan/parser/ASTVisitor.java | 14 +--
.../service/thrift/impl/ClientRPCServiceImpl.java | 32 +++--
.../db/service/thrift/impl/TSServiceImpl.java | 13 +-
5 files changed, 110 insertions(+), 86 deletions(-)
diff --git a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSyntaxConventionIT.java b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSyntaxConventionIT.java
index 9b3a24160c..f0417d0500 100644
--- a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSyntaxConventionIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSyntaxConventionIT.java
@@ -109,6 +109,7 @@ public class IoTDBSessionSyntaxConventionIT {
measurements.add("`a“(Φ)”b`");
measurements.add("`a>b`");
measurements.add("`\\\"a`");
+ measurements.add("`aaa`");
List<String> values = new ArrayList<>();
for (int i = 0; i < measurements.size(); i++) {
@@ -125,6 +126,7 @@ public class IoTDBSessionSyntaxConventionIT {
assertTrue(session.checkTimeseriesExists("root.sg1.d1.`a“(Φ)”b`"));
assertTrue(session.checkTimeseriesExists("root.sg1.d1.`a>b`"));
assertTrue(session.checkTimeseriesExists("root.sg1.d1.`\\\"a`"));
+ assertTrue(session.checkTimeseriesExists("root.sg1.d1.aaa"));
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java b/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java
index 3837424864..36f0050301 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java
@@ -26,9 +26,10 @@ import org.apache.iotdb.tsfile.exception.PathParseException;
import org.apache.iotdb.tsfile.read.common.parser.PathNodesGenerator;
import org.apache.iotdb.tsfile.read.common.parser.PathVisitor;
-import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
public class PathUtils {
@@ -48,118 +49,131 @@ public class PathUtils {
}
}
- public static void isLegalPath(String path) throws IllegalPathException {
+ public static String[] isLegalPath(String path) throws IllegalPathException {
try {
- PathNodesGenerator.splitPathToNodes(path);
+ return PathNodesGenerator.splitPathToNodes(path);
} catch (PathParseException e) {
throw new IllegalPathException(path);
}
}
/**
- * check whether measurement is legal according to syntax convention measurement can only be a
- * single node name
+ * check whether measurement is legal according to syntax convention. Measurement can only be a
+ * single node name. The returned list is updated, could be different from the original list.
*/
- public static void isLegalSingleMeasurementLists(List<List<String>> measurementLists)
- throws MetadataException {
+ public static List<List<String>> checkIsLegalSingleMeasurementListsAndUpdate(
+ List<List<String>> measurementLists) throws MetadataException {
if (measurementLists == null) {
- return;
+ return null;
}
- // use set to skip checking duplicated measurements
- Set<String> measurementSet = new HashSet<>();
+ // skip checking duplicated measurements
+ Map<String, String> checkedMeasurements = new HashMap<>();
+ List<List<String>> res = new ArrayList<>();
for (List<String> measurements : measurementLists) {
- checkLegalSingleMeasurementsAndSkipDuplicate(measurements, measurementSet);
+ res.add(checkLegalSingleMeasurementsAndSkipDuplicate(measurements, checkedMeasurements));
}
+ return res;
}
/**
- * check whether measurement is legal according to syntax convention measurement can only be a
+ * check whether measurement is legal according to syntax convention. Measurement can only be a
* single node name, use set to skip checking duplicated measurements
*/
- public static void checkLegalSingleMeasurementsAndSkipDuplicate(
- List<String> measurements, Set<String> measurementSet) throws MetadataException {
+ public static List<String> checkLegalSingleMeasurementsAndSkipDuplicate(
+ List<String> measurements, Map<String, String> checkedMeasurements) throws MetadataException {
if (measurements == null) {
- return;
+ return null;
}
+ List<String> res = new ArrayList<>();
for (String measurement : measurements) {
if (measurement == null) {
+ res.add(null);
continue;
}
- if (measurementSet.contains(measurement)) {
+ if (checkedMeasurements.get(measurement) != null) {
+ res.add(checkedMeasurements.get(measurement));
continue;
}
- measurementSet.add(measurement);
- if (measurement.startsWith(TsFileConstant.BACK_QUOTE_STRING)
- && measurement.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
- if (checkBackQuotes(measurement.substring(1, measurement.length() - 1))) {
- continue;
- } else {
- throw new IllegalPathException(measurement);
- }
- }
- if (IoTDBConstant.reservedWords.contains(measurement.toUpperCase())
- || isRealNumber(measurement)
- || !TsFileConstant.NODE_NAME_PATTERN.matcher(measurement).matches()) {
- throw new IllegalPathException(measurement);
- }
+ String checked = checkAndReturnSingleMeasurement(measurement);
+ checkedMeasurements.put(measurement, checked);
+ res.add(checked);
}
+ return res;
}
/**
- * check whether measurement is legal according to syntax convention measurement can only be a
- * single node name
+ * check whether measurement is legal according to syntax convention. Measurement can only be a
+ * single node name.
*/
- public static void isLegalSingleMeasurements(List<String> measurements) throws MetadataException {
+ public static List<String> checkIsLegalSingleMeasurementsAndUpdate(List<String> measurements)
+ throws MetadataException {
if (measurements == null) {
- return;
+ return null;
}
+ List<String> res = new ArrayList<>();
for (String measurement : measurements) {
if (measurement == null) {
continue;
}
- if (measurement.startsWith(TsFileConstant.BACK_QUOTE_STRING)
- && measurement.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
- if (checkBackQuotes(measurement.substring(1, measurement.length() - 1))) {
- continue;
- } else {
- throw new IllegalPathException(measurement);
- }
- }
- if (IoTDBConstant.reservedWords.contains(measurement.toUpperCase())
- || isRealNumber(measurement)
- || !TsFileConstant.NODE_NAME_PATTERN.matcher(measurement).matches()) {
- throw new IllegalPathException(measurement);
- }
+ res.add(checkAndReturnSingleMeasurement(measurement));
}
+ return res;
}
/**
* check whether measurement is legal according to syntax convention measurement could be like a.b
* (more than one node name), in template?
*/
- public static void isLegalMeasurementLists(List<List<String>> measurementLists)
- throws IllegalPathException {
+ public static List<List<String>> checkIsLegalMeasurementListsAndUpdate(
+ List<List<String>> measurementLists) throws IllegalPathException {
if (measurementLists == null) {
- return;
+ return null;
}
+ List<List<String>> res = new ArrayList<>();
for (List<String> measurementList : measurementLists) {
- isLegalMeasurements(measurementList);
+ res.add(checkIsLegalMeasurementsAndUpdate(measurementList));
}
+ return res;
}
/**
* check whether measurement is legal according to syntax convention measurement could be like a.b
* (more than one node name), in template?
*/
- public static void isLegalMeasurements(List<String> measurements) throws IllegalPathException {
+ public static List<String> checkIsLegalMeasurementsAndUpdate(List<String> measurements)
+ throws IllegalPathException {
if (measurements == null) {
- return;
+ return null;
}
+ List<String> res = new ArrayList<>();
for (String measurement : measurements) {
if (measurement != null) {
- PathUtils.isLegalPath(measurement);
+ res.add(PathUtils.isLegalPath(measurement)[0]);
}
}
+ return res;
+ }
+
+ /** check a measurement and update it if needed to. for example: `sd` -> sd */
+ public static String checkAndReturnSingleMeasurement(String measurement)
+ throws IllegalPathException {
+ if (measurement == null) {
+ return null;
+ }
+ if (measurement.startsWith(TsFileConstant.BACK_QUOTE_STRING)
+ && measurement.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
+ if (checkBackQuotes(measurement.substring(1, measurement.length() - 1))) {
+ return removeBackQuotesIfNecessary(measurement);
+ } else {
+ throw new IllegalPathException(measurement);
+ }
+ }
+ if (IoTDBConstant.reservedWords.contains(measurement.toUpperCase())
+ || isRealNumber(measurement)
+ || !TsFileConstant.NODE_NAME_PATTERN.matcher(measurement).matches()) {
+ throw new IllegalPathException(measurement);
+ }
+ return measurement;
}
/** Return true if the str is a real number. Examples: 1.0; +1.0; -1.0; 0011; 011e3; +23e-3 */
@@ -171,6 +185,17 @@ public class PathUtils {
return deviceName.equals(storageGroup) || deviceName.startsWith(storageGroup + ".");
}
+ /** Remove the back quotes of a measurement if necessary */
+ public static String removeBackQuotesIfNecessary(String measurement) {
+ String unWrapped = measurement.substring(1, measurement.length() - 1);
+ if (PathUtils.isRealNumber(unWrapped)
+ || !TsFileConstant.IDENTIFIER_PATTERN.matcher(unWrapped).matches()) {
+ return measurement;
+ } else {
+ return unWrapped;
+ }
+ }
+
private static boolean checkBackQuotes(String src) {
int num = src.length() - src.replace("`", "").length();
if (num % 2 == 1) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index 83b72b2c37..23e897155a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -1539,12 +1539,7 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
}
if (nodeName.startsWith(TsFileConstant.BACK_QUOTE_STRING)
&& nodeName.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
- String unWrapped = nodeName.substring(1, nodeName.length() - 1);
- if (PathUtils.isRealNumber(unWrapped)
- || !TsFileConstant.IDENTIFIER_PATTERN.matcher(unWrapped).matches()) {
- return nodeName;
- }
- return unWrapped;
+ return PathUtils.removeBackQuotesIfNecessary(nodeName);
}
checkNodeName(nodeName);
return nodeName;
@@ -1556,12 +1551,7 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
}
if (nodeName.startsWith(TsFileConstant.BACK_QUOTE_STRING)
&& nodeName.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
- String unWrapped = nodeName.substring(1, nodeName.length() - 1);
- if (PathUtils.isRealNumber(unWrapped)
- || !TsFileConstant.IDENTIFIER_PATTERN.matcher(unWrapped).matches()) {
- return nodeName;
- }
- return unWrapped;
+ return PathUtils.removeBackQuotesIfNecessary(nodeName);
}
checkNodeNameInIntoPath(nodeName);
return nodeName;
diff --git a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java
index 0f1ef48f78..f3f9d4e5ba 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java
@@ -122,7 +122,6 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.time.ZoneId;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -599,7 +598,7 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// measurementAlias is also a nodeName
- PathUtils.isLegalSingleMeasurements(Collections.singletonList(req.getMeasurementAlias()));
+ req.setMeasurementAlias(PathUtils.checkAndReturnSingleMeasurement(req.getMeasurementAlias()));
// Step 1: transfer from TSCreateTimeseriesReq to Statement
CreateTimeSeriesStatement statement =
(CreateTimeSeriesStatement) StatementGenerator.createStatement(req);
@@ -647,9 +646,10 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurements(req.getMeasurementAlias());
+ req.setMeasurementAlias(
+ PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurementAlias()));
- PathUtils.isLegalSingleMeasurements(req.getMeasurements());
+ req.setMeasurements(PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurements()));
// Step 1: transfer from CreateAlignedTimeSeriesReq to Statement
CreateAlignedTimeSeriesStatement statement =
@@ -698,7 +698,8 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurements(req.getMeasurementAliasList());
+ req.setMeasurementAliasList(
+ PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurementAliasList()));
// Step 1: transfer from CreateMultiTimeSeriesReq to Statement
CreateMultiTimeSeriesStatement statement =
@@ -951,7 +952,8 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurementLists(req.getMeasurementsList());
+ req.setMeasurementsList(
+ PathUtils.checkIsLegalSingleMeasurementListsAndUpdate(req.getMeasurementsList()));
// Step 1: transfer from TSInsertRecordsReq to Statement
InsertRowsStatement statement = (InsertRowsStatement) StatementGenerator.createStatement(req);
@@ -1006,7 +1008,8 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurementLists(req.getMeasurementsList());
+ req.setMeasurementsList(
+ PathUtils.checkIsLegalSingleMeasurementListsAndUpdate(req.getMeasurementsList()));
// Step 1: transfer from TSInsertRecordsOfOneDeviceReq to Statement
InsertRowsOfOneDeviceStatement statement =
@@ -1062,7 +1065,8 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurementLists(req.getMeasurementsList());
+ req.setMeasurementsList(
+ PathUtils.checkIsLegalSingleMeasurementListsAndUpdate(req.getMeasurementsList()));
// Step 1: transfer from TSInsertStringRecordsOfOneDeviceReq to Statement
InsertRowsOfOneDeviceStatement statement =
@@ -1119,7 +1123,7 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
req.getTimestamp());
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurements(req.getMeasurements());
+ req.setMeasurements(PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurements()));
InsertRowStatement statement = (InsertRowStatement) StatementGenerator.createStatement(req);
// return success when this statement is empty because server doesn't need to execute it
@@ -1164,7 +1168,8 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
return getNotLoggedInStatus();
}
- PathUtils.isLegalSingleMeasurementLists(req.getMeasurementsList());
+ req.setMeasurementsList(
+ PathUtils.checkIsLegalSingleMeasurementListsAndUpdate(req.getMeasurementsList()));
// Step 1: transfer from TSInsertTabletsReq to Statement
InsertMultiTabletsStatement statement =
@@ -1212,7 +1217,7 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurements(req.getMeasurements());
+ req.setMeasurements(PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurements()));
// Step 1: transfer from TSInsertTabletReq to Statement
InsertTabletStatement statement =
(InsertTabletStatement) StatementGenerator.createStatement(req);
@@ -1267,7 +1272,8 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
}
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurementLists(req.getMeasurementsList());
+ req.setMeasurementsList(
+ PathUtils.checkIsLegalSingleMeasurementListsAndUpdate(req.getMeasurementsList()));
InsertRowsStatement statement = (InsertRowsStatement) StatementGenerator.createStatement(req);
// return success when this statement is empty because server doesn't need to execute it
@@ -1731,7 +1737,7 @@ public class ClientRPCServiceImpl implements IClientRPCServiceWithHandler {
req.getTimestamp());
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurements(req.getMeasurements());
+ req.setMeasurements(PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurements()));
InsertRowStatement statement = (InsertRowStatement) StatementGenerator.createStatement(req);
diff --git a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
index 901c96eefd..2a48fb5437 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
@@ -1042,7 +1042,8 @@ public class TSServiceImpl implements IClientRPCServiceWithHandler {
}
// measurementAlias is also a nodeName
- PathUtils.isLegalSingleMeasurements(Collections.singletonList(req.getMeasurementAlias()));
+ PathUtils.checkIsLegalSingleMeasurementsAndUpdate(
+ Collections.singletonList(req.getMeasurementAlias()));
CreateTimeSeriesPlan plan =
new CreateTimeSeriesPlan(
new PartialPath(req.path),
@@ -1072,9 +1073,9 @@ public class TSServiceImpl implements IClientRPCServiceWithHandler {
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalSingleMeasurements(req.getMeasurements());
+ PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurements());
- PathUtils.isLegalSingleMeasurements(req.getMeasurementAlias());
+ PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.getMeasurementAlias());
if (AUDIT_LOGGER.isDebugEnabled()) {
AUDIT_LOGGER.debug(
@@ -1135,7 +1136,7 @@ public class TSServiceImpl implements IClientRPCServiceWithHandler {
// measurementAlias is also a nodeName
- PathUtils.isLegalSingleMeasurements(req.measurementAliasList);
+ PathUtils.checkIsLegalSingleMeasurementsAndUpdate(req.measurementAliasList);
CreateMultiTimeSeriesPlan multiPlan = new CreateMultiTimeSeriesPlan();
List<PartialPath> paths = new ArrayList<>(req.paths.size());
@@ -1255,7 +1256,7 @@ public class TSServiceImpl implements IClientRPCServiceWithHandler {
ByteBuffer buffer = ByteBuffer.wrap(req.getSerializedTemplate());
plan = CreateTemplatePlan.deserializeFromReq(buffer);
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalMeasurementLists(plan.getMeasurements());
+ PathUtils.checkIsLegalMeasurementListsAndUpdate(plan.getMeasurements());
TSStatus status = SESSION_MANAGER.checkAuthority(plan, SESSION_MANAGER.getCurrSession());
return status != null ? status : executeNonQueryPlan(plan);
@@ -1271,7 +1272,7 @@ public class TSServiceImpl implements IClientRPCServiceWithHandler {
public TSStatus appendSchemaTemplate(TSAppendSchemaTemplateReq req) {
try {
// check whether measurement is legal according to syntax convention
- PathUtils.isLegalMeasurements(req.getMeasurements());
+ PathUtils.checkIsLegalMeasurementsAndUpdate(req.getMeasurements());
} catch (IoTDBException e) {
onIoTDBException(e, OperationType.EXECUTE_NON_QUERY_PLAN, e.getErrorCode());
}