Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
8f16cc08
T
TDengine
项目概览
taosdata
/
TDengine
接近 2 年 前同步成功
通知
1191
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
8f16cc08
编写于
6月 15, 2022
作者:
D
dapan1121
提交者:
GitHub
6月 15, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #13844 from taosdata/hotfix/TD-16540
fix: fix get table index crash issue
上级
60028dce
6d1ff4c1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
62 addition
and
51 deletion
+62
-51
include/common/systable.h
include/common/systable.h
+1
-0
source/libs/catalog/src/ctgAsync.c
source/libs/catalog/src/ctgAsync.c
+50
-49
source/libs/catalog/src/ctgDbg.c
source/libs/catalog/src/ctgDbg.c
+1
-1
source/libs/catalog/src/ctgUtil.c
source/libs/catalog/src/ctgUtil.c
+2
-1
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+8
-0
未找到文件。
include/common/systable.h
浏览文件 @
8f16cc08
...
@@ -52,6 +52,7 @@ extern "C" {
...
@@ -52,6 +52,7 @@ extern "C" {
#define TSDB_PERFS_TABLE_OFFSETS "offsets"
#define TSDB_PERFS_TABLE_OFFSETS "offsets"
#define TSDB_PERFS_TABLE_TRANS "trans"
#define TSDB_PERFS_TABLE_TRANS "trans"
#define TSDB_PERFS_TABLE_STREAMS "streams"
#define TSDB_PERFS_TABLE_STREAMS "streams"
#define TSDB_PERFS_TABLE_APPS "apps"
typedef
struct
SSysDbTableSchema
{
typedef
struct
SSysDbTableSchema
{
const
char
*
name
;
const
char
*
name
;
...
...
source/libs/catalog/src/ctgAsync.c
浏览文件 @
8f16cc08
...
@@ -261,55 +261,49 @@ int32_t ctgInitGetTbIndexTask(SCtgJob *pJob, int32_t taskIdx, SName *name) {
...
@@ -261,55 +261,49 @@ int32_t ctgInitGetTbIndexTask(SCtgJob *pJob, int32_t taskIdx, SName *name) {
}
}
int32_t
ctgHandleForceUpdate
(
SCatalog
*
pCtg
,
SCtgJob
*
pJob
,
const
SCatalogReq
*
pReq
)
{
int32_t
ctgHandleForceUpdate
(
SCatalog
*
pCtg
,
int32_t
taskNum
,
SCtgJob
*
pJob
,
const
SCatalogReq
*
pReq
)
{
int32_t
dbNum
=
pJob
->
dbCfgNum
+
pJob
->
dbVgNum
+
pJob
->
dbInfoNum
;
SHashObj
*
pDb
=
taosHashInit
(
taskNum
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
HASH_NO_LOCK
);
if
(
dbNum
>
0
)
{
if
(
NULL
==
pDb
)
{
if
(
dbNum
>
pJob
->
dbCfgNum
&&
dbNum
>
pJob
->
dbVgNum
&&
dbNum
>
pJob
->
dbInfoNum
)
{
CTG_ERR_RET
(
TSDB_CODE_OUT_OF_MEMORY
);
SHashObj
*
pDb
=
taosHashInit
(
dbNum
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
HASH_NO_LOCK
);
}
if
(
NULL
==
pDb
)
{
CTG_ERR_RET
(
TSDB_CODE_OUT_OF_MEMORY
);
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbVgNum
;
++
i
)
{
}
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbVgroup
,
i
);
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbVgNum
;
++
i
)
{
}
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbVgroup
,
i
);
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
}
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbCfgNum
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbCfgNum
;
++
i
)
{
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbCfg
,
i
);
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbCfg
,
i
);
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
}
}
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbInfoNum
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbInfoNum
;
++
i
)
{
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbInfo
,
i
);
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbInfo
,
i
);
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
}
}
char
*
dbFName
=
taosHashIterate
(
pDb
,
NULL
);
for
(
int32_t
i
=
0
;
i
<
pJob
->
tbMetaNum
;
++
i
)
{
while
(
dbFName
)
{
SName
*
name
=
taosArrayGet
(
pReq
->
pTableMeta
,
i
);
ctgDropDbVgroupEnqueue
(
pCtg
,
dbFName
,
true
);
char
dbFName
[
TSDB_DB_FNAME_LEN
];
dbFName
=
taosHashIterate
(
pDb
,
dbFName
);
tNameGetFullDbName
(
name
,
dbFName
);
}
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
}
for
(
int32_t
i
=
0
;
i
<
pJob
->
tbHashNum
;
++
i
)
{
SName
*
name
=
taosArrayGet
(
pReq
->
pTableHash
,
i
);
char
dbFName
[
TSDB_DB_FNAME_LEN
];
tNameGetFullDbName
(
name
,
dbFName
);
taosHashPut
(
pDb
,
dbFName
,
strlen
(
dbFName
),
dbFName
,
TSDB_DB_FNAME_LEN
);
}
taosHashCleanup
(
pDb
);
char
*
dbFName
=
taosHashIterate
(
pDb
,
NULL
);
}
else
{
while
(
dbFName
)
{
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbVgNum
;
++
i
)
{
ctgDropDbVgroupEnqueue
(
pCtg
,
dbFName
,
true
);
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbVgroup
,
i
);
dbFName
=
taosHashIterate
(
pDb
,
dbFName
);
CTG_ERR_RET
(
ctgDropDbVgroupEnqueue
(
pCtg
,
dbFName
,
true
));
}
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbCfgNum
;
++
i
)
{
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbCfg
,
i
);
CTG_ERR_RET
(
ctgDropDbVgroupEnqueue
(
pCtg
,
dbFName
,
true
));
}
for
(
int32_t
i
=
0
;
i
<
pJob
->
dbInfoNum
;
++
i
)
{
char
*
dbFName
=
taosArrayGet
(
pReq
->
pDbInfo
,
i
);
CTG_ERR_RET
(
ctgDropDbVgroupEnqueue
(
pCtg
,
dbFName
,
true
));
}
}
}
}
taosHashCleanup
(
pDb
);
int32_t
tbNum
=
pJob
->
tbMetaNum
+
pJob
->
tbHashNum
;
int32_t
tbNum
=
pJob
->
tbMetaNum
+
pJob
->
tbHashNum
;
if
(
tbNum
>
0
)
{
if
(
tbNum
>
0
)
{
if
(
tbNum
>
pJob
->
tbMetaNum
&&
tbNum
>
pJob
->
tbHashNum
)
{
if
(
tbNum
>
pJob
->
tbMetaNum
&&
tbNum
>
pJob
->
tbHashNum
)
{
...
@@ -404,7 +398,7 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgJob** job, uint6
...
@@ -404,7 +398,7 @@ int32_t ctgInitJob(SCatalog* pCtg, SRequestConnInfo *pConn, SCtgJob** job, uint6
}
}
if
(
pReq
->
forceUpdate
)
{
if
(
pReq
->
forceUpdate
)
{
CTG_ERR_JRET
(
ctgHandleForceUpdate
(
pCtg
,
pJob
,
pReq
));
CTG_ERR_JRET
(
ctgHandleForceUpdate
(
pCtg
,
*
taskNum
,
pJob
,
pReq
));
}
}
int32_t
taskIdx
=
0
;
int32_t
taskIdx
=
0
;
...
@@ -790,8 +784,7 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTask* pTask, int32_t reqType, const SDataBuf *
...
@@ -790,8 +784,7 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTask* pTask, int32_t reqType, const SDataBuf *
_return:
_return:
if
(
dbCache
)
{
if
(
dbCache
)
{
ctgRUnlockVgInfo
(
dbCache
);
ctgReleaseVgInfoToCache
(
pCtg
,
dbCache
);
ctgReleaseDBCache
(
pCtg
,
dbCache
);
}
}
ctgHandleTaskEnd
(
pTask
,
code
);
ctgHandleTaskEnd
(
pTask
,
code
);
...
@@ -870,7 +863,7 @@ _return:
...
@@ -870,7 +863,7 @@ _return:
int32_t
ctgHandleGetTbIndexRsp
(
SCtgTask
*
pTask
,
int32_t
reqType
,
const
SDataBuf
*
pMsg
,
int32_t
rspCode
)
{
int32_t
ctgHandleGetTbIndexRsp
(
SCtgTask
*
pTask
,
int32_t
reqType
,
const
SDataBuf
*
pMsg
,
int32_t
rspCode
)
{
int32_t
code
=
0
;
int32_t
code
=
0
;
CTG_ERR_JRET
(
ctgProcessRspMsg
(
&
pTask
->
msgCtx
.
out
,
reqType
,
pMsg
->
pData
,
pMsg
->
len
,
rspCode
,
pTask
->
msgCtx
.
target
));
CTG_ERR_JRET
(
ctgProcessRspMsg
(
pTask
->
msgCtx
.
out
,
reqType
,
pMsg
->
pData
,
pMsg
->
len
,
rspCode
,
pTask
->
msgCtx
.
target
));
STableIndex
*
pOut
=
(
STableIndex
*
)
pTask
->
msgCtx
.
out
;
STableIndex
*
pOut
=
(
STableIndex
*
)
pTask
->
msgCtx
.
out
;
SArray
*
pInfo
=
NULL
;
SArray
*
pInfo
=
NULL
;
...
@@ -949,7 +942,6 @@ _return:
...
@@ -949,7 +942,6 @@ _return:
int32_t
ctgHandleGetUserRsp
(
SCtgTask
*
pTask
,
int32_t
reqType
,
const
SDataBuf
*
pMsg
,
int32_t
rspCode
)
{
int32_t
ctgHandleGetUserRsp
(
SCtgTask
*
pTask
,
int32_t
reqType
,
const
SDataBuf
*
pMsg
,
int32_t
rspCode
)
{
int32_t
code
=
0
;
int32_t
code
=
0
;
SCtgDBCache
*
dbCache
=
NULL
;
SCtgUserCtx
*
ctx
=
(
SCtgUserCtx
*
)
pTask
->
taskCtx
;
SCtgUserCtx
*
ctx
=
(
SCtgUserCtx
*
)
pTask
->
taskCtx
;
SCatalog
*
pCtg
=
pTask
->
pJob
->
pCtg
;
SCatalog
*
pCtg
=
pTask
->
pJob
->
pCtg
;
bool
pass
=
false
;
bool
pass
=
false
;
...
@@ -1018,7 +1010,7 @@ int32_t ctgAsyncRefreshTbMeta(SCtgTask *pTask) {
...
@@ -1018,7 +1010,7 @@ int32_t ctgAsyncRefreshTbMeta(SCtgTask *pTask) {
CTG_ERR_RET
(
ctgAcquireVgInfoFromCache
(
pCtg
,
dbFName
,
&
dbCache
));
CTG_ERR_RET
(
ctgAcquireVgInfoFromCache
(
pCtg
,
dbFName
,
&
dbCache
));
if
(
dbCache
)
{
if
(
dbCache
)
{
SVgroupInfo
vgInfo
=
{
0
};
SVgroupInfo
vgInfo
=
{
0
};
CTG_ERR_RET
(
ctgGetVgInfoFromHashValue
(
pCtg
,
dbCache
->
vgCache
.
vgInfo
,
ctx
->
pName
,
&
vgInfo
));
CTG_ERR_
J
RET
(
ctgGetVgInfoFromHashValue
(
pCtg
,
dbCache
->
vgCache
.
vgInfo
,
ctx
->
pName
,
&
vgInfo
));
ctgDebug
(
"will refresh tbmeta, not supposed to be stb, tbName:%s, flag:%d"
,
tNameGetTableName
(
ctx
->
pName
),
ctx
->
flag
);
ctgDebug
(
"will refresh tbmeta, not supposed to be stb, tbName:%s, flag:%d"
,
tNameGetTableName
(
ctx
->
pName
),
ctx
->
flag
);
...
@@ -1067,6 +1059,9 @@ int32_t ctgLaunchGetDbVgTask(SCtgTask *pTask) {
...
@@ -1067,6 +1059,9 @@ int32_t ctgLaunchGetDbVgTask(SCtgTask *pTask) {
CTG_ERR_RET
(
ctgAcquireVgInfoFromCache
(
pCtg
,
pCtx
->
dbFName
,
&
dbCache
));
CTG_ERR_RET
(
ctgAcquireVgInfoFromCache
(
pCtg
,
pCtx
->
dbFName
,
&
dbCache
));
if
(
NULL
!=
dbCache
)
{
if
(
NULL
!=
dbCache
)
{
CTG_ERR_JRET
(
ctgGenerateVgList
(
pCtg
,
dbCache
->
vgCache
.
vgInfo
->
vgHash
,
(
SArray
**
)
&
pTask
->
res
));
CTG_ERR_JRET
(
ctgGenerateVgList
(
pCtg
,
dbCache
->
vgCache
.
vgInfo
->
vgHash
,
(
SArray
**
)
&
pTask
->
res
));
ctgReleaseVgInfoToCache
(
pCtg
,
dbCache
);
dbCache
=
NULL
;
CTG_ERR_JRET
(
ctgHandleTaskEnd
(
pTask
,
0
));
CTG_ERR_JRET
(
ctgHandleTaskEnd
(
pTask
,
0
));
}
else
{
}
else
{
...
@@ -1101,6 +1096,9 @@ int32_t ctgLaunchGetTbHashTask(SCtgTask *pTask) {
...
@@ -1101,6 +1096,9 @@ int32_t ctgLaunchGetTbHashTask(SCtgTask *pTask) {
CTG_ERR_JRET
(
TSDB_CODE_OUT_OF_MEMORY
);
CTG_ERR_JRET
(
TSDB_CODE_OUT_OF_MEMORY
);
}
}
CTG_ERR_JRET
(
ctgGetVgInfoFromHashValue
(
pCtg
,
dbCache
->
vgCache
.
vgInfo
,
pCtx
->
pName
,
(
SVgroupInfo
*
)
pTask
->
res
));
CTG_ERR_JRET
(
ctgGetVgInfoFromHashValue
(
pCtg
,
dbCache
->
vgCache
.
vgInfo
,
pCtx
->
pName
,
(
SVgroupInfo
*
)
pTask
->
res
));
ctgReleaseVgInfoToCache
(
pCtg
,
dbCache
);
dbCache
=
NULL
;
CTG_ERR_JRET
(
ctgHandleTaskEnd
(
pTask
,
0
));
CTG_ERR_JRET
(
ctgHandleTaskEnd
(
pTask
,
0
));
}
else
{
}
else
{
...
@@ -1176,6 +1174,9 @@ int32_t ctgLaunchGetDbInfoTask(SCtgTask *pTask) {
...
@@ -1176,6 +1174,9 @@ int32_t ctgLaunchGetDbInfoTask(SCtgTask *pTask) {
pInfo
->
vgVer
=
dbCache
->
vgCache
.
vgInfo
->
vgVersion
;
pInfo
->
vgVer
=
dbCache
->
vgCache
.
vgInfo
->
vgVersion
;
pInfo
->
dbId
=
dbCache
->
dbId
;
pInfo
->
dbId
=
dbCache
->
dbId
;
pInfo
->
tbNum
=
dbCache
->
vgCache
.
vgInfo
->
numOfTable
;
pInfo
->
tbNum
=
dbCache
->
vgCache
.
vgInfo
->
numOfTable
;
ctgReleaseVgInfoToCache
(
pCtg
,
dbCache
);
dbCache
=
NULL
;
}
else
{
}
else
{
pInfo
->
vgVer
=
CTG_DEFAULT_INVALID_VERSION
;
pInfo
->
vgVer
=
CTG_DEFAULT_INVALID_VERSION
;
}
}
...
...
source/libs/catalog/src/ctgDbg.c
浏览文件 @
8f16cc08
...
@@ -19,7 +19,7 @@
...
@@ -19,7 +19,7 @@
#include "catalogInt.h"
#include "catalogInt.h"
extern
SCatalogMgmt
gCtgMgmt
;
extern
SCatalogMgmt
gCtgMgmt
;
SCtgDebug
gCTGDebug
=
{
0
};
SCtgDebug
gCTGDebug
=
{
.
lockEnable
=
true
,
.
apiEnable
=
true
};
void
ctgdUserCallback
(
SMetaData
*
pResult
,
void
*
param
,
int32_t
code
)
{
void
ctgdUserCallback
(
SMetaData
*
pResult
,
void
*
param
,
int32_t
code
)
{
ASSERT
(
*
(
int32_t
*
)
param
==
1
);
ASSERT
(
*
(
int32_t
*
)
param
==
1
);
...
...
source/libs/catalog/src/ctgUtil.c
浏览文件 @
8f16cc08
...
@@ -675,7 +675,8 @@ int32_t ctgCloneTableIndex(SArray* pIndex, SArray** pRes) {
...
@@ -675,7 +675,8 @@ int32_t ctgCloneTableIndex(SArray* pIndex, SArray** pRes) {
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
STableIndexInfo
*
pInfo
=
taosArrayGet
(
pIndex
,
i
);
STableIndexInfo
*
pInfo
=
taosArrayGet
(
pIndex
,
i
);
taosArrayPush
(
*
pRes
,
pInfo
);
pInfo
=
taosArrayPush
(
*
pRes
,
pInfo
);
pInfo
->
expr
=
strdup
(
pInfo
->
expr
);
}
}
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
8f16cc08
...
@@ -4128,12 +4128,14 @@ static const char* getSysDbName(ENodeType type) {
...
@@ -4128,12 +4128,14 @@ static const char* getSysDbName(ENodeType type) {
case
QUERY_NODE_SHOW_SNODES_STMT
:
case
QUERY_NODE_SHOW_SNODES_STMT
:
case
QUERY_NODE_SHOW_LICENCE_STMT
:
case
QUERY_NODE_SHOW_LICENCE_STMT
:
case
QUERY_NODE_SHOW_CLUSTER_STMT
:
case
QUERY_NODE_SHOW_CLUSTER_STMT
:
case
QUERY_NODE_SHOW_VARIABLE_STMT
:
return
TSDB_INFORMATION_SCHEMA_DB
;
return
TSDB_INFORMATION_SCHEMA_DB
;
case
QUERY_NODE_SHOW_CONNECTIONS_STMT
:
case
QUERY_NODE_SHOW_CONNECTIONS_STMT
:
case
QUERY_NODE_SHOW_QUERIES_STMT
:
case
QUERY_NODE_SHOW_QUERIES_STMT
:
case
QUERY_NODE_SHOW_TOPICS_STMT
:
case
QUERY_NODE_SHOW_TOPICS_STMT
:
case
QUERY_NODE_SHOW_STREAMS_STMT
:
case
QUERY_NODE_SHOW_STREAMS_STMT
:
case
QUERY_NODE_SHOW_TRANSACTIONS_STMT
:
case
QUERY_NODE_SHOW_TRANSACTIONS_STMT
:
case
QUERY_NODE_SHOW_APPS_STMT
:
return
TSDB_PERFORMANCE_SCHEMA_DB
;
return
TSDB_PERFORMANCE_SCHEMA_DB
;
default:
default:
break
;
break
;
...
@@ -4183,6 +4185,10 @@ static const char* getSysTableName(ENodeType type) {
...
@@ -4183,6 +4185,10 @@ static const char* getSysTableName(ENodeType type) {
return
TSDB_PERFS_TABLE_TOPICS
;
return
TSDB_PERFS_TABLE_TOPICS
;
case
QUERY_NODE_SHOW_TRANSACTIONS_STMT
:
case
QUERY_NODE_SHOW_TRANSACTIONS_STMT
:
return
TSDB_PERFS_TABLE_TRANS
;
return
TSDB_PERFS_TABLE_TRANS
;
case
QUERY_NODE_SHOW_VARIABLE_STMT
:
return
TSDB_INS_TABLE_CONFIGS
;
case
QUERY_NODE_SHOW_APPS_STMT
:
return
TSDB_PERFS_TABLE_APPS
;
default:
default:
break
;
break
;
}
}
...
@@ -5237,6 +5243,8 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
...
@@ -5237,6 +5243,8 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
case
QUERY_NODE_SHOW_CLUSTER_STMT
:
case
QUERY_NODE_SHOW_CLUSTER_STMT
:
case
QUERY_NODE_SHOW_TOPICS_STMT
:
case
QUERY_NODE_SHOW_TOPICS_STMT
:
case
QUERY_NODE_SHOW_TRANSACTIONS_STMT
:
case
QUERY_NODE_SHOW_TRANSACTIONS_STMT
:
case
QUERY_NODE_SHOW_VARIABLE_STMT
:
case
QUERY_NODE_SHOW_APPS_STMT
:
code
=
rewriteShow
(
pCxt
,
pQuery
);
code
=
rewriteShow
(
pCxt
,
pQuery
);
break
;
break
;
case
QUERY_NODE_CREATE_TABLE_STMT
:
case
QUERY_NODE_CREATE_TABLE_STMT
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录