Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
85d3a7a2
T
TDengine
项目概览
慢慢CG
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
85d3a7a2
编写于
6月 07, 2021
作者:
H
haojun Liao
提交者:
GitHub
6月 07, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #6386 from taosdata/feature/TD-4426
Feature/td 4426
上级
78fd1fcc
b645bb4f
变更
10
显示空白变更内容
内联
并排
Showing
10 changed file
with
425 addition
and
27 deletion
+425
-27
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+137
-4
src/common/inc/texpr.h
src/common/inc/texpr.h
+2
-0
src/common/src/texpr.c
src/common/src/texpr.c
+26
-0
src/query/inc/qExecutor.h
src/query/inc/qExecutor.h
+1
-0
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+7
-0
src/query/src/qFilterfunc.c
src/query/src/qFilterfunc.c
+23
-0
src/tsdb/src/tsdbRead.c
src/tsdb/src/tsdbRead.c
+53
-8
src/util/src/tcompare.c
src/util/src/tcompare.c
+8
-4
tests/pytest/query/in.py
tests/pytest/query/in.py
+163
-0
tests/script/general/parser/where.sim
tests/script/general/parser/where.sim
+5
-11
未找到文件。
src/client/src/tscSQLParser.c
浏览文件 @
85d3a7a2
...
...
@@ -63,6 +63,9 @@ static SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int3
static
int32_t
setShowInfo
(
SSqlObj
*
pSql
,
SSqlInfo
*
pInfo
);
static
char
*
getAccountId
(
SSqlObj
*
pSql
);
static
bool
serializeExprListToVariant
(
SArray
*
pList
,
tVariant
**
dest
,
int16_t
colType
);
static
int32_t
validateParamOfRelationIn
(
tVariant
*
pVar
,
int32_t
colType
);
static
bool
has
(
SArray
*
pFieldList
,
int32_t
startIdx
,
const
char
*
name
);
static
char
*
cloneCurrentDBName
(
SSqlObj
*
pSql
);
static
int32_t
getDelimiterIndex
(
SStrToken
*
pTableName
);
...
...
@@ -138,10 +141,93 @@ static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) {
return
pQueryInfo
->
interval
.
interval
>
0
||
pQueryInfo
->
sessionWindow
.
gap
>
0
;
}
int16_t
getNewResColId
(
SSqlCmd
*
pCmd
)
{
return
pCmd
->
resColumnId
--
;
}
// serialize expr in exprlist to binary
// formate "type | size | value"
bool
serializeExprListToVariant
(
SArray
*
pList
,
tVariant
**
dst
,
int16_t
colType
)
{
bool
ret
=
false
;
if
(
!
pList
||
pList
->
size
<=
0
)
{
return
ret
;
}
if
(
colType
==
TSDB_DATA_TYPE_DOUBLE
||
colType
==
TSDB_DATA_TYPE_FLOAT
)
{
return
ret
;
}
tSqlExprItem
*
item
=
(
tSqlExprItem
*
)
taosArrayGet
(
pList
,
0
);
int32_t
firstTokenType
=
item
->
pNode
->
token
.
type
;
int32_t
type
=
firstTokenType
;
//nchar to binary and
toTSDBType
(
type
);
if
(
type
!=
colType
&&
(
type
!=
TSDB_DATA_TYPE_BINARY
||
colType
!=
TSDB_DATA_TYPE_NCHAR
))
{
return
false
;
}
type
=
colType
;
SBufferWriter
bw
=
tbufInitWriter
(
NULL
,
false
);
tbufEnsureCapacity
(
&
bw
,
512
);
int32_t
size
=
(
int32_t
)(
pList
->
size
);
tbufWriteUint32
(
&
bw
,
type
);
tbufWriteInt32
(
&
bw
,
size
);
for
(
int32_t
i
=
0
;
i
<
size
;
i
++
)
{
tSqlExpr
*
pSub
=
((
tSqlExprItem
*
)(
taosArrayGet
(
pList
,
i
)))
->
pNode
;
// check all the token type in expr list same or not
if
(
firstTokenType
!=
pSub
->
token
.
type
)
{
break
;
}
toTSDBType
(
pSub
->
token
.
type
);
tVariant
var
;
tVariantCreate
(
&
var
,
&
pSub
->
token
);
if
(
type
==
TSDB_DATA_TYPE_BOOL
||
type
==
TSDB_DATA_TYPE_TINYINT
||
type
==
TSDB_DATA_TYPE_SMALLINT
||
type
==
TSDB_DATA_TYPE_BIGINT
||
type
==
TSDB_DATA_TYPE_INT
)
{
tbufWriteInt64
(
&
bw
,
var
.
i64
);
}
else
if
(
type
==
TSDB_DATA_TYPE_DOUBLE
||
type
==
TSDB_DATA_TYPE_FLOAT
)
{
tbufWriteDouble
(
&
bw
,
var
.
dKey
);
}
else
if
(
type
==
TSDB_DATA_TYPE_BINARY
){
tbufWriteBinary
(
&
bw
,
var
.
pz
,
var
.
nLen
);
}
else
if
(
type
==
TSDB_DATA_TYPE_NCHAR
)
{
char
*
buf
=
(
char
*
)
calloc
(
1
,
(
var
.
nLen
+
1
)
*
TSDB_NCHAR_SIZE
);
if
(
tVariantDump
(
&
var
,
buf
,
type
,
false
)
!=
TSDB_CODE_SUCCESS
)
{
free
(
buf
);
tVariantDestroy
(
&
var
);
break
;
}
tbufWriteBinary
(
&
bw
,
buf
,
twcslen
((
wchar_t
*
)
buf
)
*
TSDB_NCHAR_SIZE
);
free
(
buf
);
}
tVariantDestroy
(
&
var
);
if
(
i
==
size
-
1
)
{
ret
=
true
;}
}
if
(
ret
==
true
)
{
if
((
*
dst
=
calloc
(
1
,
sizeof
(
tVariant
)))
!=
NULL
)
{
tVariantCreateFromBinary
(
*
dst
,
tbufGetData
(
&
bw
,
false
),
tbufTell
(
&
bw
),
TSDB_DATA_TYPE_BINARY
);
}
else
{
ret
=
false
;
}
}
tbufCloseWriter
(
&
bw
);
return
ret
;
}
static
int32_t
validateParamOfRelationIn
(
tVariant
*
pVar
,
int32_t
colType
)
{
if
(
pVar
->
nType
!=
TSDB_DATA_TYPE_BINARY
)
{
return
-
1
;
}
SBufferReader
br
=
tbufInitReader
(
pVar
->
pz
,
pVar
->
nLen
,
false
);
return
colType
==
TSDB_DATA_TYPE_NCHAR
?
0
:
(
tbufReadUint32
(
&
br
)
==
colType
?
0
:
-
1
);
}
static
uint8_t
convertOptr
(
SStrToken
*
pToken
)
{
switch
(
pToken
->
type
)
{
case
TK_LT
:
...
...
@@ -162,6 +248,7 @@ static uint8_t convertOptr(SStrToken *pToken) {
return
TSDB_RELATION_EQUAL
;
case
TK_PLUS
:
return
TSDB_BINARY_OP_ADD
;
case
TK_MINUS
:
return
TSDB_BINARY_OP_SUBTRACT
;
case
TK_STAR
:
...
...
@@ -177,6 +264,8 @@ static uint8_t convertOptr(SStrToken *pToken) {
return
TSDB_RELATION_ISNULL
;
case
TK_NOTNULL
:
return
TSDB_RELATION_NOTNULL
;
case
TK_IN
:
return
TSDB_RELATION_IN
;
default:
{
return
0
;
}
}
}
...
...
@@ -3229,6 +3318,25 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
retVal
=
tVariantDump
(
&
pRight
->
value
,
(
char
*
)
&
pColumnFilter
->
upperBndd
,
colType
,
false
);
// TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
}
else
if
(
pExpr
->
tokenId
==
TK_IN
)
{
tVariant
*
pVal
;
if
(
pRight
->
tokenId
!=
TK_SET
||
!
serializeExprListToVariant
(
pRight
->
pParam
,
&
pVal
,
colType
)
||
colType
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg
);
}
if
(
validateParamOfRelationIn
(
pVal
,
colType
)
!=
TSDB_CODE_SUCCESS
)
{
tVariantDestroy
(
pVal
);
free
(
pVal
);
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg
);
}
pColumnFilter
->
pz
=
(
int64_t
)
calloc
(
1
,
pVal
->
nLen
+
1
);
pColumnFilter
->
len
=
pVal
->
nLen
;
pColumnFilter
->
filterstr
=
1
;
memcpy
((
char
*
)(
pColumnFilter
->
pz
),
(
char
*
)(
pVal
->
pz
),
pVal
->
nLen
);
//retVal = tVariantDump(pVal, (char *)(pColumnFilter->pz), TSDB_DATA_TYPE_BINARY, false);
tVariantDestroy
(
pVal
);
free
(
pVal
);
}
else
if
(
colType
==
TSDB_DATA_TYPE_BINARY
)
{
pColumnFilter
->
pz
=
(
int64_t
)
calloc
(
1
,
bufLen
*
TSDB_NCHAR_SIZE
);
pColumnFilter
->
len
=
pRight
->
value
.
nLen
;
...
...
@@ -3277,6 +3385,9 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
case
TK_NOTNULL
:
pColumnFilter
->
lowerRelOptr
=
TSDB_RELATION_NOTNULL
;
break
;
case
TK_IN
:
pColumnFilter
->
lowerRelOptr
=
TSDB_RELATION_IN
;
break
;
default:
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg
);
}
...
...
@@ -3392,7 +3503,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC
&&
pExpr
->
tokenId
!=
TK_ISNULL
&&
pExpr
->
tokenId
!=
TK_NOTNULL
&&
pExpr
->
tokenId
!=
TK_LIKE
)
{
&&
pExpr
->
tokenId
!=
TK_IN
)
{
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
}
}
else
{
...
...
@@ -3402,7 +3513,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC
if
(
pSchema
->
type
==
TSDB_DATA_TYPE_BOOL
)
{
int32_t
t
=
pExpr
->
tokenId
;
if
(
t
!=
TK_EQ
&&
t
!=
TK_NE
&&
t
!=
TK_NOTNULL
&&
t
!=
TK_ISNULL
)
{
if
(
t
!=
TK_EQ
&&
t
!=
TK_NE
&&
t
!=
TK_NOTNULL
&&
t
!=
TK_ISNULL
&&
t
!=
TK_IN
)
{
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg3
);
}
}
...
...
@@ -4444,8 +4555,12 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
free
(
tmp
);
}
else
{
double
tmp
;
if
(
p
->
_node
.
optr
==
TSDB_RELATION_IN
)
{
retVal
=
validateParamOfRelationIn
(
vVariant
,
schemaType
);
}
else
{
retVal
=
tVariantDump
(
vVariant
,
(
char
*
)
&
tmp
,
schemaType
,
false
);
}
}
if
(
retVal
!=
TSDB_CODE_SUCCESS
)
{
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
...
...
@@ -7953,6 +8068,24 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
}
return
TSDB_CODE_SUCCESS
;
}
else
if
(
pSqlExpr
->
tokenId
==
TK_SET
)
{
int32_t
type
=
-
1
;
STableMeta
*
pTableMeta
=
tscGetMetaInfo
(
pQueryInfo
,
0
)
->
pTableMeta
;
if
(
pCols
!=
NULL
)
{
SColIndex
*
idx
=
taosArrayGet
(
pCols
,
0
);
SSchema
*
pSchema
=
tscGetTableColumnSchema
(
pTableMeta
,
idx
->
colIndex
);
if
(
pSchema
!=
NULL
)
{
type
=
pSchema
->
type
;
}
}
tVariant
*
pVal
;
if
(
serializeExprListToVariant
(
pSqlExpr
->
pParam
,
&
pVal
,
type
)
==
false
)
{
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
"not support filter expression"
);
}
*
pExpr
=
calloc
(
1
,
sizeof
(
tExprNode
));
(
*
pExpr
)
->
nodeType
=
TSQL_NODE_VALUE
;
(
*
pExpr
)
->
pVal
=
pVal
;
}
else
{
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
"not support filter expression"
);
}
...
...
src/common/inc/texpr.h
浏览文件 @
85d3a7a2
...
...
@@ -94,6 +94,8 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp
void
arithmeticTreeTraverse
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
char
*
pOutput
,
void
*
param
,
int32_t
order
,
char
*
(
*
cb
)(
void
*
,
const
char
*
,
int32_t
));
void
buildFilterSetFromBinary
(
void
**
q
,
const
char
*
buf
,
int32_t
len
);
#ifdef __cplusplus
}
#endif
...
...
src/common/src/texpr.c
浏览文件 @
85d3a7a2
...
...
@@ -466,6 +466,32 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
return
expr
;
}
void
buildFilterSetFromBinary
(
void
**
q
,
const
char
*
buf
,
int32_t
len
)
{
SBufferReader
br
=
tbufInitReader
(
buf
,
len
,
false
);
uint32_t
type
=
tbufReadUint32
(
&
br
);
SHashObj
*
pObj
=
taosHashInit
(
256
,
taosGetDefaultHashFunction
(
type
),
true
,
false
);
int
dummy
=
-
1
;
int32_t
sz
=
tbufReadInt32
(
&
br
);
for
(
int32_t
i
=
0
;
i
<
sz
;
i
++
)
{
if
(
type
==
TSDB_DATA_TYPE_BOOL
||
type
==
TSDB_DATA_TYPE_TINYINT
||
type
==
TSDB_DATA_TYPE_SMALLINT
||
type
==
TSDB_DATA_TYPE_BIGINT
||
type
==
TSDB_DATA_TYPE_INT
)
{
int64_t
val
=
tbufReadInt64
(
&
br
);
taosHashPut
(
pObj
,
(
char
*
)
&
val
,
sizeof
(
val
),
&
dummy
,
sizeof
(
dummy
));
}
else
if
(
type
==
TSDB_DATA_TYPE_DOUBLE
||
type
==
TSDB_DATA_TYPE_FLOAT
)
{
double
val
=
tbufReadDouble
(
&
br
);
taosHashPut
(
pObj
,
(
char
*
)
&
val
,
sizeof
(
val
),
&
dummy
,
sizeof
(
dummy
));
}
else
if
(
type
==
TSDB_DATA_TYPE_BINARY
)
{
size_t
t
=
0
;
const
char
*
val
=
tbufReadBinary
(
&
br
,
&
t
);
taosHashPut
(
pObj
,
(
char
*
)
val
,
t
,
&
dummy
,
sizeof
(
dummy
));
}
else
if
(
type
==
TSDB_DATA_TYPE_NCHAR
)
{
size_t
t
=
0
;
const
char
*
val
=
tbufReadBinary
(
&
br
,
&
t
);
taosHashPut
(
pObj
,
(
char
*
)
val
,
t
,
&
dummy
,
sizeof
(
dummy
));
}
}
*
q
=
(
void
*
)
pObj
;
}
tExprNode
*
exprdup
(
tExprNode
*
pNode
)
{
if
(
pNode
==
NULL
)
{
return
NULL
;
...
...
src/query/inc/qExecutor.h
浏览文件 @
85d3a7a2
...
...
@@ -113,6 +113,7 @@ typedef struct SColumnFilterElem {
int16_t
bytes
;
// column length
__filter_func_t
fp
;
SColumnFilterInfo
filterInfo
;
void
*
q
;
}
SColumnFilterElem
;
typedef
struct
SSingleColumnFilterInfo
{
...
...
src/query/src/qExecutor.c
浏览文件 @
85d3a7a2
...
...
@@ -6942,6 +6942,10 @@ int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfF
}
pSingleColFilter
->
bytes
=
pCols
[
i
].
bytes
;
if
(
lower
==
TSDB_RELATION_IN
)
{
buildFilterSetFromBinary
(
&
pSingleColFilter
->
q
,
(
char
*
)(
pSingleColFilter
->
filterInfo
.
pz
),
(
int32_t
)(
pSingleColFilter
->
filterInfo
.
len
));
}
}
j
++
;
...
...
@@ -6954,6 +6958,9 @@ int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfF
void
*
doDestroyFilterInfo
(
SSingleColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilterCols
)
{
for
(
int32_t
i
=
0
;
i
<
numOfFilterCols
;
++
i
)
{
if
(
pFilterInfo
[
i
].
numOfFilters
>
0
)
{
if
(
pFilterInfo
[
i
].
pFilters
->
filterInfo
.
lowerRelOptr
==
TSDB_RELATION_IN
)
{
taosHashCleanup
((
SHashObj
*
)(
pFilterInfo
[
i
].
pFilters
->
q
));
}
tfree
(
pFilterInfo
[
i
].
pFilters
);
}
}
...
...
src/query/src/qFilterfunc.c
浏览文件 @
85d3a7a2
...
...
@@ -253,6 +253,27 @@ bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char*
bool
notNullOperator
(
SColumnFilterElem
*
pFilter
,
const
char
*
minval
,
const
char
*
maxval
,
int16_t
type
)
{
return
true
;
}
bool
inOperator
(
SColumnFilterElem
*
pFilter
,
const
char
*
minval
,
const
char
*
maxval
,
int16_t
type
)
{
if
(
type
==
TSDB_DATA_TYPE_BOOL
||
type
==
TSDB_DATA_TYPE_TINYINT
||
type
==
TSDB_DATA_TYPE_SMALLINT
||
type
==
TSDB_DATA_TYPE_BIGINT
||
type
==
TSDB_DATA_TYPE_INT
)
{
int64_t
minv
=
-
1
,
maxv
=
-
1
;
GET_TYPED_DATA
(
minv
,
int64_t
,
type
,
minval
);
GET_TYPED_DATA
(
maxv
,
int64_t
,
type
,
maxval
);
if
(
minv
==
maxv
)
{
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pFilter
->
q
,
(
char
*
)
&
minv
,
sizeof
(
minv
));
}
return
true
;
}
else
if
(
type
==
TSDB_DATA_TYPE_DOUBLE
||
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
double
v
;
GET_TYPED_DATA
(
v
,
double
,
type
,
minval
);
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pFilter
->
q
,
(
char
*
)
&
v
,
sizeof
(
v
));
}
else
if
(
type
==
TSDB_DATA_TYPE_BINARY
)
{
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pFilter
->
q
,
varDataVal
(
minval
),
varDataLen
(
minval
));
}
else
if
(
type
==
TSDB_DATA_TYPE_NCHAR
){
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pFilter
->
q
,
varDataVal
(
minval
),
varDataLen
(
minval
));
}
return
false
;
}
///////////////////////////////////////////////////////////////////////////////
bool
rangeFilter_ii
(
SColumnFilterElem
*
pFilter
,
const
char
*
minval
,
const
char
*
maxval
,
int16_t
type
)
{
...
...
@@ -389,6 +410,7 @@ bool (*filterOperators[])(SColumnFilterElem *pFilter, const char* minval, const
likeOperator
,
isNullOperator
,
notNullOperator
,
inOperator
,
};
bool
(
*
rangeFilterOperators
[])(
SColumnFilterElem
*
pFilter
,
const
char
*
minval
,
const
char
*
maxval
,
int16_t
type
)
=
{
...
...
@@ -397,6 +419,7 @@ bool (*rangeFilterOperators[])(SColumnFilterElem *pFilter, const char* minval, c
rangeFilter_ie
,
rangeFilter_ei
,
rangeFilter_ii
,
};
__filter_func_t
getFilterOperator
(
int32_t
lowerOptr
,
int32_t
upperOptr
)
{
...
...
src/tsdb/src/tsdbRead.c
浏览文件 @
85d3a7a2
...
...
@@ -2397,6 +2397,8 @@ static void destroyHelper(void* param) {
tQueryInfo
*
pInfo
=
(
tQueryInfo
*
)
param
;
if
(
pInfo
->
optr
!=
TSDB_RELATION_IN
)
{
tfree
(
pInfo
->
q
);
}
else
{
taosHashCleanup
((
SHashObj
*
)(
pInfo
->
q
));
}
free
(
param
);
...
...
@@ -3155,11 +3157,23 @@ void filterPrepare(void* expr, void* param) {
pInfo
->
sch
=
*
pSchema
;
pInfo
->
optr
=
pExpr
->
_node
.
optr
;
pInfo
->
compare
=
getComparFunc
(
p
Schema
->
type
,
pInfo
->
optr
);
pInfo
->
compare
=
getComparFunc
(
p
Info
->
sch
.
type
,
pInfo
->
optr
);
pInfo
->
indexed
=
pTSSchema
->
columns
->
colId
==
pInfo
->
sch
.
colId
;
if
(
pInfo
->
optr
==
TSDB_RELATION_IN
)
{
pInfo
->
q
=
(
char
*
)
pCond
->
arr
;
int
dummy
=
-
1
;
SHashObj
*
pObj
=
NULL
;
if
(
pInfo
->
sch
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
pObj
=
taosHashInit
(
256
,
taosGetDefaultHashFunction
(
pInfo
->
sch
.
type
),
true
,
false
);
SArray
*
arr
=
(
SArray
*
)(
pCond
->
arr
);
for
(
size_t
i
=
0
;
i
<
taosArrayGetSize
(
arr
);
i
++
)
{
char
*
p
=
taosArrayGetP
(
arr
,
i
);
taosHashPut
(
pObj
,
varDataVal
(
p
),
varDataLen
(
p
),
&
dummy
,
sizeof
(
dummy
));
}
}
else
{
buildFilterSetFromBinary
((
void
**
)
&
pObj
,
pCond
->
pz
,
pCond
->
nLen
);
}
pInfo
->
q
=
(
char
*
)
pObj
;
}
else
if
(
pCond
!=
NULL
)
{
uint32_t
size
=
pCond
->
nLen
*
TSDB_NCHAR_SIZE
;
if
(
size
<
(
uint32_t
)
pSchema
->
bytes
)
{
...
...
@@ -3330,6 +3344,20 @@ static bool tableFilterFp(const void* pNode, void* param) {
}
else
if
(
pInfo
->
optr
==
TSDB_RELATION_NOTNULL
)
{
return
(
val
!=
NULL
)
&&
(
!
isNull
(
val
,
pInfo
->
sch
.
type
));
}
}
else
if
(
pInfo
->
optr
==
TSDB_RELATION_IN
)
{
int
type
=
pInfo
->
sch
.
type
;
if
(
type
==
TSDB_DATA_TYPE_BOOL
||
type
==
TSDB_DATA_TYPE_TINYINT
||
type
==
TSDB_DATA_TYPE_SMALLINT
||
type
==
TSDB_DATA_TYPE_BIGINT
||
type
==
TSDB_DATA_TYPE_INT
)
{
int64_t
v
;
GET_TYPED_DATA
(
v
,
int64_t
,
pInfo
->
sch
.
type
,
val
);
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pInfo
->
q
,
(
char
*
)
&
v
,
sizeof
(
v
));
}
else
if
(
type
==
TSDB_DATA_TYPE_DOUBLE
||
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
double
v
;
GET_TYPED_DATA
(
v
,
double
,
pInfo
->
sch
.
type
,
val
);
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pInfo
->
q
,
(
char
*
)
&
v
,
sizeof
(
v
));
}
else
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
){
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pInfo
->
q
,
varDataVal
(
val
),
varDataLen
(
val
));
}
}
int32_t
ret
=
0
;
...
...
@@ -3679,7 +3707,11 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
pCond
->
end
=
calloc
(
1
,
sizeof
(
SEndPoint
));
pCond
->
end
->
optr
=
queryColInfo
->
optr
;
pCond
->
end
->
v
=
queryColInfo
->
q
;
}
else
if
(
optr
==
TSDB_RELATION_IN
||
optr
==
TSDB_RELATION_LIKE
)
{
}
else
if
(
optr
==
TSDB_RELATION_IN
)
{
pCond
->
start
=
calloc
(
1
,
sizeof
(
SEndPoint
));
pCond
->
start
->
optr
=
queryColInfo
->
optr
;
pCond
->
start
->
v
=
queryColInfo
->
q
;
}
else
if
(
optr
==
TSDB_RELATION_LIKE
)
{
assert
(
0
);
}
...
...
@@ -3764,6 +3796,19 @@ static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SAr
taosArrayPush
(
result
,
&
info
);
}
}
else
if
(
optr
==
TSDB_RELATION_IN
)
{
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
int32_t
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
);
if
(
ret
!=
0
)
{
break
;
}
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
else
{
assert
(
0
);
}
...
...
@@ -3857,7 +3902,7 @@ void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *re
param
->
setupInfoFn
(
pExpr
,
param
->
pExtInfo
);
tQueryInfo
*
pQueryInfo
=
pExpr
->
_node
.
info
;
if
(
pQueryInfo
->
indexed
&&
pQueryInfo
->
optr
!=
TSDB_RELATION_LIKE
)
{
if
(
pQueryInfo
->
indexed
&&
(
pQueryInfo
->
optr
!=
TSDB_RELATION_LIKE
&&
pQueryInfo
->
optr
!=
TSDB_RELATION_IN
)
)
{
queryIndexedColumn
(
pSkipList
,
pQueryInfo
,
result
);
}
else
{
queryIndexlessColumn
(
pSkipList
,
pQueryInfo
,
result
,
param
->
nodeFilterFn
);
...
...
src/util/src/tcompare.c
浏览文件 @
85d3a7a2
...
...
@@ -17,6 +17,7 @@
#include "ttype.h"
#include "tcompare.h"
#include "tarray.h"
#include "hash.h"
int32_t
compareInt32Val
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
int32_t
left
=
GET_INT32_VAL
(
pLeft
),
right
=
GET_INT32_VAL
(
pRight
);
...
...
@@ -291,9 +292,12 @@ int32_t taosArrayCompareString(const void* a, const void* b) {
return
compareLenPrefixedStr
(
x
,
y
);
}
static
int32_t
compareFindStrInArray
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
const
SArray
*
arr
=
(
const
SArray
*
)
pRight
;
return
taosArraySearchString
(
arr
,
pLeft
,
taosArrayCompareString
,
TD_EQ
)
==
NULL
?
0
:
1
;
//static int32_t compareFindStrInArray(const void* pLeft, const void* pRight) {
// const SArray* arr = (const SArray*) pRight;
// return taosArraySearchString(arr, pLeft, taosArrayCompareString, TD_EQ) == NULL ? 0 : 1;
//}
static
int32_t
compareFindItemInSet
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
return
NULL
!=
taosHashGet
((
SHashObj
*
)
pRight
,
varDataVal
(
pLeft
),
varDataLen
(
pLeft
))
?
1
:
0
;
}
static
int32_t
compareWStrPatternComp
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
...
...
@@ -325,7 +329,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) {
if
(
optr
==
TSDB_RELATION_LIKE
)
{
/* wildcard query using like operator */
comparFn
=
compareStrPatternComp
;
}
else
if
(
optr
==
TSDB_RELATION_IN
)
{
comparFn
=
compareFind
StrInArray
;
comparFn
=
compareFind
ItemInSet
;
}
else
{
/* normal relational comparFn */
comparFn
=
compareLenPrefixedStr
;
}
...
...
tests/pytest/query/in.py
0 → 100644
浏览文件 @
85d3a7a2
###################################################################
# 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
taos
from
util.log
import
tdLog
from
util.cases
import
tdCases
from
util.sql
import
tdSql
from
util.dnodes
import
tdDnodes
class
TDTestCase
:
def
init
(
self
,
conn
,
logSql
):
tdLog
.
debug
(
"start to execute %s"
%
__file__
)
tdSql
.
init
(
conn
.
cursor
(),
logSql
)
self
.
ts
=
1538548685000
def
run
(
self
):
tdSql
.
prepare
()
print
(
"==============step1"
)
tdSql
.
execute
(
"create table if not exists st (ts timestamp, tagtype int) tags(dev nchar(50))"
)
tdSql
.
execute
(
'CREATE TABLE if not exists dev_001 using st tags("dev_01")'
)
tdSql
.
execute
(
'CREATE TABLE if not exists dev_002 using st tags("dev_02")'
)
print
(
"==============step2"
)
tdSql
.
error
(
"select * from db.st where ts in ('2020-05-13 10:00:00.000')"
)
tdSql
.
execute
(
"""INSERT INTO dev_001(ts, tagtype) VALUES('2020-05-13 10:00:00.000', 1),
('2020-05-13 10:00:00.001', 1)
dev_002 VALUES('2020-05-13 10:00:00.001', 1)"""
)
# TAG nchar
tdSql
.
query
(
'select count(ts) from db.st where dev in ("dev_01")'
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
2
)
tdSql
.
query
(
'select count(ts) from db.st where dev in ("dev_01", "dev_01")'
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
2
)
tdSql
.
query
(
'select count(ts) from db.st where dev in ("dev_01", "dev_01", "dev_02")'
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
3
)
# colume int
tdSql
.
query
(
"select count(ts) from db.st where tagtype in (1)"
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
3
)
tdSql
.
query
(
"select count(ts) from db.st where tagtype in (1, 2)"
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
3
)
tdSql
.
execute
(
"""INSERT INTO dev_001(ts, tagtype) VALUES('2020-05-13 10:00:01.000', 2),
('2020-05-13 10:00:02.001', 2)
dev_002 VALUES('2020-05-13 10:00:03.001', 2)"""
)
tdSql
.
query
(
"select count(ts) from db.st where tagtype in (1, 2)"
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
6
)
tdSql
.
execute
(
"create table tb(ts timestamp, c1 int, c2 binary(10), c3 nchar(10), c4 float, c5 bool)"
)
for
i
in
range
(
10
):
tdSql
.
execute
(
"insert into tb values(%d, %d, 'binary%d', 'nchar%d', %f, %d)"
%
(
self
.
ts
+
i
,
i
,
i
,
i
,
i
+
0.1
,
i
%
2
))
#binary
tdSql
.
query
(
'select count(ts) from db.tb where c2 in ("binary1")'
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
1
)
tdSql
.
query
(
'select count(ts) from db.tb where c2 in ("binary1", "binary2", "binary1")'
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
2
)
#bool
#tdSql.query('select count(ts) from db.tb where c5 in (true)')
#tdSql.checkRows(1)
#tdSql.checkData(0, 0, 5)
#float
#tdSql.query('select count(ts) from db.tb where c4 in (0.1)')
#tdSql.checkRows(1)
#tdSql.checkData(0, 0, 1)
#nchar
tdSql
.
query
(
'select count(ts) from db.tb where c3 in ("nchar0")'
)
tdSql
.
checkRows
(
1
)
tdSql
.
checkData
(
0
,
0
,
1
)
#tdSql.query("select tbname, dev from dev_001")
#tdSql.checkRows(1)
#tdSql.checkData(0, 0, 'dev_001')
#tdSql.checkData(0, 1, 'dev_01')
#tdSql.query("select tbname, dev, tagtype from dev_001")
#tdSql.checkRows(2)
### test case for https://jira.taosdata.com:18080/browse/TD-1930
#tdSql.execute("create table tb(ts timestamp, c1 int, c2 binary(10), c3 nchar(10), c4 float, c5 bool)")
#for i in range(10):
# tdSql.execute("insert into tb values(%d, %d, 'binary%d', 'nchar%d', %f, %d)" % (self.ts + i, i, i, i, i + 0.1, i % 2))
#
#tdSql.error("select * from tb where c2 = binary2")
#tdSql.error("select * from tb where c3 = nchar2")
#tdSql.query("select * from tb where c2 = 'binary2' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c3 = 'nchar2' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c1 = '2' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c1 = 2 ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c4 = '0.1' ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c4 = 0.1 ")
#tdSql.checkRows(1)
#tdSql.query("select * from tb where c5 = true ")
#tdSql.checkRows(5)
#tdSql.query("select * from tb where c5 = 'true' ")
#tdSql.checkRows(5)
## For jira: https://jira.taosdata.com:18080/browse/TD-2850
#tdSql.execute("create database 'Test' ")
#tdSql.execute("use 'Test' ")
#tdSql.execute("create table 'TB'(ts timestamp, 'Col1' int) tags('Tag1' int)")
#tdSql.execute("insert into 'Tb0' using tb tags(1) values(now, 1)")
#tdSql.query("select * from tb")
#tdSql.checkRows(1)
def
stop
(
self
):
tdSql
.
close
()
tdLog
.
success
(
"%s successfully executed"
%
__file__
)
tdCases
.
addWindows
(
__file__
,
TDTestCase
())
tdCases
.
addLinux
(
__file__
,
TDTestCase
())
tests/script/general/parser/where.sim
浏览文件 @
85d3a7a2
...
...
@@ -151,18 +151,12 @@ sql_error select last(*) from wh_mt1 where c5 in ('1')
sql_error select last(*) from wh_mt1_tb1 where c5 in ('1')
sql_error select last(*) from wh_mt1 where c6 in ('1')
sql_error select last(*) from wh_mt1_tb1 where c6 in ('1')
sql_error select last(*) from wh_mt1 where c7 in ('binary')
sql_error select last(*) from wh_mt1_tb1 where c7 in ('binary')
sql_error select last(*) from wh_mt1 where c8 in ('nchar')
sql_error select last(*) from wh_mt1_tb1 where c9 in (true, false)
#
sql_error select last(*) from wh_mt1 where c7 in ('binary')
#
sql_error select last(*) from wh_mt1_tb1 where c7 in ('binary')
#
sql_error select last(*) from wh_mt1 where c8 in ('nchar')
#
sql_error select last(*) from wh_mt1_tb1 where c9 in (true, false)
sql_error select last(*) from wh_mt1 where c10 in ('2019-01-01 00:00:00.000')
sql_error select last(*) from wh_mt1_tb1 where c10 in ('2019-01-01 00:00:00.000')
sql_error select last(*) from wh_mt1 where t1 in ('binary')
sql_error select last(*) from wh_mt1 where t2 in (1)
sql_error select last(*) from wh_mt1 where t3 in (1)
sql_error select last(*) from wh_mt1 where t4 in (1)
sql_error select last(*) from wh_mt1 where t5 in (1)
sql_error select last(*) from wh_mt1 where t6 in (1)
sql select last(*) from wh_mt1 where c1 = 1
if $rows != 1 then
return -1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录