decimal testing
This commit is contained in:
parent
51fe4bd0c3
commit
cdc6d6eaf4
|
@ -3440,6 +3440,8 @@ typedef struct {
|
|||
int8_t source; // TD_REQ_FROM_TAOX-taosX or TD_REQ_FROM_APP-taosClient
|
||||
uint32_t compress; // TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS
|
||||
SArray* pMultiTag; // TSDB_ALTER_TABLE_ADD_MULTI_TAGS
|
||||
// for Add column
|
||||
STypeMod typeMod;
|
||||
} SVAlterTbReq;
|
||||
|
||||
int32_t tEncodeSVAlterTbReq(SEncoder* pEncoder, const SVAlterTbReq* pReq);
|
||||
|
|
|
@ -10965,6 +10965,7 @@ int32_t tEncodeSVAlterTbReq(SEncoder *pEncoder, const SVAlterTbReq *pReq) {
|
|||
TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pReq->type));
|
||||
TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pReq->flags));
|
||||
TAOS_CHECK_EXIT(tEncodeI32v(pEncoder, pReq->bytes));
|
||||
TAOS_CHECK_EXIT(tEncodeI32(pEncoder, pReq->typeMod));
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_DROP_COLUMN:
|
||||
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->colName));
|
||||
|
@ -11021,6 +11022,7 @@ int32_t tEncodeSVAlterTbReq(SEncoder *pEncoder, const SVAlterTbReq *pReq) {
|
|||
TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pReq->flags));
|
||||
TAOS_CHECK_EXIT(tEncodeI32v(pEncoder, pReq->bytes));
|
||||
TAOS_CHECK_EXIT(tEncodeU32(pEncoder, pReq->compress));
|
||||
TAOS_CHECK_EXIT(tEncodeI32(pEncoder, pReq->typeMod));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -11046,6 +11048,9 @@ static int32_t tDecodeSVAlterTbReqCommon(SDecoder *pDecoder, SVAlterTbReq *pReq)
|
|||
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->type));
|
||||
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->flags));
|
||||
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pReq->bytes));
|
||||
if (!tDecodeIsEnd(pDecoder)) {
|
||||
TAOS_CHECK_EXIT(tDecodeI32(pDecoder, &pReq->typeMod));
|
||||
}
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_DROP_COLUMN:
|
||||
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->colName));
|
||||
|
@ -11109,6 +11114,9 @@ static int32_t tDecodeSVAlterTbReqCommon(SDecoder *pDecoder, SVAlterTbReq *pReq)
|
|||
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->flags));
|
||||
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pReq->bytes));
|
||||
TAOS_CHECK_EXIT(tDecodeU32(pDecoder, &pReq->compress));
|
||||
if (!tDecodeIsEnd(pDecoder)) {
|
||||
TAOS_CHECK_EXIT(tDecodeI32(pDecoder, &pReq->typeMod));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -428,6 +428,15 @@ int32_t metaCloneEntry(const SMetaEntry *pEntry, SMetaEntry **ppEntry) {
|
|||
metaCloneEntryFree(ppEntry);
|
||||
return code;
|
||||
}
|
||||
if (pEntry->pExtSchemas && pEntry->colCmpr.nCols > 0) {
|
||||
(*ppEntry)->pExtSchemas = taosMemoryCalloc(pEntry->colCmpr.nCols, sizeof(SExtSchema));
|
||||
if (!(*ppEntry)->pExtSchemas) {
|
||||
code = terrno;
|
||||
metaCloneEntryFree(ppEntry);
|
||||
return code;
|
||||
}
|
||||
memcpy((*ppEntry)->pExtSchemas, pEntry->pExtSchemas, sizeof(SExtSchema) * pEntry->colCmpr.nCols);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,36 @@ int32_t updataTableColCmpr(SColCmprWrapper *pWp, SSchema *pSchema, int8_t add, u
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t addTableExtSchema(SMetaEntry *pEntry, const SSchema *pColumn, int32_t newColNum, SExtSchema *pExtSchema) {
|
||||
// no need to add ext schema when no column needs ext schemas
|
||||
if (!HAS_TYPE_MOD(pColumn) && !pEntry->pExtSchemas) return 0;
|
||||
if (!pEntry->pExtSchemas) {
|
||||
// add a column which needs ext schema
|
||||
// set all extschemas to zero for all columns alrady existed
|
||||
pEntry->pExtSchemas = (SExtSchema *)taosMemoryCalloc(newColNum, sizeof(SExtSchema));
|
||||
} else {
|
||||
// already has columns with ext schema
|
||||
pEntry->pExtSchemas = (SExtSchema *)taosMemoryRealloc(pEntry->pExtSchemas, sizeof(SExtSchema) * newColNum);
|
||||
}
|
||||
if (!pEntry->pExtSchemas) return terrno;
|
||||
pEntry->pExtSchemas[newColNum - 1] = *pExtSchema;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t dropTableExtSchema(SMetaEntry *pEntry, int32_t dropColId, int32_t newColNum) {
|
||||
// no ext schema, no need to drop
|
||||
if (!pEntry->pExtSchemas) return 0;
|
||||
if (dropColId == newColNum) {
|
||||
// drop the last column
|
||||
pEntry->pExtSchemas[dropColId - 1] = (SExtSchema){0};
|
||||
} else {
|
||||
// drop a column in the middle
|
||||
memmove(pEntry->pExtSchemas + dropColId, pEntry->pExtSchemas + dropColId + 1,
|
||||
(newColNum - dropColId) * sizeof(SExtSchema));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
|
||||
pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
|
||||
if (NULL == pMetaRsp->pSchemas) {
|
||||
|
|
|
@ -21,6 +21,8 @@ extern int32_t metaFetchEntryByUid(SMeta *pMeta, int64_t uid, SMetaEntry **ppEnt
|
|||
extern int32_t metaFetchEntryByName(SMeta *pMeta, const char *name, SMetaEntry **ppEntry);
|
||||
extern void metaFetchEntryFree(SMetaEntry **ppEntry);
|
||||
extern int32_t updataTableColCmpr(SColCmprWrapper *pWp, SSchema *pSchema, int8_t add, uint32_t compress);
|
||||
extern int32_t addTableExtSchema(SMetaEntry* pEntry, const SSchema* pColumn, int32_t newColNum, SExtSchema* pExtSchema);
|
||||
extern int32_t dropTableExtSchema(SMetaEntry* pEntry, int32_t dropColId, int32_t newColNum);
|
||||
|
||||
static int32_t metaCheckCreateSuperTableReq(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
||||
int32_t vgId = TD_VID(pMeta->pVnode);
|
||||
|
@ -625,6 +627,7 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
|
|||
int32_t rowSize = 0;
|
||||
SSchemaWrapper *pSchema = &pEntry->ntbEntry.schemaRow;
|
||||
SSchema *pColumn;
|
||||
SExtSchema extSchema = {0};
|
||||
pEntry->version = version;
|
||||
for (int32_t i = 0; i < pSchema->nCols; i++) {
|
||||
pColumn = &pSchema->pSchema[i];
|
||||
|
@ -659,6 +662,7 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
|
|||
pColumn->type = pReq->type;
|
||||
pColumn->flags = pReq->flags;
|
||||
pColumn->colId = pEntry->ntbEntry.ncid++;
|
||||
extSchema.typeMod = pReq->typeMod;
|
||||
tstrncpy(pColumn->name, pReq->colName, TSDB_COL_NAME_LEN);
|
||||
uint32_t compress;
|
||||
if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
|
||||
|
@ -673,6 +677,14 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
|
|||
metaFetchEntryFree(&pEntry);
|
||||
TAOS_RETURN(code);
|
||||
}
|
||||
code = addTableExtSchema(pEntry, pColumn, pSchema->nCols, &extSchema);
|
||||
// TODO wjm update extSchema, client set typeMod in add request.
|
||||
if (code) {
|
||||
metaError("vgId:%d, %s failed to add ext schema at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode),
|
||||
__func__, __FILE__, __LINE__, tstrerror(code), version);
|
||||
metaFetchEntryFree(&pEntry);
|
||||
TAOS_RETURN(code);
|
||||
}
|
||||
|
||||
// do handle entry
|
||||
code = metaHandleEntry2(pMeta, pEntry);
|
||||
|
@ -783,6 +795,15 @@ int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, S
|
|||
TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
|
||||
}
|
||||
|
||||
// update column extschema
|
||||
code = dropTableExtSchema(pEntry, iColumn, pSchema->nCols);
|
||||
if (code) {
|
||||
metaError("vgId:%d, %s failed to remove extschema at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode),
|
||||
__func__, __FILE__, __LINE__, tstrerror(code), version);
|
||||
metaFetchEntryFree(&pEntry);
|
||||
TAOS_RETURN(code);
|
||||
}
|
||||
|
||||
// do handle entry
|
||||
code = metaHandleEntry2(pMeta, pEntry);
|
||||
if (code) {
|
||||
|
|
|
@ -166,7 +166,15 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock,
|
|||
STR_TO_VARSTR(buf, pMeta->schema[i].name);
|
||||
COL_DATA_SET_VAL_AND_CHECK(pCol1, pBlock->info.rows, buf, false);
|
||||
|
||||
STR_TO_VARSTR(buf, tDataTypes[pMeta->schema[i].type].name);
|
||||
if (IS_DECIMAL_TYPE(pMeta->schema[i].type) && withExtSchema(pMeta->tableType)) {
|
||||
uint8_t prec = 0, scale = 0;
|
||||
decimalFromTypeMod(pMeta->schemaExt[i].typeMod, &prec, &scale);
|
||||
size_t len = snprintf(buf + VARSTR_HEADER_SIZE, DESCRIBE_RESULT_FIELD_LEN - VARSTR_HEADER_SIZE, "%s(%hhu, %hhu)",
|
||||
tDataTypes[pMeta->schema[i].type].name, prec, scale);
|
||||
varDataSetLen(buf, len);
|
||||
} else {
|
||||
STR_TO_VARSTR(buf, tDataTypes[pMeta->schema[i].type].name);
|
||||
}
|
||||
COL_DATA_SET_VAL_AND_CHECK(pCol2, pBlock->info.rows, buf, false);
|
||||
int32_t bytes = getSchemaBytes(pMeta->schema + i);
|
||||
COL_DATA_SET_VAL_AND_CHECK(pCol3, pBlock->info.rows, (const char*)&bytes, false);
|
||||
|
|
|
@ -609,94 +609,6 @@ TEST(decimal128, divide) {
|
|||
ASSERT_TRUE(1);
|
||||
}
|
||||
|
||||
TEST(decimal, api_taos_fetch_rows) {
|
||||
const char* host = "127.0.0.1";
|
||||
const char* user = "root";
|
||||
const char* passwd = "taosdata";
|
||||
const char* db = "test_api";
|
||||
const char* create_tb = "create table if not exists test_api.nt(ts timestamp, c1 decimal(10, 2), c2 decimal(38, 10))";
|
||||
const char* sql = "select c1, c2 from test_api.nt";
|
||||
const char* sql_insert = "insert into test_api.nt values(now, 123456.123, 98472981092.1209111)";
|
||||
|
||||
TAOS* pTaos = taos_connect(host, user, passwd, NULL, 0);
|
||||
if (!pTaos) {
|
||||
cout << "taos connect failed: " << host << " " << taos_errstr(NULL);
|
||||
FAIL();
|
||||
}
|
||||
|
||||
auto* res = taos_query(pTaos, (std::string("create database if not exists ") + db).c_str());
|
||||
taos_free_result(res);
|
||||
res = taos_query(pTaos, create_tb);
|
||||
taos_free_result(res);
|
||||
res = taos_query(pTaos, sql_insert);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(pTaos, sql);
|
||||
int32_t code = taos_errno(res);
|
||||
if (code != 0) {
|
||||
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
|
||||
FAIL();
|
||||
}
|
||||
|
||||
char buf[1024] = {0};
|
||||
auto* fields = taos_fetch_fields(res);
|
||||
auto fieldNum = taos_field_count(res);
|
||||
while (auto row = taos_fetch_row(res)) {
|
||||
taos_print_row(buf, row, fields, fieldNum);
|
||||
cout << buf << endl;
|
||||
}
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(pTaos, sql);
|
||||
code = taos_errno(res);
|
||||
if (code != 0) {
|
||||
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
|
||||
taos_free_result(res);
|
||||
FAIL();
|
||||
}
|
||||
|
||||
void* pData = NULL;
|
||||
int32_t numOfRows = 0;
|
||||
code = taos_fetch_raw_block(res, &numOfRows, &pData);
|
||||
if (code != 0) {
|
||||
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
|
||||
FAIL();
|
||||
}
|
||||
if (numOfRows > 0) {
|
||||
int32_t version = *(int32_t*)pData;
|
||||
ASSERT_EQ(version, BLOCK_VERSION_1);
|
||||
int32_t rows = *(int32_t*)((char*)pData + 4 + 4);
|
||||
int32_t colNum = *(int32_t*)((char*)pData + 4 + 4 + 4);
|
||||
int32_t bytes_skip = 4 + 4 + 4 + 4 + 4 + 8;
|
||||
char* p = (char*)pData + bytes_skip;
|
||||
// col1
|
||||
int8_t t = *(int8_t*)p;
|
||||
int32_t type_mod = *(int32_t*)(p + 1);
|
||||
|
||||
ASSERT_EQ(t, TSDB_DATA_TYPE_DECIMAL64);
|
||||
auto check_type_mod = [](char* pStart, uint8_t prec, uint8_t scale, int32_t bytes) {
|
||||
ASSERT_EQ(*pStart, bytes);
|
||||
ASSERT_EQ(*(pStart + 2), prec);
|
||||
ASSERT_EQ(*(pStart + 3), scale);
|
||||
};
|
||||
check_type_mod(p + 1, 10, 2, 8);
|
||||
|
||||
// col2
|
||||
p += 5;
|
||||
t = *(int8_t*)p;
|
||||
type_mod = *(int32_t*)(p + 1);
|
||||
check_type_mod(p + 1, 38, 10, 16);
|
||||
|
||||
p = p + 5 + BitmapLen(numOfRows) + colNum * 4;
|
||||
int64_t row1Val = *(int64_t*)p;
|
||||
ASSERT_EQ(row1Val, 12345612);
|
||||
}
|
||||
taos_free_result(res);
|
||||
|
||||
taos_close(pTaos);
|
||||
taos_cleanup();
|
||||
}
|
||||
|
||||
TEST(decimal, conversion) {
|
||||
// convert uint8 to decimal
|
||||
char buf[64] = {0};
|
||||
|
@ -1249,6 +1161,126 @@ TEST(decimal_all, ret_type_for_non_decimal_types) {
|
|||
}
|
||||
}
|
||||
|
||||
class DecimalTest : public ::testing::Test {
|
||||
TAOS* get_connection() {
|
||||
auto conn = taos_connect(host, user, passwd, db, 0);
|
||||
if (!conn) {
|
||||
cout << "taos connect failed: " << host << " " << taos_errstr(NULL);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
TAOS* default_conn_ = NULL;
|
||||
static constexpr const char* host = "127.0.0.1";
|
||||
static constexpr const char* user = "root";
|
||||
static constexpr const char* passwd = "taosdata";
|
||||
static constexpr const char* db = "test_api";
|
||||
|
||||
public:
|
||||
void SetUp() override {
|
||||
default_conn_ = get_connection();
|
||||
if (!default_conn_) {
|
||||
FAIL();
|
||||
}
|
||||
}
|
||||
void TearDown() override {
|
||||
if (default_conn_) {
|
||||
taos_close(default_conn_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(DecimalTest, insert) {
|
||||
|
||||
}
|
||||
|
||||
TEST_F(DecimalTest, api_taos_fetch_rows) {
|
||||
const char* host = "127.0.0.1";
|
||||
const char* user = "root";
|
||||
const char* passwd = "taosdata";
|
||||
const char* db = "test_api";
|
||||
const char* create_tb = "create table if not exists test_api.nt(ts timestamp, c1 decimal(10, 2), c2 decimal(38, 10))";
|
||||
const char* sql = "select c1, c2 from test_api.nt";
|
||||
const char* sql_insert = "insert into test_api.nt values(now, 123456.123, 98472981092.1209111)";
|
||||
|
||||
TAOS* pTaos = taos_connect(host, user, passwd, NULL, 0);
|
||||
if (!pTaos) {
|
||||
cout << "taos connect failed: " << host << " " << taos_errstr(NULL);
|
||||
FAIL();
|
||||
}
|
||||
|
||||
auto* res = taos_query(pTaos, (std::string("create database if not exists ") + db).c_str());
|
||||
taos_free_result(res);
|
||||
res = taos_query(pTaos, create_tb);
|
||||
taos_free_result(res);
|
||||
res = taos_query(pTaos, sql_insert);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(pTaos, sql);
|
||||
int32_t code = taos_errno(res);
|
||||
if (code != 0) {
|
||||
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
|
||||
FAIL();
|
||||
}
|
||||
|
||||
char buf[1024] = {0};
|
||||
auto* fields = taos_fetch_fields(res);
|
||||
auto fieldNum = taos_field_count(res);
|
||||
while (auto row = taos_fetch_row(res)) {
|
||||
taos_print_row(buf, row, fields, fieldNum);
|
||||
cout << buf << endl;
|
||||
}
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(pTaos, sql);
|
||||
code = taos_errno(res);
|
||||
if (code != 0) {
|
||||
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
|
||||
taos_free_result(res);
|
||||
FAIL();
|
||||
}
|
||||
|
||||
void* pData = NULL;
|
||||
int32_t numOfRows = 0;
|
||||
code = taos_fetch_raw_block(res, &numOfRows, &pData);
|
||||
if (code != 0) {
|
||||
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
|
||||
FAIL();
|
||||
}
|
||||
if (numOfRows > 0) {
|
||||
int32_t version = *(int32_t*)pData;
|
||||
ASSERT_EQ(version, BLOCK_VERSION_1);
|
||||
int32_t rows = *(int32_t*)((char*)pData + 4 + 4);
|
||||
int32_t colNum = *(int32_t*)((char*)pData + 4 + 4 + 4);
|
||||
int32_t bytes_skip = 4 + 4 + 4 + 4 + 4 + 8;
|
||||
char* p = (char*)pData + bytes_skip;
|
||||
// col1
|
||||
int8_t t = *(int8_t*)p;
|
||||
int32_t type_mod = *(int32_t*)(p + 1);
|
||||
|
||||
ASSERT_EQ(t, TSDB_DATA_TYPE_DECIMAL64);
|
||||
auto check_type_mod = [](char* pStart, uint8_t prec, uint8_t scale, int32_t bytes) {
|
||||
ASSERT_EQ(*pStart, bytes);
|
||||
ASSERT_EQ(*(pStart + 2), prec);
|
||||
ASSERT_EQ(*(pStart + 3), scale);
|
||||
};
|
||||
check_type_mod(p + 1, 10, 2, 8);
|
||||
|
||||
// col2
|
||||
p += 5;
|
||||
t = *(int8_t*)p;
|
||||
type_mod = *(int32_t*)(p + 1);
|
||||
check_type_mod(p + 1, 38, 10, 16);
|
||||
|
||||
p = p + 5 + BitmapLen(numOfRows) + colNum * 4;
|
||||
int64_t row1Val = *(int64_t*)p;
|
||||
ASSERT_EQ(row1Val, 12345612);
|
||||
}
|
||||
taos_free_result(res);
|
||||
|
||||
taos_close(pTaos);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
|
|
@ -9460,7 +9460,11 @@ static int32_t checkTableTagsSchema(STranslateContext* pCxt, SHashObj* pHash, SN
|
|||
} else {
|
||||
break;
|
||||
}
|
||||
// TODO wjm can't create tag with decimal type
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (IS_DECIMAL_TYPE(pTag->dataType.type)) {
|
||||
code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, "Decimal type is not allowed for tag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && tagsSize > TSDB_MAX_TAGS_LEN) {
|
||||
|
@ -16675,6 +16679,12 @@ static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, S
|
|||
int8_t code = setColCompressByOption(pReq->type, columnEncodeVal(pStmt->pColOptions->encode),
|
||||
columnCompressVal(pStmt->pColOptions->compress),
|
||||
columnLevelVal(pStmt->pColOptions->compressLevel), true, &pReq->compress);
|
||||
if (code != TSDB_CODE_SUCCESS) return code;
|
||||
}
|
||||
pReq->typeMod = 0;
|
||||
if (IS_DECIMAL_TYPE(pStmt->dataType.type)) {
|
||||
pReq->typeMod = decimalCalcTypeMod(pStmt->dataType.precision, pStmt->dataType.scale);
|
||||
pReq->flags |= COL_HAS_TYPE_MOD;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -2,6 +2,7 @@ from random import randrange
|
|||
import time
|
||||
import threading
|
||||
import secrets
|
||||
from tag_lite import column
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
|
@ -47,8 +48,13 @@ class DecimalType:
|
|||
if digits == '':
|
||||
digits = '0'
|
||||
return digits
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def default_compression() -> str:
|
||||
return "zstd"
|
||||
@staticmethod
|
||||
def default_encode() -> str:
|
||||
return "disabled"
|
||||
class TypeEnum:
|
||||
BOOL = 1
|
||||
TINYINT = 2
|
||||
|
@ -244,13 +250,13 @@ class TableInserter:
|
|||
sql += ", "
|
||||
local_flush_database = i % 5000 == 0;
|
||||
if len(sql) > 1000:
|
||||
tdLog.debug(f"insert into with sql{sql}")
|
||||
#tdLog.debug(f"insert into with sql{sql}")
|
||||
if flush_database and local_flush_database:
|
||||
self.conn.execute(f"flush database {self.dbName}", queryTimes=1)
|
||||
self.conn.execute(sql, queryTimes=1)
|
||||
sql = pre_insert
|
||||
if len(sql) > len(pre_insert):
|
||||
tdLog.debug(f"insert into with sql{sql}")
|
||||
#tdLog.debug(f"insert into with sql{sql}")
|
||||
if flush_database:
|
||||
self.conn.execute(f"flush database {self.dbName}", queryTimes=1)
|
||||
self.conn.execute(sql, queryTimes=1)
|
||||
|
@ -392,11 +398,13 @@ class TDTestCase:
|
|||
results = tdSql.queryResult
|
||||
for i, column_type in enumerate(column_types):
|
||||
if column_type.type == TypeEnum.DECIMAL:
|
||||
if results[i+1][1] != "DECIMAL":
|
||||
if results[i+1][1] != column_type.__str__():
|
||||
tdLog.info(str(results))
|
||||
tdLog.exit(f"check desc failed for table: {tbname} column {results[i+1][0]} type is {results[i+1][1]}, expect DECIMAL")
|
||||
## add decimal type bytes check
|
||||
## add compression/encode check
|
||||
if results[i+1][4] != DecimalType.default_encode():
|
||||
tdLog.exit(f"check desc failed for table: {tbname} column {results[i+1][0]} encode is {results[i+1][5]}, expect {DecimalType.default_encode()}")
|
||||
if results[i+1][5] != DecimalType.default_compression():
|
||||
tdLog.exit(f"check desc failed for table: {tbname} column {results[i+1][0]} compression is {results[i+1][4]}, expect {DecimalType.default_compression()}")
|
||||
|
||||
def check_show_create_table(self, tbname: str, column_types: List[DataType], tag_types: List[DataType] = []):
|
||||
sql = f"show create table {self.db_name}.{tbname}"
|
||||
|
@ -445,16 +453,34 @@ class TDTestCase:
|
|||
DecimalColumnTableCreater(tdSql, self.db_name, self.stable_name, self.columns).create_child_table(self.c_table_prefix, self.c_table_num, self.tags, tag_values)
|
||||
self.check_desc("t1", self.columns, self.tags)
|
||||
|
||||
return
|
||||
## invalid precision/scale
|
||||
invalid_precision_scale = ["decimal(-1, 2)", "decimal(39, 2)", "decimal(10, -1)", "decimal(10, 39)", "decimal(10, 2.5)", "decimal(10.5, 2)", "decimal(10.5, 2.5)", "decimal(0, 2)", "decimal(0)", "decimal", "decimal()"]
|
||||
syntax_error = -2147473920
|
||||
invalid_column = -2147473918
|
||||
invalid_precision_scale = [("decimal(-1, 2)", syntax_error), ("decimal(39, 2)", invalid_column), ("decimal(10, -1)", syntax_error),
|
||||
("decimal(10, 39)", invalid_column), ("decimal(10, 2.5)", syntax_error), ("decimal(10.5, 2)", syntax_error),
|
||||
("decimal(10.5, 2.5)", syntax_error), ("decimal(0, 2)", invalid_column), ("decimal(0)", invalid_column),
|
||||
("decimal", syntax_error), ("decimal()", syntax_error)]
|
||||
for i in invalid_precision_scale:
|
||||
sql = f"create table {self.db_name}.invalid_decimal_precision_scale (ts timestamp, c1 {i})"
|
||||
tdSql.error(sql, -1)
|
||||
sql = f"create table {self.db_name}.invalid_decimal_precision_scale (ts timestamp, c1 {i[0]})"
|
||||
tdSql.error(sql, i[1])
|
||||
|
||||
## can't create decimal tag
|
||||
sql = 'create stable %s.invalid_decimal_tag (ts timestamp) tags (t1 decimal(10, 2))' % (self.db_name)
|
||||
tdSql.error(sql, invalid_column)
|
||||
|
||||
## alter table add column
|
||||
sql = f'alter table {self.db_name}.{self.norm_table_name} add column c99 decimal(37, 19)'
|
||||
self.columns.append(DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(37, 19))))
|
||||
tdSql.execute(sql, queryTimes=1)
|
||||
self.check_desc(self.norm_table_name, self.columns)
|
||||
## alter table add column with compression
|
||||
|
||||
## Test metaentry compatibility problem for decimal type:w
|
||||
## How to test it?
|
||||
## Create table with no decimal type, the metaentries should not have extschma, and add decimal column, the metaentries should have extschema for all columns.
|
||||
## After drop this decimal column, the metaentries should not have extschema for all columns.
|
||||
## Test for normal table and super table
|
||||
|
||||
## alter table
|
||||
## drop index from stb
|
||||
### These ops will override the previous stbobjs and meta entries, so test it
|
||||
|
||||
|
@ -466,7 +492,7 @@ class TDTestCase:
|
|||
pass
|
||||
#TableInserter(tdSql, self.db_name, f"{self.c_table_prefix}{i}", self.columns, self.tags).insert(1, 1537146000000, 500)
|
||||
|
||||
TableInserter(tdSql, self.db_name, self.norm_table_name, self.columns).insert(100000, 1537146000000, 500, flush_database=True)
|
||||
TableInserter(tdSql, self.db_name, self.norm_table_name, self.columns).insert(10000, 1537146000000, 500, flush_database=True)
|
||||
|
||||
|
||||
## insert null/None for decimal type
|
||||
|
@ -483,7 +509,8 @@ class TDTestCase:
|
|||
DataType(TypeEnum.VARCHAR, 255),
|
||||
]
|
||||
DecimalColumnTableCreater(tdSql, self.db_name, "tt", columns, []).create()
|
||||
TableInserter(tdSql, self.db_name, 'tt', columns).insert(100000, 1537146000000, 500, flush_database=True)
|
||||
TableInserter(tdSql, self.db_name, 'tt', columns).insert(10000, 1537146000000, 500, flush_database=True)
|
||||
## TODO wjm test non support decimal version upgrade to decimal support version, and add decimal column
|
||||
|
||||
def test_decimal_ddl(self):
|
||||
tdSql.execute("create database test", queryTimes=1)
|
||||
|
@ -493,7 +520,6 @@ class TDTestCase:
|
|||
self.test_decimal_ddl()
|
||||
self.no_decimal_table_test()
|
||||
self.test_insert_decimal_values()
|
||||
time.sleep(9999999)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
Loading…
Reference in New Issue