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/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 9b89113 [IOTDB-1526] New Template Constraint (#3659)
9b89113 is described below
commit 9b89113770741b2b9ef3511e776913619b2cde75
Author: zyk990424 <[email protected]>
AuthorDate: Mon Aug 2 19:53:59 2021 +0800
[IOTDB-1526] New Template Constraint (#3659)
---
.../apache/iotdb/cluster/metadata/CMManager.java | 3 +-
.../Data-Concept/Data-Model-and-Terminology.md | 195 ++++------------
docs/UserGuide/Data-Concept/Data-Type.md | 125 ++++++++++
.../Data-Concept/Data-Model-and-Terminology.md | 195 ++++------------
docs/zh/UserGuide/Data-Concept/Data-Type.md | 123 ++++++++++
.../org/apache/iotdb/db/metadata/MManager.java | 156 ++++++-------
.../java/org/apache/iotdb/db/metadata/MTree.java | 65 +++++-
.../org/apache/iotdb/db/metadata/MetaUtils.java | 4 +-
.../db/metadata/template/TemplateManager.java | 63 +-----
.../apache/iotdb/db/qp/executor/PlanExecutor.java | 3 +-
.../iotdb/db/metadata/MManagerBasicTest.java | 251 ++++++++++-----------
.../iotdb/db/metadata/MManagerImproveTest.java | 2 +-
12 files changed, 601 insertions(+), 584 deletions(-)
diff --git
a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
index 1b10399..95f085c 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
@@ -48,7 +48,6 @@ import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
import org.apache.iotdb.db.metadata.mnode.InternalMNode;
import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
-import org.apache.iotdb.db.metadata.template.Template;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.physical.BatchPlan;
import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -509,7 +508,7 @@ public class CMManager extends MManager {
}
@Override
- public Pair<IMNode, Template> getDeviceNodeWithAutoCreate(PartialPath path)
+ public IMNode getDeviceNodeWithAutoCreate(PartialPath path)
throws MetadataException, IOException {
return getDeviceNodeWithAutoCreate(
path,
diff --git a/docs/UserGuide/Data-Concept/Data-Model-and-Terminology.md
b/docs/UserGuide/Data-Concept/Data-Model-and-Terminology.md
index 147f56f..e61f728 100644
--- a/docs/UserGuide/Data-Concept/Data-Model-and-Terminology.md
+++ b/docs/UserGuide/Data-Concept/Data-Model-and-Terminology.md
@@ -27,7 +27,11 @@ According to the enterprise organization structure and
equipment entity hierarch
<center><img style="width:100%; max-width:800px; max-height:600px;
margin-left:auto; margin-right:auto; display:block;"
src="https://user-images.githubusercontent.com/19167280/122668849-b1c69280-d1ec-11eb-83cb-3b73c40bdf72.png"></center>
-Here are the basic concepts of the model involved in IoTDB:
+Here are the basic concepts of the model involved in IoTDB.
+
+
+
+### Measurement, Entity, Storage Group, Path
* Measurement (Also called field)
@@ -57,38 +61,6 @@ After a storage group is set, the ancestral layers, children
and descendant laye
The Layer Name of storage group can only consist of characters, numbers,
underscores and hyphen, like `root.storagegroup_1-sg1`.
-* Data point
-
-**A "time-value" pair**.
-
-* Timeseries (A measurement of an entity corresponds to a timeseries. Also
called meter, timeline, and tag, parameter in real time database)
-
-**The record of a measurement of an entity on the time axis.** Timeseries is a
series of data points.
-
-For example, if entity wt01 in power plant wf01 of power group ln has a
measurement named status, its timeseries can be expressed as:
`root.ln.wf01.wt01.status`.
-
-
-* Multi-variable timeseries (Also called aligned timeseries, from v0.13)
-
-A multi-variable measurements of an entity corresponds to a multi-variable
timeseries. These timeseries are called **multi-variable timeseries**, also
called **aligned timeseries**.
-
-Multi-variable timeseries need to be created, inserted and deleted at the same
time. However, when querying, you can query each sub-measurement separately.
-
-By using multi-variable timeseries, the timestamp columns of a group of
multi-variable timeseries need to be stored only once in memory and disk when
inserting data, instead of once per timeseries:
-
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://user-images.githubusercontent.com/19167280/114125919-f4850800-9929-11eb-8211-81d4c04af1ec.png">
-
-In the following chapters of data definition language, data operation language
and Java Native Interface, various operations related to multi-variable
timeseries will be introduced one by one.
-
-
-* Measurement template (From v0.13)
-
-In the actual scenario, many entities collect the same measurements, that is,
they have the same measurements name and type. A **measurement template** can
be declared to define the collectable measurements set. Measurement template is
hung on any node of the tree data pattern, which means that all entities under
the node have the same measurements set.
-
-Currently you can only set one **measurement template** on a specific path. An
entity will use it's own measurement template or nearest ancestor's measurement
template.
-
-In the following chapters of data definition language, data operation language
and Java Native Interface, various operations related to measurement template
will be introduced one by one.
-
* Path
In IoTDB, a path is an expression that conforms to the following constraints:
@@ -116,7 +88,7 @@ The characters supported in LayerName without double quotes
are as below:
'-' and ':' cannot be the first character. '+' cannot use alone.
> Note: the LayerName of storage group can only be characters, numbers,
> underscores and hyphen.
->
+>
> Besides, if deploy on Windows system, the LayerName is case-insensitive,
> which means it's not allowed to set storage groups `root.ln` and `root.LN`
> at the same time.
@@ -140,119 +112,46 @@ When `*` appears in the middle of the path, it
represents `*` itself, i.e., a la
> Note2: A path with `*` at the end has the same meaning as a prefix path,
> e.g., `root.vehicle.*` and `root.vehicle` is the same.
+
+
+### Timeseries
+
+* Data point
+
+**A "time-value" pair**.
+
+* Timeseries (A measurement of an entity corresponds to a timeseries. Also
called meter, timeline, and tag, parameter in real time database)
+
+**The record of a measurement of an entity on the time axis.** Timeseries is a
series of data points.
+
+For example, if entity wt01 in power plant wf01 of power group ln has a
measurement named status, its timeseries can be expressed as:
`root.ln.wf01.wt01.status`.
+
+
+* Multi-variable timeseries (Also called aligned timeseries, from v0.13)
+
+A multi-variable measurements of an entity corresponds to a multi-variable
timeseries. These timeseries are called **multi-variable timeseries**, also
called **aligned timeseries**.
+
+Multi-variable timeseries need to be created, inserted and deleted at the same
time. However, when querying, you can query each sub-measurement separately.
+
+By using multi-variable timeseries, the timestamp columns of a group of
multi-variable timeseries need to be stored only once in memory and disk when
inserting data, instead of once per timeseries:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://user-images.githubusercontent.com/19167280/114125919-f4850800-9929-11eb-8211-81d4c04af1ec.png">
+
+In the following chapters of data definition language, data operation language
and Java Native Interface, various operations related to multi-variable
timeseries will be introduced one by one.
+
* Timestamp
-The timestamp is the time point at which data is produced. It includes
absolute timestamps and relative timestamps
-
-* Absolute timestamp
-
-Absolute timestamps in IoTDB are divided into two types: LONG and DATETIME
(including DATETIME-INPUT and DATETIME-DISPLAY). When a user inputs a
timestamp, he can use a LONG type timestamp or a DATETIME-INPUT type timestamp,
and the supported formats of the DATETIME-INPUT type timestamp are shown in the
table below:
-
-<center>**Supported formats of DATETIME-INPUT type timestamp**
-
-
-|Format|
-|:---:|
-|yyyy-MM-dd HH:mm:ss|
-|yyyy/MM/dd HH:mm:ss|
-|yyyy.MM.dd HH:mm:ss|
-|yyyy-MM-dd'T'HH:mm:ss|
-|yyyy/MM/dd'T'HH:mm:ss|
-|yyyy.MM.dd'T'HH:mm:ss|
-|yyyy-MM-dd HH:mm:ssZZ|
-|yyyy/MM/dd HH:mm:ssZZ|
-|yyyy.MM.dd HH:mm:ssZZ|
-|yyyy-MM-dd'T'HH:mm:ssZZ|
-|yyyy/MM/dd'T'HH:mm:ssZZ|
-|yyyy.MM.dd'T'HH:mm:ssZZ|
-|yyyy/MM/dd HH:mm:ss.SSS|
-|yyyy-MM-dd HH:mm:ss.SSS|
-|yyyy.MM.dd HH:mm:ss.SSS|
-|yyyy/MM/dd'T'HH:mm:ss.SSS|
-|yyyy-MM-dd'T'HH:mm:ss.SSS|
-|yyyy.MM.dd'T'HH:mm:ss.SSS|
-|yyyy-MM-dd HH:mm:ss.SSSZZ|
-|yyyy/MM/dd HH:mm:ss.SSSZZ|
-|yyyy.MM.dd HH:mm:ss.SSSZZ|
-|yyyy-MM-dd'T'HH:mm:ss.SSSZZ|
-|yyyy/MM/dd'T'HH:mm:ss.SSSZZ|
-|yyyy.MM.dd'T'HH:mm:ss.SSSZZ|
-|ISO8601 standard time format|
-
-</center>
-
-
-IoTDB can support LONG types and DATETIME-DISPLAY types when displaying
timestamps. The DATETIME-DISPLAY type can support user-defined time formats.
The syntax of the custom time format is shown in the table below:
-
-<center>**The syntax of the custom time format**
-
-|Symbol|Meaning|Presentation|Examples|
-|:---:|:---:|:---:|:---:|
-|G|era|era|era|
-|C|century of era (>=0)| number| 20|
-| Y |year of era (>=0)| year| 1996|
-|||||
-| x |weekyear| year| 1996|
-| w |week of weekyear| number |27|
-| e |day of week |number| 2|
-| E |day of week |text |Tuesday; Tue|
-|||||
-| y| year| year| 1996|
-| D |day of year |number| 189|
-| M |month of year |month| July; Jul; 07|
-| d |day of month |number| 10|
-|||||
-| a |halfday of day |text |PM|
-| K |hour of halfday (0~11) |number| 0|
-| h |clockhour of halfday (1~12) |number| 12|
-|||||
-| H |hour of day (0~23)| number| 0|
-| k |clockhour of day (1~24) |number| 24|
-| m |minute of hour| number| 30|
-| s |second of minute| number| 55|
-| S |fraction of second |millis| 978|
-|||||
-| z |time zone |text |Pacific Standard Time; PST|
-| Z |time zone offset/id| zone| -0800; -08:00; America/Los_Angeles|
-|||||
-| '| escape for text |delimiter| |
-| ''| single quote| literal |'|
-
-</center>
-
-* Relative timestamp
-
-Relative time refers to the time relative to the server time ```now()``` and
```DATETIME``` time.
-
- Syntax:
- ```
- Duration = (Digit+ ('Y'|'MO'|'W'|'D'|'H'|'M'|'S'|'MS'|'US'|'NS'))+
- RelativeTime = (now() | DATETIME) ((+|-) Duration)+
-
- ```
-
- <center>**The syntax of the duration unit**
-
-|Symbol|Meaning|Presentation|Examples|
-|:---:|:---:|:---:|:---:|
-|y|year|1y=365 days|1y|
-|mo|month|1mo=30 days|1mo|
-|w|week|1w=7 days|1w|
-|d|day|1d=1 day|1d|
-|||||
-|h|hour|1h=3600 seconds|1h|
-|m|minute|1m=60 seconds|1m|
-|s|second|1s=1 second|1s|
-|||||
-|ms|millisecond|1ms=1000_000 nanoseconds|1ms|
-|us|microsecond|1us=1000 nanoseconds|1us|
-|ns|nanosecond|1ns=1 nanosecond|1ns|
-
- </center>
-
- eg:
- ```
- now() - 1d2h //1 day and 2 hours earlier than the current server time
- now() - 1w //1 week earlier than the current server time
- ```
- > Note:There must be spaces on the left and right of '+' and '-'.
+The timestamp is the time point at which data is produced. It includes
absolute timestamps and relative timestamps. For detailed description, please
go to Data Type doc.
+
+
+
+### Measurement Template
+
+
+* Measurement template (From v0.13)
+
+In the actual scenario, many entities collect the same measurements, that is,
they have the same measurements name and type. A **measurement template** can
be declared to define the collectable measurements set. Measurement template is
hung on any node of the tree data pattern, which means that all entities under
the node have the same measurements set.
+
+Currently you can only set one **measurement template** on a specific path. If
there's one measurement template on one node, it will be forbidden to set any
measurement template on the ancestors or descendants of this node. An entity
will use it's own measurement template or ancestor's measurement template.
+
+In the following chapters of data definition language, data operation language
and Java Native Interface, various operations related to measurement template
will be introduced one by one.
diff --git a/docs/UserGuide/Data-Concept/Data-Type.md
b/docs/UserGuide/Data-Concept/Data-Type.md
index 3bf21d9..2490769 100644
--- a/docs/UserGuide/Data-Concept/Data-Type.md
+++ b/docs/UserGuide/Data-Concept/Data-Type.md
@@ -42,3 +42,128 @@ When the data type of data input by the user in the system
does not correspond t
IoTDB> create timeseries root.ln.wf02.wt02.status WITH DATATYPE=BOOLEAN,
ENCODING=TS_2DIFF
error: encoding TS_2DIFF does not support BOOLEAN
```
+
+
+
+Timestamp
+
+The timestamp is the time point at which data is produced. It includes
absolute timestamps and relative timestamps
+
+* Absolute timestamp
+
+Absolute timestamps in IoTDB are divided into two types: LONG and DATETIME
(including DATETIME-INPUT and DATETIME-DISPLAY). When a user inputs a
timestamp, he can use a LONG type timestamp or a DATETIME-INPUT type timestamp,
and the supported formats of the DATETIME-INPUT type timestamp are shown in the
table below:
+
+<center>**Supported formats of DATETIME-INPUT type timestamp**
+
+
+
+| Format |
+| :--------------------------: |
+| yyyy-MM-dd HH:mm:ss |
+| yyyy/MM/dd HH:mm:ss |
+| yyyy.MM.dd HH:mm:ss |
+| yyyy-MM-dd'T'HH:mm:ss |
+| yyyy/MM/dd'T'HH:mm:ss |
+| yyyy.MM.dd'T'HH:mm:ss |
+| yyyy-MM-dd HH:mm:ssZZ |
+| yyyy/MM/dd HH:mm:ssZZ |
+| yyyy.MM.dd HH:mm:ssZZ |
+| yyyy-MM-dd'T'HH:mm:ssZZ |
+| yyyy/MM/dd'T'HH:mm:ssZZ |
+| yyyy.MM.dd'T'HH:mm:ssZZ |
+| yyyy/MM/dd HH:mm:ss.SSS |
+| yyyy-MM-dd HH:mm:ss.SSS |
+| yyyy.MM.dd HH:mm:ss.SSS |
+| yyyy/MM/dd'T'HH:mm:ss.SSS |
+| yyyy-MM-dd'T'HH:mm:ss.SSS |
+| yyyy.MM.dd'T'HH:mm:ss.SSS |
+| yyyy-MM-dd HH:mm:ss.SSSZZ |
+| yyyy/MM/dd HH:mm:ss.SSSZZ |
+| yyyy.MM.dd HH:mm:ss.SSSZZ |
+| yyyy-MM-dd'T'HH:mm:ss.SSSZZ |
+| yyyy/MM/dd'T'HH:mm:ss.SSSZZ |
+| yyyy.MM.dd'T'HH:mm:ss.SSSZZ |
+| ISO8601 standard time format |
+
+</center>
+
+
+IoTDB can support LONG types and DATETIME-DISPLAY types when displaying
timestamps. The DATETIME-DISPLAY type can support user-defined time formats.
The syntax of the custom time format is shown in the table below:
+
+<center>**The syntax of the custom time format**
+
+
+| Symbol | Meaning | Presentation | Examples
|
+| :----: | :-------------------------: | :----------: |
:--------------------------------: |
+| G | era | era | era
|
+| C | century of era (>=0) | number | 20
|
+| Y | year of era (>=0) | year | 1996
|
+| | | |
|
+| x | weekyear | year | 1996
|
+| w | week of weekyear | number | 27
|
+| e | day of week | number | 2
|
+| E | day of week | text | Tuesday;
Tue |
+| | | |
|
+| y | year | year | 1996
|
+| D | day of year | number | 189
|
+| M | month of year | month | July; Jul;
07 |
+| d | day of month | number | 10
|
+| | | |
|
+| a | halfday of day | text | PM
|
+| K | hour of halfday (0~11) | number | 0
|
+| h | clockhour of halfday (1~12) | number | 12
|
+| | | |
|
+| H | hour of day (0~23) | number | 0
|
+| k | clockhour of day (1~24) | number | 24
|
+| m | minute of hour | number | 30
|
+| s | second of minute | number | 55
|
+| S | fraction of second | millis | 978
|
+| | | |
|
+| z | time zone | text | Pacific Standard
Time; PST |
+| Z | time zone offset/id | zone | -0800; -08:00;
America/Los_Angeles |
+| | | |
|
+| ' | escape for text | delimiter |
|
+| '' | single quote | literal | '
|
+
+</center>
+
+* Relative timestamp
+
+Relative time refers to the time relative to the server time ```now()``` and
```DATETIME``` time.
+
+ Syntax:
+
+ ```
+ Duration = (Digit+ ('Y'|'MO'|'W'|'D'|'H'|'M'|'S'|'MS'|'US'|'NS'))+
+ RelativeTime = (now() | DATETIME) ((+|-) Duration)+
+
+ ```
+
+ <center>**The syntax of the duration unit**
+
+
+| Symbol | Meaning | Presentation | Examples |
+| :----: | :---------: | :----------------------: | :------: |
+| y | year | 1y=365 days | 1y |
+| mo | month | 1mo=30 days | 1mo |
+| w | week | 1w=7 days | 1w |
+| d | day | 1d=1 day | 1d |
+| | | | |
+| h | hour | 1h=3600 seconds | 1h |
+| m | minute | 1m=60 seconds | 1m |
+| s | second | 1s=1 second | 1s |
+| | | | |
+| ms | millisecond | 1ms=1000_000 nanoseconds | 1ms |
+| us | microsecond | 1us=1000 nanoseconds | 1us |
+| ns | nanosecond | 1ns=1 nanosecond | 1ns |
+
+ </center>
+
+ eg:
+
+ ```
+ now() - 1d2h //1 day and 2 hours earlier than the current server time
+ now() - 1w //1 week earlier than the current server time
+ ```
+
+ > Note:There must be spaces on the left and right of '+' and '-'.
\ No newline at end of file
diff --git a/docs/zh/UserGuide/Data-Concept/Data-Model-and-Terminology.md
b/docs/zh/UserGuide/Data-Concept/Data-Model-and-Terminology.md
index ea07bf0..a11c88f 100644
--- a/docs/zh/UserGuide/Data-Concept/Data-Model-and-Terminology.md
+++ b/docs/zh/UserGuide/Data-Concept/Data-Model-and-Terminology.md
@@ -29,7 +29,9 @@
<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://user-images.githubusercontent.com/19167280/123542457-5f511d00-d77c-11eb-8006-562d83069baa.png">
-IoTDB 模型结构涉及如下基本概念:
+IoTDB 模型结构涉及的基本概念在下文将做详细叙述。
+
+### 物理量、实体、存储组、路径
* 物理量(Measurement,也称工况、字段 field)
@@ -61,38 +63,6 @@ IoTDB 模型结构涉及如下基本概念:
存储组节点名只支持中英文字符、数字、下划线和中划线的组合。例如`root. 存储组_1-组1` 。
-* 数据点(Data point)
-
-**一个“时间-值”对**。
-
-* 时间序列(一个实体的某个物理量对应一个时间序列,Timeseries,也称测点 meter、时间线 timeline,实时数据库中常被称作标签
tag、参数 parameter)
-
-**一个物理实体的某个物理量在时间轴上的记录**,是数据点的序列。
-
-例如,ln 电力集团、wf01 风电场的实体 wt01 有名为 status
的物理量,则它的时间序列可以表示为:`root.ln.wf01.wt01.status`。
-
-* 一元时间序列(single-variable timeseries 或 timeseries,v0.1 起支持)
-
-一个实体的一个一元物理量对应一个一元时间序列。实体+物理量=时间序列
-
-* 多元时间序列(Multi-variable timeseries 或 Aligned timeseries,v0.13 起支持)
-
-一个实体的一个多元物理量对应一个多元时间序列。这些时间序列称为**多元时间序列**,也叫**对齐时间序列**。
-
-多元时间序列需要被同时创建、同时插入值,删除时也必须同时删除。不过在查询的时候,可以对于每一个分量单独查询。
-
-通过使用对齐的时间序列,在插入数据时,一组对齐序列的时间戳列在内存和磁盘中仅需存储一次,而不是每个时间序列存储一次:
-
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://user-images.githubusercontent.com/19167280/123542458-62e4a400-d77c-11eb-8c45-ca516f1b7eba.png">
-
-在后续数据定义语言、数据操作语言和 Java 原生接口章节,将对涉及到对齐时间序列的各种操作进行逐一介绍。
-
-* 物理量模板(Measurement template,v0.13 起支持)
-
-实际应用中有许多实体所采集的物理量相同,即具有相同的工况名称和类型,可以声明一个**物理量模板**来定义可采集的物理量集合。将物理量模版挂在树形数据模式的任意节点上,表示该节点下的所有实体具有相同的物理量集合。
-
-目前每一个路径节点仅允许挂载一个物理量模板,实体将使用其自身或最近祖先的物理量模板作为有效模板。
-
* 路径
在 IoTDB 中,路径是指符合以下约束的表达式:
@@ -125,7 +95,7 @@ LayerName: Identifier | STAR
前缀路径是指一个时间序列的前缀所在的路径,一个前缀路径包含以该路径为前缀的所有时间序列。例如当前我们有`root.vehicle.device1.sensor1`,
`root.vehicle.device1.sensor2`,
`root.vehicle.device2.sensor1`三个传感器,则`root.vehicle.device1`前缀路径包含`root.vehicle.device1.sensor1`、`root.vehicle.device1.sensor2`两个时间序列,而不包含`root.vehicle.device2.sensor1`。
* 带`*`路径
-为了使得在表达多个时间序列或表达前缀路径的时候更加方便快捷,IoTDB
为用户提供带`*`路径。`*`可以出现在路径中的任何层。按照`*`出现的位置,带`*`路径可以分为两种:
+ 为了使得在表达多个时间序列或表达前缀路径的时候更加方便快捷,IoTDB
为用户提供带`*`路径。`*`可以出现在路径中的任何层。按照`*`出现的位置,带`*`路径可以分为两种:
`*`出现在路径的结尾;
@@ -141,118 +111,45 @@ LayerName: Identifier | STAR
> 注意:`*`create 创建时,后面的路径同时不能含有`*`。
-* 时间戳
-
-时间戳是一个数据到来的时间点,其中包括绝对时间戳和相对时间戳。
-
-* 绝对时间戳
-
-IOTDB 中绝对时间戳分为二种,一种为 LONG 类型,一种为 DATETIME 类型(包含 DATETIME-INPUT,
DATETIME-DISPLAY 两个小类)。
-
-在用户在输入时间戳时,可以使用 LONG 类型的时间戳或 DATETIME-INPUT 类型的时间戳,其中 DATETIME-INPUT
类型的时间戳支持格式如表所示:
-
-<center>**DATETIME-INPUT 类型支持格式**
-
-|format|
-|:---|
-|yyyy-MM-dd HH:mm:ss|
-|yyyy/MM/dd HH:mm:ss|
-|yyyy.MM.dd HH:mm:ss|
-|yyyy-MM-dd'T'HH:mm:ss|
-|yyyy/MM/dd'T'HH:mm:ss|
-|yyyy.MM.dd'T'HH:mm:ss|
-|yyyy-MM-dd HH:mm:ssZZ|
-|yyyy/MM/dd HH:mm:ssZZ|
-|yyyy.MM.dd HH:mm:ssZZ|
-|yyyy-MM-dd'T'HH:mm:ssZZ|
-|yyyy/MM/dd'T'HH:mm:ssZZ|
-|yyyy.MM.dd'T'HH:mm:ssZZ|
-|yyyy/MM/dd HH:mm:ss.SSS|
-|yyyy-MM-dd HH:mm:ss.SSS|
-|yyyy.MM.dd HH:mm:ss.SSS|
-|yyyy/MM/dd'T'HH:mm:ss.SSS|
-|yyyy-MM-dd'T'HH:mm:ss.SSS|
-|yyyy.MM.dd'T'HH:mm:ss.SSS|
-|yyyy-MM-dd HH:mm:ss.SSSZZ|
-|yyyy/MM/dd HH:mm:ss.SSSZZ|
-|yyyy.MM.dd HH:mm:ss.SSSZZ|
-|yyyy-MM-dd'T'HH:mm:ss.SSSZZ|
-|yyyy/MM/dd'T'HH:mm:ss.SSSZZ|
-|yyyy.MM.dd'T'HH:mm:ss.SSSZZ|
-|ISO8601 standard time format|
-
-</center>
-
-IoTDB 在显示时间戳时可以支持 LONG 类型以及 DATETIME-DISPLAY 类型,其中 DATETIME-DISPLAY
类型可以支持用户自定义时间格式。自定义时间格式的语法如表所示:
-
-<center>**DATETIME-DISPLAY 自定义时间格式的语法**
-
-|Symbol|Meaning|Presentation|Examples|
-|:---:|:---:|:---:|:---:|
-|G|era|era|era|
-|C|century of era (>=0)| number| 20|
-| Y |year of era (>=0)| year| 1996|
-|||||
-| x |weekyear| year| 1996|
-| w |week of weekyear| number |27|
-| e |day of week |number| 2|
-| E |day of week |text |Tuesday; Tue|
-|||||
-| y| year| year| 1996|
-| D |day of year |number| 189|
-| M |month of year |month| July; Jul; 07|
-| d |day of month |number| 10|
-|||||
-| a |halfday of day |text |PM|
-| K |hour of halfday (0~11) |number| 0|
-| h |clockhour of halfday (1~12) |number| 12|
-|||||
-| H |hour of day (0~23)| number| 0|
-| k |clockhour of day (1~24) |number| 24|
-| m |minute of hour| number| 30|
-| s |second of minute| number| 55|
-| S |fraction of second |millis| 978|
-|||||
-| z |time zone |text |Pacific Standard Time; PST|
-| Z |time zone offset/id| zone| -0800; -08:00; America/Los_Angeles|
-|||||
-| '| escape for text |delimiter| |
-| ''| single quote| literal |'|
-
-</center>
-
-* 相对时间戳
-
- 相对时间是指与服务器时间```now()```和```DATETIME```类型时间相差一定时间间隔的时间。
- 形式化定义为:
-
- ```
- Duration = (Digit+ ('Y'|'MO'|'W'|'D'|'H'|'M'|'S'|'MS'|'US'|'NS'))+
- RelativeTime = (now() | DATETIME) ((+|-) Duration)+
- ```
-
- <center>**The syntax of the duration unit**
-
- |Symbol|Meaning|Presentation|Examples|
- |:---:|:---:|:---:|:---:|
- |y|year|1y=365 days|1y|
- |mo|month|1mo=30 days|1mo|
- |w|week|1w=7 days|1w|
- |d|day|1d=1 day|1d|
- |||||
- |h|hour|1h=3600 seconds|1h|
- |m|minute|1m=60 seconds|1m|
- |s|second|1s=1 second|1s|
- |||||
- |ms|millisecond|1ms=1000_000 nanoseconds|1ms|
- |us|microsecond|1us=1000 nanoseconds|1us|
- |ns|nanosecond|1ns=1 nanosecond|1ns|
-
- </center>
-
- 例子:
- ```
- now() - 1d2h //比服务器时间早 1 天 2 小时的时间
- now() - 1w //比服务器时间早 1 周的时间
- ```
- > 注意:'+'和'-'的左右两边必须有空格
+
+
+### 一元、多元时间序列
+
+* 数据点(Data point)
+
+**一个“时间-值”对**。
+
+* 时间序列(一个实体的某个物理量对应一个时间序列,Timeseries,也称测点 meter、时间线 timeline,实时数据库中常被称作标签
tag、参数 parameter)
+
+**一个物理实体的某个物理量在时间轴上的记录**,是数据点的序列。
+
+例如,ln 电力集团、wf01 风电场的实体 wt01 有名为 status
的物理量,则它的时间序列可以表示为:`root.ln.wf01.wt01.status`。
+
+* 一元时间序列(single-variable timeseries 或 timeseries,v0.1 起支持)
+
+一个实体的一个一元物理量对应一个一元时间序列。实体+物理量=时间序列
+
+* 多元时间序列(Multi-variable timeseries 或 Aligned timeseries,v0.13 起支持)
+
+一个实体的一个多元物理量对应一个多元时间序列。这些时间序列称为**多元时间序列**,也叫**对齐时间序列**。
+
+多元时间序列需要被同时创建、同时插入值,删除时也必须同时删除。不过在查询的时候,可以对于每一个分量单独查询。
+
+通过使用对齐的时间序列,在插入数据时,一组对齐序列的时间戳列在内存和磁盘中仅需存储一次,而不是每个时间序列存储一次:
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto;
margin-right:auto; display:block;"
src="https://user-images.githubusercontent.com/19167280/123542458-62e4a400-d77c-11eb-8c45-ca516f1b7eba.png">
+
+在后续数据定义语言、数据操作语言和 Java 原生接口章节,将对涉及到对齐时间序列的各种操作进行逐一介绍。
+
+* 时间戳类型
+
+时间戳是一个数据到来的时间点,其中包括绝对时间戳和相对时间戳,详细描述参见数据类型文档。
+
+
+### 物理量模板
+
+* 物理量模板(Measurement template,v0.13 起支持)
+
+实际应用中有许多实体所采集的物理量相同,即具有相同的工况名称和类型,可以声明一个**物理量模板**来定义可采集的物理量集合。将物理量模版挂在树形数据模式的任意节点上,表示该节点下的所有实体具有相同的物理量集合。
+
+目前每一条路径节点仅允许挂载一个物理量模板,即当一个节点被挂载物理量模板后,它的祖先节点和后代节点都不能再挂载物理量模板。实体将使用其自身或祖先的物理量模板作为有效模板。
\ No newline at end of file
diff --git a/docs/zh/UserGuide/Data-Concept/Data-Type.md
b/docs/zh/UserGuide/Data-Concept/Data-Type.md
index a03f173..edf277d 100644
--- a/docs/zh/UserGuide/Data-Concept/Data-Type.md
+++ b/docs/zh/UserGuide/Data-Concept/Data-Type.md
@@ -40,3 +40,126 @@ IoTDB 支持:
IoTDB> create timeseries root.ln.wf02.wt02.status WITH DATATYPE=BOOLEAN,
ENCODING=TS_2DIFF
error: encoding TS_2DIFF does not support BOOLEAN
```
+
+
+
+时间戳类型
+
+时间戳是一个数据到来的时间点,其中包括绝对时间戳和相对时间戳。
+
+* 绝对时间戳
+
+IOTDB 中绝对时间戳分为二种,一种为 LONG 类型,一种为 DATETIME 类型(包含 DATETIME-INPUT,
DATETIME-DISPLAY 两个小类)。
+
+在用户在输入时间戳时,可以使用 LONG 类型的时间戳或 DATETIME-INPUT 类型的时间戳,其中 DATETIME-INPUT
类型的时间戳支持格式如表所示:
+
+<center>**DATETIME-INPUT 类型支持格式**
+
+
+| format |
+| :--------------------------- |
+| yyyy-MM-dd HH:mm:ss |
+| yyyy/MM/dd HH:mm:ss |
+| yyyy.MM.dd HH:mm:ss |
+| yyyy-MM-dd'T'HH:mm:ss |
+| yyyy/MM/dd'T'HH:mm:ss |
+| yyyy.MM.dd'T'HH:mm:ss |
+| yyyy-MM-dd HH:mm:ssZZ |
+| yyyy/MM/dd HH:mm:ssZZ |
+| yyyy.MM.dd HH:mm:ssZZ |
+| yyyy-MM-dd'T'HH:mm:ssZZ |
+| yyyy/MM/dd'T'HH:mm:ssZZ |
+| yyyy.MM.dd'T'HH:mm:ssZZ |
+| yyyy/MM/dd HH:mm:ss.SSS |
+| yyyy-MM-dd HH:mm:ss.SSS |
+| yyyy.MM.dd HH:mm:ss.SSS |
+| yyyy/MM/dd'T'HH:mm:ss.SSS |
+| yyyy-MM-dd'T'HH:mm:ss.SSS |
+| yyyy.MM.dd'T'HH:mm:ss.SSS |
+| yyyy-MM-dd HH:mm:ss.SSSZZ |
+| yyyy/MM/dd HH:mm:ss.SSSZZ |
+| yyyy.MM.dd HH:mm:ss.SSSZZ |
+| yyyy-MM-dd'T'HH:mm:ss.SSSZZ |
+| yyyy/MM/dd'T'HH:mm:ss.SSSZZ |
+| yyyy.MM.dd'T'HH:mm:ss.SSSZZ |
+| ISO8601 standard time format |
+
+</center>
+
+IoTDB 在显示时间戳时可以支持 LONG 类型以及 DATETIME-DISPLAY 类型,其中 DATETIME-DISPLAY
类型可以支持用户自定义时间格式。自定义时间格式的语法如表所示:
+
+<center>**DATETIME-DISPLAY 自定义时间格式的语法**
+
+
+| Symbol | Meaning | Presentation | Examples
|
+| :----: | :-------------------------: | :----------: |
:--------------------------------: |
+| G | era | era | era
|
+| C | century of era (>=0) | number | 20
|
+| Y | year of era (>=0) | year | 1996
|
+| | | |
|
+| x | weekyear | year | 1996
|
+| w | week of weekyear | number | 27
|
+| e | day of week | number | 2
|
+| E | day of week | text | Tuesday;
Tue |
+| | | |
|
+| y | year | year | 1996
|
+| D | day of year | number | 189
|
+| M | month of year | month | July; Jul;
07 |
+| d | day of month | number | 10
|
+| | | |
|
+| a | halfday of day | text | PM
|
+| K | hour of halfday (0~11) | number | 0
|
+| h | clockhour of halfday (1~12) | number | 12
|
+| | | |
|
+| H | hour of day (0~23) | number | 0
|
+| k | clockhour of day (1~24) | number | 24
|
+| m | minute of hour | number | 30
|
+| s | second of minute | number | 55
|
+| S | fraction of second | millis | 978
|
+| | | |
|
+| z | time zone | text | Pacific Standard
Time; PST |
+| Z | time zone offset/id | zone | -0800; -08:00;
America/Los_Angeles |
+| | | |
|
+| ' | escape for text | delimiter |
|
+| '' | single quote | literal | '
|
+
+</center>
+
+* 相对时间戳
+
+ 相对时间是指与服务器时间```now()```和```DATETIME```类型时间相差一定时间间隔的时间。
+ 形式化定义为:
+
+ ```
+ Duration = (Digit+ ('Y'|'MO'|'W'|'D'|'H'|'M'|'S'|'MS'|'US'|'NS'))+
+ RelativeTime = (now() | DATETIME) ((+|-) Duration)+
+ ```
+
+ <center>**The syntax of the duration unit**
+
+
+ | Symbol | Meaning | Presentation | Examples |
+ | :----: | :---------: | :----------------------: | :------: |
+ | y | year | 1y=365 days | 1y |
+ | mo | month | 1mo=30 days | 1mo |
+ | w | week | 1w=7 days | 1w |
+ | d | day | 1d=1 day | 1d |
+ | | | | |
+ | h | hour | 1h=3600 seconds | 1h |
+ | m | minute | 1m=60 seconds | 1m |
+ | s | second | 1s=1 second | 1s |
+ | | | | |
+ | ms | millisecond | 1ms=1000_000 nanoseconds | 1ms |
+ | us | microsecond | 1us=1000 nanoseconds | 1us |
+ | ns | nanosecond | 1ns=1 nanosecond | 1ns |
+
+ </center>
+
+ 例子:
+
+ ```
+ now() - 1d2h //比服务器时间早 1 天 2 小时的时间
+ now() - 1w //比服务器时间早 1 周的时间
+ ```
+
+ > 注意:'+'和'-'的左右两边必须有空格
\ No newline at end of file
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index d72338f..6e585cf 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -23,16 +23,7 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
import org.apache.iotdb.db.engine.trigger.executor.TriggerEngine;
-import org.apache.iotdb.db.exception.metadata.AliasAlreadyExistException;
-import org.apache.iotdb.db.exception.metadata.AlignedTimeseriesException;
-import org.apache.iotdb.db.exception.metadata.DataTypeMismatchException;
-import org.apache.iotdb.db.exception.metadata.DeleteFailedException;
-import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
-import org.apache.iotdb.db.exception.metadata.PathNotExistException;
-import org.apache.iotdb.db.exception.metadata.StorageGroupAlreadySetException;
-import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
+import org.apache.iotdb.db.exception.metadata.*;
import org.apache.iotdb.db.metadata.logfile.MLogReader;
import org.apache.iotdb.db.metadata.logfile.MLogWriter;
import org.apache.iotdb.db.metadata.mnode.*;
@@ -147,7 +138,7 @@ public class MManager {
private MTree mtree;
// device -> DeviceMNode
- private RandomDeleteCache<PartialPath, Pair<IMNode, Template>> mNodeCache;
+ private RandomDeleteCache<PartialPath, IMNode> mNodeCache;
private TagManager tagManager = TagManager.getInstance();
private TemplateManager templateManager = TemplateManager.getInstance();
@@ -179,10 +170,10 @@ public class MManager {
int cacheSize = config.getmManagerCacheSize();
mNodeCache =
- new RandomDeleteCache<PartialPath, Pair<IMNode, Template>>(cacheSize) {
+ new RandomDeleteCache<PartialPath, IMNode>(cacheSize) {
@Override
- public Pair<IMNode, Template> loadObjectByKey(PartialPath key)
throws CacheException {
+ public IMNode loadObjectByKey(PartialPath key) throws CacheException
{
try {
return mtree.getNodeByPathWithStorageGroupCheck(key);
} catch (MetadataException e) {
@@ -1227,10 +1218,10 @@ public class MManager {
* needs to make the Meta group aware of the creation of an SG, so an
exception needs to be
* thrown here
*/
- public Pair<IMNode, Template> getDeviceNodeWithAutoCreate(
+ public IMNode getDeviceNodeWithAutoCreate(
PartialPath path, boolean autoCreateSchema, boolean allowCreateSg, int
sgLevel)
throws IOException, MetadataException {
- Pair<IMNode, Template> node;
+ IMNode node;
boolean shouldSetStorageGroup;
try {
node = mNodeCache.get(path);
@@ -1252,22 +1243,22 @@ public class MManager {
}
}
node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
- if (!(node.left.isStorageGroup())) {
- logWriter.autoCreateDeviceMNode(new
AutoCreateDeviceMNodePlan(node.left.getPartialPath()));
+ if (!(node.isStorageGroup())) {
+ logWriter.autoCreateDeviceMNode(new
AutoCreateDeviceMNodePlan(node.getPartialPath()));
}
return node;
} catch (StorageGroupAlreadySetException e) {
// ignore set storage group concurrently
node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
- if (!(node.left.isStorageGroup())) {
- logWriter.autoCreateDeviceMNode(new
AutoCreateDeviceMNodePlan(node.left.getPartialPath()));
+ if (!(node.isStorageGroup())) {
+ logWriter.autoCreateDeviceMNode(new
AutoCreateDeviceMNodePlan(node.getPartialPath()));
}
return node;
}
}
/** !!!!!!Attention!!!!! must call the return node's readUnlock() if you
call this method. */
- public Pair<IMNode, Template> getDeviceNodeWithAutoCreate(PartialPath path)
+ public IMNode getDeviceNodeWithAutoCreate(PartialPath path)
throws MetadataException, IOException {
return getDeviceNodeWithAutoCreate(
path, config.isAutoCreateSchemaEnabled(), true,
config.getDefaultStorageGroupLevel());
@@ -1278,19 +1269,17 @@ public class MManager {
throws PathNotExistException {
Set<IMeasurementSchema> res = new HashSet<>();
try {
- Pair<IMNode, Template> mNodeTemplatePair = mNodeCache.get(path);
- if (mNodeTemplatePair.left.getSchemaTemplate() != null) {
- mNodeTemplatePair.right = mNodeTemplatePair.left.getSchemaTemplate();
- }
+ IMNode node = mNodeCache.get(path);
+ Template template = node.getUpperTemplate();
- for (IMNode IMNode : mNodeTemplatePair.left.getChildren().values()) {
- IMeasurementMNode measurementMNode = (IMeasurementMNode) IMNode;
+ for (IMNode child : node.getChildren().values()) {
+ IMeasurementMNode measurementMNode = (IMeasurementMNode) child;
res.add(measurementMNode.getSchema());
}
// template
- if (mNodeTemplatePair.left.isUseTemplate() && mNodeTemplatePair.right !=
null) {
- res.addAll(mNodeTemplatePair.right.getSchemaMap().values());
+ if (node.isUseTemplate() && template != null) {
+ res.addAll(template.getSchemaMap().values());
}
} catch (CacheException e) {
throw new PathNotExistException(path.getFullPath());
@@ -1302,7 +1291,7 @@ public class MManager {
public IMNode getDeviceNode(PartialPath path) throws MetadataException {
IMNode node;
try {
- node = mNodeCache.get(path).left;
+ node = mNodeCache.get(path);
return node;
} catch (CacheException e) {
throw new PathNotExistException(path.getFullPath());
@@ -1394,11 +1383,11 @@ public class MManager {
Map<String, String> attributesMap,
PartialPath fullPath)
throws MetadataException, IOException {
- IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode.isMeasurement())) {
+ IMNode node = mtree.getNodeByPath(fullPath);
+ if (!(node.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
- IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
+ IMeasurementMNode leafMNode = (IMeasurementMNode) node;
// upsert alias
upsertAlias(alias, fullPath, leafMNode);
@@ -1444,11 +1433,11 @@ public class MManager {
*/
public void addAttributes(Map<String, String> attributesMap, PartialPath
fullPath)
throws MetadataException, IOException {
- IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode.isMeasurement())) {
+ IMNode node = mtree.getNodeByPath(fullPath);
+ if (!(node.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
- IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
+ IMeasurementMNode leafMNode = (IMeasurementMNode) node;
// no tag or attribute, we need to add a new record in log
if (leafMNode.getOffset() < 0) {
long offset = tagManager.writeTagFile(Collections.emptyMap(),
attributesMap);
@@ -1468,11 +1457,11 @@ public class MManager {
*/
public void addTags(Map<String, String> tagsMap, PartialPath fullPath)
throws MetadataException, IOException {
- IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode.isMeasurement())) {
+ IMNode node = mtree.getNodeByPath(fullPath);
+ if (!(node.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
- IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
+ IMeasurementMNode leafMNode = (IMeasurementMNode) node;
// no tag or attribute, we need to add a new record in log
if (leafMNode.getOffset() < 0) {
long offset = tagManager.writeTagFile(tagsMap, Collections.emptyMap());
@@ -1495,11 +1484,11 @@ public class MManager {
@SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity
warning
public void dropTagsOrAttributes(Set<String> keySet, PartialPath fullPath)
throws MetadataException, IOException {
- IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode.isMeasurement())) {
+ IMNode node = mtree.getNodeByPath(fullPath);
+ if (!(node.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
- IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
+ IMeasurementMNode leafMNode = (IMeasurementMNode) node;
// no tag or attribute, just do nothing.
if (leafMNode.getOffset() < 0) {
return;
@@ -1516,11 +1505,11 @@ public class MManager {
@SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity
warning
public void setTagsOrAttributesValue(Map<String, String> alterMap,
PartialPath fullPath)
throws MetadataException, IOException {
- IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode.isMeasurement())) {
+ IMNode node = mtree.getNodeByPath(fullPath);
+ if (!(node.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
- IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
+ IMeasurementMNode leafMNode = (IMeasurementMNode) node;
if (leafMNode.getOffset() < 0) {
throw new MetadataException(
String.format("TimeSeries [%s] does not have any tag/attribute.",
fullPath));
@@ -1540,11 +1529,11 @@ public class MManager {
@SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity
warning
public void renameTagOrAttributeKey(String oldKey, String newKey,
PartialPath fullPath)
throws MetadataException, IOException {
- IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode.isMeasurement())) {
+ IMNode node = mtree.getNodeByPath(fullPath);
+ if (!(node.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
- IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
+ IMeasurementMNode leafMNode = (IMeasurementMNode) node;
if (leafMNode.getOffset() < 0) {
throw new MetadataException(
String.format("TimeSeries [%s] does not have [%s] tag/attribute.",
fullPath, oldKey),
@@ -1615,13 +1604,13 @@ public class MManager {
/** Collect the timeseries schemas under "startingPath". */
public void collectSeries(PartialPath startingPath, List<IMeasurementSchema>
measurementSchemas) {
- IMNode IMNode;
+ IMNode node;
try {
- IMNode = getNodeByPath(startingPath);
+ node = getNodeByPath(startingPath);
} catch (MetadataException e) {
return;
}
- collectMeasurementSchema(IMNode, measurementSchemas);
+ collectMeasurementSchema(node, measurementSchemas);
}
/**
@@ -1708,14 +1697,11 @@ public class MManager {
IMeasurementMNode[] measurementMNodes = plan.getMeasurementMNodes();
// 1. get device node
- Pair<IMNode, Template> deviceMNode = getDeviceNodeWithAutoCreate(deviceId);
- if (!(deviceMNode.left.isMeasurement()) &&
deviceMNode.left.getSchemaTemplate() != null) {
- deviceMNode.right = deviceMNode.left.getSchemaTemplate();
- }
+ IMNode deviceMNode = getDeviceNodeWithAutoCreate(deviceId);
// check insert non-aligned InsertPlan for aligned timeseries
- if (deviceMNode.left.isMeasurement()
- && ((IMeasurementMNode) deviceMNode.left).getSchema() instanceof
VectorMeasurementSchema
+ if (deviceMNode.isMeasurement()
+ && ((IMeasurementMNode) deviceMNode).getSchema() instanceof
VectorMeasurementSchema
&& !plan.isAligned()) {
throw new MetadataException(
String.format(
@@ -1724,8 +1710,8 @@ public class MManager {
}
// check insert aligned InsertPlan for non-aligned timeseries
else if (plan.isAligned()
- && deviceMNode.left.getChild(vectorId) != null
- && !(deviceMNode.left.getChild(vectorId).isMeasurement())) {
+ && deviceMNode.getChild(vectorId) != null
+ && !(deviceMNode.getChild(vectorId).isMeasurement())) {
throw new MetadataException(
String.format(
"Path [%s] is not an aligned timeseries, please set
InsertPlan.isAligned() = false",
@@ -1738,7 +1724,7 @@ public class MManager {
for (int i = 0; i < measurementList.length; i++) {
try {
String measurement = measurementList[i];
- IMNode child = getMNode(deviceMNode.left, plan.isAligned() ? vectorId
: measurement);
+ IMNode child = getMNode(deviceMNode, plan.isAligned() ? vectorId :
measurement);
if (child != null && child.isMeasurement()) {
measurementMNode = (IMeasurementMNode) child;
} else if (child != null && child.isStorageGroup()) {
@@ -1754,14 +1740,14 @@ public class MManager {
internalCreateTimeseries(
prefixPath.concatNode(measurement),
plan.getDataTypes()[i]);
// after creating timeseries, the deviceMNode has been
replaced by a new entityMNode
- deviceMNode.left = mtree.getNodeByPath(deviceId);
- measurementMNode = (IMeasurementMNode)
deviceMNode.left.getChild(measurement);
+ deviceMNode = mtree.getNodeByPath(deviceId);
+ measurementMNode = (IMeasurementMNode)
deviceMNode.getChild(measurement);
} else {
internalAlignedCreateTimeseries(
prefixPath, Arrays.asList(measurementList),
Arrays.asList(plan.getDataTypes()));
// after creating timeseries, the deviceMNode has been
replaced by a new entityMNode
- deviceMNode.left = mtree.getNodeByPath(deviceId);
- measurementMNode = (IMeasurementMNode)
deviceMNode.left.getChild(vectorId);
+ deviceMNode = mtree.getNodeByPath(deviceId);
+ measurementMNode = (IMeasurementMNode)
deviceMNode.getChild(vectorId);
}
} else {
throw new MetadataException(
@@ -1852,7 +1838,7 @@ public class MManager {
}
}
- return deviceMNode.left;
+ return deviceMNode;
}
/** get dataType of plan, in loc measurements only support InsertRowPlan and
InsertTabletPlan */
@@ -1876,18 +1862,18 @@ public class MManager {
return deviceMNode.getChild(measurementName);
}
- private IMeasurementMNode findTemplate(
- Pair<IMNode, Template> deviceMNode, String measurement, String vectorId)
+ private IMeasurementMNode findTemplate(IMNode deviceMNode, String
measurement, String vectorId)
throws MetadataException {
- if (deviceMNode.right != null) {
- Map<String, IMeasurementSchema> curTemplateMap =
deviceMNode.right.getSchemaMap();
+ Template curTemplate = deviceMNode.getUpperTemplate();
+ if (curTemplate != null) {
+ Map<String, IMeasurementSchema> curTemplateMap =
curTemplate.getSchemaMap();
String schemaName = vectorId != null ? vectorId : measurement;
IMeasurementSchema schema = curTemplateMap.get(schemaName);
- if (!deviceMNode.left.isUseTemplate()) {
- deviceMNode.left = setUsingSchemaTemplate(deviceMNode.left);
+ if (!deviceMNode.isUseTemplate()) {
+ deviceMNode = setUsingSchemaTemplate(deviceMNode);
try {
- logWriter.setUsingSchemaTemplate(deviceMNode.left.getPartialPath());
+ logWriter.setUsingSchemaTemplate(deviceMNode.getPartialPath());
} catch (IOException e) {
throw new MetadataException(e);
}
@@ -1895,9 +1881,9 @@ public class MManager {
if (schema != null) {
if (schema instanceof MeasurementSchema) {
- return new MeasurementMNode(deviceMNode.left, measurement, schema,
null);
+ return new MeasurementMNode(deviceMNode, measurement, schema, null);
} else if (schema instanceof VectorMeasurementSchema) {
- return new MeasurementMNode(deviceMNode.left, vectorId, schema,
null);
+ return new MeasurementMNode(deviceMNode, vectorId, schema, null);
}
}
return null;
@@ -1954,16 +1940,20 @@ public class MManager {
}
}
- public void setSchemaTemplate(SetSchemaTemplatePlan plan) throws
MetadataException {
+ public synchronized void setSchemaTemplate(SetSchemaTemplatePlan plan)
throws MetadataException {
+ // get mnode and update template should be atomic
+ Template template = templateManager.getTemplate(plan.getTemplateName());
+
try {
- Template template = templateManager.getTemplate(plan.getTemplateName());
+ PartialPath path = new PartialPath(plan.getPrefixPath());
- // get mnode and update template should be atomic
- synchronized (this) {
- Pair<IMNode, Template> node =
- getDeviceNodeWithAutoCreate(new PartialPath(plan.getPrefixPath()));
- templateManager.setSchemaTemplate(template, node);
- }
+ mtree.checkTemplateOnPath(path);
+
+ IMNode node = getDeviceNodeWithAutoCreate(path);
+
+ templateManager.checkIsTemplateAndMNodeCompatible(template, node);
+
+ node.setSchemaTemplate(template);
// write wal
if (!isRecovering) {
@@ -1974,10 +1964,6 @@ public class MManager {
}
}
- public boolean isTemplateCompatible(Template upper, Template current) {
- return templateManager.isTemplateCompatible(upper, current);
- }
-
public void autoCreateDeviceMNode(AutoCreateDeviceMNodePlan plan) throws
MetadataException {
mtree.getDeviceNodeWithAutoCreating(plan.getPath(),
config.getDefaultStorageGroupLevel());
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index 27ec0e6..76709a4 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -492,8 +492,7 @@ public class MTree implements Serializable {
*
* <p>e.g., get root.sg.d1, get or create all internal nodes and return the
node of d1
*/
- Pair<IMNode, Template> getDeviceNodeWithAutoCreating(PartialPath deviceId,
int sgLevel)
- throws MetadataException {
+ IMNode getDeviceNodeWithAutoCreating(PartialPath deviceId, int sgLevel)
throws MetadataException {
String[] nodeNames = deviceId.getNodes();
if (nodeNames.length <= 1 || !nodeNames[0].equals(root.getName())) {
throw new IllegalPathException(deviceId.getFullPath());
@@ -520,7 +519,7 @@ public class MTree implements Serializable {
upperTemplate = cur.getSchemaTemplate() == null ? upperTemplate :
cur.getSchemaTemplate();
}
- return new Pair<>(cur, upperTemplate);
+ return cur;
}
/**
@@ -731,8 +730,7 @@ public class MTree implements Serializable {
* Get node by path with storage group check If storage group is not set,
* StorageGroupNotSetException will be thrown
*/
- Pair<IMNode, Template> getNodeByPathWithStorageGroupCheck(PartialPath path)
- throws MetadataException {
+ IMNode getNodeByPathWithStorageGroupCheck(PartialPath path) throws
MetadataException {
boolean storageGroupChecked = false;
String[] nodes = path.getNodes();
if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
@@ -740,10 +738,8 @@ public class MTree implements Serializable {
}
IMNode cur = root;
- Template upperTemplate = null;
for (int i = 1; i < nodes.length; i++) {
- upperTemplate = cur.getSchemaTemplate() == null ? upperTemplate :
cur.getSchemaTemplate();
cur = cur.getChild(nodes[i]);
if (cur == null) {
// not find
@@ -761,7 +757,7 @@ public class MTree implements Serializable {
if (!storageGroupChecked) {
throw new StorageGroupNotSetException(path.getFullPath());
}
- return new Pair<>(cur, upperTemplate);
+ return cur;
}
/**
@@ -1968,10 +1964,10 @@ public class MTree implements Serializable {
}
while (!nodeStack.isEmpty()) {
- IMNode IMNode = nodeStack.removeFirst();
+ IMNode node = nodeStack.removeFirst();
int depth = depthStack.removeFirst();
- determineStorageGroup(depth + 1, nodes, IMNode, paths, nodeStack,
depthStack);
+ determineStorageGroup(depth + 1, nodes, node, paths, nodeStack,
depthStack);
}
return paths;
}
@@ -1984,12 +1980,12 @@ public class MTree implements Serializable {
private void determineStorageGroup(
int depth,
String[] nodes,
- IMNode IMNode,
+ IMNode node,
Map<String, String> paths,
Deque<IMNode> nodeStack,
Deque<Integer> depthStack) {
String currNode = depth >= nodes.length ? PATH_WILDCARD : nodes[depth];
- for (Entry<String, IMNode> entry : IMNode.getChildren().entrySet()) {
+ for (Entry<String, IMNode> entry : node.getChildren().entrySet()) {
if (!currNode.equals(PATH_WILDCARD) && !currNode.equals(entry.getKey()))
{
continue;
}
@@ -2024,4 +2020,49 @@ public class MTree implements Serializable {
return IEntityMNode.setToEntity(node);
}
}
+
+ /**
+ * check whether there is template on given path and the subTree has
template return true,
+ * otherwise false
+ */
+ void checkTemplateOnPath(PartialPath path) throws MetadataException {
+ String[] nodeNames = path.getNodes();
+ IMNode cur = root;
+ if (!nodeNames[0].equals(root.getName())) {
+ return;
+ }
+ if (cur.getSchemaTemplate() != null) {
+ throw new MetadataException("Template already exists on " +
cur.getFullPath());
+ }
+ for (int i = 1; i < nodeNames.length; i++) {
+ if (cur.isMeasurement()) {
+ return;
+ }
+ if (!cur.hasChild(nodeNames[i])) {
+ return;
+ }
+ cur = cur.getChild(nodeNames[i]);
+ if (cur.getSchemaTemplate() != null) {
+ throw new MetadataException("Template already exists on " +
cur.getFullPath());
+ }
+ }
+
+ checkTemplateOnSubtree(cur);
+ }
+
+ // traverse all the descendant of the given path node
+ private void checkTemplateOnSubtree(IMNode node) throws MetadataException {
+ if (node.isMeasurement()) {
+ return;
+ }
+ for (IMNode child : node.getChildren().values()) {
+ if (child.isMeasurement()) {
+ continue;
+ }
+ if (child.getSchemaTemplate() != null) {
+ throw new MetadataException("Template already exists on " +
child.getFullPath());
+ }
+ checkTemplateOnSubtree(child);
+ }
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
index 84672d8..e70848c 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MetaUtils.java
@@ -127,8 +127,8 @@ public class MetaUtils {
collectLastNode(node, lastNodeList);
List<String> result = new ArrayList<>();
- for (IMNode IMNode : lastNodeList) {
- result.add(IMNode.getFullPath());
+ for (IMNode lastNode : lastNodeList) {
+ result.add(lastNode.getFullPath());
}
return result;
diff --git
a/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java
b/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java
index bf4779d..9fdffef 100644
---
a/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java
+++
b/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java
@@ -20,15 +20,11 @@ package org.apache.iotdb.db.metadata.template;
import org.apache.iotdb.db.exception.metadata.DuplicatedTemplateException;
import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
import org.apache.iotdb.db.exception.metadata.UndefinedTemplateException;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
import org.apache.iotdb.db.utils.TestOnly;
-import org.apache.iotdb.tsfile.utils.Pair;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -73,64 +69,23 @@ public class TemplateManager {
return template;
}
- public void setSchemaTemplate(Template template, Pair<IMNode, Template> node)
+ public void checkIsTemplateAndMNodeCompatible(Template template, IMNode node)
throws MetadataException {
-
- if (node.left.getSchemaTemplate() != null) {
- if (node.left.getSchemaTemplate().equals(template)) {
+ if (node.getSchemaTemplate() != null) {
+ if (node.getSchemaTemplate().equals(template)) {
throw new DuplicatedTemplateException(template.getName());
} else {
throw new MetadataException("Specified node already has template");
}
}
- if (!isTemplateCompatible(node.right, template)) {
- throw new MetadataException("Incompatible template");
- }
-
- checkIsTemplateAndMNodeCompatible(template, node.left);
-
- node.left.setSchemaTemplate(template);
- }
-
- public boolean isTemplateCompatible(Template upper, Template current) {
- if (upper == null) {
- return true;
- }
-
- Map<String, IMeasurementSchema> upperMap = new
HashMap<>(upper.getSchemaMap());
- Map<String, IMeasurementSchema> currentMap = new
HashMap<>(current.getSchemaMap());
-
- // for identical vector schema, we should just compare once
- Map<IMeasurementSchema, IMeasurementSchema> sameSchema = new HashMap<>();
-
- for (String name : currentMap.keySet()) {
- IMeasurementSchema upperSchema = upperMap.remove(name);
- if (upperSchema != null) {
- IMeasurementSchema currentSchema = currentMap.get(name);
- // use "==" to compare actual address space
- if (upperSchema == sameSchema.get(currentSchema)) {
- continue;
- }
-
- if (!upperSchema.equals(currentSchema)) {
- return false;
- }
-
- sameSchema.put(currentSchema, upperSchema);
- }
- }
-
- // current template must contains all measurements of upper template
- return upperMap.isEmpty();
- }
-
- public void checkIsTemplateAndMNodeCompatible(Template template, IMNode
IMNode)
- throws PathAlreadyExistException {
for (String schemaName : template.getSchemaMap().keySet()) {
- if (IMNode.hasChild(schemaName)) {
- throw new PathAlreadyExistException(
- IMNode.getPartialPath().concatNode(schemaName).getFullPath());
+ if (node.hasChild(schemaName)) {
+ throw new MetadataException(
+ "Schema name "
+ + schemaName
+ + " in template has conflict with node's child "
+ + (node.getFullPath() + "." + schemaName));
}
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index 1939617..21dbff9 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -1187,8 +1187,7 @@ public class PlanExecutor implements IPlanExecutor {
String device = chunkGroupMetadata.getDevice();
IMNode node =
IoTDB.metaManager.getDeviceNodeWithAutoCreate(
- new PartialPath(device), true, true, sgLevel)
- .left;
+ new PartialPath(device), true, true, sgLevel);
for (ChunkMetadata chunkMetadata :
chunkGroupMetadata.getChunkMetadataList()) {
PartialPath series =
new PartialPath(
diff --git
a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
index 5c7c652..d424e07 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
@@ -21,11 +21,9 @@ package org.apache.iotdb.db.metadata;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
-import org.apache.iotdb.db.metadata.template.Template;
import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
import org.apache.iotdb.db.qp.physical.crud.SetSchemaTemplatePlan;
@@ -926,124 +924,6 @@ public class MManagerBasicTest {
}
@Test
- public void testTemplateCompatibility() throws MetadataException {
- List<List<String>> measurementList = new ArrayList<>();
- measurementList.add(Collections.singletonList("s11"));
- List<String> measurements = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- measurements.add("s" + i);
- }
- measurementList.add(measurements);
-
- List<List<TSDataType>> dataTypeList = new ArrayList<>();
- dataTypeList.add(Collections.singletonList(TSDataType.INT64));
- List<TSDataType> dataTypes = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- dataTypes.add(TSDataType.INT64);
- }
- dataTypeList.add(dataTypes);
-
- List<List<TSEncoding>> encodingList = new ArrayList<>();
- encodingList.add(Collections.singletonList(TSEncoding.RLE));
- List<TSEncoding> encodings = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- encodings.add(TSEncoding.RLE);
- }
- encodingList.add(encodings);
-
- List<CompressionType> compressionTypes = new ArrayList<>();
- for (int i = 0; i < 11; i++) {
- compressionTypes.add(CompressionType.SNAPPY);
- }
-
- List<String> schemaNames = new ArrayList<>();
- schemaNames.add("s11");
- schemaNames.add("test_vector");
-
- CreateTemplatePlan plan1 =
- new CreateTemplatePlan(
- "template1",
- new ArrayList<>(schemaNames),
- new ArrayList<>(measurementList),
- new ArrayList<>(dataTypeList),
- new ArrayList<>(encodingList),
- new ArrayList<>(compressionTypes));
-
- measurementList.add(Collections.singletonList("s12"));
- schemaNames.add("s12");
- dataTypeList.add(Collections.singletonList(TSDataType.INT64));
- encodingList.add(Collections.singletonList(TSEncoding.RLE));
- compressionTypes.add(CompressionType.SNAPPY);
-
- CreateTemplatePlan plan2 =
- new CreateTemplatePlan(
- "template2",
- new ArrayList<>(schemaNames),
- new ArrayList<>(measurementList),
- new ArrayList<>(dataTypeList),
- new ArrayList<>(encodingList),
- new ArrayList<>(compressionTypes));
-
- MManager manager = IoTDB.metaManager;
-
- assertTrue(manager.isTemplateCompatible(new Template(plan1), new
Template(plan2)));
- assertFalse(manager.isTemplateCompatible(new Template(plan2), new
Template(plan1)));
-
- System.out.println(measurementList);
- measurementList.get(1).add("s13");
- dataTypeList.get(1).add(TSDataType.INT64);
- encodingList.get(1).add(TSEncoding.RLE);
-
- CreateTemplatePlan plan3 =
- new CreateTemplatePlan(
- "template3",
- new ArrayList<>(schemaNames),
- new ArrayList<>(measurementList),
- new ArrayList<>(dataTypeList),
- new ArrayList<>(encodingList),
- new ArrayList<>(compressionTypes));
-
- assertTrue(manager.isTemplateCompatible(new Template(plan1), new
Template(plan3)));
-
- List<String> vectorList = new ArrayList<>(measurementList.get(1));
- vectorList.remove(0);
- List<TSDataType> vectorDataTypesList = new
ArrayList<>(dataTypeList.get(1));
- vectorDataTypesList.remove(0);
- List<TSEncoding> vectorEncodingsList = new
ArrayList<>(encodingList.get(1));
- vectorEncodingsList.remove(0);
-
- measurementList.set(1, vectorList);
- dataTypeList.set(1, vectorDataTypesList);
- encodingList.set(1, vectorEncodingsList);
-
- CreateTemplatePlan plan4 =
- new CreateTemplatePlan(
- "template4",
- new ArrayList<>(schemaNames),
- new ArrayList<>(measurementList),
- new ArrayList<>(dataTypeList),
- new ArrayList<>(encodingList),
- new ArrayList<>(compressionTypes));
-
- assertFalse(manager.isTemplateCompatible(new Template(plan1), new
Template(plan4)));
-
- // test manager
- manager.createSchemaTemplate(plan1);
- manager.createSchemaTemplate(plan2);
- manager.createSchemaTemplate(plan4);
-
- manager.setSchemaTemplate(new SetSchemaTemplatePlan("template1",
"root.sg1.d1"));
- try {
- manager.setSchemaTemplate(new SetSchemaTemplatePlan("template4",
"root.sg1.d1.d2"));
- fail("These two templates are incompatible");
- } catch (MetadataException e) {
- assertEquals("Incompatible template", e.getMessage());
- }
-
- manager.setSchemaTemplate(new SetSchemaTemplatePlan("template2",
"root.sg1.d1.d2"));
- }
-
- @Test
public void testTemplateAndTimeSeriesCompatibility() throws
MetadataException {
CreateTemplatePlan plan = getCreateTemplatePlan();
MManager manager = IoTDB.metaManager;
@@ -1115,8 +995,10 @@ public class MManagerBasicTest {
try {
manager.setSchemaTemplate(setSchemaTemplatePlan);
fail();
- } catch (PathAlreadyExistException e) {
- assertEquals("Path [root.sg1.d1.s11] already exist", e.getMessage());
+ } catch (MetadataException e) {
+ assertEquals(
+ "Schema name s11 in template has conflict with node's child
root.sg1.d1.s11",
+ e.getMessage());
}
manager.deleteTimeseries(new PartialPath("root.sg1.d1.s11"));
@@ -1136,8 +1018,119 @@ public class MManagerBasicTest {
try {
manager.setSchemaTemplate(setSchemaTemplatePlan);
fail();
- } catch (PathAlreadyExistException e) {
- assertEquals("Path [root.sg1.d1.vector] already exist", e.getMessage());
+ } catch (MetadataException e) {
+ assertEquals(
+ "Schema name vector in template has conflict with node's child
root.sg1.d1.vector",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testSetDeviceTemplate() throws MetadataException {
+ List<List<String>> measurementList = new ArrayList<>();
+ measurementList.add(Collections.singletonList("s11"));
+ List<String> measurements = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ measurements.add("s" + i);
+ }
+ measurementList.add(measurements);
+
+ List<List<TSDataType>> dataTypeList = new ArrayList<>();
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+ List<TSDataType> dataTypes = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ dataTypes.add(TSDataType.INT64);
+ }
+ dataTypeList.add(dataTypes);
+
+ List<List<TSEncoding>> encodingList = new ArrayList<>();
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+ List<TSEncoding> encodings = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ encodings.add(TSEncoding.RLE);
+ }
+ encodingList.add(encodings);
+
+ List<CompressionType> compressionTypes = new ArrayList<>();
+ for (int i = 0; i < 11; i++) {
+ compressionTypes.add(CompressionType.SNAPPY);
+ }
+
+ List<String> schemaNames = new ArrayList<>();
+ schemaNames.add("s11");
+ schemaNames.add("test_vector");
+
+ CreateTemplatePlan plan1 =
+ new CreateTemplatePlan(
+ "template1",
+ new ArrayList<>(schemaNames),
+ new ArrayList<>(measurementList),
+ new ArrayList<>(dataTypeList),
+ new ArrayList<>(encodingList),
+ new ArrayList<>(compressionTypes));
+
+ measurementList.add(Collections.singletonList("s12"));
+ schemaNames.add("s12");
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+ compressionTypes.add(CompressionType.SNAPPY);
+
+ CreateTemplatePlan plan2 =
+ new CreateTemplatePlan(
+ "template2",
+ new ArrayList<>(schemaNames),
+ new ArrayList<>(measurementList),
+ new ArrayList<>(dataTypeList),
+ new ArrayList<>(encodingList),
+ new ArrayList<>(compressionTypes));
+
+ measurementList.get(1).add("s13");
+ dataTypeList.get(1).add(TSDataType.INT64);
+ encodingList.get(1).add(TSEncoding.RLE);
+
+ SetSchemaTemplatePlan setPlan1 = new SetSchemaTemplatePlan("template1",
"root.sg1");
+ SetSchemaTemplatePlan setPlan2 = new SetSchemaTemplatePlan("template2",
"root.sg2.d1");
+
+ SetSchemaTemplatePlan setPlan3 = new SetSchemaTemplatePlan("template1",
"root.sg1.d1");
+ SetSchemaTemplatePlan setPlan4 = new SetSchemaTemplatePlan("template2",
"root.sg2");
+
+ SetSchemaTemplatePlan setPlan5 = new SetSchemaTemplatePlan("template2",
"root.sg1.d1");
+
+ MManager manager = IoTDB.metaManager;
+
+ manager.createSchemaTemplate(plan1);
+ manager.createSchemaTemplate(plan2);
+
+ manager.setStorageGroup(new PartialPath("root.sg1"));
+ manager.setStorageGroup(new PartialPath("root.sg2"));
+ manager.setStorageGroup(new PartialPath("root.sg3"));
+
+ try {
+ manager.setSchemaTemplate(setPlan1);
+ manager.setSchemaTemplate(setPlan2);
+ } catch (MetadataException e) {
+ fail();
+ }
+
+ try {
+ manager.setSchemaTemplate(setPlan3);
+ fail();
+ } catch (MetadataException e) {
+ assertEquals("Template already exists on root.sg1", e.getMessage());
+ }
+
+ try {
+ manager.setSchemaTemplate(setPlan4);
+ fail();
+ } catch (MetadataException e) {
+ assertEquals("Template already exists on root.sg2.d1", e.getMessage());
+ }
+
+ try {
+ manager.setSchemaTemplate(setPlan5);
+ fail();
+ } catch (MetadataException e) {
+ assertEquals("Template already exists on root.sg1", e.getMessage());
}
}
@@ -1553,9 +1546,9 @@ public class MManagerBasicTest {
new IMeasurementMNode[insertRowPlan.getMeasurements().length]);
// call getSeriesSchemasAndReadLockDevice
- IMNode IMNode = manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
- assertEquals(3, manager.getAllTimeseriesCount(IMNode.getPartialPath()));
- assertEquals(1, IMNode.getMeasurementMNodeCount());
+ IMNode node = manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
+ assertEquals(3, manager.getAllTimeseriesCount(node.getPartialPath()));
+ assertEquals(1, node.getMeasurementMNodeCount());
assertNull(insertRowPlan.getMeasurementMNodes()[0]);
assertNull(insertRowPlan.getMeasurementMNodes()[1]);
assertNull(insertRowPlan.getMeasurementMNodes()[2]);
@@ -1640,8 +1633,8 @@ public class MManagerBasicTest {
new IMeasurementMNode[insertRowPlan.getMeasurements().length]);
// call getSeriesSchemasAndReadLockDevice
- IMNode IMNode = manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
- assertEquals(1, IMNode.getMeasurementMNodeCount());
+ IMNode node = manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
+ assertEquals(1, node.getMeasurementMNodeCount());
assertNull(insertRowPlan.getMeasurementMNodes()[0]);
assertEquals(1, insertRowPlan.getFailedMeasurementNumber());
diff --git
a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java
b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java
index 40b22fb..00c1794 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java
@@ -138,7 +138,7 @@ public class MManagerImproveTest {
private void doCacheTest(String deviceId, List<String> measurementList)
throws MetadataException {
try {
- IMNode node = mManager.getDeviceNodeWithAutoCreate(new
PartialPath(deviceId)).left;
+ IMNode node = mManager.getDeviceNodeWithAutoCreate(new
PartialPath(deviceId));
for (String s : measurementList) {
assertTrue(node.hasChild(s));
IMeasurementMNode measurementNode = (IMeasurementMNode)
node.getChild(s);