Merge branch '3.0' of https://github.com/taosdata/TDengine into fix/TS-4331-3.0
This commit is contained in:
commit
9c5dbab91e
|
@ -459,7 +459,7 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
|
|||
:::info
|
||||
|
||||
- The result of a nested query is returned as a virtual table used by the outer query. It's recommended to give an alias to this table for the convenience of using it in the outer query.
|
||||
- Outer queries support directly referencing columns or pseudo-columns of inner queries in the form of column names or `column names`.
|
||||
- Outer queries support directly referencing columns or pseudo-columns of inner queries in the form of column names or \`column names\`.
|
||||
- JOIN operation is allowed between tables/STables inside both inner and outer queries. Join operation can be performed on the result set of the inner query.
|
||||
- The features that can be used in the inner query are the same as those that can be used in a non-nested query.
|
||||
- `ORDER BY` inside the inner query is unnecessary and will slow down the query performance significantly. It is best to avoid the use of `ORDER BY` inside the inner query.
|
||||
|
|
|
@ -18,7 +18,7 @@ description: This document describes the usage of escape characters in TDengine.
|
|||
|
||||
## Restrictions
|
||||
|
||||
1. If there are escape characters in identifiers (database name, table name, column name)
|
||||
1. If there are escape characters in identifiers (database name, table name, column name, alias Name)
|
||||
- Identifier without ``: Error will be returned because identifier must be constituted of digits, ASCII characters or underscore and can't be started with digits
|
||||
- Identifier quoted with ``: Original content is kept, no escaping
|
||||
2. If there are escape characters in values
|
||||
|
|
|
@ -459,7 +459,7 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
|
|||
:::info
|
||||
|
||||
- 内层查询的返回结果将作为“虚拟表”供外层查询使用,此虚拟表建议起别名,以便于外层查询中方便引用。
|
||||
- 外层查询支持直接通过列名或`列名`的形式引用内层查询的列或伪列。
|
||||
- 外层查询支持直接通过列名或\`列名\`的形式引用内层查询的列或伪列。
|
||||
- 在内层和外层查询中,都支持普通的表间/超级表间 JOIN。内层查询的计算结果也可以再参与数据子表的 JOIN 操作。
|
||||
- 内层查询支持的功能特性与非嵌套的查询语句能力是一致的。
|
||||
- 内层查询的 ORDER BY 子句一般没有意义,建议避免这样的写法以免无谓的资源消耗。
|
||||
|
|
|
@ -20,7 +20,7 @@ description: TDengine 中使用转义字符的详细规则
|
|||
|
||||
## 转义字符使用规则
|
||||
|
||||
1. 标识符里有转义字符(数据库名、表名、列名)
|
||||
1. 标识符里有转义字符(数据库名、表名、列名、别名)
|
||||
1. 普通标识符: 直接提示错误的标识符,因为标识符规定必须是数字、字母和下划线,并且不能以数字开头。
|
||||
2. 反引号``标识符: 保持原样,不转义
|
||||
2. 数据里有转义字符
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
## 3.3.2.0 版本说明
|
||||
|
||||
### 新特性
|
||||
|
||||
### 优化
|
||||
|
||||
### 修复问题
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
title: 3.3.2.0 版本说明
|
||||
sidebar_label: 3.3.2.0
|
||||
description: 3.3.2.0 版本说明
|
||||
---
|
||||
|
||||
### 新特性
|
||||
|
||||
### 优化
|
||||
|
||||
### 修复问题
|
|
@ -1759,6 +1759,7 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
tsdbRowMergerInit(pMerger, ps);
|
||||
}
|
||||
|
||||
SRowKey minKey = k;
|
||||
|
@ -1842,6 +1843,7 @@ static int32_t mergeFileBlockAndSttBlock(STsdbReader* pReader, SSttBlockReader*
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
tsdbRowMergerInit(pMerger, ps);
|
||||
}
|
||||
|
||||
bool dataInDataFile = hasDataInFileBlock(pBlockData, pDumpInfo);
|
||||
|
@ -1963,6 +1965,7 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
tsdbRowMergerInit(pMerger, ps);
|
||||
}
|
||||
|
||||
SRowKey minKey = k;
|
||||
|
@ -2326,6 +2329,7 @@ int32_t mergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pBloc
|
|||
if (ps == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
tsdbRowMergerInit(pMerger, ps);
|
||||
}
|
||||
|
||||
tRowKeyAssign(&pBlockScanInfo->lastProcKey, pKey);
|
||||
|
|
|
@ -3459,11 +3459,15 @@ static int32_t tagScanFilterByTagCond(SArray* aUidTags, SNode* pTagCond, SArray*
|
|||
SScalarParam output = {0};
|
||||
code = tagScanCreateResultData(&type, numOfTables, &output);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
blockDataDestroy(pResBlock);
|
||||
taosArrayDestroy(pBlockList);
|
||||
return code;
|
||||
}
|
||||
|
||||
code = scalarCalculate(pTagCond, pBlockList, &output);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
blockDataDestroy(pResBlock);
|
||||
taosArrayDestroy(pBlockList);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataTy
|
|||
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
|
||||
SNode* createNodeListNodeEx(SAstCreateContext* pCxt, SNode* p1, SNode* p2);
|
||||
SNode* createRealTableNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pTableName, SToken* pTableAlias);
|
||||
SNode* createTempTableNode(SAstCreateContext* pCxt, SNode* pSubquery, const SToken* pTableAlias);
|
||||
SNode* createTempTableNode(SAstCreateContext* pCxt, SNode* pSubquery, SToken* pTableAlias);
|
||||
SNode* createJoinTableNode(SAstCreateContext* pCxt, EJoinType type, EJoinSubType stype, SNode* pLeft, SNode* pRight,
|
||||
SNode* pJoinCond);
|
||||
SNode* createViewNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pViewName);
|
||||
|
|
|
@ -949,8 +949,11 @@ SNode* createRealTableNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pTa
|
|||
return (SNode*)realTable;
|
||||
}
|
||||
|
||||
SNode* createTempTableNode(SAstCreateContext* pCxt, SNode* pSubquery, const SToken* pTableAlias) {
|
||||
SNode* createTempTableNode(SAstCreateContext* pCxt, SNode* pSubquery, SToken* pTableAlias) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
if (!checkTableName(pCxt, pTableAlias)) {
|
||||
return NULL;
|
||||
}
|
||||
STempTableNode* tempTable = (STempTableNode*)nodesMakeNode(QUERY_NODE_TEMP_TABLE);
|
||||
CHECK_OUT_OF_MEM(tempTable);
|
||||
tempTable->pSubquery = pSubquery;
|
||||
|
|
|
@ -238,6 +238,9 @@ int32_t remoteChkp_readMetaData(char* path, SArray* list) {
|
|||
sprintf(metaPath, "%s%s%s", path, TD_DIRSEP, "META");
|
||||
|
||||
TdFilePtr pFile = taosOpenFile(path, TD_FILE_READ);
|
||||
if (pFile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buf[128] = {0};
|
||||
if (taosReadFile(pFile, buf, sizeof(buf)) <= 0) {
|
||||
|
@ -245,7 +248,8 @@ int32_t remoteChkp_readMetaData(char* path, SArray* list) {
|
|||
taosCloseFile(&pFile);
|
||||
return -1;
|
||||
}
|
||||
int32_t len = strlen(buf);
|
||||
|
||||
int32_t len = strnlen(buf, tListLen(buf));
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (buf[i] == '\n') {
|
||||
char* item = taosMemoryCalloc(1, i + 1);
|
||||
|
@ -2117,9 +2121,7 @@ void taskDbDestroy(void* pDb, bool flush) {
|
|||
|
||||
stDebug("succ to destroy stream backend:%p", wrapper);
|
||||
|
||||
int8_t nCf = sizeof(ginitDict) / sizeof(ginitDict[0]);
|
||||
|
||||
if (wrapper == NULL) return;
|
||||
int8_t nCf = tListLen(ginitDict);
|
||||
|
||||
if (flush) {
|
||||
if (wrapper->db && wrapper->pCf) {
|
||||
|
@ -4223,7 +4225,8 @@ int32_t dbChkpDumpTo(SDbChkp* p, char* dname, SArray* list) {
|
|||
|
||||
static char* chkpMeta = "META";
|
||||
memset(dstBuf, 0, len);
|
||||
sprintf(dstDir, "%s%s%s", dstDir, TD_DIRSEP, chkpMeta);
|
||||
sprintf(dstBuf, "%s%s%s", dstDir, TD_DIRSEP, chkpMeta);
|
||||
memcpy(dstDir, dstBuf, strlen(dstBuf));
|
||||
|
||||
TdFilePtr pFile = taosOpenFile(dstDir, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
|
||||
if (pFile == NULL) {
|
||||
|
|
|
@ -312,17 +312,12 @@ int32_t streamSnapHandleInit(SStreamSnapHandle* pHandle, char* path, void* pMeta
|
|||
ASSERT(code == 0);
|
||||
taosArrayPush(pDbSnapSet, &snapFile);
|
||||
}
|
||||
|
||||
pHandle->pDbSnapSet = pDbSnapSet;
|
||||
pHandle->pSnapInfoSet = pSnapInfoSet;
|
||||
pHandle->currIdx = 0;
|
||||
pHandle->pMeta = pMeta;
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
streamSnapHandleDestroy(pHandle);
|
||||
|
||||
code = -1;
|
||||
return code;
|
||||
}
|
||||
|
||||
void streamSnapHandleDestroy(SStreamSnapHandle* handle) {
|
||||
|
@ -444,6 +439,7 @@ _NEXT:
|
|||
pSnapFile = taosArrayGet(pHandle->pDbSnapSet, pHandle->currIdx);
|
||||
goto _NEXT;
|
||||
} else {
|
||||
taosMemoryFree(buf);
|
||||
*ppData = NULL;
|
||||
*size = 0;
|
||||
return 0;
|
||||
|
@ -465,7 +461,9 @@ _NEXT:
|
|||
pHdr->totalSize = item->size;
|
||||
pHdr->snapInfo = pSnapFile->snapInfo;
|
||||
|
||||
memcpy(pHdr->name, item->name, strlen(item->name));
|
||||
int32_t len = TMIN(strlen(item->name), tListLen(pHdr->name));
|
||||
memcpy(pHdr->name, item->name, len);
|
||||
|
||||
pSnapFile->seraial += nread;
|
||||
|
||||
*ppData = buf;
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
|
||||
import taos
|
||||
import frame
|
||||
import frame.etool
|
||||
|
||||
|
||||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.caseBase import *
|
||||
from frame import *
|
||||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
|
||||
# fix
|
||||
def FIX_TD_30686(self):
|
||||
tdLog.info("check bug TD_30686 ...\n")
|
||||
sqls = [
|
||||
"create database db",
|
||||
"create table db.st(ts timestamp, age int) tags(area tinyint);",
|
||||
"insert into db.t1 using db.st tags(100) values('2024-01-01 10:00:01', 1);",
|
||||
"insert into db.t2 using db.st tags(110) values('2024-01-01 10:00:02', 2);",
|
||||
"insert into db.t3 using db.st tags(3) values('2024-01-01 10:00:03', 3);"
|
||||
]
|
||||
tdSql.executes(sqls)
|
||||
|
||||
sql = "select * from db.st where area < 139 order by ts;"
|
||||
results = [
|
||||
["2024-01-01 10:00:01", 1, 100],
|
||||
["2024-01-01 10:00:02", 2, 110],
|
||||
["2024-01-01 10:00:03", 3, 3]
|
||||
]
|
||||
tdSql.checkDataMem(sql, results)
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
|
||||
# TD BUGS
|
||||
self.FIX_TD_30686()
|
||||
|
||||
# TS BUGS
|
||||
|
||||
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -34,6 +34,7 @@
|
|||
,,y,army,./pytest.sh python3 ./test.py -f storage/oneStageComp.py -N 3 -L 3 -D 1
|
||||
,,y,army,./pytest.sh python3 ./test.py -f storage/compressBasic.py -N 3
|
||||
,,y,army,./pytest.sh python3 ./test.py -f grant/grantBugs.py -N 3
|
||||
,,y,army,./pytest.sh python3 ./test.py -f query/queryBugs.py -N 3
|
||||
|
||||
#
|
||||
# system test
|
||||
|
|
|
@ -26,6 +26,8 @@ class TDTestCase:
|
|||
self.dbname = 'db'
|
||||
self.setsql = TDSetSql()
|
||||
self.stbname = 'stb'
|
||||
self.ntbname1 = 'ntb1'
|
||||
self.ntbname2 = 'ntb2'
|
||||
self.streamname = 'stm'
|
||||
self.streamtb = 'stm_stb'
|
||||
def topic_name_check(self):
|
||||
|
@ -74,11 +76,33 @@ class TDTestCase:
|
|||
tdSql.checkEqual(tdSql.queryResult[0][0],self.streamname)
|
||||
tdSql.execute(f'drop stream `{self.streamname}`')
|
||||
tdSql.execute(f'drop database {self.dbname}')
|
||||
|
||||
|
||||
def table_name_check(self):
|
||||
tdSql.execute(f'create database if not exists {self.dbname} wal_retention_period 3600')
|
||||
tdSql.execute(f'use {self.dbname}')
|
||||
tdSql.execute(f'create table {self.ntbname1} (ts timestamp,c0 int,c1 int)')
|
||||
tdSql.execute(f'create table {self.ntbname2} (ts timestamp,c0 int,c1 int)')
|
||||
tdSql.execute(f'insert into {self.ntbname1} values(now(),1,1)')
|
||||
tdSql.execute(f'insert into {self.ntbname2} values(now(),2,2)')
|
||||
tdSql.query(f'select `{self.ntbname1}`.`c0`, `{self.ntbname1}`.`c1` from `{self.ntbname1}`')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0], 1)
|
||||
tdSql.query(f'select `{self.ntbname1}`.`c0`, `{self.ntbname1}`.`c1` from `{self.dbname}`.`{self.ntbname1}`')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0], 1)
|
||||
tdSql.query(f'select `{self.ntbname1}`.`c0` from `{self.ntbname2}` `{self.ntbname1}`')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0], 2)
|
||||
tdSql.query(f'select `{self.ntbname1}`.`c0` from (select * from `{self.ntbname2}`) `{self.ntbname1}`')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0], 2)
|
||||
# select `t1`.`col1`, `col2`, `col3` from (select ts `col1`, 123 `col2`, c0 + c1 as `col3` from t2) `t1`;
|
||||
tdSql.query(f'select `{self.ntbname1}`.`col1`, `col2`, `col3` from (select ts `col1`, 123 `col2`, c0 + c1 as `col3` from {self.ntbname2}) `{self.ntbname1}`')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][1], 123)
|
||||
tdSql.checkEqual(tdSql.queryResult[0][2], 4)
|
||||
|
||||
tdSql.execute(f'drop database {self.dbname}')
|
||||
def run(self):
|
||||
self.topic_name_check()
|
||||
self.db_name_check()
|
||||
self.stream_name_check()
|
||||
self.table_name_check()
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
|
Loading…
Reference in New Issue