-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[IOTDB-174] Fix querying timeseries interface cannot make a query by the specified path prefix #435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[IOTDB-174] Fix querying timeseries interface cannot make a query by the specified path prefix #435
Conversation
|
I have added the SQLException to remind users if they enter the wrong child node. |
LeiRui
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the code reviews below, there are other problems in the code:
IoTDBStatementline 280 is a bug. If you querycount nodes root.demo, you will get a message "Msg: 3", which is not expected.- In
org.apache.iotdb.jdbc.Constant, COUNT_NODE_TIMESERIES = "cnttsbg". I guess "bg" is a typo for "gp"-groupby. To fix it, I suggest you change it to "cntnodets" for consistency. - In
TSServiceImplline 323, "COUNT_TIMESERIES" takes the same branch as that of "ALL_COLUMNS". However, "COUNT_TIMESERIES" only needs a count number rather than concrete path strings, so is it a waste of communication?
| Set<String> getAllDevices() { | ||
| return new HashSet<>(getNodesList(3)); | ||
| Set<String> getAllDevices() throws SQLException { | ||
| return new HashSet<>(getNodesList("root",2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
device is not necessarily at level 2.
device is at the secod to last level.
For example, CREATE TIMESERIES root.demo.m2.m2.s0 WITH DATATYPE=INT32,ENCODING=RLE and the device should be root.demo.m2.m2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LeiRui Hi, thanks for your detailed explanation. Actually I have no idea now about how to implement this interface as it was not developed by me before. What I done is just making sure that the program does not report the error.
However, I would like to discuss with you guys about how to make changes of this function, could you please give me some advices? I think this should create another PR for this or reopen PR #421 to correct this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, terribly sorry for the late reply, and I’m responsible for this issue. Do you think it is necessary to add a new param String schemaPattern for method Set<String> getAllDevices() as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe I will fix this bug after your PR is merged so that it won't result in too many conflicts since your PR is currently not reporting any error.
| String[] nodes = schemaPattern.split("\\."); | ||
| MNode node; | ||
| if ((node = getRoot()) != null) { | ||
| for (int i = 1; i < nodes.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The start of the schemaPattern is not checked to be root.
I find that count nodes xx.demo level=2 still returns the count result as normal, which is not right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
LeiRui
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides, since this feature is not only valid in jdbc, I suggest you also add relative documents in the docs/Documentation/UserGuide/5-IoTDB SQL Documentation/1-IoTDB Query Statement.md.
|
One more suggestion: the header of this pr is a little bit general. Make it more specific would be better. |
jt2594838
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not forget to add tests to cover the situations mentioned by Lei Rui.
jixuan1989
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please modify the SQL Reference document to add COUNT clause.
|
Hi, I have no idea now about how to implement the interface which could show all devices (which is another issue) as it was not developed by me before. What I done here is just making sure that the program does not report the error. However, I would like to discuss with you guys about how to make changes of this function, could you please give me some advices? I think this should create another PR for this or reopen PR #421 to correct this issue. |
I have added the new schema statement in it. Please have a look. |
| * @return A List instance which stores all node at given level | ||
| */ | ||
| public List<String> getNodesList(int nodeLevel) { | ||
| public List<String> getNodesList(String schemaPattern, int nodeLevel) throws SQLException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| public List<String> getNodesList(String schemaPattern, int nodeLevel) throws SQLException { | |
| public List<String> getNodesList(String prefixPath, int nodeLevel) throws SQLException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| Set<String> getAllDevices() { | ||
| return new HashSet<>(getNodesList(3)); | ||
| Set<String> getAllDevices() throws SQLException { | ||
| List<String> res = new ArrayList<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| List<String> res = new ArrayList<>(); | |
| List<String> devices = new ArrayList<>(); |
And, why not define a set directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| */ | ||
| Set<String> getAllDevices() { | ||
| return new HashSet<>(getNodesList(3)); | ||
| Set<String> getAllDevices() throws SQLException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Set<String> getAllDevices() throws SQLException { | |
| Set<String> getAllDevices() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| List<String> res = new ArrayList<>(); | ||
| MNode node; | ||
| if ((node = getRoot()) != null) { | ||
| findDevices(node, "root", res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| findDevices(node, "root", res); | |
| findDevices(node, SQLConstant.ROOT, res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| res.add(path); | ||
| return; | ||
| } | ||
| if (node.hasChildren()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already check the node is null or is a leaf. Here, the node should have a child. This if statement is not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| if (node.hasChildren()) { | ||
| for (MNode child : node.getChildren().values()) { | ||
| if (child.isLeaf()) { | ||
| findDevices(child, path, res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| findDevices(child, path, res); | |
| res.add(path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| return new LinkedHashSet<>(res); | ||
| } | ||
|
|
||
| private void findDevices(MNode node, String path, List<String> res) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is very confused, what's the relationship between node and path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@qiaojialin It might not have to declare two separate params here, which it could use node.getName() to get the path name of the specified node. However, the function above (findStorageGroup) has also declared like this, so I'm not sure if I have to change this declaration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or are you confusing with the naming of params? Is there any suggestion about how to change it to resolve the confusion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here path != node.getName() , path is the full path (e.g., root.d1.s1) of the node while node.getName only return the node name (e.g., s1).
But now, after you change the res.add(path), these two parameters are consistent. No need to change.
BTW, if you find some existing codes which are confusing, do not hesitate to optimize them.
| * @return a list contains all nodes at the given level | ||
| */ | ||
| List<String> getNodesList(int nodeLevel) { | ||
| List<String> getNodesList(String schemaPattern, int nodeLevel) throws SQLException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this function only for the count? If so, why not return an int?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it is not only for the count. The function "COUNT NODE ... GROUP BY ..." has also been shared with this method, as it needs paths (path string) in this list so that it could return the node number within the specified path under the specified level and the path name to users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
|
There are failing tests. |
Corresponding to JIRA issue: https://issues.apache.org/jira/browse/IOTDB-174