Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
137a9eb6
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
137a9eb6
编写于
5月 24, 2023
作者:
D
dapan1121
提交者:
GitHub
5月 24, 2023
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #21455 from taosdata/enh/add_varchar_sma
fix: fix count var type error
上级
3b6c4697
bd45785d
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
206 addition
and
15 deletion
+206
-15
source/common/src/tdataformat.c
source/common/src/tdataformat.c
+45
-7
source/dnode/vnode/inc/vnode.h
source/dnode/vnode/inc/vnode.h
+1
-1
source/dnode/vnode/src/tsdb/tsdbRead.c
source/dnode/vnode/src/tsdb/tsdbRead.c
+11
-3
source/dnode/vnode/src/tsdb/tsdbReaderWriter.c
source/dnode/vnode/src/tsdb/tsdbReaderWriter.c
+1
-1
source/libs/executor/src/scanoperator.c
source/libs/executor/src/scanoperator.c
+3
-2
source/libs/function/src/builtinsimpl.c
source/libs/function/src/builtinsimpl.c
+1
-1
tests/system-test/2-query/count_null.py
tests/system-test/2-query/count_null.py
+144
-0
未找到文件。
source/common/src/tdataformat.c
浏览文件 @
137a9eb6
...
...
@@ -2441,7 +2441,7 @@ _exit:
int32_t
tColDataAddValueByDataBlock
(
SColData
*
pColData
,
int8_t
type
,
int32_t
bytes
,
int32_t
nRows
,
char
*
lengthOrbitmap
,
char
*
data
)
{
int32_t
code
=
0
;
if
(
data
==
NULL
)
{
if
(
data
==
NULL
)
{
for
(
int32_t
i
=
0
;
i
<
nRows
;
++
i
)
{
code
=
tColDataAppendValueImpl
[
pColData
->
flag
][
CV_FLAG_NONE
](
pColData
,
NULL
,
0
);
}
...
...
@@ -2455,8 +2455,9 @@ int32_t tColDataAddValueByDataBlock(SColData *pColData, int8_t type, int32_t byt
code
=
tColDataAppendValueImpl
[
pColData
->
flag
][
CV_FLAG_NULL
](
pColData
,
NULL
,
0
);
if
(
code
)
goto
_exit
;
}
else
{
if
(
ASSERT
(
varDataTLen
(
data
+
offset
)
<=
bytes
)){
uError
(
"var data length invalid, varDataTLen(data + offset):%d <= bytes:%d"
,
(
int
)
varDataTLen
(
data
+
offset
),
bytes
);
if
(
ASSERT
(
varDataTLen
(
data
+
offset
)
<=
bytes
))
{
uError
(
"var data length invalid, varDataTLen(data + offset):%d <= bytes:%d"
,
(
int
)
varDataTLen
(
data
+
offset
),
bytes
);
code
=
TSDB_CODE_INVALID_PARA
;
goto
_exit
;
}
...
...
@@ -3521,6 +3522,43 @@ static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, int64_t *sum
}
}
static
FORCE_INLINE
void
tColDataCalcSMAVarType
(
SColData
*
pColData
,
int64_t
*
sum
,
int64_t
*
max
,
int64_t
*
min
,
int16_t
*
numOfNull
)
{
*
(
uint64_t
*
)
sum
=
0
;
*
(
uint64_t
*
)
max
=
0
;
*
(
uint64_t
*
)
min
=
0
;
*
numOfNull
=
0
;
switch
(
pColData
->
flag
)
{
case
HAS_NONE
:
case
HAS_NULL
:
case
(
HAS_NONE
|
HAS_NULL
):
*
numOfNull
=
pColData
->
nVal
;
break
;
case
HAS_VALUE
:
*
numOfNull
=
0
;
break
;
case
(
HAS_VALUE
|
HAS_NULL
):
case
(
HAS_VALUE
|
HAS_NONE
):
for
(
int32_t
iVal
=
0
;
iVal
<
pColData
->
nVal
;
iVal
++
)
{
if
(
GET_BIT1
(
pColData
->
pBitMap
,
iVal
)
==
0
)
{
(
*
numOfNull
)
++
;
}
}
break
;
case
(
HAS_VALUE
|
HAS_NONE
|
HAS_NULL
):
for
(
int32_t
iVal
=
0
;
iVal
<
pColData
->
nVal
;
iVal
++
)
{
if
(
GET_BIT2
(
pColData
->
pBitMap
,
iVal
)
!=
2
)
{
(
*
numOfNull
)
++
;
}
}
break
;
default:
ASSERT
(
0
);
break
;
}
}
void
(
*
tColDataCalcSMA
[])(
SColData
*
pColData
,
int64_t
*
sum
,
int64_t
*
max
,
int64_t
*
min
,
int16_t
*
numOfNull
)
=
{
NULL
,
tColDataCalcSMABool
,
// TSDB_DATA_TYPE_BOOL
...
...
@@ -3530,14 +3568,14 @@ void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_
tColDataCalcSMABigInt
,
// TSDB_DATA_TYPE_BIGINT
tColDataCalcSMAFloat
,
// TSDB_DATA_TYPE_FLOAT
tColDataCalcSMADouble
,
// TSDB_DATA_TYPE_DOUBLE
NULL
,
// TSDB_DATA_TYPE_VARCHAR
tColDataCalcSMAVarType
,
// TSDB_DATA_TYPE_VARCHAR
tColDataCalcSMABigInt
,
// TSDB_DATA_TYPE_TIMESTAMP
NULL
,
// TSDB_DATA_TYPE_NCHAR
tColDataCalcSMAVarType
,
// TSDB_DATA_TYPE_NCHAR
tColDataCalcSMAUTinyInt
,
// TSDB_DATA_TYPE_UTINYINT
tColDataCalcSMATinyUSmallInt
,
// TSDB_DATA_TYPE_USMALLINT
tColDataCalcSMAUInt
,
// TSDB_DATA_TYPE_UINT
tColDataCalcSMAUBigInt
,
// TSDB_DATA_TYPE_UBIGINT
NULL
,
// TSDB_DATA_TYPE_JSON
tColDataCalcSMAVarType
,
// TSDB_DATA_TYPE_JSON
NULL
,
// TSDB_DATA_TYPE_VARBINARY
NULL
,
// TSDB_DATA_TYPE_DECIMAL
NULL
,
// TSDB_DATA_TYPE_BLOB
...
...
source/dnode/vnode/inc/vnode.h
浏览文件 @
137a9eb6
...
...
@@ -184,7 +184,7 @@ int32_t tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, void *pT
SSDataBlock
*
pResBlock
,
STsdbReader
**
ppReader
,
const
char
*
idstr
,
bool
countOnly
,
SHashObj
**
pIgnoreTables
);
void
tsdbReaderClose
(
STsdbReader
*
pReader
);
int32_t
tsdbNextDataBlock
(
STsdbReader
*
pReader
,
bool
*
hasNext
);
int32_t
tsdbRetrieveDatablockSMA
(
STsdbReader
*
pReader
,
SSDataBlock
*
pDataBlock
,
bool
*
allHave
);
int32_t
tsdbRetrieveDatablockSMA
(
STsdbReader
*
pReader
,
SSDataBlock
*
pDataBlock
,
bool
*
allHave
,
bool
*
hasNullSMA
);
void
tsdbReleaseDataBlock
(
STsdbReader
*
pReader
);
SSDataBlock
*
tsdbRetrieveDataBlock
(
STsdbReader
*
pTsdbReadHandle
,
SArray
*
pColumnIdList
);
int32_t
tsdbReaderReset
(
STsdbReader
*
pReader
,
SQueryTableDataCond
*
pCond
);
...
...
source/dnode/vnode/src/tsdb/tsdbRead.c
浏览文件 @
137a9eb6
...
...
@@ -4973,7 +4973,8 @@ int32_t tsdbNextDataBlock(STsdbReader* pReader, bool* hasNext) {
return
code
;
}
static
void
doFillNullColSMA
(
SBlockLoadSuppInfo
*
pSup
,
int32_t
numOfRows
,
int32_t
numOfCols
,
SColumnDataAgg
*
pTsAgg
)
{
static
bool
doFillNullColSMA
(
SBlockLoadSuppInfo
*
pSup
,
int32_t
numOfRows
,
int32_t
numOfCols
,
SColumnDataAgg
*
pTsAgg
)
{
bool
hasNullSMA
=
false
;
// do fill all null column value SMA info
int32_t
i
=
0
,
j
=
0
;
int32_t
size
=
(
int32_t
)
taosArrayGetSize
(
pSup
->
pColAgg
);
...
...
@@ -4993,6 +4994,7 @@ static void doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_
taosArrayInsert
(
pSup
->
pColAgg
,
i
,
&
nullColAgg
);
i
+=
1
;
size
++
;
hasNullSMA
=
true
;
}
j
+=
1
;
}
...
...
@@ -5003,12 +5005,15 @@ static void doFillNullColSMA(SBlockLoadSuppInfo* pSup, int32_t numOfRows, int32_
SColumnDataAgg
nullColAgg
=
{.
colId
=
pSup
->
colId
[
j
],
.
numOfNull
=
numOfRows
};
taosArrayInsert
(
pSup
->
pColAgg
,
i
,
&
nullColAgg
);
i
+=
1
;
hasNullSMA
=
true
;
}
j
++
;
}
return
hasNullSMA
;
}
int32_t
tsdbRetrieveDatablockSMA
(
STsdbReader
*
pReader
,
SSDataBlock
*
pDataBlock
,
bool
*
allHave
)
{
int32_t
tsdbRetrieveDatablockSMA
(
STsdbReader
*
pReader
,
SSDataBlock
*
pDataBlock
,
bool
*
allHave
,
bool
*
hasNullSMA
)
{
SColumnDataAgg
***
pBlockSMA
=
&
pDataBlock
->
pBlockAgg
;
int32_t
code
=
0
;
...
...
@@ -5072,7 +5077,10 @@ int32_t tsdbRetrieveDatablockSMA(STsdbReader* pReader, SSDataBlock* pDataBlock,
}
// do fill all null column value SMA info
doFillNullColSMA
(
pSup
,
pBlock
->
nRow
,
numOfCols
,
pTsAgg
);
if
(
doFillNullColSMA
(
pSup
,
pBlock
->
nRow
,
numOfCols
,
pTsAgg
))
{
*
hasNullSMA
=
true
;
return
TSDB_CODE_SUCCESS
;
}
size_t
size
=
taosArrayGetSize
(
pSup
->
pColAgg
);
int32_t
i
=
0
,
j
=
0
;
...
...
source/dnode/vnode/src/tsdb/tsdbReaderWriter.c
浏览文件 @
137a9eb6
...
...
@@ -523,7 +523,7 @@ static int32_t tsdbWriteBlockSma(SDataFWriter *pWriter, SBlockData *pBlockData,
for
(
int32_t
iColData
=
0
;
iColData
<
pBlockData
->
nColData
;
iColData
++
)
{
SColData
*
pColData
=
tBlockDataGetColDataByIdx
(
pBlockData
,
iColData
);
if
((
!
pColData
->
smaOn
)
||
IS_VAR_DATA_TYPE
(
pColData
->
type
)
||
((
pColData
->
flag
&
HAS_VALUE
)
==
0
))
continue
;
if
((
!
pColData
->
smaOn
)
||
((
pColData
->
flag
&
HAS_VALUE
)
==
0
))
continue
;
SColumnDataAgg
sma
=
{.
colId
=
pColData
->
cid
};
tColDataCalcSMA
[
pColData
->
type
](
pColData
,
&
sma
.
sum
,
&
sma
.
max
,
&
sma
.
min
,
&
sma
.
numOfNull
);
...
...
source/libs/executor/src/scanoperator.c
浏览文件 @
137a9eb6
...
...
@@ -228,12 +228,13 @@ static bool doFilterByBlockSMA(SFilterInfo* pFilterInfo, SColumnDataAgg** pColsA
static
bool
doLoadBlockSMA
(
STableScanBase
*
pTableScanInfo
,
SSDataBlock
*
pBlock
,
SExecTaskInfo
*
pTaskInfo
)
{
bool
allColumnsHaveAgg
=
true
;
int32_t
code
=
tsdbRetrieveDatablockSMA
(
pTableScanInfo
->
dataReader
,
pBlock
,
&
allColumnsHaveAgg
);
bool
hasNullSMA
=
false
;
int32_t
code
=
tsdbRetrieveDatablockSMA
(
pTableScanInfo
->
dataReader
,
pBlock
,
&
allColumnsHaveAgg
,
&
hasNullSMA
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
T_LONG_JMP
(
pTaskInfo
->
env
,
code
);
}
if
(
!
allColumnsHaveAgg
)
{
if
(
!
allColumnsHaveAgg
||
hasNullSMA
)
{
return
false
;
}
return
true
;
...
...
source/libs/function/src/builtinsimpl.c
浏览文件 @
137a9eb6
...
...
@@ -500,7 +500,7 @@ static int64_t getNumOfElems(SqlFunctionCtx* pCtx) {
*/
SInputColumnInfoData
*
pInput
=
&
pCtx
->
input
;
SColumnInfoData
*
pInputCol
=
pInput
->
pData
[
0
];
if
(
pInput
->
colDataSMAIsSet
&&
pInput
->
totalRows
==
pInput
->
numOfRows
&&
!
IS_VAR_DATA_TYPE
(
pInputCol
->
info
.
type
)
)
{
if
(
pInput
->
colDataSMAIsSet
&&
pInput
->
totalRows
==
pInput
->
numOfRows
)
{
numOfElem
=
pInput
->
numOfRows
-
pInput
->
pColumnDataAgg
[
0
]
->
numOfNull
;
}
else
{
if
(
pInputCol
->
hasNull
)
{
...
...
tests/system-test/2-query/count_null.py
0 → 100644
浏览文件 @
137a9eb6
import
taos
import
sys
from
util.log
import
*
from
util.sql
import
*
from
util.cases
import
*
class
TDTestCase
:
def
init
(
self
,
conn
,
logSql
,
replicaVar
=
1
):
self
.
replicaVar
=
int
(
replicaVar
)
tdLog
.
debug
(
f
"start to excute
{
__file__
}
"
)
#tdSql.init(conn.cursor())
tdSql
.
init
(
conn
.
cursor
(),
logSql
)
# output sql.txt file
def
check_results
(
self
):
tdSql
.
query
(
f
"select count(*) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c1) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c2) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c3) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c4) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c5) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c6) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c7) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c8) from tb1"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(*) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c1) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c2) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c3) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c4) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c5) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c6) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c7) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
0
)
tdSql
.
query
(
f
"select count(c8) from tb2"
)
tdSql
.
checkData
(
0
,
0
,
0
)
for
i
in
range
(
3
,
6
):
tdSql
.
query
(
f
"select count(*) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
20000
)
tdSql
.
query
(
f
"select count(c1) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
tdSql
.
query
(
f
"select count(c2) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
tdSql
.
query
(
f
"select count(c3) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
tdSql
.
query
(
f
"select count(c4) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
tdSql
.
query
(
f
"select count(c5) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
tdSql
.
query
(
f
"select count(c6) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
tdSql
.
query
(
f
"select count(c7) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
tdSql
.
query
(
f
"select count(c8) from tb
{
i
}
"
)
tdSql
.
checkData
(
0
,
0
,
10000
)
def
run
(
self
):
dbname
=
'db'
tbnames
=
[
'tb1'
,
'tb2'
,
'tb3'
,
'tb4'
,
'tb5'
,
'tb6'
]
num_rows
=
20000
num_tables
=
6
ts_base
=
1685548800000
tdSql
.
prepare
()
tdLog
.
printNoPrefix
(
"==========step1:create table"
)
for
i
in
range
(
num_tables
):
tdSql
.
execute
(
f
'''create table if not exists
{
dbname
}
.
{
tbnames
[
i
]
}
(ts timestamp, c0 tinyint, c1 smallint, c2 int, c3 bigint, c4 double, c5 float, c6 bool, c7 varchar(10), c8 nchar(10))
'''
)
tdLog
.
printNoPrefix
(
"==========step2:insert data"
)
for
i
in
range
(
num_rows
):
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
0
]
}
values (
{
ts_base
+
i
}
, null, null, null, null, null, null, null, null, null)"
)
for
i
in
range
(
num_rows
):
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
1
]
}
values (
{
ts_base
+
i
}
, 1, 1, 1, 1, 1, 1, 1, null, null)"
)
for
i
in
range
(
num_rows
):
if
i
%
2
==
0
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
2
]
}
values (
{
ts_base
+
i
}
, null, null, null, null, null, null, null, null, null)"
)
else
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
2
]
}
values (
{
ts_base
+
i
}
, 1, 1, 1, 1, 1, 1, 1, 'binary', 'nchar')"
)
for
i
in
range
(
num_rows
):
if
i
%
2
==
0
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
3
]
}
values (
{
ts_base
+
i
}
, null, null, null, null, null, null, null, 'binary', 'nchar')"
)
else
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
3
]
}
values (
{
ts_base
+
i
}
, 1, 1, 1, 1, 1, 1, 1, null, null)"
)
for
i
in
range
(
num_rows
):
if
i
<
num_rows
/
2
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
4
]
}
values (
{
ts_base
+
i
}
, null, null, null, null, null, null, null, null, null)"
)
else
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
4
]
}
values (
{
ts_base
+
i
}
, 1, 1, 1, 1, 1, 1, 1, 'binary', 'nchar')"
)
for
i
in
range
(
num_rows
):
if
i
>=
num_rows
/
2
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
5
]
}
values (
{
ts_base
+
i
}
, null, null, null, null, null, null, null, null, null)"
)
else
:
tdSql
.
execute
(
f
"insert into
{
dbname
}
.
{
tbnames
[
5
]
}
values (
{
ts_base
+
i
}
, 1, 1, 1, 1, 1, 1, 1, 'binary', 'nchar')"
)
tdLog
.
printNoPrefix
(
"==========step3:check result in memory"
)
self
.
check_results
();
tdLog
.
printNoPrefix
(
"==========step3:check result from disk"
)
tdSql
.
execute
(
f
"flush database db"
)
self
.
check_results
();
def
stop
(
self
):
tdSql
.
close
()
tdLog
.
success
(
f
"
{
__file__
}
successfully executed"
)
tdCases
.
addLinux
(
__file__
,
TDTestCase
())
tdCases
.
addWindows
(
__file__
,
TDTestCase
())
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录