Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions source/libs/function/src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ static int32_t invaildFuncParaValueErrMsg(char* pErrBuf, int32_t len, const char
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_PARA_VALUE, "Invalid parameter value : %s", pFuncName);
}

#if !defined(TD_ENTERPRISE) && !defined(TD_ASTRA)
static int32_t enterpriseOnlyFuncErrMsg(char* pErrBuf, int32_t len, const char* pFuncName) {
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_OPS_NOT_SUPPORT, "%s is only supported in Enterprise edition",
pFuncName);
}
#endif

static int32_t validateTimeUnitParam(uint8_t dbPrec, const SValueNode* pVal) {
if (!IS_DURATION_VAL(pVal->flag)) {
return TSDB_CODE_FUNC_TIME_UNIT_INVALID;
Expand Down Expand Up @@ -1793,6 +1800,10 @@ static int32_t translateOutAesDe(SFunctionNode* pFunc, char* pErrBuf, int32_t le
}

static int32_t translateOutSm4(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
#if !defined(TD_ENTERPRISE) && !defined(TD_ASTRA)
return enterpriseOnlyFuncErrMsg(pErrBuf, len, pFunc->functionName);
#endif

FUNC_ERR_RET(validateParam(pFunc, pErrBuf, len));

uint8_t orgType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
Expand All @@ -1806,6 +1817,10 @@ static int32_t translateOutSm4(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
}

static int32_t translateOutSm4De(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
#if !defined(TD_ENTERPRISE) && !defined(TD_ASTRA)
return enterpriseOnlyFuncErrMsg(pErrBuf, len, pFunc->functionName);
#endif

FUNC_ERR_RET(validateParam(pFunc, pErrBuf, len));

uint8_t orgType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
Expand Down
7 changes: 7 additions & 0 deletions source/libs/parser/src/parInsertSql.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,13 @@ static int32_t parseBinary(SInsertParseContext* pCxt, const char** ppSql, SToken
uint8_t** pData = &pVal->value.pData;
uint32_t* nData = &pVal->value.nData;

#if !defined(TD_ENTERPRISE) && !defined(TD_ASTRA)
if (pToken->type == TK_SM4_ENCRYPT || pToken->type == TK_SM4_DECRYPT) {
return generateSyntaxErrMsgExt(&pCxt->msg, TSDB_CODE_OPS_NOT_SUPPORT, "%s is only supported in Enterprise edition",
pToken->type == TK_SM4_ENCRYPT ? "SM4_ENCRYPT" : "SM4_DECRYPT");
}
#endif

if (pToken->type == TK_FROM_BASE64 || pToken->type == TK_TO_BASE64 || pToken->type == TK_MD5 ||
pToken->type == TK_SHA || pToken->type == TK_SHA1 || pToken->type == TK_SHA2 || pToken->type == TK_AES_ENCRYPT ||
pToken->type == TK_AES_DECRYPT || pToken->type == TK_SM4_ENCRYPT || pToken->type == TK_SM4_DECRYPT) {
Expand Down
174 changes: 107 additions & 67 deletions test/cases/11-Functions/01-Scalar/test_scalar_crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ def test_crypto(self):

"""

self.sm4_supported = tdSql.query(
"SELECT sm4_encrypt('probe', 'mykeystring')",
queryTimes=1,
exit=False,
) is not False
if not self.sm4_supported:
self.sm4_community_rejection()

self.smoking()
tdStream.dropAllStreamsAndDbs()
self.null()
Expand All @@ -37,6 +45,34 @@ def test_crypto(self):
self.error()
tdStream.dropAllStreamsAndDbs()

def sm4_community_rejection(self):
err = "only supported in Enterprise edition"
tdSql.error(
"SELECT sm4_encrypt('plaintext', 'mykeystring')",
expectErrInfo=err,
fullMatched=False,
)
tdSql.error(
"SELECT sm4_decrypt('ciphertext', 'mykeystring')",
expectErrInfo=err,
fullMatched=False,
)

tdSql.execute("drop database if exists db_sm4_unsupported")
tdSql.execute("create database db_sm4_unsupported")
tdSql.execute("create table db_sm4_unsupported.tb(ts timestamp, v varchar(64))")
tdSql.error(
"insert into db_sm4_unsupported.tb values(now, sm4_encrypt('plaintext', 'mykeystring'))",
expectErrInfo=err,
fullMatched=False,
)
tdSql.error(
"insert into db_sm4_unsupported.tb values(now, sm4_decrypt('ciphertext', 'mykeystring'))",
expectErrInfo=err,
fullMatched=False,
)
tdSql.execute("drop database db_sm4_unsupported")

def smoking(self):
vgroups = 1
dbName = "db"
Expand Down Expand Up @@ -65,27 +101,28 @@ def smoking(self):
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'mytext')

tdLog.info(f"====> sm4")
f = 'sm4_ENCRYPT'
fi = 'sm4_decrypt'

tdSql.query(f"SELECT {fi}({f}('mytext','mykeystring'), 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'mytext')

tdSql.execute(f"drop table {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(32))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}('mytext','mykeystring'))")
tdSql.query(f"SELECT {fi}(f1, 'mykeystring') from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'mytext')

tdSql.execute(f"drop table {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(32))")
tdSql.execute(f"insert into {dbName}.{tbName} SELECT now, {fi}({f}('mytext','mykeystring'), 'mykeystring')")
tdSql.query(f"SELECT f1 from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'mytext')
if self.sm4_supported:
tdLog.info(f"====> sm4")
f = 'sm4_ENCRYPT'
fi = 'sm4_decrypt'

tdSql.query(f"SELECT {fi}({f}('mytext','mykeystring'), 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'mytext')

tdSql.execute(f"drop table {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(32))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}('mytext','mykeystring'))")
tdSql.query(f"SELECT {fi}(f1, 'mykeystring') from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'mytext')

tdSql.execute(f"drop table {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(32))")
tdSql.execute(f"insert into {dbName}.{tbName} SELECT now, {fi}({f}('mytext','mykeystring'), 'mykeystring')")
tdSql.query(f"SELECT f1 from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'mytext')

tdLog.info(f"====> base64")
f = 'to_base64'
Expand Down Expand Up @@ -258,31 +295,32 @@ def null(self):
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)

f = 'sm4_encrypt'

tdSql.query(f"SELECT {f}(null, 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)
if self.sm4_supported:
f = 'sm4_encrypt'

tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}(NULL, 'mykeystring'))")
tdSql.query(f"SELECT f1 from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)
tdSql.query(f"SELECT {f}(null, 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)

f = 'sm4_decrypt'

tdSql.query(f"SELECT {f}(null, 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)
tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}(NULL, 'mykeystring'))")
tdSql.query(f"SELECT f1 from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)

tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}(NULL, 'mykeystring'))")
tdSql.query(f"SELECT f1 from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)
f = 'sm4_decrypt'

tdSql.query(f"SELECT {f}(null, 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)

tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}(NULL, 'mykeystring'))")
tdSql.query(f"SELECT f1 from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, None)

tdLog.info(f"====> masking")

Expand Down Expand Up @@ -597,19 +635,20 @@ def empty(self):
tdSql.checkRows(1)
tdSql.checkData(0, 0, '')

f = 'sm4_encrypt'
fi = 'sm4_decrypt'

tdSql.query(f"SELECT {fi}({f}('', 'mykeystring'), 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, '')
if self.sm4_supported:
f = 'sm4_encrypt'
fi = 'sm4_decrypt'

tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}('', 'mykeystring'))")
tdSql.query(f"SELECT {fi}(f1, 'mykeystring') from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, '')
tdSql.query(f"SELECT {fi}({f}('', 'mykeystring'), 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, '')

tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}('', 'mykeystring'))")
tdSql.query(f"SELECT {fi}(f1, 'mykeystring') from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, '')

def single(self):
vgroups = 1
Expand Down Expand Up @@ -790,19 +829,20 @@ def single(self):
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'a')

f = 'sm4_encrypt'
fi = 'sm4_decrypt'

tdSql.query(f"SELECT {fi}({f}('a', 'mykeystring'), 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'a')
if self.sm4_supported:
f = 'sm4_encrypt'
fi = 'sm4_decrypt'

tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}('a', 'mykeystring'))")
tdSql.query(f"SELECT {fi}(f1, 'mykeystring') from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'a')
tdSql.query(f"SELECT {fi}({f}('a', 'mykeystring'), 'mykeystring')")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'a')

tdSql.execute(f"drop table if exists {dbName}.{tbName}")
tdSql.execute(f"create table {dbName}.{tbName}(ts timestamp, f1 varchar(256))")
tdSql.execute(f"insert into {dbName}.{tbName} values(now, {f}('a', 'mykeystring'))")
tdSql.query(f"SELECT {fi}(f1, 'mykeystring') from {dbName}.{tbName}")
tdSql.checkRows(1)
tdSql.checkData(0, 0, 'a')

def error(self):
vgroups = 1
Expand Down
23 changes: 15 additions & 8 deletions test/cases/11-Functions/09-NoFrom/test_fun_no_from_all.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from new_test_framework.utils import tdLog, tdSql, etool
from new_test_framework.utils import tdLog, tdSql, tdCom, etool
import subprocess


Expand Down Expand Up @@ -87,8 +87,6 @@ class TestFunctionNoFromAll:
("sha2", "select sha2('abc', 256);"),
("sign", "select sign(1);"),
("sin", "select sin(1);"),
("sm4_decrypt", "select sm4_decrypt(sm4_encrypt('abc', 'key123456789012'), 'key123456789012');"),
("sm4_encrypt", "select sm4_encrypt('abc', 'key123456789012');"),
("spread", "select spread(1);"),
("sqrt", "select sqrt(1);"),
("st_astext", "select st_astext(st_geomfromtext('POINT(1 2)'));"),
Expand Down Expand Up @@ -136,6 +134,11 @@ class TestFunctionNoFromAll:
("weekofyear", "select weekofyear('2024-01-01 00:00:00');"),
]

SM4_CASES = [
("sm4_decrypt", "select sm4_decrypt(sm4_encrypt('abc', 'key123456789012'), 'key123456789012');"),
("sm4_encrypt", "select sm4_encrypt('abc', 'key123456789012');"),
]

# Unsupported in query without FROM. These calls must fail.
NEGATIVE_CASES = [
# count(*) requires a table to resolve the '*' column; only count(1) is valid without FROM.
Expand All @@ -155,9 +158,8 @@ class TestFunctionNoFromAll:

def _run_by_taos_cli(self, sql):
taos_file = etool.taosFile()
escaped_sql = sql.replace('"', '\\"')
cmd = f'"{taos_file}" -s "{escaped_sql}"'
proc = subprocess.run(cmd, shell=True, text=True, capture_output=True)
cmd = [taos_file, "-c", tdCom.getClientCfgPath(), "-s", sql]
proc = subprocess.run(cmd, text=True, capture_output=True)
return proc.returncode, (proc.stdout or "") + (proc.stderr or "")

def _is_sql_failed(self, code, output):
Expand Down Expand Up @@ -194,8 +196,13 @@ def test_fun_no_from_all(self):
- 2026-04-02 wpan Add full no-from function tests

"""
sm4_code, sm4_output = self._run_by_taos_cli(self.SM4_CASES[0][1])
sm4_supported = not self._is_sql_failed(sm4_code, sm4_output)
positive_cases = self.CASES + (self.SM4_CASES if sm4_supported else [])
negative_cases = self.NEGATIVE_CASES + ([] if sm4_supported else self.SM4_CASES)

failed = []
for name, sql in self.CASES:
for name, sql in positive_cases:
code, output = self._run_by_taos_cli(sql)
if self._is_sql_failed(code, output):
tail = output.strip().splitlines()
Expand All @@ -212,7 +219,7 @@ def test_fun_no_from_all(self):
)

unexpected_success = []
for name, sql in self.NEGATIVE_CASES:
for name, sql in negative_cases:
code, output = self._run_by_taos_cli(sql)
if not self._is_sql_failed(code, output):
tail = output.strip().splitlines()
Expand Down
Loading