Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
72914955
TDengine
项目概览
taosdata
/
TDengine
12 个月 前同步成功
通知
1180
Star
22014
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看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
72914955
编写于
6月 06, 2022
作者:
wmmhello
提交者:
GitHub
6月 06, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #13530 from taosdata/feature/TD-13041
fix: error in json and add test cases for json
上级
b2e51d95
ca187f2e
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
207 addition
and
142 deletion
+207
-142
include/util/tcompare.h
include/util/tcompare.h
+0
-2
source/libs/parser/src/parTokenizer.c
source/libs/parser/src/parTokenizer.c
+1
-0
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+6
-2
source/libs/scalar/src/filter.c
source/libs/scalar/src/filter.c
+1
-1
source/libs/scalar/src/sclvector.c
source/libs/scalar/src/sclvector.c
+163
-131
source/util/src/tcompare.c
source/util/src/tcompare.c
+0
-5
tests/system-test/2-query/json_tag.py
tests/system-test/2-query/json_tag.py
+36
-1
未找到文件。
include/util/tcompare.h
浏览文件 @
72914955
...
...
@@ -105,8 +105,6 @@ int32_t compareStrPatternNotMatch(const void *pLeft, const void *pRight);
int32_t
compareWStrPatternMatch
(
const
void
*
pLeft
,
const
void
*
pRight
);
int32_t
compareWStrPatternNotMatch
(
const
void
*
pLeft
,
const
void
*
pRight
);
int32_t
compareJsonContainsKey
(
const
void
*
pLeft
,
const
void
*
pRight
);
__compar_fn_t
getComparFunc
(
int32_t
type
,
int32_t
optr
);
__compar_fn_t
getKeyComparFunc
(
int32_t
keyType
,
int32_t
order
);
int32_t
doCompare
(
const
char
*
a
,
const
char
*
b
,
int32_t
type
,
size_t
size
);
...
...
source/libs/parser/src/parTokenizer.c
浏览文件 @
72914955
...
...
@@ -64,6 +64,7 @@ static SKeyword keywordTable[] = {
{
"CONSUMER"
,
TK_CONSUMER
},
{
"COUNT"
,
TK_COUNT
},
{
"CREATE"
,
TK_CREATE
},
{
"CONTAINS"
,
TK_CONTAINS
},
{
"DATABASE"
,
TK_DATABASE
},
{
"DATABASES"
,
TK_DATABASES
},
{
"DAYS"
,
TK_DAYS
},
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
72914955
...
...
@@ -847,8 +847,12 @@ static EDealRes translateJsonOperator(STranslateContext* pCxt, SOperatorNode* pO
if
(
TSDB_DATA_TYPE_JSON
!=
ldt
.
type
||
TSDB_DATA_TYPE_BINARY
!=
rdt
.
type
)
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
}
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_JSON
;
pOp
->
node
.
resType
.
bytes
=
tDataTypes
[
TSDB_DATA_TYPE_JSON
].
bytes
;
if
(
pOp
->
opType
==
OP_TYPE_JSON_GET_VALUE
){
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_JSON
;
}
else
if
(
pOp
->
opType
==
OP_TYPE_JSON_CONTAINS
){
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_BOOL
;
}
pOp
->
node
.
resType
.
bytes
=
tDataTypes
[
pOp
->
node
.
resType
.
type
].
bytes
;
return
DEAL_RES_CONTINUE
;
}
...
...
source/libs/scalar/src/filter.c
浏览文件 @
72914955
...
...
@@ -168,7 +168,7 @@ __compar_fn_t gDataCompare[] = {compareInt32Val, compareInt8Val, compareInt16Val
compareLenPrefixedWStr
,
compareUint8Val
,
compareUint16Val
,
compareUint32Val
,
compareUint64Val
,
setChkInBytes1
,
setChkInBytes2
,
setChkInBytes4
,
setChkInBytes8
,
compareStrRegexCompMatch
,
compareStrRegexCompNMatch
,
setChkNotInBytes1
,
setChkNotInBytes2
,
setChkNotInBytes4
,
setChkNotInBytes8
,
compareChkNotInString
,
compareStrPatternNotMatch
,
compareWStrPatternNotMatch
,
compareJsonContainsKey
compareChkNotInString
,
compareStrPatternNotMatch
,
compareWStrPatternNotMatch
};
int8_t
filterGetCompFuncIdx
(
int32_t
type
,
int32_t
optr
)
{
...
...
source/libs/scalar/src/sclvector.c
浏览文件 @
72914955
...
...
@@ -88,7 +88,7 @@ void convertNumberToNumber(const void *inData, void *outData, int8_t inType, int
}
}
void
convert
StringToDouble
(
const
void
*
inData
,
void
*
outData
,
int8_t
inType
,
int8_t
outType
){
void
convert
NcharToDouble
(
const
void
*
inData
,
void
*
outData
){
char
*
tmp
=
taosMemoryMalloc
(
varDataTLen
(
inData
));
int
len
=
taosUcs4ToMbs
((
TdUcs4
*
)
varDataVal
(
inData
),
varDataLen
(
inData
),
tmp
);
if
(
len
<
0
)
{
...
...
@@ -97,13 +97,24 @@ void convertStringToDouble(const void *inData, void *outData, int8_t inType, int
tmp
[
len
]
=
0
;
ASSERT
(
outType
==
TSDB_DATA_TYPE_DOUBLE
);
double
value
=
taosStr2Double
(
tmp
,
NULL
);
*
((
double
*
)
outData
)
=
value
;
taosMemoryFreeClear
(
tmp
);
}
void
convertBinaryToDouble
(
const
void
*
inData
,
void
*
outData
){
char
*
tmp
=
taosMemoryCalloc
(
1
,
varDataTLen
(
inData
));
if
(
tmp
==
NULL
){
*
((
double
*
)
outData
)
=
0
.;
return
;
}
memcpy
(
tmp
,
varDataVal
(
inData
),
varDataLen
(
inData
));
double
ret
=
taosStr2Double
(
tmp
,
NULL
);
taosMemoryFree
(
tmp
);
*
((
double
*
)
outData
)
=
ret
;
}
typedef
int64_t
(
*
_getBigintValue_fn_t
)(
void
*
src
,
int32_t
index
);
int64_t
getVectorBigintValue_TINYINT
(
void
*
src
,
int32_t
index
)
{
...
...
@@ -147,7 +158,7 @@ int64_t getVectorBigintValue_JSON(void *src, int32_t index){
if
(
*
data
==
TSDB_DATA_TYPE_NULL
){
return
0
;
}
else
if
(
*
data
==
TSDB_DATA_TYPE_NCHAR
)
{
// json inner type can not be BINARY
convert
StringToDouble
(
data
+
CHAR_BYTES
,
&
out
,
*
data
,
TSDB_DATA_TYPE_DOUBLE
);
convert
NcharToDouble
(
data
+
CHAR_BYTES
,
&
out
);
}
else
{
convertNumberToNumber
(
data
+
CHAR_BYTES
,
&
out
,
*
data
,
TSDB_DATA_TYPE_DOUBLE
);
}
...
...
@@ -445,14 +456,30 @@ double getVectorDoubleValue_JSON(void *src, int32_t index){
if
(
*
data
==
TSDB_DATA_TYPE_NULL
){
return
out
;
}
else
if
(
*
data
==
TSDB_DATA_TYPE_NCHAR
)
{
// json inner type can not be BINARY
convert
StringToDouble
(
data
+
CHAR_BYTES
,
&
out
,
*
data
,
TSDB_DATA_TYPE_DOUBLE
);
convert
NcharToDouble
(
data
+
CHAR_BYTES
,
&
out
);
}
else
{
convertNumberToNumber
(
data
+
CHAR_BYTES
,
&
out
,
*
data
,
TSDB_DATA_TYPE_DOUBLE
);
}
return
out
;
}
bool
convertJsonValue
(
__compar_fn_t
*
fp
,
int32_t
optr
,
int8_t
typeLeft
,
int8_t
typeRight
,
char
**
pLeftData
,
char
**
pRightData
,
void
*
pLeftOut
,
void
*
pRightOut
,
bool
*
isNull
){
void
*
ncharTobinary
(
void
*
buf
){
// todo need to remove , if tobinary is nchar
int32_t
inputLen
=
varDataLen
(
buf
);
void
*
t
=
taosMemoryCalloc
(
1
,
inputLen
);
int32_t
len
=
taosUcs4ToMbs
((
TdUcs4
*
)
varDataVal
(
buf
),
varDataLen
(
buf
),
varDataVal
(
t
));
if
(
len
<
0
)
{
sclError
(
"charset:%s to %s. val:%s convert ncharTobinary failed."
,
DEFAULT_UNICODE_ENCODEC
,
tsCharset
,
(
char
*
)
varDataVal
(
buf
));
taosMemoryFree
(
t
);
return
NULL
;
}
varDataSetLen
(
t
,
len
);
return
t
;
}
bool
convertJsonValue
(
__compar_fn_t
*
fp
,
int32_t
optr
,
int8_t
typeLeft
,
int8_t
typeRight
,
char
**
pLeftData
,
char
**
pRightData
,
void
*
pLeftOut
,
void
*
pRightOut
,
bool
*
isNull
,
bool
*
freeLeft
,
bool
*
freeRight
){
if
(
optr
==
OP_TYPE_JSON_CONTAINS
)
{
return
true
;
}
...
...
@@ -489,21 +516,41 @@ bool convertJsonValue(__compar_fn_t *fp, int32_t optr, int8_t typeLeft, int8_t t
*
fp
=
filterGetCompFunc
(
type
,
optr
);
if
(
typeLeft
==
TSDB_DATA_TYPE_NCHAR
)
{
convertStringToDouble
(
*
pLeftData
,
pLeftOut
,
typeLeft
,
type
);
*
pLeftData
=
pLeftOut
;
}
else
if
(
typeLeft
!=
type
)
{
convertNumberToNumber
(
*
pLeftData
,
pLeftOut
,
typeLeft
,
type
);
*
pLeftData
=
pLeftOut
;
if
(
IS_NUMERIC_TYPE
(
type
)
||
IS_FLOAT_TYPE
(
type
)){
if
(
typeLeft
==
TSDB_DATA_TYPE_NCHAR
)
{
convertNcharToDouble
(
*
pLeftData
,
pLeftOut
);
*
pLeftData
=
pLeftOut
;
}
else
if
(
typeLeft
==
TSDB_DATA_TYPE_BINARY
)
{
convertBinaryToDouble
(
*
pLeftData
,
pLeftOut
);
*
pLeftData
=
pLeftOut
;
}
else
if
(
typeLeft
!=
type
)
{
convertNumberToNumber
(
*
pLeftData
,
pLeftOut
,
typeLeft
,
type
);
*
pLeftData
=
pLeftOut
;
}
if
(
typeRight
==
TSDB_DATA_TYPE_NCHAR
)
{
convertNcharToDouble
(
*
pRightData
,
pRightOut
);
*
pRightData
=
pRightOut
;
}
else
if
(
typeRight
==
TSDB_DATA_TYPE_BINARY
)
{
convertBinaryToDouble
(
*
pRightData
,
pRightOut
);
*
pRightData
=
pRightOut
;
}
else
if
(
typeRight
!=
type
)
{
convertNumberToNumber
(
*
pRightData
,
pRightOut
,
typeRight
,
type
);
*
pRightData
=
pRightOut
;
}
}
else
if
(
type
==
TSDB_DATA_TYPE_BINARY
){
if
(
typeLeft
==
TSDB_DATA_TYPE_NCHAR
){
*
pLeftData
=
ncharTobinary
(
*
pLeftData
);
*
freeLeft
=
true
;
}
if
(
typeRight
==
TSDB_DATA_TYPE_NCHAR
){
*
pRightData
=
ncharTobinary
(
*
pRightData
);
*
freeRight
=
true
;
}
}
else
{
ASSERT
(
0
);
}
if
(
typeRight
==
TSDB_DATA_TYPE_NCHAR
)
{
convertStringToDouble
(
*
pRightData
,
pRightOut
,
typeRight
,
type
);
*
pRightData
=
pRightOut
;
}
else
if
(
typeRight
!=
type
)
{
convertNumberToNumber
(
*
pRightData
,
pRightOut
,
typeRight
,
type
);
*
pRightData
=
pRightOut
;
}
return
true
;
}
...
...
@@ -935,44 +982,6 @@ static void doReleaseVec(SColumnInfoData* pCol, int32_t type) {
}
}
STagVal
getJsonValue
(
char
*
json
,
char
*
key
,
bool
*
isExist
)
{
STagVal
val
=
{.
pKey
=
key
};
bool
find
=
tTagGet
(((
const
STag
*
)
json
),
&
val
);
// json value is null and not exist is different
if
(
isExist
){
*
isExist
=
find
;
}
return
val
;
}
void
vectorJsonArrow
(
SScalarParam
*
pLeft
,
SScalarParam
*
pRight
,
SScalarParam
*
pOut
,
int32_t
_ord
)
{
SColumnInfoData
*
pOutputCol
=
pOut
->
columnData
;
int32_t
i
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
0
:
TMAX
(
pLeft
->
numOfRows
,
pRight
->
numOfRows
)
-
1
;
int32_t
step
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
1
:
-
1
;
pOut
->
numOfRows
=
TMAX
(
pLeft
->
numOfRows
,
pRight
->
numOfRows
);
char
*
pRightData
=
colDataGetVarData
(
pRight
->
columnData
,
0
);
char
*
jsonKey
=
taosMemoryCalloc
(
1
,
varDataLen
(
pRightData
)
+
1
);
memcpy
(
jsonKey
,
varDataVal
(
pRightData
),
varDataLen
(
pRightData
));
for
(;
i
>=
0
&&
i
<
pLeft
->
numOfRows
;
i
+=
step
)
{
if
(
colDataIsNull_var
(
pLeft
->
columnData
,
i
))
{
colDataSetNull_var
(
pOutputCol
,
i
);
pOutputCol
->
hasNull
=
true
;
continue
;
}
char
*
pLeftData
=
colDataGetVarData
(
pLeft
->
columnData
,
i
);
bool
isExist
=
false
;
STagVal
value
=
getJsonValue
(
pLeftData
,
jsonKey
,
&
isExist
);
char
*
data
=
isExist
?
tTagValToData
(
&
value
,
true
)
:
NULL
;
colDataAppend
(
pOutputCol
,
i
,
data
,
data
==
NULL
);
if
(
isExist
&&
IS_VAR_DATA_TYPE
(
value
.
type
)
&&
data
){
taosMemoryFree
(
data
);
}
}
taosMemoryFree
(
jsonKey
);
}
void
vectorMathAdd
(
SScalarParam
*
pLeft
,
SScalarParam
*
pRight
,
SScalarParam
*
pOut
,
int32_t
_ord
)
{
SColumnInfoData
*
pOutputCol
=
pOut
->
columnData
;
...
...
@@ -1510,6 +1519,38 @@ void vectorBitOr(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut,
doReleaseVec
(
pRightCol
,
rightConvert
);
}
#define VEC_COM_INNER(pCol, index1, index2) \
for (; i < pCol->numOfRows && i >= 0; i += step) {\
if (IS_HELPER_NULL(pLeft->columnData, index1) || IS_HELPER_NULL(pRight->columnData, index2)) {\
bool res = false;\
colDataAppendInt8(pOut->columnData, i, (int8_t*)&res);\
continue;\
}\
char *pLeftData = colDataGetData(pLeft->columnData, index1);\
char *pRightData = colDataGetData(pRight->columnData, index2);\
int64_t leftOut = 0;\
int64_t rightOut = 0;\
bool freeLeft = false;\
bool freeRight = false;\
bool isJsonnull = false;\
bool result = convertJsonValue(&fp, optr, GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight),\
&pLeftData, &pRightData, &leftOut, &rightOut, &isJsonnull, &freeLeft, &freeRight);\
if(isJsonnull){\
ASSERT(0);\
}\
if(!pLeftData || !pRightData){\
result = false;\
}\
if(!result){\
colDataAppendInt8(pOut->columnData, i, (int8_t*)&result);\
}else{\
bool res = filterDoCompare(fp, optr, pLeftData, pRightData);\
colDataAppendInt8(pOut->columnData, i, (int8_t*)&res);\
}\
if(freeLeft) taosMemoryFreeClear(pLeftData);\
if(freeRight) taosMemoryFreeClear(pRightData);\
}
void
vectorCompareImpl
(
SScalarParam
*
pLeft
,
SScalarParam
*
pRight
,
SScalarParam
*
pOut
,
int32_t
_ord
,
int32_t
optr
)
{
int32_t
i
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
0
:
TMAX
(
pLeft
->
numOfRows
,
pRight
->
numOfRows
)
-
1
;
int32_t
step
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
1
:
-
1
;
...
...
@@ -1533,79 +1574,11 @@ void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *
}
if
(
pLeft
->
numOfRows
==
pRight
->
numOfRows
)
{
for
(;
i
<
pRight
->
numOfRows
&&
i
>=
0
;
i
+=
step
)
{
if
(
IS_HELPER_NULL
(
pLeft
->
columnData
,
i
)
||
IS_HELPER_NULL
(
pRight
->
columnData
,
i
))
{
bool
res
=
false
;
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
res
);
continue
;
// TODO set null or ignore
}
char
*
pLeftData
=
colDataGetData
(
pLeft
->
columnData
,
i
);
char
*
pRightData
=
colDataGetData
(
pRight
->
columnData
,
i
);
int64_t
leftOut
=
0
;
int64_t
rightOut
=
0
;
bool
isJsonnull
=
false
;
bool
result
=
convertJsonValue
(
&
fp
,
optr
,
GET_PARAM_TYPE
(
pLeft
),
GET_PARAM_TYPE
(
pRight
),
&
pLeftData
,
&
pRightData
,
&
leftOut
,
&
rightOut
,
&
isJsonnull
);
if
(
isJsonnull
){
ASSERT
(
0
);
}
if
(
!
result
){
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
result
);
}
else
{
bool
res
=
filterDoCompare
(
fp
,
optr
,
pLeftData
,
pRightData
);
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
res
);
}
}
VEC_COM_INNER
(
pLeft
,
i
,
i
)
}
else
if
(
pRight
->
numOfRows
==
1
)
{
ASSERT
(
pLeft
->
pHashFilter
==
NULL
);
for
(;
i
>=
0
&&
i
<
pLeft
->
numOfRows
;
i
+=
step
)
{
if
(
IS_HELPER_NULL
(
pLeft
->
columnData
,
i
)
||
IS_HELPER_NULL
(
pRight
->
columnData
,
0
))
{
bool
res
=
false
;
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
res
);
continue
;
}
char
*
pLeftData
=
colDataGetData
(
pLeft
->
columnData
,
i
);
char
*
pRightData
=
colDataGetData
(
pRight
->
columnData
,
0
);
int64_t
leftOut
=
0
;
int64_t
rightOut
=
0
;
bool
isJsonnull
=
false
;
bool
result
=
convertJsonValue
(
&
fp
,
optr
,
GET_PARAM_TYPE
(
pLeft
),
GET_PARAM_TYPE
(
pRight
),
&
pLeftData
,
&
pRightData
,
&
leftOut
,
&
rightOut
,
&
isJsonnull
);
if
(
isJsonnull
){
ASSERT
(
0
);
}
if
(
!
result
){
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
result
);
}
else
{
bool
res
=
filterDoCompare
(
fp
,
optr
,
pLeftData
,
pRightData
);
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
res
);
}
}
VEC_COM_INNER
(
pLeft
,
i
,
0
)
}
else
if
(
pLeft
->
numOfRows
==
1
)
{
for
(;
i
>=
0
&&
i
<
pRight
->
numOfRows
;
i
+=
step
)
{
if
(
IS_HELPER_NULL
(
pRight
->
columnData
,
i
)
||
IS_HELPER_NULL
(
pLeft
->
columnData
,
0
))
{
bool
res
=
false
;
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
res
);
continue
;
}
char
*
pLeftData
=
colDataGetData
(
pLeft
->
columnData
,
0
);
char
*
pRightData
=
colDataGetData
(
pLeft
->
columnData
,
i
);
int64_t
leftOut
=
0
;
int64_t
rightOut
=
0
;
bool
isJsonnull
=
false
;
bool
result
=
convertJsonValue
(
&
fp
,
optr
,
GET_PARAM_TYPE
(
pLeft
),
GET_PARAM_TYPE
(
pRight
),
&
pLeftData
,
&
pRightData
,
&
leftOut
,
&
rightOut
,
&
isJsonnull
);
if
(
isJsonnull
){
ASSERT
(
0
);
}
if
(
!
result
){
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
result
);
}
else
{
bool
res
=
filterDoCompare
(
fp
,
optr
,
pLeftData
,
pRightData
);
colDataAppendInt8
(
pOut
->
columnData
,
i
,
(
int8_t
*
)
&
res
);
}
}
VEC_COM_INNER
(
pRight
,
0
,
i
)
}
}
...
...
@@ -1683,10 +1656,6 @@ void vectorNotMatch(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOu
vectorCompare
(
pLeft
,
pRight
,
pOut
,
_ord
,
OP_TYPE_NMATCH
);
}
void
vectorJsonContains
(
SScalarParam
*
pLeft
,
SScalarParam
*
pRight
,
SScalarParam
*
pOut
,
int32_t
_ord
)
{
vectorCompare
(
pLeft
,
pRight
,
pOut
,
_ord
,
OP_TYPE_JSON_CONTAINS
);
}
void
vectorIsNull
(
SScalarParam
*
pLeft
,
SScalarParam
*
pRight
,
SScalarParam
*
pOut
,
int32_t
_ord
)
{
for
(
int32_t
i
=
0
;
i
<
pLeft
->
numOfRows
;
++
i
)
{
int8_t
v
=
IS_HELPER_NULL
(
pLeft
->
columnData
,
i
)
?
1
:
0
;
...
...
@@ -1707,6 +1676,69 @@ void vectorIsTrue(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut,
vectorConvertImpl
(
pLeft
,
pOut
);
}
STagVal
getJsonValue
(
char
*
json
,
char
*
key
,
bool
*
isExist
)
{
STagVal
val
=
{.
pKey
=
key
};
bool
find
=
tTagGet
(((
const
STag
*
)
json
),
&
val
);
// json value is null and not exist is different
if
(
isExist
){
*
isExist
=
find
;
}
return
val
;
}
void
vectorJsonContains
(
SScalarParam
*
pLeft
,
SScalarParam
*
pRight
,
SScalarParam
*
pOut
,
int32_t
_ord
)
{
SColumnInfoData
*
pOutputCol
=
pOut
->
columnData
;
int32_t
i
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
0
:
TMAX
(
pLeft
->
numOfRows
,
pRight
->
numOfRows
)
-
1
;
int32_t
step
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
1
:
-
1
;
pOut
->
numOfRows
=
TMAX
(
pLeft
->
numOfRows
,
pRight
->
numOfRows
);
char
*
pRightData
=
colDataGetVarData
(
pRight
->
columnData
,
0
);
char
*
jsonKey
=
taosMemoryCalloc
(
1
,
varDataLen
(
pRightData
)
+
1
);
memcpy
(
jsonKey
,
varDataVal
(
pRightData
),
varDataLen
(
pRightData
));
for
(;
i
>=
0
&&
i
<
pLeft
->
numOfRows
;
i
+=
step
)
{
bool
isExist
=
false
;
if
(
!
colDataIsNull_var
(
pLeft
->
columnData
,
i
))
{
char
*
pLeftData
=
colDataGetVarData
(
pLeft
->
columnData
,
i
);
getJsonValue
(
pLeftData
,
jsonKey
,
&
isExist
);
}
colDataAppend
(
pOutputCol
,
i
,
(
const
char
*
)(
&
isExist
),
false
);
}
taosMemoryFree
(
jsonKey
);
}
void
vectorJsonArrow
(
SScalarParam
*
pLeft
,
SScalarParam
*
pRight
,
SScalarParam
*
pOut
,
int32_t
_ord
)
{
SColumnInfoData
*
pOutputCol
=
pOut
->
columnData
;
int32_t
i
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
0
:
TMAX
(
pLeft
->
numOfRows
,
pRight
->
numOfRows
)
-
1
;
int32_t
step
=
((
_ord
)
==
TSDB_ORDER_ASC
)
?
1
:
-
1
;
pOut
->
numOfRows
=
TMAX
(
pLeft
->
numOfRows
,
pRight
->
numOfRows
);
char
*
pRightData
=
colDataGetVarData
(
pRight
->
columnData
,
0
);
char
*
jsonKey
=
taosMemoryCalloc
(
1
,
varDataLen
(
pRightData
)
+
1
);
memcpy
(
jsonKey
,
varDataVal
(
pRightData
),
varDataLen
(
pRightData
));
for
(;
i
>=
0
&&
i
<
pLeft
->
numOfRows
;
i
+=
step
)
{
if
(
colDataIsNull_var
(
pLeft
->
columnData
,
i
))
{
colDataSetNull_var
(
pOutputCol
,
i
);
pOutputCol
->
hasNull
=
true
;
continue
;
}
char
*
pLeftData
=
colDataGetVarData
(
pLeft
->
columnData
,
i
);
bool
isExist
=
false
;
STagVal
value
=
getJsonValue
(
pLeftData
,
jsonKey
,
&
isExist
);
char
*
data
=
isExist
?
tTagValToData
(
&
value
,
true
)
:
NULL
;
colDataAppend
(
pOutputCol
,
i
,
data
,
data
==
NULL
);
if
(
isExist
&&
IS_VAR_DATA_TYPE
(
value
.
type
)
&&
data
){
taosMemoryFree
(
data
);
}
}
taosMemoryFree
(
jsonKey
);
}
_bin_scalar_fn_t
getBinScalarOperatorFn
(
int32_t
binFunctionId
)
{
switch
(
binFunctionId
)
{
case
OP_TYPE_ADD
:
...
...
source/util/src/tcompare.c
浏览文件 @
72914955
...
...
@@ -222,11 +222,6 @@ int32_t compareLenPrefixedWStrDesc(const void *pLeft, const void *pRight) {
return
compareLenPrefixedWStr
(
pRight
,
pLeft
);
}
int32_t
compareJsonContainsKey
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
if
(
pLeft
)
return
0
;
return
1
;
}
// string > number > bool > null
// ref: https://dev.mysql.com/doc/refman/8.0/en/json.html#json-comparison
int32_t
compareJsonVal
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
...
...
tests/system-test/2-query/json_tag.py
浏览文件 @
72914955
...
...
@@ -118,7 +118,7 @@ class TDTestCase:
tdSql
.
error
(
"select jtag->location from jsons1"
)
tdSql
.
error
(
"select jtag contains location from jsons1"
)
tdSql
.
error
(
"select * from jsons1 where jtag contains location"
)
tdSql
.
error
(
"select * from jsons1 where jtag contains''"
)
#
tdSql.error("select * from jsons1 where jtag contains''")
tdSql
.
error
(
"select * from jsons1 where jtag contains 'location'='beijing'"
)
#
# # test function error
...
...
@@ -129,6 +129,41 @@ class TDTestCase:
tdSql
.
error
(
"select ceil(jtag->'tag1') from jsons1"
)
tdSql
.
error
(
"select ceil(jtag) from jsons1"
)
#
#test scalar operation
tdSql
.
query
(
"select jtag contains 'tag1',jtag->'tag1' from jsons1 order by jtag->'tag1'"
)
tdSql
.
checkRows
(
13
)
tdSql
.
checkData
(
0
,
0
,
False
)
tdSql
.
checkData
(
5
,
0
,
True
)
tdSql
.
checkData
(
12
,
0
,
True
)
tdSql
.
query
(
"select jtag->'tag1' like 'fe%',jtag->'tag1' from jsons1 order by jtag->'tag1'"
)
tdSql
.
checkRows
(
13
)
tdSql
.
checkData
(
10
,
0
,
False
)
tdSql
.
checkData
(
11
,
0
,
False
)
tdSql
.
checkData
(
12
,
0
,
True
)
tdSql
.
query
(
"select jtag->'tag1' not like 'fe%',jtag->'tag1' from jsons1 order by jtag->'tag1'"
)
tdSql
.
checkRows
(
13
)
tdSql
.
checkData
(
10
,
0
,
False
)
tdSql
.
checkData
(
11
,
0
,
True
)
tdSql
.
checkData
(
12
,
0
,
False
)
tdSql
.
query
(
"select jtag->'tag1' match 'fe',jtag->'tag1' from jsons1 order by jtag->'tag1'"
)
tdSql
.
checkRows
(
13
)
tdSql
.
checkData
(
10
,
0
,
False
)
tdSql
.
checkData
(
11
,
0
,
False
)
tdSql
.
checkData
(
12
,
0
,
True
)
tdSql
.
query
(
"select jtag->'tag1' nmatch 'fe',jtag->'tag1' from jsons1 order by jtag->'tag1'"
)
tdSql
.
checkRows
(
13
)
tdSql
.
checkData
(
10
,
0
,
False
)
tdSql
.
checkData
(
11
,
0
,
True
)
tdSql
.
checkData
(
12
,
0
,
False
)
tdSql
.
query
(
"select jtag->'tag1',jtag->'tag1'>='a' from jsons1 order by jtag->'tag1'"
)
tdSql
.
checkRows
(
13
)
tdSql
.
checkData
(
0
,
0
,
None
)
tdSql
.
checkData
(
0
,
1
,
False
)
tdSql
.
checkData
(
7
,
0
,
"false"
)
tdSql
.
checkData
(
7
,
1
,
True
)
tdSql
.
checkData
(
12
,
1
,
True
)
# # test select normal column
tdSql
.
query
(
"select dataint from jsons1 order by dataint"
)
tdSql
.
checkRows
(
9
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录